collage of images for title

This commit is contained in:
Trilarion 2020-11-11 17:01:26 +01:00
parent 7e2569b9e2
commit 967a98eed0
14 changed files with 231 additions and 34 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ __pycache__
/local-config.ini
/code/archive/**
/code/lgw-import
/code/html/images-download

View File

@ -10,6 +10,8 @@ https://github.com/eduard-permyakov/permafrost-engine
https://github.com/codenamecpp/carnage3d
https://github.com/WohlSoft/PGE-Project
https://github.com/wesnoth/haldric
https://github.com/project-imprimis/imprimis
https://github.com/WohlSoft/PGE-Project
https://github.com/mgerhardy/engine
https://github.com/GDQuest/godot-visual-effects
https://sourceforge.net/projects/freetrain/

View File

@ -17,12 +17,11 @@ Listing:
"""
# TODO index.html tiles, content
# TODO index.html image (maybe downloaded and assembled from osgameclones)
# TODO index.html only count games
# TODO Font awesome 4 or others (icons for OS, for Github, Gitlab and maybe others like external link)
# TODO contribute.html tiles? content?
# TODO games: links to licenses (wikipedia)
# TODO index.html content
# TODO index.html only count games and frameworks separately
# TODO more icons?
# TODO contribute.html content
# TODO games: links to licenses (wikipedia) complete
# TODO indexes: make categories bold that have a certain amount of entries!
# TODO everywhere: style URLs (Github, Wikipedia, Internet archive, SourceForge, ...)
# TODO developers: links to games and more information, styles
@ -48,6 +47,11 @@ Listing:
# TODO icons: for the main categories (devs, games, statistics, home, ...)
# TODO SEO optimizations, google search ...
# TODO <a> rel attribute https://www.w3schools.com/TAGS/att_a_rel.asp
# TODO recommended tags, links not going to genre
# TODO @see-home/@see-download (ignore or replace?)
# TODO tooltip of supported systems
# TODO improve or send feedback?
# TODO link dependencies
import os
import shutil
@ -91,6 +95,15 @@ platform_icon_map = {
'Unspecified': 'device_unknown'
}
genre_icon_map = {
'Action': 'target',
'Arcade': 'pacman',
'Visual novel': 'book',
'Puzzle': 'puzzle-piece',
'Cards': 'spades',
'Music': 'music'
}
plurals = {k: k+'s' for k in ('Assets license', 'Contact', 'Code language', 'Code license', 'Developer', 'Download', 'Inspiration', 'Game', 'Keyword', 'Home', 'Organization', 'Platform')}
for k in ('Media', 'Play', 'State'):
plurals[k] = k
@ -426,7 +439,10 @@ def convert_developers(developers, entries):
def create_keyword_tag(keyword):
if keyword in c.recommended_keywords:
return make_url(games_by_genres_path, make_text(keyword), '{} games'.format(keyword), 'tag is-info')
if keyword.capitalize() in genre_icon_map:
return make_url(games_by_genres_path, [make_icon(genre_icon_map[keyword.capitalize()]), make_text(keyword)], '{} games'.format(keyword), 'tag is-info')
else:
return make_url(games_by_genres_path, make_text(keyword), '{} games'.format(keyword), 'tag is-info')
else:
return make_text(keyword, 'tag is-light')
@ -439,9 +455,9 @@ def create_state_texts(states):
texts.append(make_text('beta', 'is-size-7 has-text-gray-light'))
inactive = [x for x in states if x.startswith('inactive since')]
if inactive:
texts.append([make_text(inactive[0], 'is-size-7 has-text-gray-light'), make_icon('bedtime')])
texts.append([make_text(inactive[0], 'is-size-7 has-text-gray-light'), make_icon('brightness_3')])
else:
texts.append(make_text('active', 'is-size-7 has-text-weight-bold has-text-info'))
texts.append([make_text('active', 'is-size-7 has-text-weight-bold has-text-info'), make_icon('sun')])
return texts
@ -461,7 +477,7 @@ def convert_entries(entries, inspirations, developers):
entry['note'] = make_text(entry['Note'], 'is-italic')
# keywords as tags
e = [create_keyword_tag(x) for x in entry['Keyword']]
e = [create_keyword_tag(x.value) for x in entry['Keyword']]
entry['keyword'] = make_tags(e)
# other normal fields (not technical info)
@ -583,10 +599,11 @@ def generate(entries, inspirations, developers):
'creation-date': datetime.datetime.utcnow()
}
# copy bulma css
# copy css
utils.copy_tree(os.path.join(c.web_template_path, 'css'), c.web_css_path)
#os.mkdir(c.web_css_path)
#shutil.copy2(os.path.join(c.web_template_path, 'bulma.min.css'), c.web_css_path)
# collage_image
shutil.copyfile(os.path.join(c.web_template_path, 'collage_games.jpg'), os.path.join(c.web_path, 'collage_games.jpg'))
# create Jinja Environment
environment = Environment(loader=FileSystemLoader(c.web_template_path), autoescape=True)
@ -657,7 +674,8 @@ def generate(entries, inspirations, developers):
# generate frameworks pages
for keyword in c.framework_keywords:
listing = {
'title': keyword.capitalize(),
'title': framework_names[keyword],
'subtitle': make_url(frameworks_path + ['index.html'], 'Index'),
'items': frameworks_by_type[keyword]
}
write(template_listing_entries.render(listing=listing), frameworks_path +['{}.html'.format(keyword)])
@ -689,7 +707,7 @@ def generate(entries, inspirations, developers):
index['title'] = make_text('Open source games')
index['subtitle'] = make_text('Index by game genre')
index['categories'] = genres
index['category-names'] = {k:k for k in index['categories']}
index['category-names'] = {k:[make_icon(genre_icon_map[k]), make_text(k)] if k in genre_icon_map else make_text(k) for k in index['categories']}
index['number_entries_per_category_threshold'] = 15
write(template_categorical_index.render(index=index), games_by_genres_path)

View File

@ -15,9 +15,6 @@
<div class="navbar-start">
<a class="navbar-item{% if 'index' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['index.html']) }}">{{ macros.render_icon('home') }}<span>Home</span></a>
<a class="navbar-item{% if 'games' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['games', 'index.html']) }}">{{ macros.render_icon('dice') }}<span>Games</span></a>
<a class="navbar-item{% if 'frameworks' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['frameworks', 'index.html']) }}">{{ macros.render_icon('wrench') }}<span>Frameworks/Tools</span></a>
<a class="navbar-item{% if 'developers' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['developers', 'index.html']) }}">{{ macros.render_icon('users') }}<span>Developers</span></a>
<a class="navbar-item{% if 'inspirations' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['inspirations', 'index.html']) }}">{{ macros.render_icon('bulb') }}<span>Inspirations</span></a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link{% if 'filter' in base['active_nav'] %} is-active{% endif %}">{{ macros.render_icon('filter') }}<span>Filter</span></a>
<div class="navbar-dropdown">
@ -26,6 +23,9 @@
<a class="navbar-item{% if 'platforms' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['games', 'platforms.html']) }}">{{ macros.render_icon('laptop') }}<span>By OS support</span></a>
</div>
</div>
<a class="navbar-item{% if 'frameworks' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['frameworks', 'index.html']) }}">{{ macros.render_icon('wrench') }}<span>Frameworks/Tools</span></a>
<a class="navbar-item{% if 'developers' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['developers', 'index.html']) }}">{{ macros.render_icon('users') }}<span>Developers</span></a>
<a class="navbar-item{% if 'inspirations' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['inspirations', 'index.html']) }}">{{ macros.render_icon('bulb') }}<span>Inspirations</span></a>
<a class="navbar-item{% if 'statistics' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['statistics.html']) }}">{{ macros.render_icon('stats-dots') }}<span>Statistics</span></a>
<a class="navbar-item{% if 'contribute' in base['active_nav'] %} is-active{% endif %}" href="{{ base['url_to'](['contribute.html']) }}">{{ macros.render_icon('pencil') }}<span>Contribute</span></a>
<a class="navbar-item" href="https://github.com/Trilarion/opensourcegames">{{ macros.render_icon('github') }}<span>On GitHub</span></a>

View File

@ -19,13 +19,16 @@
</div>
{% for category in index['categories'] %}
<div class="box">
<div class="block"><h2 id="{{ category.lower() }}" class="is-size-3 has-text-weight-semibold">{{ macros.render_element(index['category-names'][category]) }}</h2></div>
<div class="block"><h2 id="{{ category.lower() }}" class="is-size-4 has-text-weight-semibold">{{ macros.render_element(index['category-names'][category]) }}</h2></div>
<div class="columns">
{%- for entries_column in index['entries'][category] -%}
<div class="column">
<ul>
{%- for entry in entries_column -%}
<li>{{ macros.render_element(entry['url']) }}{%- if 'tags' in entry -%}{{ macros.render_element(entry['tags']) }}{%- endif -%}</li>
<li>{%- if 'tags' in entry -%}{{ macros.render_element(entry['url']) }}{{ macros.render_element(entry['tags']) }}
{%- else -%}
<span class="has-text-weight-semibold">{{ macros.render_element(entry['url']) }}</span>
{%- endif -%}</li>
{%- endfor -%}
</ul>
</div>

BIN
code/html/collage_games.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 305 KiB

View File

@ -27,8 +27,14 @@
<glyph unicode="&#xe911;" glyph-name="help1" d="M642 458.667q40 40 40 96 0 70-50 120t-120 50-120-50-50-120h84q0 34 26 60t60 26 60-26 26-60-26-60l-52-54q-50-54-50-120v-22h84q0 66 50 120zM554 128.667v84h-84v-84h84zM512 852.667q176 0 301-125t125-301-125-301-301-125-301 125-125 301 125 301 301 125z" />
<glyph unicode="&#xe912;" glyph-name="help_center" d="M810 810.667h-596q-36 0-61-25t-25-61v-596q0-36 25-61t61-25h596q36 0 61 25t25 61v596q0 36-25 61t-61 25zM512 170.667q-22 0-38 16t-16 38 16 38 38 16q24 0 39-16t15-38-15-38-39-16zM640 486.667q-24-36-45-53t-33-39q-6-10-8-21t-2-41h-78v40t14 46q14 28 40 47t42 45q14 16 12 40t-19 42-51 18-52-21-24-43l-70 30q14 42 51 74t95 32q46 0 79-19t49-45q14-24 18-62t-18-70z" />
<glyph unicode="&#xe913;" glyph-name="device_unknown" d="M474 276.667h76v-76h-76v76zM512 652.667q64 0 107-43t43-105q0-50-56-100t-56-90h-76q0 42 17 71t39 42 39 33 17 44q0 30-22 52t-52 22-52-22-22-52h-76q0 62 43 105t107 43zM726 128.667v596h-428v-596h428zM726 896.667q34 0 59-26t25-60v-768q0-34-25-60t-59-26h-428q-34 0-59 26t-25 60v768q0 34 25 60t59 26h428z" />
<glyph unicode="&#xe914;" glyph-name="brightness_3" d="M384 852.667q176 0 301-125t125-301-125-301-301-125q-68 0-128 18 132 40 215 153t83 255-83 255-215 153q60 18 128 18z" />
<glyph unicode="&#xe915;" glyph-name="dice" d="M864 768h-512c-88 0-160-72-160-160v-512c0-88 72-160 160-160h512c88 0 160 72 160 160v512c0 88-72 160-160 160zM416 64c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM416 448c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM608 256c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM800 64c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM800 448c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM828.76 832c-14.93 72.804-79.71 128-156.76 128h-512c-88 0-160-72-160-160v-512c0-77.046 55.196-141.83 128-156.76v636.76c0 35.2 28.8 64 64 64h636.76z" />
<glyph unicode="&#xe916;" glyph-name="pacman" d="M964.73 781.196c-93.902 109.45-233.21 178.804-388.73 178.804-282.77 0-512-229.23-512-512s229.23-512 512-512c155.52 0 294.828 69.356 388.728 178.804l-324.728 333.196 324.73 333.196zM704 839.398c39.432 0 71.398-31.964 71.398-71.398 0-39.432-31.966-71.398-71.398-71.398s-71.398 31.966-71.398 71.398c0 39.432 31.966 71.398 71.398 71.398z" />
<glyph unicode="&#xe917;" glyph-name="wb_sunny" d="M152 146.667l76 78 60-60-76-78zM470-19.333v126h84v-126h-84zM512 704.667q106 0 181-75t75-181-75-181-181-75-181 75-75 181 75 181 181 75zM854 490.667h128v-86h-128v86zM736 164.667l60 58 76-76-60-60zM872 748.667l-76-76-60 60 76 76zM554 914.667v-126h-84v126h84zM170 490.667v-86h-128v86h128zM288 732.667l-60-60-76 76 60 60z" />
<glyph unicode="&#xe918;" glyph-name="puzzle-piece" horiz-adv-x="951" d="M950.857 323.428c0-58.857-33.714-108-96-108-69.714 0-88 63.429-150.857 63.429-45.714 0-62.857-28.571-62.857-70.857 0-44.571 18.286-87.429 17.714-131.429v-2.857c-6.286 0-12.571 0-18.857-0.571-58.857-5.714-118.286-17.143-177.714-17.143-40.571 0-82.857 16-82.857 62.857 0 62.857 63.429 81.143 63.429 150.857 0 62.286-49.143 96-108 96-60 0-115.429-33.143-115.429-98.857 0-72.571 55.429-104 55.429-143.429 0-20-12.571-37.714-26.286-50.857-17.714-16.571-42.857-20-66.857-20-46.857 0-93.714 6.286-140 13.714-10.286 1.714-21.143 2.857-31.429 4.571l-7.429 1.143c-1.143 0.571-2.857 0.571-2.857 1.143v585.143c2.286-1.714 36-5.714 41.714-6.857 46.286-7.429 93.143-13.714 140-13.714 24 0 49.143 3.429 66.857 20 13.714 13.143 26.286 30.857 26.286 50.857 0 39.429-55.429 70.857-55.429 143.429 0 65.714 55.429 98.857 116 98.857 58.286 0 107.429-33.714 107.429-96 0-69.714-63.429-88-63.429-150.857 0-46.857 42.286-62.857 82.857-62.857 65.714 0 130.857 14.857 196 18.286v-1.143c-1.714-2.286-5.714-36-6.857-41.714-7.429-46.286-13.714-93.143-13.714-140 0-24 3.429-49.143 20-66.857 13.143-13.714 30.857-26.286 50.857-26.286 39.429 0 70.857 55.429 143.429 55.429 65.714 0 98.857-55.429 98.857-115.429z" />
<glyph unicode="&#xe919;" glyph-name="book" horiz-adv-x="953" d="M936.571 677.714c14.286-20.571 18.286-47.429 10.286-73.714l-157.143-517.714c-14.286-48.571-64.571-86.286-113.714-86.286h-527.429c-58.286 0-120.571 46.286-141.714 105.714-9.143 25.714-9.143 50.857-1.143 72.571 1.143 11.429 3.429 22.857 4 36.571 0.571 9.143-4.571 16.571-3.429 23.429 2.286 13.714 14.286 23.429 23.429 38.857 17.143 28.571 36.571 74.857 42.857 104.571 2.857 10.857-2.857 23.429 0 33.143 2.857 10.857 13.714 18.857 19.429 29.143 15.429 26.286 35.429 77.143 38.286 104 1.143 12-4.571 25.143-1.143 34.286 4 13.143 16.571 18.857 25.143 30.286 13.714 18.857 36.571 73.143 40 103.429 1.143 9.714-4.571 19.429-2.857 29.714 2.286 10.857 16 22.286 25.143 35.429 24 35.429 28.571 113.714 101.143 93.143l-0.571-1.714c9.714 2.286 19.429 5.143 29.143 5.143h434.857c26.857 0 50.857-12 65.143-32 14.857-20.571 18.286-47.429 10.286-74.286l-156.571-517.714c-26.857-88-41.714-107.429-114.286-107.429h-496.571c-7.429 0-16.571-1.714-21.714-8.571-4.571-6.857-5.143-12-0.571-24.571 11.429-33.143 50.857-40 82.286-40h527.429c21.143 0 45.714 12 52 32.571l171.429 564c3.429 10.857 3.429 22.286 2.857 32.571 13.143-5.143 25.143-13.143 33.714-24.571zM328.571 676.571c-3.429-10.286 2.286-18.286 12.571-18.286h347.429c9.714 0 20.571 8 24 18.286l12 36.571c3.429 10.286-2.286 18.286-12.571 18.286h-347.429c-9.714 0-20.571-8-24-18.286zM281.143 530.286c-3.429-10.286 2.286-18.286 12.571-18.286h347.429c9.714 0 20.571 8 24 18.286l12 36.571c3.429 10.286-2.286 18.286-12.571 18.286h-347.429c-9.714 0-20.571-8-24-18.286z" />
<glyph unicode="&#xe91a;" glyph-name="music" d="M960 960h64v-736c0-88.366-100.29-160-224-160s-224 71.634-224 160c0 88.368 100.29 160 224 160 62.684 0 119.342-18.4 160-48.040v368.040l-512-113.778v-494.222c0-88.366-100.288-160-224-160s-224 71.634-224 160c0 88.368 100.288 160 224 160 62.684 0 119.342-18.4 160-48.040v624.040l576 128z" />
<glyph unicode="&#xe91b;" glyph-name="spades" d="M817.57 611.85c-193.566 143.858-260.266 259.018-305.566 348.148v0c-0.004 0-0.004 0.002-0.004 0.002v-0.002c-45.296-89.13-112-204.292-305.566-348.148-330.036-245.286-19.376-587.668 253.758-399.224-17.796-116.93-78.53-202.172-140.208-238.882v-37.744h384.032v37.74c-61.682 36.708-122.41 121.954-140.212 238.884 273.136-188.446 583.8 153.94 253.766 399.226z" />
<glyph unicode="&#xe921;" glyph-name="library" horiz-adv-x="1088" d="M1024 0v64h-64v384h64v64h-192v-64h64v-384h-192v384h64v64h-192v-64h64v-384h-192v384h64v64h-192v-64h64v-384h-192v384h64v64h-192v-64h64v-384h-64v-64h-64v-64h1088v64h-64zM512 960h64l512-320v-64h-1088v64l512 320z" />
<glyph unicode="&#xe935;" glyph-name="price-tag" d="M976 960h-384c-26.4 0-63.274-15.274-81.942-33.942l-476.116-476.116c-18.668-18.668-18.668-49.214 0-67.882l412.118-412.118c18.668-18.668 49.214-18.668 67.882 0l476.118 476.118c18.666 18.666 33.94 55.54 33.94 81.94v384c0 26.4-21.6 48-48 48zM736 576c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96z" />
<glyph unicode="&#xe936;" glyph-name="price-tags" horiz-adv-x="1280" d="M1232 960h-384c-26.4 0-63.274-15.274-81.942-33.942l-476.116-476.116c-18.668-18.668-18.668-49.214 0-67.882l412.118-412.118c18.668-18.668 49.214-18.668 67.882 0l476.118 476.118c18.666 18.666 33.94 55.54 33.94 81.94v384c0 26.4-21.6 48-48 48zM992 576c-53.020 0-96 42.98-96 96s42.98 96 96 96 96-42.98 96-96-42.98-96-96-96zM128 416l544 544h-80c-26.4 0-63.274-15.274-81.942-33.942l-476.116-476.116c-18.668-18.668-18.668-49.214 0-67.882l412.118-412.118c18.668-18.668 49.214-18.668 67.882 0l30.058 30.058-416 416z" />
@ -39,6 +45,7 @@
<glyph unicode="&#xe9ae;" glyph-name="briefcase" d="M960 704h-256v64c0 35.2-28.8 64-64 64h-256c-35.204 0-64-28.8-64-64v-64h-256c-35.2 0-64-28.8-64-64v-576c0-35.202 28.796-64 64-64h896c35.2 0 64 28.798 64 64v576c0 35.2-28.8 64-64 64zM384 767.884c0.034 0.040 0.074 0.082 0.114 0.116h255.772c0.042-0.034 0.082-0.076 0.118-0.116v-63.884h-256.004v63.884zM960 448h-128v-96c0-17.602-14.4-32-32-32h-64c-17.604 0-32 14.398-32 32v96h-384v-96c0-17.602-14.4-32-32-32h-64c-17.602 0-32 14.398-32 32v96h-128v64h896v-64z" />
<glyph unicode="&#xe9b3;" glyph-name="target" d="M1024 512h-100.924c-27.64 178.24-168.836 319.436-347.076 347.076v100.924h-128v-100.924c-178.24-27.64-319.436-168.836-347.076-347.076h-100.924v-128h100.924c27.64-178.24 168.836-319.436 347.076-347.076v-100.924h128v100.924c178.24 27.64 319.436 168.836 347.076 347.076h100.924v128zM792.822 512h-99.762c-19.284 54.55-62.51 97.778-117.060 117.060v99.762c107.514-24.49 192.332-109.31 216.822-216.822zM512 384c-35.346 0-64 28.654-64 64s28.654 64 64 64c35.346 0 64-28.654 64-64s-28.654-64-64-64zM448 728.822v-99.762c-54.55-19.282-97.778-62.51-117.060-117.060h-99.762c24.49 107.512 109.31 192.332 216.822 216.822zM231.178 384h99.762c19.282-54.55 62.51-97.778 117.060-117.060v-99.762c-107.512 24.49-192.332 109.308-216.822 216.822zM576 167.178v99.762c54.55 19.284 97.778 62.51 117.060 117.060h99.762c-24.49-107.514-109.308-192.332-216.822-216.822z" />
<glyph unicode="&#xe9ca;" glyph-name="earth" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512-0.002c-62.958 0-122.872 13.012-177.23 36.452l233.148 262.29c5.206 5.858 8.082 13.422 8.082 21.26v96c0 17.674-14.326 32-32 32-112.99 0-232.204 117.462-233.374 118.626-6 6.002-14.14 9.374-22.626 9.374h-128c-17.672 0-32-14.328-32-32v-192c0-12.122 6.848-23.202 17.69-28.622l110.31-55.156v-187.886c-116.052 80.956-192 215.432-192 367.664 0 68.714 15.49 133.806 43.138 192h116.862c8.488 0 16.626 3.372 22.628 9.372l128 128c6 6.002 9.372 14.14 9.372 22.628v77.412c40.562 12.074 83.518 18.588 128 18.588 70.406 0 137.004-16.26 196.282-45.2-4.144-3.502-8.176-7.164-12.046-11.036-36.266-36.264-56.236-84.478-56.236-135.764s19.97-99.5 56.236-135.764c36.434-36.432 85.218-56.264 135.634-56.26 3.166 0 6.342 0.080 9.518 0.236 13.814-51.802 38.752-186.656-8.404-372.334-0.444-1.744-0.696-3.488-0.842-5.224-81.324-83.080-194.7-134.656-320.142-134.656z" />
<glyph unicode="&#xe9d4;" glyph-name="sun" d="M512 128c35.346 0 64-28.654 64-64v-64c0-35.346-28.654-64-64-64s-64 28.654-64 64v64c0 35.346 28.654 64 64 64zM512 768c-35.346 0-64 28.654-64 64v64c0 35.346 28.654 64 64 64s64-28.654 64-64v-64c0-35.346-28.654-64-64-64zM960 512c35.346 0 64-28.654 64-64s-28.654-64-64-64h-64c-35.348 0-64 28.654-64 64s28.652 64 64 64h64zM192 448c0-35.346-28.654-64-64-64h-64c-35.346 0-64 28.654-64 64s28.654 64 64 64h64c35.346 0 64-28.654 64-64zM828.784 221.726l45.256-45.258c24.992-24.99 24.992-65.516 0-90.508-24.994-24.992-65.518-24.992-90.51 0l-45.256 45.256c-24.992 24.99-24.992 65.516 0 90.51 24.994 24.992 65.518 24.992 90.51 0zM195.216 674.274l-45.256 45.256c-24.994 24.994-24.994 65.516 0 90.51s65.516 24.994 90.51 0l45.256-45.256c24.994-24.994 24.994-65.516 0-90.51s-65.516-24.994-90.51 0zM828.784 674.274c-24.992-24.992-65.516-24.992-90.51 0-24.992 24.994-24.992 65.516 0 90.51l45.256 45.254c24.992 24.994 65.516 24.994 90.51 0 24.992-24.994 24.992-65.516 0-90.51l-45.256-45.254zM195.216 221.726c24.992 24.992 65.518 24.992 90.508 0 24.994-24.994 24.994-65.52 0-90.51l-45.254-45.256c-24.994-24.992-65.516-24.992-90.51 0s-24.994 65.518 0 90.508l45.256 45.258zM512 704c-141.384 0-256-114.616-256-256 0-141.382 114.616-256 256-256 141.382 0 256 114.618 256 256 0 141.384-114.616 256-256 256zM512 288c-88.366 0-160 71.634-160 160s71.634 160 160 160 160-71.634 160-160-71.634-160-160-160z" />
<glyph unicode="&#xea5b;" glyph-name="filter" d="M512 960c-282.77 0-512-71.634-512-160v-96l384-384v-320c0-35.346 57.306-64 128-64 70.692 0 128 28.654 128 64v320l384 384v96c0 88.366-229.23 160-512 160zM94.384 821.176c23.944 13.658 57.582 26.62 97.278 37.488 87.944 24.076 201.708 37.336 320.338 37.336 118.628 0 232.394-13.26 320.338-37.336 39.696-10.868 73.334-23.83 97.28-37.488 15.792-9.006 24.324-16.624 28.296-21.176-3.972-4.552-12.506-12.168-28.296-21.176-23.946-13.658-57.584-26.62-97.28-37.488-87.942-24.076-201.708-37.336-320.338-37.336s-232.394 13.26-320.338 37.336c-39.696 10.868-73.334 23.83-97.278 37.488-15.792 9.008-24.324 16.624-28.298 21.176 3.974 4.552 12.506 12.168 28.298 21.176z" />
<glyph unicode="&#xea7e;" glyph-name="new-tab" d="M192 896v-768h768v768h-768zM896 192h-640v640h640v-640zM128 64v672l-64 64v-800h800l-64 64h-672zM352 704l160-160-192-192 96-96 192 192 160-160v416z" />
<glyph unicode="&#xeab0;" glyph-name="github" d="M512.008 947.358c-282.738 0-512.008-229.218-512.008-511.998 0-226.214 146.704-418.132 350.136-485.836 25.586-4.738 34.992 11.11 34.992 24.632 0 12.204-0.48 52.542-0.696 95.324-142.448-30.976-172.504 60.41-172.504 60.41-23.282 59.176-56.848 74.916-56.848 74.916-46.452 31.778 3.51 31.124 3.51 31.124 51.4-3.61 78.476-52.766 78.476-52.766 45.672-78.27 119.776-55.64 149.004-42.558 4.588 33.086 17.852 55.68 32.506 68.464-113.73 12.942-233.276 56.85-233.276 253.032 0 55.898 20.004 101.574 52.76 137.428-5.316 12.9-22.854 64.972 4.952 135.5 0 0 43.006 13.752 140.84-52.49 40.836 11.348 84.636 17.036 128.154 17.234 43.502-0.198 87.336-5.886 128.256-17.234 97.734 66.244 140.656 52.49 140.656 52.49 27.872-70.528 10.35-122.6 5.036-135.5 32.82-35.856 52.694-81.532 52.694-137.428 0-196.654-119.778-239.95-233.79-252.624 18.364-15.89 34.724-47.046 34.724-94.812 0-68.508-0.596-123.644-0.596-140.508 0-13.628 9.222-29.594 35.172-24.566 203.322 67.776 349.842 259.626 349.842 485.768 0 282.78-229.234 511.998-511.992 511.998z" />

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Binary file not shown.

View File

@ -1,9 +1,9 @@
@font-face {
font-family: 'osgl';
src:
url('fonts/osgl.ttf?twf6ln') format('truetype'),
url('fonts/osgl.woff?twf6ln') format('woff'),
url('fonts/osgl.svg?twf6ln#osgl') format('svg');
url('fonts/osgl.ttf?mzgdt7') format('truetype'),
url('fonts/osgl.woff?mzgdt7') format('woff'),
url('fonts/osgl.svg?mzgdt7#osgl') format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
@ -27,6 +27,12 @@ i {
.icon-help:before {
content: "\e908";
}
.icon-puzzle-piece:before {
content: "\e918";
}
.icon-book:before {
content: "\e919";
}
.icon-question:before {
content: "\e90f";
}
@ -45,6 +51,12 @@ i {
.icon-idea:before {
content: "\e90e";
}
.icon-brightness_3:before {
content: "\e914";
}
.icon-wb_sunny:before {
content: "\e917";
}
.icon-device_unknown:before {
content: "\e913";
}
@ -90,12 +102,18 @@ i {
.icon-pencil:before {
content: "\e907";
}
.icon-music:before {
content: "\e91a";
}
.icon-dice:before {
content: "\e915";
}
.icon-pacman:before {
content: "\e916";
}
.icon-spades:before {
content: "\e91b";
}
.icon-library:before {
content: "\e921";
}
@ -126,6 +144,9 @@ i {
.icon-earth:before {
content: "\e9ca";
}
.icon-sun:before {
content: "\e9d4";
}
.icon-filter:before {
content: "\ea5b";
}

View File

@ -6,6 +6,7 @@
<div class="container">
<h1 class="title">Open source games list (OSGL)</h1>
<p class="subtitle">{{ macros.render_text(index['subtitle']) }}</p>
<img src="collage_games.jpg" alt="" width="1200" height="600">
</div>
</div>
</section>

View File

@ -3,6 +3,9 @@
<section class="section">
<div class="container">
<h1 class="title">{{ listing['title'] }}</h1>
{%- if 'subtitle' in listing -%}
<h2 class="subtitle">{{ macros.render_element(listing['subtitle']) }}</h2>
{%- endif -%}
{# iterate over items -#}
{% for item in listing['items'] %}
<div class="box">

View File

@ -7,14 +7,10 @@ import os
import requests
from PIL import Image
from io import BytesIO
import numpy as np
if __name__ == "__main__":
# paths
root_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.pardir))
download_path = os.path.join(root_path, 'code', 'html', 'images-download')
output_file = os.path.join(root_path, 'code', 'html', 'collage_games.jpg')
def download_images():
# import the osgameclones data
path = os.path.realpath(os.path.join(root_path, os.path.pardir, 'osgameclones.git', 'games'))
files = os.listdir(path)
@ -45,8 +41,152 @@ if __name__ == "__main__":
# download them all
for url in images:
r = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'},
timeout=20, allow_redirects=True)
name = "".join(x for x in url[5:] if (x.isalnum() or x in '._-'))
outfile = os.path.join(download_path, name)
if not os.path.isfile(outfile):
try:
r = requests.get(url, headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'},
timeout=20, allow_redirects=True)
if r.status_code == requests.codes.ok:
im = Image.open(BytesIO(r.content))
im.save(outfile)
print('saved {}'.format(url))
except:
pass
if r.status_code == requests.codes.ok:
im = Image.open(BytesIO(r.content))
def downsize_images():
scale_factor = 10
for file in os.listdir(download_path):
file_path = os.path.join(download_path, file)
if not os.path.isfile(file_path):
continue
outfile = os.path.join(downsized_path, file[:-4]+'.png') # losless storage of downsize image
if os.path.isfile(outfile):
continue
im = Image.open(file_path)
if im.mode != 'RGB':
print('{} - {}'.format(file, im.mode))
continue
width = im.width
height = im.height
if width < target_width * scale_factor or height < target_height * scale_factor:
continue
box = [(width-target_width*scale_factor)/2, (height-target_height*scale_factor)/2, target_width * scale_factor, target_height * scale_factor]
box[2] += box[0]
box[3] += box[1]
im_resized = im.resize((target_width, target_height), resample=Image.LANCZOS, box=box)
im_resized.save(outfile)
print('saved {}'.format(file))
def assemble_collage():
# load all from downsized path
files = os.listdir(downsized_path)
files = [file for file in files if os.path.isfile(os.path.join(downsized_path, file))]
images = []
for file in files:
im = Image.open(os.path.join(downsized_path, file))
im = np.asarray(im)
images.append(im)
# compute total amount of light in each image and only keep the N brightest
images = [(np.sum(image), image) for image in images]
images.sort(key=lambda x: x[0], reverse=True)
images = images[:N]
images = [x[1] for x in images]
# compute the average color in each quadrant
Cx = int(target_height / 2)
Cy = int(target_width / 2)
U = [np.mean(image[:Cx, :, :], axis=(1, 2)) for image in images]
D = [np.mean(image[Cx:, :, :], axis=(1, 2)) for image in images]
R = [np.mean(image[:, :Cy, :], axis=(1, 2)) for image in images]
L = [np.mean(image[:, Cy:, :], axis=(1, 2)) for image in images]
# initially just sort them in randomly
map = np.random.permutation(N).reshape((Nx, Ny))
# optimize neighbors with a stochastic metropolis algorithm
Ni = 500000
T = np.linspace(150, 2, Ni)
A = np.zeros((Ni, 1))
u = lambda x: (x + 1) % Nx
d = lambda x: (x - 1) % Nx
r = lambda x: (x + 1) % Ny
l = lambda x: (x - 1) % Ny
score = lambda i1, j1, i2, j2: np.linalg.norm(U[map[i1, j1]] - D[map[u(i2), j2]]) + np.linalg.norm(D[map[i1, j1]] - U[map[d(i2), j2]]) + np.linalg.norm(L[map[i1, j1]] - R[map[i2, l(j2)]]) + np.linalg.norm(R[map[i1, j1]] - L[map[i2, r(j2)]])
for ai in range(Ni):
# get two non-equal random locations
i1 = np.random.randint(Nx)
j1 = np.random.randint(Ny)
while True:
i2 = np.random.randint(Nx)
j2 = np.random.randint(Ny)
if i1 != i2 or j1 != j2:
break
# compute score
x = score(i1, j1, i1, j1) - score(i1, j1, i2, j2) + score(i2, j2, i2, j2) - score(i2, j2, i1, j1)
# exchange
# if x < 0:
# if x > 0:
if x > 0 or np.exp(x / T[ai]) > np.random.uniform():
map[i1, j1], map[i2, j2] = map[i2, j2], map[i1, j1]
A[ai] = 1
# time evolution of acceptance rate
Nc = int(np.floor(Ni / 20))
for ai in range(20):
print('{}: {}'.format(ai, np.mean(A[ai*Nc:(ai+1)*Nc])))
# shift brightest to center
B = np.zeros((Nx, Ny))
for i in range(Nx):
for j in range(Ny):
B[i, j] = np.sum(images[map[i, j]])
sk = np.array([0.25, 0.5, 1, 0.5, 0.25])
# convolve in 1D along all rows and all columns
for i in range(Nx):
B[i, :] = np.convolve(B[i, :], sk, mode='same')
for j in range(Ny):
B[:, j] = np.convolve(B[:, j], sk, mode='same')
cx, cy = np.unravel_index(np.argmax(B), B.shape)
map = np.roll(map, (int(Nx/2-cx), int(Ny/2-cy)), axis=(0, 1))
# assemble image
final = np.zeros((Nx * target_height, Ny * target_width, 3), dtype=np.uint8)
for i in range(Nx):
for j in range(Ny):
final[i*target_height:(i+1)*target_height, j*target_width:(j+1)*target_width] = images[map[i, j]]
# convert back to pillow image and save
im = Image.fromarray(final)
im.save(output_file)
if __name__ == "__main__":
target_height = 60
target_width = 80
Nx = 12 # vertical
Ny = 20 # horizontal
N = Nx * Ny
# paths
root_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.pardir))
download_path = os.path.join(root_path, 'code', 'html', 'images-download')
downsized_path = os.path.join(download_path, 'downsized')
output_file = os.path.join(root_path, 'code', 'html', 'collage_games.jpg')
if not os.path.exists(download_path):
os.mkdir(download_path)
if not os.path.exists(downsized_path):
os.mkdir(downsized_path)
# download files
# download_images()
# downsize downloaded images
# downsize_images()
# assemble collage
assemble_collage()

View File

@ -6,4 +6,5 @@ wikipedia
Jinja2
html5lib
ruamel.yaml
requests
requests
numpy