summaryrefslogtreecommitdiffstats
path: root/scripts/deb822.py
blob: a6432cc5de4ef3950e0b4ca7f79143380063cfd1 (plain) (blame)
1
2
3
4
5
6
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/python

## Version: 0.20051107

import re, string

class deb822:
    def __init__(self, fp):
        self.map = {}
        self.keys = []
        single = re.compile("^(?P<key>\S+):\s+(?P<data>\S.*)$")
        multi = re.compile("^(?P<key>\S+):\s*$")
        multidata = re.compile("^\s(?P<data>.*)$")
        ws = re.compile("^\s*$")
        
        curkey = None
        content = ""
        for line in fp.readlines():
            if ws.match(line):
                if curkey:
                    self.map[curkey] = content[:-1]
                    curkey = None
                    content = ""
                continue
            
            m = single.match(line)
            if m:
                if curkey:
                    self.map[curkey] = content[:-1]
                curkey = m.group('key')
                self.keys.append(curkey)
                self.map[curkey] = m.group('data')
                curkey = None
                content = ""
                continue

            m = multi.match(line)
            if m:
                if curkey:
                    self.map[curkey] = content[:-1]
                curkey = m.group('key')
                self.keys.append(curkey)
                content = "\n"
                continue

            m = multidata.match(line)
            if m:
                content = content + line
                continue

        if curkey:
            self.map[curkey] = content[:-1]

    def dump(self, fd):
        for key in self.keys:
            fd.write(key + ": " + self.map[key] + "\n")

    def isSingleLine(self, s):
        if s.count("\n"):
            return False
        else:
            return True

    def isMultiLine(self, s):
        return not self.isSingleLine(s)

    def _mergeFields(self, s1, s2):
        if not s2:
            return s1
        if not s1:
            return s2
        
        if self.isSingleLine(s1) and self.isSingleLine(s2):
            ## some fields are delimited by a single space, others
            ## a comma followed by a space.  this heuristic assumes
            ## that there are multiple items in one of the string fields
            ## so that we can pick up on the delimiter being used
            delim = ' '
            if (s1 + s2).count(', '):
                delim = ', '

            L = (s1 + delim + s2).split(delim)
            L.sort()

            prev = merged = L[0]
            
            for item in L[1:]:
                ## skip duplicate entries
                if item == prev:
                    continue
                merged = merged + delim + item
                prev = item
            return merged
            
        if self.isMultiLine(s1) and self.isMultiLine(s2):
            for item in s2.splitlines(True):
                if item not in s1.splitlines(True):
                    s1 = s1 + "\n" + item
            return s1

        raise ValueError
    
    def mergeFields(self, key, d1, d2 = None):
        ## this method can work in two ways - abstract that away
        if d2 == None:
            x1 = self
            x2 = d1
        else:
            x1 = d1
            x2 = d2

        ## we only have to do work if both objects contain our key
        ## otherwise, we just take the one that does, or raise an
        ## exception if neither does
        if key in x1.keys and key in x1.keys:
            merged = self._mergeFields(x1.map[key], x2.map[key])
        elif key in x1.keys:
            merged = x1[key]
        elif key in x2.keys:
            merged = x2[key]
        else:
            raise KeyError

        ## back to the two different ways - if this method was called
        ## upon an object, update that object in place.
        ## return nothing in this case, to make the author notice a
        ## problem if she assumes the object itself will not be modified
        if d2 == None:
            self.map[key] = merged
            return None

        return merged

    def hasField(self, key):
        if key in self.keys:
            return True
        return False

    def addField(self, key, value):
        if key in self.keys:
            ## key is already there
            raise KeyError
        else:
            self.keys.append(key)
            self.map[key] = value

## methods that changes and dsc files have in common
class _dscchanges(deb822):
    """A base class; not intended for direct use"""
    
## Specialty class for dealing with .dsc files
class dsc(_dscchanges):
    def files(self):
        fileList = []

        for fileEntry in self.map["Files"].splitlines():
            file = {}
            if fileEntry:
                fields = fileEntry.split()
                file["md5sum"] = fields[0]
                file["size"] = fields[1]
                file["name"] = fields[2]
                fileList.append(file)

        return fileList

class changes(_dscchanges):
    def files(self):
        fileList = []

        for fileEntry in self.map["Files"].splitlines():
            file = {}
            if fileEntry:
                fields = fileEntry.split()
                file["md5sum"] = fields[0]
                file["size"] = fields[1]
                file["section"] = fields[2]
                file["priority"] = fields[3]
                file["name"] = fields[4]
                fileList.append(file)

        return fileList

© 2014-2024 Faster IT GmbH | imprint | privacy policy