]> git.ipfire.org Git - ipfire.org.git/blame - www/webapp/backend/mirrors.py
Remove old screenshots.
[ipfire.org.git] / www / webapp / backend / mirrors.py
CommitLineData
940227cb
MT
1#!/usr/bin/python
2
3import logging
4import socket
5import time
6import tornado.httpclient
7
8from databases import Databases
9from geoip import GeoIP
10from misc import Singleton
11
12class Mirrors(object):
13 __metaclass__ = Singleton
14
15 @property
16 def db(self):
17 return Databases().webapp
18
19 def list(self):
20 return [Mirror(m.id) for m in self.db.query("SELECT id FROM mirrors ORDER BY state")]
21
22 def check_all(self):
23 for mirror in self.list():
24 mirror.check()
25
26 def get(self, id):
27 return Mirror( id)
28
29 def get_by_hostname(self, hostname):
30 mirror = self.db.get("SELECT id FROM mirrors WHERE hostname=%s", hostname)
31
32 return Mirror(mirror.id)
33
34 def get_with_file(self, filename):
35 return [Mirror(m.mirror) for m in \
36 self.db.query("SELECT mirror FROM mirror_files WHERE filename=%s", filename)]
37
38
39class Mirror(object):
40 def __init__(self, id):
41 self.id = id
42
43 self.reload()
44
45 @property
46 def db(self):
47 return Databases().webapp
48
49 def reload(self):
50 self._info = self.db.get("SELECT * FROM mirrors WHERE id=%s", self.id)
51 self._info["url"] = self.generate_url()
52
53 def generate_url(self):
54 url = "http://%s" % self.hostname
55 if not self.path.startswith("/"):
56 url += "/"
57 url += "%s" % self.path
58 if not self.path.endswith("/"):
59 url += "/"
60 return url
61
62 def __getattr__(self, key):
63 try:
64 return self._info[key]
65 except KeyError:
66 raise AttributeError(key)
67
68 @property
69 def address(self):
70 return socket.gethostbyname(self.hostname)
71
72 @property
73 def country_code(self):
74 return GeoIP().get_country(self.address).lower() or "unknown"
75
76 @property
77 def filelist(self):
78 filelist = self.db.query("SELECT filename FROM mirror_files WHERE mirror=%s ORDER BY filename", self.id)
79 return [f.filename for f in filelist]
80
81 def set_state(self, state):
82 logging.info("Setting state of %s to %s" % (self.hostname, state))
83
84 if self.state == state:
85 return
86
87 self.db.execute("UPDATE mirrors SET state=%s WHERE id=%s",
88 state, self.id)
89
90 # Reload changed settings
91 self.reload()
92
93 def check(self):
94 logging.info("Running check for mirror %s" % self.hostname)
95
96 self.check_timestamp()
97 self.check_filelist()
98
99 def check_state(self):
100 logging.debug("Checking state of mirror %s" % self.id)
101
102 if self.disabled == "Y":
103 self.set_state("DOWN")
104
105 time_diff = time.time() - self.last_update
106 if time_diff > 3*24*60*60: # XXX get this into Settings
107 self.set_state("DOWN")
108 elif time_diff > 6*60*60:
109 self.set_state("OUTOFSYNC")
110 else:
111 self.set_state("UP")
112
113 def check_timestamp(self):
114 if self.releases == "N":
115 return
116
117 http = tornado.httpclient.AsyncHTTPClient()
118
119 http.fetch(self.url + ".timestamp",
120 headers={"Pragma" : "no-cache", },
121 callback=self.__check_timestamp_response)
122
123 def __check_timestamp_response(self, response):
124 if response.error:
125 logging.debug("Error getting timestamp from %s" % self.hostname)
126 return
127
128 try:
129 timestamp = int(response.body.strip())
130 except ValueError:
131 timestamp = 0
132
133 self.db.execute("UPDATE mirrors SET last_update=%s WHERE id=%s",
134 timestamp, self.id)
135
136 # Reload changed settings
137 self.reload()
138
139 self.check_state()
140
141 logging.info("Successfully updated timestamp from %s" % self.hostname)
142
143 def check_filelist(self):
144 if self.releases == "N":
145 return
146
147 http = tornado.httpclient.AsyncHTTPClient()
148
149 http.fetch(self.url + ".filelist",
150 headers={"Pragma" : "no-cache", },
151 callback=self.__check_filelist_response)
152
153 def __check_filelist_response(self, response):
154 if response.error:
155 logging.debug("Error getting timestamp from %s" % self.hostname)
156 return
157
158 self.db.execute("DELETE FROM mirror_files WHERE mirror=%s", self.id)
159
160 for file in response.body.splitlines():
161 self.db.execute("INSERT INTO mirror_files(mirror, filename) VALUES(%s, %s)",
162 self.id, file)
163
164 logging.info("Successfully updated mirror filelist from %s" % self.hostname)
165
166
167if __name__ == "__main__":
168 m = Mirrors()
169
170 for mirror in m.list():
171 print mirror.hostname, mirror.country_code