MangAdventure

MangAdventure, aka MangADV, is a simple manga hosting CMS.
It is fully written in Django, SCSS and Vanilla JS. No PHP, no Node.js, no jQuery.

Warning

This is the last release that supports Python 2.
Please upgrade to Python 3 to use the latest release.

Installation

Warning

This project is still in an experimental state and may be unstable. Proceed at your own risk.

Note

This tutorial assumes you are using Linux and plan on installing MangAdventure under /var/www/my-site.com/. The instructions are similar for Windows and MacOS.

Install the project

First, install the following prerequisites:

Afterwards, set up a virtualenv for MangAdventure with the following commands:

# This will install a virtualenv under /var/www/my-site.com/
python -m virtualenv /var/www/my-site.com/

# This will activate the virtualenv
source /var/www/my-site.com/bin/activate

Finally, install MangAdventure inside the activated virtualenv:

pip install -e "git+https://github.com/mangadventure/MangAdventure@v0.5.3#egg=MangAdventure"

MangAdventure also optionally provides Content-Security-Policy configuration via the django-csp package. You can install it if you’d like some extra security:

pip install django-csp

Configure the settings

Before proceeding, there are some settings you will need to configure. To configure them, copy the .env.example file to .env and edit it.

Create the database

This command will set up the database for your site.

mangadventure makemigrations
mangadventure migrate

Collect the static files

This command will collect the static files into static/.

mangadventure collectstatic

Create an administrator account

You will be prompted for a name, email, and password. This account is needed to access the /admin-panel/ page. You can create multiple administrator accounts.

mangadventure createsuperuser

Migrate from FoolSlide2

You can import your data from a FoolSlide2 installation.
If you weren’t using FoolSlide2 before, feel free to skip to the next section.

Limitations

  • Series will be imported without authors & artists.
  • Users & team members will not be imported.
  • Chapters with multiple teams will be imported without the teams.
  • Languages are not yet supported and thus cannot be imported.
  • This has only been tested with FoolSlide2 v2.3.3 using a MySQL database.

First, export the data from FoolSlide2:

  • Visit your site’s phpMyAdmin page.
  • Click on your FoolSlide2 database.
  • Go to the Export tab.
  • In Format: select XML and click Go.
  • Save the generated file somewhere and copy its path.

Next, import the data into MangAdventure:

  • Replace {root} with the path to your FoolSlide2 installation.
  • Replace {data} with the path to the XML file you exported.
mangadventure fs2import "{root}" "{data}"

Load Categories

If you want to load an initial set of manga categories imported from MangaUpdates, run this command:

mangadventure loaddata categories

Set up the server

To set up the server you will need Apache, Nginx, or any other web server that supports Django.
Make sure the user running the web server and uwsgi has the necessary permissions to access all the relevant files.
Also, create the media and log directories beforehand to avoid possible permission errors.
Lastly, don’t forget to run uwsgi after setting up the server:
(For more details, check the uWSGI docs.)
uwsgi --socket "127.0.0.1:25432" --chdir "/var/www/my-site.com/" --module "MangAdventure.wsgi"

Apache example

Apache requires mod_wsgi.

<VirtualHost *:80>
    ServerName my-site.com
    ServerAlias www.my-site.com
    ServerAdmin you@email.com
    LimitRequestBody 51000000

    Alias /static /var/www/my-site.com/src/mangadventure/static
    <Directory /var/www/my-site.com/src/mangadventure/static>
        Require all granted
    </Directory>

    Alias /media /var/www/my-site.com/src/mangadventure/media
    <Directory /var/www/my-site.com/src/mangadventure/MangAdventure/media>
        Require all granted
    </Directory>

    WSGIDaemonProcess my-site python-path=/var/www/my-site.com/src/mangadventure/MangAdventure:/var/www/my-site.com/lib/python3.6/site-packages
    WSGIProcessGroup my-site
    WSGIScriptAlias / /var/www/my-site.com/src/mangadventure/MangAdventure/wsgi.py process-group=my-site
    <Directory /var/www/my-site.com/src/mangadventure/MangAdventure>
        <Files wsgi.py>
            Require all granted
        </Files>
    </Directory>
</VirtualHost>

Nginx example

