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