import repository from arizona
[raven.git] / lib / ravenlib / files / tpfile.py
1 import os
2 import time
3
4 from sfa.trust.certificate import Keypair
5
6 import ravenlib.crypto
7 import ravenlib.package.storkpackage
8
9 class tpfile:
10
11     def __init__(self):
12         self.reset()
13
14     def reset(self):
15         self.header = '<?xml version="1.0" encoding="ISO-8859-1" standalone="yes" ?>\n' + \
16                   '<TRUSTEDPACKAGES>\n'
17         self.footer = '</TRUSTEDPACKAGES>\n'
18
19         self.uninstall_names = []
20
21         self.contents = []
22
23     def get_string(self):
24         return self.header + self.get_contents_string() + self.footer
25
26     def get_contents(self):
27         return self.contents
28
29     def get_contents_string(self):
30         contentsStr = ""
31         for item in self.contents:
32             line = None
33             provides = item.get("provides", [])
34
35             if item["type"] == "user":
36                 line = '<USER PATTERN="' + item["pattern"] + \
37                        '" USERNAME="' + item["username"] + \
38                        '" PUBLICKEY="' + item["publickey"] + \
39                        '" ACTION="' + item["action"] + '"'
40                 if (provides != []):
41                     line = line + ' PROVIDES="' + provides + '"'
42                 line = line + '/>\n'
43             elif item["type"] == "package":
44                 line = '<FILE PATTERN="' + item["pattern"] + \
45                        '" HASH="' + item["hash"] + \
46                        '" TIMESTAMP="' + str(item["timestamp"]) + \
47                        '" TAGS="' + ",".join(item["tags"]) + \
48                        '" ACTION="' + item["action"] + '"'
49                 if (provides != []):
50                     line = line + ' PROVIDES="' + provides + '"'
51                 line = line + '/>\n'
52
53             if line:
54                 contentsStr += line
55
56         return contentsStr
57
58     def save(self, destFileName):
59         open(destFileName, "w").write(self.get_string())
60
61     def parse_comments(self, fn):
62         dict = {}
63         f = open(fn, "rt")
64         for line in f.readlines():
65             line = line.strip()
66             if line.startswith("#"):
67                 line = line[1:].strip()
68                 parts = line.split(":", 1)
69                 if (len(parts) == 2):
70                     key = parts[0]
71                     values = parts[1].split(",")
72                     values = [value.strip() for value in values]
73                     list = dict.get(key, [])
74                     list.extend(values)
75                     dict[key] = list
76
77         return dict
78
79     def add_user(self, userName, publicKey, pattern="*", action="allow", provides=[]):
80         keyString = ravenlib.crypto.keypair_to_stork_pubkey_string(publicKey)
81
82         userDict = {"type": "user", "pattern": pattern, "username": userName, "publickey": keyString, "action": action}
83
84         if (provides != None) and (provides != []):
85             userDict["provides"] = ",".join(provides)
86
87         self.contents.append(userDict)
88         return userDict
89
90     def add_user_from_file(self, userName, publicKeyFileName, pattern="*", action="allow"):
91         # let the user use comments to add some addition stuff to the tpfile entry
92         modifiers = self.parse_comments(publicKeyFileName)
93         provides = modifiers.get("provides", [])
94
95         publicKey = Keypair()
96         publicKey.load_pubkey_from_file(publicKeyFileName)
97         userDict = self.add_user(userName, publicKey, pattern, action, provides=provides)
98         userDict["srcFileName"] = publicKeyFileName
99         return userDict
100
101     def add_package(self, pattern, hash, timestamp="now", tags=[], action="allow"):
102         if timestamp=="now":
103             timestamp=str(time.time())
104
105         packageDict = {"type": "package", "pattern": pattern, "hash": hash, "timestamp": str(timestamp), "tags": tags, "action": action}
106         self.contents.append(packageDict)
107         return packageDict
108
109     def add_package_from_file(self, fileName, timestamp="now", tags=[], action="allow"):
110         dir = os.path.dirname(fileName)
111         pattern = os.path.basename(fileName)
112         metadata = ravenlib.package.storkpackage.get_package_metadata(fileName)
113
114         urlFileName = ".".join(fileName.split(".")[:-1]) + ".url"
115         if os.path.exists(urlFileName):
116             url = file(urlFileName).readline().strip()
117             if url:
118                 if url.endswith("/"):
119                     url = os.path.join(url, os.path.basename(filename))
120                 metadata['URL'] = [url]
121
122         metaHash = ravenlib.package.storkpackage.package_metadata_dict_get_hash(metadata)
123         packageDict = self.add_package(pattern, metaHash, timestamp, tags, action)
124         packageDict["metadata"] = metadata
125         packageDict["packagename"] = metadata["name"]
126
127         packageDict["srcFileName"] = fileName
128
129     # A bit of overloading of the tpfile module to support the raven tool. We
130     # allow the user to add packages names to the list that we'll use to later
131     # generate the packages.pacman file. Package names aren't "trusted" so
132     # they don't technically belong here, but it's more convenient to store
133     # them here than to invent a separate data structure for them.
134     def add_name(self, pattern, tags=[], action="allow"):
135         packageDict = {"type": "name", "pattern": pattern, "tags": tags, "packagename": pattern, "action": action}
136         self.contents.append(packageDict)
137         return packageDict
138
139     def add_name_from_file(self, fileName, tags=[], action="allow"):
140         packageDict = self.add_name(fileName.split(".name")[0], tags, action)
141
142         packageDict["srcFileName"] = fileName
143
144     # a litte bit more overloading. The tpfile is a handy container to hold
145     # package-related stuff for the raven tool
146     def add_uninstall_from_file(self, fileName):
147         self.uninstall_names.append(fileName.split(".uninstall")[0])
148
149
150