Commit ed5a1ccf authored by Louis's avatar Louis
Browse files

Working version, but a lot of remaining TODOs

parent 21a2ae22
default:
gitlab:
gitlabci:
server: http://framagit.org
user: spalax
columns:
- color
- homepage
- pypiversion
- mdownload
- wdownload
- ddownload
- docs
- ci
- coverage
- depends
- pypimdownloads
- pypiwdownloads
- pypiddownloads
- readthedocs
- gitlabci
packages:
argdispatch:
cahier:
......@@ -26,26 +25,20 @@ packages:
papersize:
patacrep:
docs:
type: readthedocs
ci:
type: travis
slug: patacrep/patacrep
column: readthedocs
gitlabci:
column: travisci
user: patacrep
pdfautonup:
docs:
type: readthedocs
ci:
type: gitlab
coverage:
TODO
depends:
TODO
column: readthedocs
pdfimpose:
pypimonitor:
scal:
squelette:
sphinxcontrib-packages:
docs:
type: readthedocs
column: readthedocs
slug: packages
sphinxcontrib-proof:
srsync:
default:
gitlabci:
server: http://framagit.org
columns:
- color
- homepage
- pypiversion
- pypimdownloads
- pypiwdownloads
- pypiddownloads
- readthedocs
- gitlabci
- html
packages:
argdispatch:
html:
html: "Tagada tsoin tsoin"
papersize:
html:
column: "empty"
pdfautonup:
html:
column: "link"
pdfimpose:
html:
column: "link"
href: "http://example.com"
content: "Example"
......@@ -18,6 +18,8 @@ import urllib
import xmlrpc.client as xmlrpclib
import yaml
from pypimonitor.column import load_column_plugins
VERSION = "0.2.0-dev"
_client = xmlrpclib.ServerProxy('https://pypi.python.org/pypi')
......@@ -58,9 +60,16 @@ class Renderer:
if "columns" not in self.config:
self.config['columns'] = list(set(itertools.chain(*[
package.keys()
for package
for package
in self.config['packages'].values()
])))
for package in self.config['packages']:
if self.config['packages'][package] is None:
self.config['packages'][package] = {}
for column in self.config['columns']:
if self.config['packages'][package].get(column, None) is None:
self.config['packages'][package][column] = {}
self.config['packages'][package][column]['column'] = self.config['packages'][package][column].get('column', column)
# Processing packages
self.packages = {}
......@@ -71,6 +80,13 @@ class Renderer:
sys.stderr.write("Ignoring package '{}': {}.\n".format(name, error))
continue
# Loading plugins
self.columns = {
plugin.keyword: plugin(self)
for plugin
in load_column_plugins()
}
@classmethod
def from_yaml(cls, filename):
with open(filename, 'r') as stream:
......@@ -125,17 +141,10 @@ class Renderer:
def render(self):
env = self._get_environment()
# Check columns
columns = []
for column in self.config['columns']:
env.get_template("columns/{}.html".format(column))
columns.append(column)
# Render
template = env.get_template("index.html")
return template.render(
columns=columns,
config=self.config,
columns=self.columns,
packages=self.packages,
)
......
# TODO Copyright
import contextlib
import logging
import os
from straight import plugin
import jinja2
import pypimonitor
LOGGER = logging.getLogger(pypimonitor.__name__)
def load_column_plugins():
for column in set(plugin.load('pypimonitor.column', subclasses=Column)):
if column.keyword is not None:
yield column
@contextlib.contextmanager
def temp_update(source, update):
bak = {}
new = set()
for key in update:
if key not in source:
new.add(key)
source[key] = update[key]
for key in source:
if key in update:
bak[key] = source[key]
source[key] = update[key]
yield source
for key in bak:
source[key] = bak[key]
for key in new:
del source[key]
class Column:
keyword = None
title = ""
default = {}
def __init__(self, config):
self.config = config
def __init__(self, renderer):
self.renderer = renderer
self.config = renderer.config
@jinja2.contextfilter
def __call__(self, context, package, options):
filled = default.copy()
if ('default' in config) and (self.keyword in config['default']):
@jinja2.contextfunction
def __call__(self, context, column, package):
filled = self.default.copy()
if ('default' in self.config) and (self.keyword in self.config['default']):
filled.update(self.config['default'][self.keyword])
filled.update(options)
self.render(context, package, options)
filled.update(self.config['packages'][package].get(column, {}))
return self.render(context, package, filled)
def render(self, context, package, options):
def render(self, context, package, column):
raise NotImplementedError()
def render_error(self, column, package, message):
LOGGER.error("Package {}, column {}: {}".format(package, column, message))
return message
class Empty(Column):
keyword = "empty"
def render(self, context, package, options):
return ""
class Html(Column):
keyword = 'html'
default = {'html': ''}
def render(self, context, package, options):
return options['html']
return """<span class="error">&#9888;<div class="tooltip">{}</div></div>""".format(message)
class Jinja2(Column):
def render(self, context, package, options):
TODO("""Make available:
- package: the package name (as the key of the yaml dict)
- pypi: the package information (as get from pypi)
- column: the column options
- config: the whole yaml file
""")
return context.environment.get_template(os.path.join("columns", self.keyword)).render(context)
class Link(Jinja2):
keyword = 'link'
def render(self, context, package, options):
if 'href' not in options:
return self.render_error(self.keyword, package, "Missing argument 'href'.")
if 'content' not in options:
options['content'] = options['href']
super().render(context, package, options)
def render(self, context, package, column):
with temp_update(dict(context), {
'package': package,
'pypi': self.renderer[package],
'column': column,
}) as arguments:
return context.environment.get_template(self.template).render(**arguments)
@property
def template(self):
return os.path.join("columns", "{}.html".format(self.keyword))
import os
from pypimonitor.column import Jinja2
class BadgesIO(Jinja2):
@property
def template(self):
return os.path.join("columns", "badgesio", "{}.html".format(self.keyword))
class PypiVersion(BadgesIO):
keyword = "pypiversion"
title = "Version"
class PypiWeeklyDownloads(BadgesIO):
keyword = "pypiwdownloads"
title = "Weekly"
class PypiDailyDownloads(BadgesIO):
keyword = "pypiddownloads"
title = "Daily"
class PypiMonthlyDownloads(BadgesIO):
keyword = "pypimdownloads"
title = "Monthly"
from pypimonitor.column import Column, Jinja2
class Empty(Column):
keyword = "empty"
def render(self, context, package, column):
return ""
class Html(Column):
keyword = 'html'
default = {'html': ''}
def render(self, context, package, column):
return column['html']
class Link(Jinja2):
keyword = 'link'
def render(self, context, package, column):
if 'href' not in column:
return self.render_error(self.keyword, package, "Missing argument 'href'.")
if 'content' not in column:
column['content'] = column['href']
return super().render(context, package, column)
class Color(Jinja2):
keyword = 'color'
import os
from pypimonitor.column import Jinja2
class Gitlab(Jinja2):
@property
def template(self):
return os.path.join("columns", "gitlab", "{}.html".format(self.keyword))
class CI(Gitlab):
keyword = "gitlabci"
title = "CI"
from pypimonitor.column.jinja2 import Jinja2
from pypimonitor.column import Jinja2
class Homepage(Jinja2):
keyword = 'homepage'
from pypimonitor.column.jinja2 import Jinja2
from pypimonitor.column import Jinja2
class Readthedocs(Jinja2):
keyword = 'readthedocs'
......
import os
from pypimonitor.column import Jinja2
class TravisCI(Jinja2):
keyword = "travisci"
{%- macro render(column, package) -%}
{%- from "columns/%s.html" % column import render -%}
{{- render(package) -}}
{%- endmacro -%}
<a href="{{ pypi.info.package_url }}">
<img src="https://img.shields.io/pypi/dd/{{ pypi.info.name }}.svg" alt="Daily downloads">
</a>
<a href="{{ pypi.info.package_url }}">
<img src="https://img.shields.io/pypi/dm/{{ pypi.info.name }}.svg" alt="Daily downloads">
</a>
<a href="{{ pypi.info.package_url }}">
<img src="https://img.shields.io/pypi/dw/{{ pypi.info.name }}.svg" alt="Daily downloads">
</a>
<div style="
background-color: {{ package | color(0.8, 0.8) }};
width: 10px;
height: 10px;
display: inline-block;
"></div>
{%- macro render(package) -%}
{%- if package is none -%}
Docs
{%- else -%}
{% set type, args = package.get_documentation() %}
{% if type is none %}
<!-- No documentation found for '{{ package.info.name }}'. -->
{% elif type == "readthedocs" %}
<a href="//{{ package.name }}.readthedocs.io">
<img src="//readthedocs.io/projects/{{ package.name.lower() }}/badge" alt="Documentation">
</a>
{% else %}
<a href="{{ package.info.docs_url }}">
<img src="//img.shields.io/badge/docs-latest-brightgreen.svg" alt="Documentation">
</a>
{% endif %}
{%- endif -%}
{%- endmacro -%}
<a href="{{ pypi.home_page }}">{{ pypi.name }}</a>
<a href="{{ pypi.info.home_page }}">{{ pypi.info.name }}</a>
<a href="{{ href }}">
{{ content }}
<a href="{{ column.href }}">
{{ column.content }}
</a>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment