improved static website

This commit is contained in:
Trilarion 2020-09-21 10:23:12 +02:00
parent c18b225780
commit 9d65ee912b
16 changed files with 381 additions and 155 deletions

View File

@ -210,6 +210,7 @@ https://github.com/AtomicGameEngine/AtomicGameEngine
https://github.com/atphalix/nexuiz https://github.com/atphalix/nexuiz
https://github.com/azhirnov/FrameGraph https://github.com/azhirnov/FrameGraph
https://github.com/benl23x5/gloss https://github.com/benl23x5/gloss
https://github.com/bepu/bepuphysics2
https://github.com/bernardosulzbach/dungeon https://github.com/bernardosulzbach/dungeon
https://github.com/bioglaze/aether3d https://github.com/bioglaze/aether3d
https://github.com/bomblik/BlockOut_II_PSVITA https://github.com/bomblik/BlockOut_II_PSVITA
@ -243,6 +244,7 @@ https://github.com/DethRaid/SanityEngine
https://github.com/Donerkebap13/DonerComponents https://github.com/Donerkebap13/DonerComponents
https://github.com/Drasky-Vanderhoff/CommonDrops https://github.com/Drasky-Vanderhoff/CommonDrops
https://github.com/Dzierzan/OpenSA https://github.com/Dzierzan/OpenSA
https://github.com/EasyRPG/Editor-Qt
https://github.com/EaW-Team/equestria_dev https://github.com/EaW-Team/equestria_dev
https://github.com/EliFUT/android https://github.com/EliFUT/android
https://github.com/elishacloud/Silent-Hill-2-Enhancements https://github.com/elishacloud/Silent-Hill-2-Enhancements
@ -300,8 +302,10 @@ https://github.com/libretro/libretro-chailove
https://github.com/libretro/libretro-prboom https://github.com/libretro/libretro-prboom
https://github.com/ligurio/awesome-ttygames https://github.com/ligurio/awesome-ttygames
https://github.com/luciopanepinto/pacman https://github.com/luciopanepinto/pacman
https://github.com/LuminoEngine/Lumino
https://github.com/MarcoLizza/tofu-engine https://github.com/MarcoLizza/tofu-engine
https://github.com/MarilynDafa/Bulllord-Engine https://github.com/MarilynDafa/Bulllord-Engine
https://github.com/Martenfur/Monofoxe
https://github.com/MatthewTheGlutton/HideousDestructor https://github.com/MatthewTheGlutton/HideousDestructor
https://github.com/McKay42/McOsu https://github.com/McKay42/McOsu
https://github.com/megamarc/Tilengine https://github.com/megamarc/Tilengine
@ -326,6 +330,7 @@ https://github.com/OpenRA/d2
https://github.com/OpenRA/OpenRAModSDK https://github.com/OpenRA/OpenRAModSDK
https://github.com/opensourcedesign https://github.com/opensourcedesign
https://github.com/opentrack/opentrack https://github.com/opentrack/opentrack
https://github.com/OrionFive/Hospitality
https://github.com/OSSGames https://github.com/OSSGames
https://github.com/OSSGames (all there, but we should have them already) https://github.com/OSSGames (all there, but we should have them already)
https://github.com/ozkriff/zemeroth https://github.com/ozkriff/zemeroth
@ -404,6 +409,7 @@ https://github.com/wojtekpil/Godot-Octahedral-Impostors
https://github.com/xrOxygen/xray-oxygen https://github.com/xrOxygen/xray-oxygen
https://github.com/YuriiSalimov/15-puzzle https://github.com/YuriiSalimov/15-puzzle
https://github.com/Zal0/ZGB https://github.com/Zal0/ZGB
https://github.com/zcaliptium/gdinv
https://github.com/zurn/zapper (or any other tapper clone) https://github.com/zurn/zapper (or any other tapper clone)
https://gitlab.com/LibreGames https://gitlab.com/LibreGames
https://gitlab.com/nyov/nyovs-nexuiz https://gitlab.com/nyov/nyovs-nexuiz

View File

