# -*- python -*- # -*- coding: utf8 -*- # # Debian Member Portfolio Service url builder # # Copyright © 2009-2020 Jan Dittberner # # This file is part of the Debian Member Portfolio Service. # # Debian Member Portfolio Service is free software: you can redistribute it # and/or modify it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the License, # or (at your option) any later version. # # Debian Member Portfolio Service is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero # General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # """ This module provides the function build_urls to build personalized URLs using the given information and the URL patterns defined in portfolio.ini. """ from configparser import ConfigParser, InterpolationMissingOptionError from encodings.utf_8 import StreamReader as UTF8StreamReader import pkg_resources from debianmemberportfolio.model import keyfinder from urllib.parse import quote_plus from flask_babel import gettext as _, lazy_gettext as N_ my_config = ConfigParser() my_config.read_file(UTF8StreamReader( pkg_resources.resource_stream(__name__, 'portfolio.ini'))) _FIELDNAMES_MAP = { 'email': N_('Email address'), 'name': N_('Name'), 'gpgfp': N_('GPG fingerprint'), 'username': N_('Debian user name'), 'nonddemail': N_('Non Debian email address'), 'salsausername': N_('Salsa user name'), } class DDPortfolioEntry(object): def __init__(self, config, section, key): self.name = key self.optional = config.has_option(section, key + '.optional') and \ config.getboolean(section, key + '.optional') or False if config.has_option(section, key + '.type'): self.type = config.get(section, key + '.type') else: self.type = 'url' def _build_quoted_fields(fields): """ Take a dictionary of raw field values and quote the values if required. """ qfields = {} for key, value in fields.items(): if value is not None: if isinstance(value, str): qfields[key] = quote_plus(value.encode('utf8')) elif isinstance(value, str): qfields[key] = quote_plus(value) else: qfields[key] = value qfields[key] = str(qfields[key]).replace('%', '%%') if 'gpgfp' not in qfields: fpr = keyfinder.getFingerprintByEmail(fields['email'].encode('utf8')) if fpr: qfields['gpgfp'] = fpr[0] qfields['firstchar'] = fields['email'][0].encode('utf8') qfields['emailnoq'] = fields['email'].encode('utf8') return qfields def build_urls(fields): """Build personalized URLs using the developer information in fields.""" data = [] qfields = _build_quoted_fields(fields) for section in [section.strip() for section in my_config.get('DEFAULT', 'urlbuilder.sections').split(',')]: data.append(['section', section]) if my_config.has_option(section, 'urls'): for entry in ([ DDPortfolioEntry(my_config, section, url) for url in my_config.get(section, 'urls').split(',')]): try: data.append( ['url', section, entry, my_config.get(section, entry.name + '.pattern', raw=False, vars=qfields)]) except InterpolationMissingOptionError as e: if not entry.optional: if e.reference in _FIELDNAMES_MAP: data.append(['error', section, entry, _('Missing input: %s') % _(_FIELDNAMES_MAP[e.reference])]) else: data.append(['error', section, entry, _('Missing input: %s') % e.reference]) return data