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