]> git.ipfire.org Git - pakfire.git/blame - python/pakfire/packages/installed.py
Add transaction test for duplicate files.
[pakfire.git] / python / pakfire / packages / installed.py
CommitLineData
47a4cb89 1#!/usr/bin/python
b792d887
MT
2###############################################################################
3# #
4# Pakfire - The IPFire package management system #
5# Copyright (C) 2011 Pakfire development team #
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
47a4cb89 21
4f91860e
MT
22import os
23
14ea3228 24import pakfire.downloader
862bea4d 25import pakfire.filelist
14ea3228 26
47a4cb89 27from base import Package
e0636b31 28from file import BinaryPackage
4f91860e 29
e871a081 30import pakfire.util as util
4f91860e 31from pakfire.constants import *
47a4cb89 32
fa6d335b
MT
33class DatabasePackage(Package):
34 type = "db"
47a4cb89 35
4f91860e
MT
36 def __init__(self, pakfire, repo, db, data):
37 Package.__init__(self, pakfire, repo)
3723913b 38
47a4cb89
MT
39 self.db = db
40
41 self._data = {}
42
43 for key in data.keys():
44 self._data[key] = data[key]
45
46 def __repr__(self):
47 return "<%s %s>" % (self.__class__.__name__, self.friendly_name)
48
49 @property
50 def metadata(self):
51 return self._data
52
53 @property
54 def id(self):
55 id = self.metadata.get("id")
56 if not id:
57 id = 0
58
59 return id
60
61 @property
62 def name(self):
63 return self.metadata.get("name")
64
65 @property
66 def version(self):
67 return self.metadata.get("version")
68
69 @property
70 def release(self):
71 return self.metadata.get("release")
72
73 @property
74 def epoch(self):
75 epoch = self.metadata.get("epoch", 0)
76
77 return int(epoch)
78
79 @property
80 def arch(self):
81 return self.metadata.get("arch")
82
83 @property
84 def maintainer(self):
85 return self.metadata.get("maintainer")
86
87 @property
88 def license(self):
89 return self.metadata.get("license")
90
91 @property
92 def summary(self):
93 return self.metadata.get("summary")
94
95 @property
96 def description(self):
97 return self.metadata.get("description")
98
99 @property
8537c16d 100 def groups(self):
e74f185d
MT
101 groups = self.metadata.get("groups", "")
102
103 if groups:
104 return groups.split()
105
106 return []
47a4cb89
MT
107
108 @property
0c665250
MT
109 def build_date(self):
110 return self.metadata.get("build_date")
111
112 @property
113 def build_time(self):
b566f7e3
MT
114 build_time = self.metadata.get("build_time", 0)
115
6b151a68
MT
116 try:
117 return int(build_time)
118 except TypeError:
119 return 0
47a4cb89
MT
120
121 @property
122 def build_host(self):
123 return self.metadata.get("build_host")
124
125 @property
126 def build_id(self):
127 return self.metadata.get("build_id")
128
1317485d
MT
129 @property
130 def uuid(self):
131 return self.metadata.get("uuid")
132
e399ad3a
MT
133 @property
134 def size(self):
a5f5fced 135 return self.metadata.get("size", 0)
e399ad3a 136
0304200a
MT
137 @property
138 def inst_size(self):
139 # XXX to be done
140 return 0
141
47a4cb89
MT
142 @property
143 def provides(self):
c605d735 144 return self.metadata.get("provides", "").split()
47a4cb89
MT
145
146 @property
147 def requires(self):
c605d735 148 return self.metadata.get("requires", "").split()
47a4cb89
MT
149
150 @property
151 def conflicts(self):
c605d735 152 return self.metadata.get("conflicts", "").split()
ae20b05f
MT
153
154 @property
155 def obsoletes(self):
c605d735 156 return self.metadata.get("obsoletes", "").split()
47a4cb89 157
4f91860e
MT
158 @property
159 def hash1(self):
160 return self.metadata.get("hash1")
161
a5f5fced
MT
162 @property
163 def scriptlet(self):
164 return self.metadata.get("scriptlet")
165
4f91860e
MT
166 @property
167 def filename(self):
168 return self.metadata.get("filename") # XXX basename?
169
47a4cb89
MT
170 @property
171 def filelist(self):
862bea4d
MT
172 filelist = []
173
ae20b05f 174 c = self.db.cursor()
862bea4d
MT
175 c.execute("SELECT id FROM files WHERE pkg = ?", (self.id,))
176
177 for id in c:
178 file = pakfire.filelist.FileDatabase(self.pakfire, self.db, id[0])
179 filelist.append(file)
47a4cb89 180
862bea4d 181 return filelist
47a4cb89 182
6ee3d6b9
MT
183 @property
184 def configfiles(self):
185 return [] # XXX to be done
186
a88d2cdc
MT
187 def _does_provide_file(self, requires):
188 """
189 A faster version to find a file in the database.
190 """
191 c = self.db.cursor()
311ce792 192 c.execute("SELECT * FROM files WHERE name GLOB ? AND pkg = ?",
a2d1644c 193 (requires.requires, self.id))
a88d2cdc
MT
194
195 ret = False
196 for pkg in c:
a2d1644c
MT
197 ret = True
198 break
a88d2cdc
MT
199
200 c.close()
201
202 return ret
203
14ea3228 204 def download(self, text=""):
4f91860e
MT
205 """
206 Downloads the package from repository and returns a new instance
207 of BinaryPackage.
208 """
d4c94aa5
MT
209
210 # XXX a bit hacky, but InstalledRepository has no cache.
211 if self.repo.name == "installed":
212 return self
213
4f91860e
MT
214 # Marker, if we need to download the package.
215 download = True
216
217 # Add shortcut for cache.
218 cache = self.repo.cache
219
220 cache_filename = "packages/%s" % os.path.basename(self.filename)
221
222 # Check if file already exists in cache.
223 if cache.exists(cache_filename):
224 # If the file does already exist, we check if the hash1 matches.
225 if cache.verify(cache_filename, self.hash1):
226 # We already got the right file. Skip download.
227 download = False
228 else:
229 # The file in cache has a wrong hash. Remove it and repeat download.
230 cache.remove(cache_filename)
231
232 if download:
4f91860e
MT
233 # Make sure filename is of type string (and not unicode)
234 filename = str(self.filename)
235
14ea3228
MT
236 # Get a package grabber and add mirror download capabilities to it.
237 grabber = pakfire.downloader.PackageDownloader(
238 text=text + os.path.basename(filename),
239 )
240 grabber = self.repo.mirrors.group(grabber)
241
242 i = grabber.urlopen(filename)
243
244 # Open input and output files and download the file.
245 o = cache.open(cache_filename, "w")
4f91860e
MT
246
247 buf = i.read(BUFFER_SIZE)
248 while buf:
249 o.write(buf)
250 buf = i.read(BUFFER_SIZE)
251
252 i.close()
253 o.close()
254
255 # Verify if the download was okay.
256 if not cache.verify(cache_filename, self.hash1):
257 raise Exception, "XXX this should never happen..."
258
259 filename = os.path.join(cache.path, cache_filename)
260 return BinaryPackage(self.pakfire, self.repo, filename)
fa6d335b 261
e871a081
MT
262 def cleanup(self, message, prefix):
263 c = self.db.cursor()
264
265 # Get all files, that are in this package and check for all of
266 # them if they need to be removed.
267 files = self.filelist
268
269 # Fetch the whole filelist of the system from the database and create
270 # a diff. Exclude files from this package - of course.
271 c.execute("SELECT name FROM files WHERE pkg != ?", (self.id,))
272
273 for row in c:
274 # Check if file in filelist.
275 if row["name"] in files:
276 files.remove(row["name"])
277
278 c.close()
279
280 self._remove_files(files, message, prefix)
281
282
fa6d335b
MT
283# XXX maybe we can remove this later?
284class InstalledPackage(DatabasePackage):
285 type = "installed"
286