The Debian Member Portfolio Service https://portfolio.debian.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
4.3 KiB

  1. # -*- python -*-
  2. # -*- coding: utf8 -*-
  3. #
  4. # Debian Member Portfolio Service url builder
  5. #
  6. # Copyright © 2009-2017 Jan Dittberner <jan@dittberner.info>
  7. #
  8. # This file is part of the Debian Member Portfolio Service.
  9. #
  10. # Debian Member Portfolio Service is free software: you can redistribute it
  11. # and/or modify it under the terms of the GNU Affero General Public License as
  12. # published by the Free Software Foundation, either version 3 of the License,
  13. # or (at your option) any later version.
  14. #
  15. # Debian Member Portfolio Service is distributed in the hope that it will be
  16. # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  18. # General Public License for more details.
  19. #
  20. # You should have received a copy of the GNU Affero General Public License
  21. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  22. #
  23. """
  24. This module provides the function build_urls to build personalized
  25. URLs using the given information and the URL patterns defined in
  26. portfolio.ini.
  27. """
  28. from configparser import ConfigParser, InterpolationMissingOptionError
  29. from encodings.utf_8 import StreamReader as UTF8StreamReader
  30. import pkg_resources
  31. from debianmemberportfolio.model import keyfinder
  32. from urllib.parse import quote_plus
  33. from flask_babel import gettext as _, lazy_gettext as N_
  34. my_config = ConfigParser()
  35. my_config.read_file(UTF8StreamReader(
  36. pkg_resources.resource_stream(__name__, 'portfolio.ini')))
  37. _FIELDNAMES_MAP = {
  38. 'email': N_('Email address'),
  39. 'name': N_('Name'),
  40. 'gpgfp': N_('GPG fingerprint'),
  41. 'username': N_('Debian user name'),
  42. 'nonddemail': N_('Non Debian email address'),
  43. 'salsausername': N_('Salsa user name'),
  44. }
  45. class DDPortfolioEntry(object):
  46. def __init__(self, config, section, key):
  47. self.name = key
  48. self.optional = config.has_option(section, key + '.optional') and \
  49. config.getboolean(section, key + '.optional') or False
  50. if config.has_option(section, key + '.type'):
  51. self.type = config.get(section, key + '.type')
  52. else:
  53. self.type = 'url'
  54. def _build_quoted_fields(fields):
  55. """
  56. Take a dictionary of raw field values and quote the values if required.
  57. """
  58. qfields = {}
  59. for key, value in fields.items():
  60. if value is not None:
  61. if isinstance(value, str):
  62. qfields[key] = quote_plus(value.encode('utf8'))
  63. elif isinstance(value, str):
  64. qfields[key] = quote_plus(value)
  65. else:
  66. qfields[key] = value
  67. qfields[key] = str(qfields[key]).replace('%', '%%')
  68. if 'gpgfp' not in qfields:
  69. fpr = keyfinder.getFingerprintByEmail(fields['email'].encode('utf8'))
  70. if fpr:
  71. qfields['gpgfp'] = fpr[0]
  72. qfields['firstchar'] = fields['email'][0].encode('utf8')
  73. qfields['emailnoq'] = fields['email'].encode('utf8')
  74. return qfields
  75. def build_urls(fields):
  76. """Build personalized URLs using the developer information in
  77. fields."""
  78. data = []
  79. qfields = _build_quoted_fields(fields)
  80. for section in [section.strip() for section in
  81. my_config.get('DEFAULT',
  82. 'urlbuilder.sections').split(',')]:
  83. data.append(['section', section])
  84. if my_config.has_option(section, 'urls'):
  85. for entry in ([
  86. DDPortfolioEntry(my_config, section, url) for url in
  87. my_config.get(section, 'urls').split(',')]):
  88. try:
  89. data.append(
  90. ['url', section, entry,
  91. my_config.get(section, entry.name + '.pattern',
  92. raw=False, vars=qfields)])
  93. except InterpolationMissingOptionError as e:
  94. if not entry.optional:
  95. if e.reference in _FIELDNAMES_MAP:
  96. data.append(['error', section, entry,
  97. _('Missing input: %s') %
  98. _(_FIELDNAMES_MAP[e.reference])])
  99. else:
  100. data.append(['error', section, entry,
  101. _('Missing input: %s') % e.reference])
  102. return data