Nginx requires uwsgi.

server {
    listen 80;
    server_name my-site.com www.my-site.com;
    charset utf-8;
    client_max_body_size 51M;

    location /static {
        alias /var/www/my-site.com/src/mangadventure/static;
    }

    location /media  {
        alias /var/www/my-site.com/src/mangadventure/media;
    }

    location / {
        uwsgi_pass 127.0.0.1:25432;
        include uwsgi_params;
    }
}

Updating

First, install the latest release from GitHub:
(Replace {tag} with the latest release tag.)
pip install -U "git+https://github.com/mangadventure/MangAdventure@{tag}#egg=MangAdventure"

Then, check .env.example for new variables. If there are any, set them in .env.

Finally, update the database:

mangadventure makemigrations
mangadventure migrate

API

Releases

GET /api/v1/releases

Retrieve the latest release of each series.

Example request

curl -i http://example.com/api/v1/releases \
     -H 'If-Modified-Since: Fri, 24 Aug 2018 12:48:01 GMT'
Request headers

Example response

HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
Last-Modified: Sun, 26 Aug 2018 16:40:11 GMT
ETag: "6fd721cb9531502d4c52f0f3ebc34f22"
X-Frame-Options: SAMEORIGIN
Content-Length: 254

[
  {
    "slug": "some-manga",
    "title": "Some Manga",
    "url": "http://example.com/reader/some-manga/",
    "cover": "http://example.com/media/series/some-manga/cover.jpg",
    "latest_chapter": {
      "title": "Prologue",
      "volume": 1,
      "number": 0,
      "date": "Sun, 26 Aug 2018 16:14:52 GMT"
    }
  },
]
Response headers
Response body

The response body is an array of JSON objects. Each object contains the following:

  • slug (string) - The slug of the series.

  • title (string) - The title of the series.

  • url (string) - The URL of the series.

  • cover (string) - The URL of the series’s cover.

  • latest_chapter (object) - The latest chapter of the series.

    • title (string) - The title of the chapter.
    • volume (int) - The volume of the chapter.
    • number (int) - The number of the chapter.
    • date (string) - The date the chapter was uploaded.
Status Codes

Series

All series

GET /api/v1/series

Retrieve the info of every series.

Example request
curl -i http://example.com/api/v1/series \
     -H 'If-Modified-Since: Fri, 24 Aug 2018 12:48:01 GMT'
Request headers
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
Last-Modified: Sun, 26 Aug 2018 16:40:11 GMT
ETag: "2ce26c7f5182ce4aa4793147627b2a96"
X-Frame-Options: SAMEORIGIN
Content-Length: 510

[
  {
    "slug": "some-manga",
    "title": "Some Manga",
    "aliases": [
      "Some Mango"
    ],
    "url": "https://example.com/reader/some-manga/",
    "description": "Some description.",
    "authors": [
      ["John Doe", "Johnnie Doe"],
      ["Jack Doe"]
    ],
    "artists": [
      ["Jane Doe"]
    ],
    "categories": [
      {
        "name": "Drama",
        "description": "Drama"
      }
    ],
    "cover": "http://example.com/media/series/some-manga/cover.jpg",
    "completed": false,
    "volumes": {
      "1": {
        "0": {
          "title": "Prologue",
          "url": "http://example.com/reader/some-manga/1/0/",
          "pages_list": [
            "001.jpg",
            "002.jpg",
            "003.jpg",
            "004.jpg"
          ],
          "pages_root": "http://example.com/media/series/some-manga/1/0/",
          "date": "Sun, 26 Aug 2018 16:14:52 GMT",
          "final": false
        }
      }
    }
  }
]
Response headers
Response body

The response body is an array of JSON objects. Each object contains the following:

  • slug (string) - The slug of the series.
  • title (string) - The title of the series.
  • aliases (array of string) - Other names for the series.
  • url (string) - The URL of the series.
  • description (string) - The description of the series.
  • authors (array of array) - The series’ authors. Each array contains the name and aliases of the author.
  • artists (array of array) - The series’ artists. Each array contains the name and aliases of the artist.
  • categories (array of object) - The series’ categories. Each object contains the name and description of the category.
  • cover (string) - The URL of the series’ cover.
  • completed (boolean) - Whether the series is completed.
  • volumes (object) - The volumes of the series. The key of each volume is its number. The value is an object containing the volume’s chapters. Each chapter’s key is its number and its value contains the following:
  • title (string) - The title of the chapter.
  • url (string) - The URL of the chapter.
  • pages_list (array of string) - A list of pages of the chapter.
  • pages_root (array of string) - The root URl of the pages.
  • date (string) - The date the chapter was uploaded.
  • final (boolean) - Whether the chapter is the finale of the series.
