]> git.ipfire.org Git - people/jschlag/pbs.git/blame - src/buildservice/mirrors.py
Refactor keys
[people/jschlag/pbs.git] / src / buildservice / mirrors.py
CommitLineData
f6e6ff79
MT
1#!/usr/bin/python
2
3import logging
4import math
5import socket
f6e6ff79 6
2c909128
MT
7from . import base
8from . import logs
f6e6ff79 9
d3e7a9fb 10from .decorators import lazy_property
f6e6ff79
MT
11
12class Mirrors(base.Object):
13 def get_all(self):
14 mirrors = []
15
16 for mirror in self.db.query("SELECT id FROM mirrors \
17 WHERE NOT status = 'deleted' ORDER BY hostname"):
18 mirror = Mirror(self.pakfire, mirror.id)
19 mirrors.append(mirror)
20
21 return mirrors
22
23 def count(self, status=None):
24 query = "SELECT COUNT(*) AS count FROM mirrors"
25 args = []
26
27 if status:
28 query += " WHERE status = %s"
29 args.append(status)
30
31 query = self.db.get(query, *args)
32
33 return query.count
34
35 def get_random(self, limit=None):
36 query = "SELECT id FROM mirrors WHERE status = 'enabled' ORDER BY RAND()"
37 args = []
38
39 if limit:
40 query += " LIMIT %s"
41 args.append(limit)
42
43 mirrors = []
44 for mirror in self.db.query(query, *args):
45 mirror = Mirror(self.pakfire, mirror.id)
46 mirrors.append(mirror)
47
48 return mirrors
49
50 def get_by_id(self, id):
51 mirror = self.db.get("SELECT id FROM mirrors WHERE id = %s", id)
52 if not mirror:
53 return
54
55 return Mirror(self.pakfire, mirror.id)
56
57 def get_by_hostname(self, hostname):
58 mirror = self.db.get("SELECT id FROM mirrors WHERE NOT status = 'deleted' \
59 AND hostname = %s", hostname)
60
61 if not mirror:
62 return
63
64 return Mirror(self.pakfire, mirror.id)
65
66 def get_for_location(self, addr):
d3e7a9fb 67 country_code = self.backend.geoip.guess_from_address(addr)
f6e6ff79 68
d3e7a9fb
MT
69 # Cannot return any good mirrors if location is unknown
70 if not country_code:
71 return []
f6e6ff79
MT
72
73 mirrors = []
f6e6ff79 74
d3e7a9fb
MT
75 # Walk through all mirrors
76 for mirror in self.get_all():
77 if not mirror.enabled:
78 continue
f6e6ff79 79
d3e7a9fb
MT
80 if mirror.country_code == country_code:
81 mirrors.append(mirror)
f6e6ff79 82
d3e7a9fb 83 # XXX needs to search for nearby countries
f6e6ff79
MT
84
85 return mirrors
86
87 def get_history(self, limit=None, offset=None, mirror=None, user=None):
88 query = "SELECT * FROM mirrors_history"
89 args = []
90
91 conditions = []
92
93 if mirror:
94 conditions.append("mirror_id = %s")
95 args.append(mirror.id)
96
97 if user:
98 conditions.append("user_id = %s")
99 args.append(user.id)
100
101 if conditions:
102 query += " WHERE %s" % " AND ".join(conditions)
103
104 query += " ORDER BY time DESC"
105
106 if limit:
107 if offset:
108 query += " LIMIT %s,%s"
109 args += [offset, limit,]
110 else:
111 query += " LIMIT %s"
112 args += [limit,]
113
114 entries = []
115 for entry in self.db.query(query, *args):
116 entry = logs.MirrorLogEntry(self.pakfire, entry)
117 entries.append(entry)
118
119 return entries
120
121
122class Mirror(base.Object):
123 def __init__(self, pakfire, id):
124 base.Object.__init__(self, pakfire)
125
126 self.id = id
127
128 # Cache.
129 self._data = None
130 self._location = None
131
132 def __cmp__(self, other):
133 return cmp(self.id, other.id)
134
135 @classmethod
136 def create(cls, pakfire, hostname, path="", owner=None, contact=None, user=None):
137 id = pakfire.db.execute("INSERT INTO mirrors(hostname, path, owner, contact) \
138 VALUES(%s, %s, %s, %s)", hostname, path, owner, contact)
139
140 mirror = cls(pakfire, id)
141 mirror.log("created", user=user)
142
143 return mirror
144
145 def log(self, action, user=None):
146 user_id = None
147 if user:
148 user_id = user.id
149
150 self.db.execute("INSERT INTO mirrors_history(mirror_id, action, user_id, time) \
151 VALUES(%s, %s, %s, NOW())", self.id, action, user_id)
152
153 @property
154 def data(self):
155 if self._data is None:
156 self._data = \
157 self.db.get("SELECT * FROM mirrors WHERE id = %s", self.id)
158
159 return self._data
160
161 def set_status(self, status, user=None):
162 assert status in ("enabled", "disabled", "deleted")
163
164 if self.status == status:
165 return
166
167 self.db.execute("UPDATE mirrors SET status = %s WHERE id = %s",
168 status, self.id)
169
170 if self._data:
171 self._data["status"] = status
172
173 # Log the status change.
174 self.log(status, user=user)
175
176 def set_hostname(self, hostname):
177 if self.hostname == hostname:
178 return
179
180 self.db.execute("UPDATE mirrors SET hostname = %s WHERE id = %s",
181 hostname, self.id)
182
183 if self._data:
184 self._data["hostname"] = hostname
185
186 hostname = property(lambda self: self.data.hostname, set_hostname)
187
188 @property
189 def path(self):
190 return self.data.path
191
192 def set_path(self, path):
193 if self.path == path:
194 return
195
196 self.db.execute("UPDATE mirrors SET path = %s WHERE id = %s",
197 path, self.id)
198
199 if self._data:
200 self._data["path"] = path
201
202 path = property(lambda self: self.data.path, set_path)
203
204 @property
205 def url(self):
206 ret = "http://%s" % self.hostname
207
208 if self.path:
209 path = self.path
210
211 if not self.path.startswith("/"):
212 path = "/%s" % path
213
214 if self.path.endswith("/"):
215 path = path[:-1]
216
217 ret += path
218
219 return ret
220
221 def set_owner(self, owner):
222 if self.owner == owner:
223 return
224
225 self.db.execute("UPDATE mirrors SET owner = %s WHERE id = %s",
226 owner, self.id)
227
228 if self._data:
229 self._data["owner"] = owner
230
231 owner = property(lambda self: self.data.owner or "", set_owner)
232
233 def set_contact(self, contact):
234 if self.contact == contact:
235 return
236
237 self.db.execute("UPDATE mirrors SET contact = %s WHERE id = %s",
238 contact, self.id)
239
240 if self._data:
241 self._data["contact"] = contact
242
243 contact = property(lambda self: self.data.contact or "", set_contact)
244
245 @property
246 def status(self):
247 return self.data.status
248
249 @property
250 def enabled(self):
251 return self.status == "enabled"
252
253 @property
254 def check_status(self):
255 return self.data.check_status
256
257 @property
258 def last_check(self):
259 return self.data.last_check
260
261 @property
262 def address(self):
263 return socket.gethostbyname(self.hostname)
264
d3e7a9fb 265 @lazy_property
f6e6ff79 266 def country_code(self):
d3e7a9fb 267 return self.backend.geoip.guess_from_address(self.address) or "UNKNOWN"
f6e6ff79
MT
268
269 def get_history(self, *args, **kwargs):
270 kwargs["mirror"] = self
271
272 return self.pakfire.mirrors.get_history(*args, **kwargs)