1
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 Commands}.
10
11 """
12
13 import os
14 from entropy.exceptions import *
15 from entropy.const import etpConst, const_get_stringtype, const_debug_write
16 from entropy.output import darkblue, bold, blue, darkgreen, darkred, brown
17 from entropy.i18n import _
18 from entropy.core.settings.base import SystemSettings
19
21
22 - def __init__(self, OutputInterface, Service):
23
24 if not hasattr(OutputInterface, 'updateProgress'):
25 mytxt = _("OutputInterface does not have an updateProgress method")
26 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface, mytxt,))
27 elif not hasattr(OutputInterface.updateProgress, '__call__'):
28 mytxt = _("OutputInterface does not have an updateProgress method")
29 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface, mytxt,))
30
31 from entropy.services.ugc.interfaces import Client as Cl
32 if not isinstance(Service, Cl):
33 mytxt = _("A valid entropy.services.ugc.interfaces.Client based instance is needed")
34 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (Service, mytxt,))
35
36 import socket, zlib, struct
37 import entropy.tools as entropyTools
38 import entropy.dump as dumpTools
39 self.entropyTools, self.socket, self.zlib, self.struct, \
40 self.dumpTools = entropyTools, socket, zlib, struct, dumpTools
41 self.Output = OutputInterface
42 self.Service = Service
43 self.output_header = ''
44 self.SystemSettings = SystemSettings()
45 self.standard_answers_map = {
46 'all_fine': 0,
47 'not_supported_remotely': 1,
48 'service_temp_not_avail': 2,
49 'command_failed': 3,
50 'wrong_answer': 4,
51 }
52
53
56
57 do_skip = False
58 answer_id = self.standard_answers_map['all_fine']
59
60
61 if data == None:
62 mytxt = _("feature not supported remotely")
63 self.Output.updateProgress(
64 "[%s:%s|%s:%s|%s:%s] %s" % (
65 darkblue(_("repo")),
66 bold(str(repository)),
67 darkred(_("arch")),
68 bold(str(arch)),
69 darkgreen(_("product")),
70 bold(str(product)),
71 blue(mytxt),
72 ),
73 importance = 1,
74 type = "error",
75 header = self.output_header
76 )
77 do_skip = True
78 answer_id = self.standard_answers_map['not_supported_remotely']
79 elif not data:
80 mytxt = _("service temporarily not available")
81 self.Output.updateProgress(
82 "[%s:%s|%s:%s|%s:%s] %s" % (
83 darkblue(_("repo")),
84 bold(str(repository)),
85 darkred(_("arch")),
86 bold(str(arch)),
87 darkgreen(_("product")),
88 bold(str(product)),
89 blue(mytxt),
90 ),
91 importance = 1,
92 type = "error",
93 header = self.output_header
94 )
95 do_skip = True
96 answer_id = self.standard_answers_map['service_temp_not_avail']
97 elif data == self.Service.answers['no']:
98
99 mytxt = _("command failed")
100 self.Output.updateProgress(
101 "[%s:%s|%s:%s|%s:%s] %s" % (
102 darkblue(_("repo")),
103 bold(str(repository)),
104 darkred(_("arch")),
105 bold(str(arch)),
106 darkgreen(_("product")),
107 bold(str(product)),
108 blue(mytxt),
109 ),
110 importance = 1,
111 type = "error",
112 header = self.output_header
113 )
114 do_skip = True
115 answer_id = self.standard_answers_map['command_failed']
116 elif data != self.Service.answers['ok']:
117 mytxt = _("received wrong answer")
118
119
120 if isinstance(data, const_get_stringtype()):
121 if len(data) > 10:
122 data = data[:10] + "[...]"
123
124 self.Output.updateProgress(
125 "[%s:%s|%s:%s|%s:%s] %s: %s" % (
126 darkblue(_("repo")),
127 bold(str(repository)),
128 darkred(_("arch")),
129 bold(str(arch)),
130 darkgreen(_("product")),
131 bold(str(product)),
132 blue(mytxt),
133 repr(data),
134 ),
135 importance = 1,
136 type = "error",
137 header = self.output_header
138 )
139 do_skip = True
140 answer_id = self.standard_answers_map['wrong_answer']
141
142 return do_skip, answer_id
143
145
146 cmd = "%s rc" % (session,)
147 self.Service.transmit(cmd)
148 try:
149 data = self.Service.receive()
150 return data
151 except:
152 self.entropyTools.print_traceback()
153 return None
154
156
157
158 error = False
159 try:
160 data = self.Service.stream_to_object(data, gzipped)
161 except (EOFError, IOError, self.zlib.error, self.dumpTools.pickle.UnpicklingError,):
162 const_debug_write(__name__, self.entropyTools.get_traceback())
163 mytxt = _("cannot convert stream into object")
164 self.Output.updateProgress(
165 "[%s:%s|%s:%s|%s:%s] %s" % (
166 darkblue(_("repo")),
167 bold(str(repository)),
168 darkred(_("arch")),
169 bold(str(arch)),
170 darkgreen(_("product")),
171 bold(str(product)),
172 blue(mytxt),
173 ),
174 importance = 1,
175 type = "error",
176 header = self.output_header
177 )
178 data = None
179 error = True
180 return data, error
181
182 - def retrieve_command_answer(self, cmd, session_id, repository = None, arch = None, product = None, compression = False):
183
184 tries = 3
185 lasterr = None
186 while True:
187
188 if tries <= 0:
189 return lasterr
190 tries -= 1
191
192 try:
193
194 self.Service.transmit(cmd)
195 except (SSLError,):
196 return None
197
198 data = self.Service.receive()
199
200 skip, answer_id = self.handle_standard_answer(data, repository,
201 arch, product)
202 if skip:
203 if tries <= 0:
204 const_debug_write(__name__,
205 darkred("skipping command, NOT reconnecting"))
206 else:
207 const_debug_write(__name__,
208 darkred("skipping command, reconnect+retry!"))
209 const_debug_write(__name__, str(answer_id))
210
211 self.Service.reconnect_socket()
212 continue
213
214 data = self.get_result(session_id)
215 if data == None:
216 lasterr = None
217 continue
218 elif not data:
219 lasterr = False
220 continue
221
222 objdata, error = self.convert_stream_to_object(data, compression, repository, arch, product)
223 if not error:
224 return objdata
225
227
228 self.Service.check_socket_connection()
229
230 while True:
231 try:
232 result = self.retrieve_command_answer(cmd, session_id, compression = compression)
233 if result == None:
234 return False, 'command not supported'
235 return result
236 except (self.socket.error, self.struct.error,):
237 self.Service.reconnect_socket()
238 tries -= 1
239 if tries < 1:
240 raise
241
243 self.Service.check_socket_connection()
244 cmd = "%s %s %s %s zlib" % (session, 'session_config', 'compression', do,)
245 self.Service.transmit(cmd)
246 data = self.Service.receive()
247 if data == self.Service.answers['ok']:
248 return True
249 return False
250
252
253 cmd = "%s %s %s %s" % (
254 session_id,
255 'login',
256 username,
257 password,
258 )
259 return self.do_generic_handler(cmd, session_id)
260
262
263 cmd = "%s %s %s" % (
264 session_id,
265 'logout',
266 username,
267 )
268 return self.do_generic_handler(cmd, session_id)
269
271
272 cmd = "%s %s" % (
273 session_id,
274 'user_data',
275 )
276 return self.do_generic_handler(cmd, session_id)
277
279
280 cmd = "%s %s" % (
281 session_id,
282 'is_user',
283 )
284 return self.do_generic_handler(cmd, session_id)
285
287
288 cmd = "%s %s" % (
289 session_id,
290 'is_developer',
291 )
292 return self.do_generic_handler(cmd, session_id)
293
295
296 cmd = "%s %s" % (
297 session_id,
298 'is_moderator',
299 )
300 return self.do_generic_handler(cmd, session_id)
301
303
304 cmd = "%s %s" % (
305 session_id,
306 'is_administrator',
307 )
308 return self.do_generic_handler(cmd, session_id)
309
311
312 cmd = "%s %s" % (
313 session_id,
314 'available_commands',
315 )
316 return self.do_generic_handler(cmd, session_id)
317
318
320
321 - def __init__(self, EntropyInterface, ServiceInterface):
323
325
326 myidlist = ' '.join([str(x) for x in idpackages])
327 cmd = "%s %s %s %s %s %s %s" % (
328 session_id,
329 'repository_server:dbdiff',
330 repository,
331 arch,
332 product,
333 self.SystemSettings['repositories']['branch'],
334 myidlist,
335 )
336
337
338 compression = self.set_gzip_compression(session_id, True)
339
340 data = self.do_generic_handler(cmd, session_id, tries = 5, compression = compression)
341
342
343 self.set_gzip_compression(session_id, False)
344
345 return data
346
348
349 cmd = "%s %s %s %s %s %s" % (
350 session_id,
351 'repository_server:treeupdates',
352 repository,
353 arch,
354 product,
355 self.SystemSettings['repositories']['branch'],
356 )
357 return self.do_generic_handler(cmd, session_id, tries = 5)
358
360
361 cmd = "%s %s %s %s %s %s" % (
362 session_id,
363 'repository_server:get_package_sets',
364 repository,
365 arch,
366 product,
367 self.SystemSettings['repositories']['branch'],
368 )
369 return self.do_generic_handler(cmd, session_id, tries = 5)
370
382
405
407
408 cmd = "%s %s %s" % (
409 session_id,
410 'ugc:do_downloads',
411 ' '.join(pkgkeys),
412 )
413 return self.do_generic_handler(cmd, session_id)
414
416
417 sub_lists = self.entropyTools.split_indexable_into_chunks(
418 package_names, 100)
419
420 last_srv_rc_data = None
421 for pkgkeys in sub_lists:
422
423 release_string = '--N/A--'
424 rel_file = etpConst['systemreleasefile']
425 if os.path.isfile(rel_file) and os.access(rel_file, os.R_OK):
426 with open(rel_file, "r") as f:
427 release_string = f.read(512)
428
429 hw_hash = self.SystemSettings['hw_hash']
430 if not hw_hash:
431 hw_hash = ''
432
433 mydict = {
434 'branch': self.SystemSettings['repositories']['branch'],
435 'release_string': release_string,
436 'hw_hash': hw_hash,
437 'pkgkeys': ' '.join(pkgkeys),
438 }
439 xml_string = self.entropyTools.xml_from_dict(mydict)
440
441 cmd = "%s %s %s" % (
442 session_id,
443 'ugc:do_download_stats',
444 xml_string,
445 )
446 last_srv_rc_data = self.do_generic_handler(cmd, session_id)
447 if not isinstance(last_srv_rc_data, tuple):
448 return last_srv_rc_data
449 elif last_srv_rc_data[0] != True:
450 return last_srv_rc_data
451 return last_srv_rc_data
452
454
455 cmd = "%s %s %s" % (
456 session_id,
457 'ugc:get_downloads',
458 pkgkey,
459 )
460 return self.do_generic_handler(cmd, session_id)
461
463
464 cmd = "%s %s" % (
465 session_id,
466 'ugc:get_alldownloads',
467 )
468
469
470 compression = self.set_gzip_compression(session_id, True)
471
472 rc = self.do_generic_handler(cmd, session_id, compression = compression)
473
474
475 self.set_gzip_compression(session_id, False)
476
477 return rc
478
480
481 cmd = "%s %s %s %s" % (
482 session_id,
483 'ugc:do_vote',
484 pkgkey,
485 vote,
486 )
487 return self.do_generic_handler(cmd, session_id)
488
490
491 cmd = "%s %s %s" % (
492 session_id,
493 'ugc:get_vote',
494 pkgkey,
495 )
496 return self.do_generic_handler(cmd, session_id)
497
499
500 cmd = "%s %s" % (
501 session_id,
502 'ugc:get_allvotes',
503 )
504
505
506 compression = self.set_gzip_compression(session_id, True)
507
508 rc = self.do_generic_handler(cmd, session_id, compression = compression)
509
510
511 self.set_gzip_compression(session_id, False)
512
513 return rc
514
532
549
558
560
561 cmd = "%s %s %s" % (
562 session_id,
563 'ugc:remove_image',
564 iddoc,
565 )
566 return self.do_generic_handler(cmd, session_id)
567
569
570 cmd = "%s %s %s" % (
571 session_id,
572 'ugc:remove_file',
573 iddoc,
574 )
575 return self.do_generic_handler(cmd, session_id)
576
578
579 cmd = "%s %s %s" % (
580 session_id,
581 'ugc:remove_youtube_video',
582 iddoc,
583 )
584 return self.do_generic_handler(cmd, session_id)
585
587
588 cmd = "%s %s %s" % (
589 session_id,
590 'ugc:get_alldocs',
591 pkgkey,
592 )
593 return self.do_generic_handler(cmd, session_id)
594
595 - def ugc_get_textdocs(self, session_id, pkgkey):
596
597 cmd = "%s %s %s" % (
598 session_id,
599 'ugc:get_textdocs',
600 pkgkey,
601 )
602 return self.do_generic_handler(cmd, session_id)
603
604 - def ugc_get_textdocs_by_identifiers(self, session_id, identifiers):
605
606 cmd = "%s %s %s" % (
607 session_id,
608 'ugc:get_textdocs_by_identifiers',
609 ' '.join([str(x) for x in identifiers]),
610 )
611 return self.do_generic_handler(cmd, session_id)
612
614
615 cmd = "%s %s %s" % (
616 session_id,
617 'ugc:get_documents_by_identifiers',
618 ' '.join([str(x) for x in identifiers]),
619 )
620 return self.do_generic_handler(cmd, session_id)
621
623
624 if not (os.path.isfile(file_path) and os.access(file_path, os.R_OK)):
625 return False, False, 'cannot read file_path'
626
627 import zlib
628
629 cmd = "%s %s %s on" % (
630 session_id,
631 'session_config',
632 'stream',
633 )
634 status, msg = self.do_generic_handler(cmd, session_id)
635 if not status:
636 return False, status, msg
637
638
639 compression = self.set_gzip_compression(session_id, True)
640
641
642 stream_status = True
643 stream_msg = 'ok'
644 f = open(file_path, "rb")
645 chunk = f.read(8192)
646 base_path = os.path.basename(file_path)
647 transferred = len(chunk)
648 max_size = self.entropyTools.get_file_size(file_path)
649 while chunk:
650
651 if (not self.Service.quiet) or self.Service.show_progress:
652 self.Output.updateProgress(
653 "%s, %s: %s" % (
654 blue(_("User Generated Content")),
655 darkgreen(_("sending file")),
656 darkred(base_path),
657 ),
658 importance = 1,
659 type = "info",
660 header = brown(" @@ "),
661 back = True,
662 count = (transferred, max_size,),
663 percent = True
664 )
665
666 chunk = zlib.compress(chunk, 7)
667 cmd = "%s %s %s" % (
668 session_id,
669 'stream',
670 chunk,
671 )
672 status, msg = self.do_generic_handler(cmd, session_id, compression = compression)
673 if not status:
674 stream_status = status
675 stream_msg = msg
676 break
677 chunk = f.read(8192)
678 transferred += len(chunk)
679
680 f.close()
681
682
683 self.set_gzip_compression(session_id, False)
684
685
686 cmd = "%s %s %s off" % (
687 session_id,
688 'session_config',
689 'stream',
690 )
691 status, msg = self.do_generic_handler(cmd, session_id)
692 if not status:
693 return False, status, msg
694
695 return True, stream_status, stream_msg
696
697 - def ugc_send_file(self, session_id, pkgkey, file_path, doc_type, title, description, keywords):
698
699 status, rem_status, err_msg = self.ugc_send_file_stream(session_id, file_path)
700 if not (status and rem_status):
701 return False, err_msg
702
703 mydict = {
704 'doc_type': str(doc_type),
705 'title': title,
706 'description': description,
707 'keywords': keywords,
708 'file_name': os.path.join(pkgkey, os.path.basename(file_path)),
709 'real_filename': os.path.basename(file_path),
710 }
711 xml_string = self.entropyTools.xml_from_dict(mydict)
712
713 cmd = "%s %s %s %s" % (
714 session_id,
715 'ugc:register_stream',
716 pkgkey,
717 xml_string,
718 )
719 return self.do_generic_handler(cmd, session_id)
720
722
723 import zlib
724 xml_string = self.entropyTools.xml_from_dict_extended(error_data)
725 xml_comp_string = zlib.compress(xml_string)
726
727 cmd = "%s %s %s" % (
728 session_id,
729 'ugc:report_error',
730 xml_comp_string,
731 )
732
733 return self.do_generic_handler(cmd, session_id)
734