Status Codes

Single series

GET /api/v1/series/:slug

Retrieve the info of a certain series.

Request parameters
  • slug (string) - The slug of the series.
Example request
curl -i http://example.com/api/v1/series/some-manga \
     -H 'If-Modified-Since: Fri, 24 Aug 2018 12:48:01 GMT'
Request headers
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
Last-Modified: Sun, 26 Aug 2018 16:40:11 GMT
ETag: "877d416e5573564ef3148716a799bb1a"
X-Frame-Options: SAMEORIGIN
Content-Length: 507

{
  "slug": "some-manga",
  "title": "Some Manga",
  "aliases": [
    "Some Mango"
  ],
  "url": "http://example.com/reader/some-manga/",
  "description": "Some description.",
  "authors": [
    ["John Doe", "Johnnie Doe"],
    ["Jack Doe"]
  ],
  "artists": [
    ["Nemo Nobody"]
  ],
  "categories": [
    {
      "name": "Drama",
      "description": "Drama"
    }
  ],
  "cover": "http://example.com/media/series/some-manga/cover.jpg",
  "completed": false,
  "volumes": {
    "1": {
      "0": {
        "title": "Prologue",
        "url": "http://example.com/reader/some-manga/1/0/",
        "pages_list": [
          "001.jpg",
          "002.jpg",
          "003.jpg",
          "004.jpg"
        ],
        "pages_root": "http://example.com/media/series/some-manga/1/0/",
        "date": "Sun, 26 Aug 2018 16:14:52 GMT",
        "final": false
      }
    }
  }
}
Response headers
Response body

The response body is a JSON object containing the following:

  • slug (string) - The slug of the series.
  • title (string) - The title of the series.
  • aliases (array of string) - Other names for the series.
  • url (string) - The URL of the series.
  • description (string) - The description of the series.
  • authors (array of array) - The series’ authors. Each array contains the name and aliases of the author.
  • artists (array of array) - The series’ artists. Each array contains the name and aliases of the artist.
  • categories (array of object) - The series’ categories. Each object contains the name and description of the category.
  • cover (string) - The URL of the series’ cover.
  • completed (boolean) - Whether the series is completed.
  • volumes (object) - The volumes of the series. The key of each volume is its number. The value is an object containing the volume’s chapters. Each chapter’s key is its number and its value contains the following:
  • title (string) - The title of the chapter.
  • url (string) - The URL of the chapter.
  • pages_list (array of string) - A list of pages of the chapter.
  • pages_root (array of string) - The root URl of the pages.
  • date (string) - The date the chapter was uploaded.
  • final (boolean) - Whether the chapter is the finale of the series.
Status Codes

Volume

GET /api/v1/series/:slug/:volume

Retrieve all chapters of a volume.

Request parameters
  • slug (string) - The slug of the series.
  • volume (int) - A volume of the series.
Example request
curl -i http://example.com/api/v1/series/some-manga/1 \
     -H 'If-Modified-Since: Fri, 24 Aug 2018 12:48:01 GMT'
Request headers
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
Last-Modified: Sun, 26 Aug 2018 16:14:52 GMT
ETag: "88bc064c71f4d4e925c6725de3077fd4"
X-Frame-Options: SAMEORIGIN
Content-Length: 187

{
  "0": {
    "title": "Prologue",
    "url": "http://example.com/reader/some-manga/1/0/",
    "pages_list": [
      "001.jpg",
      "002.jpg",
      "003.jpg",
      "004.jpg"
    ],
    "pages_root": "http://example.com/media/some-manga/1/0/",
    "date": "Sun, 26 Aug 2018 16:14:52 GMT",
    "final": false
  }
}
Response headers
Response body

