Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the wiki_symbol shield factory #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion wmt_shields/common/shield_maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from io import BytesIO
from xml.dom.minidom import parseString as xml_parse
from xml.parsers.expat import ExpatError
from urllib.parse import urlparse
from urllib.request import urlopen

import cairo
import gi
Expand Down Expand Up @@ -60,7 +62,11 @@ def dimensions(self):
def find_resource(self, subdir, filename):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a separate function find_url_resource here to make it explicit that an external source is needed.

subdir_str = str(subdir) if subdir is not None else ''
filename = str(filename)
if os.path.isabs(filename):
if(urlparse(filename).netloc):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: always leave a space after if.

with urlopen(filename) as response:
return response.read()

elif os.path.isabs(filename):
abspath = filename
elif subdir is not None \
and (os.path.isabs(subdir_str) or subdir_str.startswith('{data}')):
Expand Down
63 changes: 63 additions & 0 deletions wmt_shields/styles/wiki_symbol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# SPDX-License-Identifier: GPL-3.0-only
#
# This file is part of the Waymarked Trails Map Project
# Copyright (C) 2023 Stéphane Chatty
#

import sys
from urllib.parse import urlparse, quote as urlquote

import hashlib
import re

import gi
gi.require_version('Rsvg', '2.0')
from gi.repository import Rsvg
import os

from ..common.tags import Tags
from ..common.config import ShieldConfig
from ..common.shield_maker import ShieldMaker

class WikiSymbol(ShieldMaker):
""" A shield with an SVG image located in the OSM wiki.
"""

def __init__(self, uuid, url, config):
self.uuid_pattern = uuid
self.url = url
self.config = config

def render(self, ctx, w, h):
data = self.find_resource('', self.url)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to protect against download failures here or imports will abort at most inconvenient times just because wiki.osm.org is temporarily down.

rhdl = Rsvg.Handle.new_from_data(data)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And this line may fail because of bogus or broken external data.

dim = rhdl.get_dimensions()

ctx.scale(w/dim.width, h/dim.height)
rhdl.render_cairo(ctx)


def create_for(tags: Tags, region: str, config: ShieldConfig):
wiki_symbol = tags.get('wiki:symbol')
if not (wiki_symbol):
return None

print(f'wiki:symbol = {wiki_symbol}', file=sys.stderr)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use the log library here at debug level.

if(urlparse(wiki_symbol).netloc):
print(f'URLs are not accepted in tag wiki:symbol: {wiki_symbol}', file=sys.stderr)
return None

match_svg = re.search('(.*)\.svg$', wiki_symbol)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't that rather be re.fullmatch instead of re.search (i.e. mach the entire string?).

if not (match_svg):
print(f'only SVG files are handled in tag wiki:symbol: {wiki_symbol}', file=sys.stderr)
return None

md5 = hashlib.md5(wiki_symbol.encode('utf-8')).hexdigest()
c1 = md5[0]
c2 = md5[1]
filebasename = match_svg.group(1)
filename = urlquote(wiki_symbol.encode('utf-8'))
url = f'https://wiki.openstreetmap.org/w/images/{c1}/{c1}{c2}/{filename}'
print(f' {url}', file=sys.stderr)
return WikiSymbol(f'wiki_{filebasename}', url, config)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be saver to use filename here instead of filenamebase to avoid illegal file names.