mirror of
https://github.com/minetest/contentdb.git
synced 2024-12-22 22:12:24 +01:00
Update API docs, add support for code highlighting, add markdown table support
This commit is contained in:
parent
033f40c263
commit
2f66db5989
@ -1,5 +1,5 @@
|
||||
# ContentDB
|
||||
# Copyright (C) 2018-1 rubenwardy
|
||||
# Copyright (C) 2018-21 rubenwardy
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as published by
|
||||
@ -21,7 +21,7 @@ import flask_menu as menu
|
||||
from flask_mail import Mail
|
||||
from flask_github import GitHub
|
||||
from flask_wtf.csrf import CSRFProtect
|
||||
from flask_flatpages import FlatPages
|
||||
from flask_flatpages import FlatPages, pygments_style_defs
|
||||
from flask_babel import Babel
|
||||
from flask_login import logout_user, current_user, LoginManager
|
||||
import os, redis
|
||||
@ -29,6 +29,14 @@ import os, redis
|
||||
app = Flask(__name__, static_folder="public/static")
|
||||
app.config["FLATPAGES_ROOT"] = "flatpages"
|
||||
app.config["FLATPAGES_EXTENSION"] = ".md"
|
||||
app.config["FLATPAGES_MARKDOWN_EXTENSIONS"] = ["fenced_code", "tables", "codehilite"]
|
||||
app.config["FLATPAGES_EXTENSION_CONFIG"] = {
|
||||
"fenced_code": {},
|
||||
"tables": {},
|
||||
"codehilite": {
|
||||
"linenums": "True"
|
||||
}
|
||||
}
|
||||
app.config.from_pyfile(os.environ["FLASK_CONFIG"])
|
||||
|
||||
r = redis.Redis.from_url(app.config["REDIS_URL"])
|
||||
@ -41,8 +49,8 @@ pages = FlatPages(app)
|
||||
babel = Babel(app)
|
||||
gravatar = Gravatar(app,
|
||||
size=58,
|
||||
rating='g',
|
||||
default='mp',
|
||||
rating="g",
|
||||
default="mp",
|
||||
force_default=False,
|
||||
force_lower=False,
|
||||
use_ssl=True,
|
||||
@ -66,7 +74,7 @@ init_app(app)
|
||||
|
||||
# @babel.localeselector
|
||||
# def get_locale():
|
||||
# return request.accept_languages.best_match(app.config['LANGUAGES'].keys())
|
||||
# return request.accept_languages.best_match(app.config["LANGUAGES"].keys())
|
||||
|
||||
from . import models, template_filters
|
||||
|
||||
@ -80,13 +88,13 @@ create_blueprints(app)
|
||||
|
||||
@app.route("/uploads/<path:path>")
|
||||
def send_upload(path):
|
||||
return send_from_directory(app.config['UPLOAD_DIR'], path)
|
||||
return send_from_directory(app.config["UPLOAD_DIR"], path)
|
||||
|
||||
@menu.register_menu(app, ".help", "Help", order=19, endpoint_arguments_constructor=lambda: { 'path': 'help' })
|
||||
@app.route('/<path:path>/')
|
||||
@menu.register_menu(app, ".help", "Help", order=19, endpoint_arguments_constructor=lambda: { "path": "help" })
|
||||
@app.route("/<path:path>/")
|
||||
def flatpage(path):
|
||||
page = pages.get_or_404(path)
|
||||
template = page.meta.get('template', 'flatpage.html')
|
||||
template = page.meta.get("template", "flatpage.html")
|
||||
return render_template(template, page=page)
|
||||
|
||||
@app.before_request
|
||||
@ -95,7 +103,7 @@ def check_for_ban():
|
||||
if current_user.rank == models.UserRank.BANNED:
|
||||
flash("You have been banned.", "danger")
|
||||
logout_user()
|
||||
return redirect(url_for('users.login'))
|
||||
return redirect(url_for("users.login"))
|
||||
elif current_user.rank == models.UserRank.NOT_JOINED:
|
||||
current_user.rank = models.UserRank.MEMBER
|
||||
models.db.session.commit()
|
||||
|
@ -102,7 +102,7 @@ def populate_test_data(session):
|
||||
mod1.desc = """
|
||||
Majority of awards are back ported from Calinou's old fork in Carbone, under same license.
|
||||
|
||||
```
|
||||
```lua
|
||||
awards.register_achievement("award_mesefind",{
|
||||
title = "First Mese Find",
|
||||
description = "Found some Mese!",
|
||||
|
@ -12,7 +12,6 @@ title: Help
|
||||
## Help for Package Authors
|
||||
|
||||
* [Package Inclusion Policy and Guidance](/policy_and_guidance/)
|
||||
* [Package Tags](package_tags)
|
||||
* [Git Update Detection](update_config)
|
||||
* [Creating Releases using Webhooks](release_webhooks)
|
||||
* [Package Configuration and Releases Guide](package_config)
|
||||
|
@ -5,11 +5,11 @@ title: API
|
||||
Not all endpoints require authentication.
|
||||
Authentication is done using Bearer tokens:
|
||||
|
||||
Authorization: Bearer YOURTOKEN
|
||||
```bash
|
||||
curl -H "Authorization: Bearer YOURTOKEN" https://content.minetest.net/api/whoami/
|
||||
```
|
||||
|
||||
You can use the `/api/whoami` to check authentication.
|
||||
|
||||
Tokens can be attained by visiting [Profile > "API Tokens"](/user/tokens/).
|
||||
Tokens can be attained by visiting [Settings > API Tokens](/user/tokens/).
|
||||
|
||||
## Endpoints
|
||||
|
||||
@ -43,8 +43,8 @@ Tokens can be attained by visiting [Profile > "API Tokens"](/user/tokens/).
|
||||
|
||||
### Releases
|
||||
|
||||
* GET `/api/packages/<username>/<name>/releases/`
|
||||
* POST `/api/packages/<username>/<name>/releases/new/`
|
||||
* GET `/api/packages/<username>/<name>/releases/` (List)
|
||||
* POST `/api/packages/<username>/<name>/releases/new/` (Create)
|
||||
* Requires authentication.
|
||||
* Body is multipart form if zip upload, JSON otherwise.
|
||||
* `title`: human-readable name of the release.
|
||||
@ -55,6 +55,19 @@ Tokens can be attained by visiting [Profile > "API Tokens"](/user/tokens/).
|
||||
* `file`: multipart file to upload, like `<input type=file>`.
|
||||
* You can set min and max Minetest Versions [using the content's .conf file](/help/package_config/).
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
# Create release from Git
|
||||
curl -X POST https://content.minetest.net/api/packages/username/name/releases/new/ \
|
||||
-H "Authorization: Bearer YOURTOKEN" -H "Content-Type: application/json" \
|
||||
-d "{\"method\": \"git\", \"title\": \"My Release\", \"ref\": \"master\" }"
|
||||
|
||||
# Create release from zip upload
|
||||
curl https://content.minetest.net/api/packages/username/name/releases/new/ \
|
||||
-H "Authorization: Bearer YOURTOKEN" \
|
||||
-F title="My Release" -F file=@path/to/file.zip
|
||||
```
|
||||
|
||||
### Topics
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
title: Package Tags
|
||||
|
||||
## Overview
|
||||
|
||||
Tags should be added to packages to enable easy identification of different types of mods, games and texture packs.
|
||||
|
||||
They are only beneficial when applied correctly, so please use the following guidelines.
|
||||
|
||||
## Tag Usage
|
||||
|
||||
* **Building** - For mods that focus on adding new materials or nodes to build with.
|
||||
* **Education** - For mods or games created for educational purposes.
|
||||
* **Environment** - For mods that add environmental effects, including ambient sound and weather effects.
|
||||
* **Inventory** - For mods that add new inventory systems or new inventory pages.
|
||||
* **Machines and Electronics** - For mods that include placeable machinery or electronic components which interact to complete tasks.
|
||||
* **Maintenance** - For mods that assist with world or player maintenance. This includes large-scale map manipulation, area protection and other administrative tools.
|
||||
* **Mapgen** - For mods that add new biomes, new mapgen decorations, or any other mapgen elements.
|
||||
* **Mobs and NPCs** - For mods that add mobs or NPCs, or provide tools that assist with mob and NPC creation or manipulation.
|
||||
* **Plants and Farming** - For mods that add new plants or other farmable resources.
|
||||
* **Player effects/Food** - For mods that change player effects, for example speed, jump height or gravity, and food.
|
||||
* **Tools** - For mods that add new tools or new features for existing tools.
|
||||
* **Transport** - For mods that add transportation methods. This includes teleportation, vehicles and ridable mobs.
|
||||
* **Survival** - For mods written specifically for survival games. For example, these mods might focus on game-balance or increase the difficulty level. This tag should also be used for games with a heavy survival focus.
|
||||
* **Creative** - For mods written specifically (and often exclusively) for use in creative mode. For example, these mods may add a large amount of decorative content, or content without crafting recipes. This tag should also be used for games with a heavy creative focus.
|
||||
* **Multiplayer-focused** - For games that can be played with other players.
|
||||
* **Singleplayer-focused** - For games that can be played alone.
|
||||
* **PvP** - For games designed to be played competitively against other players.
|
||||
* **PvE** - For games designed for one or multiple players which focus on combat against mobs or NPCs.
|
||||
* **Puzzle** - For mods and games with a focus on puzzle solving instead of combat.
|
||||
* **16px** - For 16px texture packs.
|
||||
* **32px** - For 32px texture packs.
|
||||
* **64px** - For 64px texture packs.
|
||||
* **128px+** - For 128px or higher texture packs.
|
@ -11,8 +11,10 @@ plus the sum of the score given by reviews.
|
||||
|
||||
A review score is 100 if positive, -100 if negative.
|
||||
|
||||
reviews_sum = sum(100 * (positive ? 1 : -1))
|
||||
score = avg_downloads + reviews_sum
|
||||
```c
|
||||
reviews_sum = sum(100 * (positive ? 1 : -1));
|
||||
score = avg_downloads + reviews_sum;
|
||||
```
|
||||
|
||||
## Pseudo rolling average of downloads
|
||||
|
||||
|
@ -3,7 +3,7 @@ title: Git Update Detection
|
||||
## Introduction
|
||||
|
||||
When you push a change to your Git repository, ContentDB can create a new release automatically or
|
||||
send you a reminder. ContentDB will check your Git repository every day, but you can use
|
||||
send you a reminder. ContentDB will check your Git repository one per day, but you can use
|
||||
webhooks or the API for faster updates.
|
||||
|
||||
Git Update Detection is clever enough to not create a release again if you've already created
|
||||
|
@ -11,25 +11,18 @@ Default whitelist of allowed HTML tags. Any other HTML tags will be escaped or
|
||||
stripped from the text. This applies to the html output that Markdown produces.
|
||||
"""
|
||||
ALLOWED_TAGS = [
|
||||
'ul',
|
||||
'ol',
|
||||
'li',
|
||||
'p',
|
||||
'pre',
|
||||
'code',
|
||||
'blockquote',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'hr',
|
||||
'br',
|
||||
'strong',
|
||||
'em',
|
||||
'a',
|
||||
'img'
|
||||
"h1", "h2", "h3", "h4", "h5", "h6", "hr",
|
||||
"ul", "ol", "li",
|
||||
"p",
|
||||
"br",
|
||||
"pre",
|
||||
"code",
|
||||
"blockquote",
|
||||
"strong",
|
||||
"em",
|
||||
"a",
|
||||
"img",
|
||||
"table", "thead", "tbody", "tr", "th", "td"
|
||||
]
|
||||
|
||||
"""
|
||||
@ -38,8 +31,8 @@ tags and the src, title and alt attributes for <img> tags. Any other attribute
|
||||
will be stripped from its tag.
|
||||
"""
|
||||
ALLOWED_ATTRIBUTES = {
|
||||
'a': ['href', 'title'],
|
||||
'img': ['src', 'title', 'alt']
|
||||
"a": ["href", "title"],
|
||||
"img": ["src", "title", "alt"]
|
||||
}
|
||||
|
||||
"""
|
||||
@ -47,10 +40,10 @@ If you allow tags that have attributes containing a URI value
|
||||
(like the href attribute of an anchor tag,) you may want to adapt
|
||||
the accepted protocols. The default list only allows http, https and mailto.
|
||||
"""
|
||||
ALLOWED_PROTOCOLS = ['http', 'https', 'mailto']
|
||||
ALLOWED_PROTOCOLS = ["http", "https", "mailto"]
|
||||
|
||||
|
||||
md = Markdown(extensions=["fenced_code"], output_format="html5")
|
||||
md = None
|
||||
|
||||
def render_markdown(source):
|
||||
return bleach.clean(md.convert(source),
|
||||
@ -58,6 +51,10 @@ def render_markdown(source):
|
||||
styles=[], protocols=ALLOWED_PROTOCOLS)
|
||||
|
||||
def init_app(app):
|
||||
global md
|
||||
|
||||
md = Markdown(extensions=app.config["FLATPAGES_MARKDOWN_EXTENSIONS"], output_format="html5")
|
||||
|
||||
@app.template_filter()
|
||||
def markdown(source):
|
||||
return Markup(render_markdown(source))
|
||||
|
@ -67,7 +67,7 @@ p, .content li {
|
||||
pre code {
|
||||
display: block;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
background: rgba(51, 51, 51, 0.25);
|
||||
padding: 0.75rem 1.25rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
@ -157,3 +157,5 @@ pre code {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@import "dracula.scss";
|
||||
|
94
app/scss/dracula.scss
Normal file
94
app/scss/dracula.scss
Normal file
@ -0,0 +1,94 @@
|
||||
/* Dracula Theme v1.2.5
|
||||
*
|
||||
* https://github.com/zenorocha/dracula-theme
|
||||
*
|
||||
* Copyright 2016, All rights reserved
|
||||
*
|
||||
* Code licensed under the MIT license
|
||||
* http://zenorocha.mit-license.org
|
||||
*
|
||||
* @author Rob G <wowmotty@gmail.com>
|
||||
* @author Chris Bracco <chris@cbracco.me>
|
||||
* @author Zeno Rocha <hi@zenorocha.com>
|
||||
*/
|
||||
|
||||
.highlight, .codehilite {
|
||||
color: #f8f8f2;
|
||||
|
||||
.hll { background-color: #f1fa8c }
|
||||
.c { color: #6272a4 } /* Comment */
|
||||
.err { color: #f8f8f2 } /* Error */
|
||||
.g { color: #f8f8f2 } /* Generic */
|
||||
.k { color: #ff79c6 } /* Keyword */
|
||||
.l { color: #f8f8f2 } /* Literal */
|
||||
.n { color: #f8f8f2 } /* Name */
|
||||
.o { color: #ff79c6 } /* Operator */
|
||||
.x { color: #f8f8f2 } /* Other */
|
||||
.p { color: #f8f8f2 } /* Punctuation */
|
||||
.ch { color: #6272a4 } /* Comment.Hashbang */
|
||||
.cm { color: #6272a4 } /* Comment.Multiline */
|
||||
.cp { color: #ff79c6 } /* Comment.Preproc */
|
||||
.cpf { color: #6272a4 } /* Comment.PreprocFile */
|
||||
.c1 { color: #6272a4 } /* Comment.Single */
|
||||
.cs { color: #6272a4 } /* Comment.Special */
|
||||
.gd { color: #8b080b } /* Generic.Deleted */
|
||||
.ge { color: #f8f8f2; text-decoration: underline } /* Generic.Emph */
|
||||
.gr { color: #f8f8f2 } /* Generic.Error */
|
||||
.gh { color: #f8f8f2; font-weight: bold } /* Generic.Heading */
|
||||
.gi { color: #f8f8f2; font-weight: bold } /* Generic.Inserted */
|
||||
.go { color: #44475a } /* Generic.Output */
|
||||
.gp { color: #f8f8f2 } /* Generic.Prompt */
|
||||
.gs { color: #f8f8f2 } /* Generic.Strong */
|
||||
.gu { color: #f8f8f2; font-weight: bold } /* Generic.Subheading */
|
||||
.gt { color: #f8f8f2 } /* Generic.Traceback */
|
||||
.kc { color: #ff79c6 } /* Keyword.Constant */
|
||||
.kd { color: #8be9fd; font-style: italic } /* Keyword.Declaration */
|
||||
.kn { color: #ff79c6 } /* Keyword.Namespace */
|
||||
.kp { color: #ff79c6 } /* Keyword.Pseudo */
|
||||
.kr { color: #ff79c6 } /* Keyword.Reserved */
|
||||
.kt { color: #8be9fd } /* Keyword.Type */
|
||||
.ld { color: #f8f8f2 } /* Literal.Date */
|
||||
.m { color: #bd93f9 } /* Literal.Number */
|
||||
.s { color: #f1fa8c } /* Literal.String */
|
||||
.na { color: #50fa7b } /* Name.Attribute */
|
||||
.nb { color: #8be9fd; font-style: italic } /* Name.Builtin */
|
||||
.nc { color: #50fa7b } /* Name.Class */
|
||||
.no { color: #f8f8f2 } /* Name.Constant */
|
||||
.nd { color: #f8f8f2 } /* Name.Decorator */
|
||||
.ni { color: #f8f8f2 } /* Name.Entity */
|
||||
.ne { color: #f8f8f2 } /* Name.Exception */
|
||||
.nf { color: #50fa7b } /* Name.Function */
|
||||
.nl { color: #8be9fd; font-style: italic } /* Name.Label */
|
||||
.nn { color: #f8f8f2 } /* Name.Namespace */
|
||||
.nx { color: #f8f8f2 } /* Name.Other */
|
||||
.py { color: #f8f8f2 } /* Name.Property */
|
||||
.nt { color: #ff79c6 } /* Name.Tag */
|
||||
.nv { color: #8be9fd; font-style: italic } /* Name.Variable */
|
||||
.ow { color: #ff79c6 } /* Operator.Word */
|
||||
.w { color: #f8f8f2 } /* Text.Whitespace */
|
||||
.mb { color: #bd93f9 } /* Literal.Number.Bin */
|
||||
.mf { color: #bd93f9 } /* Literal.Number.Float */
|
||||
.mh { color: #bd93f9 } /* Literal.Number.Hex */
|
||||
.mi { color: #bd93f9 } /* Literal.Number.Integer */
|
||||
.mo { color: #bd93f9 } /* Literal.Number.Oct */
|
||||
.sa { color: #f1fa8c } /* Literal.String.Affix */
|
||||
.sb { color: #f1fa8c } /* Literal.String.Backtick */
|
||||
.sc { color: #f1fa8c } /* Literal.String.Char */
|
||||
.dl { color: #f1fa8c } /* Literal.String.Delimiter */
|
||||
.sd { color: #f1fa8c } /* Literal.String.Doc */
|
||||
.s2 { color: #f1fa8c } /* Literal.String.Double */
|
||||
.se { color: #f1fa8c } /* Literal.String.Escape */
|
||||
.sh { color: #f1fa8c } /* Literal.String.Heredoc */
|
||||
.si { color: #f1fa8c } /* Literal.String.Interpol */
|
||||
.sx { color: #f1fa8c } /* Literal.String.Other */
|
||||
.sr { color: #f1fa8c } /* Literal.String.Regex */
|
||||
.s1 { color: #f1fa8c } /* Literal.String.Single */
|
||||
.ss { color: #f1fa8c } /* Literal.String.Symbol */
|
||||
.bp { color: #f8f8f2; font-style: italic } /* Name.Builtin.Pseudo */
|
||||
.fm { color: #50fa7b } /* Name.Function.Magic */
|
||||
.vc { color: #8be9fd; font-style: italic } /* Name.Variable.Class */
|
||||
.vg { color: #8be9fd; font-style: italic } /* Name.Variable.Global */
|
||||
.vi { color: #8be9fd; font-style: italic } /* Name.Variable.Instance */
|
||||
.vm { color: #8be9fd; font-style: italic } /* Name.Variable.Magic */
|
||||
.il { color: #bd93f9 } /* Literal.Number.Integer.Long */
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{% block title %}title{% endblock %} - {{ config.USER_APP_NAME }}</title>
|
||||
<link rel="stylesheet" type="text/css" href="/static/bootstrap.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/custom.css?v=19">
|
||||
<link rel="stylesheet" type="text/css" href="/static/custom.css?v=20">
|
||||
<link rel="search" type="application/opensearchdescription+xml" href="/static/opensearch.xml" title="ContentDB" />
|
||||
<link rel="shortcut icon" href="/favicon-16.png" sizes="16x16">
|
||||
<link rel="icon" href="/favicon-128.png" sizes="128x128">
|
||||
|
@ -51,6 +51,7 @@ psycopg2==2.8.5
|
||||
py==1.9.0
|
||||
pycparser==2.20
|
||||
pyparsing==2.4.7
|
||||
pygments==2.7.4
|
||||
pyScss==1.3.7
|
||||
pytest==5.4.3
|
||||
pytest-cov==2.10.0
|
||||
|
@ -15,6 +15,7 @@ markdown ~= 3.1
|
||||
bleach ~= 3.1
|
||||
passlib ~= 1.7
|
||||
|
||||
pygments ~= 2.7
|
||||
|
||||
beautifulsoup4 ~= 4.6
|
||||
celery ~= 4.4
|
||||
|
Loading…
Reference in New Issue
Block a user