Skip to content

Commit

Permalink
updating site generator
Browse files Browse the repository at this point in the history
  • Loading branch information
mariotaku committed Jan 9, 2022
1 parent bfec348 commit 14b7c51
Show file tree
Hide file tree
Showing 13 changed files with 206 additions and 58 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/repo-sitegen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
run: python3 -m pip install -r ./requirements.txt

- name: Generate repository data
run: python3 -m repogen -i ./packages -o ./content
run: python3 -m repogen -i ./packages -o ./content -d false

- name: Generate site content
run: pelican content
Expand Down
32 changes: 16 additions & 16 deletions packages/com.crunchyroll.webos.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
title: Crunchyroll
iconUri: https://raw.githubusercontent.com/mateussouzaweb/crunchyroll-webos/master/src/img/130px.png
manifestUrl: https://github.com/mateussouzaweb/crunchyroll-webos/releases/latest/download/webosbrew.manifest.json
category: multimedia
description: |
Unofficial WebOS TV App for Crunchyroll.
The last Crunchyroll app you will ever need!
## Support
Support [author](https://github.com/mateussouzaweb) for future versions for Samsung, Android TV, ChromeCast and Others.
## Known Bugs
- Select dropdown does not trigger with LG TV Controller in arrow navigation mode.
title: Crunchyroll
iconUri: https://raw.githubusercontent.com/mateussouzaweb/crunchyroll-webos/master/src/img/130px.png
manifestUrl: https://github.com/mateussouzaweb/crunchyroll-webos/releases/latest/download/webosbrew.manifest.json
category: multimedia
description: |
Unofficial WebOS TV App for Crunchyroll.
The last Crunchyroll app you will ever need!
## Support
Support [author](https://github.com/mateussouzaweb) for future versions for Samsung, Android TV, ChromeCast and Others.
## Known Bugs
- Select dropdown does not trigger with LG TV Controller in arrow navigation mode.
20 changes: 12 additions & 8 deletions pelicanconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,26 @@
import datetime
from os.path import join, dirname, abspath

import repogen
from pelican.plugins import webassets

AUTHOR = 'webOS Homebrew Project'
SITENAME = 'webOS Homebrew Project'
SITEURL = ''

THEME = './theme'
THEME_STATIC_PATHS = [join(dirname(abspath(__file__)), 'website/theme/static')]
THEME_TEMPLATES_OVERRIDES = ['./website/theme/templates']

PLUGINS = [webassets, repogen]

WEBASSETS_SOURCE_PATHS = ['static']

PATH = 'content'

STATIC_PATHS = ['api', 'extra/CNAME', 'styles']
ARTICLE_EXCLUDES = ['api']
PAGE_PATHS = ['pages', 'apps']
PAGE_PATHS = ['pages', 'apps', '../packages']

EXTRA_PATH_METADATA = {
'extra/CNAME': {'path': 'CNAME'},
Expand Down Expand Up @@ -45,23 +51,21 @@
TRANSLATION_FEED_ATOM = None
AUTHOR_FEED_ATOM = None
AUTHOR_FEED_RSS = None
CACHE_CONTENT = False
LOAD_CONTENT_CACHE = False

MENUITEMS = (
('Applications', '/apps'),
('Submit', '/submit'),
)

# Blogroll
LINKS = (
('webOS Homebrew', 'https://github.com/webosbrew/'),
('Github Organization', 'https://github.com/webosbrew/'),
('Join us on Discord', 'https://discord.gg/xWqRVEm'),
('RootMy.TV', 'https://rootmy.tv/'),
('openlgtv', 'https://openlgtv.github.io/'),
)

# Social widget
SOCIAL = (
('openlgtv Discord', 'https://discord.gg/xWqRVEm'),
)

DEFAULT_PAGINATION = 30

# Uncomment following line if you want document-relative URLs when developing
Expand Down
5 changes: 5 additions & 0 deletions repogen/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
__title__ = 'repogen'
__version__ = '1.0.0'

from .plugin import *
14 changes: 12 additions & 2 deletions repogen/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,18 @@
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input-dir', required=True)
parser.add_argument('-o', '--output-dir', required=True)

parser.add_argument('-A', '--no-gen-api', dest='gen_api', action='store_false')
parser.add_argument('-D', '--no-gen-details', dest='gen_details', action='store_false')
parser.add_argument('-L', '--no-gen-list', dest='gen_list', action='store_false')

parser.set_defaults(gen_api=True, gen_details=True, gen_list=True)

args = parser.parse_args()

packages = list_packages(args.input_dir)
apidata.generate(packages, path.join(args.output_dir, 'api'))
apppage.generate(packages, path.join(args.output_dir, 'apps'))

if args.gen_api:
apidata.generate(packages, path.join(args.output_dir, 'api'))

apppage.generate(packages, path.join(args.output_dir, 'apps'), gen_details=args.gen_details, gen_list=args.gen_list)
13 changes: 9 additions & 4 deletions repogen/apppage.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def _gen_page(self, outdir, items, pagination):

def _nav_path(p: int):
return 'apps' if p == 1 else 'apps/page/%d' % p

prev_href = _nav_path(prevp) if prevp else None
next_href = _nav_path(nextp) if nextp else None

Expand All @@ -45,17 +46,19 @@ def _nav_path(p: int):

def _nav_item(p: int):
return {'page': p, 'path': _nav_path(p), 'current': p == page}

page_links = list(map(_nav_item, range(
nav_center_start, nav_center_end + 1)))
if page > 4:
page_links = page_links[1:]
page_links = [_nav_item(1), None] + page_links
page_links = [_nav_item(1), None] + page_links
if page < maxp - 3:
page_links = page_links[:-1]
page_links = page_links + [None, _nav_item(maxp)]

def _page_path(p: int):
return 'apps/index.html' if p == 1 else 'apps/page/%d.html' % p

with open(join(outdir, ('apps-page-%d.html' % page)), 'w', encoding='utf-8') as f:
f.write(pystache.render(self.index_template, {
'packages': items, 'pagePath': _page_path(page),
Expand All @@ -81,14 +84,16 @@ def gen_list(self, outdir):
self._gen_page(outdir, items, pagination)


def generate(packages, outdir):
def generate(packages, outdir, gen_details=True, gen_list=True):
generator = AppListingGenerator(packages)

if not exists(outdir):
makedirs(outdir)

generator.gen_details(outdir)
generator.gen_list(outdir)
if gen_details:
generator.gen_details(outdir)
if gen_list:
generator.gen_list(outdir)

print('Generated application page for %d packages.' %
len(generator.packages))
Expand Down
35 changes: 26 additions & 9 deletions repogen/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import urllib
from datetime import datetime
from email.utils import parsedate_to_datetime
from json import JSONDecodeError
from os import listdir, mkdir, path
from os.path import basename, isfile, join
from urllib.parse import urljoin
Expand All @@ -27,15 +28,25 @@ def url_fixup(u):
return u


def obtain_manifest(pkgid, type, url: str):
def url_size(u):
content_length = requests.head(u, allow_redirects=True).headers.get('content-length', None)
if not content_length:
return 0
return int(content_length)


def obtain_manifest(pkgid, type, url: str, offline=False):
if not path.exists('cache'):
mkdir('cache')
cache_file = path.join('cache', f'manifest_{pkgid}_{type}.json')
try:
if offline:
raise requests.exceptions.ConnectionError('Offline')
url = url_fixup(url)
resp = requests.get(url=url, allow_redirects=True)
manifest = resp.json()
manifest['ipkUrl'] = urljoin(url, manifest['ipkUrl'])
manifest['ipkSize'] = url_size(manifest['ipkUrl'])
with open(cache_file, 'w', encoding='utf-8') as f:
json.dump(manifest, f)
last_modified = datetime.now()
Expand All @@ -44,14 +55,19 @@ def obtain_manifest(pkgid, type, url: str):
resp.headers['last-modified'])
os.utime(cache_file, (last_modified.timestamp(), last_modified.timestamp()))
return manifest, last_modified
except requests.exceptions.RequestException:
except requests.exceptions.RequestException as e:
if path.exists(cache_file):
with open(cache_file, encoding='utf-8') as f:
return json.load(f), datetime.fromtimestamp(os.stat(cache_file).st_mtime)
try:
with open(cache_file, encoding='utf-8') as f:
return json.load(f), datetime.fromtimestamp(os.stat(cache_file).st_mtime)
except IOError or JSONDecodeError:
os.unlink(cache_file)
else:
raise e
return None


def parse_package_info(path: str):
def parse_package_info(path: str, offline=False):
extension = os.path.splitext(path)[1]
if extension == '.yml':
content = parse_yml_package(path)
Expand All @@ -71,7 +87,7 @@ def parse_package_info(path: str):
'category': content['category'],
'description': bleach.clean(content.get('description', '')),
}
manifest, lastmodified_r = obtain_manifest(pkgid, 'release', manifest_url)
manifest, lastmodified_r = obtain_manifest(pkgid, 'release', manifest_url, offline)
if manifest:
pkginfo['manifest'] = manifest
lastmodified_b = None
Expand All @@ -80,7 +96,8 @@ def parse_package_info(path: str):
if manifest_b:
pkginfo['manifestBeta'] = manifest_b
lastmodified = lastmodified_r, lastmodified_b
pkginfo['lastmodified'] = max(d for d in lastmodified if d is not None).strftime('%Y/%m/%d %H:%M:%S %Z')
pkginfo['lastmodified'] = max(d for d in lastmodified if d is not None)
pkginfo['lastmodified_str'] = pkginfo['lastmodified'].strftime('%Y/%m/%d %H:%M:%S %Z')
return pkginfo


Expand All @@ -99,7 +116,7 @@ def load_py_package(path):
return module.load()


def list_packages(pkgdir):
def list_packages(pkgdir, offline=False):
paths = [join(pkgdir, f)
for f in listdir(pkgdir) if isfile(join(pkgdir, f))]
return sorted(filter(lambda x: x, map(parse_package_info, paths)), key=lambda x: x['title'])
return sorted(filter(lambda x: x, map(lambda p: parse_package_info(p, offline), paths)), key=lambda x: x['title'])
42 changes: 42 additions & 0 deletions repogen/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import logging
import os

from markdown import Markdown
from pelican import signals, Readers
from pelican.readers import BaseReader

from repogen.common import parse_package_info

log = logging.getLogger(__name__)


class PackageInfoReader(BaseReader):
enabled = True

file_extensions = ['yml', 'py']

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._md = Markdown(**self.settings['MARKDOWN'])

def read(self, filename):
info = parse_package_info(filename, offline='CI' not in os.environ)
metadata = {
'title': info['title'],
'override_save_as': f'apps/{info["id"]}.html',
'template': 'app',
'status': 'hidden',
'modified': info['lastmodified'],
'manifest': info['manifest'],
}
return self._md.convert(info['description']), metadata


def readers_init(readers: Readers):
readers.reader_classes['yml'] = PackageInfoReader
readers.reader_classes['py'] = PackageInfoReader


def register():
signals.readers_init.connect(readers_init)
pass
2 changes: 1 addition & 1 deletion repogen/templates/apps/detail.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Version: {{manifest.version}}

{{#manifest.sourceUrl}}Source: [{{manifest.sourceUrl}}]({{manifest.sourceUrl}}){{/manifest.sourceUrl}}

{{#lastmodified}}Last Updated: {{lastmodified}}{{/lastmodified}}
{{#lastmodified_str}}Last Updated: {{lastmodified_str}}{{/lastmodified_str}}

---

Expand Down
63 changes: 59 additions & 4 deletions theme/static/styles/app.scss
Original file line number Diff line number Diff line change
@@ -1,11 +1,66 @@
@import "../../../website/theme/static/styles/variables";

$icon-size: 160px;

#content .main {
img {
max-width: 100%;
}

img.app-icon {
max-width: 80px;
margin-top: -20px;
float: right;
.app-icon {
width: $icon-size;
height: $icon-size;
float: left;
}

.app-info {
display: flex;
flex-flow: column;
min-height: $icon-size;

.app-title {
margin-top: 10px;
}

.app-actions {
margin: auto 10px 10px auto;
padding-top: 10px;

.app-action {
height: 48px;
padding: 5px 10px;
box-sizing: border-box;

overflow: hidden;

background-color: $color-accent;
border-radius: 5px;
color: white;
}

.download-ipk {
.title {
font-size: 15px;
}

.version {
display: inline-block;
font-size: 12px;
float: left;
}

.size {
display: inline-block;
font-size: 12px;
float: right;
}

hr {
margin: 2px 0;
border-color: rgba(255, 255, 255, 0.5);
border-width: 1px;
}
}
}
}
}
Loading

0 comments on commit 14b7c51

Please sign in to comment.