The response body is a JSON object. The key of each object is the chapter number. The value is an object containing the info of the chapter:

  • title (string) - The title of the chapter.
  • url (string) - The URL of the chapter.
  • pages_list (array of string) - A list of pages of the chapter.
  • pages_root (array of string) - The root URl of the pages.
  • date (string) - The date the chapter was uploaded.
  • final (boolean) - Whether the chapter is the finale of the series.
Status Codes

Chapter

GET /api/v1/series/:slug/:volume/:chapter

Retrieve a certain chapter of a volume.

Request parameters
  • slug (string) - The slug of the series.
  • volume (int) - A volume of the series.
  • chapter (int) - A chapter of the volume.
Example request
curl -i http://example.com/api/v1/series/some-manga/1/0 \
     -H 'If-Modified-Since: Fri, 24 Aug 2018 12:48:01 GMT'
Request headers
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
Last-Modified: Sun, 26 Aug 2018 16:14:52 GMT
ETag: "11b9df2f0904dc4f1b2dfaa7d7419bbc"
X-Frame-Options: SAMEORIGIN
Content-Length: 181

{
  "title": "Prologue",
  "url": "http://example.com/reader/some-manga/1/0/",
  "pages_list": [
    "001.jpg",
    "002.jpg",
    "003.jpg",
    "004.jpg"
  ],
  "pages_root": "http://example.com/media/some-manga/1/0/",
  "date": "Sun, 26 Aug 2018 16:14:52 GMT",
  "final": false
}
Response headers
Response body

The response body is a JSON object containing the following:

  • title (string) - The title of the chapter.
  • url (string) - The URL of the chapter.
  • pages_list (array of string) - A list of pages of the chapter.
  • pages_root (array of string) - The root URl of the pages.
  • date (string) - The date the chapter was uploaded.
  • final (boolean) - Whether the chapter is the finale of the series.
Status Codes

Authors

All authors

GET /api/v1/authors

Retrieve the info of each author.

Example request
curl -i http://example.com/api/v1/authors \
     -H 'If-None-Match: f2e17505f242cfbcd13496c3bd05f223'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
ETag: "5c67e7ccb7f5e711431e81053dad33bb"
X-Frame-Options: SAMEORIGIN
Content-Length: 143

[
  {
    "id": 1,
    "name": "John Doe",
    "aliases": ["Johnnie Doe"],
    "series": [
      {
        "slug": "some-manga",
        "title": "Some Manga",
        "aliases": ["Some Mango"]
      }
    ]
  }
]
Response headers
Response body

The response body is an array of JSON objects. Each object contains the following:

  • id (int) - The ID of the author.

  • name (string) - The name of the author.

  • aliases (array of string) - The author’s other names.

  • series (array of object) - The author’s series. Each object contains the following:

    • slug (slug) - The slug of the series.
    • title (string) - The title of the series.
    • aliases (array of string) - Other names for the series.
Status Codes

Single author

GET /api/v1/authors/:id

Retrieve the info of a certain author.

Request parameters
  • id (int) - The author’s ID.
Example request
curl -i http://example.com/api/v1/authors/1 \
     -H 'If-None-Match: cf62b5e432293fc2b7cf32d5f100d415'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
ETag: "03785faa8c59138c6c16155f51f53bba"
X-Frame-Options: SAMEORIGIN
Content-Length: 141

{
  "id": 1,
  "name": "John Doe",
  "aliases": ["Johnnie Doe"],
  "series": [
    {
      "slug": "some-manga",
      "title": "Some Manga",
      "aliases": ["Some Mango"]
    }
  ]
}
Response headers
Response body

The response body is a JSON object which contains the following:

  • id (int) - The ID of the author.

  • name (string) - The name of the author.

  • aliases (array of string) - The author’s other names.

  • series (array of object) - The author’s series. Each object contains the following:

    • slug (slug) - The slug of the series.
    • title (string) - The title of the series.
    • aliases (array of string) - Other names for the series.
Status Codes

Artists

All artists

GET /api/v1/artists

Retrieve the info of each artist.

Example request
curl -i http://example.com/api/v1/artists \
     -H 'If-None-Match: cb51bd8357e0c7fba317ee1331d765c4'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
