1
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 import time
26 import subprocess
27 import shutil
28 from entropy.services.skel import RemoteDatabase
29 from entropy.exceptions import *
30 from entropy.const import etpConst, etpUi, etpCache, const_setup_perms, const_set_chmod, const_setup_file
31 from entropy.output import brown, bold, blue
32 from entropy.i18n import _
33
35
36 SQL_TABLES = {
37 'entropy_base': """
38 CREATE TABLE `entropy_base` (
39 `idkey` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
40 `key` VARCHAR( 255 ) collate utf8_bin NOT NULL,
41 KEY `key` (`key`)
42 );
43 """,
44 'entropy_votes': """
45 CREATE TABLE `entropy_votes` (
46 `idvote` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
47 `idkey` INT UNSIGNED NOT NULL,
48 `userid` INT UNSIGNED NOT NULL,
49 `vdate` DATE NOT NULL,
50 `vote` TINYINT NOT NULL,
51 `ts` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
52 FOREIGN KEY (`idkey`) REFERENCES `entropy_base` (`idkey`)
53 );
54 """,
55 'entropy_user_scores': """
56 CREATE TABLE `entropy_user_scores` (
57 `userid` INT UNSIGNED NOT NULL PRIMARY KEY,
58 `score` INT UNSIGNED NOT NULL DEFAULT 0
59 );
60 """,
61 'entropy_downloads': """
62 CREATE TABLE `entropy_downloads` (
63 `iddownload` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
64 `idkey` INT UNSIGNED NOT NULL,
65 `ddate` DATE NOT NULL,
66 `count` INT UNSIGNED NULL DEFAULT '0',
67 KEY `idkey` (`idkey`,`ddate`),
68 KEY `idkey_2` (`idkey`),
69 FOREIGN KEY (`idkey`) REFERENCES `entropy_base` (`idkey`)
70 );
71 """,
72 'entropy_downloads_data': """
73 CREATE TABLE `entropy_downloads_data` (
74 `iddownload` INT UNSIGNED NOT NULL,
75 `ip_address` VARCHAR(40) NULL DEFAULT '',
76 `entropy_ip_locations_id` INT UNSIGNED NULL DEFAULT 0,
77 FOREIGN KEY (`iddownload`) REFERENCES `entropy_downloads` (`iddownload`)
78 );
79 """,
80 'entropy_docs': """
81 CREATE TABLE `entropy_docs` (
82 `iddoc` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
83 `idkey` INT UNSIGNED NOT NULL,
84 `userid` INT UNSIGNED NOT NULL,
85 `username` VARCHAR( 255 ),
86 `iddoctype` TINYINT NOT NULL,
87 `ddata` TEXT NOT NULL,
88 `title` VARCHAR( 512 ),
89 `description` VARCHAR( 4000 ),
90 `ts` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
91 KEY `idkey` (`idkey`),
92 KEY `userid` (`userid`),
93 KEY `idkey_2` (`idkey`,`userid`,`iddoctype`),
94 KEY `title` (`title`(333)),
95 KEY `description` (`description`(333)),
96 FOREIGN KEY (`idkey`) REFERENCES `entropy_base` (`idkey`)
97 );
98 """,
99 'entropy_doctypes': """
100 CREATE TABLE `entropy_doctypes` (
101 `iddoctype` TINYINT NOT NULL PRIMARY KEY,
102 `description` TEXT NOT NULL
103 );
104 """,
105 'entropy_docs_keywords': """
106 CREATE TABLE `entropy_docs_keywords` (
107 `iddoc` INT UNSIGNED NOT NULL,
108 `keyword` VARCHAR( 100 ),
109 KEY `keyword` (`keyword`),
110 FOREIGN KEY (`iddoc`) REFERENCES `entropy_docs` (`iddoc`)
111 );
112 """,
113 'entropy_distribution_usage': """
114 CREATE TABLE `entropy_distribution_usage` (
115 `entropy_distribution_usage_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
116 `entropy_branches_id` INT NOT NULL,
117 `entropy_release_strings_id` INT NOT NULL,
118 `ts` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
119 `ip_address` VARCHAR( 15 ),
120 `entropy_ip_locations_id` INT UNSIGNED NULL DEFAULT 0,
121 `creation_date` DATETIME DEFAULT NULL,
122 `hits` INT UNSIGNED NULL DEFAULT 0,
123 FOREIGN KEY (`entropy_branches_id`) REFERENCES `entropy_branches` (`entropy_branches_id`),
124 FOREIGN KEY (`entropy_release_strings_id`) REFERENCES `entropy_release_strings` (`entropy_release_strings_id`),
125 KEY `ip_address` (`ip_address`),
126 KEY `entropy_ip_locations_id` (`entropy_ip_locations_id`)
127 );
128 """,
129 'entropy_hardware_usage': """
130 CREATE TABLE `entropy_hardware_usage` (
131 `entropy_hardware_usage_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
132 `entropy_distribution_usage_id` INT UNSIGNED NOT NULL,
133 `entropy_hardware_hash` VARCHAR ( 64 ),
134 FOREIGN KEY (`entropy_distribution_usage_id`) REFERENCES `entropy_distribution_usage` (`entropy_distribution_usage_id`)
135 );
136 """,
137
138
139
140
141
142
143
144
145 'entropy_branches': """
146 CREATE TABLE `entropy_branches` (
147 `entropy_branches_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
148 `entropy_branch` VARCHAR( 100 )
149 );
150 """,
151 'entropy_release_strings': """
152 CREATE TABLE `entropy_release_strings` (
153 `entropy_release_strings_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
154 `release_string` VARCHAR( 255 )
155 );
156 """,
157 'entropy_ip_locations': """
158 CREATE TABLE `entropy_ip_locations` (
159 `entropy_ip_locations_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
160 `ip_latitude` FLOAT( 8,5 ),
161 `ip_longitude` FLOAT( 8,5 ),
162 KEY `ip_locations_lat_lon` (`ip_latitude`,`ip_longitude`)
163 );
164 """,
165 }
166 VOTE_RANGE = etpConst['ugc_voterange']
167 VIRUS_CHECK_EXEC = '/usr/bin/clamscan'
168 VIRUS_CHECK_ARGS = []
169 gdata = None
170 YouTube = None
171 YouTubeService = None
172 entropy_docs_title_len = 512
173 entropy_docs_description_len = 4000
174 entropy_docs_keyword_len = 100
175 COMMENTS_SCORE_WEIGHT = 5
176 DOCS_SCORE_WEIGHT = 10
177 VOTES_SCORE_WEIGHT = 2
178 STATS_MAP = {
179 'installer': "installer",
180 }
181
182 '''
183 dependencies:
184 dev-python/gdata
185 '''
186 - def __init__(self, connection_data, store_path, store_url = ''):
187 import entropy.dump as dumpTools
188 import entropy.tools as entropyTools
189 from entropy.misc import EntropyGeoIP
190 self.EntropyGeoIP = EntropyGeoIP
191 self.entropyTools, self.dumpTools = entropyTools, dumpTools
192 self.store_url = store_url
193 self.FLOOD_INTERVAL = 30
194 self.DOC_TYPES = etpConst['ugc_doctypes'].copy()
195 self.UPLOADED_DOC_TYPES = [
196 self.DOC_TYPES['image'],
197 self.DOC_TYPES['generic_file']
198 ]
199 RemoteDatabase.__init__(self)
200 self.set_connection_data(connection_data)
201 self.connect()
202 self.initialize_tables()
203 self.initialize_doctypes()
204 self.setup_store_path(store_path)
205 from entropy.core import SystemSettings
206 self.__system_settings = SystemSettings()
207 self.system_name = self.__system_settings['system']['name']
208 from datetime import datetime
209 self.datetime = datetime
210 try:
211 import gdata
212 import gdata.youtube
213 import gdata.youtube.service
214 self.gdata = gdata
215 self.YouTube = gdata.youtube
216 self.YouTubeService = gdata.youtube.service
217 except ImportError:
218 pass
219
220 self.cached_results = {
221
222 'get_ugc_alldownloads': (self.get_ugc_alldownloads, [], {}, 86400),
223
224 'get_total_downloads_count': (self.get_total_downloads_count, [], {}, 7200),
225 }
226
228 return int(time.time())
229
231 for cache_item in self.cached_results:
232 fdata = self.cached_results.get(cache_item)
233 if fdata == None: return
234 func, args, kwargs, exp_time = fdata
235 key = self.get_cache_item_key(cache_item)
236 r = func(*args,**kwargs)
237 self.dumpTools.dumpobj(key, r)
238
240 return os.path.join(etpCache['ugc_srv_cache'],cache_item)
241
243 if not self.cached_results.get(cache_item): return None
244 key = self.get_cache_item_key(cache_item)
245 self.dumpTools.dumpobj(key, r)
246
248 geoip_dbpath = self.connection_data.get('geoip_dbpath','')
249 if os.path.isfile(geoip_dbpath) and os.access(geoip_dbpath,os.R_OK):
250 try:
251 geo = self.EntropyGeoIP(geoip_dbpath)
252 return geo.get_geoip_record_from_ip(ip_address)
253 except:
254 pass
255
256
258 fdata = self.cached_results.get(cache_item)
259 if fdata == None: return None
260 func, args, kwargs, exp_time = fdata
261
262 key = self.get_cache_item_key(cache_item)
263 cur_time = self.get_current_time()
264 cache_time = self.dumpTools.getobjmtime(key)
265 if (cache_time + exp_time) < cur_time:
266
267 return None
268 return self.dumpTools.loadobj(key)
269
271 path = os.path.realpath(path)
272 if not os.path.isabs(path):
273 raise PermissionDenied('PermissionDenied: %s' % (_("not a valid directory path"),))
274 if not os.path.isdir(path):
275 try:
276 os.makedirs(path)
277 except OSError, e:
278 raise PermissionDenied('PermissionDenied: %s' % (e,))
279 if etpConst['entropygid'] != None:
280 const_setup_perms(path,etpConst['entropygid'])
281 self.STORE_PATH = path
282
292
298
300 self.check_connection()
301 rows = self.execute_query('SELECT `iddoctype` FROM entropy_doctypes WHERE `iddoctype` = %s', (iddoctype,))
302 if rows:
303 return True
304 return False
305
307 self.check_connection()
308 rows = self.execute_query('SELECT `idkey` FROM entropy_base WHERE `key` = %s', (key,))
309 if rows:
310 return True
311 return False
312
314 self.check_connection()
315 rows = self.execute_query('SELECT `iddoc` FROM entropy_docs WHERE `iddoc` = %s', (iddoc,))
316 if rows:
317 return True
318 return False
319
324
331
339
346
353
360
362 entropy_ip_locations_id = 0
363 geo_data = self._get_geoip_data_from_ip_address(ip_addr)
364 if isinstance(geo_data,dict):
365 ip_lat = geo_data.get('latitude')
366 ip_long = geo_data.get('longitude')
367 if isinstance(ip_lat,float) and isinstance(ip_long,float):
368 ip_lat = round(ip_lat,5)
369 ip_long = round(ip_long,5)
370 entropy_ip_locations_id = self.get_entropy_ip_locations_id(ip_lat, ip_long)
371 if entropy_ip_locations_id == -1:
372 entropy_ip_locations_id = self.insert_entropy_ip_locations_id(ip_lat, ip_long)
373 return entropy_ip_locations_id
374
376 self.check_connection()
377 self.execute_query('UPDATE entropy_downloads SET `count` = `count`+1 WHERE `iddownload` = %s', (iddownload,))
378 if do_commit: self.commit()
379 return iddownload
380
382 entropy_ip_locations_id = self.handle_entropy_ip_locations_id(ip_addr)
383 mydata = [(x,ip_addr,entropy_ip_locations_id,) for x in iddownloads]
384 self.execute_many('INSERT INTO entropy_downloads_data VALUES (%s,%s,%s)', mydata)
385 if do_commit: self.commit()
386
388 mytime = time.time()
389 mydate = self.datetime.fromtimestamp(mytime)
390 mydate = self.datetime(mydate.year,mydate.month,mydate.day)
391 return mydate
392
394 mytime = time.time()
395 mydate = self.datetime.fromtimestamp(mytime)
396 mydate = self.datetime(mydate.year,mydate.month,mydate.day,mydate.hour,mydate.minute,mydate.second)
397 return mydate
398
400 self.check_connection()
401 idkey = self.handle_pkgkey(key)
402 self.execute_query('SELECT `iddownload` FROM entropy_downloads WHERE `idkey` = %s AND `ddate` = %s', (idkey,ddate,))
403 data = self.fetchone()
404 if data:
405 return data['iddownload']
406 return -1
407
409 self.check_connection()
410 self.execute_query('SELECT `idkey` FROM entropy_base WHERE `key` = %s', (key,))
411 data = self.fetchone()
412 if data: return data['idkey']
413 return -1
414
416 self.check_connection()
417 self.execute_query('SELECT `iddoctype` FROM entropy_docs WHERE `iddoc` = %s', (iddoc,))
418 data = self.fetchone()
419 if data: return data['iddoctype']
420 return -1
421
423 self.check_connection()
424 self.execute_query('SELECT `entropy_branches_id` FROM entropy_branches WHERE `entropy_branch` = %s', (branch,))
425 data = self.fetchone()
426 if data: return data['entropy_branches_id']
427 return -1
428
430 self.check_connection()
431 self.execute_query('SELECT `entropy_release_strings_id` FROM entropy_release_strings WHERE `release_string` = %s', (release_string,))
432 data = self.fetchone()
433 if data: return data['entropy_release_strings_id']
434 return -1
435
437 self.check_connection()
438 self.execute_query("""
439 SELECT `entropy_ip_locations_id` FROM
440 entropy_ip_locations WHERE
441 `ip_latitude` = %s AND `ip_longitude` = %s""", (ip_latitude,ip_longitude,))
442 data = self.fetchone()
443 if data: return data['entropy_ip_locations_id']
444 return -1
445
451
465
467 self.execute_query('SELECT `keyword` FROM entropy_docs_keywords WHERE `iddoc` = %s order by `keyword`', (iddoc,))
468 data = self.fetchall()
469 if not data: return []
470 mykeys = []
471 for mydict in data:
472 if not mydict.has_key('keyword'):
473 continue
474 mykeys.append(mydict['keyword'])
475 return mykeys
476
490
504
515
543
545 self.check_connection()
546 vote = 0.0
547 self.execute_query("""
548 SELECT avg(entropy_votes.`vote`) as avg_vote FROM entropy_votes,entropy_base WHERE
549 entropy_base.`key` = %s AND
550 entropy_base.idkey = entropy_votes.idkey""", (pkgkey,))
551 data = self.fetchone()
552 if isinstance(data,dict):
553 if data.get('avg_vote'):
554 return data['avg_vote']
555 return vote
556
558
559
560 cache_item = 'get_ugc_allvotes'
561 cached = self.get_cached_result(cache_item)
562 if cached != None: return cached
563
564 self.check_connection()
565 vote_data = {}
566 self.execute_query("""
567 SELECT entropy_base.`key` as `vkey`,avg(entropy_votes.vote) as `avg_vote` FROM
568 entropy_votes,entropy_base WHERE
569 entropy_votes.`idkey` = entropy_base.`idkey` GROUP BY entropy_base.`key`""")
570 data = self.fetchall()
571 for d_dict in data:
572 vote_data[d_dict['vkey']] = d_dict['avg_vote']
573
574
575 self.cache_result(cache_item, vote_data)
576 return vote_data
577
579 self.check_connection()
580 downloads = 0
581 self.execute_query("""
582 SELECT SQL_CACHE sum(entropy_downloads.`count`) as `tot_downloads` FROM
583 entropy_downloads,entropy_base WHERE entropy_base.key = %s AND
584 entropy_base.idkey = entropy_downloads.idkey""", (pkgkey,))
585 data = self.fetchone()
586 if data['tot_downloads'] != None:
587 downloads = data['tot_downloads']
588 return downloads
589
591
592 cache_item = 'get_ugc_alldownloads'
593 cached = self.get_cached_result(cache_item)
594 if cached != None: return cached
595
596 self.check_connection()
597 down_data = {}
598 self.execute_query("""
599 SELECT SQL_CACHE entropy_base.`key` as `vkey`,sum(entropy_downloads.`count`) as `tot_downloads` FROM
600 entropy_downloads,entropy_base WHERE
601 entropy_downloads.`idkey` = entropy_base.`idkey` GROUP BY entropy_base.`idkey`""")
602 data = self.fetchall()
603 for d_dict in data:
604 down_data[d_dict['vkey']] = d_dict['tot_downloads']
605
606
607 self.cache_result(cache_item, down_data)
608 return down_data
609
611 self.check_connection()
612 self.execute_query('SELECT `userid` FROM entropy_docs WHERE `iddoc` = %s', (iddoc,))
613 data = self.fetchone()
614 if not data:
615 return None
616 elif not data.has_key('userid'):
617 return None
618 return data['userid']
619
627
629 self.check_connection()
630 self.execute_query('SELECT count(`iddoc`) as comments FROM entropy_docs WHERE `iddoctype` != %s', (self.DOC_TYPES['comments'],))
631 data = self.fetchone()
632 if isinstance(data,dict):
633 if data['comments']: return data['comments']
634 return 0
635
637 self.check_connection()
638 self.execute_query('SELECT count(`idvote`) as votes FROM entropy_votes')
639 data = self.fetchone()
640 if isinstance(data,dict):
641 if data['votes']: return data['votes']
642 return 0
643
645
646
647 cache_item = 'get_total_downloads_count'
648 cached = self.get_cached_result(cache_item)
649 if cached != None: return cached
650
651 self.check_connection()
652 self.execute_query('SELECT SQL_CACHE sum(entropy_downloads.`count`) as downloads FROM entropy_downloads')
653 data = self.fetchone()
654 r = 0
655 if isinstance(data,dict):
656 if data['downloads']: r = int(data['downloads'])
657
658
659 self.cache_result(cache_item, r)
660 return r
661
663 self.check_connection()
664 self.execute_query('SET @row = 0')
665 self.execute_query("""
666 SELECT Row, col_a FROM (SELECT @row := @row + 1 AS Row, userid AS col_a FROM
667 entropy_user_scores ORDER BY score DESC) As derived1 WHERE col_a = %s""", (userid,))
668 data = self.fetchone()
669 if isinstance(data,dict):
670 if data.get('Row'): return data['Row']
671 return 0
672
674
675
676 cache_item = 'get_users_scored_count'
677 cached = self.get_cached_result(cache_item)
678 if cached != None: return cached
679
680 self.check_connection()
681 self.execute_query('SELECT SQL_CACHE count(`userid`) as mycount FROM entropy_user_scores')
682 data = self.fetchone()
683 r = 0
684 if isinstance(data,dict):
685 if data.get('mycount'): r = data['mycount']
686
687
688 self.cache_result(cache_item, r)
689 return r
690
692 self.check_connection()
693 rows = self.execute_query('SELECT `userid` FROM entropy_user_scores WHERE `userid` = %s', (userid,))
694 if rows:
695 return True
696 return False
697
703
713
715 self.check_connection()
716 myscore = None
717 self.execute_query('SELECT score FROM entropy_user_scores WHERE userid = %s',(userid,))
718 data = self.fetchone()
719 if isinstance(data,dict):
720 if data.has_key('score'): myscore = data.get('score')
721 if myscore == None: myscore = self.update_user_score(userid)
722 return myscore
723
725 self.check_connection()
726 limit_string = ''
727 if count:
728 limit_string = ' LIMIT %s,%s' % (offset,count,)
729 self.execute_query('SELECT SQL_CALC_FOUND_ROWS *,userid,score FROM entropy_user_scores ORDER BY score DESC'+limit_string)
730 data = self.fetchall()
731
732 self.execute_query('SELECT FOUND_ROWS() as count')
733 rdata = self.fetchone()
734 found_rows = 0
735 if isinstance(rdata,dict):
736 if rdata.has_key('count'):
737 found_rows = rdata.get('count')
738
739 return found_rows, data
740
742 self.check_connection()
743 self.execute_query('SELECT avg(`vote`) as vote_avg FROM entropy_votes WHERE `userid` = %s', (userid,))
744 data = self.fetchone()
745 if isinstance(data,dict):
746 if data['vote_avg']: return round(float(data['vote_avg']),2)
747 return 0.0
748
750 self.check_connection()
751 self.execute_query("""
752 SELECT * FROM entropy_docs,entropy_base WHERE
753 entropy_docs.`userid` = %s AND
754 entropy_base.idkey = entropy_docs.idkey ORDER BY entropy_base.`key`""", (userid,))
755 return self.fetchall()
756
759
762
767
769 self.check_connection()
770 self.execute_query('SELECT * FROM entropy_docs WHERE `userid` = %s AND `iddoctype` '+doctype_sql_cmp+' %s', (userid,doctype,))
771 return self.fetchall()
772
774 self.check_connection()
775 self.execute_query('SELECT count(`iddoc`) as docs FROM entropy_docs WHERE `userid` = %s AND `iddoctype` '+doctype_sql_cmp+' %s', (userid,doctype,))
776 data = self.fetchone()
777 if isinstance(data,dict):
778 if data['docs']: return data['docs']
779 return 0
780
783
786
789
792
795
797 self.check_connection()
798 self.execute_query('SELECT count(`idvote`) as votes FROM entropy_votes WHERE `userid` = %s', (userid,))
799 data = self.fetchone()
800 if isinstance(data,dict):
801 if data['votes']: return data['votes']
802 return 0
803
817
826
827 - def search_pkgkey_items(self, pkgkey_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
828 self.check_connection()
829
830 if iddoctypes == None:
831 iddoctypes = [self.DOC_TYPES[x] for x in self.DOC_TYPES]
832 iddoctypes = "("+', '.join([str(self.DOC_TYPES[x]) for x in self.DOC_TYPES])+")"
833 myterm = "%"+pkgkey_string+"%"
834
835 search_params = [myterm,results_offset,results_limit]
836
837 order_by_string = ''
838 if order_by == "key":
839 order_by_string = 'ORDER BY entropy_base.`key`'
840 elif order_by == "username":
841 order_by_string = 'ORDER BY entropy_docs.`username`'
842 elif order_by == "vote":
843 order_by_string = 'ORDER BY avg_vote DESC'
844 elif order_by == "downloads":
845 order_by_string = 'ORDER BY tot_downloads DESC'
846
847 self.execute_query("""
848 SELECT SQL_CALC_FOUND_ROWS *, avg(entropy_votes.`vote`) as avg_vote,
849 sum(entropy_downloads.`count`) as `tot_downloads`,
850 entropy_user_scores.`score` as `score` FROM
851 entropy_docs,entropy_base,entropy_votes,entropy_downloads,entropy_user_scores WHERE
852 entropy_base.`key` LIKE %s AND
853 entropy_docs.`iddoctype` IN """+iddoctypes+""" AND
854 entropy_docs.`idkey` = entropy_base.`idkey` AND
855 entropy_votes.`idkey` = entropy_base.`idkey` AND
856 entropy_downloads.`idkey` = entropy_base.`idkey` AND
857 entropy_docs.`userid` = entropy_user_scores.`userid`
858 GROUP BY entropy_docs.`iddoc` """+order_by_string+""" LIMIT %s,%s""", search_params)
859
860 results = self.fetchall()
861 self.execute_query('SELECT FOUND_ROWS() as count')
862 data = self.fetchone()
863 found_rows = 0
864 if isinstance(data,dict):
865 if data.has_key('count'):
866 found_rows = data.get('count')
867 return results, found_rows
868
869 - def search_username_items(self, pkgkey_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
870 self.check_connection()
871
872 if iddoctypes == None:
873 iddoctypes = [self.DOC_TYPES[x] for x in self.DOC_TYPES]
874 iddoctypes = "("+', '.join([str(self.DOC_TYPES[x]) for x in self.DOC_TYPES])+")"
875 myterm = "%"+pkgkey_string+"%"
876
877 search_params = [myterm,results_offset,results_limit]
878
879 order_by_string = ''
880 if order_by == "key":
881 order_by_string = 'ORDER BY entropy_base.`key`'
882 elif order_by == "username":
883 order_by_string = 'ORDER BY entropy_docs.`username`'
884 elif order_by == "vote":
885 order_by_string = 'ORDER BY avg_vote DESC'
886 elif order_by == "downloads":
887 order_by_string = 'ORDER BY tot_downloads DESC'
888
889 self.execute_query("""
890 SELECT SQL_CALC_FOUND_ROWS *, avg(entropy_votes.`vote`) as avg_vote,
891 sum(entropy_downloads.`count`) as `tot_downloads`,
892 entropy_user_scores.`score` as `score` FROM
893 entropy_docs,entropy_base,entropy_votes,entropy_downloads,entropy_user_scores WHERE
894 entropy_docs.`username` LIKE %s AND entropy_docs.`iddoctype` IN """+iddoctypes+""" AND
895 entropy_docs.`idkey` = entropy_base.`idkey` AND
896 entropy_votes.`idkey` = entropy_base.`idkey` AND
897 entropy_downloads.`idkey` = entropy_base.`idkey` AND
898 entropy_docs.`userid` = entropy_user_scores.`userid`
899 GROUP BY entropy_docs.`iddoc` """+order_by_string+""" LIMIT %s,%s""", search_params)
900
901 results = self.fetchall()
902 self.execute_query('SELECT FOUND_ROWS() as count')
903 data = self.fetchone()
904 found_rows = 0
905 if isinstance(data,dict):
906 if data.has_key('count'):
907 found_rows = data.get('count')
908 return results, found_rows
909
910 - def search_content_items(self, pkgkey_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
911 self.check_connection()
912
913 if iddoctypes == None:
914 iddoctypes = [self.DOC_TYPES[x] for x in self.DOC_TYPES]
915 iddoctypes = "("+', '.join([str(self.DOC_TYPES[x]) for x in self.DOC_TYPES])+")"
916 myterm = "%"+pkgkey_string+"%"
917 search_params = [myterm,myterm,myterm,results_offset,results_limit]
918
919 order_by_string = ''
920 if order_by == "key":
921 order_by_string = 'ORDER BY entropy_base.`key`'
922 elif order_by == "username":
923 order_by_string = 'ORDER BY entropy_docs.`username`'
924 elif order_by == "vote":
925 order_by_string = 'ORDER BY avg_vote DESC'
926 elif order_by == "downloads":
927 order_by_string = 'ORDER BY tot_downloads DESC'
928
929 self.execute_query("""
930 SELECT SQL_CALC_FOUND_ROWS *, avg(entropy_votes.`vote`) as avg_vote,
931 sum(entropy_downloads.`count`) as `tot_downloads`,
932 entropy_user_scores.`score` as `score` FROM
933 entropy_docs,entropy_base,entropy_votes,entropy_downloads,entropy_user_scores WHERE
934 (entropy_docs.`title` LIKE %s OR entropy_docs.`description` LIKE %s OR entropy_docs.`ddata` LIKE %s) AND
935 entropy_docs.`iddoctype` IN """+iddoctypes+""" AND
936 entropy_docs.`idkey` = entropy_base.`idkey` AND
937 entropy_votes.`idkey` = entropy_base.`idkey` AND
938 entropy_downloads.`idkey` = entropy_base.`idkey` AND
939 entropy_docs.`userid` = entropy_user_scores.`userid`
940 GROUP BY entropy_docs.`iddoc` """+order_by_string+""" LIMIT %s,%s""", search_params)
941
942 results = self.fetchall()
943 self.execute_query('SELECT FOUND_ROWS() as count')
944 data = self.fetchone()
945 found_rows = 0
946 if isinstance(data,dict):
947 if data.has_key('count'):
948 found_rows = data.get('count')
949 return results, found_rows
950
951 - def search_keyword_items(self, keyword_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
952 self.check_connection()
953
954 if iddoctypes == None:
955 iddoctypes = [self.DOC_TYPES[x] for x in self.DOC_TYPES]
956 iddoctypes = "("+', '.join([str(self.DOC_TYPES[x]) for x in self.DOC_TYPES])+")"
957 myterm = "%"+keyword_string+"%"
958
959 search_params = [myterm,results_offset,results_limit]
960
961 order_by_string = ''
962 if order_by == "key":
963 order_by_string = 'ORDER BY entropy_base.`key`'
964 elif order_by == "username":
965 order_by_string = 'ORDER BY entropy_docs.`username`'
966 elif order_by == "vote":
967 order_by_string = 'ORDER BY avg_vote DESC'
968 elif order_by == "downloads":
969 order_by_string = 'ORDER BY tot_downloads DESC'
970
971 self.execute_query("""
972 SELECT SQL_CALC_FOUND_ROWS *, avg(entropy_votes.`vote`) as avg_vote,
973 sum(entropy_downloads.`count`) as `tot_downloads`,
974 entropy_user_scores.`score` as `score` FROM
975 entropy_docs,entropy_base,entropy_docs_keywords,entropy_votes,entropy_downloads,entropy_user_scores WHERE
976 entropy_docs_keywords.`keyword` LIKE %s AND
977 entropy_docs.`iddoctype` IN """+iddoctypes+""" AND
978 entropy_docs.`idkey` = entropy_base.`idkey` AND
979 entropy_docs_keywords.`iddoc` = entropy_docs.`iddoc` AND
980 entropy_votes.`idkey` = entropy_base.`idkey` AND
981 entropy_downloads.`idkey` = entropy_base.`idkey` AND
982 entropy_docs.`userid` = entropy_user_scores.`userid`
983 GROUP BY entropy_docs.`iddoc` """+order_by_string+""" LIMIT %s,%s""", search_params)
984
985 results = self.fetchall()
986 self.execute_query('SELECT FOUND_ROWS() as count')
987 data = self.fetchone()
988 found_rows = 0
989 if isinstance(data,dict):
990 if data.has_key('count'):
991 found_rows = data.get('count')
992 return results, found_rows
993
994 - def search_iddoc_item(self, iddoc_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
995 self.check_connection()
996
997 if iddoctypes == None:
998 iddoctypes = [self.DOC_TYPES[x] for x in self.DOC_TYPES]
999 iddoctypes = "("+', '.join([str(self.DOC_TYPES[x]) for x in self.DOC_TYPES])+")"
1000 try:
1001 myterm = int(iddoc_string)
1002 except ValueError:
1003 return [],0
1004
1005 search_params = [myterm,results_offset,results_limit]
1006
1007 order_by_string = ''
1008 if order_by == "key":
1009 order_by_string = 'ORDER BY entropy_base.`key`'
1010 elif order_by == "username":
1011 order_by_string = 'ORDER BY entropy_docs.`username`'
1012 elif order_by == "vote":
1013 order_by_string = 'ORDER BY avg_vote DESC'
1014 elif order_by == "downloads":
1015 order_by_string = 'ORDER BY tot_downloads DESC'
1016
1017 self.execute_query("""
1018 SELECT SQL_CALC_FOUND_ROWS *, avg(entropy_votes.`vote`) as avg_vote,
1019 sum(entropy_downloads.`count`) as `tot_downloads`,
1020 entropy_user_scores.`score` as `score` FROM
1021 entropy_docs,entropy_base,entropy_votes,entropy_downloads,entropy_user_scores WHERE
1022 entropy_docs.`iddoc` = %s AND
1023 entropy_docs.`iddoctype` IN """+iddoctypes+""" AND
1024 entropy_docs.`idkey` = entropy_base.`idkey` AND
1025 entropy_votes.`idkey` = entropy_base.`idkey` AND
1026 entropy_downloads.`idkey` = entropy_base.`idkey` AND
1027 entropy_docs.`userid` = entropy_user_scores.`userid`
1028 GROUP BY entropy_docs.`iddoc` """+order_by_string+""" LIMIT %s,%s""", search_params)
1029
1030 results = self.fetchall()
1031 self.execute_query('SELECT FOUND_ROWS() as count')
1032 data = self.fetchone()
1033 found_rows = 0
1034 if isinstance(data,dict):
1035 if data.has_key('count'):
1036 found_rows = data.get('count')
1037 return results, found_rows
1038
1043
1045 self.check_connection()
1046 self.execute_query('SELECT max(`ts`) as ts FROM entropy_docs WHERE `userid` = %s', (userid,))
1047 data = self.fetchone()
1048 if not data:
1049 return False
1050 elif not data.has_key('ts'):
1051 return False
1052 elif data['ts'] == None:
1053 return False
1054 delta = self.datetime.fromtimestamp(time.time()) - data['ts']
1055 if (delta.days == 0) and (delta.seconds <= self.FLOOD_INTERVAL):
1056 return True
1057 return False
1058
1059 - def insert_generic_doc(self, idkey, userid, username, doc_type, data, title, description, keywords, do_commit = False):
1060 self.check_connection()
1061
1062 title = title[:self.entropy_docs_title_len]
1063 description = description[:self.entropy_docs_description_len]
1064
1065
1066 flood_risk = self.insert_flood_control_check(userid)
1067 if flood_risk: return 'flooding detected'
1068
1069 self.execute_query('INSERT INTO entropy_docs VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)',(
1070 None,
1071 idkey,
1072 userid,
1073 username,
1074 doc_type,
1075 data,
1076 title,
1077 description,
1078 None,
1079 )
1080 )
1081 if do_commit: self.commit()
1082 iddoc = self.lastrowid()
1083 self.insert_keywords(iddoc, keywords)
1084 self.update_user_score(userid)
1085 return iddoc
1086
1088 keywords = keywords.split(",")
1089 clean_keys = []
1090 for key in keywords:
1091 try:
1092 key = key.strip().split()[0]
1093 except IndexError:
1094 continue
1095 if not key: continue
1096 if not key.isalnum(): continue
1097 key = key[:self.entropy_docs_keyword_len]
1098 if key in clean_keys: continue
1099 clean_keys.append(key)
1100
1101 if not clean_keys:
1102 return
1103
1104 mydata = []
1105 for key in clean_keys:
1106 mydata.append((iddoc, key,))
1107
1108 self.execute_many('INSERT INTO entropy_docs_keywords VALUES (%s,%s)', mydata)
1109
1111 self.execute_query('DELETE FROM entropy_docs_keywords WHERE `iddoc` = %s',(iddoc,))
1112
1121
1138
1150
1151
1152 - def do_vote(self, pkgkey, userid, vote, do_commit = False):
1153 self.check_connection()
1154 idkey = self.handle_pkgkey(pkgkey)
1155 vote = int(vote)
1156 if vote not in self.VOTE_RANGE:
1157 vote = 3
1158 mydate = self.get_date()
1159 if self.has_user_already_voted(pkgkey, userid):
1160 return False
1161 self.execute_query('INSERT INTO entropy_votes VALUES (%s,%s,%s,%s,%s,%s)',(
1162 None,
1163 idkey,
1164 userid,
1165 mydate,
1166 vote,
1167 None,
1168 )
1169 )
1170 if do_commit: self.commit()
1171 self.update_user_score(userid)
1172 return True
1173
1175 self.check_connection()
1176 idkey = self.handle_pkgkey(pkgkey)
1177 self.execute_query('SELECT `idvote` FROM entropy_votes WHERE `idkey` = %s AND `userid` = %s', (idkey,userid,))
1178 data = self.fetchone()
1179 if data:
1180 return True
1181 return False
1182
1183
1184 - def do_downloads(self, pkgkeys, ip_addr = None, do_commit = False):
1185 self.check_connection()
1186 mydate = self.get_date()
1187 iddownloads = set()
1188 for pkgkey in pkgkeys:
1189 iddownload = self.get_iddownload(pkgkey, mydate)
1190 if iddownload == -1:
1191 iddownload = self.insert_download(pkgkey, mydate, count = 1)
1192 else:
1193 self.update_download(iddownload)
1194 if (iddownload > 0) and isinstance(ip_addr,basestring):
1195 iddownloads.add(iddownload)
1196
1197 if iddownloads: self.store_download_data(iddownloads, ip_addr)
1198 if do_commit: self.commit()
1199 return True
1200
1201 - def do_download_stats(self, branch, release_string, hw_hash, pkgkeys,
1202 ip_addr, do_commit = False):
1203
1204 self.check_connection()
1205 branch_id = self.get_entropy_branches_id(branch)
1206 if branch_id == -1:
1207 branch_id = self.insert_entropy_branch(branch)
1208
1209 rel_strings_id = self.get_entropy_release_strings_id(release_string)
1210 if rel_strings_id == -1:
1211 rel_strings_id = self.insert_entropy_release_string(release_string)
1212
1213 self.do_downloads(pkgkeys, ip_addr = ip_addr)
1214
1215 entropy_distribution_usage_id = self.is_user_ip_available_in_entropy_distribution_usage(ip_addr)
1216
1217 hits = 1
1218 if self.STATS_MAP['installer'] in pkgkeys:
1219 hits = 0
1220 if entropy_distribution_usage_id == -1:
1221 entropy_ip_locations_id = self.handle_entropy_ip_locations_id(ip_addr)
1222 self.execute_query('INSERT INTO entropy_distribution_usage VALUES (%s,%s,%s,%s,%s,%s,%s,%s)',(
1223 None,
1224 branch_id,
1225 rel_strings_id,
1226 None,
1227 ip_addr,
1228 entropy_ip_locations_id,
1229 self.get_datetime(),
1230 hits,
1231 )
1232 )
1233 entropy_distribution_usage_id = self.lastrowid()
1234 else:
1235 self.execute_query("""
1236 UPDATE entropy_distribution_usage SET `entropy_branches_id` = %s,
1237 `entropy_release_strings_id` = %s,
1238 `hits` = `hits`+%s
1239 WHERE `entropy_distribution_usage_id` = %s
1240 """,(
1241 branch_id,
1242 rel_strings_id,
1243 hits,
1244 entropy_distribution_usage_id,
1245 )
1246 )
1247
1248
1249 if hw_hash and not \
1250 self.is_entropy_hardware_usage_stats_available(entropy_distribution_usage_id):
1251
1252 self.do_entropy_hardware_usage_stats(entropy_distribution_usage_id,
1253 hw_hash)
1254
1255 if do_commit: self.commit()
1256 return True
1257
1259
1260 self.execute_query('INSERT INTO entropy_hardware_usage VALUES (%s,%s,%s)', (
1261 None,
1262 entropy_distribution_usage_id,
1263 hw_hash,
1264 )
1265 )
1266
1268 self.check_connection()
1269 self.execute_query('SELECT entropy_hardware_usage_id FROM entropy_hardware_usage WHERE `entropy_distribution_usage_id` = %s',(entropy_distribution_usage_id,))
1270 data = self.fetchone()
1271 if data:
1272 return True
1273 return False
1274
1276 self.check_connection()
1277 self.execute_query('SELECT entropy_distribution_usage_id FROM entropy_distribution_usage WHERE `ip_address` = %s',(ip_address,))
1278 data = self.fetchone()
1279 if data:
1280 return data['entropy_distribution_usage_id']
1281 return -1
1282
1283 - def insert_document(self, pkgkey, userid, username, text, title, description, keywords, doc_type = None, do_commit = False):
1284 self.check_connection()
1285 idkey = self.handle_pkgkey(pkgkey)
1286 if doc_type == None: doc_type = self.DOC_TYPES['bbcode_doc']
1287 iddoc = self.insert_generic_doc(idkey, userid, username, doc_type, text, title, description, keywords)
1288 if isinstance(iddoc,basestring):
1289 return False, iddoc
1290 if do_commit: self.commit()
1291 return True, iddoc
1292
1293 - def edit_document(self, iddoc, new_document, new_title, new_keywords, do_commit = False):
1311
1323
1325
1326 if not os.access(filepath,os.R_OK):
1327 return False,None
1328
1329 args = [self.VIRUS_CHECK_EXEC]
1330 args += self.VIRUS_CHECK_ARGS
1331 args += [filepath]
1332 f = open("/dev/null","w")
1333 p = subprocess.Popen(args, stdout = f, stderr = f)
1334 rc = p.wait()
1335 f.close()
1336 if rc == 1:
1337 return True,None
1338 return False,None
1339
1340 - def insert_generic_file(self, pkgkey, userid, username, file_path, file_name, doc_type, title, description, keywords):
1341 self.check_connection()
1342 file_path = os.path.realpath(file_path)
1343
1344
1345 virus_found, virus_type = self.scan_for_viruses(file_path)
1346 if virus_found:
1347 os.remove(file_path)
1348 return False, None
1349
1350
1351 flood_risk = self.insert_flood_control_check(userid)
1352 if flood_risk: return False, 'flooding detected'
1353
1354
1355 if doc_type == self.DOC_TYPES['image']:
1356 valid = False
1357 if os.path.isfile(file_path) and os.access(file_path,os.R_OK):
1358 valid = self.entropyTools.is_supported_image_file(file_path)
1359 if not valid:
1360 return False, 'not a valid image'
1361
1362 dest_path = os.path.join(self.STORE_PATH,file_name)
1363
1364
1365 dest_dir = os.path.dirname(dest_path)
1366 if not os.path.isdir(dest_dir):
1367 try:
1368 os.makedirs(dest_dir)
1369 except OSError, e:
1370 raise PermissionDenied('PermissionDenied: %s' % (e,))
1371 if etpConst['entropygid'] != None:
1372 const_setup_perms(dest_dir,etpConst['entropygid'])
1373
1374 orig_dest_path = dest_path
1375 dcount = 0
1376 while os.path.isfile(dest_path):
1377 dcount += 1
1378 dest_path_name = "%s_%s" % (dcount,os.path.basename(orig_dest_path),)
1379 dest_path = os.path.join(os.path.dirname(orig_dest_path),dest_path_name)
1380
1381 if os.path.dirname(file_path) != dest_dir:
1382 shutil.move(file_path,dest_path)
1383 if etpConst['entropygid'] != None:
1384 try:
1385 const_setup_file(dest_path, etpConst['entropygid'], 0664)
1386 except OSError:
1387 pass
1388
1389 try: const_set_chmod(dest_path,0664)
1390 except OSError: pass
1391
1392 title = title[:self.entropy_docs_title_len]
1393 description = description[:self.entropy_docs_description_len]
1394
1395
1396 idkey = self.handle_pkgkey(pkgkey)
1397 self.execute_query('INSERT INTO entropy_docs VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)',(
1398 None,
1399 idkey,
1400 userid,
1401 username,
1402 doc_type,
1403 file_name,
1404 title,
1405 description,
1406 None,
1407 )
1408 )
1409 iddoc = self.lastrowid()
1410 self.insert_keywords(iddoc, keywords)
1411 store_url = os.path.basename(dest_path)
1412 if self.store_url:
1413 store_url = os.path.join(self.store_url,store_url)
1414 self.update_user_score(userid)
1415 return True, (iddoc, store_url)
1416
1417 - def insert_image(self, pkgkey, userid, username, image_path, file_name, title, description, keywords):
1418 return self.insert_generic_file(pkgkey, userid, username, image_path, file_name, self.DOC_TYPES['image'], title, description, keywords)
1419
1420 - def insert_file(self, pkgkey, userid, username, file_path, file_name, title, description, keywords):
1421 return self.insert_generic_file(pkgkey, userid, username, file_path, file_name, self.DOC_TYPES['generic_file'], title, description, keywords)
1422
1425
1428
1430 self.check_connection()
1431
1432 userid = self.get_iddoc_userid(iddoc)
1433 self.execute_query('SELECT `ddata` FROM entropy_docs WHERE `iddoc` = %s AND `iddoctype` = %s',(
1434 iddoc,
1435 doc_type,
1436 )
1437 )
1438 data = self.fetchone()
1439 if data != None:
1440 mypath = data.get('ddata')
1441 if not isinstance(mypath,basestring):
1442 mypath = mypath.tostring()
1443 if mypath != None:
1444 mypath = os.path.join(self.STORE_PATH,mypath)
1445 if os.path.isfile(mypath) and os.access(mypath,os.W_OK):
1446 os.remove(mypath)
1447
1448 self.remove_keywords(iddoc)
1449 self.execute_query('DELETE FROM entropy_docs WHERE `iddoc` = %s AND `iddoctype` = %s',(
1450 iddoc,
1451 doc_type,
1452 )
1453 )
1454 if userid: self.update_user_score(userid)
1455 return True, (iddoc, None)
1456
1457 - def insert_youtube_video(self, pkgkey, userid, username, video_path, file_name, title, description, keywords):
1458 self.check_connection()
1459 if not self.gdata:
1460 return False, None
1461
1462 idkey = self.handle_pkgkey(pkgkey)
1463 video_path = os.path.realpath(video_path)
1464 if not (os.access(video_path,os.R_OK) and os.path.isfile(video_path)):
1465 return False
1466 virus_found, virus_type = self.scan_for_viruses(video_path)
1467 if virus_found:
1468 os.remove(video_path)
1469 return False, None
1470
1471 new_video_path = video_path
1472 if isinstance(file_name,basestring):
1473
1474 new_video_path = os.path.join(os.path.dirname(video_path),os.path.basename(file_name))
1475 scount = 0
1476 while os.path.lexists(new_video_path):
1477 scount += 1
1478 bpath = "%s.%s" % (unicode(scount),os.path.basename(file_name),)
1479 new_video_path = os.path.join(os.path.dirname(video_path),bpath)
1480 shutil.move(video_path,new_video_path)
1481
1482 yt_service = self.get_youtube_service()
1483 if yt_service == None:
1484 return False, None
1485
1486 mykeywords = ', '.join([x.strip().strip(',') for x in keywords.split()+["sabayon"] if (x.strip() and x.strip(",") and (len(x.strip()) > 4))])
1487 gd_keywords = self.gdata.media.Keywords(text = mykeywords)
1488
1489 mydescription = "%s: %s" % (pkgkey,description,)
1490 mytitle = "%s: %s" % (self.system_name,title,)
1491 my_media_group = self.gdata.media.Group(
1492 title = self.gdata.media.Title(text = mytitle),
1493 description = self.gdata.media.Description(
1494 description_type = 'plain',
1495 text = mydescription
1496 ),
1497 keywords = gd_keywords,
1498 category = self.gdata.media.Category(
1499 text = 'Tech',
1500 scheme = 'http://gdata.youtube.com/schemas/2007/categories.cat',
1501 label = 'Tech'
1502 ),
1503 player = None
1504 )
1505 video_entry = self.gdata.youtube.YouTubeVideoEntry(media = my_media_group)
1506 new_entry = yt_service.InsertVideoEntry(video_entry, new_video_path)
1507 if not isinstance(new_entry,self.gdata.youtube.YouTubeVideoEntry):
1508 return False, None
1509 video_url = new_entry.GetSwfUrl()
1510 video_id = os.path.basename(video_url)
1511
1512 iddoc = self.insert_generic_doc(idkey, userid, username, self.DOC_TYPES['youtube_video'], video_id, title, description, keywords)
1513 if isinstance(iddoc,basestring):
1514 return False, (iddoc, None,)
1515 return True, (iddoc, video_id,)
1516
1536
1537 self.execute_query('SELECT `ddata` FROM entropy_docs WHERE `iddoc` = %s AND `iddoctype` = %s',(
1538 iddoc,
1539 self.DOC_TYPES['youtube_video'],
1540 )
1541 )
1542 data = self.fetchone()
1543 if data == None:
1544 do_remove()
1545 return False, None
1546 elif not data.has_key('ddata'):
1547 do_remove()
1548 return False, None
1549
1550 video_id = data.get('ddata')
1551 try:
1552 video_entry = yt_service.GetYouTubeVideoEntry(video_id = video_id)
1553 deleted = yt_service.DeleteVideoEntry(video_entry)
1554 except:
1555 deleted = True
1556
1557 if deleted:
1558 do_remove()
1559 if userid: self.update_user_score(userid)
1560 return deleted, (iddoc, video_id,)
1561
1563 self.check_connection()
1564 if not self.gdata:
1565 return None
1566 keywords = ['google_email', 'google_password']
1567 for keyword in keywords:
1568 if not self.connection_data.has_key(keyword):
1569 return None
1570
1571 srv = self.YouTubeService.YouTubeService()
1572 srv.email = self.connection_data['google_email']
1573 srv.password = self.connection_data['google_password']
1574 if self.connection_data.has_key('google_developer_key'):
1575 srv.developer_key = self.connection_data['google_developer_key']
1576 if self.connection_data.has_key('google_client_id'):
1577 srv.client_id = self.connection_data['google_client_id']
1578 srv.source = 'Entropy'
1579 srv.ProgrammaticLogin()
1580 return srv
1581
1583
1584 import socket
1585 import entropy.dump as dumpTools
1586 import entropy.tools as entropyTools
1587 import zlib
1588 import select
1589 - def __init__(self, OutputInterface, ClientCommandsClass, quiet = False, show_progress = True, output_header = '', ssl = False, socket_timeout = 25):
1590
1591
1592 if not hasattr(OutputInterface,'updateProgress'):
1593 mytxt = _("OutputInterface does not have an updateProgress method")
1594 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
1595 elif not callable(OutputInterface.updateProgress):
1596 mytxt = _("OutputInterface does not have an updateProgress method")
1597 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
1598
1599 from entropy.client.services.ugc.commands import Base
1600 if not issubclass(ClientCommandsClass, (Base,)):
1601 mytxt = _("A valid entropy.client.services.ugc.commands.Base interface is needed")
1602 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (ClientCommandsClass,mytxt,))
1603
1604 self.ssl_mod = None
1605 self.setup_ssl(ssl)
1606
1607 self.answers = etpConst['socket_service']['answers']
1608 self.Output = OutputInterface
1609 self.sock_conn = None
1610 self.real_sock_conn = None
1611 self.hostname = None
1612 self.hostport = None
1613 self.buffered_data = ''
1614 self.buffer_length = None
1615 self.quiet = quiet
1616 self.show_progress = show_progress
1617 self.output_header = output_header
1618 self.CmdInterface = ClientCommandsClass(self.Output, self)
1619 self.CmdInterface.output_header = self.output_header
1620 self.socket_timeout = socket_timeout
1621 self.socket.setdefaulttimeout(self.socket_timeout)
1622
1623
1625
1626 self.SSL = {}
1627 self.SSL_exceptions = {
1628 'WantReadError': None,
1629 'WantWriteError': None,
1630 'WantX509LookupError': None,
1631 'ZeroReturnError': None,
1632 'Error': None,
1633 'SysCallError': None
1634 }
1635 self.ssl = ssl
1636 self.pyopenssl = True
1637 self.context = None
1638
1639 '''
1640 self.server_cert = server_cert
1641 self.server_ca_cert = server_ca_cert
1642 self.ssl_pkey = None
1643 self.ssl_cert = None
1644 self.ssl_CN = 'Entropy Repository Service Client'
1645 self.ssl_digest = 'md5'
1646 self.ssl_serial = 1
1647 self.ssl_not_before = 0
1648 self.ssl_not_after = 60*60*24*1 # 1 day
1649 '''
1650
1651 if self.ssl:
1652
1653 try:
1654 from OpenSSL import SSL, crypto
1655 except ImportError:
1656 self.pyopenssl = False
1657
1658
1659 try:
1660 import ssl as ssl_mod
1661 self.ssl_mod = ssl_mod
1662 except ImportError:
1663 pass
1664
1665 '''
1666 if not (self.server_cert and self.server_ca_cert):
1667 raise SSLError('SSLError: %s: %s' % (_("Specified SSL server certificate not available"),)
1668 if not (os.path.isfile(self.server_cert) and \
1669 os.access(self.server_cert,os.R_OK) and \
1670 os.path.isfile(self.server_ca_cert) and \
1671 os.access(self.server_ca_cert,os.R_OK)) and self.pyopenssl:
1672 raise SSLError('SSLError: %s: %s' % (_("Specified SSL server certificate not available"),self.server_cert,))
1673 '''
1674
1675 if self.pyopenssl:
1676
1677 self.SSL_exceptions['WantReadError'] = SSL.WantReadError
1678 self.SSL_exceptions['WantWriteError'] = SSL.WantWriteError
1679 self.SSL_exceptions['WantX509LookupError'] = SSL.WantX509LookupError
1680 self.SSL_exceptions['ZeroReturnError'] = SSL.ZeroReturnError
1681 self.SSL_exceptions['Error'] = SSL.Error
1682 self.SSL_exceptions['SysCallError'] = SSL.SysCallError
1683 self.SSL['m'] = SSL
1684 self.SSL['crypto'] = crypto
1685
1686
1687 self.context = self.SSL['m'].Context(self.SSL['m'].SSLv23_METHOD)
1688
1689
1690
1691 '''
1692 self.ssl_pkey = self.create_ssl_key_pair(self.SSL['crypto'].TYPE_RSA, 1024)
1693 self.context.use_privatekey(self.ssl_pkey)
1694 self.context.use_certificate_file(self.server_cert)
1695 self.context.load_verify_locations(self.server_ca_cert)
1696 self.context.load_client_ca(self.server_cert)
1697 self.ssl_pkey = self.create_ssl_key_pair(self.SSL['crypto'].TYPE_RSA, 1024)
1698 self.ssl_cert = self.create_ssl_certificate(self.ssl_pkey)
1699 self.context.use_privatekey(self.ssl_pkey)
1700 self.context.use_certificate(self.ssl_cert)
1701 self.context.load_client_ca(self.server_cert)
1702 '''
1703
1704 else:
1705 self.ssl = False
1706 self.pyopenssl = False
1707
1708
1710 if not self.pyopenssl:
1711 raise SSLError('SSLError: %s' % (_("OpenSSL Python module not available, you need dev-python/pyopenssl"),))
1712
1713 '''
1714 # this function should do the authentication checking to see that
1715 # the client is who they say they are.
1716 def verify_ssl_cb(self, conn, cert, errnum, depth, ok):
1717 self.check_pyopenssl()
1718 #print 'Got certificate: %s' % cert.get_subject()
1719 #print repr(ok),repr(cert),repr(errnum),repr(depth)
1720 return ok
1721
1722
1723 def create_ssl_key_pair(self, keytype, bits):
1724 if not self.pyopenssl:
1725 raise SSLError('SSLError: %s' % (_("OpenSSL Python module not available, you need dev-python/pyopenssl"),))
1726 pkey = self.SSL['crypto'].PKey()
1727 pkey.generate_key(keytype, bits)
1728 return pkey
1729
1730 def create_ssl_certificate(self, pkey):
1731 self.check_pyopenssl()
1732 myreq = self.create_ssl_certificate_request(pkey, CN = self.ssl_CN)
1733 cert = self.SSL['crypto'].X509()
1734 cert.set_serial_number(self.ssl_serial)
1735 cert.gmtime_adj_notBefore(self.ssl_not_before)
1736 cert.gmtime_adj_notAfter(self.ssl_not_after)
1737 cert.set_issuer(myreq.get_subject())
1738 cert.set_subject(myreq.get_subject())
1739 cert.set_pubkey(myreq.get_pubkey())
1740 cert.sign(pkey, self.ssl_digest)
1741 return cert
1742
1743 def create_ssl_certificate_request(self, pkey, **name):
1744 self.check_pyopenssl()
1745 req = self.SSL['crypto'].X509Req()
1746 subj = req.get_subject()
1747 for (key,value) in name.items():
1748 setattr(subj, key, value)
1749 req.set_pubkey(pkey)
1750 req.sign(pkey, self.ssl_digest)
1751
1752 return req
1753 '''
1754
1756
1757 if gzipped:
1758 data = self.zlib.decompress(data)
1759 obj = self.dumpTools.unserialize_string(data)
1760
1761 return obj
1762
1764 return str(len(data))+self.answers['eos']+data
1765
1767 self.check_socket_connection()
1768 if hasattr(self.sock_conn,'settimeout'):
1769 self.sock_conn.settimeout(self.socket_timeout)
1770 data = self.append_eos(data)
1771 try:
1772
1773 if self.ssl and not self.pyopenssl:
1774 try:
1775 self.sock_conn.write(data)
1776 except UnicodeEncodeError:
1777 self.sock_conn.write(data.encode('utf-8'))
1778 else:
1779 encode_done = False
1780 mydata = data[:]
1781 while 1:
1782 try:
1783 sent = self.sock_conn.send(mydata)
1784 if sent == len(mydata):
1785 break
1786 mydata = mydata[sent:]
1787 except (self.SSL_exceptions['WantWriteError'],self.SSL_exceptions['WantReadError'],):
1788 time.sleep(0.2)
1789 continue
1790 except UnicodeEncodeError, e:
1791 if encode_done:
1792 raise
1793 mydata = mydata.encode('utf-8')
1794 encode_done = True
1795 continue
1796
1797 except self.SSL_exceptions['Error'], e:
1798 self.disconnect()
1799 raise SSLError('SSLError: %s' % (e,))
1800 except self.socket.sslerror, e:
1801 self.disconnect()
1802 raise SSLError('SSL Socket error: %s' % (e,))
1803 except:
1804 self.disconnect()
1805 raise
1806
1808 self.check_socket_connection()
1809 try:
1810 self.transmit("%s end" % (session_id,))
1811
1812 data = self.receive()
1813 except self.socket.error, e:
1814 if etpUi['debug']:
1815 self.entropyTools.print_traceback()
1816 import pdb
1817 pdb.set_trace()
1818 if e[0] == 32:
1819 return None
1820 raise
1821 except SSLError:
1822 raise
1823 return data
1824
1831
1833 self.check_socket_connection()
1834 self.socket.setdefaulttimeout(self.socket_timeout)
1835 self.transmit('alive %s' % (session,))
1836 data = self.receive()
1837 if data == self.answers['ok']:
1838 return True
1839 return False
1840
1842
1843 self.check_socket_connection()
1844 if hasattr(self.sock_conn,'settimeout'):
1845 self.sock_conn.settimeout(self.socket_timeout)
1846 self.ssl_prepending = True
1847
1848 def do_receive():
1849 data = ''
1850 if self.ssl and not self.pyopenssl:
1851 data = self.sock_conn.read(1024)
1852 elif self.ssl:
1853 if self.ssl_prepending:
1854 data = self.sock_conn.recv(1024)
1855 self.ssl_prepending = False
1856 while self.sock_conn.pending():
1857 data += self.sock_conn.recv(1024)
1858 else:
1859 data = self.sock_conn.recv(1024)
1860 return data
1861
1862 myeos = self.answers['eos']
1863 ssl_error_loop_count = 0
1864 while 1:
1865
1866 try:
1867
1868 data = do_receive()
1869 if self.buffer_length == None:
1870 self.buffered_data = ''
1871 if (data == '') or (data == self.answers['cl']):
1872
1873
1874 if not self.quiet:
1875 mytxt = _("command not supported. receive aborted")
1876 self.Output.updateProgress(
1877 "[%s:%s] %s" % (
1878 brown(self.hostname),
1879 bold(str(self.hostport)),
1880 blue(mytxt),
1881 ),
1882 importance = 1,
1883 type = "warning",
1884 header = self.output_header
1885 )
1886 return None
1887 elif len(data) < len(myeos):
1888 if not self.quiet:
1889 mytxt = _("malformed EOS. receive aborted")
1890 self.Output.updateProgress(
1891 "[%s:%s] %s" % (
1892 brown(self.hostname),
1893 bold(str(self.hostport)),
1894 blue(mytxt),
1895 ),
1896 importance = 1,
1897 type = "warning",
1898 header = self.output_header
1899 )
1900 if etpUi['debug']:
1901 self.entropyTools.print_traceback()
1902 import pdb
1903 pdb.set_trace()
1904 return None
1905 mystrlen = data.split(myeos)[0]
1906 self.buffer_length = int(mystrlen)
1907 data = data[len(mystrlen)+1:]
1908 self.buffer_length -= len(data)
1909 self.buffered_data = data
1910 else:
1911 self.buffer_length -= len(data)
1912 self.buffered_data += data
1913
1914 while self.buffer_length > 0:
1915 x = do_receive()
1916 if self.ssl and self.pyopenssl and not x:
1917 self.ssl_prepending = True
1918 self.buffer_length -= len(x)
1919 self.buffered_data += x
1920 self.buffer_length = None
1921 break
1922
1923 except ValueError, e:
1924 if not self.quiet:
1925 mytxt = _("malformed data. receive aborted")
1926 self.Output.updateProgress(
1927 "[%s:%s] %s: %s" % (
1928 brown(self.hostname),
1929 bold(str(self.hostport)),
1930 blue(mytxt),
1931 e,
1932 ),
1933 importance = 1,
1934 type = "warning",
1935 header = self.output_header
1936 )
1937 return None
1938 except self.socket.timeout, e:
1939 if not self.quiet:
1940 mytxt = _("connection timed out while receiving data")
1941 self.Output.updateProgress(
1942 "[%s:%s] %s: %s" % (
1943 brown(self.hostname),
1944 bold(str(self.hostport)),
1945 blue(mytxt),
1946 e,
1947 ),
1948 importance = 1,
1949 type = "warning",
1950 header = self.output_header
1951 )
1952 return None
1953 except self.socket.error, e:
1954 if not self.quiet:
1955 mytxt = _("connection error while receiving data")
1956 self.Output.updateProgress(
1957 "[%s:%s] %s: %s" % (
1958 brown(self.hostname),
1959 bold(str(self.hostport)),
1960 blue(mytxt),
1961 e,
1962 ),
1963 importance = 1,
1964 type = "warning",
1965 header = self.output_header
1966 )
1967 return None
1968 except (self.SSL_exceptions['WantReadError'],self.SSL_exceptions['WantX509LookupError'],), e:
1969 ssl_error_loop_count += 1
1970 if ssl_error_loop_count > 3000000:
1971 if not self.quiet:
1972 mytxt = _("too many WantReadError error while receiving data")
1973 self.Output.updateProgress(
1974 "[%s:%s] %s: %s" % (
1975 brown(self.hostname),
1976 bold(str(self.hostport)),
1977 blue(mytxt),
1978 e,
1979 ),
1980 importance = 1,
1981 type = "warning",
1982 header = self.output_header
1983 )
1984 return None
1985 continue
1986 except self.SSL_exceptions['ZeroReturnError']:
1987 break
1988 except self.SSL_exceptions['SysCallError'], e:
1989 if not self.quiet:
1990 mytxt = _("syscall error while receiving data")
1991 self.Output.updateProgress(
1992 "[%s:%s] %s: %s" % (
1993 brown(self.hostname),
1994 bold(str(self.hostport)),
1995 blue(mytxt),
1996 e,
1997 ),
1998 importance = 1,
1999 type = "warning",
2000 header = self.output_header
2001 )
2002 return None
2003
2004 return self.buffered_data
2005
2007 if not self.quiet:
2008 mytxt = _("Reconnecting to socket")
2009 self.Output.updateProgress(
2010 "[%s:%s] %s" % (
2011 brown(unicode(self.hostname)),
2012 bold(unicode(self.hostport)),
2013 blue(mytxt),
2014 ),
2015 importance = 1,
2016 type = "info",
2017 header = self.output_header
2018 )
2019 self.connect(self.hostname,self.hostport)
2020
2022 if not self.sock_conn:
2023 raise ConnectionError("ConnectionError: %s" % (_("Not connected to host"),))
2024
2026
2027 if self.ssl:
2028 self.real_sock_conn = self.socket.socket(self.socket.AF_INET, self.socket.SOCK_STREAM)
2029 if hasattr(self.real_sock_conn,'settimeout'):
2030 self.real_sock_conn.settimeout(self.socket_timeout)
2031 if self.pyopenssl:
2032 self.sock_conn = self.SSL['m'].Connection(self.context, self.real_sock_conn)
2033 else:
2034 self.sock_conn = self.real_sock_conn
2035 else:
2036 self.sock_conn = self.socket.socket(self.socket.AF_INET, self.socket.SOCK_STREAM)
2037 if hasattr(self.sock_conn,'settimeout'):
2038 self.sock_conn.settimeout(self.socket_timeout)
2039 self.real_sock_conn = self.sock_conn
2040
2041 self.hostname = host
2042 self.hostport = port
2043
2044 try:
2045 self.sock_conn.connect((self.hostname, self.hostport))
2046 if self.ssl and not self.pyopenssl:
2047 if self.ssl_mod != None:
2048 self.sock_conn = self.ssl_mod.wrap_socket(self.real_sock_conn)
2049 else:
2050 self.sock_conn = self.socket.ssl(self.real_sock_conn)
2051
2052 if not self.quiet:
2053 mytxt = _("Warning: you are using an emergency SSL interface, SSL certificate can't be verified. Please install dev-python/pyopenssl")
2054 self.Output.updateProgress(
2055 "[%s:%s] %s" % (
2056 brown(str(self.hostname)),
2057 bold(str(self.hostport)),
2058 blue(mytxt),
2059 ),
2060 importance = 1,
2061 type = "warning",
2062 header = self.output_header
2063 )
2064 mytxt = _("Service issuer")
2065 self.Output.updateProgress(
2066 "[%s:%s] %s: %s" % (
2067 brown(str(self.hostname)),
2068 bold(str(self.hostport)),
2069 blue(mytxt),
2070 self.sock_conn.issuer()
2071 ),
2072 importance = 1,
2073 type = "warning",
2074 header = self.output_header
2075 )
2076 except self.socket.error, e:
2077 if e[0] == 111:
2078 mytxt = "%s: %s, %s: %s" % (_("Cannot connect to"),host,_("on port"),port,)
2079 raise ConnectionError("ConnectionError: %s" % (mytxt,))
2080 else:
2081 raise
2082
2083 if not self.quiet:
2084 mytxt = _("Successfully connected to host")
2085 self.Output.updateProgress(
2086 "[%s:%s] %s" % (
2087 brown(self.hostname),
2088 bold(str(self.hostport)),
2089 blue(mytxt),
2090 ),
2091 importance = 1,
2092 type = "info",
2093 header = self.output_header
2094 )
2095
2097 if not self.real_sock_conn:
2098 return True
2099 if self.ssl and self.pyopenssl:
2100 self.sock_conn.shutdown()
2101 self.sock_conn.close()
2102 elif self.ssl and not self.pyopenssl:
2103 try:
2104 self.real_sock_conn.shutdown(self.socket.SHUT_RDWR)
2105 except self.socket.error:
2106 pass
2107 del self.sock_conn
2108 self.sock_conn = None
2109 try:
2110 self.real_sock_conn.close()
2111 except self.socket.error:
2112 pass
2113 if not self.quiet:
2114 mytxt = _("Successfully disconnected from host")
2115 self.Output.updateProgress(
2116 "[%s:%s] %s" % (
2117 brown(self.hostname),
2118 bold(str(self.hostport)),
2119 blue(mytxt),
2120 ),
2121 importance = 1,
2122 type = "info",
2123 header = self.output_header
2124 )
2125 self.real_sock_conn = None
2126
2127
2128
2129