@ -4,15 +4,41 @@ Generates the static website
Uses Jinja2 (see https://jinja.palletsprojects.com/en/2.11.x/) Uses Jinja2 (see https://jinja.palletsprojects.com/en/2.11.x/)
""" """
# TODO index.html tiles, content
# TODO index.html image
# TODO index.html only count games
# TODO Font awesome 5 (icons for OS, for Github, Gitlab and maybe others)
# TODO contribute.html tiles? content
# TODO games pages links to licenses (wikipedia)
# TODO games pages edit/contribute button
# TODO indexes: make categories bold that have a certain amount of entries!
# TODO everywhere: style URLs (Github, Wikipedia, Internet archive, SourceForge, ...)
# TODO developers pages links to games and more information, styles, block around entry, edit/contribute button
# TODO inspirations pages, add link to games and more information, styles, block around entry, edit/contribute button
# TODO navbar add is active
# TODO statistics page: better and more statistics with links where possible
# TODO meaningful information (links, license, last updated with lower precision)
# TODO singular, plural everywhere (game, entries, items)
import os import os
import shutil import shutil
import math import math
import datetime import datetime
from functools import partial
from utils import osg, constants as c, utils from utils import osg, constants as c, utils
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
import html5lib
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
extra = '0'
extended_alphabet = alphabet + extra
games_path = 'games'
inspirations_path = 'inspirations'
developers_path = 'developers'
html5parser = html5lib.HTMLParser(strict=True)
alphabet = 'abcdefghijklmnopqrstuvwxyz'
extended_alphabet = '0' + alphabet
def write(text, file): def write(text, file):
""" """
@ -20,14 +46,23 @@ def write(text, file):
:param text: :param text:
:param file: :param file:
""" """
# validate text
try:
html5parser.parse(text)
except Exception as e:
utils.write_text(os.path.join(c.web_path, 'invalid.html'), text) # for further checking with https://validator.w3.org/
raise RuntimeError(e)
# output file
file = os.path.join(c.web_path, file) file = os.path.join(c.web_path, file)
# create output directory if necessary
containing_dir = os.path.dirname(file) containing_dir = os.path.dirname(file)
if not os.path.isdir(containing_dir): if not os.path.isdir(containing_dir):
os.mkdir(containing_dir) os.mkdir(containing_dir)
# write text
utils.write_text(file, text) utils.write_text(file, text)
def sort_into_categories(list, categories, fit, unknown_category_name): def sort_into_categories(list, categories, fit, unknown_category_name=None):
""" """
:param list: :param list:
@ -46,16 +81,8 @@ def sort_into_categories(list, categories, fit, unknown_category_name):
categorized_sublists[unknown_category_name] = sublist categorized_sublists[unknown_category_name] = sublist
return categorized_sublists return categorized_sublists
def sort_by_alphabet(list, key):
"""
:param list: def divide_in_columns(categorized_lists, transform):
:param key:
:return:
"""
return sort_into_categories(list, alphabet, lambda item, category: item[key].lower().startswith(category), '0')
def divide_in_columns(categorized_lists, key):
""" """
:param categorized_lists: :param categorized_lists:
@ -66,7 +93,8 @@ def divide_in_columns(categorized_lists, key):
entries = {} entries = {}
for category in categorized_lists.keys(): for category in categorized_lists.keys():
e = categorized_lists[category] e = categorized_lists[category]
e = [e[key] for e in e] # transform entry
e = [transform(e) for e in e]
# divide in three equal lists # divide in three equal lists
n = len(e) n = len(e)
n1 = math.ceil(n/3) n1 = math.ceil(n/3)
@ -76,6 +104,118 @@ def divide_in_columns(categorized_lists, key):
return {'number_entries': number_entries, 'entries': entries} return {'number_entries': number_entries, 'entries': entries}
def url_to(current, target):
"""
:param current:
:param target:
:return:
"""
# split by slash
if current:
current = current.split('/')
target = target.split('/')
# reduce by common elements
while len(current) > 0 and len(target) > 1 and current[0] == target[0]:
current = current[1:]
target = target[1:]
# add .. as often as length of current still left
target = ['..'] * len(current) + target
# join by slash again
url = '/'.join(target)
return url
def preprocess(list, key, path):
"""
:param list:
:param key:
:return:
"""
_ = set()
for item in list:
# add unique anchor ref
anchor = osg.canonical_name(item[key])
while anchor in _:
anchor += 'x'
_.add(anchor)
item['anchor-id'] = anchor
# for alphabetic sorting
start = item[key][0].upper()
if not start in alphabet:
start = extra
item['letter'] = start
item['href'] = os.path.join(path, '{}.html#{}'.format(start, anchor))
def game_index(entry):
e = {
'name': entry['Title'],
'href': entry['href'],
'anchor-id': entry['anchor-id']
}
tags = []
if 'beta' in entry['State']:
tags.append('beta')
if osg.is_inactive(entry):
tags.append('inactive since {}'.format(osg.extract_inactive_year(entry)))
if tags:
e['tags'] = ', '.join(tags)
return e
def inspiration_index(inspiration):
e = {
'name': inspiration['Name'],
'href': inspiration['href'],
'anchor-id': inspiration['anchor-id'],
}
n = len(inspiration['Inspired entries'])
if n > 1:
e['tags'] = n
return e
def developer_index(developer):
e = {
'name': developer['Name'],
'href': developer['href'],
'anchor-id': developer['anchor-id']
}
n = len(developer['Games'])
if n > 1:
e['tags'] = n
return e
def add_entries_links_to_inspirations(inspirations, entries):
entries_references = {entry['Title']:entry['href'] for entry in entries}
for inspiration in inspirations:
inspired_entries = inspiration['Inspired entries']
inspired_entries = [(entries_references[entry], entry) for entry in inspired_entries]
inspiration['Inspired entries'] = inspired_entries
def add_entries_links_to_developers(developers, entries):
entries_references = {entry['Title']:entry['href'] for entry in entries}
for developer in developers:
developed_entries = developer['Games']
developed_entries = [(entries_references[entry], entry) for entry in developed_entries]
developer['Games'] = developed_entries
def add_inspirations_and_developers_links_to_entries(entries, inspirations, developers):
inspirations_references = {inspiration['Name']: inspiration['href'] for inspiration in inspirations}
developer_references = {developer['Name']: developer['href'] for developer in developers}
for entry in entries:
if 'Inspirations' in entry:
entry['Inspirations'] = [(inspirations_references[inspiration.value], inspiration.value) for inspiration in entry['Inspirations']]
if 'Developer' in entry:
entry['Developer'] = [(developer_references[developer.value], developer.value) for developer in entry['Developer']]
def generate(entries, inspirations, developers): def generate(entries, inspirations, developers):
""" """
@ -84,21 +224,29 @@ def generate(entries, inspirations, developers):
:param developers: :param developers:
""" """
# add anchor ref () to every entry # preprocess
for entry in entries: preprocess(entries, 'Title', games_path)
entry['title-anchor'] = osg.canonical_entry_name(entry['Title']) preprocess(inspirations, 'Name', inspirations_path)
preprocess(developers, 'Name', developers_path)
# set internal links up
add_entries_links_to_inspirations(inspirations, entries)
add_entries_links_to_developers(developers, entries)
add_inspirations_and_developers_links_to_entries(entries, inspirations, developers)
# sort into categories
games_by_alphabet = sort_into_categories(entries, extended_alphabet, lambda item, category: category == item['letter'])
inspirations_by_alphabet = sort_into_categories(inspirations, extended_alphabet, lambda item, category: category == item['letter'])
developers_by_alphabet = sort_into_categories(developers, extended_alphabet, lambda item, category: category == item['letter'])
genres = [keyword.capitalize() for keyword in c.recommended_keywords]
games_by_genre = sort_into_categories(entries, genres, lambda item, category: category.lower() in item['Keywords'])
games_by_platform = sort_into_categories(entries, c.valid_platforms, lambda item, category: category in item.get('Platform', []), 'Unspecified')
games_by_language = sort_into_categories(entries, c.known_languages, lambda item, category: category in item['Code language'])
# base dictionary # base dictionary
base = { base = {
'title': 'OSGL', 'title': 'OSGL',
'paths': {
'css': 'css/bulma.min.css',
'index': 'index.html',
'index-games': 'games/index.html',
'index-developers': 'developers/index.html',
'index-inspirations': 'inspirations/index.html',
'index-statistics': 'index-statistics'
},
'creation-date': datetime.datetime.utcnow() 'creation-date': datetime.datetime.utcnow()
} }
@ -114,80 +262,26 @@ def generate(entries, inspirations, developers):
template_categorical_index = environment.get_template('categorical_index.jinja') template_categorical_index = environment.get_template('categorical_index.jinja')
template_list = environment.get_template('list.jinja') template_list = environment.get_template('list.jinja')
# top level folder
base['url_to'] = partial(url_to, '')
# index.html # index.html
index = {'number_games': len(entries)} # TODO only count games index = {'number_games': len(entries)}
template = environment.get_template('index.jinja') template = environment.get_template('index.jinja')
write(template.render(index=index), 'index.html') write(template.render(index=index), 'index.html')
# generate games pages # contribute.html
games_by_alphabet = sort_by_alphabet(entries, 'Title') template = environment.get_template('contribute.jinja')
template = environment.get_template('games_for_letter.jinja') write(template.render(), 'contribute.html')
for letter in extended_alphabet:
write(template.render(letter=letter, games=games_by_alphabet[letter]), os.path.join('games', '{}.html'.format(letter.capitalize())))
# generate games index # statistics
index = divide_in_columns(games_by_alphabet, 'Title')
index['title'] = 'Games index'
index['categories'] = extended_alphabet
write(template_categorical_index.render(index=index), os.path.join('games', 'index.html'))
## inspirations # preparation
inspirations_by_alphabet = sort_by_alphabet(inspirations, 'Name') template = environment.get_template('statistics.jinja')
data = {
# inspirations index 'title': 'Statistics',
index = divide_in_columns(inspirations_by_alphabet, 'Name') 'sections': []
index['title'] = 'Inspirations index' }
index['categories'] = extended_alphabet
write(template_categorical_index.render(index=index), os.path.join('inspirations', 'index.html'))
# inspirations single pages
template = environment.get_template('inspirations_for_letter.jinja')
for letter in extended_alphabet:
write(template.render(letter=letter, inspirations=inspirations_by_alphabet[letter]), os.path.join('inspirations', '{}.html'.format(letter.capitalize())))
## developers
# developers single pages
developers_by_alphabet = sort_by_alphabet(developers, 'Name')
template = environment.get_template('developers_for_letter.jinja')
for letter in extended_alphabet:
write(template.render(letter=letter, developers=developers_by_alphabet[letter]), os.path.join('developers', '{}.html'.format(letter.capitalize())))
# developers index
index = divide_in_columns(developers_by_alphabet, 'Name')
index['title'] = 'Developers index'
index['categories'] = extended_alphabet
write(template_categorical_index.render(index=index), os.path.join('developers', 'index.html'))
## genres
genres = c.recommended_keywords
games_by_genre = sort_into_categories(entries, genres, lambda item, category: category in item['Keywords'], None)
index = divide_in_columns(games_by_genre, 'Title')
index['title'] = 'Games by genre'
index['categories'] = genres
write(template_categorical_index.render(index=index), os.path.join('games', 'genres.html'))
## games by language TODO make categories bold that have a certain amount of entries!
languages = c.known_languages
games_by_language = sort_into_categories(entries, languages, lambda item, category: category in item['Code language'], None)
index = divide_in_columns(games_by_language, 'Title')
index['title'] = 'Games by language'
index['categories'] = languages # it's fine if they get capitalized, because they are already capitalized
write(template_categorical_index.render(index=index), os.path.join('games', 'languages.html'))
## games by platform
platforms = c.valid_platforms
games_by_platform = sort_into_categories(entries, platforms, lambda item, category: category in item.get('Platform', []), 'Unspecified')
index = divide_in_columns(games_by_platform, 'Title')
index['title'] = 'Games by platform'
index['categories'] = platforms # TODO (do not capitalize automatically)
write(template_categorical_index.render(index=index), os.path.join('games', 'platforms.html'))
## statistics
# index
template = environment.get_template('statistics_index.jinja')
write(template.render(), os.path.join('statistics', 'index.html'))
# build-systems # build-systems
build_systems = [] build_systems = []
@ -201,12 +295,78 @@ def generate(entries, inspirations, developers):
unique_build_systems = [(l, build_systems.count(l)) for l in unique_build_systems] unique_build_systems = [(l, build_systems.count(l)) for l in unique_build_systems]
unique_build_systems.sort(key=lambda x: str.casefold(x[0])) # first sort by name unique_build_systems.sort(key=lambda x: str.casefold(x[0])) # first sort by name
unique_build_systems.sort(key=lambda x: -x[1]) # then sort by occurrence (highest occurrence first) unique_build_systems.sort(key=lambda x: -x[1]) # then sort by occurrence (highest occurrence first)
data = { section = {
'title': 'Build system', 'title': 'Build system',
'items': ['{} ({})'.format(*item) for item in unique_build_systems] 'items': ['{} ({})'.format(*item) for item in unique_build_systems]
} }
write(template_list.render(data=data), os.path.join('statistics', 'build-systems.html')) data['sections'].append(section)
write(template.render(data=data), os.path.join('statistics.html'))
# games folder
base['url_to'] = partial(url_to, games_path)
# generate games pages
template = environment.get_template('games_for_letter.jinja')
for letter in extended_alphabet:
data = {
'title': 'Games with {}'.format(letter.capitalize()),
'games': games_by_alphabet[letter]
}
write(template.render(data=data), os.path.join(games_path, '{}.html'.format(letter.capitalize())))
# generate games index
index = divide_in_columns(games_by_alphabet, game_index)
index['title'] = 'Alphabetical index'
index['categories'] = extended_alphabet
write(template_categorical_index.render(index=index), os.path.join(games_path, 'index.html'))
# genres
index = divide_in_columns(games_by_genre, game_index)
index['title'] = 'Games by genre'
index['categories'] = genres
write(template_categorical_index.render(index=index), os.path.join(games_path, 'genres.html'))
# games by language
index = divide_in_columns(games_by_language, game_index)
index['title'] = 'Games by language'
index['categories'] = c.known_languages
write(template_categorical_index.render(index=index), os.path.join(games_path, 'languages.html'))
# games by platform
index = divide_in_columns(games_by_platform, game_index)
index['title'] = 'Games by platform'
index['categories'] = c.valid_platforms + ('Unspecified',)
write(template_categorical_index.render(index=index), os.path.join(games_path, 'platforms.html'))
# inspirations folder
base['url_to'] = partial(url_to, inspirations_path)
# inspirations
# inspirations index
index = divide_in_columns(inspirations_by_alphabet, inspiration_index)
index['title'] = 'Inspirations index'
index['categories'] = extended_alphabet
write(template_categorical_index.render(index=index), os.path.join(inspirations_path, 'index.html'))
# inspirations single pages
template = environment.get_template('inspirations_for_letter.jinja')
for letter in extended_alphabet:
write(template.render(letter=letter, inspirations=inspirations_by_alphabet[letter]), os.path.join(inspirations_path, '{}.html'.format(letter.capitalize())))
# developers folder
base['url_to'] = partial(url_to, developers_path)
# developers single pages
template = environment.get_template('developers_for_letter.jinja')
for letter in extended_alphabet:
write(template.render(letter=letter, developers=developers_by_alphabet[letter]), os.path.join(developers_path, '{}.html'.format(letter.capitalize())))
# developers index
index = divide_in_columns(developers_by_alphabet, developer_index)
index['title'] = 'Developers index'
index['categories'] = extended_alphabet
write(template_categorical_index.render(index=index), os.path.join(developers_path, 'index.html'))
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -4,22 +4,22 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ base['title'] }}</title> <title>{{ base['title'] }}</title>
<link rel="stylesheet" href="{{ base['paths']['css'] }}"> <link rel="stylesheet" href="{{ base['url_to']('css/bulma.min.css') }}">
</head> </head>
<body> <body>
<nav class="container navbar" role="navigation" aria-label="main navigation"> <nav class="container navbar" role="navigation" aria-label="main navigation">
<div class="navbar-menu"> <div class="navbar-menu">
<div class="navbar-start"> <div class="navbar-start">
<a class="navbar-item" href="{{ base['paths']['index'] }}"> <a class="navbar-item" href="{{ base['url_to']('index.html') }}">
Home Home
</a> </a>
<a class="navbar-item" href="{{ base['paths']['index-games'] }}"> <a class="navbar-item" href="{{ base['url_to']('games/index.html') }}">
Games Games
</a> </a>
<a class="navbar-item" href="{{ base['paths']['index-developers'] }}"> <a class="navbar-item" href="{{ base['url_to']('developers/index.html') }}">
Developers Developers
</a> </a>
@ -29,28 +29,33 @@
</a> </a>
<div class="navbar-dropdown"> <div class="navbar-dropdown">
<a class="navbar-item" href="{{ base['paths']['index-inspirations'] }}"> <a class="navbar-item" href="{{ base['url_to']('inspirations/index.html') }}">
By inspiration By inspiration
</a> </a>
<a class="navbar-item" href="{{ base['paths']['index-developers'] }}"> <a class="navbar-item" href="{{ base['url_to']('games/genres.html') }}">
By category By category
</a> </a>
<a class="navbar-item" href="{{ base['paths']['index-developers'] }}"> <a class="navbar-item" href="{{ base['url_to']('games/languages.html') }}">
By code language By code language
</a> </a>
<a class="navbar-item" href="{{ base['paths']['index-developers'] }}"> <a class="navbar-item" href="{{ base['url_to']('games/platforms.html') }}">
By OS support By OS support
</a> </a>
<a class="navbar-item" href="{{ base['paths']['index-developers'] }}">
By dependency
</a>
</div> </div>
</div> </div>
<a class="navbar-item" href="{{ base['paths']['index-statistics'] }}"> <a class="navbar-item" href="{{ base['url_to']('statistics.html') }}">
Statistics Statistics
</a> </a>
<a class="navbar-item" href="{{ base['url_to']('contribute.html') }}">
Contribute
</a>
<a class="navbar-item" href="https://github.com/Trilarion/opensourcegames">
On GitHub
</a>
</div> </div>
</div> </div>
</nav> </nav>
@ -58,10 +63,9 @@
{% block content %}{% endblock %} {% block content %}{% endblock %}
<footer class="footer"> <footer class="footer">
<div class="content has-text-centered"> <div class="container is-size-7">
<p> <a href="https://trilarion.blogspot.com/search/label/osgames">Blog</a><br>
Footer content {{ base['creation-date'] }} Last updated on {{ base['creation-date'] }}
</p>
</div> </div>
</footer> </footer>
</body> </body>