ETag: "31b0b177cc7138befc5dd56ae745e313"
X-Frame-Options: SAMEORIGIN
Content-Length: 133

[
  {
    "id": 1,
    "name": "Nemo Nobody",
    "aliases": [],
    "series": [
      {
        "slug": "some-manga",
        "title": "Some Manga",
        "aliases": ["Some Mango"]
      }
    ]
  }
]
Response headers
Response body

The response body is an array of JSON objects. Each object contains the following:

  • id (int) - The ID of the artist.

  • name (string) - The name of the artist.

  • aliases (array of string) - The artist’s other names.

  • series (array of object) - The artist’s series. Each object contains the following:

    • slug (slug) - The slug of the series.
    • title (string) - The title of the series.
    • aliases (array of string) - Other names for the series.
Status Codes

Single artist

GET /api/v1/artists/:id

Retrieve the info of a certain artist.

Request parameters
  • id (int) - The artist’s ID.
Example request
curl -i http://example.com/api/v1/artists/1 \
     -H 'If-None-Match: 7cd7ac5d353b1ee4833b6b1e1cf17705'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
ETag: "3bcf5cf18a6ac3a515878561f5b10395"
X-Frame-Options: SAMEORIGIN
Content-Length: 131

{
  "id": 1,
  "name": "Nemo Nobody",
  "aliases": [],
  "series": [
    {
      "slug": "some-manga",
      "title": "Some Manga",
      "aliases": ["Some Mango"]
    }
  ]
}
Response headers
Response body

The response body is a JSON object which contains the following:

  • id (int) - The ID of the artist.

  • name (string) - The name of the artist.

  • aliases (array of string) - The artist’s other names.

  • series (array of object) - The artist’s series. Each object contains the following:

    • slug (slug) - The slug of the series.
    • title (string) - The title of the series.
    • aliases (array of string) - Other names for the series.
Status Codes

Groups

All groups

GET /api/v1/groups

Retrieve the info of each group.

Example request
curl -i http://example.com/api/v1/groups \
     -H 'If-None-Match: 2503eb9066af0aaef2274e8a7d158fd7'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
ETag: "ee0581f62afb372d5faea0092d674a87"
X-Frame-Options: SAMEORIGIN
Content-Length: 286

[
   {
      "id": 1,
      "name": "Group",
      "description": "An example group",
      "website": "https://example.com",
      "discord": "https://discord.me/examplegroup",
      "twitter": "ExampleGroup",
      "logo": "https://example.com/media/groups/1/logo.png",
      "members": [
         {
            "id": 1,
            "name": "John Doe",
            "roles": ["Leader"],
            "twitter": "JohnDoe_1234",
            "discord": "John Doe#1234"
         },
      ],
      "series": [
         {
            "slug": "some-manga",
            "title": "Some manga",
            "aliases": ["Some mango"]
         }
      ]
   }
]
Response headers
Response body

The response body is an array of JSON objects. Each object contains the following:

  • id (int) - The ID of the group.

  • name (string) - The name of the group.

  • description (string) - The group’s description.

  • website (string) - The group’s website.

  • discord (string) - The group’s Discord server.

  • twitter (string) - The group’s Twitter username.

  • logo (string) - The group’s logo.

  • members (array of object) - The group’s members. Each object contains the following:

    • id (int) - The ID of the member.
    • name (string) - The name of the member.
    • roles (array of string) - The roles of the member.
    • twitter (string) - The member’s Twitter username.
    • discord (string) - The member’s Discord username and discriminator.
  • series (array of object) - The group’s series. Each object contains the following:

    • slug (slug) - The slug of the series.
    • title (string) - The title of the series.
    • aliases (array of string) - Other names for the series.
Status Codes

Single group

GET /api/v1/groups/:id

Retrieve the info of a certain group.

Request parameters
  • id (int) - The group’s ID.
Example request
curl -i http://example.com/api/v1/groups/1 \
     -H 'If-None-Match: 820727be5a235d089af4ad66ffeae017'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.
Example response
HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
ETag: "37fef7866db8e2a0020d2a4ea519fa75"
X-Frame-Options: SAMEORIGIN
Content-Length: 284

