Package entropy :: Package client :: Package services :: Package ugc :: Module commands

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

  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.exceptions import * 
 26  from entropy.const import etpConst 
 27  from entropy.output import darkblue, bold, blue, darkgreen, darkred, brown 
 28  from entropy.i18n import _ 
 29  from entropy.core import SystemSettings 
 30   
31 -class Base:
32
33 - def __init__(self, OutputInterface, Service):
34 35 if not hasattr(OutputInterface,'updateProgress'): 36 mytxt = _("OutputInterface does not have an updateProgress method") 37 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,)) 38 elif not callable(OutputInterface.updateProgress): 39 mytxt = _("OutputInterface does not have an updateProgress method") 40 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,)) 41 42 from entropy.services.ugc.interfaces import Client as Cl 43 if not isinstance(Service, (Cl,)): 44 mytxt = _("A valid entropy.services.ugc.interfaces.Client based instance is needed") 45 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (Service,mytxt,)) 46 47 import socket, zlib, struct 48 import entropy.tools as entropyTools 49 import entropy.dump as dumpTools 50 self.entropyTools, self.socket, self.zlib, self.struct, self.dumpTools = entropyTools, socket, zlib, struct, dumpTools 51 self.Output = OutputInterface 52 self.Service = Service 53 self.output_header = '' 54 self.SystemSettings = SystemSettings()
55
56 - def handle_standard_answer(self, data, repository = None, arch = None, product = None):
57 do_skip = False 58 # elaborate answer 59 if data == None: 60 mytxt = _("feature not supported remotely") 61 self.Output.updateProgress( 62 "[%s:%s|%s:%s|%s:%s] %s" % ( 63 darkblue(_("repo")), 64 bold(str(repository)), 65 darkred(_("arch")), 66 bold(str(arch)), 67 darkgreen(_("product")), 68 bold(str(product)), 69 blue(mytxt), 70 ), 71 importance = 1, 72 type = "error", 73 header = self.output_header 74 ) 75 do_skip = True 76 elif not data: 77 mytxt = _("service temporarily not available") 78 self.Output.updateProgress( 79 "[%s:%s|%s:%s|%s:%s] %s" % ( 80 darkblue(_("repo")), 81 bold(str(repository)), 82 darkred(_("arch")), 83 bold(str(arch)), 84 darkgreen(_("product")), 85 bold(str(product)), 86 blue(mytxt), 87 ), 88 importance = 1, 89 type = "error", 90 header = self.output_header 91 ) 92 do_skip = True 93 elif data == self.Service.answers['no']: 94 # command failed 95 mytxt = _("command failed") 96 self.Output.updateProgress( 97 "[%s:%s|%s:%s|%s:%s] %s" % ( 98 darkblue(_("repo")), 99 bold(str(repository)), 100 darkred(_("arch")), 101 bold(str(arch)), 102 darkgreen(_("product")), 103 bold(str(product)), 104 blue(mytxt), 105 ), 106 importance = 1, 107 type = "error", 108 header = self.output_header 109 ) 110 elif data != self.Service.answers['ok']: 111 mytxt = _("received wrong answer") 112 self.Output.updateProgress( 113 "[%s:%s|%s:%s|%s:%s] %s: %s" % ( 114 darkblue(_("repo")), 115 bold(str(repository)), 116 darkred(_("arch")), 117 bold(str(arch)), 118 darkgreen(_("product")), 119 bold(str(product)), 120 blue(mytxt), 121 repr(data), 122 ), 123 importance = 1, 124 type = "error", 125 header = self.output_header 126 ) 127 do_skip = True 128 return do_skip
129
130 - def get_result(self, session):
131 # get the information 132 cmd = "%s rc" % (session,) 133 self.Service.transmit(cmd) 134 try: 135 data = self.Service.receive() 136 return data 137 except: 138 self.entropyTools.print_traceback() 139 return None
140
141 - def convert_stream_to_object(self, data, gzipped, repository = None, arch = None, product = None):
142 143 # unstream object 144 error = False 145 try: 146 data = self.Service.stream_to_object(data, gzipped) 147 except (EOFError,IOError,self.zlib.error,self.dumpTools.pickle.UnpicklingError,): 148 mytxt = _("cannot convert stream into object") 149 self.Output.updateProgress( 150 "[%s:%s|%s:%s|%s:%s] %s" % ( 151 darkblue(_("repo")), 152 bold(unicode(repository)), 153 darkred(_("arch")), 154 bold(unicode(arch)), 155 darkgreen(_("product")), 156 bold(unicode(product)), 157 blue(mytxt), 158 ), 159 importance = 1, 160 type = "error", 161 header = self.output_header 162 ) 163 data = None 164 error = True 165 return data, error
166
167 - def retrieve_command_answer(self, cmd, session_id, repository = None, arch = None, product = None, compression = False):
168 169 tries = 3 170 lasterr = None 171 while 1: 172 173 if tries <= 0: 174 return lasterr 175 tries -= 1 176 177 try: 178 # send command 179 self.Service.transmit(cmd) 180 except (SSLError,): 181 return None 182 # receive answer 183 data = self.Service.receive() 184 185 skip = self.handle_standard_answer(data, repository, arch, product) 186 if skip: 187 continue 188 189 data = self.get_result(session_id) 190 if data == None: 191 lasterr = None 192 continue 193 elif not data: 194 lasterr = False 195 continue 196 197 objdata, error = self.convert_stream_to_object(data, compression, repository, arch, product) 198 if not error: 199 return objdata
200
201 - def do_generic_handler(self, cmd, session_id, tries = 10, compression = False):
202 203 self.Service.check_socket_connection() 204 205 while 1: 206 try: 207 result = self.retrieve_command_answer(cmd, session_id, compression = compression) 208 if result == None: 209 return False,'command not supported' # untranslated on purpose 210 return result 211 except (self.socket.error,self.struct.error,): 212 self.Service.reconnect_socket() 213 tries -= 1 214 if tries < 1: 215 raise
216
217 - def set_gzip_compression(self, session, do):
218 self.Service.check_socket_connection() 219 cmd = "%s %s %s %s zlib" % (session, 'session_config', 'compression', do,) 220 self.Service.transmit(cmd) 221 data = self.Service.receive() 222 if data == self.Service.answers['ok']: 223 return True 224 return False
225
226 - def service_login(self, username, password, session_id):
227 228 cmd = "%s %s %s %s" % ( 229 session_id, 230 'login', 231 username, 232 password, 233 ) 234 return self.do_generic_handler(cmd, session_id)
235
236 - def service_logout(self, username, session_id):
237 238 cmd = "%s %s %s" % ( 239 session_id, 240 'logout', 241 username, 242 ) 243 return self.do_generic_handler(cmd, session_id)
244
245 - def get_logged_user_data(self, session_id):
246 247 cmd = "%s %s" % ( 248 session_id, 249 'user_data', 250 ) 251 return self.do_generic_handler(cmd, session_id)
252
253 - def is_user(self, session_id):
254 255 cmd = "%s %s" % ( 256 session_id, 257 'is_user', 258 ) 259 return self.do_generic_handler(cmd, session_id)
260
261 - def is_developer(self, session_id):
262 263 cmd = "%s %s" % ( 264 session_id, 265 'is_developer', 266 ) 267 return self.do_generic_handler(cmd, session_id)
268
269 - def is_moderator(self, session_id):
270 271 cmd = "%s %s" % ( 272 session_id, 273 'is_moderator', 274 ) 275 return self.do_generic_handler(cmd, session_id)
276
277 - def is_administrator(self, session_id):
278 279 cmd = "%s %s" % ( 280 session_id, 281 'is_administrator', 282 ) 283 return self.do_generic_handler(cmd, session_id)
284
285 - def available_commands(self, session_id):
286 287 cmd = "%s %s" % ( 288 session_id, 289 'available_commands', 290 ) 291 return self.do_generic_handler(cmd, session_id)
292 293
294 -class Client(Base):
295
296 - def __init__(self, EntropyInterface, ServiceInterface):
297 Base.__init__(self, EntropyInterface, ServiceInterface)
298
299 - def differential_packages_comparison(self, session_id, idpackages, repository, arch, product):
300 301 myidlist = ' '.join([str(x) for x in idpackages]) 302 cmd = "%s %s %s %s %s %s %s" % ( 303 session_id, 304 'repository_server:dbdiff', 305 repository, 306 arch, 307 product, 308 self.SystemSettings['repositories']['branch'], 309 myidlist, 310 ) 311 312 # enable zlib compression 313 compression = self.set_gzip_compression(session_id, True) 314 315 data = self.do_generic_handler(cmd, session_id, tries = 5, compression = compression) 316 317 # disable compression 318 self.set_gzip_compression(session_id, False) 319 320 return data
321
322 - def get_repository_treeupdates(self, session_id, repository, arch, product):
323 324 cmd = "%s %s %s %s %s %s" % ( 325 session_id, 326 'repository_server:treeupdates', 327 repository, 328 arch, 329 product, 330 self.SystemSettings['repositories']['branch'], 331 ) 332 return self.do_generic_handler(cmd, session_id, tries = 5)
333
334 - def get_package_sets(self, session_id, repository, arch, product):
335 336 cmd = "%s %s %s %s %s %s" % ( 337 session_id, 338 'repository_server:get_package_sets', 339 repository, 340 arch, 341 product, 342 self.SystemSettings['repositories']['branch'], 343 ) 344 return self.do_generic_handler(cmd, session_id, tries = 5)
345
346 - def get_repository_metadata(self, session_id, repository, arch, product):
347 348 cmd = "%s %s %s %s %s %s" % ( 349 session_id, 350 'repository_server:get_repository_metadata', 351 repository, 352 arch, 353 product, 354 self.SystemSettings['repositories']['branch'], 355 ) 356 return self.do_generic_handler(cmd, session_id, tries = 5)
357
358 - def get_strict_package_information(self, session_id, idpackages, repository, arch, product):
359 360 cmd = "%s %s %s %s %s %s %s %s" % ( 361 session_id, 362 'repository_server:pkginfo_strict', 363 True, 364 repository, 365 arch, 366 product, 367 self.SystemSettings['repositories']['branch'], 368 ' '.join([str(x) for x in idpackages]), 369 ) 370 371 # enable zlib compression 372 compression = self.set_gzip_compression(session_id, True) 373 374 data = self.do_generic_handler(cmd, session_id, compression = compression) 375 376 # disable compression 377 self.set_gzip_compression(session_id, False) 378 379 return data
380
381 - def ugc_do_downloads(self, session_id, pkgkeys):
382 383 cmd = "%s %s %s" % ( 384 session_id, 385 'ugc:do_downloads', 386 ' '.join(pkgkeys), 387 ) 388 return self.do_generic_handler(cmd, session_id)
389
390 - def ugc_do_download_stats(self, session_id, package_names):
391 392 sub_lists = self.entropyTools.split_indexable_into_chunks( 393 package_names, 100) 394 395 last_srv_rc_data = None 396 for pkgkeys in sub_lists: 397 398 release_string = '--N/A--' 399 rel_file = etpConst['systemreleasefile'] 400 if os.path.isfile(rel_file) and os.access(rel_file,os.R_OK): 401 with open(rel_file,"r") as f: 402 release_string = f.read(512) 403 404 hw_hash = self.SystemSettings['hw_hash'] 405 if not hw_hash: 406 hw_hash = '' 407 408 mydict = { 409 'branch': self.SystemSettings['repositories']['branch'], 410 'release_string': release_string, 411 'hw_hash': hw_hash, 412 'pkgkeys': ' '.join(pkgkeys), 413 } 414 xml_string = self.entropyTools.xml_from_dict(mydict) 415 416 cmd = "%s %s %s" % ( 417 session_id, 418 'ugc:do_download_stats', 419 xml_string, 420 ) 421 last_srv_rc_data = self.do_generic_handler(cmd, session_id) 422 if not isinstance(last_srv_rc_data, tuple): 423 return last_srv_rc_data 424 elif last_srv_rc_data[0] != True: 425 return last_srv_rc_data 426 return last_srv_rc_data
427
428 - def ugc_get_downloads(self, session_id, pkgkey):
429 430 cmd = "%s %s %s" % ( 431 session_id, 432 'ugc:get_downloads', 433 pkgkey, 434 ) 435 return self.do_generic_handler(cmd, session_id)
436
437 - def ugc_get_alldownloads(self, session_id):
438 439 cmd = "%s %s" % ( 440 session_id, 441 'ugc:get_alldownloads', 442 ) 443 444 # enable zlib compression 445 compression = self.set_gzip_compression(session_id, True) 446 447 rc = self.do_generic_handler(cmd, session_id, compression = compression) 448 449 # disable compression 450 self.set_gzip_compression(session_id, False) 451 452 return rc
453
454 - def ugc_do_vote(self, session_id, pkgkey, vote):
455 456 cmd = "%s %s %s %s" % ( 457 session_id, 458 'ugc:do_vote', 459 pkgkey, 460 vote, 461 ) 462 return self.do_generic_handler(cmd, session_id)
463
464 - def ugc_get_vote(self, session_id, pkgkey):
465 466 cmd = "%s %s %s" % ( 467 session_id, 468 'ugc:get_vote', 469 pkgkey, 470 ) 471 return self.do_generic_handler(cmd, session_id)
472
473 - def ugc_get_allvotes(self, session_id):
474 475 cmd = "%s %s" % ( 476 session_id, 477 'ugc:get_allvotes', 478 ) 479 480 # enable zlib compression 481 compression = self.set_gzip_compression(session_id, True) 482 483 rc = self.do_generic_handler(cmd, session_id, compression = compression) 484 485 # disable compression 486 self.set_gzip_compression(session_id, False) 487 488 return rc
489
490 - def ugc_add_comment(self, session_id, pkgkey, comment, title, keywords):
491 492 mydict = { 493 'comment': comment, 494 'title': title, 495 'keywords': keywords, 496 } 497 xml_string = self.entropyTools.xml_from_dict(mydict) 498 499 cmd = "%s %s %s %s" % ( 500 session_id, 501 'ugc:add_comment', 502 pkgkey, 503 xml_string, 504 ) 505 506 return self.do_generic_handler(cmd, session_id)
507
508 - def ugc_edit_comment(self, session_id, iddoc, new_comment, new_title, new_keywords):
509 510 mydict = { 511 'comment': new_comment, 512 'title': new_title, 513 'keywords': new_keywords, 514 } 515 xml_string = self.entropyTools.xml_from_dict(mydict) 516 517 cmd = "%s %s %s %s" % ( 518 session_id, 519 'ugc:edit_comment', 520 iddoc, 521 xml_string, 522 ) 523 return self.do_generic_handler(cmd, session_id)
524
525 - def ugc_remove_comment(self, session_id, iddoc):
526 527 cmd = "%s %s %s" % ( 528 session_id, 529 'ugc:remove_comment', 530 iddoc, 531 ) 532 return self.do_generic_handler(cmd, session_id)
533
534 - def ugc_remove_image(self, session_id, iddoc):
535 536 cmd = "%s %s %s" % ( 537 session_id, 538 'ugc:remove_image', 539 iddoc, 540 ) 541 return self.do_generic_handler(cmd, session_id)
542
543 - def ugc_remove_file(self, session_id, iddoc):
544 545 cmd = "%s %s %s" % ( 546 session_id, 547 'ugc:remove_file', 548 iddoc, 549 ) 550 return self.do_generic_handler(cmd, session_id)
551
552 - def ugc_remove_youtube_video(self, session_id, iddoc):
553 554 cmd = "%s %s %s" % ( 555 session_id, 556 'ugc:remove_youtube_video', 557 iddoc, 558 ) 559 return self.do_generic_handler(cmd, session_id)
560
561 - def ugc_get_docs(self, session_id, pkgkey):
562 563 cmd = "%s %s %s" % ( 564 session_id, 565 'ugc:get_alldocs', 566 pkgkey, 567 ) 568 return self.do_generic_handler(cmd, session_id)
569
570 - def ugc_get_textdocs(self, session_id, pkgkey):
571 572 cmd = "%s %s %s" % ( 573 session_id, 574 'ugc:get_textdocs', 575 pkgkey, 576 ) 577 return self.do_generic_handler(cmd, session_id)
578
579 - def ugc_get_textdocs_by_identifiers(self, session_id, identifiers):
580 581 cmd = "%s %s %s" % ( 582 session_id, 583 'ugc:get_textdocs_by_identifiers', 584 ' '.join([str(x) for x in identifiers]), 585 ) 586 return self.do_generic_handler(cmd, session_id)
587
588 - def ugc_get_documents_by_identifiers(self, session_id, identifiers):
589 590 cmd = "%s %s %s" % ( 591 session_id, 592 'ugc:get_documents_by_identifiers', 593 ' '.join([str(x) for x in identifiers]), 594 ) 595 return self.do_generic_handler(cmd, session_id)
596
597 - def ugc_send_file_stream(self, session_id, file_path):
598 599 if not (os.path.isfile(file_path) and os.access(file_path,os.R_OK)): 600 return False,False,'cannot read file_path' 601 602 import zlib 603 # enable stream 604 cmd = "%s %s %s on" % ( 605 session_id, 606 'session_config', 607 'stream', 608 ) 609 status, msg = self.do_generic_handler(cmd, session_id) 610 if not status: 611 return False,status,msg 612 613 # enable zlib compression 614 compression = self.set_gzip_compression(session_id, True) 615 616 # start streamer 617 stream_status = True 618 stream_msg = 'ok' 619 f = open(file_path,"rb") 620 chunk = f.read(8192) 621 base_path = os.path.basename(file_path) 622 transferred = len(chunk) 623 max_size = self.entropyTools.get_file_size(file_path) 624 while chunk: 625 626 if (not self.Service.quiet) or self.Service.show_progress: 627 self.Output.updateProgress( 628 "%s, %s: %s" % ( 629 blue(_("User Generated Content")), 630 darkgreen(_("sending file")), 631 darkred(base_path), 632 ), 633 importance = 1, 634 type = "info", 635 header = brown(" @@ "), 636 back = True, 637 count = (transferred,max_size,), 638 percent = True 639 ) 640 641 chunk = zlib.compress(chunk, 7) # compression level 1-9 642 cmd = "%s %s %s" % ( 643 session_id, 644 'stream', 645 chunk, 646 ) 647 status, msg = self.do_generic_handler(cmd, session_id, compression = compression) 648 if not status: 649 stream_status = status 650 stream_msg = msg 651 break 652 chunk = f.read(8192) 653 transferred += len(chunk) 654 655 f.close() 656 657 # disable compression 658 self.set_gzip_compression(session_id, False) 659 660 # disable config 661 cmd = "%s %s %s off" % ( 662 session_id, 663 'session_config', 664 'stream', 665 ) 666 status, msg = self.do_generic_handler(cmd, session_id) 667 if not status: 668 return False,status,msg 669 670 return True,stream_status,stream_msg
671
672 - def ugc_send_file(self, session_id, pkgkey, file_path, doc_type, title, description, keywords):
673 674 status, rem_status, err_msg = self.ugc_send_file_stream(session_id, file_path) 675 if not (status and rem_status): 676 return False,err_msg 677 678 mydict = { 679 'doc_type': str(doc_type), 680 'title': title, 681 'description': description, 682 'keywords': keywords, 683 'file_name': os.path.join(pkgkey,os.path.basename(file_path)), 684 'real_filename': os.path.basename(file_path), 685 } 686 xml_string = self.entropyTools.xml_from_dict(mydict) 687 688 cmd = "%s %s %s %s" % ( 689 session_id, 690 'ugc:register_stream', 691 pkgkey, 692 xml_string, 693 ) 694 return self.do_generic_handler(cmd, session_id)
695
696 - def report_error(self, session_id, error_data):
697 698 import zlib 699 xml_string = self.entropyTools.xml_from_dict_extended(error_data) 700 xml_comp_string = zlib.compress(xml_string) 701 702 cmd = "%s %s %s" % ( 703 session_id, 704 'ugc:report_error', 705 xml_comp_string, 706 ) 707 708 return self.do_generic_handler(cmd, session_id)
709