View File

@ -3,26 +3,29 @@
{% block content %} {% block content %}
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1>{{ index['title'] }}</h1> <div class="box">
<p> <h1 class="title">{{ index['title'] }}</h1>
{% set comma = joiner(",") %} {% set comma = joiner(",") %}
{% for category in index['categories'] %} {% for category in index['categories'] %}
{{ comma() }} <a href="#{{ category }}">{{ category.capitalize() }}</a> ({{ index['number_entries'][category] }}) {{ comma() }} <a href="#{{ category }}" class="is-size-4">{{ category }}</a>&nbsp;with&nbsp;{{ index['number_entries'][category] }}&nbsp;item(s)
{% endfor %} {% endfor %}
</p> </div>
{% for category in index['categories'] %} {% for category in index['categories'] %}
<h2 id="{{ category }}">{{ category.capitalize() }}</h2> <div class="box">
<h2 id="{{ category }}" class="is-size-4">{{ category }}</h2>
<div class="columns"> <div class="columns">
{% for entries_column in index['entries'][category] %} {% for entries_column in index['entries'][category] %}
<div class="column"> <div class="column">
<ul> <ul>
{% for entry in entries_column %} {% for entry in entries_column %}
<li>{{ entry }}</li> <li><a href="{{ base['url_to'](entry['href']) }}">{{ entry['name'] }}</a> {% if 'tags' in entry %}<span class="is-light is-size-7">({{ entry['tags'] }})</span>{% endif %}</li>
{% endfor %} {% endfor %}
</ul> </ul>
</div> </div>
{% endfor %} {% endfor %}
</div> </div>
<a class="is-light is-size-7" href="#">Back to top</a>
</div>
{% endfor %} {% endfor %}
</div> </div>
</section> </section>