{
   "id": 1,
   "name": "Group",
   "description": "An example group",
   "website": "https://example.com",
   "discord": "https://discord.me/examplegroup",
   "twitter": "ExampleGroup",
   "logo": "https://example.com/media/groups/1/logo.png",
   "members": [
      {
         "id": 1,
         "name": "John Doe",
         "roles": ["Leader"],
         "twitter": "JohnDoe_1234",
         "discord": "John Doe#1234"
      },
   ],
   "series": [
      {
         "slug": "some-manga",
         "title": "Some manga",
         "aliases": ["Some mango"]
      }
   ]
}
Response headers
Response body

The response body is a JSON object which contains the following:

  • id (int) - The ID of the group.

  • name (string) - The name of the group.

  • description (string) - The group’s description.

  • website (string) - The group’s website.

  • discord (string) - The group’s Discord server.

  • twitter (string) - The group’s Twitter username.

  • logo (string) - The group’s logo.

  • members (array of object) - The group’s members. Each object contains the following:

    • id (int) - The ID of the member.
    • name (string) - The name of the member.
    • roles (array of string) - The roles of the member.
    • twitter (string) - The member’s Twitter username.
    • discord (string) - The member’s Discord username and discriminator.
  • series (array of object) - The group’s series. Each object contains the following:

    • slug (slug) - The slug of the series.
    • title (string) - The title of the series.
    • aliases (array of string) - Other names for the series.
Status Codes

Categories

GET /api/v1/categories

Retrieve a list of available categories.

Example request

curl -i http://example.com/api/v1/categories \
     -H 'If-None-Match: be534a1d37be8db1c3c57177e1305f6c'
Request headers
  • If-None-Match: Send a conditional request checking the ETag header.

Example response

HTTP/1.1 200 OK
Date: Tue, 28 Aug 2018 09:35:27 GMT
Server: WSGIServer/0.2 CPython/3.7.0
Content-Type: application/json
Last-Modified: Sun, 26 Aug 2018 16:40:11 GMT
ETag: "fe35ca7670b351b38c1c1d5e4b1e773d"
X-Frame-Options: SAMEORIGIN
Content-Length: 79

[
  {
    "id": "drama",
    "name": "Drama",
    "description": "Drama"
  }
]
Response headers
Response body

The response body is an array of JSON objects. Each object contains the following:

  • id (string) - The ID of the category.
  • name (string) - The name of the category.
  • description (string) - The description of the category.
Status Codes

Compatibility

If you find that MangAdventure is incompatible with any Python or browser version listed as compatible, or compatible with any version listed as incompatible or untested, please submit an issue.

Python

Version Compatibility
<2.7 Incompatible
2.7 Compatible
3.0 - 3.4 Untested
3.5 - 3.7 Compatible

Browsers

Browser Versions
Chrome
Chrome
29+
Firefox
Firefox
28+
Internet Explorer
IE
10+/Edge
Safari
Safari
6.1+
Opera
Opera
15+
iOS Safari
iOS Safari
7.1+
Android Browser
Android Browser
4.4+
Samsung Internet
Samsung Internet
4+

Changelog

v0.5.3

  • Fixed page-click navigation
  • Added support for CSP report URI
  • Added nofollow to private links
  • Added noopener & noreferrer to external links
  • Added filters, ordering, search, date hierarchy to admin interface
  • Added images & more info to change lists in admin interface
  • Replaced large/medium/small logos with a single logo
  • Replaced django-tinymce with custom TinyMCE widget
  • Replaced django-constance with .env variables
  • Removed django-static-precompiler dependency

v0.5.2

  • Fixed missing fields in series API response
  • Fixed OSError in zipfile_validator
  • Added more blocked user agents & image types
  • Added ability to search by slug (for Tachiyomi)
  • Added PreloadMiddleware for HTTP/2 push
  • Disabled XPBMiddleware
  • Disabled autocomplete in password inputs
  • Replaced JsonVaryAllowResponse with require_methods_api
  • Replaced logo object with img
  • Moved /admin page to /admin-panel
  • Moved redirects & sites admin pages under constance
  • Moved configuration to .env
  • Removed configure command

v0.5.1

  • Fixed group addition edge case.
  • Fixed chapter cover images not being closed.
  • Implemented series bookmarking.
  • Added bookmarks feed page.
  • Removed permission to add users from admin interface.

