Package entropy :: Package client :: Package services :: Package ugc :: Module interfaces

Source Code for Module entropy.client.services.ugc.interfaces

  1  # -*- coding: utf-8 -*- 
  2  """ 
  3   
  4      @author: Fabio Erculiani <lxnay@sabayonlinux.org> 
  5      @contact: lxnay@sabayonlinux.org 
  6      @copyright: Fabio Erculiani 
  7      @license: GPL-2 
  8   
  9      B{Entropy Client Services UGC Base Interfaces}. 
 10   
 11  """ 
 12   
 13  from __future__ import with_statement 
 14  import os 
 15  from entropy.core import Singleton 
 16  from entropy.exceptions import * 
 17  from entropy.const import etpConst, etpCache, const_setup_file, const_setup_perms 
 18  from entropy.i18n import _ 
 19   
20 -class Client:
21 22 ssl_connection = True
23 - def __init__(self, EquoInstance, quiet = True, show_progress = False):
24 25 from entropy.client.interfaces import Client as Cl 26 if not isinstance(EquoInstance,Cl): 27 mytxt = _("A valid Client based instance is needed") 28 raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,)) 29 30 import socket, threading 31 self.socket, self.threading = socket, threading 32 import struct 33 self.struct = struct 34 self.Entropy = EquoInstance 35 self.store = AuthStore() 36 self.quiet = quiet 37 self.show_progress = show_progress 38 self.UGCCache = Cache(self) 39 self.TxLocks = {}
40
41 - def connect_to_service(self, repository, timeout = None):
42 if repository not in self.Entropy.SystemSettings['repositories']['available']: 43 raise RepositoryError("RepositoryError: %s" % (_('repository is not available'),)) 44 45 try: 46 url = self.Entropy.SystemSettings['repositories']['available'][repository]['plain_database'].split("/")[2] 47 port = self.Entropy.SystemSettings['repositories']['available'][repository]['service_port'] 48 if self.ssl_connection: port = self.Entropy.SystemSettings['repositories']['available'][repository]['ssl_service_port'] 49 except (IndexError,KeyError,): 50 raise RepositoryError("RepositoryError: %s" % (_('repository metadata is malformed'),)) 51 52 from entropy.services.ugc.interfaces import Client 53 from entropy.client.services.ugc.commands import Client as CommandsClient 54 args = [self.Entropy, CommandsClient] 55 kwargs = { 56 'ssl': self.ssl_connection, 57 'quiet': self.quiet, 58 'show_progress': self.show_progress 59 } 60 if timeout != None: kwargs['socket_timeout'] = timeout 61 srv = Client(*args,**kwargs) 62 srv.connect(url, port) 63 return srv
64
65 - def get_service_connection(self, repository, check = True, timeout = None):
66 if check: 67 if not self.is_repository_eapi3_aware(repository): 68 return None 69 try: 70 srv = self.connect_to_service(repository, timeout = timeout) 71 except (RepositoryError,ConnectionError,): 72 return None 73 except (self.socket.error,self.struct.error,): 74 return None 75 return srv
76
77 - def is_repository_eapi3_aware(self, repository):
78 79 aware = self.UGCCache._get_live_cache_item(repository, 'is_repository_eapi3_aware') 80 if aware != None: 81 return aware 82 83 srv = self.get_service_connection(repository, check = False, timeout = 3) 84 if srv == None: 85 aware = False 86 else: 87 session = srv.open_session() 88 if session != None: 89 srv.close_session(session) 90 srv.disconnect() 91 aware = True 92 else: 93 aware = False 94 95 self.UGCCache._set_live_cache_item(repository, 'is_repository_eapi3_aware', aware) 96 return aware
97
98 - def read_login(self, repository):
99 return self.store.read_login(repository)
100
101 - def remove_login(self, repository):
102 return self.store.remove_login(repository)
103
104 - def do_login(self, repository, force = False):
105 106 login_data = self.read_login(repository) 107 if (login_data != None) and not force: 108 return True,_('ok') 109 110 aware = self.is_repository_eapi3_aware(repository) 111 if not aware: 112 return False,_('repository does not support EAPI3') 113 114 def fake_callback(*args,**kwargs): 115 return True
116 117 attempts = 3 118 while attempts: 119 120 # use input box to read login 121 input_params = [ 122 ('username',_('Username'),fake_callback,False), 123 ('password',_('Password'),fake_callback,True) 124 ] 125 login_data = self.Entropy.inputBox( 126 "%s %s %s" % (_('Please login against'),repository,_('repository'),), 127 input_params, 128 cancel_button = True 129 ) 130 if not login_data: 131 return False,_('login abort') 132 133 # now verify 134 srv = self.get_service_connection(repository) 135 if srv == None: 136 return False,_('connection issues') 137 session = srv.open_session() 138 login_status, login_msg = srv.CmdInterface.service_login(login_data['username'], login_data['password'], session) 139 if not login_status: 140 srv.close_session(session) 141 srv.disconnect() 142 self.Entropy.askQuestion("%s: %s" % (_("Access denied. Login failed"),login_msg,), responses = ["Ok"]) 143 attempts -= 1 144 continue 145 146 # login accepted, store it? 147 srv.close_session(session) 148 srv.disconnect() 149 rc = self.Entropy.askQuestion(_("Login successful. Do you want to save these credentials ?")) 150 save = False 151 if rc == "Yes": save = True 152 self.store.store_login(login_data['username'], login_data['password'], repository, save = save) 153 return True,_('ok')
154 155
156 - def login(self, repository, force = False):
157 158 if not self.TxLocks.has_key(repository): 159 self.TxLocks[repository] = self.threading.Lock() 160 161 with self.TxLocks[repository]: 162 return self.do_login(repository, force = force)
163 164
165 - def logout(self, repository):
166 return self.store.remove_login(repository)
167
168 - def do_cmd(self, repository, login_required, func, args, kwargs):
169 170 if not self.TxLocks.has_key(repository): 171 self.TxLocks[repository] = self.threading.Lock() 172 173 with self.TxLocks[repository]: 174 175 if login_required: 176 status, err_msg = self.do_login(repository) 177 if not status: 178 return False,err_msg 179 180 srv = self.get_service_connection(repository) 181 if srv == None: 182 return False,'no connection' 183 session = srv.open_session() 184 if session == None: 185 return False,'no session' 186 args.insert(0,session) 187 188 if login_required: 189 stored_pass = False 190 while 1: 191 # login 192 login_data = self.read_login(repository) 193 if login_data == None: 194 status, msg = self.login(repository) 195 if not status: return status, msg 196 username, password = self.read_login(repository) 197 else: 198 stored_pass = True 199 username, password = login_data 200 logged, error = srv.CmdInterface.service_login(username, password, session) 201 if not logged: 202 if stored_pass: 203 stored_pass = False 204 self.remove_login(repository) 205 continue 206 srv.close_session(session) 207 srv.disconnect() 208 return logged, error 209 break 210 211 try: 212 cmd_func = getattr(srv.CmdInterface, func) 213 except AttributeError: 214 return False, 'local function not available' 215 rslt = cmd_func(*args,**kwargs) 216 try: 217 srv.close_session(session) 218 srv.disconnect() 219 except ConnectionError: 220 return False, 'no connection' 221 222 return rslt
223
224 - def get_comments(self, repository, pkgkey):
225 return self.do_cmd(repository, False, "ugc_get_textdocs", [pkgkey], {})
226
227 - def get_comments_by_identifiers(self, repository, identifiers):
228 return self.do_cmd(repository, False, "ugc_get_textdocs_by_identifiers", [identifiers], {})
229
230 - def get_documents_by_identifiers(self, repository, identifiers):
231 return self.do_cmd(repository, False, "ugc_get_documents_by_identifiers", [identifiers], {})
232
233 - def add_comment(self, repository, pkgkey, comment, title, keywords):
234 self.UGCCache.clear_alldocs_cache(repository) 235 return self.do_cmd(repository, True, "ugc_add_comment", [pkgkey, comment, title, keywords], {})
236
237 - def edit_comment(self, repository, iddoc, new_comment, new_title, new_keywords):
238 self.UGCCache.clear_alldocs_cache(repository) 239 return self.do_cmd(repository, True, "ugc_edit_comment", [iddoc, new_comment, new_title, new_keywords], {})
240
241 - def remove_comment(self, repository, iddoc):
242 self.UGCCache.clear_alldocs_cache(repository) 243 return self.do_cmd(repository, True, "ugc_remove_comment", [iddoc], {})
244
245 - def add_vote(self, repository, pkgkey, vote):
246 data = self.do_cmd(repository, True, "ugc_do_vote", [pkgkey, vote], {}) 247 if isinstance(data,tuple): voted, add_err_msg = data 248 else: return False,'wrong server answer' 249 if voted: self.get_vote(repository, pkgkey) 250 return voted, add_err_msg
251
252 - def get_vote(self, repository, pkgkey):
253 vote, err_msg = self.do_cmd(repository, False, "ugc_get_vote", [pkgkey], {}) 254 if isinstance(vote,float): 255 mydict = {pkgkey: vote} 256 self.UGCCache.update_vote_cache(repository, mydict) 257 return vote, err_msg
258
259 - def get_all_votes(self, repository):
260 votes_dict, err_msg = self.do_cmd(repository, False, "ugc_get_allvotes", [], {}) 261 if isinstance(votes_dict,dict): 262 self.UGCCache.update_vote_cache(repository, votes_dict) 263 return votes_dict, err_msg
264
265 - def add_downloads(self, repository, pkgkeys):
266 return self.do_cmd(repository, False, "ugc_do_downloads", [pkgkeys], {})
267
268 - def get_downloads(self, repository, pkgkey):
269 data = self.do_cmd(repository, False, "ugc_get_downloads", [pkgkey], {}) 270 if isinstance(data,tuple): downloads, err_msg = data 271 else: return False,'wrong server answer' 272 if downloads: 273 mydict = {pkgkey: downloads} 274 self.UGCCache.update_downloads_cache(repository, mydict) 275 return downloads, err_msg
276
277 - def get_all_downloads(self, repository):
278 down_dict, err_msg = self.do_cmd(repository, False, "ugc_get_alldownloads", [], {}) 279 if isinstance(down_dict,dict): 280 self.UGCCache.update_downloads_cache(repository, down_dict) 281 return down_dict, err_msg
282
283 - def add_download_stats(self, repository, pkgkeys):
284 return self.do_cmd(repository, False, "ugc_do_download_stats", [pkgkeys], {})
285
286 - def send_file(self, repository, pkgkey, file_path, title, description, keywords):
287 self.UGCCache.clear_alldocs_cache(repository) 288 return self.do_cmd(repository, True, "ugc_send_file", [pkgkey, file_path, etpConst['ugc_doctypes']['generic_file'], title, description, keywords], {})
289
290 - def remove_file(self, repository, iddoc):
291 self.UGCCache.clear_alldocs_cache(repository) 292 return self.do_cmd(repository, True, "ugc_remove_file", [iddoc], {})
293
294 - def send_image(self, repository, pkgkey, image_path, title, description, keywords):
295 self.UGCCache.clear_alldocs_cache(repository) 296 return self.do_cmd(repository, True, "ugc_send_file", [pkgkey, image_path, etpConst['ugc_doctypes']['image'], title, description, keywords], {})
297
298 - def remove_image(self, repository, iddoc):
299 self.UGCCache.clear_alldocs_cache(repository) 300 return self.do_cmd(repository, True, "ugc_remove_image", [iddoc], {})
301
302 - def send_youtube_video(self, repository, pkgkey, video_path, title, description, keywords):
303 self.UGCCache.clear_alldocs_cache(repository) 304 return self.do_cmd(repository, True, "ugc_send_file", [pkgkey, video_path, etpConst['ugc_doctypes']['youtube_video'], title, description, keywords], {})
305
306 - def remove_youtube_video(self, repository, iddoc):
307 self.UGCCache.clear_alldocs_cache(repository) 308 return self.do_cmd(repository, True, "ugc_remove_youtube_video", [iddoc], {})
309
310 - def get_docs(self, repository, pkgkey):
311 data = self.do_cmd(repository, False, "ugc_get_docs", [pkgkey], {}) 312 if isinstance(data,tuple): docs_data, err_msg = data 313 else: return False,'wrong server answer' 314 if err_msg == 'ok': 315 self.UGCCache.update_alldocs_cache(pkgkey, repository, docs_data) 316 return docs_data, err_msg
317
318 - def send_document_autosense(self, repository, pkgkey, ugc_type, data, title, description, keywords):
319 if ugc_type == etpConst['ugc_doctypes']['generic_file']: 320 return self.send_file(repository, pkgkey, data, title, description, keywords) 321 elif ugc_type == etpConst['ugc_doctypes']['image']: 322 return self.send_image(repository, pkgkey, data, title, description, keywords) 323 elif ugc_type == etpConst['ugc_doctypes']['youtube_video']: 324 return self.send_youtube_video(repository, pkgkey, data, title, description, keywords) 325 elif ugc_type == etpConst['ugc_doctypes']['comments']: 326 return self.add_comment(repository, pkgkey, description, title, keywords) 327 return None,'type not supported locally'
328
329 - def remove_document_autosense(self, repository, iddoc, ugc_type):
330 if ugc_type == etpConst['ugc_doctypes']['generic_file']: 331 return self.remove_file(repository, iddoc) 332 elif ugc_type == etpConst['ugc_doctypes']['image']: 333 return self.remove_image(repository, iddoc) 334 elif ugc_type == etpConst['ugc_doctypes']['youtube_video']: 335 return self.remove_youtube_video(repository, iddoc) 336 elif ugc_type == etpConst['ugc_doctypes']['comments']: 337 return self.remove_comment(repository, iddoc) 338 return None,'type not supported locally'
339
340 - def report_error(self, repository, error_data):
341 return self.do_cmd(repository, False, "report_error", [error_data], {})
342 343
344 -class AuthStore(Singleton):
345 346 access_file = etpConst['ugc_accessfile']
347 - def init_singleton(self):
348 349 from xml.dom import minidom 350 from xml.parsers import expat 351 self.expat = expat 352 self.minidom = minidom 353 self.setup_store_paths() 354 try: 355 self.setup_permissions() 356 except IOError: 357 pass 358 self.store = {} 359 try: 360 self.xmldoc = self.minidom.parse(self.access_file) 361 except (self.expat.ExpatError,IOError,): 362 self.xmldoc = None 363 if self.xmldoc != None: 364 try: 365 self.parse_document() 366 except self.expat.ExpatError: 367 self.xmldoc = None 368 self.store = {}
369
370 - def setup_store_paths(self):
371 myhome = os.getenv("HOME") 372 if myhome != None: 373 if os.path.isdir(myhome) and os.access(myhome,os.W_OK): 374 self.access_file = os.path.join(myhome,".config/entropy", 375 os.path.basename(self.access_file)) 376 self.access_dir = os.path.dirname(self.access_file)
377
378 - def setup_permissions(self):
379 if not os.path.isdir(self.access_dir): 380 os.makedirs(self.access_dir) 381 if not os.path.isfile(self.access_file): 382 f = open(self.access_file, "w") 383 f.close() 384 gid = etpConst['entropygid'] 385 if gid is None: 386 gid = 0 387 388 try: 389 const_setup_file(self.access_dir, gid, 0700) 390 except OSError: 391 pass 392 try: 393 const_setup_file(self.access_file, gid, 0600) 394 except OSError: 395 pass
396
397 - def parse_document(self):
398 self.store.clear() 399 store = self.xmldoc.getElementsByTagName("store")[0] 400 repositories = store.getElementsByTagName("repository") 401 for repository in repositories: 402 repoid = repository.getAttribute("id") 403 if not repoid: continue 404 username = repository.getElementsByTagName("username")[0].firstChild.data.strip() 405 password = repository.getElementsByTagName("password")[0].firstChild.data.strip() 406 self.store[repoid] = {'username': username, 'password': password}
407
408 - def store_login(self, username, password, repository, save = True):
409 self.store[repository] = {'username': username, 'password': password} 410 if save: 411 self.save_store()
412
413 - def save_store(self):
414 415 self.xmldoc = self.minidom.Document() 416 store = self.xmldoc.createElement("store") 417 418 for repository in self.store: 419 repo = self.xmldoc.createElement("repository") 420 repo.setAttribute('id',repository) 421 # username 422 username = self.xmldoc.createElement("username") 423 username_value = self.xmldoc.createTextNode(self.store[repository]['username']) 424 username.appendChild(username_value) 425 repo.appendChild(username) 426 # password 427 password = self.xmldoc.createElement("password") 428 password_value = self.xmldoc.createTextNode(self.store[repository]['password']) 429 password.appendChild(password_value) 430 repo.appendChild(password) 431 store.appendChild(repo) 432 433 self.xmldoc.appendChild(store) 434 f = open(self.access_file,"w") 435 f.writelines(self.xmldoc.toprettyxml(indent=" ")) 436 f.flush() 437 f.close() 438 self.setup_permissions() 439 self.parse_document()
440
441 - def remove_login(self, repository, save = True):
442 if repository in self.store: 443 del self.store[repository] 444 if save: 445 self.save_store()
446
447 - def read_login(self, repository):
448 if repository in self.store: 449 return self.store[repository]['username'],self.store[repository]['password']
450
451 -class Cache:
452
453 - def __init__(self, UGCClientInstance):
454 455 if not isinstance(UGCClientInstance,Client): 456 mytxt = _("A valid UGC Client interface based instance is needed") 457 raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,)) 458 459 import threading 460 import entropy.dump as dumpTools 461 self.CacheLock = threading.Lock() 462 self.dumpTools = dumpTools 463 self.Service = UGCClientInstance 464 self.xcache = {}
465
466 - def _get_live_cache_item(self, repository, item):
467 if repository not in self.xcache: 468 return None 469 return self.xcache[repository].get(item)
470
471 - def _set_live_cache_item(self, repository, item, obj):
472 if repository not in self.xcache: 473 self.xcache[repository] = {} 474 if type(obj) in (list,tuple,): 475 my_obj = obj[:] 476 elif type(obj) in (set,frozenset,dict,): 477 my_obj = obj.copy() 478 else: 479 my_obj = obj 480 self.xcache[repository][item] = my_obj
481
482 - def _clear_live_cache_item(self, repository, item):
483 if not self.xcache.has_key(repository): 484 return 485 if not self.xcache[repository].has_key(item): 486 return 487 del self.xcache[repository][item]
488
489 - def _get_store_cache_file(self, iddoc, repository, doc_url):
490 return "%s/%s/iddoc_%s/%s" % (etpCache['ugc_docs'], repository, iddoc, doc_url,)
491
492 - def _get_vote_cache_file(self, repository):
493 return self._get_vote_cache_dir(repository)
494
495 - def _get_downloads_cache_file(self, repository):
496 return self._get_downloads_cache_dir(repository)
497
498 - def _get_alldocs_cache_file(self, pkgkey, repository):
499 return self._get_alldocs_cache_dir(repository)+"/"+pkgkey
500
501 - def _get_alldocs_cache_dir(self, repository):
502 return etpCache['ugc_docs']+"/"+repository
503
504 - def _get_downloads_cache_dir(self, repository):
505 return etpCache['ugc_downloads']+"/"+repository
506
507 - def _get_vote_cache_dir(self, repository):
508 return etpCache['ugc_votes']+"/"+repository
509
510 - def _get_vote_cache_key(self, repository):
511 return 'get_vote_cache_'+repository
512
513 - def _get_downloads_cache_key(self, repository):
514 return 'get_downloads_cache_'+repository
515
516 - def _get_alldocs_cache_key(self, repository):
517 return 'get_package_alldocs_cache_'+repository
518
519 - def store_document(self, iddoc, repository, doc_url):
520 cache_file = os.path.join(etpConst['dumpstoragedir'],self._get_store_cache_file(iddoc, repository, doc_url)) 521 cache_dir = os.path.dirname(cache_file) 522 523 try: 524 if not os.path.isdir(cache_dir): 525 os.makedirs(cache_dir,0775) 526 if etpConst['entropygid'] != None: 527 const_setup_perms(cache_dir,etpConst['entropygid']) 528 except OSError: 529 raise PermissionDenied("PermissionDenied: %s %s" % (_("Cannot setup cache directory"),cache_dir,)) 530 if not os.access(cache_dir,os.W_OK): 531 raise PermissionDenied("PermissionDenied: %s %s" % (_("Cannot write to cache directory"),cache_dir,)) 532 533 if os.path.isfile(cache_file) or os.path.islink(cache_file): 534 try: 535 os.remove(cache_file) 536 except OSError: 537 raise PermissionDenied("PermissionDenied: %s %s" % (_("Cannot remove cache file"),cache_file,)) 538 539 fetcher = self.Service.Entropy.urlFetcher(doc_url, cache_file, resume = False) 540 rc = fetcher.download() 541 if rc in ("-1","-2","-3","-4"): return None 542 if not os.path.isfile(cache_file): return None 543 544 try: 545 os.chmod(cache_file,0664) 546 if etpConst['entropygid'] != None: 547 os.chown(cache_file,-1,etpConst['entropygid']) 548 except OSError: 549 raise PermissionDenied("PermissionDenied: %s %s" % (_("Cannot write to cache file"),cache_file,)) 550 551 del fetcher 552 return cache_file
553
554 - def get_stored_document(self, iddoc, repository, doc_url):
555 cache_file = os.path.join(etpConst['dumpstoragedir'],self._get_store_cache_file(iddoc, repository, doc_url)) 556 if os.path.isfile(cache_file) and os.access(cache_file,os.R_OK): 557 return cache_file
558
559 - def update_vote_cache(self, repository, vote_dict):
560 cached = self.get_vote_cache(repository) 561 if cached == None: 562 cached = vote_dict.copy() 563 else: 564 cached.update(vote_dict) 565 self.save_vote_cache(repository,cached)
566
567 - def update_downloads_cache(self, repository, down_dict):
568 cached = self.get_downloads_cache(repository) 569 if cached == None: 570 cached = down_dict.copy() 571 else: 572 cached.update(down_dict) 573 self.save_downloads_cache(repository,cached)
574
575 - def update_alldocs_cache(self, pkgkey, repository, alldocs_dict):
576 self.save_alldocs_cache(pkgkey, repository, alldocs_dict)
577
578 - def clear_alldocs_cache(self, repository):
579 with self.CacheLock: 580 self.Service.Entropy.clear_dump_cache(self._get_alldocs_cache_dir(repository)) 581 self._clear_live_cache_item(repository, self._get_alldocs_cache_key(repository))
582
583 - def clear_downloads_cache(self, repository):
584 with self.CacheLock: 585 self.Service.Entropy.clear_dump_cache(self._get_alldocs_cache_dir(repository)) 586 self._clear_live_cache_item(repository, self._get_downloads_cache_key(repository))
587
588 - def clear_vote_cache(self, repository):
589 with self.CacheLock: 590 self.Service.Entropy.clear_dump_cache(self._get_vote_cache_dir(repository)) 591 self._clear_live_cache_item(repository, self._get_vote_cache_key(repository))
592
593 - def clear_cache(self, repository):
598
599 - def get_vote_cache(self, repository):
600 cache_key = self._get_vote_cache_key(repository) 601 cached = self._get_live_cache_item(repository, cache_key) 602 if cached != None: 603 return cached 604 with self.CacheLock: 605 cache_file = self._get_vote_cache_file(repository) 606 try: 607 data = self.dumpTools.loadobj(cache_file) 608 if data != None: 609 self._set_live_cache_item(repository, cache_key, data) 610 except (IOError,EOFError,OSError): 611 data = None 612 return data
613
614 - def get_downloads_cache(self, repository):
615 cache_key = self._get_downloads_cache_key(repository) 616 cached = self._get_live_cache_item(repository, cache_key) 617 if cached != None: 618 return cached 619 with self.CacheLock: 620 cache_file = self._get_downloads_cache_file(repository) 621 try: 622 data = self.dumpTools.loadobj(cache_file) 623 if data != None: 624 self._set_live_cache_item(repository, cache_key, data) 625 except (IOError,EOFError,OSError): 626 data = None 627 return data
628
629 - def get_alldocs_cache(self, pkgkey, repository):
630 cache_key = self._get_alldocs_cache_key(repository) 631 cached = self._get_live_cache_item(repository, cache_key) 632 if isinstance(cached,dict): 633 if cached.has_key(pkgkey): return cached[pkgkey] 634 else: 635 cached = {} 636 with self.CacheLock: 637 cache_file = self._get_alldocs_cache_file(pkgkey, repository) 638 try: 639 data = self.dumpTools.loadobj(cache_file) 640 if data != None: 641 cached[pkgkey] = data 642 self._set_live_cache_item(repository, cache_key, cached) 643 except (IOError,EOFError,OSError): 644 data = None 645 return data
646
647 - def save_vote_cache(self, repository, vote_dict):
648 with self.CacheLock: 649 self._clear_live_cache_item(repository, self._get_vote_cache_key(repository)) 650 self.dumpTools.dumpobj(self._get_vote_cache_file(repository), vote_dict)
651
652 - def save_downloads_cache(self, repository, down_dict):
653 with self.CacheLock: 654 self._clear_live_cache_item(repository, self._get_downloads_cache_key(repository)) 655 self.dumpTools.dumpobj(self._get_downloads_cache_file(repository), down_dict)
656
657 - def save_alldocs_cache(self, pkgkey, repository, alldocs_dict):
658 with self.CacheLock: 659 self._clear_live_cache_item(repository, self._get_alldocs_cache_key(repository)) 660 self.dumpTools.dumpobj(self._get_alldocs_cache_file(pkgkey, repository), alldocs_dict)
661
662 - def get_package_vote(self, repository, pkgkey):
663 cache = self.get_vote_cache(repository) 664 if not cache: 665 return 0.0 666 elif not isinstance(cache,dict): 667 return 0.0 668 elif not cache.has_key(pkgkey): 669 return 0.0 670 return cache[pkgkey]
671
672 - def get_package_downloads(self, repository, pkgkey):
673 cache = self.get_downloads_cache(repository) 674 if not cache: 675 return 0 676 elif not isinstance(cache,dict): 677 return 0 678 elif not cache.has_key(pkgkey): 679 return 0 680 try: 681 return int(cache[pkgkey]) 682 except ValueError: 683 return 0
684