View File

@ -3,12 +3,13 @@
{% block content %} {% block content %}
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1>Inspirations ({{ letter.capitalize() }})</h1> <h1 class="title">Developers ({{ letter.capitalize() }})</h1>
{% for developer in developers %} {% for developer in developers %}
<p> <div class="box">
{{ developer['Name'] }}<br> <h2 id="{{ developer['anchor-id'] }}">{{ developer['Name'] }}</h2><br>
Games: {{ developer['Games']|join(', ') }} {% set comma = joiner(", ") %}
</p> Game(s):{% for game in developer['Games'] %}{{ comma() }}<a href="{{ base['url_to'](game[0]) }}">{{ game[1] }}</a>{% endfor %}
</div>
{% endfor %} {% endfor %}
</div> </div>
</section> </section>

View File

@ -3,21 +3,41 @@
{% block content %} {% block content %}
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1>Games ({{ letter.capitalize() }})</h1> <h1 class="title">{{ data['title'] }}</h1>
{% for g in games %} {% for g in data['games'] %}
<p> <div class="box">
<a id="#{{ g['title-anchor'] }}">{{ g['Title'] }}</a><br> <nav class="level is-mobile">
Home: {{ g['Home'] }}<br> <div class="level-left">
{% if 'Inspirations' in g %}{% endif%} <h2 id="{{ g['anchor-id'] }}">{{ g['Title'] }}</h2>
{% if 'Media' in g %}{% endif%} </div>
{% if 'Download' in g %}{% endif%} <div class="level-right is-size-7">
{% if 'Play' in g %}{% endif%} <p class="level-item"><a href="{{ base['url_to']('contribute.html') }}">Edit</a></p>
{% if 'Developer' in g %}{% endif%} </div>
{% if 'Note' in g %}{% endif%} </nav>
Technical info:<br>
Language: {{ g['Code language'] }}<br> {%- set comma = joiner(", ") -%}
License: {{ g['Code license'] }} Home: {% for url in g['Home'] %}{{ comma() }}<a href="{{ url }}">{{ url }}</a>{% endfor %}<br>
</p> {% if 'Inspirations' in g %}
{%- set comma = joiner(", ") -%}
Inspirations: {% for inspiration in g['Inspirations']%}{{ comma() }}<a href="{{ base['url_to'](inspiration[0]) }}">{{ inspiration[1] }}</a>{% endfor %}<br>
{% endif%}
{%- set comma = joiner(", ") -%}
{% if 'Media' in g %}Media: {% for url in g['Media'] %}{{ comma() }}<a href="{{ url }}">{{ url }}</a>{% endfor %}<br>{% endif%}
{%- set comma = joiner(", ") -%}
{% if 'Download' in g %}Download: {% for url in g['Download'] %}{{ comma() }}<a href="{{ url }}">{{ url }}</a>{% endfor %}<br>{% endif%}
{%- set comma = joiner(", ") -%}
{% if 'Play' in g %}Play: {% for url in g['Play'] %}{{ comma() }}<a href="{{ url }}">{{ url }}</a>{% endfor %}<br>{% endif%}
{% if 'Developer' in g %}
{%- set comma = joiner(", ") -%}
Developer: {% for developer in g['Developer']%}{{ comma() }}<a href="{{ base['url_to'](developer[0]) }}">{{ developer[1] }}</a>{% endfor %}<br>{% endif%}
{% if 'Note' in g %}{{ g['Note'] }}<br>{% endif%}
Technical info<br>
{%- set comma = joiner(", ") -%}
Language: {% for language in g['Code language'] %}{{ comma() }}{{ language }}{% endfor %}<br>
{%- set comma = joiner(", ") -%}
License: {% for license in g['Code license'] %}{{ comma() }}{{ license }}{% endfor %}<br>
{% if 'Build system' in g['Building'] %}Build system: <br>{% endif%}
</div>
{% endfor %} {% endfor %}
</div> </div>
</section> </section>

