This commit is contained in:
Trilarion
2020-04-16 20:21:14 +02:00
parent 48ade4bc0b
commit 1ca7c6c12d
10 changed files with 346 additions and 183 deletions

View File

@ -7,6 +7,11 @@ http://cyxdown.free.fr/bs/
http://cyxdown.free.fr/f2b/
http://dead-code.org/home/
https://github.com/restorer/gloomy-dungeons-2
https://github.com/WohlSoft/PGE-Project
https://en.wikipedia.org/wiki/List_of_free_and_open-source_Android_applications#Games
https://notabug.org/Calinou/awesome-gamedev#games
https://forum.freegamedev.net/viewtopic.php?f=20&t=11627
https://www.old-games.ru/forum/threads/nekommercheskie-analogi-izvestnyx-igr.40868/page-9
https://github.com/MyreMylar/pygame_gui
http://e-adventure.e-ucm.es/login/index.php (games of eAdventure)
http://ethernet.wasted.ch/

View File

@ -1,4 +1,4 @@
start: title description property+ _E note _E? building
start: title description property+ _E note? _E? building
title: "# " /(?! ).+(?<! )/ "\n" _E // not starting or ending with a space
@ -12,4 +12,4 @@ building: "## Building\n" _E property+ _E? note // the "building" section
note: /(?![\-#]).*\n/* // Unstructured text, not starting with - or #
_E: /^$\n/m // empty new line (filtered from tree)
_E: /^$\n/m // empty new line

View File

@ -1,8 +1,8 @@
start: header entries*
start: header entry*
header: "# " name " (" number ")\n" _E
entries: "## " name " (" number ")\n" _E property+ _E
entry: "## " name " (" number ")\n" _E property+ _E
property: "- " _key ": " _value "\n"
_key: /(?! ).+?(?=:)(?<! )/ // key: everything until next ":", not beginning or ending with a space

View File

@ -22,11 +22,14 @@ if __name__ == "__main__":
# read developer info
developer_info = osg.read_developer_info()
osg.write_developer_info(developer_info)
osg.write_developer_info(developer_info) # write again just to make nice
# assemble info
entries = osg.assemble_infos()
# cross-check
osg.compare_entries_developers(entries, developer_info)
# loop over infos
developers = ''
try:

View File

@ -0,0 +1,9 @@
from utils import constants as c, utils, osg
if __name__ == "__main__":
inspirations = osg.read_inspirations_info()
osg.write_inspirations_info(inspirations) # write again just to check integrity
# assemble info
entries = osg.assemble_infos()

View File

@ -20,7 +20,7 @@ class ListingTransformer(lark.Transformer):
def name(self, x):
return ('name', x[0].value)
def entries(self, x):
def entry(self, x):
d = {}
for key, value in x:
d[key] = value
@ -32,6 +32,34 @@ class ListingTransformer(lark.Transformer):
def start(self, x):
return x
# transformer
class EntryTransformer(lark.Transformer):
def start(self, x):
d = {}
for key, value in x:
d[key] = value
return d
def title(self, x):
return ('title', x[0].value)
def description(self, x):
return ('description', x[0].value)
def property(self, x):
return (str.casefold(x[0].value), x[1].value)
def note(self, x):
return ('note', x[0].value)
def building(self, x):
d = {}
for key, value in x:
d[key] = value
return ('building', d)
essential_fields = ('Home', 'State', 'Keywords', 'Code repository', 'Code language', 'Code license')
valid_fields = (
@ -72,6 +100,7 @@ regex_sanitize_name = re.compile(r"[^A-Za-z 0-9-+]+")
regex_sanitize_name_space_eater = re.compile(r" +")
valid_developer_fields = ('name', 'games', 'contact', 'organization', 'home')
valid_inspiration_fields = ('name', 'inspired entries')
comment_string = '[comment]: # (partly autogenerated content, edit with care, read the manual before)'
@ -383,18 +412,27 @@ def read_developer_info():
developers = read_and_parse(developer_file, grammar_file, transformer)
# now transform a bit more
for index, dev in enumerate(developers):
# check for valid keys
for field in dev.keys():
if field not in valid_developer_fields:
raise RuntimeError('Unknown developer field "{}" for developer: {}.'.format(field, dev['name']))
# strip from name or organization (just in case)
for field in ('name', 'organization'):
if field in dev:
dev[field] = dev[field].strip()
# split games, contact (are lists)
for field in ('games', 'contact'):
if field in dev:
content = dev[field]
content = content.split(',')
content = [x.strip() for x in content]
dev[field] = content
# check for duplicate names entries
names = [dev['name'] for dev in developers]
duplicate_names = (name for name in names if names.count(name) > 1)
duplicate_names = set(duplicate_names) # to avoid duplicates in duplicate_names
if duplicate_names:
print('Warning: duplicate developer names: {}'.format(', '.join(duplicate_names)))
return developers
@ -445,7 +483,27 @@ def read_inspirations_info():
inspirations_file = os.path.join(c.root_path, 'inspirations.md')
grammar_file = os.path.join(c.code_path, 'grammar_listing.lark')
transformer = ListingTransformer()
return read_and_parse(inspirations_file, grammar_file, transformer)
inspirations = read_and_parse(inspirations_file, grammar_file, transformer)
# now transform a bit more
for index, inspiration in enumerate(inspirations):
# check for valid keys
for field in inspiration.keys():
if field not in valid_inspiration_fields:
raise RuntimeError('Unknown field "{}" for inspiration: {}.'.format(field, inspiration['name']))
# split lists
for field in ('inspired entries', ):
if field in inspiration:
content = inspiration[field]
content = content.split(',')
content = [x.strip() for x in content]
inspiration[field] = content
# check for duplicate names entries
names = [inspiration['name'] for inspiration in inspirations]
duplicate_names = (name for name in names if names.count(name) > 1)
duplicate_names = set(duplicate_names) # to avoid duplicates in duplicate_names
if duplicate_names:
print('Warning: duplicate inspiration names: {}'.format(', '.join(duplicate_names)))
return inspirations
def write_inspirations_info(inspirations):
@ -454,4 +512,79 @@ def write_inspirations_info(inspirations):
:param inspirations:
:return:
"""
inspirations_file = os.path.join(c.root_path, 'inspirations.md')
# comment
content = '{}\n'.format(comment_string)
# number of developer
content += '# Inspirations ({})\n\n'.format(len(inspirations))
# sort by name
inspirations.sort(key=lambda x: str.casefold(x['name']))
# iterate over them
for inspiration in inspirations:
# inspiration name
content += '## {} ({})\n\n'.format(inspiration['name'], len(inspiration['inspired entries']))
# games
content += '- Inspired entries: {}\n'.format(', '.join(sorted(inspiration['inspired entries'], key=str.casefold)))
# all the remaining in alphabetical order
for field in sorted(inspiration.keys()):
if field not in ('name', 'inspired entries'):
value = inspiration[field]
field = field.capitalize()
if isinstance(value, str):
content += '- {}: {}\n'.format(field, value)
else:
content += '- {}: {}\n'.format(field, ', '.join(sorted(value, key=str.casefold)))
content += '\n'
# write
inspirations_file = os.path.join(c.root_path, 'inspirations2.md')
utils.write_text(inspirations_file, content)
def compare_entries_developers(entries, developers):
"""
Cross checks the game entries lists and the developers lists.
:param entries: List of game entries
:param developers: List of developers
"""
# from the entries create a dictionary with developer names
devs1 = {}
for entry in entries:
name = entry['name']
for dev in entry.get('developer', []):
if dev in devs1:
devs1[dev].append(name)
else:
devs1[dev] = [name]
devs1_names = set(devs1.keys())
# from the developers create a dictionary with developer names
devs2 = dict(zip((dev['name'] for dev in developers), (dev['games'] for dev in developers)))
devs2_names = set(devs2.keys())
# devs only in entries
for dev in devs1_names - devs2_names:
print('Warning: dev "{}" only in entries ({}), not in developers'.format(dev, ','.join(devs1[dev])))
# devs only in developers
for dev in devs2_names - devs1_names:
print('Warning: dev "{}" only in developers ({}), not in entries'.format(dev, ','.join(devs2[dev])))
# for those in both, check that the games lists are equal
for dev in devs1_names.intersection(devs2_names):
games1 = set(devs1[dev])
games2 = set(devs2[dev])
delta = games1 - games2
if delta:
print('Warning: dev "{}" has games in entries ({}) that are not present in developers'.format(dev, ', '.join(delta)))
delta = games2 - games1
if delta:
print('Warning: dev "{}" has games in developers ({}) that are not present in entries'.format(dev, ', '.join(delta)))