copyright.py 3.05 KB
Newer Older
Baptiste Beauplat's avatar
Baptiste Beauplat committed
1
2
3
4
5
#   copyright.py - copyright parsing
#
#   This file is part of debexpo
#   https://salsa.debian.org/mentors.debian.net-team/debexpo
#
6
#   Copyright © 2020 Baptiste Beauplat <lyknode@cilg.org>
Baptiste Beauplat's avatar
Baptiste Beauplat committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#
#   Permission is hereby granted, free of charge, to any person
#   obtaining a copy of this software and associated documentation
#   files (the "Software"), to deal in the Software without
#   restriction, including without limitation the rights to use,
#   copy, modify, merge, publish, distribute, sublicense, and/or sell
#   copies of the Software, and to permit persons to whom the
#   Software is furnished to do so, subject to the following
#   conditions:
#
#   The above copyright notice and this permission notice shall be
#   included in all copies or substantial portions of the Software.
#
#   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
#   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
#   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
#   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
#   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
#   OTHER DEALINGS IN THE SOFTWARE.

from debian.copyright import Copyright as DebianCopyright, \
    MachineReadableFormatError, NotMachineReadableError


class ExceptionCopyright(Exception):
34
35
36
    def __str__(self):
        message = super().__str__()
        return f'Failed to parse debian/copyright: {message}'
Baptiste Beauplat's avatar
Baptiste Beauplat committed
37
38
39
40
41
42
43
44
45
46
47
48


class Copyright():
    def __init__(self, filename):
        self.copyright = self._parse_copyright(filename)
        self._build_copyright()

    def _parse_copyright(self, filename):
        copyright = None

        try:
            fd = open(filename, 'r')
49
50
        # After dpkg 1.20.0, this will be catched by dpkg-source -x
        except IOError:  # pragma: no cover
51
            return copyright
Baptiste Beauplat's avatar
Baptiste Beauplat committed
52
53
54
55

        with fd:
            try:
                copyright = DebianCopyright(fd)
56
            except (MachineReadableFormatError, ValueError) as e:
Baptiste Beauplat's avatar
Baptiste Beauplat committed
57
58
59
60
61
62
63
                raise ExceptionCopyright(e)
            except NotMachineReadableError:
                pass

        return copyright

    def _build_copyright(self):
64
65
66
67
68
        try:
            self.licenses = self._get_licenses()
            self.author = self._get_author()
        except MachineReadableFormatError as e:
            raise ExceptionCopyright(e)
Baptiste Beauplat's avatar
Baptiste Beauplat committed
69
70
71
72
73
74
75
76
77
78
79
80

    def validate(self):
        # Validated by the _parse_copyright method
        pass

    def _get_licenses(self):
        licenses = set()

        if not self.copyright:
            return licenses

        for paragraph in self.copyright.all_files_paragraphs():
81
82
            if not paragraph.files == ('debian/*',):
                licenses.update([paragraph.license.synopsis])
Baptiste Beauplat's avatar
Baptiste Beauplat committed
83
84
85
86
87
88
89
90
91

        return licenses

    def _get_author(self):
        if self.copyright and self.copyright.header and \
                self.copyright.header.upstream_contact:
            return self.copyright.header.upstream_contact[0]

        return None