33
|
1 # -*- coding: utf-8 -*-
|
|
2
|
|
3 # daemon/_metadata.py
|
|
4 # Part of ‘python-daemon’, an implementation of PEP 3143.
|
|
5 #
|
|
6 # Copyright © 2008–2015 Ben Finney <ben+python@benfinney.id.au>
|
|
7 #
|
|
8 # This is free software: you may copy, modify, and/or distribute this work
|
|
9 # under the terms of the Apache License, version 2.0 as published by the
|
|
10 # Apache Software Foundation.
|
|
11 # No warranty expressed or implied. See the file ‘LICENSE.ASF-2’ for details.
|
|
12
|
|
13 """ Package metadata for the ‘python-daemon’ distribution. """
|
|
14
|
|
15 from __future__ import (absolute_import, unicode_literals)
|
|
16
|
|
17 import json
|
|
18 import re
|
|
19 import collections
|
|
20 import datetime
|
|
21
|
|
22 import pkg_resources
|
|
23
|
|
24
|
|
25 distribution_name = "python-daemon"
|
|
26 version_info_filename = "version_info.json"
|
|
27
|
|
28 def get_distribution_version_info(filename=version_info_filename):
|
|
29 """ Get the version info from the installed distribution.
|
|
30
|
|
31 :param filename: Base filename of the version info resource.
|
|
32 :return: The version info as a mapping of fields. If the
|
|
33 distribution is not available, the mapping is empty.
|
|
34
|
|
35 The version info is stored as a metadata file in the
|
|
36 distribution.
|
|
37
|
|
38 """
|
|
39 version_info = {
|
|
40 'release_date': "UNKNOWN",
|
|
41 'version': "UNKNOWN",
|
|
42 'maintainer': "UNKNOWN",
|
|
43 }
|
|
44
|
|
45 try:
|
|
46 distribution = pkg_resources.get_distribution(distribution_name)
|
|
47 except pkg_resources.DistributionNotFound:
|
|
48 distribution = None
|
|
49
|
|
50 if distribution is not None:
|
|
51 if distribution.has_metadata(version_info_filename):
|
|
52 content = distribution.get_metadata(version_info_filename)
|
|
53 version_info = json.loads(content)
|
|
54
|
|
55 return version_info
|
|
56
|
|
57 version_info = get_distribution_version_info()
|
|
58
|
|
59 version_installed = version_info['version']
|
|
60
|
|
61
|
|
62 rfc822_person_regex = re.compile(
|
|
63 "^(?P<name>[^<]+) <(?P<email>[^>]+)>$")
|
|
64
|
|
65 ParsedPerson = collections.namedtuple('ParsedPerson', ['name', 'email'])
|
|
66
|
|
67 def parse_person_field(value):
|
|
68 """ Parse a person field into name and email address.
|
|
69
|
|
70 :param value: The text value specifying a person.
|
|
71 :return: A 2-tuple (name, email) for the person's details.
|
|
72
|
|
73 If the `value` does not match a standard person with email
|
|
74 address, the `email` item is ``None``.
|
|
75
|
|
76 """
|
|
77 result = (None, None)
|
|
78
|
|
79 match = rfc822_person_regex.match(value)
|
|
80 if len(value):
|
|
81 if match is not None:
|
|
82 result = ParsedPerson(
|
|
83 name=match.group('name'),
|
|
84 email=match.group('email'))
|
|
85 else:
|
|
86 result = ParsedPerson(name=value, email=None)
|
|
87
|
|
88 return result
|
|
89
|
|
90 author_name = "Ben Finney"
|
|
91 author_email = "ben+python@benfinney.id.au"
|
|
92 author = "{name} <{email}>".format(name=author_name, email=author_email)
|
|
93
|
|
94
|
|
95 class YearRange:
|
|
96 """ A range of years spanning a period. """
|
|
97
|
|
98 def __init__(self, begin, end=None):
|
|
99 self.begin = begin
|
|
100 self.end = end
|
|
101
|
|
102 def __unicode__(self):
|
|
103 text = "{range.begin:04d}".format(range=self)
|
|
104 if self.end is not None:
|
|
105 if self.end > self.begin:
|
|
106 text = "{range.begin:04d}–{range.end:04d}".format(range=self)
|
|
107 return text
|
|
108
|
|
109 __str__ = __unicode__
|
|
110
|
|
111
|
|
112 def make_year_range(begin_year, end_date=None):
|
|
113 """ Construct the year range given a start and possible end date.
|
|
114
|
|
115 :param begin_date: The beginning year (text) for the range.
|
|
116 :param end_date: The end date (text, ISO-8601 format) for the
|
|
117 range, or a non-date token string.
|
|
118 :return: The range of years as a `YearRange` instance.
|
|
119
|
|
120 If the `end_date` is not a valid ISO-8601 date string, the
|
|
121 range has ``None`` for the end year.
|
|
122
|
|
123 """
|
|
124 begin_year = int(begin_year)
|
|
125
|
|
126 try:
|
|
127 end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d")
|
|
128 except (TypeError, ValueError):
|
|
129 # Specified end_date value is not a valid date.
|
|
130 end_year = None
|
|
131 else:
|
|
132 end_year = end_date.year
|
|
133
|
|
134 year_range = YearRange(begin=begin_year, end=end_year)
|
|
135
|
|
136 return year_range
|
|
137
|
|
138 copyright_year_begin = "2001"
|
|
139 build_date = version_info['release_date']
|
|
140 copyright_year_range = make_year_range(copyright_year_begin, build_date)
|
|
141
|
|
142 copyright = "Copyright © {year_range} {author} and others".format(
|
|
143 year_range=copyright_year_range, author=author)
|
|
144 license = "Apache-2"
|
|
145 url = "https://alioth.debian.org/projects/python-daemon/"
|
|
146
|
|
147
|
|
148 # Local variables:
|
|
149 # coding: utf-8
|
|
150 # mode: python
|
|
151 # End:
|
|
152 # vim: fileencoding=utf-8 filetype=python :
|