View File

@ -3,9 +3,7 @@
{% block content %} {% block content %}
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1 class="title"> <h1 class="title">Open source games list (OSGL)</h1>
Open source games list (OSGL)
</h1>
<p class="subtitle"> <p class="subtitle">
Contains information about {{ index['number_games'] }} open source games. Contains information about {{ index['number_games'] }} open source games.
</p> </p>

View File

@ -3,13 +3,14 @@
{% block content %} {% block content %}
<section class="section"> <section class="section">
<div class="container"> <div class="container">
<h1>Inspirations ({{ letter.capitalize() }})</h1> <h1 class="title">Inspirations ({{ letter.capitalize() }})</h1>
{% for inspiration in inspirations %} {% for inspiration in inspirations %}
<p> <div class="box">
{{ inspiration['Name'] }}<br> <h2 id="{{ inspiration['anchor-id'] }}">{{ inspiration['Name'] }}</h2><br>
{% if 'Media' in inspiration %}Media: {{ inspiration['Media'] }}<br>{% endif %} {% if 'Media' in inspiration %}Media: {{ inspiration['Media'] }}<br>{% endif %}
Inspired entries: {% for game in inspiration['Inspired entries'] %}{{ game }}{% endfor %} {% set comma = joiner(", ") %}
</p> Inspired entries: {% for game in inspiration['Inspired entries'] %}{{ comma() }}<a href="{{ base['url_to'](game[0]) }}">{{ game[1] }}</a>{% endfor %}
</div>
{% endfor %} {% endfor %}
</div> </div>
</section> </section>

