summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Dockerfile1
-rw-r--r--README1
-rw-r--r--data/docs/10115
-rw-r--r--data/docs/111870
-rw-r--r--data/docs/12190
-rw-r--r--data/docs/1366
-rw-r--r--data/docs/14162
-rw-r--r--data/docs/1567
-rw-r--r--data/docs/1645
-rw-r--r--data/docs/2257
-rw-r--r--data/docs/3160
-rw-r--r--data/docs/476
-rw-r--r--data/docs/590
-rw-r--r--data/docs/6138
-rw-r--r--data/docs/769
-rw-r--r--data/docs/980
-rw-r--r--data/docs/incomplete4
-rw-r--r--data/docs/index19
-rw-r--r--data/docs/notfinished4
-rw-r--r--data/style.css26
-rw-r--r--lib/Multi/Feed.pm5
-rw-r--r--lib/Multi/IRC.pm31
-rw-r--r--lib/VNDB/BBCode.pm8
-rw-r--r--lib/VNDB/DB/Docs.pm53
-rw-r--r--lib/VNDB/DB/Misc.pm4
-rw-r--r--lib/VNDB/Handler/Discussions.pm4
-rw-r--r--lib/VNDB/Handler/Docs.pm177
-rw-r--r--lib/VNDB/Handler/Misc.pm84
-rw-r--r--lib/VNDB/Handler/VNEdit.pm2
-rw-r--r--lib/VNDB/Util/CommonHTML.pm10
-rw-r--r--lib/VNDB/Util/FormHTML.pm4
-rwxr-xr-xutil/bbcode-test.pl4
-rw-r--r--util/sql/all.sql4
-rw-r--r--util/sql/devdb.sql55
-rw-r--r--util/sql/func.sql3
-rw-r--r--util/sql/perms.sql4
-rw-r--r--util/sql/schema.sql16
-rw-r--r--util/updates/update_20180208.sql57
38 files changed, 428 insertions, 3537 deletions
diff --git a/Dockerfile b/Dockerfile
index 0220e6b5..faf90437 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -23,6 +23,7 @@ RUN apt-get install -y --no-install-recommends \
libjson-xs-perl \
libperlio-gzip-perl \
libpq-dev \
+ libtext-multimarkdown-perl \
libtie-ixhash-perl \
libxml-parser-perl \
postgresql
diff --git a/README b/README
index 530863f0..9ea26f7e 100644
--- a/README
+++ b/README
@@ -56,6 +56,7 @@ Requirements (when not using Docker)
util/vndb.pl:
Algorithm::Diff::XS
+ Text::MultiMarkdown
TUWF
HTTP::Server::Simple (optional, but greatly simplifies development setup)
FCGI (optional, for running as a FastCGI script)
diff --git a/data/docs/10 b/data/docs/10
deleted file mode 100644
index 0630d580..00000000
--- a/data/docs/10
+++ /dev/null
@@ -1,115 +0,0 @@
-:TITLE:Tags & traits
-:INC:index
-
-
-:SUB:Introduction
-<p>
- VNDB has a system for tags and one for traits. Tags are used to categorize
- <b>visual novels</b>, while traits tell something about <b>characters</b>. This
- also makes them somewhat different in use. This page describes some general
- guidelines and tips on using tags and traits.
-</p>
-
-
-
-:SUB:Tags
-<p>
- Tags can be assigned to visual novel entries using a voting system. Every user
- can add a tag to a visual novel by going to the "modify tags" tab of a visual
- novel page.
-</p>
-
-:SUBSUB:Tag voting
-<p>Tags can be assigned a vote from -3 to 3. This vote should be interpreted as
- follows:</p>
-<ol style="list-style-type: none; margin-left: 15px">
- <li><b>-3</b>: This tag really doesn't apply to the VN.</li>
- <li><b>-2</b> and <b>-1</b>: These not very often used, but can be useful to
- show that you disagree, but are not 100% sure.</li>
- <li><b>0</b>: It is possible to change your vote to '0' to remove it.</li>
- <li><b>1</b>: The tag does apply to the visual novel, but is not too apparent
- or only plays a minor role.</li>
- <li><b>2</b>: The tag certainly applies to the visual novel.</li>
- <li><b>3</b>: The tag applies, is very apparent and plays a major role.</li>
-</ol>
-<p><br />
- While everyone is pretty much free to link any tag to any visual novel, please
- keep the following in mind while voting:
-</p>
-<ul>
- <li>Read the description of each tag before you link it to a VN: some tags may
- not always mean what you think they do.</li>
- <li>Try to be as specific as you can. For example, if a game has drama
- elements, rather than voting on the "Drama" tag, try to look for a more
- specific child tag that describes what kind of drama a player can expect.</li>
- <li>Some tags can act as spoilers for the plot of a VN, this can be indicated
- by voting on the spoiler status. It is highly recommended to not leave this as
- "Neutral", and really try to give an indication of whether the tag is not a
- spoiler at all or does spoil a bit.</li>
- <li>Tags are supposed to reflect the things you'll be experiencing as you play
- the game, even if some things might get revealed to be lies or illusions
- towards the end of the story. In cases like this, add both the (arguably
- incorrect) tags and the tags describing the situation after the truth has been
- revealed, making sure to mark the "correct" tags as spoilers.</li>
-</ul>
-
-
-:SUBSUB:Tag creation guidelines
-<p>
- New tags can be requested by everyone, but they'll have to be accepted by a
- moderator before the tags will be browsable. Applying the following guidelines
- significantly increases the chances that your tag will be accepted and lowers
- the workload of the moderator team.
-</p>
-<ul>
- <li>Tag names should be self-describing. While the meaning of a tag can be obvious if you look
- at its place within the tag tree, when displayed on a VN page only their name is visible and
- not the parent tags. The name should thus fully describe what the tag means and should be used
- for. For example: a tag to describe a male protagonist should be fully named "Male protagonist",
- even if its parent tag is "Characters &gt; Protagonist".</li>
- <li>Tags should be used to describe objective information about a VN. Subjective tags like
- "Awesome protagonist", which would have a different meaning for each individual, are not allowed.</li>
- <li>Tags should only cover information that VNDB itself doesn't cover already. So tags about release
- information or the length of a VN are not allowed.</li>
- <li>The above rule also holds true for any other information about the VN itself which is (not yet)
- covered by VNDB, like staff or licensed state in a country.</li>
-</ul>
-
-
-
-:SUB:Traits
-<p>
- Traits can be assigned to characters. Contrary to tags, traits can't be voted
- on. Instead, traits are part of the editing system, and modifying the traits
- for a certain character involves editing the character entry itself.
-</p>
-
-:SUBSUB:Assigning traits
-<p>
- Unlike tags, traits don't have any "levels": a trait either applies to the
- character or it does not. Here are some guidelines and tips when assigning
- traits to characters:
-</p>
-<ul>
- <li>If no traits are present yet and you're the first person to add traits,
- please try to be as complete as possible. Browse through the <a
- href="/i">trait tree</a> and try to find as many traits that apply to the
- character as possible.</li>
- <li>Spoilery traits should *always* be marked as such.</li>
-</ul>
-
-:SUBSUB:Trait creation
-<p>
- Anyone can request new traits to be added to the database. However, these need
- to be approved by a moderator before they can actually be assigned to a
- character.<br /><br />
- Traits are categorized into "groups", the top-most trait in the tree
- defines in which group a trait is. Unlike tags, traits don't need to have a
- globally unique name, but they must be unique and self-describing within the
- same group. For example, there can be multiple traits with the name "Blue",
- but one is in the "Hair" group while the other is in the "Eyes" group. So
- make sure to keep the group in mind when naming a trait.<br /><br />
- Read the descriptions of the various trait groups and meta traits to get a
- feel on how they are supposed to be used.
-</p>
-
diff --git a/data/docs/11 b/data/docs/11
deleted file mode 100644
index 77e7cf66..00000000
--- a/data/docs/11
+++ /dev/null
@@ -1,1870 +0,0 @@
-:TITLE:Public Database API
-:INC:index
-
-:SUB:Introduction
-<p>
- This document describes the public API of VNDB and is intended to be read by
- programmers. This API allows programs and websites to access (parts of) the
- VNDB database without actually visiting the website.
- <br /><br />
- In addition to this real-time API, we also provide some information in the
- form of <a href="/d14">database dumps</a>.
- <br /><br />
-</p>
-
-<b>Usage terms</b>
-<p>
- This service is free for non-commercial use. The API is provided on a
- best-effort basis, no guarantees are made about the stability or applicability
- of this service.
-</p>
-<br />
-
-<b>Design goals</b>
-<ul>
- <li>
- Simple in implementation of both client and server. "Simple" here means that
- it shouldn't take much code to write a secure and full implementation and that
- client applications shouldn't require huge dependency trees just to use this API.
- </li>
- <li>Powerful: Not as powerful as raw SQL, but not as rigid as commonly used REST or RPC protocols.</li>
- <li>High-level: common applications need to perform only few actions to get what they want.</li>
- <li>Fast: minimal bandwidth overhead and simple and customizable queries.</li>
-</ul>
-<br />
-
-<b>Design overview</b>
-<ul>
- <li>TCP-based, all communication between the client and the server is done
- using one TCP connection. This connection stays alive until it is explicitely
- closed by either the client or the server.</li>
- <li>Request/response, client sends a request and server replies with a response.</li>
- <li>Session-based: clients are required to login before issuing commands to
- the server. A session is created by issuing the 'login' command, this session
- stays valid for the lifetime of the TCP connection.</li>
- <li><b>Everything</b> sent between the client and the server is encoded in UTF-8.</li>
-</ul>
-<br />
-
-<b>Limits</b>
-<p>The following limits are enforced by the server, in order to limit the
-server resources and prevent abuse of this service.</p>
-<ul>
- <li>10 connections per IP. All connections that are opened after reaching this limit will be immediately closed.</li>
- <li>200 commands per 10 minutes per ip. Server will reply with a 'throttled' error (type="cmd") when reaching this limit.</li>
- <li>
- 1 second of SQL time per minute per ip. SQL time is the total time taken to
- run the database queries for each command. This depends on both the command
- (filters and get flags) and server load, and is thus not very predictable.
- Server will reply with a 'throttled' error with type="sql" upon reaching
- this limit.
- </li>
- <li>Each command returns at most 25 results, with the exception of get
- votelist/vnlist/wishlist, which returns at most 100 results.</li>
-</ul>
-<p>
- These limits may sound strict, but in practice you won't have to worry much
- about it. As long as your application properly waits when the server replies
- with a "throttle" error, everything will be handled automatically. In the event
- that your application does require more resources, don't hesitate to ask.
-</p>
-
-
-<br />
-<b>Connection info:</b>
-<dl>
- <dt>Host</dt><dd>api.vndb.org</dd>
- <dt>Port (plain tcp)</dt><dd>19534 ('VN')</dd>
- <dt>Port (TLS)</dt><dd>19535<br />For improved security, make sure to verify that the certificate is valid for 'api.vndb.org' and is signed by a trusted root (in particular, by <a href="https://letsencrypt.org/certificates/">Let's Encrypt</a>).</dd>
-</dl>
-
-
-
-:SUB:Request/response syntax
-<p>
- The VNDB API uses the JSON format for data in various places, this document assumes
- you are familiar with it. See <a href="http://json.org/">JSON.org</a> for a quick
- overview and <a href="http://www.ietf.org/rfc/rfc4627.txt?number=4627">RFC 4627</a>
- for the glory details.
- <br /><br />
- The words <i>object</i>, <i>array</i>, <i>value</i>, <i>string</i>,
- <i>number</i> and <i>integer</i> refer to the JSON data types. In addition the following
- definitions are used in this document:
-</p>
-<dl>
- <dt><i>request</i> or <i>command</i></dt><dd>
- Message sent from the client to the server.
- </dd><dt><i>response</i></dt><dd>
- Message sent from the server to the client.
- </dd><dt><i>whitespace</i></dt><dd>
- Any sequence of the following characters: space, tab, line feed and carriage
- return. (hexadecimal: 20, 09, 0A, 0D, respectively). This is in line with the
- definition of whitespace in the JSON specification.
- </dd><dt><i>date</i></dt><dd>
- A <i>string</i> signifying a date (in particular: release date). The
- following formats are used: "yyyy" (when day and month are unknown), "yyyy-mm"
- (when day is unknown) "yyyy-mm-dd", and "tba" (To Be Announced). If the year is
- not known and the date is not "tba", the special value <b>null</b> is used.
- </dd>
-</dl>
-<br />
-
-<b>Message format</b>
-<p>
- A message is formatted as a command or response name, followed by any number of
- arguments, followed by the End Of Transmission character (04 in hexadecimal).
- Arguments are separated by one or more whitespace characters, and any sequence
- of whitespace characters is allowed before and after the message.<br />
- The command or response name is an unescaped string containing only lowercase
- alphabetical ASCII characters, and indicates what kind of command or response
- this message contains.<br />
- An argument can either be an unescaped string (not containing whitespace), any
- JSON value, or a filter string. The following two examples demonstrate a
- 'login' command, with an object as argument. Both messages are equivalent, as
- the whitespace is ignored. '0x04' is used to indicate the End Of Transmission
- character.
-</p>
-<pre>
- login {"protocol":1,"username":"ayo"}<b class="standout">0x04</b>
-</pre><pre>
- login {
- "protocol" : 1,
- "username" : "ayo"
- }
- <b class="standout">0x04</b>
-</pre>
-The 0x04 byte will be ommitted in the other examples in this document. It is
-however still required.<br />
-
-<br />
-<b>Filter string syntax</b>
-<p>
- Some commands accept a filter string as argument. This argument is formatted
- similar to boolean expressions in most programming languages. A filter consists
- of one or more <i>expressions</i>, separated by the boolean operators "and" or
- "or" (lowercase). Each filter expression can be surrounded by parentheses to
- indicate precedence, the filter argument itself must be surrounded by parentheses.
- <br />
- An <i>expression</i> consists of a <i>field name</i>, followed by an
- <i>operator</i> and a <i>value</i>. The field name must consist entirely of
- lowercase alphanumeric characters and can also contain an underscore. The
- operator must be one of the following characters: =, !=, &lt;, &lt;=, &gt;,
- &gt;= or ~. The <i>value</i> can be any valid JSON value. Whitespace
- characters are allowed, but not required, between all expressions, field names,
- operators and values.<br />
- The following two filters are equivalent:
-</p>
-<pre>
- (title~"osananajimi"or(id=2))
-</pre><pre>
- (
- id = 2
- or
- title ~ "osananajimi"
- )
-</pre>
-<p>More complex filters are also possible:</p>
-<pre>
- ((platforms = ["win", "ps2"] or languages = "ja") and released > "2009-01-10")
-</pre>
-<p>See the individual commands for more details.</p>
-
-
-:SUB:The 'login' command
-<pre>
- login {"protocol":1,"client":"test","clientver":0.1,"username":"ayo","password":"hi-mi-tsu!"}
-</pre>
-<p>
- Every client is required to login before issuing other commands. The login
- command accepts a JSON object as argument. This object has the following members:
-</p>
-<dl>
- <dt>protocol</dt><dd>An integer that indicates which protocol version the client implements. Must be 1.</dd>
- <dt>client</dt><dd>
- A string identifying the client application. Between the 3 and 50 characters,
- must contain only alphanumeric ASCII characters, space, underscore and hyphens.
- When writing a client, think of a funny (unique) name and hardcode it into
- your application.
- </dd><dt>clientver</dt><dd>A number or string indicating the software version of the client.</dd>
- <dt>username</dt><dd>(optional) String containing the username of the person using the client.</dd>
- <dt>password</dt><dd>(optional) String, password of that user in plain text.</dd>
-</dl>
-<p>
- The server replies with either 'ok' (no arguments), or 'error' (see below).
- Note that logging in using a username and password is optional, but some
- commands are only available when logged in. It is strongly recommended to
- connect with TLS when logging in with a username and password.
-</p>
-
-
-:SUB:The 'dbstats' command
-<p>
- This command gives the global database statistics that are visible in the main
- menu of the site. The command is simply:
-</p>
-<pre>
- dbstats
-</pre>
-<p>And the response has the following format:</p>
-<pre>
- dbstats <b class="standout">stats</b>
-</pre>
-<p>Where <i>stats</i> is a JSON object with integer values. Example response:</p>
-<pre>
- dbstats {"users":49084,
- "threads":3998,
- "tags":1627,
- "releases":28071,
- "producers":3456,
- "chars":14046,
- "posts":52470,
- "vn":13051,
- "traits":1272}
-</pre>
-
-
-:SUB:The 'get' command
-<p>
- This command is used to fetch data from the database. It accepts 4 arguments:
- the type of data to fetch (e.g. visual novels or producers), what part of that
- data to fetch (e.g. only the VN titles, or the descriptions and relations as
- well), a filter expression, and lastly some options.
-</p>
-<pre>
- get <b class="standout">type flags filters options</b>
-</pre>
-<p>
- <i>type</i> and <i>flags</i> are unescaped strings. The accepted values for <i>type</i> are
- documented below. <i>flags</i> is a comma-separated list of flags indicating what
- info to fetch. The filters, available flags and their meaning are documented
- separately for each type. The last <i>options</i> argument is optional, and
- influences the behaviour of the returned results. When present, <i>options</i>
- should be a JSON object with the following members (all are optional):
-</p>
-<dl>
- <dt>page</dt><dd>
- integer, used for pagination. Page 1 (the default) returns the first 10
- results (1-10), page 2 returns the following 10 (11-20), etc. (The actual
- number of results per page can be set with the "results" option below).
- </dd><dt>results</dt><dd>
- integer, maximum number of results to return. Also affects the "page" option
- above. For example: with "page" set to 2 and "results" set to 5, the second
- five results (that is, results 6-10) will be returned. Default: 10.
- </dd><dt>sort</dt><dd>
- string, the field to order the results by. The accepted field names differ
- per type, the default sort field is the ID of the database entry.
- </dd>
- <dt>reverse</dt><dd>boolean, default false. Set to true to reverse the order of the results.</dd>
-</dl>
-<p>
- The following example will fetch basic information and information about the
- related anime of the visual novel with id = 17:
-</p>
-<pre>
- get vn basic,anime (id = 17)
-</pre>
-<p>
- The server will reply with a 'results' message, this message is followed by a
- JSON object describing the results. This object has three members: 'num', which
- is an integer indicating the number of results returned, 'more', which is true
- when there are more results available (i.e. increasing the <i>page</i> option
- described above will give new results) and 'items', which contains the results
- as an array of objects. For example, the server could reply to the previous
- command with the following message:
-</p>
-<pre>
- results {"num":1, "more":false, "items":[{
- "id": 17, "title": "Ever17 -the out of infinity-", "original": null,
- "released": "2002-08-29", "languages": ["en","ja","ru","zh"],
- "platforms": ["drc","ps2","psp","win"],"anime": []
- }]}
-</pre>
-<p>
- Note that the actual result from the server can (and likely will) be formatted
- differently and that the order of the members may not be the same. What each
- member means and what possible values they can have differs per type and is
- documented below.
-</p>
-
-:SUBSUB:get vn
-<p>The following members are returned from a 'get vn' command:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>-</td>
- <td>integer</td>
- <td>no</td>
- <td>Visual novel ID</td>
- </tr>
- <tr>
- <td>title</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>Main title</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>Original/official title.</td>
- </tr>
- <tr>
- <td>released</td>
- <td>basic</td>
- <td>date (string)</td>
- <td>yes</td>
- <td>Date of the first release.</td>
- </tr>
- <tr class="odd">
- <td>languages</td>
- <td>basic</td>
- <td>array of strings</td>
- <td>no</td>
- <td>Can be an empty array when nothing has been released yet.</td>
- </tr>
- <tr>
- <td>orig_lang</td>
- <td>basic</td>
- <td>array of strings</td>
- <td>no</td>
- <td>Language(s) of the first release. Can be an empty array.</td>
- </tr>
- <tr class="odd">
- <td>platforms</td>
- <td>basic</td>
- <td>array of strings</td>
- <td>no</td>
- <td>Can be an empty array when unknown or nothing has been released yet.</td>
- </tr>
- <tr>
- <td>aliases</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Aliases, separated by newlines.</td>
- </tr>
- <tr class="odd">
- <td>length</td>
- <td>details</td>
- <td>integer</td>
- <td>yes</td>
- <td>Length of the game, 1-5</td>
- </tr>
- <tr>
- <td>description</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Description of the VN. Can include formatting codes as described in <a href="/d9.3">d9.3</a>.</td>
- </tr>
- <tr class="odd">
- <td>links</td>
- <td>details</td>
- <td>object</td>
- <td>no</td>
- <td>
- Contains the following members:<br />
- "wikipedia", string, name of the related article on the English Wikipedia.<br />
- "encubed", string, the URL-encoded tag used on <a href="http://novelnews.net/">encubed</a>.<br />
- "renai", string, the name part of the url on <a href="http://renai.us/">renai.us</a>.<br />
- All members can be <b>null</b> when no links are available or known to us.
- </td>
- </tr>
- <tr>
- <td>image</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>HTTP link to the VN image.</td>
- </tr>
- <tr class="odd">
- <td>image_nsfw</td>
- <td>details</td>
- <td>boolean</td>
- <td>no</td>
- <td>Whether the VN image is flagged as NSFW or not.</td>
- </tr>
- <tr>
- <td>anime</td>
- <td>anime</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- (Possibly empty) list of anime related to the VN, each object has the following members:<br />
- "id", integer, <a href="http://anidb.net/">AniDB</a> ID<br />
- "ann_id", integer, <a href="http://animenewsnetwork.com/">AnimeNewsNetwork</a> ID<br />
- "nfo_id", string, <a href="http://animenfo.com/">AnimeNfo</a> ID<br />
- "title_romaji", string<br />
- "title_kanji", string<br />
- "year", integer, year in which the anime was aired<br />
- "type", string<br />
- All members except the "id" can be <b>null</b>. Note that this data is courtesy of AniDB,
- and may not reflect the latest state of their information due to caching.
- </td>
- </tr>
- <tr class="odd">
- <td>relations</td>
- <td>relations</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- (Possibly empty) list of related visual novels, each object has the following members:<br />
- "id", integer<br />
- "relation", string, relation to the VN<br />
- "title", string, (romaji) title<br />
- "original", string, original/official title, can be <b>null</b><br />
- "official", boolean.
- </td>
- </tr>
- <tr>
- <td>tags</td>
- <td>tags</td>
- <td>array of arrays</td>
- <td>no</td>
- <td>
- (Possibly empty) list of tags linked to this VN. Each tag is represented as
- an array with three elements:<br />
- tag id (integer),<br />
- score (number between 0 and 3),<br />
- spoiler level (integer, 0=none, 1=minor, 2=major)<br />
- Only tags with a positive score are included. Note that this list may be
- relatively large - more than 50 tags for a VN is quite possible.<br />
- General information for each tag is available in the <a href="/d14.2">tags
- dump</a>. Keep in mind that it is possible that a tag has only recently been
- added and is not available in the dump yet, though this doesn't happen
- often.
- </td>
- </tr>
- <tr class="odd">
- <td>popularity</td>
- <td>stats</td>
- <td>number</td>
- <td>no</td>
- <td>Between 0 (unpopular) and 100 (most popular).</td>
- </tr>
- <tr>
- <td>rating</td>
- <td>stats</td>
- <td>number</td>
- <td>no</td>
- <td>Bayesian rating, between 1 and 10.</td>
- </tr>
- <tr class="odd">
- <td>votecount</td>
- <td>stats</td>
- <td>integer</td>
- <td>no</td>
- <td>Number of votes.</td>
- </tr>
- <tr>
- <td>screens</td>
- <td>screens</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- (Possibly empty) list of screenshots, each object has the following members:<br />
- "image", string, URL of the full-size screenshot<br />
- "rid", integer, release ID<br />
- "nsfw", boolean<br />
- "height", integer, height of the full-size screenshot<br />
- "width", integer, width of the full-size screenshot
- </td>
- </tr>
- <tr class="odd">
- <td>staff</td>
- <td>staff</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- (Possibly empty) list of staff related to the VN, each object has the following members:<br />
- "sid", integer, staff ID<br />
- "aid", integer, alias ID<br />
- "name", string<br />
- "original", string, possibly null<br />
- "role", string<br />
- "note", string, possibly null
- </td>
- </tr>
-</table>
-<p>Sorting is possible on the following fields: id, title, released, popularity, rating, votecount.</p><br />
-
-<p>'get vn' accepts the following filter expressions:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &gt;= &lt; &lt;=<br />= !=</td>
- <td>
- When you need to fetch info about multiple VNs, it is recommended to do so
- in one command using an array of integers as value. e.g. (id = [7,11,17]).
- </td>
- </tr>
- <tr>
- <td>title</td>
- <td>string</td>
- <td>= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>null<br />string</td>
- <td>= !=<br />= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>firstchar</td>
- <td>null<br />string</td>
- <td>= !=<br />= !=</td>
- <td>
- Filter by the first character of the title, similar to the
- <a href="http://vndb.org/v/all">VN browser interface</a>. The character
- must either be a lowercase 'a' to 'z', or null to match all titles not
- starting with an alphabetic character.
- </td>
- </tr>
- <tr class="odd">
- <td>released</td>
- <td>null<br />date (string)</td>
- <td>= !=<br />= != &gt; &gt;= &lt; &lt;=</td>
- <td>
- Note that matching on partial dates (released = "2009") doesn't do what
- you want, use ranges instead, e.g. (released &gt; "2008" and released &lt;= "2009").
- </td>
- </tr>
- <tr>
- <td>platforms</td>
- <td>null<br />string<br />array of strings</td>
- <td><br />= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>languages</td>
- <td>null<br />string<br />array of strings</td>
- <td><br />= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>orig_lang</td>
- <td>string<br />array of strings</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>search</td>
- <td>string</td>
- <td>~</td>
- <td>
- This is not an actual field, but performs a search on the titles of the visual
- novel and its releases. Note that the algorithm of this search may change and
- that it can use a different algorithm than the search function on the website.
- </td>
- </tr>
- <tr>
- <td>tags</td>
- <td>int<br />array of ints</td>
- <td>= !=</td>
- <td>
- Find VNs by tag. When providing an array of ints, the '=' filter will return
- VNs that are linked to any (not all) of the given tags, the '!=' filter will
- return VNs that are not linked to any of the given tags. You can combine
- multiple tags filters with 'and' and 'or' to get the exact behavior you
- need.<br />
- This filter may used cached data, it may take up to 24 hours
- before a VN will have its tag updated with respect to this filter.<br />
- VNs that are linked to childs of the given tag are also included.<br />
- Be warned that this filter ignores spoiler settings, fetch the tags
- associated with the returned VN to verify the spoiler level.
- </td>
- </tr>
-</table>
-
-:SUBSUB:get release
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>-</td>
- <td>integer</td>
- <td>no</td>
- <td>Release ID</td>
- </tr>
- <tr>
- <td>title</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>Release title (romaji)</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>Original/official title of the release.</td>
- </tr>
- <tr>
- <td>released</td>
- <td>basic</td>
- <td>date (string)</td>
- <td>yes</td>
- <td>Release date</td>
- </tr>
- <tr class="odd">
- <td>type</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>"complete", "partial" or "trial"</td>
- </tr>
- <tr>
- <td>patch</td>
- <td>basic</td>
- <td>boolean</td>
- <td>no</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>freeware</td>
- <td>basic</td>
- <td>boolean</td>
- <td>no</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>doujin</td>
- <td>basic</td>
- <td>boolean</td>
- <td>no</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>languages</td>
- <td>basic</td>
- <td>array of strings</td>
- <td>no</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>website</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Official website URL</td>
- </tr>
- <tr class="odd">
- <td>notes</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Random notes, can contain formatting codes as described in <a href="/d9.3">d9.3</a></td>
- </tr>
- <tr>
- <td>minage</td>
- <td>details</td>
- <td>integer</td>
- <td>yes</td>
- <td>Age rating, 0 = all ages.</td>
- </tr>
- <tr class="odd">
- <td>gtin</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>JAN/UPC/EAN code. This is actually an integer, but formatted as a string to avoid an overflow on 32bit platforms.</td>
- </tr>
- <tr>
- <td>catalog</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Catalog number.</td>
- </tr>
- <tr class="odd">
- <td>platforms</td>
- <td>details</td>
- <td>array of strings</td>
- <td>no</td>
- <td>Empty array when platform is unknown.</td>
- </tr>
- <tr>
- <td>media</td>
- <td>details</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- Objects have the following two members:<br />
- "medium", string<br />
- "qty", integer, the quantity. <b>null</b> when it is not applicable for the medium.<br />
- An empty array is returned when the media are unknown.
- </td>
- </tr>
- <tr class="odd">
- <td>resolution</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td></td>
- </tr>
- <tr>
- <td>voiced</td>
- <td>details</td>
- <td>integer</td>
- <td>yes</td>
- <td>1 = Not voiced, 2 = Only ero scenes voiced, 3 = Partially voiced, 4 = Fully voiced</td>
- </tr>
- <tr class="odd">
- <td>animation</td>
- <td>details</td>
- <td>array of integers</td>
- <td>no</td>
- <td>
- The array has two integer members, the first one indicating the story
- animations, the second the ero scene animations. Both members can be null
- if unknown or not applicable.<br />
- <br />
- When not null, the number indicates the following: 1 = No animations, 2 =
- Simple animations, 3 = Some fully animated scenes, 4 = All scenes fully
- animated.
- </td>
- </tr>
- <tr>
- <td>vn</td>
- <td>vn</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- Array of visual novels linked to this release. Objects have the following members:
- id, title and original. These are the same as the members of the "get vn" command.
- </td>
- </tr>
- <tr class="odd">
- <td>producers</td>
- <td>producers</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- (Possibly empty) list of producers involved in this release. Objects have the following members:<br />
- "id", integer<br />
- "developer", boolean,<br />
- "publisher", boolean,<br />
- "name", string, romaji name<br />
- "original", string, official/original name, can be <b>null</b><br />
- "type", string, producer type
- </td>
- </tr>
-</table>
-<p>Sorting is possible on the 'id', 'title' and 'released' fields.</p><br />
-
-<p>Accepted filters:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &gt;= &lt; &lt;=<br />= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>integer<br />array of integers</td>
- <td>= !=</td>
- <td>Find releases linked to the given visual novel ID.</td>
- </tr>
- <tr class="odd">
- <td>producer</td>
- <td>integer</td>
- <td>=</td>
- <td>Find releases linked to the given producer ID.</td>
- </tr>
- <tr>
- <td>title</td>
- <td>string</td>
- <td>= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>null<br />string</td>
- <td>= !=<br />= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>released</td>
- <td>null<br />date (string)</td>
- <td>= !=<br />= != &gt; &gt;= &lt; &lt;=</td>
- <td>Note about released filter for the vn type also applies here.</td>
- </tr>
- <tr class="odd">
- <td>patch</td>
- <td>boolean</td>
- <td>=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>freeware</td>
- <td>boolean</td>
- <td>=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>doujin</td>
- <td>boolean</td>
- <td>=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>type</td>
- <td>string</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>gtin</td>
- <td>int</td>
- <td>= !=</td>
- <td>Value can also be escaped as a string (if you risk an integer overflow otherwise)</td>
- </tr>
- <tr>
- <td>catalog</td>
- <td>string</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>languages</td>
- <td>string<br />array of strings</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>platforms</td>
- <td>string<br />array of strings</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
-</table>
-
-:SUBSUB:get producer
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>-</td>
- <td>integer</td>
- <td>no</td>
- <td>Producer ID</td>
- </tr>
- <tr>
- <td>name</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>(romaji) producer name</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>Original/official name</td>
- </tr>
- <tr>
- <td>type</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>Producer type</td>
- </tr>
- <tr class="odd">
- <td>language</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>Primary language</td>
- </tr>
- <tr>
- <td>links</td>
- <td>details</td>
- <td>object</td>
- <td>no</td>
- <td>
- External links, object has the following members:<br />
- "homepage", official homepage,<br />
- "wikipedia", title of the related article on the English wikipedia.<br />
- Both values can be <b>null</b>.
- </td>
- </tr>
- <tr class="odd">
- <td>aliases</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>List of alternative names, separated by a newline</td>
- </tr>
- <tr>
- <td>description</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Description/notes of the producer, can contain formatting codes as described in <a href="/d9.3">d9.3</a></td>
- </tr>
- <tr class="odd">
- <td>relations</td>
- <td>relations</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- (possibly empty) list of related producers, each object has the following members:<br />
- "id", integer, producer ID,<br />
- "relation", string, relation to the current producer,<br />
- "name", string,<br />
- "original", string, can be <b>null</b>
- </td>
- </tr>
-</table>
-<p>Sorting is possible on the 'id' and 'name' fields.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &gt;= &lt; &lt;=<br />= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>name</td>
- <td>string</td>
- <td>= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>null<br />string</td>
- <td>= !=<br />= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>type</td>
- <td>string</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>language</td>
- <td>string<br />array of strings</td>
- <td>= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>search</td>
- <td>string</td>
- <td>~</td>
- <td>Not an actual field. Performs a search on the name, original and aliases fields.</td>
- </tr>
-</table>
-
-:SUBSUB:get character
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>-</td>
- <td>integer</td>
- <td>no</td>
- <td>Character ID</td>
- </tr>
- <tr>
- <td>name</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>(romaji) name</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>Original (kana/kanji) name</td>
- </tr>
- <tr>
- <td>gender</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>"m" (male), "f" (female) or "b" (both)</td>
- </tr>
- <tr class="odd">
- <td>bloodt</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>Blood type, "a", "b", "ab" or "o"</td>
- </tr>
- <tr>
- <td>birthday</td>
- <td>basic</td>
- <td>array</td>
- <td>no</td>
- <td>
- Array of two numbers: day of the month (1-31) and the month (1-12). Either can be null.
- </td>
- </tr>
- <tr class="odd">
- <td>aliases</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Alternative names, separated with a newline.</td>
- </tr>
- <tr>
- <td>description</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Description/notes, can contain formatting codes as described in <a href="/d9.3">d9.3</a>. May also include [spoiler] tags!</td>
- </tr>
- <tr class="odd">
- <td>image</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>HTTP link to the character image. Always (supposed to be) SFW.</td>
- </tr>
- <tr>
- <td>bust</td>
- <td>meas</td>
- <td>integer</td>
- <td>yes</td>
- <td>cm</td>
- </tr>
- <tr class="odd">
- <td>waist</td>
- <td>meas</td>
- <td>integer</td>
- <td>yes</td>
- <td>cm</td>
- </tr>
- <tr>
- <td>hip</td>
- <td>meas</td>
- <td>integer</td>
- <td>yes</td>
- <td>cm</td>
- </tr>
- <tr class="odd">
- <td>height</td>
- <td>meas</td>
- <td>integer</td>
- <td>yes</td>
- <td>cm</td>
- </tr>
- <tr>
- <td>weight</td>
- <td>meas</td>
- <td>integer</td>
- <td>yes</td>
- <td>kg</td>
- </tr>
- <tr class="odd">
- <td>traits</td>
- <td>traits</td>
- <td>array of arrays</td>
- <td>no</td>
- <td>(Possibly empty) list of traits linked to this character. Each trait is
- represented as an array of two elements: The trait id (integer) and the
- spoiler level (integer, 0-2). General information for each trait is
- available in the <a href="/d14.3">traits dump</a>.</td>
- </tr>
- <tr>
- <td>vns</td>
- <td>vns</td>
- <td>array of arrays</td>
- <td>no</td>
- <td>List of VNs linked to this character. Each VN is an array of 4 elements:
- VN id, release ID (0 = "all releases"), spoiler level (0-2) and the role
- (string).<br />
- Available roles: "main", "primary", "side" and "appears".</td>
- </tr>
- <tr class="odd">
- <td>voiced</td>
- <td>voiced</td>
- <td>array of objects</td>
- <td>no</td>
- <td>List of voice actresses (staff) that voiced this character, per VN. Each
- staff/VN is represented as a object with the following members:<br />
- "id", integer, staff ID<br />
- "aid", integer, the staff alias ID being used<br />
- "vid", integer, VN id<br />
- "note", string<br />
- The same voice actor may be listed multiple times if this entry is
- character to multiple visual novels. Similarly, the same visual novel may
- be listed multiple times if this character has multiple voice actors in the
- same VN.
- </td>
- </tr>
-</table>
-<p>Sorting is possible on the 'id' and 'name' fields.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &gt;= &lt; &lt;=<br />= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>name</td>
- <td>string</td>
- <td>= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>null<br />string</td>
- <td>= !=<br />= != ~</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>search</td>
- <td>string</td>
- <td>~</td>
- <td>Not an actual field. Performs a search on the name, original and aliases fields.</td>
- </tr>
- <tr class="odd">
- <td>vn</td>
- <td>integer<br />array of integers</td>
- <td>=</td>
- <td>Find characters linked to the given visual novel ID(s). Note that this
- may also include characters that are normally hidden by spoiler settings.
- </td>
- </tr>
- <tr>
- <td>traits</td>
- <td>int<br />array of ints</td>
- <td>= !=</td>
- <td>
- Find chars by traits. When providing an array of ints, the '=' filter will return
- chars that are linked to any (not all) of the given traits, the '!=' filter will
- return chars that are not linked to any of the given traits. You can combine
- multiple trait filters with 'and' and 'or' to get the exact behavior you
- need.<br />
- This filter may used cached data, it may take up to 24 hours
- before a char entry will have its traits updated with respect to this filter.<br />
- Chars that are linked to childs of the given trait are also included.<br />
- Be warned that this filter ignores spoiler settings, fetch the traits
- associated with the returned char to verify the spoiler level.
- </td>
- </tr>
-</table>
-
-
-:SUBSUB:get staff
-<p>
-Unlike other database entries, staff have more than one unique identifier.<br />
-There is the main 'staff ID', which uniquely identifies a person and is what
-the staff pages on the site represent.<br />
-Additionally, every staff name and alias also has its own unique identifier,
-which is referenced from other database entries to identify which alias was
-used. This identifier is generally hidden on the site and aliases do not have
-their own page, but the IDs are exposed in this API in order to facilitate
-linking between VNs/characters and staff.<br />
-<br />
-Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>-</td>
- <td>integer</td>
- <td>no</td>
- <td>Staff ID</td>
- </tr>
- <tr>
- <td>name</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>Primary (romaji) staff name</td>
- </tr>
- <tr class="odd">
- <td>original</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>Primary original name</td>
- </tr>
- <tr>
- <td>gender</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td></td>
- </tr>
- <tr class="odd">
- <td>language</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td>Primary language</td>
- </tr>
- <tr>
- <td>links</td>
- <td>details</td>
- <td>object</td>
- <td>no</td>
- <td>
- External links, object has the following members:<br />
- "homepage", official homepage,<br />
- "wikipedia", title of the related article on the English wikipedia.<br />
- "twitter", name of the twitter account.<br />
- "anidb", <a href="http://anidb.net/">AniDB</a> creator ID.<br />
- All values can be <b>null</b>.
- </td>
- </tr>
- <tr class="odd">
- <td>description</td>
- <td>details</td>
- <td>string</td>
- <td>yes</td>
- <td>Description/notes of the staff, can contain formatting codes as described in <a href="/d9.3">d9.3</a></td>
- </tr>
- <tr>
- <td>aliases</td>
- <td>aliases</td>
- <td>array of arrays</td>
- <td>no</td>
- <td>
- List of names and aliases. Each name is represented as an array with the
- following elements: Alias ID, name (romaji) and the original name.<br />
- This list also includes the "primary" name.
- </td>
- </tr>
- <tr class="odd">
- <td>main_alias</td>
- <td>aliases</td>
- <td>integer</td>
- <td>no</td>
- <td>ID of the alias that is the "primary" name of the entry</td>
- </tr>
- <tr>
- <td>vns</td>
- <td>vns</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- List of visual novels that this staff entry has been credited in (excluding
- character voicing). Each vn is represented as an object with the following
- members:<br />
- "id", integer, visual novel id<br />
- "aid", integer, alias ID of this staff entry<br />
- "role", string<br />
- "note", string, may be null if unset<br />
- The same VN entry may appear multiple times if the staff has been credited
- for multiple roles.
- </td>
- </tr>
- <tr class="odd">
- <td>voiced</td>
- <td>voiced</td>
- <td>array of objects</td>
- <td>no</td>
- <td>
- List of characters that this staff entry has voiced. Each object has the
- following members:<br />
- "id", integer, visual novel id<br />
- "aid", integer, alias ID of this staff entry<br />
- "cid", integer, character ID<br />
- "note", string, may be null if unset<br />
- The same VN entry may appear multiple times if the staff has been credited
- for multiple characters. Similarly, the same character may appear multiple
- times if it has been linked to multiple VNs.
- </td>
- </tr>
-</table>
-<p>Sorting is possible on the 'id' field.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &gt;= &lt; &lt;=<br />= !=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>aid</td>
- <td>integer<br />array of integers</td>
- <td>=<br />=</td>
- <td>&nbsp;</td>
- </tr>
- <tr>
- <td>search</td>
- <td>string</td>
- <td>~</td>
- <td>Searched through all aliases, both the romanized and original names.</td>
- </tr>
-</table>
-
-
-:SUBSUB:get user
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>User ID</td>
- </tr>
- <tr>
- <td>username</td>
- <td>basic</td>
- <td>string</td>
- <td>no</td>
- <td></td>
- </tr>
-</table>
-<p>The returned list is always sorted on the 'id' field.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer<br />array of integers</td>
- <td>=</td>
- <td>The special value '0' is recognized as the currently logged in user.</td>
- </tr>
- <tr>
- <td>username</td>
- <td>string<br />array of strings</td>
- <td>= != ~<br />=</td>
- <td></td>
- </tr>
-</table>
-
-
-:SUBSUB:get votelist
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>uid</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>User ID</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>Visual Novel ID</td>
- </tr>
- <tr class="odd">
- <td>vote</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>In the range of 10 (lowest) to 100 (highest). These are displayed on the site as a fractional number between 1 and 10.</td>
- </tr>
- <tr>
- <td>added</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>Unix timestamp of when this vote has been added.</td>
- </tr>
-</table>
-<p>The returned list is always sorted on the 'vn' field.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>uid</td>
- <td>integer</td>
- <td>=</td>
- <td>The special value '0' is recognized as the currently logged in user.</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &lt; &gt;= &lt;=<br />= !=</td>
- <td>Visual novel ID.</td>
- </tr>
-</table>
-<p>
- Note: It's possible that a user has voted on a VN that has been deleted. The
- vote is still included this list, but a 'get vn' command on its id will not
- return anything.<br />
- Note#2: This command will not return any results for users who have their vote
- list hidden from the public in their preferences, except when the user itself
- has logged into the API.
-</p>
-
-:SUBSUB:get vnlist
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>uid</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>User ID</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>Visual Novel ID</td>
- </tr>
- <tr class="odd">
- <td>status</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>0=Unknown, 1=playing, 2=finished, 3=stalled, 4=dropped.</td>
- </tr>
- <tr>
- <td>added</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>Unix timestamp of when this item has been added.</td>
- </tr>
- <tr class="odd">
- <td>notes</td>
- <td>basic</td>
- <td>string</td>
- <td>yes</td>
- <td>User-set notes</td>
- </tr>
-</table>
-<p>The returned list is always sorted on the 'vn' field.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>uid</td>
- <td>integer</td>
- <td>=</td>
- <td>The special value '0' is recognized as the currently logged in user.</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &lt; &gt;= &lt;=<br />= !=</td>
- <td>Visual novel ID.</td>
- </tr>
-</table>
-<p>The notes mentioned under 'get votelist' also apply here.</p>
-
-:SUBSUB:get wishlist
-<p>Returned members:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 50px">Flag</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>uid</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>User ID</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>Visual Novel ID</td>
- </tr>
- <tr class="odd">
- <td>priority</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>0=high, 1=medium, 2=low, 3=blacklist.</td>
- </tr>
- <tr>
- <td>added</td>
- <td>basic</td>
- <td>integer</td>
- <td>no</td>
- <td>Unix timestamp of when this item has been added.</td>
- </tr>
-</table>
-<p>The returned list is always sorted on the 'vn' field.</p><br />
-
-<p>The following filters are recognised:</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Value</td>
- <td style="width: 90px">Operators</td>
- <td>&nbsp;</td>
- </tr></thead>
- <tr class="odd">
- <td>uid</td>
- <td>integer</td>
- <td>=</td>
- <td>The special value '0' is recognized as the currently logged in user.</td>
- </tr>
- <tr>
- <td>vn</td>
- <td>integer<br />array of integers</td>
- <td>= != &gt; &lt; &gt;= &lt;=<br />= !=</td>
- <td>Visual novel ID.</td>
- </tr>
-</table>
-<p>The notes mentioned under 'get votelist' also apply here.</p>
-
-
-:SUB:The 'set' command
-<p>
- The set command can be used to modify stuff in the database. It can only be
- used when logged in as a user. The command has the following syntax:
-</p>
-<pre>
- set <b class="standout">type id fields</b>
-</pre>
-<p>
- Here, <i>type</i> is similar to the type argument to the 'get' command,
- <i>id</i> is the (integer) identifier of the database entry to change, and
- <i>fields</i> is an object with the fields to set or modify. If the
- <i>fields</i> object is not present, the set command works as a 'delete'. The
- interpretation of the <i>id</i> and <i>fields</i> arguments depend on the
- <i>type</i>, and are documented in the sections below.<br />
- <br />
- But before that, let me present some examples to get a feel on what the
- previous paragraph meant. The following example adds a '10' vote on <a
- href="/v17">v17</a>, or changes the vote to a 10 if a previous vote was
- already present:
-</p>
-<pre>
- set votelist 17 {"vote":100}
-</pre>
-<p>And here's how to remove the previous vote:</p>
-<pre>
- set votelist 17
-</pre>
-<p>
- 'set' replies with a simple 'ok' on success, or with an 'error' (see below) on
- failure. Note that, due to my laziness, no error is currently returned if the
- identifier does not exist. So voting on a VN that does not exist will return
- an 'ok', but no vote is actually added. This behaviour may change in the
- future. Note that this API doesn't care whether the VN has been deleted or
- not, so you can manage votes and stuff for deleted VNs (Which isn't very
- helpful, because 'get vn' won't return a thing for deleted VNs).
-</p>
-
-:SUBSUB:set votelist
-<p>
- This command facilitates adding, removing and modifying votes. The
- <i>identifier</i> argument is the visual novel ID, and the following fields
- are recognized:
-</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Type</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>vote</td>
- <td>integer</td>
- <td>Same as the 'vote' member returned by 'get votelist', in the range 10 to 100. This field has no default; it must always be present.</td>
- </tr>
-</table>
-<p>
- The 'added' member returned by 'get votelist' is, as its name implies, only
- set when the vote is added. Changing an existing vote will not update the
- 'added' field.
-</p>
-
-:SUBSUB:set vnlist
-<p>
- This command facilitates adding, removing and modifying your VN list. The
- <i>identifier</i> argument is the visual novel ID, and the following fields
- are recognized:
-</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Type</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>status</td>
- <td>integer</td>
- <td>Same as the 'status' member returned by 'get vnlist'. Default: 0</td>
- </tr>
- <tr>
- <td>notes</td>
- <td>string</td>
- <td>Same as the 'notes' member returned by 'get vnlist'. An empty string is considered equivalent to 'null'. A newline is currently not allowed because the web interface won't handle them well. Default: null.</td>
- </tr>
-</table>
-<p>
- Sames notes about the 'added' member for 'set votelist' applies here.<br />
- Also note that, when removing a vnlist item, any releases associated with the
- VN will be removed from the users' list as well. The release list
- functionality is not currently exposed to the API, so this will only be
- visible when the web interface is used.
-</p>
-
-:SUBSUB:set wishlist
-<p>
- This command facilitates adding, removing and modifying VNs from your
- wishlist. The <i>identifier</i> argument is the visual novel ID, and the
- following fields are recognized:
-</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Field</td>
- <td style="width: 90px">Type</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>priority</td>
- <td>integer</td>
- <td>Same as the 'priority' member returned by 'get wishlist'.</td>
- </tr>
-</table>
-<p>
- Sames notes about the 'added' member for 'set votelist' applies here.<br />
-</p>
-
-
-
-:SUB:The 'error' response
-<p>
- Every command to the server can receive an 'error' response, this response has one
- argument: a JSON object containing at least a member named "id", which identifies
- the error, and a "msg", which contains a human readable message explaining what
- went wrong. Other members are also possible, depending on the value of "id".
- Example error message:
-</p>
-<pre>
- error {"id":"parse", "msg":"Invalid command or argument"}
-</pre>
-<p>
- Note that the value of "msg" is not directly linked to the error identifier:
- the message explains what went wrong in more detail, there are several
- different messages for the same id. The following error identifiers are currently
- defined:
-</p>
-<dl>
- <dt>parse</dt><dd>Syntax error, unknown command or invalid argument type.</dd>
- <dt>missing</dt><dd>A JSON object argument is missing a required member. The name of which is given in the additional "field" member.</dd>
- <dt>badarg</dt><dd>A JSON value is of the wrong type or in the wrong format. The name of the incorrect field is given in a "field" member.</dd>
- <dt>needlogin</dt><dd>Need to be logged in to issue this command.</dd>
- <dt>throttled</dt><dd>
- You have used too many server resources within a short time, and need to wait
- a bit before sending the next command. The type of throttle is given in the
- "type" member, and the "minwait" and "fullwait" members tell you how long you
- need to wait before sending the next command and when you can start bursting
- again (this is the recommended waiting time), respectively. Both values are in
- seconds, with a precision of 0.1 seconds.
- </dd>
- <dt>auth</dt><dd>(login) Incorrect username/password combination.</dd>
- <dt>loggedin</dt><dd>(login) Already logged in. Only one successful login command can be issues on one connection.</dd>
- <dt>gettype</dt><dd>(get) Unknown type argument to the 'get' command.</dd>
- <dt>getinfo</dt><dd>(get) Unknown info flag to the 'get' command. The name of the unrecognised flag is given in an additional "flag" member.</dd>
- <dt>filter</dt><dd>(get) Unknown filter field or invalid combination of field/operator/argument type. Includes three additional members: "field", "op" and "value" of the incorrect expression.</dd>
- <dt>settype</dt><dd>(set) Unknown type argument to the 'set' command.</dd>
-</dl>
-
-
-
-:SUB:Change Log
-<p>
- This section lists the changes made in each version of the VNDB code.
- Check out the <a href="/t/an">announcements board</a> for more information about updates.
- <br /><br />
-</p>
-<b>2018-02-07</b>
-<ul>
- <li>The 'aliases' member for "get producer" is now uses newline as separation rather than a comma</li>
-</ul>
-<b>2017-08-14</b>
-<ul>
- <li>Add 'uid' field to "get votelist/vnlist/wishlist" commands</li>
- <li>Add 'vn' filter to the same commands</li>
- <li>The 'uid' filter for these commands is now optional, making it possible to find all list entries for a particular VN</li>
-</ul>
-<b>2017-06-21</b>
-<ul>
- <li>Add "resolution", "voiced", "animation" members to "get release" command</li>
- <li>Add "platforms" filter to "get release" command</li>
- <li>Accept arrays for the "vn" filter to the "get release" command</li>
- <li>Add "search" filter to "get staff"</li>
-</ul>
-<b>2017-05-22</b>
-<ul>
- <li>Add "vns" and "voiced" flags to "get staff" command</li>
- <li>Add "voiced" flag to "get character" command</li>
-</ul>
-<b>2017-04-28</b> <b class="grayedout">because screw version numbers</b>
-<ul>
- <li>Add "get staff" command</li>
- <li>Add "staff" flag to "get vn" command</li>
-</ul>
-<b>2.27</b>
-<ul>
- <li>Add "username" filter to "get user"</li>
- <li>Add "traits" filter to "get character"</li>
-</ul>
-<b>2.25</b>
-<ul>
- <li>Add "tags" filter to "get vn"</li>
- <li>Increased connection limit per IP from 5 to 10</li>
- <li>Increased command limit from 100 to 200 commands per 10 minutes</li>
- <li>Added support for TLS</li>
- <li>Added "screens" flag and member to "get vn"</li>
- <li>Added "vns" flag and member to "get character"</li>
- <li>Allow sorting "get vn" on popularity, rating and votecount</li>
- <li>Added basic "get user" command</li>
- <li>Added "official" field to "get vn relations"</li>
-</ul>
-<b>2.23</b>
-<ul>
- <li>Added new 'dbstats' command</li>
- <li>Added new 'get' types: character, votelist, vnlist and wishlist</li>
- <li>Added 'set' command, with types: votelist, vnlist and wishlist</li>
- <li>New error id: 'settype'</li>
- <li>Added "tags" flag and member to "get vn"</li>
- <li>Added "stats" flag to "get vn"</li>
- <li>Added "firstchar" filter to "get vn"</li>
- <li>Added "vn" filter to "get character"</li>
-</ul>
-<b>2.15</b>
-<ul>
- <li>Fixed a bug with the server not allowing extra whitespace after a "get .. " command</li>
- <li>Allow non-numbers as "clientver" for the login command</li>
- <li>Added "image_nsfw" member to "get vn"</li>
- <li>Added "results" option to the "get .. {<options>}"</li>
- <li>Increased the maximum number of results for the "get .." command to 25</li>
- <li>Added "orig_lang" member and filter to the "get vn .." command</li>
- <li>Throttle the commands and sqltime per IP instead of per user</li>
- <li>Removed the limit on the number of open sessions per user</li>
- <li>Allow the API to be used without logging in with a username/password</li>
-</ul>
-<b>2.12</b>
-<ul>
- <li>Added "image" member to "get vn"</li>
- <li>A few minor fixes in some error messages</li>
- <li>Switched to a different (and faster) search algorithm for "get vn .. (search ~ ..)"</li>
-</ul>
-
diff --git a/data/docs/12 b/data/docs/12
deleted file mode 100644
index 8149343e..00000000
--- a/data/docs/12
+++ /dev/null
@@ -1,190 +0,0 @@
-:TITLE:Adding/Editing Characters
-:INC:index
-
-
-:SUB:Introduction
-<p>
- Characters represent persons, animals and things within a visual novel. Any
- character in a visual novel, no matter how obscure their role is, may be added
- to the database, although it is recommended to at least add the more important
- characters first. When adding characters, try to be complete: That is, try to
- add as many characters of a single visual novel, rather than adding a single
- character to many VNs.
-</p>
-
-
-:SUB:Instances
-<p>
-You can link two (or more) characters with an "instance relationship" when they are, in some way, the same person.
-</p>
-:SUBSUB: Where instances might be suitable
-<ul>
- <li>The two characters seemed to be different people, but were actually the same person.
- For example, <a href="/c7373">Arsene</a> and <a href="/c7374">Henriette</a>.</li>
- <li>One of the characters is an older version of the other.</li>
- <li>One character transforms into the other. There does not need to be a way for them to transform back.
- For example, <a href="/c1022">Kaoru (Male)</a> and <a href="/c1023">Kaoru (Female)</a>.</li>
- <li>The two characters are the same character in different universes, timelines or realities.
- For example, Tohsaka Rin <a href="/c34">in Fate/stay night</a> and in <a href="/c3529">in Fate/extra</a>.</li>
- <li>The two characters are the same character used by different developers. This may result in different interpretations of the character or different art styles.
- For example, Emiya Shirou <a href="/c15">in Fate/stay night</a> and in <a href="/c4479">in Happy Valentines Day</a>.</li>
- <li>Spoilers about the character need to be hidden. This may be done by
- creating a character entry with incorrect or incomplete, but non-spoiling
- information. This is linked to another entry for the same character with
- complete, but spoiling information.</li>
-</ul>
-
-:SUBSUB:Where instances might not be suitable
-<ul>
- <li>It is preferable to avoid using instances just to hide spoilers if other
- methods would be effective. These methods include marking traits as spoilers
- and hiding information within spoiler tags in the character description.</li>
- <li>If the two characters to be linked by an instance are not sufficiently
- different, they should just use one character entry.
- For example, <a href="/c4287">Alice (lamia)</a> and <a href="http://s.vndb.org/sf/26/18226.jpg">Alice (human)</a>.</li>
-</ul>
-
-:SUBSUB:How to use instances
-<p>
-To link two (or more) characters with an instance relationship, you must choose
-one character to be the "main character". All others will be "instance
-characters". (Do not confuse this with a character's role in a visual novel.)
-Usually, the most often seen or least spoiling character should be the "main
-character".<br />
-Do not fill the "Instance of" field when editing the "main character", but fill
-it for the "instance characters". If the instance relation is a spoiler, make
-sure to mark it as such when editing the "instance characters". If the
-existence of a character in a visual novel is a spoiler, see the <a
-href="/d12#6">Visual Novels</a> section below.
-</p>
-
-
-:SUB:General info
-<dl>
- <dt>Name (romaji)</dt><dd>
- Name of the character, in the latin alphabet. Check out the <a
- href="/d5">general editing guidelines</a> for information on name order and
- romanization. Try to use the full name when known. If the full name is not
- known, then use either the first or last name. If even that isn't known, use
- the name that is most commonly used to refer to this character in the story.
- In the case the character is never referred to with a name or title (e.g.
- it's the protagonist), "Unnamed" can be used as name.<br />
- In some cases the full name is a spoiler, see the chapter on instances above
- for some ways to handle that.
- </dd><dt>Original name</dt><dd>
- The actual name of the character, in the case it is not officially in the
- latin alphabet. Leave empty if it's the same as the "Name (romaji)". If
- possible, try to include a space between the given name and the surname.
- </dd><dt>Aliases</dt><dd>
- Other names this character is known by, such as nick names used by other
- characters within the story. Since this field does not have any option to
- hide spoilers, you shouldn't include spoilery names here. It is possible to
- mention such aliases with a [spoiler] tag in the description.
- </dd><dt>Description</dt><dd>
- A short description of the character. While it is advised to keep the
- spoilers to a minimum, you can use the usual <a href="/d9.3">formatting
- codes</a> such as [spoiler] to include spoilers while hiding them by default.
- When using a description from external sources, check out the <a
- href="/d5.5">general editing guidelines</a> for quoting rules.
- </dd><dt>Gender</dt><dd>
- Gender of the character. This is usually rather straightforward, but there
- are some odd cases: (Reverse) traps should have their biological gender
- filled out here. Futanari should be marked as "both".<br />
- If the real gender is a spoiler, which is sometimes the case with traps,
- leave this field at "Unknown". See the chapter on instances above if the
- character "transforms" between a male and female version.
- </dd><dt>Birthday</dt><dd>
- Month and day of the character's birthday. Note that a year is not included.
- </dd><dt>Bust / Waist / Hips</dt><dd>
- <a href="http://en.wikipedia.org/wiki/BWH">BWH</a> measurements, if known.
- This information should either come from the game itself or from a reliable
- source (usually the official homepage). Don't try to guess these!<br />
- If the official source does not provide this information as a natural number,
- the number should rounded to allow its use in the database. If the official
- information is not in the metric system, convert the numbers and round them
- before entering.
- </dd><dt>Height</dt><dd>
- Height of the character, in cm. The above note on natural numbers and the
- metric system also applies here.
- </dd><dt>Weight</dt><dd>
- Weight of the character, in kg. The above note on natural numbers and the
- metric system also applies here.
- </dd><dt>Blood type</dt><dd>
- Blood type, if known and applicable. This makes little sense if the character
- isn't a human.
- </dd>
-</dl>
-
-
-:SUB:Image
-<p>
- There is a lot of freedom with regards to uploading an image to a character
- entry, but the following is a list of things to keep in mind:
-<ul>
- <li>The image must be "safe for work", according to the <a href="/d2#4">VN
- image guidelines</a>. You may add creative sensoring to make an image safe if
- otherwise no image for the character is available.</li>
- <li>The image must be official, i.e. it must be extracted from the VN itself
- or from the official homepage. Fan art is definitely not allowed!</li>
- <li>This image should be chosen from an image that is showing the most common
- clothing and facial expression the character wears through the game.</li>
- <li>Screenshots of the in-game sprites (tachi-e) are preferred, including any
- background art; Raw sprites or cuts from CGs are allowed, too.</li>
- <li>The image must at least include the head (assuming it has one) and
- shoulders of the character. Full-body shots are fine, but legs are generally
- not that interesting yet cause the overall image to shrink dramatically.</li>
- <li>The image will be cropped to 256x300, but it is recommended to do this
- cropping manually before uploading to ensure that all character images of the
- same VN have the same width. This consistency looks better on the character
- listing on the VN page.</li>
-</ul>
-
-
-:SUB:Traits
-<p>
- See the <a href="/d10">Tags &amp; traits</a> page for guidelines on the traits.
-</p>
-
-
-:SUB:Visual Novels
-<p>
- A character should always be linked to at least one visual novel entry, but may
- be linked with more when it appears in multiple visual novels.<br />
- If a character appears in all releases of the visual novel, with the possible
- exception of trial releases, then simply keep one release and leave it at "All
- / others". In other situations, mention explicitely in which releases the
- character appears and which role they have in that release. Multiple releases
- can be added with the same role and spoiler information.<br />
- If a characters' role or the entire existance of that character in the visual
- novel is a spoiler, make sure to mark it as such.<br />
- The following roles are available:
-</p>
-<dl>
- <dt>Protagonist</dt><dd>
- The (or "a") protagonist. The person through which the story is told. Note
- that a significant portion of the story has to be told through the eyes of
- the character for it to be considered a protagonist. Some visual novels may
- switch perspectives for a (relatively) short amount of time, but this does
- not always make the character a protagonist.
- </dd><dt>Main character</dt><dd>
- A character that plays a major role in the story or gets a lot of screen
- time. In general, a herione with an own route always qualifies and so do
- sidekicks/classmates that are very often seen.
- </dd><dt>Side character</dt><dd>
- A character that plays a minor role or does not get a lot of screen time.
- This is often the case for characters that appear only in a single branch or
- a single part of the story, although this is not a mandatory.
- </dd><dt>Makes an appearance</dt><dd>
- This role is used for characters that only appear in the story for a short
- while and have only very little to no lines of dialog. Often used for <a
- href="http://en.wikipedia.org/wiki/Cameo_appearance">cameo appearances</a>.
- </dd>
-</dl>
-<p>
- Note that there is no distinct line between these roles, and one could have
- endless (and often rather pointless) discussions about the actual role of a
- character. Simply assign the role that you think most naturally fits the
- character. To get some inspiration, look around for characters in other visual
- novels that play a somewhat similar role.
-</p>
-
diff --git a/data/docs/13 b/data/docs/13
deleted file mode 100644
index ca99365b..00000000
--- a/data/docs/13
+++ /dev/null
@@ -1,66 +0,0 @@
-:TITLE:How to Capture Screenshots
-
-:INC:index
-
-
-:SUB:Introduction
-Screenshots uploaded to VNDB must confirm to some strict guidelines. In
-particular, they should not have any window borders and must be in the correct
-resolution (precise to the pixel!). Uploading screenshots that do not confirm
-to these rules will likely result in them getting deleted shortly afterwards.
-This page is a tutorial on how to <b>correctly</b> capture screenshots using
-various tools.
-
-
-:SUB:IrfanView
-<ol>
- <li>Download and install Irfanview from <a
- href="http://www.irfanview.com/">irfanview.com</a>. Installation should be
- fairly straight-forward.</li>
- <li>Start Irfanview, you should get a window like <a
- href="https://s.vndb.org/sf/24/103524.jpg">this</a>.</li>
- <li>Hit the <i>C</i> key or go <i>Options -> Capture/Screenshot</i> to open
- the <a href="https://s.vndb.org/sf/26/103526.jpg">capture
- setup</a> window.</li>
- <li>Check the "Foreground window - client area" selection box. This
- option makes sure that you won't see any window borders and that the
- screenshot is already correctly cropped.</li>
- <li>Set a hot key. Irfanview uses Ctrl+F11 by default, but since the Ctrl
- is usually assigned to skipping in most games, you will probably want to
- change it. To do so, left-click on the key area and press the desired key
- combination. Alt+F11 should do the trick.</li>
- <li>Check the "Save captured image as file", choose a destination folder and
- select JPG in the "Save as" options.</li>
- <li>Click "Options" to open the <a
- href="https://s.vndb.org/sf/25/103525.jpg">JPEG save options</a>
- window</li>
- <li>Set the quality somewhere between 95 and 100.</li>
- <li>Press "OK", and then press "Start" to close the capture setup window.</li>
-</ol>
-<br />
-Now go to the visual novel you want to capture and press the configured hot key
-at the desired moment. Irfanview will automatically capture and save the
-screenshot in the chosen directory. These screenshots are suitable for
-uploading to VNDB without further modifications.
-
-
-:SUB:ShareX
-<ol>
- <li>Download and install ShareX from <a href="https://getsharex.com/downloads/">getsharex.com</a>.</li>
- <li>Start ShareX, you should then get a window like <a href="https://s.vndb.org/sf/63/103563.jpg">this</a>.</li>
- <li>Go to <a href="https://s.vndb.org/sf/66/103566.jpg">Task settings</a> and
- adjust your <a href="https://s.vndb.org/sf/62/103562.jpg">capture settings</a> and
- <a href="https://s.vndb.org/sf/61/103561.jpg">image settings</a>.</li>
- </li>
- <li>You can set a custom hotkey for window capture: Go to
- <a href="https://s.vndb.org/sf/71/103571.jpg">Hotkey settings</a> and change the
- <a href="https://s.vndb.org/sf/64/103564.jpg">default hotkey for window capture</a>.
- </li>
- <li>Change the <a href="https://s.vndb.org/sf/65/103565.jpg">After capture tasks</a> according to your preferences</a>.</li>
- <li>(Tip) If you want to change the directory where screenshots will be saved, go to <a href="https://s.vndb.org/sf/68/103568.jpg">Application settings</a> and <a href="https://s.vndb.org/sf/67/103567.jpg">follow these steps</a>.</li>
- <li>(Tip) You can change the naming pattern of the saved screenshots by going to the <a href="https://s.vndb.org/sf/69/103569.jpg">Task settings</a> and <a href="https://s.vndb.org/sf/70/103570.jpg">following these steps</a>.</li>
-</ol>
-<br />
-Now go to the visual novel you want to capture and press the configured hot key
-at the desired moment. The saved screenshots can be uploaded to VNDB without
-further modifications.
diff --git a/data/docs/14 b/data/docs/14
deleted file mode 100644
index 18f403a7..00000000
--- a/data/docs/14
+++ /dev/null
@@ -1,162 +0,0 @@
-:TITLE:Database Dumps
-:INC:index
-
-:SUB:Introduction
-<p>
- This page lists and documents any provided database dumps. These dumps are
- complimentary to the <a href="/d11">real-time API</a>, and the usage terms
- that apply to the API apply here as well.
-</p>
-
-
-:SUB:Tags
-<p>
- <b>URL:</b> <a href="https://vndb.org/api/tags.json.gz">https://vndb.org/api/tags.json.gz</a><br />
- <b>Updated:</b> Every 24 hours.<br />
- <b>Size:</b> ~240 KiB compressed, ~800 KiB uncompressed.<br />
- This dump includes information about all (approved) VN tags in the JSON
- format. The top-level type is an array of tags, and each tag is represented as
- an object with the following members:
-</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer</td>
- <td>no</td>
- <td>Tag ID</td>
- </tr>
- <tr>
- <td>name</td>
- <td>string</td>
- <td>no</td>
- <td>Tag name</td>
- </tr>
- <tr class="odd">
- <td>description</td>
- <td>string</td>
- <td>no</td>
- <td>Can include formatting codes as described in <a href="/d9.3">d9.3</a>.</td>
- </tr>
- <tr>
- <td>meta</td>
- <td>bool</td>
- <td>no</td>
- <td>Whether this is a meta tag or not.</td>
- </tr>
- <tr class="odd">
- <td>vns</td>
- <td>integer</td>
- <td>no</td>
- <td>Number of tagged VNs (including child tags)</td>
- </tr>
- <tr>
- <td>cat</td>
- <td>string</td>
- <td>no</td>
- <td>Tag category/classification: "cont" for content, "ero" for sexual stuff, and "tech" for technical details.</td>
- </tr>
- <tr class="odd">
- <td>aliases</td>
- <td>array of strings</td>
- <td>no</td>
- <td>(Possibly empty) list of alternative names.</td>
- </tr>
- <tr>
- <td>parents</td>
- <td>array of integers</td>
- <td>no</td>
- <td>List of parent tags (empty for root tags).</td>
- </tr>
-</table>
-<p>
- Tag names and their aliases are globally unique and self-describing. See the
- <a href="/d10#2.2">tag creation guidelines</a> for more information.
-</p>
-
-
-:SUB:Traits
-<p>
- <b>URL:</b> <a href="https://vndb.org/api/traits.json.gz">https://vndb.org/api/traits.json.gz</a><br />
- <b>Updated:</b> Every 24 hours.<br />
- <b>Size:</b> ~340 KiB compressed, ~1 MiB uncompressed.<br />
- This dump includes information about all (approved) character traits in the
- JSON format. The top-level type is an array of traits, and each trait is
- represented as an object with the following members:
-</p>
-<table style="margin: 5px 2%; width: 95%">
- <thead><tr>
- <td style="width: 80px">Member</td>
- <td style="width: 90px">Type</td>
- <td style="width: 40px">null</td>
- <td>Description</td>
- </tr></thead>
- <tr class="odd">
- <td>id</td>
- <td>integer</td>
- <td>no</td>
- <td>Trait ID</td>
- </tr>
- <tr>
- <td>name</td>
- <td>string</td>
- <td>no</td>
- <td>Trait name</td>
- </tr>
- <tr class="odd">
- <td>description</td>
- <td>string</td>
- <td>no</td>
- <td>Can include formatting codes as described in <a href="/d9.3">d9.3</a>.</td>
- </tr>
- <tr>
- <td>meta</td>
- <td>bool</td>
- <td>no</td>
- <td>Whether this is a meta trait or not.</td>
- </tr>
- <tr class="odd">
- <td>chars</td>
- <td>integer</td>
- <td>no</td>
- <td>Number of characters on which this trait and any child traits is used.</td>
- </tr>
- <tr class="odd">
- <td>aliases</td>
- <td>array of strings</td>
- <td>no</td>
- <td>(Possibly empty) list of alternative names.</td>
- </tr>
- <tr>
- <td>parents</td>
- <td>array of integers</td>
- <td>no</td>
- <td>List of parent traits (empty for root traits).</td>
- </tr>
-</table>
-<p>
- Unlike with tags, trait names and aliases are neither globally unique nor
- self-describing. If you wish to display a trait (name) to the user, you
- should do so in combination with its associated root trait. For example,
- <a href="/i112">i112</a> is often displayed as "Eyes > Green", to
- differentiate it with <a href="/i50">i50</a>, which is "Hair > Green".
-</p>
-
-
-:SUB:Votes
-<p>
- <b>URL:</b> <a href="https://vndb.org/api/votes2.gz">https://vndb.org/api/votes2.gz</a><br />
- <b>Updated:</b> Every 24 hours.<br />
- <b>Size:</b> ~2.8 MiB compressed, ~11.6 MiB uncompressed.<br />
- This dump contains the VN votes of all users who did not mark their vote list
- as private. Votes from known duplicate accounts or from users who voted on
- unreleased VNs are also not included.<br />
- Each line in the file represents a single vote. Each line contains the VN id,
- user ID, vote, and date that the vote was cast, separated by a space. Votes
- are as listed on the site, multiplied by 10 (i.e. in the range of 10 - 100).
-</p>
diff --git a/data/docs/15 b/data/docs/15
deleted file mode 100644
index 45f808df..00000000
--- a/data/docs/15
+++ /dev/null
@@ -1,67 +0,0 @@
-:TITLE:Special Games
-:INC:index
-
-:SUB:Introduction
-<p>
- This page lists a few games that are commonly discussed for inclusion in the
- database and the reasoning for their inclusion or exclusion. Check <a
- href="/d2.1">d2.1</a> for the general inclusion guidelines.
-</p>
-
-:SUB:Deleted Games
-<p>
- The following is a list of games that have been (proposed to be) included in
- the database, but that were removed or rejected. These games are <b>not</b>
- visual novels and will <b>not</b> be reinstated.
-</p>
-<ul>
- <li><b>The Disgaea series (except for Infinite)</b><br />
- <i>They are TRPGs with no narration or uninterrupted VN segments.</i></li>
- <li><b>Persona 3/4</b><br />
- <i>They are JRPGs and have no narration or VN segments.</i></li>
- <li><b>Ghost Trick</b><br />
- <i>A Puzzle/Adventure game with no narration.</i></li>
- <li><b>Princess Maker 1/2/3</b><br />
- <i>Pure raising sims with no narration or VN segments.</i></li>
- <li><b>Battle Moon Wars</b><br />
- <i>Super Robot Wars style TRPG with no narration.</i></li>
- <li><b>The Shin Megami Tensei series</b><br />
- <i>RPGs/TRPGs with no narration.</i></li>
- <li><b>The Touho games</b><br />
- <i>Bullet hell shooters with only token character interactions.</i></li>
- <li><b>Record of Agarest War / Agarest Senki</b><br />
- <i>No narration and very low story/gameplay ratio.</i></li>
- <li><b>To The Moon</b><br />
- <i>An adventure game with no narration.</i></li>
-</ul>
-
-:SUB:Borderline Games
-<p>
- The following is a lists of few games that <b>are</b> included in the database, but
- are very much borderline cases. When arguing for another game to be included,
- do <b>not, ever,</b> refer to these games as examples.
-</p>
-<ul>
- <li><b>The Ar Tonélico series</b><br />
- <i>The series is in the database because of the Cosmosphere sections, which are long, uninterrupted VN segments. The rest of the game might be a relatively typical JRPG, but it doesn't matter in this case.</i></li>
- <li><b>The Phoenix Wright series</b><br />
- <i>The games are only considered VNs in the broadest sense, and thus they should not be cited as examples for inclusion. They are considered one of the few "mod approved" games that stay in the DB mostly because of reasons not necessarily related to the guidelines (in this case that removing them would cause more problems than keeping them).</i></li>
- <li><b>The Melty Blood series</b><br />
- <i>The only reason the series is in the DB is becasue the first game has narration and proper VN segments, and while the rest are straight up fighting games, they are only considered different releases of said game.</i></li>
- <li><b>The BlazBlue series</b><br />
- <i>The game has narration in the ADV VN segments between battles and these segments are extensive enough to qualify it, if only barely. </i></li>
- <li><b>The Rance series and other turn-based Alice Soft titles</b><br />
- <i>VN hybrids, Sengoku Rance in particular has a lot of narration, and while there is a lot of gameplay in them, they still qualify.</i></li>
- <li><b>Castle Fantasia 2</b><br />
- <i>No consistent narration, but otherwise the game fulfills all other VN requirements, so it is kept as-is.</i></li>
- <li><b>The Corpse Party series (except for the original and Rebuilded)</b><br />
- <i>The games have narration and event CGs, which qualify it over the lack of ADV/NVL presentation.</i></li>
- <li><b>The School Days series (Shiny Days, Summer Days, etc.)</b><br />
- <i>While it would be arguable that the games are more "interactive anime" instead of VNs, they have rudimentary narration and other VN elements to qualify, albeit barely. They are the second most borderline "mod approved" keepers beside the Phoenix Wright series.</i></li>
- <li><b>999 / Kyokugen Dasshutsu 9-Jikan 9-Nin 9 no Tobira / 9 Hours, 9 Persons, 9 Doors</b><br />
- <i>A pure VN with puzzles. I don't even know why people like to bring it up as an example, but it is a proper VN with narration and every other necessary aspect.</i></li>
- <li><b>The Lightning Warrior Raidy series</b><br />
- <i>The games are mostly dungeon crawlers, but they have enough narrated ADV segments to warrant their presence in the DB, albeit barely.</i></li>
- <li><b>Kamidori and other Eushully games</b><br />
- <i>These games have very extensive TRPG gameplay and crafting systems, but they also have equally extensive, uninterrupted and narrated VN segments throughout the games.</i></li>
-</ul>
diff --git a/data/docs/16 b/data/docs/16
deleted file mode 100644
index 036015fb..00000000
--- a/data/docs/16
+++ /dev/null
@@ -1,45 +0,0 @@
-:TITLE:Adding/Editing Staff Members
-:INC:index
-
-:SUB:Introduction
-<p>
- Staff entries represent individuals and groups that play significant roles in visual
- novels production, such as script writers, character designers, artists, voice actors,
- composers and singers.
-</p>
-
-:SUB:General info
-<dl>
- <dt>Names</dt><dd>
- People involved in visual novel production often hide behind multiple
- aliases. These aliases can be listed here. Add only aliases that are actually
- used in VN credits. Sometimes names with different Japanese spellings are
- romanized equally. You may add such aliases, but in that case the original
- spelling should be used when that name is being looked up in the VN staff
- edit form.<br />
- <br />
- One of the aliases can be selected as the primary name of the staff entry.
- Typically this is either the person's true name (if known, and if the person
- has used their true name in the context of VNs) or, alternatively, the most
- widely used alias.<br />
- <br />
- For each alias, the romaji field should contain the name in Latin alphabet.
- The original name should contain the name as it is written in the original
- script, and should be left blank if the name is already in the Latin
- alphabet. Check out the <a href="/d5">general editing guidelines</a> for
- information on name order and romanization. If possible, try to include a
- space between the given name and the surname.
- </dd><dt>Gender</dt><dd>
- Person's gender, if known.
- </dd><dt>Primary language</dt><dd>
- Native language, Japanese by default.
- </dd><dt>Staff note</dt><dd>
- Brief note describing biography, occupation and production companies affiliations, if any.
- It's fine to leave this field empty if there's nothing much known about the person in question.
- </dd><dt>Official page</dt><dd>
- Link to the official page or blog.
- </dd><dt>Additional links</dt><dd>
- You could also provide links to Wikipedia entry, Twitter account and/or AniDB entry. Do
- not specify the full URL for additional links, we only need a small part of it!
- </dd>
-</dl>
diff --git a/data/docs/2 b/data/docs/2
deleted file mode 100644
index 3eded990..00000000
--- a/data/docs/2
+++ /dev/null
@@ -1,257 +0,0 @@
-:TITLE:Adding/Editing a Visual Novel
-:INC:index
-
-:SUB:What can be added to the database
-<p>
- For a game to qualify for inclusion in the database, it must meet one of the
- following two requirements:<br /><br />
-</p>
-
-<ol>
-<li>Visual Novels that have the following characteristics:
- <ul>
- <li>Choices are the only allowed (but optional) form of interactivity. There
- are no other gameplay elements (including stats-based gameplay in
- dating/raising sims). Mini-games and simple mechanics, such as map-movenent,
- are only allowed when they play a very minimal role – at least 99% of the
- title should be made of pure reading.</li>
- <li>The story is told employing one of the known Visual Novel presentation
- methods such as <a href="http://s.vndb.org/sf/40/3440.jpg">ADV</a>, <a
- href="http://s.vndb.org/sf/52/3152.jpg">NVL</a> and their <a
- href="http://s.vndb.org/sf/39/339.jpg">variations</a>.</li>
- </ul>
-</li>
-<li>Visual Novel / Game hybrids that have the following characteristics:
- <ul>
- <li>The game consistently uses the novel narrative for telling its story.
- Examples include describing <a
- href="http://s.vndb.org/sf/58/258.jpg">visuals</a>, <a
- href="http://s.vndb.org/sf/63/2663.jpg">events</a>, <a
- href="http://s.vndb.org/sf/74/274.jpg">character actions</a> or <a
- href="http://s.vndb.org/sf/49/449.jpg">thoughts</a>.<br />
- This point is ESSENTIAL - dialogues, no matter how extensive, are a
- characteristic of such game genres as RPGs, adventure games, dating
- simulations, etc., NOT of visual novels.</li>
- <li>The story is told employing one of the known Visual Novel presentation
- methods such as <a href="http://s.vndb.org/sf/40/3440.jpg">ADV</a>, <a
- href="http://s.vndb.org/sf/52/3152.jpg">NVL</a> and their <a
- href="http://s.vndb.org/sf/39/339.jpg">variations</a>, consistently and for
- a significant length - at least 50% of the game should be made of pure,
- VN-style reading.</li>
- </ul>
-</li>
-</ol>
-
-<p>
- <br />
- Note: In some special cases, a game may be added even if it does not strictly
- adhere to the above points. However, this is the decision of the moderators. Do
- not add a game yourself expecting it to be an exception to the above rules.
- <br />
- See also the <a href="/d15">list of special games</a>.
-</p>
-
-
-:SUB:General info
-<dl>
- <dt>Title (romaji)</dt><dd>
- The title should be based upon the title of the original release.<br />
- If the title uses the Latin alphabet, use our <a href="/d5.2">capitalisation guidelines</a>.<br />
- Otherwise, <a href="/d5.1">romanise</a> according to our guidelines.
- </dd><dt>Original title</dt><dd>
- If the name is officially under a different title (usually because of different
- character sets), put the original title here.
- </dd><dt>Aliases</dt><dd>
- Visual novels can be known under several names, use this field to add any aliases
- and acronyms used around the net. Official titles of releases should not be added
- here, as these are already listed in the releases.
- </dd><dt>Description</dt><dd>
- Short description of the main story.
- </dd><dt>Length</dt><dd>
- Very rough estimate of the time required to finish all endings of the visual novel.
- To determine the length of a game, it's often better to ignore this time indication
- and instead compare it with other games you've played. It's all relative, after all.
- </dd><dt>External links</dt><dd>
- Links to external resources about this visual novel. To get the URLs, go to the
- sites (<a href="http://en.wikipedia.org/">Wikipedia</a>, <a href="http://novelnews.net/">
- Novelnews.net</a>, <a href="http://renai.us/">Renai.us</a> and
- <a href="http://visual-novels.net/">Visual-novels.net</a>),
- search for a page about the game, and determine the ID or name of that page to fill
- out in the text boxes. Do not specify the full URL, we only need a small part of
- it!
- </dd><dt>Related anime</dt><dd>
- Some visual novels (e.g. <a href="/v4">Clannad</a> and <a href="/v3">Utawarerumono</a>)
- have anime adaptions, and some visual novels were adapted from an anime series. Use
- this field to specify these related anime for the visual novel.<br />
- Anime should be specified using <a href="http://anidb.net/">AniDB</a> IDs. To add an
- anime, just search for it on AniDB and add the numeric ID of the entry (found in the
- <i>aid=xxx</i> part of the URL) to the edit field. Multiple IDs should be seperated
- with a whitespace.<br />
- If the visual novel already has a relation with an other visual novel, and both games
- have an anime adaption, the same anime does not have to be added to both games. For
- example, <a href="/v264">Da Capo</a> has two anime adaptions
- (<a href="http://anidb.net/a837">837</a>, <a href="http://anidb.net/a2832">2832</a>),
- and <a href="/v266">Da Capo II</a> as well. (<a href="http://anidb.net/a5419">5419</a>,
- <a href="http://anidb.net/a5652">5652</a>) But the relations for Da Capo II do not
- have to be added to Da Capo and vice versa - the internal visual novel relations will
- take care of that.<br />
- After submitting a new AniDB ID, VNDB will automatically fetch information about the
- anime and will present that on the site. This action can take a few minutes to - in the
- worst case - hours. In that time you will see the ID of the anime, but not the title
- and links to AnimeNFO and Anime News Network. It is not possible to manually add this
- information, this will be fetched automatically!
- </dd>
-</dl>
-
-
-:SUB:Staff & Cast
-<p>It's possible to link VN entries to <a href="/d16">staff entries</a> in the
-staff and cast tabs.<br /><br />
-In both tabs, staff aliases can be selected by searching for their romanized or
-original names. To match an exact name instead of performing a search, prefix
-the name with '='. If the name is not in the database yet, you need to <a
-href="/d16">add it</a> first.
-</p>
-
-:SUBSUB:Staff
-<p>
- The staff tab lists the people or groups involved in the creation of the
- visual novel. The following roles can be used:
-</p>
-<dl>
- <dt>Scenario</dt><dd>&nbsp;</dd>
- <dt>Character design</dt><dd>&nbsp;</dd>
- <dt>Composer</dt><dd>&nbsp;</dd>
- <dt>Director</dt><dd>&nbsp;</dd>
- <dt>Artist</dt><dd>&nbsp;</dd>
- <dt>Vocals</dt><dd>Vocals used in the music. Not to be used for voice actors of characters, these should be listed under <a href="/d2.3.2">cast</a> instead.</dd>
- <dt>Staff</dt><dd>Used for any additional minor roles, use the "notes" field to indicate the staff's involvement.</dd>
-</dl>
-<p>A few guidelines:</p>
-<ul>
- <li>Add major staff only.</li>
- <li>If someone performed several jobs, add multiple entries with different major roles.</li>
-</ul>
-
-:SUBSUB:Cast
-<p>
- The cast tab lists the voice actors for each character. This tab is only
- available when characters have been linked to the visual novel.
-</p>
-
-:SUB:Image
-<p>
- Every visual novel should have an image, preferably one of the official cover
- art of one of the releases. In some cases, especially with doujin games, if there is
- no official cover art available, a general image from the game's homepage or a
- screenshot of the game itself could be used instead.<br />
- Images can be uploaded in JPEG or PNG format, and should not be larger than 5 MiB.
- All images larger than 256x400px will automatically be resized to fit on the page.
- <br /><br />
- The NSFW warning should be used in cases where the cover art is not safe for work.
- To determine what is safe for work and what is not, use the following guidelines:
-</p><ul>
- <li>Nudity is only safe if the sexual characteristics are covered or hidden</li>
- <li>Bikini, pantsu and other underwear are only safe if they contain no implicit
- indication of sexual anatomy</li>
- <li>If the characters pose is overly sexually suggestive, it's NSFW</li>
- <li>If multiple characters are portrayed and they are engaged in physical contact
- that may be considered as (a precursor to) sexual contact, then it's NSFW as well.
- </li>
- <li>NSFW is solely determined by the graphics: Images that contain suggestive
- text but are not otherwise NSFW are safe.</li>
-</ul><p>
- Even with these guidelines it may not always be easy to determine whether an image
- is safe or not. When in doubt, it's often best to go for NSFW.
-</p>
-
-
-:SUB:Relations
-<p>
- Visual novel relations can be used to indicate what games are related to each
- other.<br />
- When adding a relation, the reverse relation will automatically be added to
- the other visual novel. E.g. if you add game x as a sequel to game y, then game
- y will automatically be added as a prequel to game x. You do not have to edit
- both games.<br />
- Only specify <b>direct</b> relations. If one game 1 is listed to have a relation
- with game 2, and game 2 has a relation with game 3, then game 3 does not have
- to be added as a relation to game 1. This may sound a bit confusing at first,
- but you will understand when you look at the relation graphs. When editing relations,
- always try to think about the relations between all related games - as shown in
- the graph - instead of only looking at the specific visual novel you're editing.
- <br />
- The "official" checkbox can be used to indicate whether relation is an official
- one or not. A relation is official if both games were published by the same
- brand, or at least the publisher of the earlier game has given persmission to
- create the later game. In general: fandiscs and games of the same series are
- official, while fan fiction is not.
- <br />
- There is a static list of relations to choose from (as described below). As with
- many things, the relations between games can in reality be more complex than these
- options could describe. Simply choose the option you think is closest to describing
- the actual relation when you're not sure which one to choose.
-</p>
-<dl>
- <dt>Sequel</dt><dd>
- Continuation of the story. &lt;=&gt;<i>Prequel</i>.
- </dd><dt>Prequel</dt><dd>
- The story happens before the original story.&lt;=&gt;<i>Sequel</i>.
- </dd><dt>Same setting</dt><dd>
- Same universe, world, reality and timeline, but completely different characters.
- The definition of "setting" is not always easy to define, but usually it
- means that if places or items not existing in the real world described in one
- game also exist in the other game, you could use this relation.
- </dd><dt>Alternative version</dt><dd>
- Same setting, same characters, but the story is told differently.
- </dd><dt>Shares characters</dt><dd>
- Different story, but shares some characters.
- </dd><dt>Side story</dt><dd>
- The story takes place sometime during the parent storyline. &lt;=&gt;<i>Parent story</i>
- </dd><dt>Parent story</dt><dd>
- Opposite of <i>Side story</i>.
- </dd><dt>Same series</dt><dd>
- The games are part of the same series.
- </dd><dt>Fandisc</dt><dd>
- <a href="http://en.wikipedia.org/wiki/Fan_disc">Fandisc</a>.
- </dd><dt>Original game</dt><dd>
- The opposite of fandisc.
- </dd>
-</dl>
-
-
-:SUB:Screenshots
-Each visual novel entry can have at most 10 screenshots. Screenshots can be
-uploaded in JPEG and PNG format. The uploaded screenshots are strictly
-moderated to follow the guidelines listed below. It is highly recommended to
-follow our <a href="/d13">instructions on creating good screenshots</a> if you
-don't want your efforts to go to waste.
-<ul>
- <li>All images must be in the highest native resolution of the VN. The native resolution
- is the resolution for which the bitmap images are made, this is 640x480 or 800x600 for most
- entries. Any upscaling or downscaling, whether done by the game engine itself or by manually
- using an image editor, is <b>not</b> allowed!</li>
- <li>All images have to be screenshots of the <b>game itself</b>, this means that any window
- borders will have to be removed before uploading. We are neither interested in your heavily
- modified window borders nor in your awesome AGTH setup.</li>
- <li>At least half of the images should be actual screenshots of the game. That is, they should
- include character sprites or some form of dialog or user interface. Plain event CG images
- without any text or interfaces are allowed to demonstrate the drawing style, but should
- not dominate over the other screenshots.</li>
- <li>Uploading screenshots with erotic content is allowed, as long as the ratio of erotic/non-erotic
- screenshots is somewhat in line with the actual erotic/non-erotic ratio of the VN itself. For example,
- if a 10 hour VN has only 2 H-scenes of 10 minutes, it wouldn't be appropriate to upload more than 2 or 3
- erotic images. On the other hand, if a VN is mostly about sex, it wouldn't make sense to upload only one
- erotic screenshot. It is advised - even for the sex-only games - to have at least one non-erotic screenshot.</li>
- <li>Keep the spoilers to a minimum. It's impossible to upload screenshots that are completely devoid
- of spoilers, but it is possible to keep this to a minimum. I.e. screenshots early in the beginning of
- the VN are prefered, and shots later in the game are fine as long as they don't reveal any major information
- about the plot.</li>
- <li>Images that are NSFW should be flagged as such, see the <a href="#4">image</a> guidelines above.</li>
- <li>Screenshots have to be unmarked: they shouldn't contain any copyright information, website URL,
- or other text that's not present in the original screenshot.</li>
- <li>Screenshots should preferably be of the English or original (Japanese) releases. Other languages are
- allowed, but the number of images should be kept to a minimum.</li>
- <li>Do not post different language versions of the same screenshot, this is not a comparision gallery.</li>
-</ul>
-
diff --git a/data/docs/3 b/data/docs/3
deleted file mode 100644
index 703d4172..00000000
--- a/data/docs/3
+++ /dev/null
@@ -1,160 +0,0 @@
-:TITLE:Adding/Editing a Release
-:INC:index
-
-
-:SUB:When to add a release
-<p>
- A 'release' is a product - either physical or digital - containing (parts of) the
- visual novel. This excludes soundtracks, drama CDs, fandisks, and other products
- that do not contain the visual novel itself.<br />
- All releases should be added seperately. For example, a limited and a regular edition
- shouldn't be combined into one release, even if they share the release date and
- contents. For commercial games, separate releases can be distinguished by their
- JAN/UPC/EAN number.
-</p>
-
-
-:SUB:General info
-<dl>
- <dt>Type</dt><dd>
- Is the release complete, partial or a trial version?
- Complete releases have everything.
- Partial releases have most of the game, but there are things still waiting
- to be released.
- Trial versions are heavily cut down and free releases so that you can
- experience a game before you buy it. Sometimes, trial versions are cut
- down for web transmission and do not completely represent the finished product.<br />
- In the case of a translation patch, the type should indicate whether it translates
- the full game (Complete), or just parts of it (Partial).
- </dd><dt>Patch</dt><dd>
- Use this checkbox to indicate that the release is a (translation) patch, used to
- patch an other release.
- </dd><dt>Freeware</dt><dd>
- Check if this box if the game is downloadable (or otherwise distributed) at no cost.
- </dd><dt>Doujin</dt><dd>
- Published by a doujin circle, amateur group or individual, as opposed to a legal
- entity such as a company. This field is ignored when the release type is set to patch.
- </dd><dt>Title (romaji)</dt><dd>
- The name of the release, in the Latin character set (using Romanisation or translation)
- </dd><dt>Original title</dt><dd>
- If the name is officially under a different title (usually because of different
- character sets), put the original title here.
- </dd><dt>Language</dt><dd>
- What language is this release? Use the language that the majority of the game is in.
- </dd><dt>JAN/UPC/EAN</dt><dd>
- The <a href="http://en.wikipedia.org/wiki/Global_Trade_Item_Number">GTIN</a> code
- of the product. Often called "JAN" for Japanese releases, "UPC" for USA and Canada
- and "EAN" for Europe. The system will automatically detect the type from the code and
- use the appropriate term on the release page.
- </dd><dt>Catalog number</dt><dd>
- Catalog number as assigned by the producer. Often used to identify releases on
- webshops, and can usually be found somewhere on the packaging of the product.
- </dd><dt>Official website</dt><dd>
- URL of the official homepage for this product. Note that, even though VNDB does
- not support piracy, it is allowed to link to a homepage or forum that does in the
- case it is the only <b>official</b> source of information for this release.
- </dd><dt>Release date</dt><dd>
- For commercial games, the sale date.
- For all others, the date on which the release was first available.
- If it was posted on a website, the date on which the post was public.
- </dd><dt>Age rating</dt><dd>
- The minimum age rating for the release. On most releases, this is specified on the
- packaging or on product web pages.
- </dd><dt>Notes</dt><dd>
- Anything miscellaneous and useful.
- Generally, extras (but not preorder bonuses) and progress information go here.
- </dd>
-</dl>
-
-
-:SUB:Format
-<dl>
- <dt>Resolution</dt><dd>
- Primary/native screen resolution of the game.
- </dd><dt>Voiced</dt><dd>
- Indicates whether this release includes voice acting in the VN/ADV parts of the game.
- <i>Fully voiced</i> indicates that all characters (usually excluding the protagonist
- and some minor characters) are voiced in all scenes. <i>Only ero scenes voiced</i>
- speaks for itself, and <i>Partially voiced</i> should be used when there is some voice
- acting, but only for the main characters or only in some scenes.
- </dd><dt>Animation</dt><dd>
- Whether the game has any animation can be specified with two seperate options: one for
- the normal story mode and one for the ero scenes, if the game has any. With <i>Simple
- animations</i>, we refer to (usually looping) effects like falling leaves or snow in the
- background or animated facial expressions like blinking eyes and a moving mouth.
- <i>Fully animated scenes</i> refers to non-looping anime-like scenes. Some games are
- entirely like this, others only have a few scenes that are fully animated. Effects like
- moving sprites around the screen, basic zooming and shaking background images are not
- considered as "animations". Minigames or other gameplay elements are excluded as well,
- only the (ADV/VN-like) story parts and ero scenes should be considered.
- </dd>
-</dl>
-<p>
- <b>NOTE</b>: The resolution, voiced and animation fields have no meaning for patches, and
- should be left empty for those releases.
- <br /><br />
- <b>Platform</b><br />
- The platforms that the product was released for. Does not include emulated platforms
- (e.g. Playstation 2 games on Playstation 3) or WINE. DVD Player refers to games playable
- as a normal DVD Video (DVDPG) and should not be confused with the DVD as a medium.
- <br /><br />
- <b>Media</b>
-</p>
-<dl>
- <dt>Blu-ray</dt><dd>
- Blu-ray Disk, typically 30-60GB+. Requires a Blu-ray Drive. Playstation 3 are
- normally Blu-ray.
- </dd><dt>CD</dt><dd>
- CD-ROM, typically 700MB.
- </dd><dt>DVD</dt><dd>
- DVD5, typically 4.5GB, or DVD9, typically 9GB. DVDPG games are DVD.
- </dd><dt>Floppy</dt><dd>
- 5 1/4" or 3 3/4", no greater than 1.44MB.
- </dd><dt>GD</dt><dd>
- Dreamcast games are normally GD disks.
- </dd><dt>Internet Download</dt><dd>
- Anything without a physical box, i.e. obtained by downloading it over a network.
- </dd><dt>Memory Card</dt><dd>
- Any SD (Secure Digital) Card variant or MMC variant, Compact Flash or "USB Sticks".
- The Main difference between this and Cartridge (below) is that Memory Cards are
- re-writable (RW).
- </dd><dt>Cartridge</dt><dd>
- Compare with Memory Cards (above). Read-only. Famicom (NES), Super Nintendo (SNES),
- Game Boy Advanced (GBA) and Nintendo DS use cartridges.
- </dd><dt>Nintendo Optical Disk</dt><dd>
- Non-CD or DVD optical disks used by various Nintendo consoles.
- </dd><dt>Other</dt><dd>
- Any format not considered to be any of these mentioned should take this media.
- However, it should not be used liberally, and it's inclusion may need to be justified.
- </dd><dt>UMD</dt><dd>
- Universal Media Disk, typically 2.2GB. Playstation Portable uses this format.
- </dd>
-</dl>
-
-
-:SUB:Producers
-<p>
- The companies/groups/individuals involved in the development or publishing of
- this release. Does not include distributors. The following roles can be selected:
- <dl>
- <dt>Developer</dt><dd>
- The producer involved in the creation of the game itself, not necessarily of
- this specific release. Keep in mind that producers that have made modifications
- to a game but have not made the game itself should NOT be listed as developers.
- </dd><dt>Publisher</dt><dd>
- The producer responsible for publishing this specific release. The publisher may have
- made modifications to the game (e.g. translating all text or porting to a different
- platform), but was not involved in the creation process.
- </dd><dt>Both</dt><dd>
- When the release is developed and published by the same producer. This is often
- true for doujin games and the first releases of commercial games.
- </dd>
- </dl>
-</p>
-
-
-:SUB:Visual novel relations
-<p>
- The visual novels that this release (either partially or fully) covers.
-</p>
-
diff --git a/data/docs/4 b/data/docs/4
deleted file mode 100644
index b30c32c5..00000000
--- a/data/docs/4
+++ /dev/null
@@ -1,76 +0,0 @@
-:TITLE:Adding/Editing a Producer
-:INC:index
-
-
-:SUB:When to add a producer
-<p>A producer entry may be created in one of the following scenarios:</p>
-<ol>
-<li>When it is needed to link the developer or publisher to a release entry.
-In this case, the producer is required to have released at least one completed
-product. This means that translation projects and starting developers may only
-be added when they've actually finished a project.</li>
-<li>When it is needed to link two or more producer entries together to provide
-a correct view of the relations between producers. The producer entries that
-are being linked together should qualify for the first criteria, and need to be
-linked to at least one release entry.</li>
-</ol>
-<p>Producer entries that do not qualify for either rule may be deleted after a
-while.</p>
-
-
-:SUB:General info
-<dl>
- <dt>Type</dt><dd>
- The type of producer.
- </dd><dt>Name (romaji)</dt><dd>
- The name of the producer in the Latin alphabet, using <a href="/d5.1">romanisation</a>
- in case the original name isn't in the Latin alphabet already. <a href="/d5.2">Capitalization</a>
- is also important for this field.
- </dd><dt>Original name</dt><dd>
- If the Name (above) has been romanised, make sure to mention the original (most likely
- the Japanese) name here.
- </dd><dt>Aliases</dt><dd>
- Other names the producer is known as. Multiple aliases should be separated by a newline.
- </dd><dt>Primary language</dt><dd>
- The language the the producer works in most of the time. By default, it is Japanese.
- </dd><dt>Website</dt><dd>
- Official homepage of the producer.
- </dd><dt>Description</dt><dd>
- A history of the producer, or a description of what type of games they make.
- </dd>
-</dl>
-
-
-:SUB:Relations
-These relations provide information about which producers are related to each
-other, and how they are related. Choosing the correct relation may be a bit
-confusing, check the relation graph of the producer entry in case of doubt.
-The following relations are defined:
-<dl>
- <dt>Formerly</dt><dd>
- The current producer was earlier known as the selected producer. This can be
- because of a name change, or when the earlier producer disbanded and the same
- people started again under a different name.
- </dd><dt>Succeeded by</dt><dd>
- Reverse of <i>Formerly</i> - selected producer was formerly known as the current producer.
- </dd><dt>Subsidiary</dt><dd>
- Selected producer is a <a href="http://en.wikipedia.org/wiki/Subsidiary">subsidiary</a>
- of the current producer.
- </dd><dt>Parent producer</dt><dd>
- Reverse of <i>Subsidiary</i> - current producer is a subsidiary of the selected producer.
- </dd><dt>Imprint</dt><dd>
- Selected producer is an imprint of the current producer. Simply put, an
- "imprint" is a different name for the same group of people, used when
- publishing games. See <a href="http://en.wikipedia.org/wiki/Imprint">Wikipedia</a> for more info.
- </dd><dt>Parent brand</dt><dd>
- Reverse of <i>Imprint</i> - current producer is an imprint of the selected producer.
- </dd><dt>Spawned</dt><dd>
- The selected producer was formed by former members of the current producers.
- The difference with the <i>Formerly</i> relation is that the producer where the
- members came from is still alive.
- </dd><dt>Originated from</dt><dd>
- Reverse of <i>Spawned</i> - selected producer spawned the current producer.
- </dd>
-</dl>
-
-
diff --git a/data/docs/5 b/data/docs/5
deleted file mode 100644
index 72fc58c9..00000000
--- a/data/docs/5
+++ /dev/null
@@ -1,90 +0,0 @@
-:TITLE:Editing guidelines
-:INC:index
-
-
-:SUB:Romanization
-<p>
- The main audience of VNDB are the English speaking fans of visual novels. In
- creating the database, we assume the intended audience can't read or recognise
- anything not written in the roman script. Therefore, romanization is applied
- to many fields in the database: The main title of visual novels, releases,
- producers and characters should all be properly romanized if they arent in
- roman script already.<br />
- To keep the database consistent, we have decided to use a mix of <a
- href="http://en.wikipedia.org/wiki/Hepburn_romanization">Hepburn</a> and <a
- href="http://en.wikipedia.org/wiki/Wapuro">Wapuro</a> for all fields. This is
- also consistent with <a href="http://wiki.anidb.net/w/Romanisation">AniDBs
- romanization</a>.
- <br />
- For English (or other foreign) words in a non-roman script, the original word
- should be used as long as it is the intended effect. If those words are in a
- non-roman script, a suitable romanisation technique should be used.
-</p>
-
-
-:SUB:Capitalization
-<p>
- It occasionally happens that official titles are either entirely in uppercase
- or lowercase characters. If there is no real reason for this choice of
- capitalization (e.g. it's not an acronym), these titles should be properly
- converted to normal English capitalization (as described <a
- href="http://en.wikipedia.org/wiki/Capitalization">on Wikipedia</a>) before
- being entered in the database.<br />
- This only applies to the main title of a visual novel entry, the 'Original
- title' field and the title/name fields of other database entries (including
- release entries) should use the official capitalization wherever possible.
-</p>
-
-
-:SUB:Name Order
-<p>
- In most English speaking countries, names are given in a "given name, family
- name" order. This is called "Western Order". In English, you call someone
- using their given name if you know them well, otherwise use their title and
- family name.
- <br />
- In Japanese (and some other languages too), names are given in "family name,
- given name" order. We call this "Japanese Order". In Japanese you can call
- someone using either name with an appropriate suffix.
- <br />
- To aid English speakers, some resources (e.g. wikipedia) use Japanese names in
- Western order. Here on vndb.org, we prefer to use the order that the original
- game used.
- <br />
- That is, if it was originally a Japanese game with Japanese character names,
- use Japanese order.
- <br />
- If the game is originally English, or a character has a completely foreign
- name (Mary Smith), use Western order.
-</p>
-
-
-:SUB:Edit Summaries
-<p>
- Every edit to any page has a required "Edit summary" box, this allows you to
- explain yourself on what your edit is about without cluttering the main page.
- You can say why you've modified the description, changed a link, or show where
- you obtained some information (so that other contributors can verify it).
- Perhaps you want to add a visual novel to the database but are unable to find
- more information for it. If you say so here, another contributor is bound to
- finish it off.
-</p>
-
-
-:SUB:Descriptions From External Sources
-<p>
- It is possible to add a description or notes to visual novel, producer,
- release and character entries in the database. While original descriptions are
- preferred, using descriptions from external resources is allowed, provided the
- source is properly credited. The preferred form to credit external resources
- is by adding the following template to the bottom of the description:<br />
- [From [url=<b>URL</b>]<b>title or author</b>[/url]]<br />
- This would result in, for example, '[From <a
- href="http://en.wikipedia.org/Wiki/Ever17">Wikipedia</a>]' for descriptions
- taken from Wikipedia. If the description is not literally taken from the
- source but has some modifications, the 'From' should be replaced with
- something similar, indicating that it's modified, e.g. 'Edited from', 'Based
- on'.<br />
- As it is not allowed to provide links to websites providing or promoting
- illegal downloads, the URL part should be left out for such descriptions.
-</p>
diff --git a/data/docs/6 b/data/docs/6
deleted file mode 100644
index 0ab93f0c..00000000
--- a/data/docs/6
+++ /dev/null
@@ -1,138 +0,0 @@
-:TITLE:Frequently Asked Questions
-:INC:index
-
-
-:SUB:What is a Visual Novel?
-<p>
- A visual novel can be seen as a combination of a novel and a computer game:
- they're computer games with a large text based storyline and only little
- interaction of the player. A typical visual novel consists of text over
- an anime-style background image and is accompanied by background music.
- Throughout the game, the player usually has to answer a few questions which will
- have an effect on the story, thus playing a visual novel a second time while
- giving other answers may result in an entirely different plot.<br />
- <br />
- To get a general idea of the genre, try one of the free short visual novels
- from <a href="http://altogether.insani.org/">al|together</a>.
-</p>
-
-
-:SUB:How about Eroge, H-Games and Dating Sims?
-<p>
- An eroge or H-game is basically any Japanese game that features sexual
- content. Many visual novels are eroge and many eroge are visual novels,
- but this is not a rule. The definition of dating sim is a bit more vague,
- but it's usually the same as a visual novel, except that a dating sim
- generally uses a gameplay based on statistics.<br />
- <br />
- There are no strict bounds to the definition of "visual novel", most eroge and
- dating sims include elements of visual novels, but may - strictly speaking -
- not be visual novels themselves. VNDB has its own rules for inclusion in the
- database, see the <a href="/d2">guidelines</a> and the <a href="/d15">list of
- special games</a> for more information.
-</p>
-
-
-:SUB:Why a Visual Novel Database?
-<p>
- The internet is large, very large, but the number of English resources
- related to visual novels is only very limited. VNDB attempts to collect
- and present as much information as possible that would otherwise be very
- hard to find for the English speaking audience. This way fans can easily
- keep track of new releases and localizations of their favorite games,
- while not having to browse numerous of indistinct Japanese websites.
-</p>
-
-
-:SUB:How can I help VNDB?
-<p>
- There are many ways to contribute to VNDB. First of all you can freely edit
- all information found on this website, so if you find any errors just click
- the "edit" link on the top right of the page. You can also add new information
- to the database, though please search the database before you do in order to
- prevent duplicate pages.<br />
- <br />
- To discuss about new features or to help the development of the website
- itself, feel free to participate on the <a href="/t">discussion board</a>
- or join us on IRC at <a href="irc://irc.synirc.net/vndb">#vndb @ irc.synirc.net</a>.
- If you aren't used to IRC or are just too lazy to install a client, you can
- still join the chat using <a href="http://cgiirc.synirc.net/?chan=%23vndb">the Webchat</a>.
- Just choose a nickname and hit Login!
-</p>
-
-
-:SUB:Where can I download the Visual Novels?
-<p>
- Not here. We do not provide any links to direct downloads, torrents or
- other means of downloading games. We do, however, link to the official
- homepages of the producers, who may provide free trials or even full
- game downloads.<br />
- <br />
- Our stance on piracy is that patches and downloads that have modifications to
- the game's contents are allowed. This includes translation patches and
- restoration patches. Any downloads, tools, cracks or codes that have the sole
- purpose of avoiding the purchase of a game are considered piracy and should
- not be discussed on this site.
-</p>
-
-
-:SUB:Can you recommend me a Visual Novel?
-<p>
- Asking for recommendations on the discussion board or on IRC is usually not a
- good idea, for various reasons. If you're looking for VNs that most people
- have played, check out the <a href="/v/all?s=pop;o=d">popularity rankings</a>.
- If you're interested in VNs that are generally considered "good" or "awesome",
- check out the <a href="/v/all?s=rating;o=d">ratings</a>. If you're looking for
- something specific, <a href="/g">browse through the tags</a>. If you're
- interested in a more personal answer, compare the vote lists of our <a
- href="/u/all">users</a> with your own and decide what to read next based on
- that.<br />
- <br />
- If you prefer a human answer, you can also ask around at the following communities:
-</p>
-<ul>
- <li><a href="https://www.reddit.com/r/vnsuggest">/r/vnsuggest</a></li>
- <li><a href="https://www.reddit.com/r/visualnovelsuggest">/r/visualnovelsuggest</a></li>
- <li><a href="https://www.reddit.com/r/visualnovels">/r/visualnovels</a> - Not
- intended for recommendations, but a good resource to ask for general VN help.</li>
- <li>There is also a related <a href="https://discord.gg/Z6skErt">Discord</a> and
- <a href="http://irc.lc/Snoonet/visualnovels/Guest@@@@">IRC</a> channel.</li>
-</ul>
-
-
-:SUB:Who's that girl on the background?
-<p>
- If you don't have an account on VNDB or you've never played around with your
- profile settings, then the answer you're looking for is <a href="/c3005">Lasty
- Farson</a> from <a href="/v1280">Angelic Serenade</a>. If you do have an
- account then you can simply go to your profile page and check which skin
- you're using - the name of the skin tells you where it's from.
-</p>
-
-
-:SUB:I found this awesome game, but it's not available in English!?
-<p>
- Shit happens. There are several things to keep in mind: first of all, if our
- database does not have a translation listed, then with a *very* high
- probability it simply does not exist, anywhere. Second, we don't translate
- these games ourselves and we do not coordinate the translations, either, so
- asking for a translation here is rather pointless and a sure-fire way to get
- your thread locked. Also, there is an order of magnitude more visual novels
- than there are translators within this community. :-(
-</p>
-
-
-:SUB:Can I link to VNDB?
-<p>
- Of course you can! We even have some icons you could use to link to and promote
- VNDB. Direct linking is, as with all other images on this site, allowed.<br />
- <img src="//s.vndb.org/linkimg/vndb0.gif" style="margin: 5px">
- <img src="//s.vndb.org/linkimg/vndb1.gif" style="margin: 5px">
- <img src="//s.vndb.org/linkimg/vndb2.jpg" style="margin: 5px">
- <img src="//s.vndb.org/linkimg/vndb3.jpg" style="margin: 5px">
- <img src="//s.vndb.org/linkimg/vndb4.jpg" style="margin: 5px">
- <img src="//s.vndb.org/linkimg/vndb5.jpg" style="margin: 5px">
- <img src="//s.vndb.org/linkimg/vndb6.jpg" style="margin: 5px"><br />
- If you feel these banners don't suit your needs, please don't hesitate to make
- one yourself.
-</p>
diff --git a/data/docs/7 b/data/docs/7
deleted file mode 100644
index 67a74a1a..00000000
--- a/data/docs/7
+++ /dev/null
@@ -1,69 +0,0 @@
-:TITLE:About us
-:INC:index
-
-
-:SUB:Goal
-<p>
- Our primary goal is building a large, comprehensive and up-to-date database for
- information about all existing visual novels. VNDB aims to be a central place
- to look up general information about the visual novels themselves, as well as
- practical information around it, like available releases, localisations and
- producers.<br />
- Our secondary goal is to promote the wonderful medium called visual novels to
- a broader audience, an audience not limited only to people who can understand
- Japanese, but to anyone interested in literature, anime, manga or games,
- regardless of their geographical location or cultural differences.
-</p>
-
-
-:SUB:Genesis
-<p>
- It all started right after <a href="/u2">yorhel</a> finished reading
- <a href="/v17">Ever17</a>. Highly impressed by the masterpiece, several
- questions came to his mind: After learning about visual novels, why did it
- still take several months to find this game? Why hasn't he ever heard about it before?
- How can a visual novel of that quality go by unnoticed in almost all online
- anime and gaming communities? And more importantly: Are there more visual
- novels like that out there?<br />
- <br />
- VNDB was born to answer that last question. The complete lack of any central
- resource for, or even a simple list of visual novels made it very hard to
- find new games or get a good overview of what was available. Having a central
- and well-organized place where everyone can share their information and knowledge
- about visual novels would solve this problem.<br />
- <br />
- After a short three weeks of hard work, the first version of VNDB saw the light
- of day in September 2007. The obscurity and small fanbase around visual novels,
- combined with the bare minimum of features and the rigid contribution system
- in use at the time, made that the database only grew at a slow pace. But with time
- more people learned about VNDB, new and advanced features were being introduced,
- and in response more visitors started contributing information. The introduction
- of an improved and open contribution system in February 2008 motivated even more
- users to submit information, and as of September 2008 - a year after the initial
- version of VNDB - the database catalogues more than 1000 visual novels and 2000
- releases, which still continues to grow in size and quality today.
-</p>
-
-
-:SUB:Credits
-<p>
- <b>Code development</b><br />
- <dl>
- <dt>Yorhel</dt><dd>Main developer.</dd>
- <dt>QCyph</dt><dd>Contributed the character filters.</dd>
- <dt>3dB</dt><dd>Contributed improved user authentication code and post throttling on the discussion board.</dd>
- <dt>SpaceRanger</dt><dd>Contributed the visual novel release comparison page, userlist columns to the VN list and dx.x.x link formatting.</dd>
- <dt>morkt</dt><dd>Contributed the staff database and lots of other stuff.</dd>
- <dt>flan</dt><dd>Contributed Open graph tags and test cases for the BBCode parser.</dd>
- <dt>TigerShark</dt><dd>Contributed release icons.</dd>
- </dl>
- <br />
-
- <b>Special users</b><br />
-:MODERATORS:
- <br />
-
- <br />
- <b>Skins</b>
-:SKINCONTRIB:
-</p>
diff --git a/data/docs/9 b/data/docs/9
deleted file mode 100644
index 8f964382..00000000
--- a/data/docs/9
+++ /dev/null
@@ -1,80 +0,0 @@
-:TITLE:Discussion board
-:INC:index
-
-
-:SUB:Introduction
-<p>
- VNDB has a nicely integrated discussion board which can be used for, well,
- discussions. As we're not using any popular or freely available forum software
- and have instead written something by ourselves, this discussion board has a
- few slight differences with the popular boards you're used to.
-</p>
-
-
-:SUB:Boards
-<p>
- To make sure interested people can find your post, all threads have relations
- to one or more 'boards' that define what the discussion is about. This is similar
- to boards on other forums, but here every item in the DB has its own board, and
- it's possible to link a thread to more than one board. The following boards can be used:
-</p>
-<dl>
- <dt>db</dt><dd>
- VNDB Discussions. This board is for discussions about the database and the site.
- </dd><dt>ge</dt><dd>
- General discussions. This is a general board for threads that do not fit in
- any of the other boards.
- </dd><dt>v#</dt><dd>
- For discussions about a particular visual novel. The board <i>v17</i>, for example,
- is used for all threads related to <a href="/v17">v17</a>.
- </dd><dt>p#</dt><dd>
- Same as <i>v#</i>, but for producers.
- </dd><dt>u#</dt><dd>
- The <i>u#</i> board can be used to notify a user on this site about something
- he/she must see or to discuss about an edit he/she has made. This is similar
- to the 'private message' feature of most sites, except it's not 'private'...
- </dd><dt>an</dt><dd>
- Used for site announcements. Limited to moderators.
- </dd>
-</dl>
-
-
-:SUB:Formatting
-<p>
- The following codes can be used to format your message:
-</p>
-<dl>
- <dt>X# or X#.#</dt><dd>
- A 'VNDBID', as we call them. These are numbers starting with a character (d, p, r, u or v),
- and are optionally followed by a period and a second number. VNDBIDs will automatically be converted
- into links to the page on the website. For example, typing 'v4.4' will result in '<a href="/v4.4">v4.4</a>'.
- </dd><dt>URL</dt><dd>
- Any URL (without the use of the [url]-tag, see below) will be converted into a link, similar to the
- VNDBIDs. Example: 'http://vndb.org/' will be formatted as '<a href="http://vndb.org/">link</a>'.
- </dd><dt>[url]</dt><dd>
- The classic BBCode [url]-tag. Can only be used in the form of <i>[url=link]link title[/url]</i>.<br />
- E.g. '[url=/v]List of visual novels[/url] and [url=http://blicky.net/]some external website[/url]'
- will be displayed as '<a href="/v">List of visual novels</a> and <a href="http://blicky.net/">some external website</a>'
- </dd><dt>[spoiler]</dt><dd>
- The [spoiler]-tag should be used to hide information that could spoil the enjoyment of playing the
- visual novel for people who haven't done so yet.
- </dd><dt>[quote]</dt><dd>
- When quoting other people, put the quoted message inside a [quote] .. [/quote] block. Please
- note that the popular [quote=source]-syntax doesn't work on VNDB. (yet)
- </dd><dt>[raw]</dt><dd>
- Show off your formatting code skills by putting anything you don't want to have formatted in a [raw]
- tag. Any of the formatting codes mentioned above are ignored within a [raw] .. [/raw] block.
- </dd><dt>[code]</dt><dd>
- Similar to [raw], except that the text within the [code] .. [/code] block is
- formatted in a fixed width font and surrounded by a nice box to keep it
- separate from the rest of your post.
- </dd>
-</dl>
-<p>
- There is no [img]-tag and there won't likely ever be one, if you want to include
- screenshots or other images, please upload them to an external hosting service
- (e.g. <a href="http://tinypic.com/" rel="nofollow">TinyPic</a>) and link to them
- in your post.
-</p>
-
-
diff --git a/data/docs/incomplete b/data/docs/incomplete
deleted file mode 100644
index 61109196..00000000
--- a/data/docs/incomplete
+++ /dev/null
@@ -1,4 +0,0 @@
-<div class="warning">
- The translation for this page is not synchronised with the original version.
- To see the latest version, switch to the <a href="/setlang?lang=en">English</a> website.
-</div>
diff --git a/data/docs/index b/data/docs/index
deleted file mode 100644
index 05339b6a..00000000
--- a/data/docs/index
+++ /dev/null
@@ -1,19 +0,0 @@
-<ul class="index">
- <li><b>Guidelines</b></li>
- <li><a href="/d5">Editing Guidelines</a></li>
- <li><a href="/d2">Visual Novels</a></li>
- <li><a href="/d15">Special Games</a></li>
- <li><a href="/d3">Releases</a></li>
- <li><a href="/d4">Producers</a></li>
- <li><a href="/d16">Staff</a></li>
- <li><a href="/d12">Characters</a></li>
- <li><a href="/d10">Tags &amp; Traits</a></li>
- <li><a href="/d13">Capturing Screenshots</a></li>
- <li><b>About VNDB</b></li>
- <li><a href="/d9">Discussion Board</a></li>
- <li><a href="/d6">FAQ</a></li>
- <li><a href="/d7">About Us</a></li>
- <li><a href="/d11">Database API</a></li>
- <li><a href="/d14">Database Dumps</a></li>
- <li><a href="/d8">Development</a></li>
-</ul>
diff --git a/data/docs/notfinished b/data/docs/notfinished
deleted file mode 100644
index 8b6b379f..00000000
--- a/data/docs/notfinished
+++ /dev/null
@@ -1,4 +0,0 @@
-<div class="warning">
- This page is not yet finished!<br />
- If you are interested in helping us finish it off, please join us on <a href="irc://irc.synirc.net/vndb">IRC</a>.
-</div>
diff --git a/data/style.css b/data/style.css
index 950b479e..1c4afa39 100644
--- a/data/style.css
+++ b/data/style.css
@@ -4,11 +4,13 @@ body { $_bodybg$; color: $maintext$ }
a { color: $link$; text-decoration: none; }
a:hover { border-bottom: 1px dotted $maintext$; }
table { border-collapse: collapse; }
-table td { vertical-align: top; padding: 3px; }
+table td,
+table th { vertical-align: top; padding: 3px; }
img { border: none; }
table tr.odd,
-table.stripe tbody tr:nth-child(odd):not(.nostripe) { background: url($_boxbg$) repeat; }
+table.stripe tbody tr:nth-child(odd):not(.nostripe),
+.docs table tbody tr:nth-child(odd) { background: url($_boxbg$) repeat; }
#bgright { position: absolute; top: 0px; right: 0px; $_bgright$ }
#header { position: absolute; top: 80px; left: 400px; }
@@ -264,7 +266,8 @@ p.browseopts a:hover { border: 0; padding: 2px 4px; }
div.mainbox.browse { padding: 0; }
div.mainbox.browse table { width: 100%; }
div.mainbox.browse table td.tc1 { padding-left: 25px; }
-table thead td { font-weight: bold; background-color: $secbg$; }
+table thead td, table thead th { font-weight: bold; background-color: $secbg$; }
+table thead th { text-align: left }
fieldset.search { display: block; width: 100%; text-align: center; margin: 0 0 10px 0; }
fieldset.search .submit { padding: 0 1px; }
p#searchtabs { height: 12px; padding-right: 70px; }
@@ -661,16 +664,25 @@ div.charsum_list .charsum_bubble {
/***** Documentation pages *****/
-.docs { padding: 0 15% 20px 15%; }
-.docs h3 { margin-top: 30px; font-size: 14px }
+.docs { padding: 0 15% 20px 15%; line-height: 1.4 }
+.docs h3 { margin: 30px 0 5px; font-size: 14px }
.docs h4 { margin-top: 15px; font-size: 12px }
-.docs dd { padding-bottom: 5px; margin-left: 120px; }
+.docs dd { margin: 5px 0 5px 120px }
.docs dt { float: left }
+.docs ul, .docs ol { margin: 5px 0 5px 20px }
+.docs table { margin: 10px; width: 95% }
+.docs td { white-space: nowrap }
+.docs td { white-space: nowrap }
+.docs td+td+td+td,
+.docs td[colspan],
+.docs td[colspan]+td,
+.docs td[colspan]+td+td { white-space: normal }
+.docs p + p { padding-top: 10px }
.docs ul.index { display: block; float: right; width: 150px; padding: 2px; margin: 0 0 10px 5px; background: url($_boxbg$) repeat; border: 1px solid $border$; }
.docs ul.index li { list-style-type: none; }
.docs ul.index li a { margin: 0 0 0 10px; }
-.docs .retired { text-decoration: line-through; }
.docs dt b { color: $grayedout$; font-weight: normal; font-style: normal; font-size: 12px; }
+.docs img { margin: 5px }
diff --git a/lib/Multi/Feed.pm b/lib/Multi/Feed.pm
index 86f0ffa1..b4cddfac 100644
--- a/lib/Multi/Feed.pm
+++ b/lib/Multi/Feed.pm
@@ -44,14 +44,15 @@ sub generate {
# changes
pg_cmd q{
- SELECT '/'||c.type||COALESCE(v.id, r.id, p.id, c.id, s.id)||'.'||c.rev AS id,
- COALESCE(v.title, r.title, p.name, ca.name, sa.name) AS title, extract('epoch' from c.added) AS updated,
+ SELECT '/'||c.type||COALESCE(v.id, r.id, p.id, ca.id, s.id, d.id)||'.'||c.rev AS id,
+ COALESCE(v.title, r.title, p.name, ca.name, sa.name, d.title) AS title, extract('epoch' from c.added) AS updated,
u.username, u.id AS uid, c.comments AS summary
FROM changes c
LEFT JOIN vn v ON c.type = 'v' AND c.itemid = v.id
LEFT JOIN releases r ON c.type = 'r' AND c.itemid = r.id
LEFT JOIN producers p ON c.type = 'p' AND c.itemid = p.id
LEFT JOIN chars ca ON c.type = 'c' AND c.itemid = ca.id
+ LEFT JOIN docs d ON c.type = 'd' AND c.itemid = d.id
LEFT JOIN staff s ON c.type = 's' AND c.itemid = s.id
LEFT JOIN staff_alias sa ON sa.id = s.id AND sa.aid = s.aid
JOIN users u ON u.id = c.requester
diff --git a/lib/Multi/IRC.pm b/lib/Multi/IRC.pm
index ef36bace..b1be1a24 100644
--- a/lib/Multi/IRC.pm
+++ b/lib/Multi/IRC.pm
@@ -218,9 +218,8 @@ sub set_notify {
# type database item in [dvprtug]
# id database id
# title main name or title of the DB entry
-# rev (optional) revision, post number or section number
+# rev (optional) revision, post number
# username (optional) relevant username
-# section (optional, for d+.+) section title
# boards (optional) board titles the thread has been posted in
# comments (optional) edit summary
sub formatid {
@@ -238,6 +237,7 @@ sub formatid {
g => 'tag',
i => 'trait',
t => 'thread',
+ d => 'doc',
);
for (@$res) {
@@ -267,9 +267,6 @@ sub formatid {
length $_->{comments} > 40 ? substr($_->{comments}, 0, 37).'...' : $_->{comments}
) if defined $_->{comments};
- # (for d+.+) -> section title
- push @msg, $c."->$NORMAL $_->{section}" if $_->{section};
-
# (always) @ URL
push @msg, $c."@ $NORMAL$LIGHT_GREY$VNDB::S{url}/$id$NORMAL";
@@ -303,8 +300,9 @@ sub handleid {
$t eq 't' ? 'title, '.$GETBOARDS.' FROM threads t WHERE id = $2' :
$t eq 'g' ? 'name AS title FROM tags WHERE id = $2' :
$t eq 'i' ? 'name AS title FROM traits WHERE id = $2' :
+ $t eq 'd' ? 'title FROM docs WHERE id = $2' :
'r.title FROM releases r WHERE r.id = $2'),
- [ $t, $id ], $c if !$rev && $t =~ /[vprtugics]/;
+ [ $t, $id ], $c if !$rev && $t =~ /[dvprtugics]/;
# edit/insert of vn/release/producer or discussion board post
pg_cmd 'SELECT $1::text AS type, $2::integer AS id, $3::integer AS rev, '.(
@@ -313,23 +311,9 @@ sub handleid {
$t eq 'p' ? 'ph.name AS title, u.username, c.comments FROM changes c JOIN producers_hist ph ON c.id = ph.chid JOIN users u ON u.id = c.requester WHERE c.type = \'p\' AND c.itemid = $2 AND c.rev = $3' :
$t eq 'c' ? 'ch.name AS title, u.username, c.comments FROM changes c JOIN chars_hist ch ON c.id = ch.chid JOIN users u ON u.id = c.requester WHERE c.type = \'c\' AND c.itemid = $2 AND c.rev = $3' :
$t eq 's' ? 'sah.name AS title, u.username, c.comments FROM changes c JOIN staff_hist sh ON c.id = sh.chid JOIN users u ON u.id = c.requester JOIN staff_alias_hist sah ON sah.chid = c.id AND sah.aid = sh.aid WHERE c.type = \'s\' AND c.itemid = $2 AND c.rev = $3' :
+ $t eq 'd' ? 'dh.title, u.username, c.comments FROM changes c JOIN docs_hist dh ON c.id = dh.chid JOIN users u ON u.id = c.requester WHERE c.type = \'d\' AND c.itemid = $2 AND c.rev = $3' :
't.title, u.username, '.$GETBOARDS.' FROM threads t JOIN threads_posts tp ON tp.tid = t.id JOIN users u ON u.id = tp.uid WHERE t.id = $2 AND tp.num = $3'),
- [ $t, $id, $rev], $c if $rev && $t =~ /[vprtcs]/;
-
- # documentation page (need to parse the doc pages manually here)
- if($t eq 'd') {
- my $f = sprintf $VNDB::ROOT.'/data/docs/%d', $id;
- my($title, $sec, $sub) = (undef, 0);
- open my $F, '<', $f or next;
- while(<$F>) {
- chomp;
- $title = $1 if /^:TITLE:(.+)$/;
- $sub = $1 if $rev && /^:SUB:(.+)$/ && ++$sec == $rev;
- }
- close $F;
- next if $rev && !$sub;
- formatid([{type => 'd', id => $id, title => $title, rev => $rev, section => $sub}], $chan, 0);
- }
+ [ $t, $id, $rev], $c if $rev && $t =~ /[dvprtcs]/;
}
@@ -358,7 +342,7 @@ sub notify {
my $q = {
rev => q{
SELECT c.type, c.rev, c.comments, c.id AS lastid, c.itemid AS id,
- COALESCE(vh.title, rh.title, ph.name, ch.name, sah.name) AS title, u.username
+ COALESCE(vh.title, rh.title, ph.name, ch.name, sah.name, dh.title) AS title, u.username
FROM changes c
LEFT JOIN vn_hist vh ON c.type = 'v' AND c.id = vh.chid
LEFT JOIN releases_hist rh ON c.type = 'r' AND c.id = rh.chid
@@ -366,6 +350,7 @@ sub notify {
LEFT JOIN chars_hist ch ON c.type = 'c' AND c.id = ch.chid
LEFT JOIN staff_hist sh ON c.type = 's' AND c.id = sh.chid
LEFT JOIN staff_alias_hist sah ON c.type = 's' AND sah.aid = sh.aid AND sah.chid = c.id
+ LEFT JOIN docs_hist dh ON c.type = 'd' AND c.id = dh.chid
JOIN users u ON u.id = c.requester
WHERE c.id > $1 AND c.requester <> 1
ORDER BY c.id},
diff --git a/lib/VNDB/BBCode.pm b/lib/VNDB/BBCode.pm
index d2f3135d..7ddfcd1b 100644
--- a/lib/VNDB/BBCode.pm
+++ b/lib/VNDB/BBCode.pm
@@ -14,7 +14,7 @@ our @EXPORT = qw/bb2html bb2text/;
# [url=..] [/url]
# [raw] .. [/raw]
# link: http://../
-# dblink: v#, v#.#, d#.#.#
+# dblink: v+, v+.+, d+#+, d+#+.+
#
# Permitted nesting of formatting codes:
# spoiler -> url, raw, link, dblink
@@ -112,9 +112,9 @@ sub parse {
while($raw =~ m{(?:
\[ \/? (?i: spoiler|quote|code|url|raw ) [^\s\]]* \] | # tag
- d[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]* | # d#.#.#
- [tdvprcs][1-9][0-9]*\.[1-9][0-9]* | # v#.#
- [tdvprcsugi][1-9][0-9]* | # v#
+ d[1-9][0-9]* \# [1-9][0-9]* (?: \.[1-9][0-9]* )? | # d+#+[.+]
+ [tdvprcs][1-9][0-9]*\.[1-9][0-9]* | # v+.+
+ [tdvprcsugi][1-9][0-9]* | # v+
(?:https?|ftp)://[^><"\n\s\]\[]+[\d\w=/-] # link
)}xg) {
my $token = $&;
diff --git a/lib/VNDB/DB/Docs.pm b/lib/VNDB/DB/Docs.pm
new file mode 100644
index 00000000..27cabf6e
--- /dev/null
+++ b/lib/VNDB/DB/Docs.pm
@@ -0,0 +1,53 @@
+
+package VNDB::DB::Docs;
+
+use strict;
+use warnings;
+use Exporter 'import';
+
+our @EXPORT = qw|dbDocGet dbDocGetRev dbDocRevisionInsert|;
+
+
+# Can only fetch a single document.
+# $doc = $self->dbDocGet(id => $id);
+sub dbDocGet {
+ my $self = shift;
+ my %o = @_;
+
+ my $r = $self->dbAll('SELECT id, title, content FROM docs WHERE id = ?', $o{id});
+ return wantarray ? ($r, 0) : $r;
+}
+
+
+# options: id, rev
+sub dbDocGetRev {
+ my $self = shift;
+ my %o = @_;
+
+ $o{rev} ||= $self->dbRow('SELECT MAX(rev) AS rev FROM changes WHERE type = \'d\' AND itemid = ?', $o{id})->{rev};
+
+ my $r = $self->dbAll(q|
+ SELECT de.id, d.title, d.content, de.hidden, de.locked,
+ extract('epoch' from c.added) as added, c.requester, c.comments, u.username, c.rev, c.ihid, c.ilock, c.id AS cid,
+ NOT EXISTS(SELECT 1 FROM changes c2 WHERE c2.type = c.type AND c2.itemid = c.itemid AND c2.rev = c.rev+1) AS lastrev
+ FROM changes c
+ JOIN docs de ON de.id = c.itemid
+ JOIN docs_hist d ON d.chid = c.id
+ JOIN users u ON u.id = c.requester
+ WHERE c.type = 'd' AND c.itemid = ? AND c.rev = ?|,
+ $o{id}, $o{rev}
+ );
+ return wantarray ? ($r, 0) : $r;
+}
+
+
+# Updates the edit_* tables, used from dbItemEdit()
+# Arguments: { title content },
+sub dbDocRevisionInsert {
+ my($self, $o) = @_;
+ my %set = map exists($o->{$_}) ? (qq|"$_" = ?|, $o->{$_}) : (), qw|title content|;
+ $self->dbExec('UPDATE edit_docs !H', \%set) if keys %set;
+}
+
+
+1;
diff --git a/lib/VNDB/DB/Misc.pm b/lib/VNDB/DB/Misc.pm
index d6389376..61bb71a2 100644
--- a/lib/VNDB/DB/Misc.pm
+++ b/lib/VNDB/DB/Misc.pm
@@ -21,7 +21,7 @@ sub dbStats {
# Inserts a new revision into the database
-# Arguments: type [vrp], itemid, rev, %options->{ editsum uid ihid ilock + db[item]RevisionInsert }
+# Arguments: type [vrpcsd], itemid, rev, %options->{ editsum uid ihid ilock + db[item]RevisionInsert }
# rev = changes.rev of the revision this edit is based on, undef to create a new DB item
# Returns: { itemid, chid, rev }
sub dbItemEdit {
@@ -41,6 +41,7 @@ sub dbItemEdit {
$self->dbReleaseRevisionInsert( \%o) if $type eq 'r';
$self->dbCharRevisionInsert( \%o) if $type eq 'c';
$self->dbStaffRevisionInsert( \%o) if $type eq 's';
+ $self->dbDocRevisionInsert( \%o) if $type eq 'd';
return $self->dbRow('SELECT * FROM edit_!s_commit()', $type);
}
@@ -98,6 +99,7 @@ sub dbRevisionGet {
UNION ALL SELECT 'r'::dbentry_type, chid, title, original FROM releases_hist
UNION ALL SELECT 'p'::dbentry_type, chid, name, original FROM producers_hist
UNION ALL SELECT 'c'::dbentry_type, chid, name, original FROM chars_hist
+ UNION ALL SELECT 'd'::dbentry_type, chid, title, '' AS original FROM docs_hist
UNION ALL SELECT 's'::dbentry_type, sh.chid, name, original FROM staff_hist sh JOIN staff_alias_hist sah ON sah.chid = sh.chid AND sah.aid = sh.aid
) x(type, id, title, original)
WHERE $w
diff --git a/lib/VNDB/Handler/Discussions.pm b/lib/VNDB/Handler/Discussions.pm
index f7f26a5e..f6b68c36 100644
--- a/lib/VNDB/Handler/Discussions.pm
+++ b/lib/VNDB/Handler/Discussions.pm
@@ -304,7 +304,7 @@ sub edit {
!$tid || $num == 1 ? (
[ input => short => 'title', name => 'Thread title' ],
[ input => short => 'boards', name => 'Board(s)' ],
- [ static => content => 'Read <a href="/d9.2">d9.2</a> for information about how to specify boards.' ],
+ [ static => content => 'Read <a href="/d9#2">d9#2</a> for information about how to specify boards.' ],
$self->authCan('boardmod') ? (
[ check => name => 'Locked', short => 'locked' ],
) : (),
@@ -318,7 +318,7 @@ sub edit {
) : (),
) : (),
[ text => name => 'Message<br /><b class="standout">English please!</b>', short => 'msg', rows => 25, cols => 75 ],
- [ static => content => 'See <a href="/d9.3">d9.3</a> for the allowed formatting codes' ],
+ [ static => content => 'See <a href="/d9#3">d9#3</a> for the allowed formatting codes' ],
(!$tid || $num == 1) ? (
[ static => content => '<br />' ],
[ check => short => 'poll', name => 'Add poll' ],
diff --git a/lib/VNDB/Handler/Docs.pm b/lib/VNDB/Handler/Docs.pm
new file mode 100644
index 00000000..bc1166d5
--- /dev/null
+++ b/lib/VNDB/Handler/Docs.pm
@@ -0,0 +1,177 @@
+
+package VNDB::Handler::Docs;
+
+
+use strict;
+use warnings;
+use TUWF ':html';
+use VNDB::Func;
+use Text::MultiMarkdown 'markdown';
+
+
+TUWF::register(
+ qr{d([1-9]\d*)(?:\.([1-9]\d*))?} => \&page,
+ qr{d([1-9]\d*)(?:\.([1-9]\d*))?/edit} => \&edit,
+);
+
+
+sub _html {
+ my $content = shift;
+
+ $content =~ s{^:MODERATORS:$}{
+ my $l = tuwf->dbUserGet(results => 100, sort => 'id', notperm => tuwf->{default_perm}, what => 'extended');
+ my $admin = 0;
+ $admin |= $_ for values %{ tuwf->{permissions} };
+ '<dl>'.join('', map {
+ my $u = $_;
+ my $p = $u->{perm} >= $admin ? 'admin' : join ', ', sort map +($u->{perm} &~ tuwf->{default_perm}) & tuwf->{permissions}{$_} ? $_ : (), keys %{ tuwf->{permissions} };
+ $p ? sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>', $_->{id}, $_->{username}, $p) : ()
+ } @$l).'</dl>';
+ }me;
+ $content =~ s{^:SKINCONTRIB:$}{
+ my %users;
+ push @{$users{ tuwf->{skins}{$_}[1] }}, [ $_, tuwf->{skins}{$_}[0] ]
+ for sort { tuwf->{skins}{$a}[0] cmp tuwf->{skins}{$b}[0] } keys %{ tuwf->{skins} };
+ my $u = tuwf->dbUserGet(uid => [ keys %users ]);
+ '<dl>'.join('', map sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>',
+ $_->{id}, $_->{username}, join(', ', map sprintf('<a href="?skin=%s">%s</a>', $_->[0], $_->[1]), @{$users{$_->{id}}})
+ ), @$u).'</dl>';
+ }me;
+
+ my $html = markdown $content, {
+ strip_metadata => 1,
+ img_ids => 0,
+ disable_footnotes => 1,
+ disable_bibliography => 1,
+ };
+
+ # Number sections and turn them into links
+ my($sec, $subsec) = (0,0);
+ $html =~ s{<h([1-2])[^>]+>(.*?)</h\1>}{
+ if($1 == 1) {
+ $sec++;
+ $subsec = 0;
+ qq{<h3><a href="#$sec" name="$sec">$sec. $2</a></h3>}
+ } elsif($1 == 2) {
+ $subsec++;
+ qq|<h4><a href="#$sec.$subsec" name="$sec.$subsec">$sec.$subsec. $2</a></h4>\n|
+ }
+ }ge;
+
+ # Text::MultiMarkdown doesn't handle fenced code blocks properly. The
+ # following solution breaks inline code blocks, but I don't use those anyway.
+ $html =~ s/<code>/<pre>/g;
+ $html =~ s#</code>#</pre>#g;
+
+ $html
+}
+
+
+sub page {
+ my($self, $id, $rev) = @_;
+
+ my $method = $rev ? 'dbDocGetRev' : 'dbDocGet';
+ my $d = $self->$method(id => $id, $rev ? ( rev => $rev ) : ())->[0];
+ return $self->resNotFound if !$d->{id};
+
+ $self->htmlHeader(title => $d->{title}, noindex => $rev);
+ $self->htmlMainTabs(d => $d);
+ return if $self->htmlHiddenMessage('d', $d);
+
+ if($rev) {
+ my $prev = $rev && $rev > 1 && $self->dbDocGetRev(id => $id, rev => $rev-1)->[0];
+ $self->htmlRevision('d', $prev, $d,
+ [ title => 'Title', diff => 1 ],
+ [ content => 'Content', diff => qr/\s+/ ],
+ );
+ }
+
+ div class => 'mainbox';
+ h1 $d->{title};
+ div class => 'docs';
+ ul class => 'index';
+ li; b 'Guidelines'; end;
+ li; a href => '/d5', 'Editing Guidelines'; end;
+ li; a href => '/d2', 'Visual Novels'; end;
+ li; a href => '/d15', 'Special Games'; end;
+ li; a href => '/d3', 'Releases'; end;
+ li; a href => '/d4', 'Producers'; end;
+ li; a href => '/d16', 'Staff'; end;
+ li; a href => '/d12', 'Characters'; end;
+ li; a href => '/d10', 'Tags & Traits'; end;
+ li; a href => '/d13', 'Capturing Screenshots'; end;
+ li; b 'About VNDB'; end;
+ li; a href => '/d9', 'Discussion Board'; end;
+ li; a href => '/d6', 'FAQ'; end;
+ li; a href => '/d7', 'About Us'; end;
+ li; a href => '/d11', 'Database API'; end;
+ li; a href => '/d14', 'Database Dumps'; end;
+ end;
+ lit _html $d->{content};
+ end;
+ end;
+ $self->htmlFooter;
+}
+
+
+sub edit {
+ my($self, $id, $rev) = @_;
+
+ my $d = $self->dbDocGetRev(id => $id, rev => $rev)->[0];
+ return $self->resNotFound if !$d->{id};
+ $rev = undef if $d->{lastrev};
+
+ return $self->htmlDenied if !$self->authCan('dbmod');
+
+ my %b4 = map { $_ => $d->{$_} } qw|title content ihid ilock|;
+ my $frm;
+
+ if($self->reqMethod eq 'POST') {
+ return if !$self->authCheckCode;
+ $frm = $self->formValidate(
+ { post => 'title', maxlength => 200 },
+ { post => 'content', },
+ { post => 'editsum', template => 'editsum' },
+ { post => 'ihid', required => 0 },
+ { post => 'ilock', required => 0 },
+ { post => 'preview', required => 0 },
+ );
+ if(!$frm->{_err} && !$frm->{preview}) {
+ $frm->{ihid} = $frm->{ihid}?1:0;
+ $frm->{ilock} = $frm->{ilock}?1:0;
+
+ return $self->resRedirect("/d$id", 'post') if !form_compare(\%b4, $frm);
+ my $nrev = $self->dbItemEdit(d => $id, $d->{rev}, %$frm);
+ return $self->resRedirect("/d$nrev->{itemid}.$nrev->{rev}", 'post');
+ }
+ }
+
+ !defined $frm->{$_} && ($frm->{$_} = $b4{$_}) for keys %b4;
+ $frm->{editsum} = sprintf 'Reverted to revision d%d.%d', $id, $rev if $rev && !defined $frm->{editsum};
+ delete $frm->{_err} if $frm->{preview};
+
+ my $title = "Edit $d->{title}";
+ $self->htmlHeader(title => $title, noindex => 1);
+ $self->htmlMainTabs('d', $d, 'edit');
+
+ if($frm->{preview}) {
+ div class => 'mainbox';
+ h1 'Preview';
+ div class => 'docs';
+ lit _html $frm->{content};
+ end;
+ end;
+ }
+
+ $self->htmlForm({ frm => $frm, action => "/d$id/edit", editsum => 1, preview => 1 }, dedit => [ $title,
+ [ input => name => 'Title', short => 'title', width => 300 ],
+ [ static => nolabel => 1, content => q{
+ <br>Contents (HTML and MultiMarkdown supported, which is
+ <a href="https://daringfireball.net/projects/markdown/basics">Markdown</a>
+ with some <a href="http://fletcher.github.io/MultiMarkdown-5/syntax.html">extensions</a>).} ],
+ [ textarea => short => 'content', name => 'Content', rows => 50, cols => 90, nolabel => 1 ],
+ ]);
+ $self->htmlFooter;
+}
+
+1;
diff --git a/lib/VNDB/Handler/Misc.pm b/lib/VNDB/Handler/Misc.pm
index e3b67d52..771c9d83 100644
--- a/lib/VNDB/Handler/Misc.pm
+++ b/lib/VNDB/Handler/Misc.pm
@@ -4,18 +4,16 @@ package VNDB::Handler::Misc;
use strict;
use warnings;
-use TUWF ':html', ':xml', 'xml_escape', 'uri_escape';
+use TUWF ':html', ':xml', 'uri_escape';
use VNDB::Func;
-use POSIX 'strftime';
TUWF::register(
- qr{}, \&homepage,
- qr{(?:([upvrcs])([1-9]\d*)/)?hist},\&history,
- qr{d([1-9]\d*)}, \&docpage,
- qr{nospam}, \&nospam,
- qr{xml/prefs\.xml}, \&prefs,
- qr{opensearch\.xml}, \&opensearch,
+ qr{}, \&homepage,
+ qr{(?:([upvrcsd])([1-9]\d*)/)?hist},\&history,
+ qr{nospam}, \&nospam,
+ qr{xml/prefs\.xml}, \&prefs,
+ qr{opensearch\.xml}, \&opensearch,
# redirects for old URLs
qr{u([1-9]\d*)/tags}, sub { $_[0]->resRedirect("/g/links?u=$_[1]", 'perm') },
@@ -28,8 +26,6 @@ TUWF::register(
sub { $_[0]->resRedirect("/v$_[1]", 'perm') },
qr{u/list(/[a-z0]|/all)?},
sub { my $l = defined $_[1] ? $_[1] : '/all'; $_[0]->resRedirect("/u$l", 'perm') },
- qr{d([1-9]\d*)\.([1-9]\d*)},
- sub { $_[0]->resRedirect("/d$_[1]#$_[2]", 'perm') }
);
@@ -206,7 +202,7 @@ sub history {
{ get => 'p', required => 0, default => 1, template => 'page' },
{ get => 'm', required => 0, default => !$type, enum => [ 0, 1 ] },
{ get => 'h', required => 0, default => 0, enum => [ -1..1 ] },
- { get => 't', required => 0, default => '', enum => [qw|v r p c s a|] },
+ { get => 't', required => 0, default => '', enum => [qw|v r p c s d a|] },
{ get => 'e', required => 0, default => 0, enum => [ -1..1 ] },
{ get => 'r', required => 0, default => 0, enum => [ 0, 1 ] },
);
@@ -218,6 +214,7 @@ sub history {
$type eq 'r' ? $self->dbReleaseGet(id => $id)->[0] :
$type eq 'c' ? $self->dbCharGet(id => $id)->[0] :
$type eq 's' ? $self->dbStaffGet(id => $id)->[0] :
+ $type eq 'd' ? $self->dbDocGet(id => $id)->[0] :
$type eq 'v' ? $self->dbVNGet(id => $id)->[0] : undef;
return $self->resNotFound if $type && !$obj->{id};
my $title = $type ? 'Edit history of '.($obj->{title} || $obj->{name} || $obj->{username}) : 'Recent changes';
@@ -226,7 +223,7 @@ sub history {
my($list, $np) = $self->dbRevisionGet(
$type && $type ne 'u' ? ( type => $type, itemid => $id ) : (),
$type eq 'u' ? ( uid => $id ) : (),
- $f->{t} ? ( type => $f->{t} eq 'a' ? [qw|v r p s|] : $f->{t} ) : (),
+ $f->{t} ? ( type => $f->{t} eq 'a' ? [qw|v r p s d|] : $f->{t} ) : (),
page => $f->{p},
results => 50,
auto => $f->{m},
@@ -273,6 +270,7 @@ sub history {
a $f->{t} eq 'p' ? (class => 'optselected') : (), href => $u->(t => 'p'), 'Only producers';
a $f->{t} eq 's' ? (class => 'optselected') : (), href => $u->(t => 's'), 'Only staff';
a $f->{t} eq 'c' ? (class => 'optselected') : (), href => $u->(t => 'c'), 'Only characters';
+ a $f->{t} eq 'd' ? (class => 'optselected') : (), href => $u->(t => 'd'), 'Only docs';
a $f->{t} eq 'a' ? (class => 'optselected') : (), href => $u->(t => 'a'), 'All except characters';
end;
p class => 'browseopts';
@@ -294,68 +292,6 @@ sub history {
}
-sub docpage {
- my($self, $did) = @_;
-
- my $f = sprintf('%s/data/docs/%d', $VNDB::ROOT, $did);
- my $F;
- open($F, '<:utf8', $f) or return $self->resNotFound;
- my @c = <$F>;
- close $F;
-
- (my $title = shift @c) =~ s/^:TITLE://;
- chomp $title;
-
- my($sec, $subsec) = (0,0);
- for (@c) {
- s{^:SUB:(.+)\r?\n$}{
- $sec++;
- $subsec = 0;
- qq|<h3><a href="#$sec" name="$sec">$sec. $1</a></h3>\n|
- }e;
- s{^:SUBSUB:(.+)\r?\n$}{
- $subsec++;
- qq|<h4><a href="#$sec.$subsec" name="$sec.$subsec">$sec.$subsec. $1</a></h4>\n|
- }e;
- s{^:INC:(.+)\r?\n$}{
- $f = sprintf('%s/data/docs/%s', $VNDB::ROOT, $1);
- open($F, '<:utf8', $f) or die $!;
- my $ii = join('', <$F>);
- close $F;
- $ii;
- }e;
- s{^:MODERATORS:$}{
- my $l = $self->dbUserGet(results => 100, sort => 'id', notperm => $self->{default_perm}, what => 'extended');
- my $admin = 0;
- $admin |= $_ for values %{$self->{permissions}};
- '<dl>'.join('', map {
- my $u = $_;
- my $p = $u->{perm} >= $admin ? 'admin' : join ', ', sort map +($u->{perm} &~ $self->{default_perm}) & $self->{permissions}{$_} ? $_ : (), keys %{$self->{permissions}};
- $p ? sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>', $_->{id}, $_->{username}, $p) : ()
- } @$l).'</dl>';
- }e;
- s{^:SKINCONTRIB:$}{
- my %users;
- push @{$users{ $self->{skins}{$_}[1] }}, [ $_, $self->{skins}{$_}[0] ]
- for sort { $self->{skins}{$a}[0] cmp $self->{skins}{$b}[0] } keys %{$self->{skins}};
- my $u = $self->dbUserGet(uid => [ keys %users ]);
- '<dl>'.join('', map sprintf('<dt><a href="/u%d">%s</a></dt><dd>%s</dd>',
- $_->{id}, $_->{username}, join(', ', map sprintf('<a href="?skin=%s">%s</a>', $_->[0], $_->[1]), @{$users{$_->{id}}})
- ), @$u).'</dl>';
- }e;
- }
-
- $self->htmlHeader(title => $title);
- div class => 'mainbox';
- h1 $title;
- div class => 'docs';
- lit join '', @c;
- end;
- end;
- $self->htmlFooter;
-}
-
-
sub nospam {
my $self = shift;
$self->htmlHeader(title => 'Could not send form', noindex => 1);
diff --git a/lib/VNDB/Handler/VNEdit.pm b/lib/VNDB/Handler/VNEdit.pm
index ce10611d..e08925f7 100644
--- a/lib/VNDB/Handler/VNEdit.pm
+++ b/lib/VNDB/Handler/VNEdit.pm
@@ -319,7 +319,7 @@ sub _form {
@alist ? @{$self->dbStaffGet(aid => \@alist, results => 200)} : ()
};
div class => 'warning';
- lit 'Please check the <a href="/d2.3">staff editing guidelines</a>. You can'
+ lit 'Please check the <a href="/d2#3">staff editing guidelines</a>. You can'
.' <a href="/s/new">create a new staff entry</a> if it is not in the database yet,'
.' but please <a href="/s/all">check for aliasses first</a>.';
end;
diff --git a/lib/VNDB/Util/CommonHTML.pm b/lib/VNDB/Util/CommonHTML.pm
index e8561e3c..dd129c18 100644
--- a/lib/VNDB/Util/CommonHTML.pm
+++ b/lib/VNDB/Util/CommonHTML.pm
@@ -18,7 +18,7 @@ our @EXPORT = qw|
# generates the "main tabs". These are the commonly used tabs for
# 'objects', i.e. VN/producer/release entries and users
-# Arguments: u/v/r/p/g/i/c, object, currently selected item (empty=main)
+# Arguments: u/v/r/p/g/i/c/d, object, currently selected item (empty=main)
sub htmlMainTabs {
my($self, $type, $obj, $sel) = @_;
$sel ||= '';
@@ -27,7 +27,7 @@ sub htmlMainTabs {
return if $type eq 'g' && !$self->authCan('tagmod');
ul class => 'maintabs';
- if($type =~ /[uvrpcs]/) {
+ if($type =~ /[uvrpcsd]/) {
li $sel eq 'hist' ? (class => 'tabselected') : ();
a href => "/$id/hist", 'history';
end;
@@ -75,6 +75,7 @@ sub htmlMainTabs {
if( $type eq 'u' && ($self->authInfo->{id} && $obj->{id} == $self->authInfo->{id} || $self->authCan('usermod'))
|| $type =~ /[vrpcs]/ && $self->authCan('edit') && ((!$obj->{locked} && !$obj->{hidden}) || $self->authCan('dbmod'))
|| $type =~ /[gi]/ && $self->authCan('tagmod')
+ || $type eq 'd' && $self->authCan('dbmod')
) {
li $sel eq 'edit' ? (class => 'tabselected') : ();
a href => "/$id/edit", 'edit';
@@ -132,12 +133,13 @@ sub htmlDenied {
sub htmlHiddenMessage {
my($self, $type, $obj) = @_;
return 0 if !$obj->{hidden};
- my $board = $type =~ /[cs]/ ? 'db' : $type eq 'r' ? 'v'.$obj->{vn}[0]{vid} : $type.$obj->{id};
+ my $board = $type =~ /[csd]/ ? 'db' : $type eq 'r' ? 'v'.$obj->{vn}[0]{vid} : $type.$obj->{id};
# fetch edit summary (not present in $obj, requires the db*GetRev() methods)
my $editsum = $type eq 'v' ? $self->dbVNGetRev(id => $obj->{id})->[0]{comments}
: $type eq 'r' ? $self->dbReleaseGetRev(id => $obj->{id})->[0]{comments}
: $type eq 'c' ? $self->dbCharGetRev(id => $obj->{id})->[0]{comments}
: $type eq 's' ? $self->dbStaffGetRev(id => $obj->{id})->[0]{comments}
+ : $type eq 'd' ? $self->dbDocGetRev(id => $obj->{id})->[0]{comments}
: $self->dbProducerGetRev(id => $obj->{id})->[0]{comments};
div class => 'mainbox';
h1 $obj->{title}||$obj->{name};
@@ -156,7 +158,7 @@ sub htmlHiddenMessage {
# Shows a revision, including diff if there is a previous revision.
-# Arguments: v|p|r|c, old revision, new revision, @fields
+# Arguments: v|p|r|c|d, old revision, new revision, @fields
# Where @fields is a list of fields as arrayrefs with:
# [ shortname, displayname, %options ],
# Where %options:
diff --git a/lib/VNDB/Util/FormHTML.pm b/lib/VNDB/Util/FormHTML.pm
index a522599e..11de460b 100644
--- a/lib/VNDB/Util/FormHTML.pm
+++ b/lib/VNDB/Util/FormHTML.pm
@@ -54,7 +54,7 @@ sub htmlFormError {
li "$field: Malformed data or invalid input" if $rule eq 'json';
li 'Invalid release date' if $rule eq 'rdate';
if($rule eq 'editsum') {
- li; lit 'Please read <a href="/d5.4">the guidelines</a> on how to use the edit summary.'; end;
+ li; lit 'Please read <a href="/d5#4">the guidelines</a> on how to use the edit summary.'; end;
}
}
}
@@ -187,6 +187,7 @@ sub htmlFormPart {
# nosubmit => 1/0, hides the submit button
# editsum => 1/0, adds an edit summary field before the submit button
# continue => 2/1/0, replace submit button with continue buttons
+# preview => 1/0, add preview button
# noformcode=> 1/0, remove the formcode field
# The other arguments are a list of subforms in the form
# of (subform-name => [form parts]). Each subform is shown as a
@@ -265,6 +266,7 @@ sub htmlForm {
input type => 'submit', name => 'continue_ign', value => 'Continue and ignore duplicates',
class => 'submit', style => 'width: auto', tabindex => 10 if $options->{continue} == 2;
}
+ input type => 'submit', value => 'Preview', id => 'preview', name => 'preview', class => 'submit', tabindex => 10 if $options->{preview};
end;
end 'div';
}
diff --git a/util/bbcode-test.pl b/util/bbcode-test.pl
index ba39fb13..1100b34e 100755
--- a/util/bbcode-test.pl
+++ b/util/bbcode-test.pl
@@ -105,6 +105,10 @@ my @tests = (
'<a href="/r12.1">r12.1</a> <a href="/v6.3">v6.3</a> <a href="/s1.2">s1.2</a>',
'r12.1 v6.3 s1.2',
+ 'd3 d1.3 d2#4 d5#6.7',
+ '<a href="/d3">d3</a> <a href="/d1.3">d1.3</a> <a href="/d2#4">d2#4</a> <a href="/d5#6.7">d5#6.7</a>',
+ 'd3 d1.3 d2#4 d5#6.7',
+
'v17 text dds16v21 more text1 v9',
'<a href="/v17">v17</a> text dds16v21 more text1 <a href="/v9">v9</a>',
'v17 text dds16v21 more text1 v9',
diff --git a/util/sql/all.sql b/util/sql/all.sql
index b3a87948..a8009b0d 100644
--- a/util/sql/all.sql
+++ b/util/sql/all.sql
@@ -8,13 +8,13 @@ CREATE TYPE blood_type AS ENUM ('unknown', 'a', 'b', 'ab', 'o');
CREATE TYPE board_type AS ENUM ('an', 'db', 'ge', 'v', 'p', 'u');
CREATE TYPE char_role AS ENUM ('main', 'primary', 'side', 'appears');
CREATE TYPE credit_type AS ENUM ('scenario', 'chardesign', 'art', 'music', 'songs', 'director', 'staff');
-CREATE TYPE dbentry_type AS ENUM ('v', 'r', 'p', 'c', 's');
+CREATE TYPE dbentry_type AS ENUM ('v', 'r', 'p', 'c', 's', 'd');
CREATE TYPE edit_rettype AS (itemid integer, chid integer, rev integer);
CREATE TYPE gender AS ENUM ('unknown', 'm', 'f', 'b');
CREATE TYPE language AS ENUM ('ar', 'bg', 'ca', 'cs', 'da', 'de', 'en', 'es', 'fi', 'fr', 'he', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'nl', 'no', 'pl', 'pt-pt', 'pt-br', 'ro', 'ru', 'sk', 'sv', 'ta', 'th', 'tr', 'uk', 'vi', 'zh');
CREATE TYPE medium AS ENUM ('cd', 'dvd', 'gdr', 'blr', 'flp', 'mrt', 'mem', 'umd', 'nod', 'in', 'otc');
CREATE TYPE notification_ntype AS ENUM ('pm', 'dbdel', 'listdel', 'dbedit', 'announce');
-CREATE TYPE notification_ltype AS ENUM ('v', 'r', 'p', 'c', 't', 's');
+CREATE TYPE notification_ltype AS ENUM ('v', 'r', 'p', 'c', 't', 's', 'd');
CREATE TYPE platform AS ENUM ('win', 'dos', 'lin', 'mac', 'ios', 'and', 'dvd', 'bdp', 'fmt', 'gba', 'gbc', 'msx', 'nds', 'nes', 'p88', 'p98', 'pce', 'pcf', 'psp', 'ps1', 'ps2', 'ps3', 'ps4', 'psv', 'drc', 'sat', 'sfc', 'swi', 'wii', 'wiu', 'n3d', 'x68', 'xb1', 'xb3', 'xbo', 'web', 'oth');
CREATE TYPE prefs_key AS ENUM ('l10n', 'skin', 'customcss', 'filter_vn', 'filter_release', 'show_nsfw', 'hide_list', 'notify_nodbedit', 'notify_announce', 'vn_list_own', 'vn_list_wish', 'tags_all', 'tags_cat', 'spoilers', 'traits_sexual');
CREATE TYPE producer_type AS ENUM ('co', 'in', 'ng');
diff --git a/util/sql/devdb.sql b/util/sql/devdb.sql
index b4c3e4c4..dea9ab29 100644
--- a/util/sql/devdb.sql
+++ b/util/sql/devdb.sql
@@ -4,7 +4,7 @@
SET CONSTRAINTS ALL DEFERRED;
-- Hack to disable triggers
SET session_replication_role = replica;
-TRUNCATE TABLE chars_vns, chars_traits_hist, staff_hist, tags_vn, vn_anime_hist, sessions, releases_lang_hist, releases_lang, rlists, releases_producers_hist, releases_platforms, releases_producers, releases_vn_hist, tags_parents, screenshots, stats_cache, threads_poll_options, threads_poll_votes, traits_parents, votes, vn_relations_hist, vn_screenshots_hist, vn_hist, vn_relations, releases_vn, releases_media, releases_hist, vn_seiyuu_hist, vn_screenshots, vn_seiyuu, vn_staff_hist, traits, producers_hist, releases_platforms_hist, producers_relations, releases_media_hist, chars_hist, chars, staff, users_prefs, vn, tags_aliases, affiliate_links, vn_anime, releases, login_throttle, relgraphs, tags, staff_alias, traits_chars, threads_posts, threads, threads_boards, tags_vn_inherit, users, vn_staff, vnlists, notifications, chars_traits, producers, anime, staff_alias_hist, wlists, chars_vns_hist, quotes, changes, producers_relations_hist CASCADE;
+TRUNCATE TABLE chars_traits_hist, chars_vns_hist, releases_media_hist, releases_lang_hist, releases_platforms_hist, releases_producers_hist, releases_vn_hist, threads_poll_options, threads_poll_votes, vn_relations_hist, vn_seiyuu_hist, vn_anime_hist, affiliate_links, anime, changes, chars, chars_hist, chars_traits, chars_vns, docs, docs_hist, login_throttle, notifications, producers, producers_hist, producers_relations, quotes, releases, releases_hist, releases_lang, releases_media, releases_platforms, releases_producers, releases_vn, relgraphs, rlists, screenshots, staff, staff_alias, staff_alias_hist, staff_hist, stats_cache, tags, tags_aliases, tags_parents, tags_vn, tags_vn_inherit, threads, threads_boards, threads_posts, traits, traits_chars, traits_parents, users, users_prefs, vn, vn_anime, vn_hist, vn_relations, vn_screenshots, vn_screenshots_hist, vn_seiyuu, vn_staff, vn_staff_hist, vnlists, producers_relations_hist, votes, wlists, sessions CASCADE;
SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
@@ -28,8 +28,8 @@ COPY anime (id, year, ann_id, nfo_id, type, title_romaji, title_kanji, lastfetch
COPY users (id, username, mail, perm, passwd, registered, c_votes, c_changes, ip, c_tags, ign_votes, email_confirmed) FROM stdin;
0 deleted del@vndb.org 0 \\x 2018-01-04 19:13:32.823908+00 0 0 0.0.0.0 0 f f
6 user user@vndb.org 21 \\x0001000008013fb73157f3cdcd27990198726e7e083007b307adcc70a4705170acd69e307f5e764e031d28d39eb4 2018-01-04 22:25:42.054632+00 0 3 0.0.0.0 0 f f
-1 multi multi@vndb.org 0 \\x 2018-01-04 19:13:32.82486+00 0 3 0.0.0.0 0 f f
4 admin admin@vndb.org 503 \\x000100000801ec4185fed438752d6b3b968e2b2cd045f70005cb7e10cafdbb694a82246bd34a065b6e977e0c3dcc 2018-01-04 19:26:10.731713+00 6 48 0.0.0.0 3 f f
+1 multi multi@vndb.org 0 \\x 2018-01-04 19:13:32.82486+00 0 17 0.0.0.0 0 f f
\.
COPY changes (id, type, itemid, rev, added, requester, ip, comments, ihid, ilock) FROM stdin;
1 v 1 1 2018-01-04 22:30:48.928438+00 4 0.0.0.0 add f f
@@ -50,8 +50,22 @@ COPY changes (id, type, itemid, rev, added, requester, ip, comments, ihid, ilock
16 v 2 4 2018-02-03 22:01:48.939799+00 4 0.0.0.0 relation f f
17 v 3 2 2018-02-03 22:01:48.939799+00 1 0.0.0.0 Reverse relation update caused by revision v2.4 f f
18 v 1 3 2018-02-03 22:02:58.404134+00 4 0.0.0.0 more info f f
-\.
-SELECT pg_catalog.setval('changes_id_seq', 18, true);
+19 d 2 1 2018-02-08 14:54:17.489737+00 1 0.0.0.0 Empty page f f
+20 d 3 1 2018-02-08 14:54:17.502614+00 1 0.0.0.0 Empty page f f
+21 d 4 1 2018-02-08 14:54:17.511867+00 1 0.0.0.0 Empty page f f
+22 d 5 1 2018-02-08 14:54:17.528422+00 1 0.0.0.0 Empty page f f
+23 d 6 1 2018-02-08 14:54:17.531662+00 1 0.0.0.0 Empty page f f
+24 d 7 1 2018-02-08 14:54:17.54061+00 1 0.0.0.0 Empty page f f
+25 d 9 1 2018-02-08 14:54:17.5497+00 1 0.0.0.0 Empty page f f
+26 d 10 1 2018-02-08 14:54:17.553128+00 1 0.0.0.0 Empty page f f
+27 d 11 1 2018-02-08 14:54:17.564129+00 1 0.0.0.0 Empty page f f
+28 d 12 1 2018-02-08 14:54:17.57348+00 1 0.0.0.0 Empty page f f
+29 d 13 1 2018-02-08 14:54:17.582157+00 1 0.0.0.0 Empty page f f
+30 d 14 1 2018-02-08 14:54:17.590882+00 1 0.0.0.0 Empty page f f
+31 d 15 1 2018-02-08 14:54:17.599512+00 1 0.0.0.0 Empty page f f
+32 d 16 1 2018-02-08 14:54:17.608296+00 1 0.0.0.0 Empty page f f
+\.
+SELECT pg_catalog.setval('changes_id_seq', 32, true);
SELECT pg_catalog.setval('charimg_seq', 1, false);
COPY chars (id, locked, hidden, name, original, alias, image, "desc", gender, s_bust, s_waist, s_hip, b_month, b_day, height, weight, bloodt, main, main_spoil) FROM stdin;
1 f f Celica A. Mercury セリカ゠アヤツキ゠マーキュリー Antenna Girl, Celica Ayatsuki Mercury 0 Hobbies: Strolls\nLikes: Sister, family\nDislikes: Nothing\n\nCelica Ayatsuki Mercury is the younger sister of Nine, Jubei's sister-in-law and aunt of Kokonoe. She is a playable character in Chronophantasma Extend and Centralfiction. After the Dark War, she watched over the Black Beast's remains and built a church. She was also the previous owner of the Nox Nyctores, Deus Machina: Nirvana, but both she and Trinity sealed Nirvana at some point.\n<hidden by spoiler settings>\n\nCelica is a kind, generous, and sociable person who deeply loves her sister and friends. She is a sentimental individual who maintains a firm stance that all life is precious and will use her healing magic to assist those in need of it, regardless of who or what they are. She is also shown to be selfless to the point that she will shield a person with her own body without any hesitation and is willing to sacrifice herself, believing that her sacrifice will be a small price to pay for the chance to defeat the Black Beast and save the world.\nIt has also been noted by people that she has no sense of direction, which usually ends with her getting lost. She is also shown to be very stubborn, such as when she ignores her sister's warnings and heads to Japan by herself to search for her missing father and is also unwilling to admit that she has a poor sense of direction.\n\nCelica has the rare ability to use healing Magic. She has been shown to heal most wounds, although she cannot use her magic to remove illnesses such as seithr poisoning. She has also exhibited the latent ability to suppress seithr, and it is for this reason that Celica is the key to Kushinada's Lynchpin, a device created to seal the seithr within the Gate, and thus disrupt the source of the Black Beast's power, although at the cost of her life. This also makes her the ultimate weakness of the Azure Grimoire as Ragna was unable to see through his right eye and move or use his Grimoire as long as he was near her. f 0 0 0 9 8 160 51 a \N 0
@@ -86,6 +100,39 @@ COPY chars_vns_hist (chid, vid, rid, spoil, role) FROM stdin;
13 2 \N 0 primary
\.
SELECT pg_catalog.setval('covers_seq', 1, false);
+COPY docs (id, locked, hidden, title, content) FROM stdin;
+2 f f Adding/Editing a Visual Novel
+3 f f Adding/Editing a Release
+4 f f Adding/Editing a Producer
+5 f f Editing guidelines
+6 f f Frequently Asked Questions
+7 f f About us
+9 f f Discussion board
+10 f f Tags & traits
+11 f f Public Database API
+12 f f Adding/Editing Characters
+13 f f How to Capture Screenshots
+14 f f Database Dumps
+15 f f Special Games
+16 f f Adding/Editing Staff Members
+\.
+COPY docs_hist (chid, title, content) FROM stdin;
+19 Adding/Editing a Visual Novel
+20 Adding/Editing a Release
+21 Adding/Editing a Producer
+22 Editing guidelines
+23 Frequently Asked Questions
+24 About us
+25 Discussion board
+26 Tags & traits
+27 Public Database API
+28 Adding/Editing Characters
+29 How to Capture Screenshots
+30 Database Dumps
+31 Special Games
+32 Adding/Editing Staff Members
+\.
+SELECT pg_catalog.setval('docs_id_seq', 16, true);
COPY login_throttle (ip, timeout) FROM stdin;
127.0.0.0 2018-02-04 14:45:01+00
\.
diff --git a/util/sql/func.sql b/util/sql/func.sql
index dcd537b3..e36d46e8 100644
--- a/util/sql/func.sql
+++ b/util/sql/func.sql
@@ -258,6 +258,7 @@ BEGIN
WHEN 'p' THEN INSERT INTO producers DEFAULT VALUES RETURNING id INTO ret.itemid;
WHEN 'c' THEN INSERT INTO chars DEFAULT VALUES RETURNING id INTO ret.itemid;
WHEN 's' THEN INSERT INTO staff DEFAULT VALUES RETURNING id INTO ret.itemid;
+ WHEN 'd' THEN INSERT INTO docs DEFAULT VALUES RETURNING id INTO ret.itemid;
END CASE;
END IF;
-- insert change
@@ -624,6 +625,7 @@ CREATE OR REPLACE FUNCTION notify_dbdel(xtype dbentry_type, xedit edit_rettype)
UNION SELECT r.title FROM releases r WHERE xtype = 'r' AND r.id = xedit.itemid
UNION SELECT p.name FROM producers p WHERE xtype = 'p' AND p.id = xedit.itemid
UNION SELECT c.name FROM chars c WHERE xtype = 'c' AND c.id = xedit.itemid
+ UNION SELECT d.title FROM docs d WHERE xtype = 'd' AND d.id = xedit.itemid
UNION SELECT sa.name FROM staff s JOIN staff_alias sa ON sa.aid = s.aid WHERE xtype = 's' AND s.id = xedit.itemid
) x(title) ON true
WHERE h.type = xtype AND h.itemid = xedit.itemid
@@ -645,6 +647,7 @@ CREATE OR REPLACE FUNCTION notify_dbedit(xtype dbentry_type, xedit edit_rettype)
UNION SELECT r.title FROM releases r WHERE xtype = 'r' AND r.id = xedit.itemid
UNION SELECT p.name FROM producers p WHERE xtype = 'p' AND p.id = xedit.itemid
UNION SELECT c.name FROM chars c WHERE xtype = 'c' AND c.id = xedit.itemid
+ UNION SELECT d.title FROM docs d WHERE xtype = 'd' AND d.id = xedit.itemid
UNION SELECT sa.name FROM staff s JOIN staff_alias sa ON sa.aid = s.aid WHERE xtype = 's' AND s.id = xedit.itemid
) x(title) ON true
WHERE h.type = xtype AND h.itemid = xedit.itemid
diff --git a/util/sql/perms.sql b/util/sql/perms.sql
index 4a5d94ef..5b643ed1 100644
--- a/util/sql/perms.sql
+++ b/util/sql/perms.sql
@@ -14,6 +14,8 @@ GRANT SELECT, INSERT, DELETE ON chars_traits TO vndb_site;
GRANT SELECT, INSERT ON chars_traits_hist TO vndb_site;
GRANT SELECT, INSERT, DELETE ON chars_vns TO vndb_site;
GRANT SELECT, INSERT ON chars_vns_hist TO vndb_site;
+GRANT SELECT, INSERT, UPDATE ON docs TO vndb_site;
+GRANT SELECT, INSERT ON docs_hist TO vndb_site;
GRANT SELECT, INSERT, UPDATE, DELETE ON login_throttle TO vndb_site;
GRANT SELECT, INSERT, UPDATE, DELETE ON notifications TO vndb_site;
GRANT SELECT, INSERT, UPDATE ON producers TO vndb_site;
@@ -98,6 +100,8 @@ GRANT SELECT ON chars TO vndb_multi;
GRANT SELECT ON chars_hist TO vndb_multi;
GRANT SELECT ON chars_traits TO vndb_multi;
GRANT SELECT ON chars_vns TO vndb_multi;
+GRANT SELECT ON docs TO vndb_multi;
+GRANT SELECT ON docs_hist TO vndb_multi;
GRANT SELECT, INSERT, UPDATE, DELETE ON login_throttle TO vndb_multi;
GRANT SELECT, INSERT, UPDATE, DELETE ON notifications TO vndb_multi;
GRANT SELECT, UPDATE ON producers TO vndb_multi;
diff --git a/util/sql/schema.sql b/util/sql/schema.sql
index 4cddf7e7..c580894f 100644
--- a/util/sql/schema.sql
+++ b/util/sql/schema.sql
@@ -157,6 +157,22 @@ CREATE TABLE chars_vns_hist (
role char_role NOT NULL DEFAULT 'main'
);
+-- docs
+CREATE TABLE docs ( -- dbentry_type=d
+ id SERIAL PRIMARY KEY,
+ locked boolean NOT NULL DEFAULT FALSE,
+ hidden boolean NOT NULL DEFAULT FALSE,
+ title varchar(200) NOT NULL DEFAULT '',
+ content text NOT NULL DEFAULT ''
+);
+
+-- docs_hist
+CREATE TABLE docs_hist (
+ chid integer NOT NULL PRIMARY KEY,
+ title varchar(200) NOT NULL DEFAULT '',
+ content text NOT NULL DEFAULT ''
+);
+
-- login_throttle
CREATE TABLE login_throttle (
ip inet NOT NULL PRIMARY KEY,
diff --git a/util/updates/update_20180208.sql b/util/updates/update_20180208.sql
new file mode 100644
index 00000000..d84ac0e1
--- /dev/null
+++ b/util/updates/update_20180208.sql
@@ -0,0 +1,57 @@
+CREATE TABLE docs (
+ id SERIAL PRIMARY KEY,
+ locked boolean NOT NULL DEFAULT FALSE,
+ hidden boolean NOT NULL DEFAULT FALSE,
+ title varchar(200) NOT NULL DEFAULT '',
+ content text NOT NULL DEFAULT ''
+);
+CREATE TABLE docs_hist (
+ chid integer NOT NULL PRIMARY KEY,
+ title varchar(200) NOT NULL DEFAULT '',
+ content text NOT NULL DEFAULT ''
+);
+ALTER TYPE dbentry_type ADD VALUE 'd';
+ALTER TYPE notification_ltype ADD VALUE 'd';
+
+\i util/sql/func.sql
+\i util/sql/editfunc.sql
+\i util/sql/perms.sql
+
+
+-- Insert empty pages
+CREATE OR REPLACE FUNCTION insert_doc(integer, text) RETURNS void AS $$
+BEGIN
+ PERFORM setval('docs_id_seq', $1-1);
+ PERFORM edit_d_init(NULL, NULL);
+ UPDATE edit_revision SET requester = 1, comments = 'Empty page', ip = '0.0.0.0';
+ UPDATE edit_docs SET title = $2;
+ PERFORM edit_d_commit();
+END
+$$ LANGUAGE plpgsql;
+
+SELECT insert_doc( 2, 'Adding/Editing a Visual Novel');
+SELECT insert_doc( 3, 'Adding/Editing a Release');
+SELECT insert_doc( 4, 'Adding/Editing a Producer');
+SELECT insert_doc( 5, 'Editing guidelines');
+SELECT insert_doc( 6, 'Frequently Asked Questions');
+SELECT insert_doc( 7, 'About us');
+SELECT insert_doc( 9, 'Discussion board');
+SELECT insert_doc(10, 'Tags & traits');
+SELECT insert_doc(11, 'Public Database API');
+SELECT insert_doc(12, 'Adding/Editing Characters');
+SELECT insert_doc(13, 'How to Capture Screenshots');
+SELECT insert_doc(14, 'Database Dumps');
+SELECT insert_doc(15, 'Special Games');
+SELECT insert_doc(16, 'Adding/Editing Staff Members');
+
+DROP FUNCTION insert_doc(integer, text);
+
+
+
+-- Update doc references
+CREATE OR REPLACE FUNCTION safedocreplace(text) RETURNS text AS $$
+ SELECT regexp_replace($1, 'd(2|3|4|5|6|7|9|10|11|12|13|14|15|16)\.([1-8](?:\.[1-8])?)', 'd\1#\2', 'g')
+$$ LANGUAGE sql;
+UPDATE threads_posts SET msg = safedocreplace(msg) WHERE msg ~ 'd[1-9]';
+UPDATE changes SET comments = safedocreplace(comments) WHERE comments ~ 'd[1-9]';
+DROP FUNCTION safedocreplace(text);