v0.5.0

  • Added support for users (registration, login, OAuth, profile, settings)
  • Switched to custom icon font made with fontello & replaced group.png with an SVG image
  • Improved reader page design
  • Fixed thumbnail downsampling for grayscale images
  • Moved templates to MangAdventure directory & renamed skeleton.html to layout.html
  • Converted bad bots list to a python file
  • Configured autogeneration of a secret key
  • Added ColorField for constance
  • Added constance hook to generate _variables.scss & removed inline SCSS
  • Added setup.py & MANIFEST.in for setuptools
  • Added optional configuration for django-csp
  • Compressed tablesort into a single vendored file
  • Converted info page to a flatpage with TinyMCE editor & added privacy policy page
  • Added IRC & Reddit links to groups & members
  • Removed configuration commands and added a configure command that lets users edit a configuration file with an editor
  • Added support for migration from FoolSlide2
  • Added MangaUpdates categories fixture
  • Made series slugs editable & added a signal to move directories on change
  • Added contribute.json & robots.txt

v0.4.5

  • Added categories to API.
  • Added series filtering to API.

v0.4.4

  • Added categories to series page.
  • Removed sha256 hashes.
  • Removed breadcrumbs.

v0.4.3

  • Added series categories
  • Moved /api/ to /api/v1/
  • Made site keywords configurable
  • Added Google breadcrumbs & description
  • Added OpenSearch description
  • Added noscript fallbacks
  • Added X-Powered-By response header
  • Improved database queries

v0.4.2

  • Fixed blocked user agents
  • Added default group icon file
  • Added Vary, Allow headers to api responses
  • Moved inline styles & scripts to separate files
  • Replaced pluralize script with count checks
  • Switched to cdnjs for all remote scripts and added SRI hash

v0.4.1

  • Converted chapter numbers to float
  • Made page number indicator editable
  • Made page compression optional
  • Added Quality Checker to roles

v0.4.0

  • Enabled searching for series via the API

v0.3.1

  • Added group info page

v0.3.0

  • Added groups app
  • Restructured custom modules
  • Added custom model & form fields
  • Added browser icons to compatibility.rst

v0.2.2

  • Added search page
  • Enabled conditional requests
  • Added authors & artists to the API
  • Removed obsolete no_future_date validator
  • Configured API URLs to not require a trailing slash
  • Converted docs to rst

v0.2.1

  • Compatibility fixes for Python 2
  • Added compatibility tables
  • Moved index to MangAdventure.urls
  • Renamed settings app to config
  • Resized series cover to thumbnail size

v0.2.0

  • Added basic API
  • Added HTTPS support
  • Fixed html meta tags
  • More minor fixes

v0.1.0

  • Initial release

Roadmap

v0.1.0

  ☑ Latest landing page with up to x releases.
  ☑ Library page with series, each showing the y latest chapters.
  ☑ A page for each series with its info and chapters.
  ☑ A reader page for individual chapters.

v0.2.x

  ☑ API (latest, series).
  ☑ Search page (utilise the API if needed).
  ☑ Allow searching by author & artist.

v0.3.x

  ☑ Group pages.
  ☑ Expand API.
  ☑ Information page.

v0.4.x

  ☑ Categories.
  ☑ Expand API & search.
  ☑ Search for series by title via the API.

v0.5.x

  ☑ User registration:
  ☑ Allow Google/Twitter/Reddit sign-in.
  ☑ Allow users to bookmark series.
  ☑ Password reset form.
  ☑ Privacy page.
  ☑ Migration from FoolSlide2.

v0.6.x

  ☐ More reading modes:
  ☐ Long strip mode.
  ☐ Fit page to screen.
  ☐ Double page.
  ☐ Right to left.
  ☐ RSS feeds.

v0.7.x

  ☐ Revamp API:
  ☐ Use a framework.
  ☐ API keys.
  ☐ Rate limit.
  ☐ POST,PUT,PATCH,DELETE privileges for staff.

v0.8.x

  ☐ Serialize models into JSON-LD.
  ☐ Use comics-manifest for series.
  ☐ Heroku Procfile & app.json.
  ☐ Web App Manifest.
  ☐ Sitemap.