fix bug in conditional
[popcorn.git] / popcorn-client
blobe5b9b96b41d8a0f85e1903de813b9a9c8a8da7ae
1 #!/usr/bin/python
3 # Copyright (c) 2009 Pavol Rusnak <stick@gk2.sk>
5 # Permission is hereby granted, free of charge, to any person
6 # obtaining a copy of this software and associated documentation
7 # files (the "Software"), to deal in the Software without
8 # restriction, including without limitation the rights to use,
9 # copy, modify, merge, publish, distribute, sublicense, and/or sell
10 # copies of the Software, and to permit persons to whom the
11 # Software is furnished to do so, subject to the following
12 # conditions:
14 # The above copyright notice and this permission notice shall be
15 # included in all copies or substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 # OTHER DEALINGS IN THE SOFTWARE.
26 import os
27 import re
28 import rpm
29 import platform
30 import httplib
31 import smtplib
32 import time
34 version = '0.1'
35 popcorn_post_server = 'stats.opensuse.org'
36 popcorn_post_uri = '/popcorn'
37 popcorn_email = 'popcorn@stats.opensuse.org'
39 days_recent = 30
40 days_voted = 30
42 pathre = '^/(bin|boot|lib|lib64|opt/gnome/bin|opt/gnome/sbin|opt/kde3/bin|opt/kde3/sbin|sbin|usr/bin|usr/games|usr/include|usr/lib|usr/lib64|usr/libexec|usr/sbin|usr/share)/'
44 system_mounts = ['binfmt_misc', 'debugfs', 'devpts', 'fuse.gvfs-fuse-daemon', 'fusectl', 'nfs', 'nfs4', 'proc', 'rootfs', 'rpc_pipefs', 'securityfs', 'sysfs']
46 class Statistics:
47 arch = platform.machine()
48 packages = []
50 def fill_packages(self):
51 pathreprg = re.compile(pathre)
52 now = int(time.time())
54 # detect mountpoints that are atime and noatime/relatime
55 atime_mounts = []
56 noatime_mounts = []
57 try:
58 f = open('/proc/mounts', 'r')
59 for line in f:
60 mount = line.split(' ', 4)
61 if not mount[2] in system_mounts:
62 if mount[3].find('noatime') < 0 and mount[3].find('relatime') < 0:
63 atime_mounts.append(mount[1])
64 else:
65 noatime_mounts.append(mount[1])
66 f.close()
67 except:
68 pass
70 ts = rpm.TransactionSet()
71 mi = ts.dbMatch()
72 for h in mi:
73 name = h[rpm.RPMTAG_NAME]
74 if name == 'gpg-pubkey': continue
75 installed = h[rpm.RPMTAG_INSTALLTIME]
76 (accessed, atime) = (0, 0)
77 if len(atime_mounts) > 0:
78 for file in h[rpm.RPMTAG_FILENAMES]:
79 # skip non-watched files
80 if not pathreprg.match(file): continue
81 # if the file is mounted from noatime/relatime mountpoint, skip it
82 if len( [i for i in noatime_mounts if file.startswith(i)] ) > 0 and \
83 len( [i for i in atime_mounts if file.startswith(i)] ) <= 0: continue
84 try:
85 (atime, ) = os.stat(file)[7:8]
86 if atime > accessed:
87 accessed = atime
88 except:
89 pass
90 if accessed == 0:
91 cat = 'n' # no-files
92 else:
93 if now - installed < days_recent * 86400:
94 cat = 'r' # recent
95 else:
96 if now - accessed < days_voted * 86400:
97 cat = 'v' # voted
98 else:
99 cat ='o' # old
100 self.packages.append( (cat, name) )
102 def serialize(self):
103 ret = ''
104 ret += 'POPCORN %s %s\n' % (version, self.arch)
105 for pkg in self.packages:
106 ret += '%s %s\n' % pkg
107 return ret
109 class Client:
110 def __init__(self):
111 stats = Statistics()
112 stats.fill_packages()
113 self.data = stats.serialize()
115 def post(self, compress = False):
116 conn = httplib.HTTPConnection(popcorn_uri_server)
117 conn.putrequest('POST', popcorn_post_uri)
118 conn.putheader('content-type', 'text/plain')
119 conn.putheader('content-length', str(len(self.data)))
120 conn.endheaders()
121 conn.send(self.data)
123 def email(self):
124 smtp = smtplib.SMTP()
125 smtp.sendmail('', popcorn_email, self.data)
126 smtp.quit()
128 def write(self):
129 print self.data,
131 client = Client()
132 # client.post()
133 # client.email()
134 client.write()