From c7befe173ed2b0f5fd82228fa45c7a105ac44818 Mon Sep 17 00:00:00 2001 From: Lars-Dominik Braun Date: Fri, 20 Jan 2017 14:14:12 +0100 Subject: Auto-generate software list --- tools/formatSoftware.py | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100755 tools/formatSoftware.py (limited to 'tools') diff --git a/tools/formatSoftware.py b/tools/formatSoftware.py new file mode 100755 index 0000000..a54a740 --- /dev/null +++ b/tools/formatSoftware.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python3 + +from rdflib import URIRef, BNode, Literal, Graph, Namespace +from rdflib.namespace import RDF, NamespaceManager +from urllib.parse import urlparse +import sys +from itertools import chain, groupby +from jinja2 import Environment +from formatRefs import first + +class RDFWalker: + """ + Simple RDF graph walker + """ + + def __init__ (self, g, s, n, path=[]): + """ + :param g: Graph + :param s: Namespace + :param n: Start node + """ + self.g = g + self.n = n + self.s = s + self._path = path + + def __getattr__ (self, k): + """ + If k is underscore _, walk up tree one level, otherwise search for + direct descendents and get first one. + """ + if k == '_': + return RDFWalker (self.g, self.s, self._path[0], self._path[1:]) + yieldall = False + if k.endswith ('_'): + yieldall = True + k = k[:-1] + + if k == 'a': + attr = RDF.type + else: + attr = getattr (self.s, k) + + ret = [RDFWalker (self.g, self.s, n, [self.n] + self._path) for n in self.g.objects (self.n, attr)] + + if yieldall: + return ret + elif not ret: + return None + else: + return ret[0] + + def __eq__ (self, b): + return self.n == b.n + + def __lt__ (self, b): + return str (self) < str (b) + + def __str__ (self): + return str (self.n) + +if __name__ == '__main__': + env = Environment () + env.filters['urlparse'] = urlparse + template = env.from_string (""" +{% macro schemaval(n, name, tag='span') -%} +<{{ tag }} property="{{ name }}">{{ n|attr(name) }} +{%- endmacro %} +{%- for companyname, software in items %} + {% set company = companyname._ %} +
+ {{ schemaval(company, 'name', 'h3') }} + {% set addr = company.address %} +

+ {% if addr.streetAddress %}{{ schemaval(addr, 'streetAddress') }}
+ {% elif addr.postOfficeBoxNumber %}PO box {{ schemaval(addr, 'postOfficeBoxNumber') }}
+ {% endif %} + {{ schemaval(addr, 'postalCode') }} {{ schemaval(addr, 'addressLocality') }} +

+ {% set url = company.url %} + {% if url %} +

{{ url }}

+ {% endif %} +
+ {%- for s in software|sort(attribute='name') %} +
+

{{ schemaval(s, 'name') }}{% if s.softwareVersion %} ({{ schemaval(s, 'softwareVersion') }}){% endif %}

+

+ {% if s.dateCreated %}{{ schemaval(s, 'dateCreated') }} + {% if s.datePublished %}/{{ schemaval(s, 'datePublished') }}{% endif %} + {% elif s.datePublished %}{{ schemaval(s, 'datePublished') }} + {% endif %} +

+ {% if s.description %}{{ schemaval(s, 'description', 'p') }}{% endif %} +
    + {% for o in s.offers_|sort(attribute='name') %} +
  • + {% if o.name %}{{ schemaval(o, 'name') }}, {% endif %} + {{ schemaval(o.priceSpecification, 'price') }} + {{ schemaval(o.priceSpecification, 'priceCurrency') }}, + {{ schemaval(o, 'validFrom') }}{% if o.validThrough and o.validFrom != o.validThrough %}–{{ schemaval(o, 'validThrough') }}{% endif %} +
  • + {% endfor %} +
+
+ {% endfor -%} +
+
+{% endfor %}""") + g = Graph() + result = g.parse ("index.ttl", format='turtle') + s = Namespace ("https://schema.org/") + + items = [] + + for n in g.subjects (RDF.type, s.SoftwareApplication): + n = RDFWalker (g, s, n) + if n.author: + items.append (n) + + items = groupby (sorted (items, key=lambda x: str (x.author.name).lower ()), lambda x: x.author.name) + print (template.render(items=items)) + -- cgit v1.2.3