View File

@ -0,0 +1,28 @@
{% extends "base.jinja" %}
{% block content %}
<section class="section">
<div class="container">
<h1 class="title">{{ data['title'] }}</h1>
{% set comma = joiner(",") %}
{% for section in data['sections'] %}
{{ comma() }} <a href="#">{{ section['title'] }}</a>
{% endfor %}
</div>
</section>
{% for section in data['sections'] %}
<section class="section">
<div class="container">
<h2 id="">{{ section['title'] }}</h2>
<ul>
{% for item in section['items'] %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</div>
</section>
{% endfor %}
{% endblock %}

View File

@ -1,4 +0,0 @@
{% extends "base.jinja" %}
{% block content %}
{% endblock %}

View File

@ -55,7 +55,7 @@ def download_lgw_content():
for game in games: for game in games:
print(game[1]) print(game[1])
url = base_url + game[0] url = base_url + game[0]
destination_file = os.path.join(destination_path, osg.canonical_entry_name(game[0][1:]) + '.html') destination_file = os.path.join(destination_path, osg.canonical_name(game[0][1:]) + '.html')
text = requests.get(url).text text = requests.get(url).text
utils.write_text(destination_file, text) utils.write_text(destination_file, text)

View File

@ -218,7 +218,7 @@ if __name__ == "__main__":
# determine file name # determine file name
print('create new entry for {}'.format(lgw_name)) print('create new entry for {}'.format(lgw_name))
file_name = osg.canonical_entry_name(lgw_name) + '.md' file_name = osg.canonical_name(lgw_name) + '.md'
target_file = os.path.join(constants.entries_path, file_name) target_file = os.path.join(constants.entries_path, file_name)
if os.path.isfile(target_file): if os.path.isfile(target_file):
print('warning: file {} already existing, save under slightly different name'.format(file_name)) print('warning: file {} already existing, save under slightly different name'.format(file_name))

View File

@ -423,7 +423,7 @@ if __name__ == "__main__":
# determine file name # determine file name
print('create new entry for {}'.format(osgc_name)) print('create new entry for {}'.format(osgc_name))
file_name = osg.canonical_entry_name(osgc_name) + '.md' file_name = osg.canonical_name(osgc_name) + '.md'
target_file = os.path.join(constants.entries_path, file_name) target_file = os.path.join(constants.entries_path, file_name)
if os.path.isfile(target_file): if os.path.isfile(target_file):
print('warning: file {} already existing, save under slightly different name'.format(file_name)) print('warning: file {} already existing, save under slightly different name'.format(file_name))

View File

@ -3,4 +3,5 @@ lark-parser
BeautifulSoup BeautifulSoup
PyQt5 PyQt5
wikipedia wikipedia
Jinja2 Jinja2
html5lib

View File

@ -85,6 +85,14 @@ known_licenses = (
'LGPL-2.1', 'LGPL-3.0', 'MAME', 'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NetHack General Public License', 'LGPL-2.1', 'LGPL-3.0', 'MAME', 'MIT', 'MPL-1.1', 'MPL-2.0', 'MS-PL', 'MS-RL', 'NetHack General Public License',
'None', 'Proprietary', 'Public domain', 'SWIG license', 'Unlicense', 'WTFPL', 'wxWindows license', 'zlib', '?') 'None', 'Proprietary', 'Public domain', 'SWIG license', 'Unlicense', 'WTFPL', 'wxWindows license', 'zlib', '?')
license_urls = {
'2-clause BSD': 'https://en.wikipedia.org/wiki/BSD_licenses#2-clause_license_(%22Simplified_BSD_License%22_or_%22FreeBSD_License%22)',
'3-clause BSD': 'https://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_(%22BSD_License_2.0%22,_%22Revised_BSD_License%22,_%22New_BSD_License%22,_or_%22Modified_BSD_License%22)',
'AFL-3.0': 'https://en.wikipedia.org/wiki/Academic_Free_License',
'AGPL-3.0': 'https://en.wikipedia.org/wiki/GNU_Affero_General_Public_License',
'Apache-2.0': 'https://en.wikipedia.org/wiki/Apache_License'
}
# valid multiplayer modes (can be combined with "+" ) # valid multiplayer modes (can be combined with "+" )
valid_multiplayer_modes = ( valid_multiplayer_modes = (
'competitive', 'co-op', 'hotseat', 'LAN', 'local', 'massive', 'matchmaking', 'online', 'split-screen') 'competitive', 'co-op', 'hotseat', 'LAN', 'local', 'massive', 'matchmaking', 'online', 'split-screen')

View File

@ -38,9 +38,9 @@ def entry_iterator():
yield entry, entry_path, content yield entry, entry_path, content
def canonical_entry_name(name): def canonical_name(name):
""" """
Derives a canonical game name from an actual game name (suitable for file names, ...) Derives a canonical name from an actual name (suitable for file names, anchor names, ...)
""" """
name = name.casefold() name = name.casefold()
name = name.replace('ö', 'o').replace('ä', 'a').replace('ü', 'u') name = name.replace('ö', 'o').replace('ä', 'a').replace('ü', 'u')
@ -302,7 +302,7 @@ def check_and_process_entry(entry):
# check canonical file name # check canonical file name
file = entry['File'] file = entry['File']
canonical_file_name = canonical_entry_name(entry['Title']) + '.md' canonical_file_name = canonical_name(entry['Title']) + '.md'
# we also allow -X with X =2..9 as possible extension (because of duplicate canonical file names) # we also allow -X with X =2..9 as possible extension (because of duplicate canonical file names)
if canonical_file_name != file and canonical_file_name != file[:-5] + '.md': if canonical_file_name != file and canonical_file_name != file[:-5] + '.md':
message += 'file name should be {}\n'.format(canonical_file_name) message += 'file name should be {}\n'.format(canonical_file_name)