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 sys
26 import select
27 import time
28 import subprocess
29 import shutil
30 from entropy.services.skel import RemoteDatabase
31 from entropy.exceptions import *
32 from entropy.const import etpConst, etpUi, etpCache, const_setup_perms, const_set_chmod, const_setup_file
33 from entropy.output import brown, bold, blue
34 from entropy.i18n import _
35
37
38 SQL_TABLES = {
39 'entropy_base': """
40 CREATE TABLE `entropy_base` (
41 `idkey` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
42 `key` VARCHAR( 255 ) collate utf8_bin NOT NULL,
43 KEY `key` (`key`)
44 );
45 """,
46 'entropy_votes': """
47 CREATE TABLE `entropy_votes` (
48 `idvote` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
49 `idkey` INT UNSIGNED NOT NULL,
50 `userid` INT UNSIGNED NOT NULL,
51 `vdate` DATE NOT NULL,
52 `vote` TINYINT NOT NULL,
53 `ts` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
54 FOREIGN KEY (`idkey`) REFERENCES `entropy_base` (`idkey`)
55 );
56 """,
57 'entropy_user_scores': """
58 CREATE TABLE `entropy_user_scores` (
59 `userid` INT UNSIGNED NOT NULL PRIMARY KEY,
60 `score` INT UNSIGNED NOT NULL DEFAULT 0
61 );
62 """,
63 'entropy_downloads': """
64 CREATE TABLE `entropy_downloads` (
65 `iddownload` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
66 `idkey` INT UNSIGNED NOT NULL,
67 `ddate` DATE NOT NULL,
68 `count` INT UNSIGNED NULL DEFAULT '0',
69 KEY `idkey` (`idkey`,`ddate`),
70 KEY `idkey_2` (`idkey`),
71 FOREIGN KEY (`idkey`) REFERENCES `entropy_base` (`idkey`)
72 );
73 """,
74 'entropy_downloads_data': """
75 CREATE TABLE `entropy_downloads_data` (
76 `iddownload` INT UNSIGNED NOT NULL,
77 `ip_address` VARCHAR(40) NULL DEFAULT '',
78 `entropy_ip_locations_id` INT UNSIGNED NULL DEFAULT 0,
79 FOREIGN KEY (`iddownload`) REFERENCES `entropy_downloads` (`iddownload`)
80 );
81 """,
82 'entropy_docs': """
83 CREATE TABLE `entropy_docs` (
84 `iddoc` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
85 `idkey` INT UNSIGNED NOT NULL,
86 `userid` INT UNSIGNED NOT NULL,
87 `username` VARCHAR( 255 ),
88 `iddoctype` TINYINT NOT NULL,
89 `ddata` TEXT NOT NULL,
90 `title` VARCHAR( 512 ),
91 `description` VARCHAR( 4000 ),
92 `ts` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
93 KEY `idkey` (`idkey`),
94 KEY `userid` (`userid`),
95 KEY `idkey_2` (`idkey`,`userid`,`iddoctype`),
96 KEY `title` (`title`(333)),
97 KEY `description` (`description`(333)),
98 FOREIGN KEY (`idkey`) REFERENCES `entropy_base` (`idkey`)
99 );
100 """,
101 'entropy_doctypes': """
102 CREATE TABLE `entropy_doctypes` (
103 `iddoctype` TINYINT NOT NULL PRIMARY KEY,
104 `description` TEXT NOT NULL
105 );
106 """,
107 'entropy_docs_keywords': """
108 CREATE TABLE `entropy_docs_keywords` (
109 `iddoc` INT UNSIGNED NOT NULL,
110 `keyword` VARCHAR( 100 ),
111 KEY `keyword` (`keyword`),
112 FOREIGN KEY (`iddoc`) REFERENCES `entropy_docs` (`iddoc`)
113 );
114 """,
115 'entropy_distribution_usage': """
116 CREATE TABLE `entropy_distribution_usage` (
117 `entropy_distribution_usage_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
118 `entropy_branches_id` INT NOT NULL,
119 `entropy_release_strings_id` INT NOT NULL,
120 `ts` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
121 `ip_address` VARCHAR( 15 ),
122 `entropy_ip_locations_id` INT UNSIGNED NULL DEFAULT 0,
123 `creation_date` DATETIME DEFAULT NULL,
124 `hits` INT UNSIGNED NULL DEFAULT 0,
125 FOREIGN KEY (`entropy_branches_id`) REFERENCES `entropy_branches` (`entropy_branches_id`),
126 FOREIGN KEY (`entropy_release_strings_id`) REFERENCES `entropy_release_strings` (`entropy_release_strings_id`),
127 KEY `ip_address` (`ip_address`),
128 KEY `entropy_ip_locations_id` (`entropy_ip_locations_id`)
129 );
130 """,
131 'entropy_hardware_usage': """
132 CREATE TABLE `entropy_hardware_usage` (
133 `entropy_hardware_usage_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
134 `entropy_distribution_usage_id` INT UNSIGNED NOT NULL,
135 `entropy_hardware_hash` VARCHAR ( 64 ),
136 FOREIGN KEY (`entropy_distribution_usage_id`) REFERENCES `entropy_distribution_usage` (`entropy_distribution_usage_id`)
137 );
138 """,
139
140
141
142
143
144
145
146
147 'entropy_branches': """
148 CREATE TABLE `entropy_branches` (
149 `entropy_branches_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
150 `entropy_branch` VARCHAR( 100 )
151 );
152 """,
153 'entropy_release_strings': """
154 CREATE TABLE `entropy_release_strings` (
155 `entropy_release_strings_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
156 `release_string` VARCHAR( 255 )
157 );
158 """,
159 'entropy_ip_locations': """
160 CREATE TABLE `entropy_ip_locations` (
161 `entropy_ip_locations_id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
162 `ip_latitude` FLOAT( 8,5 ),
163 `ip_longitude` FLOAT( 8,5 ),
164 KEY `ip_locations_lat_lon` (`ip_latitude`,`ip_longitude`)
165 );
166 """,
167 }
168 VOTE_RANGE = etpConst['ugc_voterange']
169 VIRUS_CHECK_EXEC = '/usr/bin/clamscan'
170 VIRUS_CHECK_ARGS = []
171 gdata = None
172 YouTube = None
173 YouTubeService = None
174 entropy_docs_title_len = 512
175 entropy_docs_description_len = 4000
176 entropy_docs_keyword_len = 100
177 COMMENTS_SCORE_WEIGHT = 5
178 DOCS_SCORE_WEIGHT = 10
179 VOTES_SCORE_WEIGHT = 2
180 STATS_MAP = {
181 'installer': "installer",
182 }
183
184 '''
185 dependencies:
186 dev-python/gdata
187 '''
188 - def __init__(self, connection_data, store_path, store_url = ''):
189 import entropy.dump as dumpTools
190 import entropy.tools as entropyTools
191 from entropy.misc import EntropyGeoIP
192 self.EntropyGeoIP = EntropyGeoIP
193 self.entropyTools, self.dumpTools = entropyTools, dumpTools
194 self.store_url = store_url
195 self.FLOOD_INTERVAL = 30
196 self.DOC_TYPES = etpConst['ugc_doctypes'].copy()
197 self.UPLOADED_DOC_TYPES = [
198 self.DOC_TYPES['image'],
199 self.DOC_TYPES['generic_file']
200 ]
201 RemoteDatabase.__init__(self)
202 self.set_connection_data(connection_data)
203 self.connect()
204 self.initialize_tables()
205 self.initialize_doctypes()
206 self.setup_store_path(store_path)
207 from entropy.core import SystemSettings
208 self.__system_settings = SystemSettings()
209 self.system_name = self.__system_settings['system']['name']
210 from datetime import datetime
211 self.datetime = datetime
212 try:
213 import gdata
214 import gdata.youtube
215 import gdata.youtube.service
216 self.gdata = gdata
217 self.YouTube = gdata.youtube
218 self.YouTubeService = gdata.youtube.service
219 except ImportError:
220 pass
221
222 self.cached_results = {
223
224 'get_ugc_alldownloads': (self.get_ugc_alldownloads, [], {}, 86400),
225
226 'get_total_downloads_count': (self.get_total_downloads_count, [], {}, 7200),
227 }
228
230 return int(time.time())
231
233 for cache_item in self.cached_results:
234 fdata = self.cached_results.get(cache_item)
235 if fdata == None: return
236 func, args, kwargs, exp_time = fdata
237 key = self.get_cache_item_key(cache_item)
238 r = func(*args,**kwargs)
239 self.dumpTools.dumpobj(key, r)
240
242 return os.path.join(etpCache['ugc_srv_cache'],cache_item)
243
245 if not self.cached_results.get(cache_item): return None
246 key = self.get_cache_item_key(cache_item)
247 self.dumpTools.dumpobj(key, r)
248
250 geoip_dbpath = self.connection_data.get('geoip_dbpath','')
251 if os.path.isfile(geoip_dbpath) and os.access(geoip_dbpath,os.R_OK):
252 try:
253 geo = self.EntropyGeoIP(geoip_dbpath)
254 return geo.get_geoip_record_from_ip(ip_address)
255 except:
256 pass
257
258
260 fdata = self.cached_results.get(cache_item)
261 if fdata == None: return None
262 func, args, kwargs, exp_time = fdata
263
264 key = self.get_cache_item_key(cache_item)
265 cur_time = self.get_current_time()
266 cache_time = self.dumpTools.getobjmtime(key)
267 if (cache_time + exp_time) < cur_time:
268
269 return None
270 return self.dumpTools.loadobj(key)
271
273 path = os.path.realpath(path)
274 if not os.path.isabs(path):
275 raise PermissionDenied('PermissionDenied: %s' % (_("not a valid directory path"),))
276 if not os.path.isdir(path):
277 try:
278 os.makedirs(path)
279 except OSError, e:
280 raise PermissionDenied('PermissionDenied: %s' % (e,))
281 if etpConst['entropygid'] != None:
282 const_setup_perms(path,etpConst['entropygid'])
283 self.STORE_PATH = path
284
294
300
302 self.check_connection()
303 rows = self.execute_query('SELECT `iddoctype` FROM entropy_doctypes WHERE `iddoctype` = %s', (iddoctype,))
304 if rows:
305 return True
306 return False
307
309 self.check_connection()
310 rows = self.execute_query('SELECT `idkey` FROM entropy_base WHERE `key` = %s', (key,))
311 if rows:
312 return True
313 return False
314
316 self.check_connection()
317 rows = self.execute_query('SELECT `iddoc` FROM entropy_docs WHERE `iddoc` = %s', (iddoc,))
318 if rows:
319 return True
320 return False
321
326
333
341
348
355
362
364 entropy_ip_locations_id = 0
365 geo_data = self._get_geoip_data_from_ip_address(ip_addr)
366 if isinstance(geo_data,dict):
367 ip_lat = geo_data.get('latitude')
368 ip_long = geo_data.get('longitude')
369 if isinstance(ip_lat,float) and isinstance(ip_long,float):
370 ip_lat = round(ip_lat,5)
371 ip_long = round(ip_long,5)
372 entropy_ip_locations_id = self.get_entropy_ip_locations_id(ip_lat, ip_long)
373 if entropy_ip_locations_id == -1:
374 entropy_ip_locations_id = self.insert_entropy_ip_locations_id(ip_lat, ip_long)
375 return entropy_ip_locations_id
376
378 self.check_connection()
379 self.execute_query('UPDATE entropy_downloads SET `count` = `count`+1 WHERE `iddownload` = %s', (iddownload,))
380 if do_commit: self.commit()
381 return iddownload
382
384 entropy_ip_locations_id = self.handle_entropy_ip_locations_id(ip_addr)
385 mydata = [(x,ip_addr,entropy_ip_locations_id,) for x in iddownloads]
386 self.execute_many('INSERT INTO entropy_downloads_data VALUES (%s,%s,%s)', mydata)
387 if do_commit: self.commit()
388
390 mytime = time.time()
391 mydate = self.datetime.fromtimestamp(mytime)
392 mydate = self.datetime(mydate.year,mydate.month,mydate.day)
393 return mydate
394
396 mytime = time.time()
397 mydate = self.datetime.fromtimestamp(mytime)
398 mydate = self.datetime(mydate.year,mydate.month,mydate.day,mydate.hour,mydate.minute,mydate.second)
399 return mydate
400
402 self.check_connection()
403 idkey = self.handle_pkgkey(key)
404 self.execute_query('SELECT `iddownload` FROM entropy_downloads WHERE `idkey` = %s AND `ddate` = %s', (idkey,ddate,))
405 data = self.fetchone()
406 if data:
407 return data['iddownload']
408 return -1
409
411 self.check_connection()
412 self.execute_query('SELECT `idkey` FROM entropy_base WHERE `key` = %s', (key,))
413 data = self.fetchone()
414 if data:
415 return data['idkey']
416 return -1
417
419 self.check_connection()
420 self.execute_query('SELECT `iddoctype` FROM entropy_docs WHERE `iddoc` = %s', (iddoc,))
421 data = self.fetchone()
422 if data:
423 return data['iddoctype']
424 return -1
425
427 self.check_connection()
428 self.execute_query('SELECT `entropy_branches_id` FROM entropy_branches WHERE `entropy_branch` = %s', (branch,))
429 data = self.fetchone()
430 if data:
431 return data['entropy_branches_id']
432 return -1
433
435 self.check_connection()
436 self.execute_query('SELECT `entropy_release_strings_id` FROM entropy_release_strings WHERE `release_string` = %s', (release_string,))
437 data = self.fetchone()
438 if data:
439 return data['entropy_release_strings_id']
440 return -1
441
443 self.check_connection()
444 self.execute_query("""
445 SELECT `entropy_ip_locations_id` FROM
446 entropy_ip_locations WHERE
447 `ip_latitude` = %s AND `ip_longitude` = %s""", (ip_latitude,ip_longitude,))
448 data = self.fetchone()
449 if data:
450 return data['entropy_ip_locations_id']
451 return -1
452
458
471
473 self.execute_query('SELECT `keyword` FROM entropy_docs_keywords WHERE `iddoc` = %s order by `keyword`', (iddoc,))
474 return [x.get('keyword') for x in self.fetchall() if x.get('keyword')]
475
486
497
505
535
537 self.check_connection()
538 self.execute_query("""
539 SELECT avg(entropy_votes.`vote`) as avg_vote FROM entropy_votes,entropy_base WHERE
540 entropy_base.`key` = %s AND
541 entropy_base.idkey = entropy_votes.idkey""", (pkgkey,))
542 data = self.fetchone() or {}
543 avg_vote = data.get('avg_vote')
544 if not avg_vote:
545 return 0.0
546 return avg_vote
547
549
550
551 cache_item = 'get_ugc_allvotes'
552 cached = self.get_cached_result(cache_item)
553 if cached != None:
554 return cached
555
556 self.check_connection()
557 self.execute_query("""
558 SELECT entropy_base.`key` as `vkey`,avg(entropy_votes.vote) as `avg_vote` FROM
559 entropy_votes,entropy_base WHERE
560 entropy_votes.`idkey` = entropy_base.`idkey` GROUP BY entropy_base.`key`""")
561 vote_data = dict( ((x['vkey'], x['avg_vote'],) for x in self.fetchall()) )
562
563
564 self.cache_result(cache_item, vote_data)
565 return vote_data
566
568 self.check_connection()
569
570 self.execute_query("""
571 SELECT SQL_CACHE sum(entropy_downloads.`count`) as `tot_downloads` FROM
572 entropy_downloads,entropy_base WHERE entropy_base.key = %s AND
573 entropy_base.idkey = entropy_downloads.idkey""", (pkgkey,))
574
575 data = self.fetchone() or {}
576 downloads = data.get('tot_downloads')
577 if not downloads:
578 return 0
579 return downloads
580
582
583 cache_item = 'get_ugc_alldownloads'
584 cached = self.get_cached_result(cache_item)
585 if cached != None: return cached
586
587 self.check_connection()
588 self.execute_query("""
589 SELECT SQL_CACHE entropy_base.key as vkey, tot_downloads from entropy_base,
590 (SELECT idkey as idp1, sum(entropy_downloads.`count`) AS `tot_downloads` FROM
591 entropy_downloads GROUP BY entropy_downloads.`idkey`) as tmp where idkey = tmp.idp1;
592 """)
593 down_data = dict( ((x['vkey'], x['tot_downloads'],) for x in self.fetchall()) )
594
595
596 self.cache_result(cache_item, down_data)
597 return down_data
598
604
613
615 self.check_connection()
616 self.execute_query('SELECT count(`iddoc`) as comments FROM entropy_docs WHERE `iddoctype` != %s', (self.DOC_TYPES['comments'],))
617 data = self.fetchone() or {}
618 comments = data.get('comments')
619 if not comments:
620 return 0
621 return comments
622
624 self.check_connection()
625 self.execute_query('SELECT count(`idvote`) as votes FROM entropy_votes')
626 data = self.fetchone() or {}
627 votes = data.get('votes')
628 if not votes:
629 return 0
630 return votes
631
633
634
635 cache_item = 'get_total_downloads_count'
636 cached = self.get_cached_result(cache_item)
637 if cached != None: return cached
638
639 self.check_connection()
640 self.execute_query('SELECT SQL_CACHE sum(entropy_downloads.`count`) as downloads FROM entropy_downloads')
641 data = self.fetchone() or {}
642 downloads = data.get('downloads', 0)
643 if not downloads:
644 return 0
645 result = int(downloads)
646
647
648 self.cache_result(cache_item, result)
649 return result
650
652 self.check_connection()
653 self.execute_query('SET @row = 0')
654 self.execute_query("""
655 SELECT Row, col_a FROM (SELECT @row := @row + 1 AS Row, userid AS col_a FROM
656 entropy_user_scores ORDER BY score DESC) As derived1 WHERE col_a = %s""", (userid,))
657 data = self.fetchone() or {}
658 ranking = data.get('Row', 0)
659 if not ranking:
660 return 0
661 return ranking
662
664
665
666 cache_item = 'get_users_scored_count'
667 cached = self.get_cached_result(cache_item)
668 if cached != None:
669 return cached
670
671 self.check_connection()
672 self.execute_query('SELECT SQL_CACHE count(`userid`) as mycount FROM entropy_user_scores')
673 data = self.fetchone() or {}
674 count = data.get('mycount', 0)
675 if not count:
676 return 0
677
678
679 self.cache_result(cache_item, count)
680 return count
681
683 self.check_connection()
684 rows = self.execute_query('SELECT `userid` FROM entropy_user_scores WHERE `userid` = %s', (userid,))
685 if rows:
686 return True
687 return False
688
696
706
715
717 self.check_connection()
718 limit_string = ''
719 if count:
720 limit_string += ' LIMIT %s,%s' % (offset,count,)
721 self.execute_query('SELECT SQL_CALC_FOUND_ROWS *, userid, score FROM entropy_user_scores ORDER BY score DESC' + limit_string)
722 data = self.fetchall()
723
724 self.execute_query('SELECT FOUND_ROWS() as count')
725 rdata = self.fetchone() or {}
726 found_rows = rdata.get('count', 0)
727 if found_rows is None:
728 found_rows = 0
729
730 return found_rows, data
731
733 self.check_connection()
734 self.execute_query('SELECT avg(`vote`) as vote_avg FROM entropy_votes WHERE `userid` = %s', (userid,))
735 data = self.fetchone() or {}
736 vote_avg = data.get('vote_avg', 0.0)
737 if not vote_avg:
738 return 0.0
739 return round(float(vote_avg), 2)
740
742 self.check_connection()
743 self.execute_query("""
744 SELECT * FROM entropy_docs,entropy_base WHERE
745 entropy_docs.`userid` = %s AND
746 entropy_base.idkey = entropy_docs.idkey ORDER BY entropy_base.`key`""", (userid,))
747 return self.fetchall()
748
751
754
759
761 self.check_connection()
762 self.execute_query('SELECT * FROM entropy_docs WHERE `userid` = %s AND `iddoctype` '+doctype_sql_cmp+' %s', (userid,doctype,))
763 return self.fetchall()
764
766 self.check_connection()
767 self.execute_query('SELECT count(`iddoc`) as docs FROM entropy_docs WHERE `userid` = %s AND `iddoctype` '+doctype_sql_cmp+' %s', (userid,doctype,))
768 data = self.fetchone() or {}
769 docs = data.get('docs', 0)
770 if docs is None:
771 docs = 0
772 return docs
773
776
779
782
785
788
790 self.check_connection()
791 self.execute_query('SELECT count(`idvote`) as votes FROM entropy_votes WHERE `userid` = %s', (userid,))
792 data = self.fetchone() or {}
793 votes = data.get('votes', 0)
794 if votes is None:
795 votes = 0
796 return votes
797
811
820
821 - def search_pkgkey_items(self, pkgkey_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
822 self.check_connection()
823
824 if iddoctypes is None:
825 iddoctypes = self.DOC_TYPES.values()
826
827 if len(iddoctypes) == 1:
828 iddoctypes_str = " = %s" % (iddoctypes[0],)
829 else:
830 iddoctypes_str = "IN ("+', '.join([str(x) for x in iddoctypes])+")"
831
832 myterm = "%"+pkgkey_string+"%"
833
834 search_params = [myterm,results_offset,results_limit]
835
836 order_by_string = ''
837 if order_by == "key":
838 order_by_string = 'ORDER BY entropy_base.`key`'
839 elif order_by == "username":
840 order_by_string = 'ORDER BY entropy_docs.`username`'
841 elif order_by == "vote":
842 order_by_string = 'ORDER BY avg_vote DESC'
843 elif order_by == "downloads":
844 order_by_string = 'ORDER BY tot_downloads DESC'
845
846 self.execute_query("""
847 SELECT
848 SQL_CALC_FOUND_ROWS entropy_base.`key`,
849 entropy_docs.*,
850 entropy_downloads.iddownload,
851 entropy_downloads.ddate,
852 entropy_votes.idvote,
853 entropy_votes.vdate,
854 entropy_votes.vote,
855 avg(entropy_votes.vote) as avg_vote,
856 sum(entropy_downloads.`count`) as tot_downloads,
857 entropy_user_scores.score as `score`
858 FROM
859 entropy_base
860 LEFT JOIN entropy_votes ON entropy_base.idkey = entropy_votes.idkey
861 LEFT JOIN entropy_docs ON entropy_base.idkey = entropy_docs.idkey
862 LEFT JOIN entropy_docs as ed ON entropy_base.idkey = ed.idkey
863 LEFT JOIN entropy_user_scores on entropy_docs.userid = entropy_user_scores.userid
864 LEFT JOIN entropy_downloads on entropy_base.idkey = entropy_downloads.idkey
865 WHERE
866 entropy_base.`key` LIKE %s AND
867 entropy_docs.iddoctype """+iddoctypes_str+"""
868 GROUP BY entropy_docs.`iddoc`
869 """+order_by_string+"""
870 LIMIT %s,%s
871 """, search_params)
872
873 results = self.fetchall()
874 for item in results:
875 if item['avg_vote'] is None:
876 item['avg_vote'] = 0.0
877
878 self.execute_query('SELECT FOUND_ROWS() as count')
879 data = self.fetchone() or {}
880 count = data.get('count', 0)
881 if count is None:
882 count = 0
883 return results, count
884
885 - def search_username_items(self, pkgkey_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
886 self.check_connection()
887
888 if iddoctypes is None:
889 iddoctypes = self.DOC_TYPES.values()
890
891 if len(iddoctypes) == 1:
892 iddoctypes_str = " = %s" % (iddoctypes[0],)
893 else:
894 iddoctypes_str = "IN ("+', '.join([str(x) for x in iddoctypes])+")"
895
896 myterm = "%"+pkgkey_string+"%"
897
898 search_params = [myterm,results_offset,results_limit]
899
900 order_by_string = ''
901 if order_by == "key":
902 order_by_string = 'ORDER BY entropy_base.`key`'
903 elif order_by == "username":
904 order_by_string = 'ORDER BY entropy_docs.`username`'
905 elif order_by == "vote":
906 order_by_string = 'ORDER BY avg_vote DESC'
907 elif order_by == "downloads":
908 order_by_string = 'ORDER BY tot_downloads DESC'
909
910 self.execute_query("""
911 SELECT
912 SQL_CALC_FOUND_ROWS entropy_base.`key`,
913 entropy_docs.*,
914 entropy_downloads.iddownload,
915 entropy_downloads.ddate,
916 entropy_votes.idvote,
917 entropy_votes.vdate,
918 entropy_votes.vote,
919 avg(entropy_votes.vote) as avg_vote,
920 sum(entropy_downloads.`count`) as tot_downloads,
921 entropy_user_scores.score as `score`
922 FROM
923 entropy_base
924 LEFT JOIN entropy_votes ON entropy_base.idkey = entropy_votes.idkey
925 LEFT JOIN entropy_docs ON entropy_base.idkey = entropy_docs.idkey
926 LEFT JOIN entropy_docs as ed ON entropy_base.idkey = ed.idkey
927 LEFT JOIN entropy_user_scores on entropy_docs.userid = entropy_user_scores.userid
928 LEFT JOIN entropy_downloads on entropy_base.idkey = entropy_downloads.idkey
929 WHERE
930 entropy_docs.`username` LIKE %s AND
931 entropy_docs.iddoctype """+iddoctypes_str+"""
932 GROUP BY entropy_docs.`iddoc`
933 """+order_by_string+"""
934 LIMIT %s,%s
935 """, search_params)
936
937 results = self.fetchall()
938
939 for item in results:
940 if item['avg_vote'] is None:
941 item['avg_vote'] = 0.0
942
943 self.execute_query('SELECT FOUND_ROWS() as count')
944 data = self.fetchone() or {}
945 count = data.get('count', 0)
946 if count is None:
947 count = 0
948 return results, count
949
950 - def search_content_items(self, pkgkey_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
951 self.check_connection()
952
953 if iddoctypes is None:
954 iddoctypes = self.DOC_TYPES.values()
955
956 if len(iddoctypes) == 1:
957 iddoctypes_str = " = %s" % (iddoctypes[0],)
958 else:
959 iddoctypes_str = "IN ("+', '.join([str(x) for x in iddoctypes])+")"
960
961 myterm = "%"+pkgkey_string+"%"
962 search_params = [myterm,myterm,myterm,results_offset,results_limit]
963
964 order_by_string = ''
965 if order_by == "key":
966 order_by_string = 'ORDER BY entropy_base.`key`'
967 elif order_by == "username":
968 order_by_string = 'ORDER BY entropy_docs.`username`'
969 elif order_by == "vote":
970 order_by_string = 'ORDER BY avg_vote DESC'
971 elif order_by == "downloads":
972 order_by_string = 'ORDER BY tot_downloads DESC'
973
974 self.execute_query("""
975 SELECT
976 SQL_CALC_FOUND_ROWS entropy_base.`key`,
977 entropy_docs.*,
978 entropy_downloads.iddownload,
979 entropy_downloads.ddate,
980 entropy_votes.idvote,
981 entropy_votes.vdate,
982 entropy_votes.vote,
983 avg(entropy_votes.vote) as avg_vote,
984 sum(entropy_downloads.`count`) as tot_downloads,
985 entropy_user_scores.score as `score`
986 FROM
987 entropy_base
988 LEFT JOIN entropy_votes ON entropy_base.idkey = entropy_votes.idkey
989 LEFT JOIN entropy_docs ON entropy_base.idkey = entropy_docs.idkey
990 LEFT JOIN entropy_docs as ed ON entropy_base.idkey = ed.idkey
991 LEFT JOIN entropy_user_scores on entropy_docs.userid = entropy_user_scores.userid
992 LEFT JOIN entropy_downloads on entropy_base.idkey = entropy_downloads.idkey
993 WHERE
994 (entropy_docs.`title` LIKE %s OR entropy_docs.`description` LIKE %s OR entropy_docs.`ddata` LIKE %s) AND
995 entropy_docs.iddoctype """+iddoctypes_str+"""
996 GROUP BY entropy_docs.`iddoc`
997 """+order_by_string+"""
998 LIMIT %s,%s
999 """, search_params)
1000
1001 results = self.fetchall()
1002
1003 for item in results:
1004 if item['avg_vote'] is None:
1005 item['avg_vote'] = 0.0
1006
1007 self.execute_query('SELECT FOUND_ROWS() as count')
1008 data = self.fetchone() or {}
1009 count = data.get('count', 0)
1010 if count is None:
1011 count = 0
1012 return results, count
1013
1014 - def search_keyword_items(self, keyword_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
1015 self.check_connection()
1016
1017 if iddoctypes is None:
1018 iddoctypes = self.DOC_TYPES.values()
1019
1020 if len(iddoctypes) == 1:
1021 iddoctypes_str = " = %s" % (iddoctypes[0],)
1022 else:
1023 iddoctypes_str = "IN ("+', '.join([str(x) for x in iddoctypes])+")"
1024
1025 myterm = "%"+keyword_string+"%"
1026
1027 search_params = [myterm,results_offset,results_limit]
1028
1029 order_by_string = ''
1030 if order_by == "key":
1031 order_by_string = 'ORDER BY entropy_base.`key`'
1032 elif order_by == "username":
1033 order_by_string = 'ORDER BY entropy_docs.`username`'
1034 elif order_by == "vote":
1035 order_by_string = 'ORDER BY avg_vote DESC'
1036 elif order_by == "downloads":
1037 order_by_string = 'ORDER BY tot_downloads DESC'
1038
1039 self.execute_query("""
1040 SELECT
1041 SQL_CALC_FOUND_ROWS entropy_base.`key`,
1042 entropy_docs.*,
1043 entropy_downloads.iddownload,
1044 entropy_downloads.ddate,
1045 entropy_votes.idvote,
1046 entropy_votes.vdate,
1047 entropy_votes.vote,
1048 avg(entropy_votes.vote) as avg_vote,
1049 sum(entropy_downloads.`count`) as tot_downloads,
1050 entropy_user_scores.score as `score`
1051 FROM
1052 entropy_base
1053 LEFT JOIN entropy_votes ON entropy_base.idkey = entropy_votes.idkey
1054 LEFT JOIN entropy_docs ON entropy_base.idkey = entropy_docs.idkey
1055 LEFT JOIN entropy_docs as ed ON entropy_base.idkey = ed.idkey
1056 LEFT JOIN entropy_user_scores on entropy_docs.userid = entropy_user_scores.userid
1057 LEFT JOIN entropy_downloads on entropy_base.idkey = entropy_downloads.idkey
1058 LEFT JOIN entropy_docs_keywords on entropy_docs_keywords.iddoc = entropy_docs.iddoc
1059 WHERE
1060 entropy_docs_keywords.`keyword` LIKE %s AND
1061 entropy_docs.iddoctype """+iddoctypes_str+"""
1062 GROUP BY entropy_docs.`iddoc`
1063 """+order_by_string+"""
1064 LIMIT %s,%s
1065 """, search_params)
1066
1067 results = self.fetchall()
1068
1069 for item in results:
1070 if item['avg_vote'] is None:
1071 item['avg_vote'] = 0.0
1072
1073 self.execute_query('SELECT FOUND_ROWS() as count')
1074 data = self.fetchone() or {}
1075 count = data.get('count', 0)
1076 if count is None:
1077 count = 0
1078 return results, count
1079
1080 - def search_iddoc_item(self, iddoc_string, iddoctypes = None, results_offset = 0, results_limit = 30, order_by = None):
1081 self.check_connection()
1082
1083 if iddoctypes is None:
1084 iddoctypes = self.DOC_TYPES.values()
1085
1086 if len(iddoctypes) == 1:
1087 iddoctypes_str = " = %s" % (iddoctypes[0],)
1088 else:
1089 iddoctypes_str = "IN ("+', '.join([str(x) for x in iddoctypes])+")"
1090
1091 try:
1092 myterm = int(iddoc_string)
1093 except ValueError:
1094 return [], 0
1095
1096 search_params = [myterm,results_offset,results_limit]
1097
1098 order_by_string = ''
1099 if order_by == "key":
1100 order_by_string = 'ORDER BY entropy_base.`key`'
1101 elif order_by == "username":
1102 order_by_string = 'ORDER BY entropy_docs.`username`'
1103 elif order_by == "vote":
1104 order_by_string = 'ORDER BY avg_vote DESC'
1105 elif order_by == "downloads":
1106 order_by_string = 'ORDER BY tot_downloads DESC'
1107
1108 self.execute_query("""
1109 SELECT
1110 SQL_CALC_FOUND_ROWS entropy_base.`key`,
1111 entropy_docs.*,
1112 entropy_downloads.iddownload,
1113 entropy_downloads.ddate,
1114 entropy_votes.idvote,
1115 entropy_votes.vdate,
1116 entropy_votes.vote,
1117 avg(entropy_votes.vote) as avg_vote,
1118 sum(entropy_downloads.`count`) as tot_downloads,
1119 entropy_user_scores.score as `score`
1120 FROM
1121 entropy_base
1122 LEFT JOIN entropy_votes ON entropy_base.idkey = entropy_votes.idkey
1123 LEFT JOIN entropy_docs ON entropy_base.idkey = entropy_docs.idkey
1124 LEFT JOIN entropy_docs as ed ON entropy_base.idkey = ed.idkey
1125 LEFT JOIN entropy_user_scores on entropy_docs.userid = entropy_user_scores.userid
1126 LEFT JOIN entropy_downloads on entropy_base.idkey = entropy_downloads.idkey
1127 WHERE
1128 entropy_docs.`iddoc` = %s AND
1129 entropy_docs.iddoctype """+iddoctypes_str+"""
1130 GROUP BY entropy_docs.`iddoc`
1131 """+order_by_string+"""
1132 LIMIT %s,%s
1133 """, search_params)
1134
1135 results = self.fetchall()
1136
1137 for item in results:
1138 if item['avg_vote'] is None:
1139 item['avg_vote'] = 0.0
1140
1141 self.execute_query('SELECT FOUND_ROWS() as count')
1142 data = self.fetchone() or {}
1143 count = data.get('count', 0)
1144 if count is None:
1145 count = 0
1146 return results, count
1147
1153
1155 self.check_connection()
1156 self.execute_query('SELECT max(`ts`) as ts FROM entropy_docs WHERE `userid` = %s', (userid,))
1157 data = self.fetchone()
1158 if not data:
1159 return False
1160 elif not data.has_key('ts'):
1161 return False
1162 elif data['ts'] == None:
1163 return False
1164 delta = self.datetime.fromtimestamp(time.time()) - data['ts']
1165 if (delta.days == 0) and (delta.seconds <= self.FLOOD_INTERVAL):
1166 return True
1167 return False
1168
1169 - def insert_generic_doc(self, idkey, userid, username, doc_type, data, title, description, keywords, do_commit = False):
1170 self.check_connection()
1171
1172 title = title[:self.entropy_docs_title_len]
1173 description = description[:self.entropy_docs_description_len]
1174
1175
1176 flood_risk = self.insert_flood_control_check(userid)
1177 if flood_risk:
1178 return 'flooding detected'
1179
1180 self.execute_query('INSERT INTO entropy_docs VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)',(
1181 None,
1182 idkey,
1183 userid,
1184 username,
1185 doc_type,
1186 data,
1187 title,
1188 description,
1189 None,
1190 )
1191 )
1192 if do_commit:
1193 self.commit()
1194 iddoc = self.lastrowid()
1195 self.insert_keywords(iddoc, keywords)
1196 self.update_user_score(userid)
1197 return iddoc
1198
1200 keywords = keywords.split(",")
1201 clean_keys = []
1202 for key in keywords:
1203 try:
1204 key = key.strip().split()[0]
1205 except IndexError:
1206 continue
1207 if not key: continue
1208 if not key.isalnum(): continue
1209 key = key[:self.entropy_docs_keyword_len]
1210 if key in clean_keys: continue
1211 clean_keys.append(key)
1212
1213 if not clean_keys:
1214 return
1215
1216 mydata = []
1217 for key in clean_keys:
1218 mydata.append((iddoc, key,))
1219
1220 self.execute_many('INSERT INTO entropy_docs_keywords VALUES (%s,%s)', mydata)
1221
1223 self.execute_query('DELETE FROM entropy_docs_keywords WHERE `iddoc` = %s',(iddoc,))
1224
1235
1253
1266
1267
1268 - def do_vote(self, pkgkey, userid, vote, do_commit = False):
1269 self.check_connection()
1270 idkey = self.handle_pkgkey(pkgkey)
1271 vote = int(vote)
1272 if vote not in self.VOTE_RANGE:
1273 vote = 3
1274 mydate = self.get_date()
1275 if self.has_user_already_voted(pkgkey, userid):
1276 return False
1277 self.execute_query('INSERT INTO entropy_votes VALUES (%s,%s,%s,%s,%s,%s)',(
1278 None,
1279 idkey,
1280 userid,
1281 mydate,
1282 vote,
1283 None,
1284 )
1285 )
1286 if do_commit:
1287 self.commit()
1288 self.update_user_score(userid)
1289 return True
1290
1292 self.check_connection()
1293 idkey = self.handle_pkgkey(pkgkey)
1294 self.execute_query('SELECT `idvote` FROM entropy_votes WHERE `idkey` = %s AND `userid` = %s', (idkey,userid,))
1295 data = self.fetchone()
1296 if data:
1297 return True
1298 return False
1299
1300
1301 - def do_downloads(self, pkgkeys, ip_addr = None, do_commit = False):
1302 self.check_connection()
1303 mydate = self.get_date()
1304 iddownloads = set()
1305 for pkgkey in pkgkeys:
1306 iddownload = self.get_iddownload(pkgkey, mydate)
1307 if iddownload == -1:
1308 iddownload = self.insert_download(pkgkey, mydate, count = 1)
1309 else:
1310 self.update_download(iddownload)
1311 if (iddownload > 0) and isinstance(ip_addr,basestring):
1312 iddownloads.add(iddownload)
1313
1314 if iddownloads:
1315 self.store_download_data(iddownloads, ip_addr)
1316 if do_commit:
1317 self.commit()
1318 return True
1319
1320 - def do_download_stats(self, branch, release_string, hw_hash, pkgkeys,
1321 ip_addr, do_commit = False):
1322
1323 self.check_connection()
1324 branch_id = self.get_entropy_branches_id(branch)
1325 if branch_id == -1:
1326 branch_id = self.insert_entropy_branch(branch)
1327
1328 rel_strings_id = self.get_entropy_release_strings_id(release_string)
1329 if rel_strings_id == -1:
1330 rel_strings_id = self.insert_entropy_release_string(release_string)
1331
1332 self.do_downloads(pkgkeys, ip_addr = ip_addr)
1333
1334 entropy_distribution_usage_id = self.is_user_ip_available_in_entropy_distribution_usage(ip_addr)
1335
1336 hits = 1
1337 if self.STATS_MAP['installer'] in pkgkeys:
1338 hits = 0
1339 if entropy_distribution_usage_id == -1:
1340 entropy_ip_locations_id = self.handle_entropy_ip_locations_id(ip_addr)
1341 self.execute_query('INSERT INTO entropy_distribution_usage VALUES (%s,%s,%s,%s,%s,%s,%s,%s)',(
1342 None,
1343 branch_id,
1344 rel_strings_id,
1345 None,
1346 ip_addr,
1347 entropy_ip_locations_id,
1348 self.get_datetime(),
1349 hits,
1350 )
1351 )
1352 entropy_distribution_usage_id = self.lastrowid()
1353 else:
1354 self.execute_query("""
1355 UPDATE entropy_distribution_usage SET `entropy_branches_id` = %s,
1356 `entropy_release_strings_id` = %s,
1357 `hits` = `hits`+%s
1358 WHERE `entropy_distribution_usage_id` = %s
1359 """,(
1360 branch_id,
1361 rel_strings_id,
1362 hits,
1363 entropy_distribution_usage_id,
1364 )
1365 )
1366
1367
1368 if hw_hash and not \
1369 self.is_entropy_hardware_usage_stats_available(entropy_distribution_usage_id):
1370
1371 self.do_entropy_hardware_usage_stats(entropy_distribution_usage_id,
1372 hw_hash)
1373
1374 if do_commit: self.commit()
1375 return True
1376
1378
1379 self.execute_query('INSERT INTO entropy_hardware_usage VALUES (%s,%s,%s)', (
1380 None,
1381 entropy_distribution_usage_id,
1382 hw_hash,
1383 )
1384 )
1385
1387 self.check_connection()
1388 self.execute_query('SELECT entropy_hardware_usage_id FROM entropy_hardware_usage WHERE `entropy_distribution_usage_id` = %s',(entropy_distribution_usage_id,))
1389 data = self.fetchone()
1390 if data:
1391 return True
1392 return False
1393
1395 self.check_connection()
1396 self.execute_query('SELECT entropy_distribution_usage_id FROM entropy_distribution_usage WHERE `ip_address` = %s',(ip_address,))
1397 data = self.fetchone() or {}
1398 myid = data.get('entropy_distribution_usage_id')
1399 if myid is None:
1400 return -1
1401 return myid
1402
1403 - def insert_document(self, pkgkey, userid, username, text, title,
1404 description, keywords, doc_type = None, do_commit = False):
1405 self.check_connection()
1406 idkey = self.handle_pkgkey(pkgkey)
1407 if doc_type == None: doc_type = self.DOC_TYPES['bbcode_doc']
1408 iddoc = self.insert_generic_doc(idkey, userid, username, doc_type,
1409 text, title, description, keywords)
1410 if isinstance(iddoc, basestring):
1411 return False, iddoc
1412 if do_commit:
1413 self.commit()
1414 return True, iddoc
1415
1416 - def edit_document(self, iddoc, new_document, new_title, new_keywords, do_commit = False):
1435
1448
1450
1451 if not os.access(filepath,os.R_OK):
1452 return False,None
1453
1454 args = [self.VIRUS_CHECK_EXEC]
1455 args += self.VIRUS_CHECK_ARGS
1456 args += [filepath]
1457 f = open("/dev/null","w")
1458 p = subprocess.Popen(args, stdout = f, stderr = f)
1459 rc = p.wait()
1460 f.close()
1461 if rc == 1:
1462 return True, None
1463 return False, None
1464
1465 - def insert_generic_file(self, pkgkey, userid, username, file_path,
1466 file_name, doc_type, title, description, keywords):
1467 self.check_connection()
1468 file_path = os.path.realpath(file_path)
1469
1470
1471 virus_found, virus_type = self.scan_for_viruses(file_path)
1472 if virus_found:
1473 os.remove(file_path)
1474 return False, None
1475
1476
1477 flood_risk = self.insert_flood_control_check(userid)
1478 if flood_risk: return False, 'flooding detected'
1479
1480
1481 if doc_type == self.DOC_TYPES['image']:
1482 valid = False
1483 if os.path.isfile(file_path) and os.access(file_path,os.R_OK):
1484 valid = self.entropyTools.is_supported_image_file(file_path)
1485 if not valid:
1486 return False, 'not a valid image'
1487
1488 dest_path = os.path.join(self.STORE_PATH,file_name)
1489
1490
1491 dest_dir = os.path.dirname(dest_path)
1492 if not os.path.isdir(dest_dir):
1493 try:
1494 os.makedirs(dest_dir)
1495 except OSError, e:
1496 raise PermissionDenied('PermissionDenied: %s' % (e,))
1497 if etpConst['entropygid'] != None:
1498 const_setup_perms(dest_dir,etpConst['entropygid'])
1499
1500 orig_dest_path = dest_path
1501 dcount = 0
1502 while os.path.isfile(dest_path):
1503 dcount += 1
1504 dest_path_name = "%s_%s" % (dcount,os.path.basename(orig_dest_path),)
1505 dest_path = os.path.join(os.path.dirname(orig_dest_path),dest_path_name)
1506
1507 if os.path.dirname(file_path) != dest_dir:
1508 try:
1509 os.rename(file_path, dest_path)
1510 except OSError:
1511
1512 shutil.move(file_path, dest_path)
1513 if etpConst['entropygid'] != None:
1514 try:
1515 const_setup_file(dest_path, etpConst['entropygid'], 0664)
1516 except OSError:
1517 pass
1518
1519 try:
1520 const_set_chmod(dest_path,0664)
1521 except OSError:
1522 pass
1523
1524 title = title[:self.entropy_docs_title_len]
1525 description = description[:self.entropy_docs_description_len]
1526
1527
1528 idkey = self.handle_pkgkey(pkgkey)
1529 self.execute_query('INSERT INTO entropy_docs VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)',(
1530 None,
1531 idkey,
1532 userid,
1533 username,
1534 doc_type,
1535 file_name,
1536 title,
1537 description,
1538 None,
1539 )
1540 )
1541 iddoc = self.lastrowid()
1542 self.insert_keywords(iddoc, keywords)
1543 store_url = os.path.basename(dest_path)
1544 if self.store_url:
1545 store_url = os.path.join(self.store_url,store_url)
1546 self.update_user_score(userid)
1547 return True, (iddoc, store_url)
1548
1549 - def insert_image(self, pkgkey, userid, username, image_path, file_name,
1550 title, description, keywords):
1551 return self.insert_generic_file(pkgkey, userid, username, image_path,
1552 file_name, self.DOC_TYPES['image'], title, description, keywords)
1553
1554 - def insert_file(self, pkgkey, userid, username, file_path, file_name, title,
1555 description, keywords):
1556 return self.insert_generic_file(pkgkey, userid, username, file_path,
1557 file_name, self.DOC_TYPES['generic_file'], title, description,
1558 keywords)
1559
1562
1565
1567 self.check_connection()
1568
1569 userid = self.get_iddoc_userid(iddoc)
1570 self.execute_query('SELECT `ddata` FROM entropy_docs WHERE `iddoc` = %s AND `iddoctype` = %s',(
1571 iddoc,
1572 doc_type,
1573 )
1574 )
1575 data = self.fetchone() or {}
1576 mypath = data.get('ddata')
1577 if not isinstance(mypath, basestring) and (mypath is not None):
1578 mypath = mypath.tostring()
1579 if mypath is not None:
1580 mypath = os.path.join(self.STORE_PATH,mypath)
1581 if os.path.isfile(mypath) and os.access(mypath,os.W_OK):
1582 os.remove(mypath)
1583
1584 self.remove_keywords(iddoc)
1585 self.execute_query('DELETE FROM entropy_docs WHERE `iddoc` = %s AND `iddoctype` = %s',(
1586 iddoc,
1587 doc_type,
1588 )
1589 )
1590 if userid:
1591 self.update_user_score(userid)
1592 return True, (iddoc, None)
1593
1594 - def insert_youtube_video(self, pkgkey, userid, username, video_path, file_name, title, description, keywords):
1595 self.check_connection()
1596 if not self.gdata:
1597 return False, None
1598
1599 idkey = self.handle_pkgkey(pkgkey)
1600 video_path = os.path.realpath(video_path)
1601 if not (os.access(video_path,os.R_OK) and os.path.isfile(video_path)):
1602 return False
1603 virus_found, virus_type = self.scan_for_viruses(video_path)
1604 if virus_found:
1605 os.remove(video_path)
1606 return False, None
1607
1608 new_video_path = video_path
1609 if isinstance(file_name,basestring):
1610
1611 new_video_path = os.path.join(os.path.dirname(video_path),os.path.basename(file_name))
1612 scount = 0
1613 while os.path.lexists(new_video_path):
1614 scount += 1
1615 bpath = "%s.%s" % (unicode(scount),os.path.basename(file_name),)
1616 new_video_path = os.path.join(os.path.dirname(video_path),bpath)
1617 shutil.move(video_path,new_video_path)
1618
1619 yt_service = self.get_youtube_service()
1620 if yt_service == None:
1621 return False, None
1622
1623 mykeywords = ', '.join([x.strip().strip(',') for x in \
1624 keywords.split() + ["sabayon"] if (x.strip() and x.strip(",") and \
1625 (len(x.strip()) > 4))])
1626 gd_keywords = self.gdata.media.Keywords(text = mykeywords)
1627
1628 mydescription = "%s: %s" % (pkgkey,description,)
1629 mytitle = "%s: %s" % (self.system_name,title,)
1630 my_media_group = self.gdata.media.Group(
1631 title = self.gdata.media.Title(text = mytitle),
1632 description = self.gdata.media.Description(
1633 description_type = 'plain',
1634 text = mydescription
1635 ),
1636 keywords = gd_keywords,
1637 category = self.gdata.media.Category(
1638 text = 'Tech',
1639 scheme = 'http://gdata.youtube.com/schemas/2007/categories.cat',
1640 label = 'Tech'
1641 ),
1642 player = None
1643 )
1644 video_entry = self.gdata.youtube.YouTubeVideoEntry(media = my_media_group)
1645 new_entry = yt_service.InsertVideoEntry(video_entry, new_video_path)
1646 if not isinstance(new_entry, self.gdata.youtube.YouTubeVideoEntry):
1647 return False, None
1648 video_url = new_entry.GetSwfUrl()
1649 video_id = os.path.basename(video_url)
1650
1651 iddoc = self.insert_generic_doc(idkey, userid, username,
1652 self.DOC_TYPES['youtube_video'], video_id, title, description,
1653 keywords)
1654 if isinstance(iddoc,basestring):
1655 return False, (iddoc, None,)
1656 return True, (iddoc, video_id,)
1657
1677
1678 self.execute_query('SELECT `ddata` FROM entropy_docs WHERE `iddoc` = %s AND `iddoctype` = %s',(
1679 iddoc,
1680 self.DOC_TYPES['youtube_video'],
1681 )
1682 )
1683 data = self.fetchone()
1684 if data is None:
1685 do_remove()
1686 return False, None
1687 elif not data.has_key('ddata'):
1688 do_remove()
1689 return False, None
1690
1691 video_id = data.get('ddata')
1692 try:
1693 video_entry = yt_service.GetYouTubeVideoEntry(video_id = video_id)
1694 deleted = yt_service.DeleteVideoEntry(video_entry)
1695 except:
1696 deleted = True
1697
1698 if deleted:
1699 do_remove()
1700 if userid: self.update_user_score(userid)
1701 return deleted, (iddoc, video_id,)
1702
1704 self.check_connection()
1705 if not self.gdata:
1706 return None
1707 keywords = ['google_email', 'google_password']
1708 for keyword in keywords:
1709 if not self.connection_data.has_key(keyword):
1710 return None
1711
1712 srv = self.YouTubeService.YouTubeService()
1713 srv.email = self.connection_data['google_email']
1714 srv.password = self.connection_data['google_password']
1715 if self.connection_data.has_key('google_developer_key'):
1716 srv.developer_key = self.connection_data['google_developer_key']
1717 if self.connection_data.has_key('google_client_id'):
1718 srv.client_id = self.connection_data['google_client_id']
1719 srv.source = 'Entropy'
1720 srv.ProgrammaticLogin()
1721 return srv
1722
1724
1725 import socket
1726 import entropy.dump as dumpTools
1727 import entropy.tools as entropyTools
1728 import zlib
1729 import select
1730 - def __init__(self, OutputInterface, ClientCommandsClass, quiet = False, show_progress = True, output_header = '', ssl = False, socket_timeout = 25):
1731
1732
1733 if not hasattr(OutputInterface,'updateProgress'):
1734 mytxt = _("OutputInterface does not have an updateProgress method")
1735 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
1736 elif not callable(OutputInterface.updateProgress):
1737 mytxt = _("OutputInterface does not have an updateProgress method")
1738 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (OutputInterface,mytxt,))
1739
1740 from entropy.client.services.ugc.commands import Base
1741 if not issubclass(ClientCommandsClass, (Base,)):
1742 mytxt = _("A valid entropy.client.services.ugc.commands.Base interface is needed")
1743 raise IncorrectParameter("IncorrectParameter: %s, (! %s !)" % (ClientCommandsClass,mytxt,))
1744
1745 self.ssl_mod = None
1746 self.setup_ssl(ssl)
1747
1748 self.answers = etpConst['socket_service']['answers']
1749 self.Output = OutputInterface
1750 self.sock_conn = None
1751 self.real_sock_conn = None
1752 self.hostname = None
1753 self.hostport = None
1754 self.buffered_data = ''
1755 self.buffer_length = None
1756 self.quiet = quiet
1757 self.show_progress = show_progress
1758 self.output_header = output_header
1759 self.CmdInterface = ClientCommandsClass(self.Output, self)
1760 self.CmdInterface.output_header = self.output_header
1761 self.socket_timeout = socket_timeout
1762 self.socket.setdefaulttimeout(self.socket_timeout)
1763
1764
1766
1767 self.SSL = {}
1768 self.SSL_exceptions = {
1769 'WantReadError': None,
1770 'WantWriteError': None,
1771 'WantX509LookupError': None,
1772 'ZeroReturnError': None,
1773 'Error': None,
1774 'SysCallError': None
1775 }
1776 self.ssl = ssl
1777 self.pyopenssl = True
1778 self.context = None
1779
1780 '''
1781 self.server_cert = server_cert
1782 self.server_ca_cert = server_ca_cert
1783 self.ssl_pkey = None
1784 self.ssl_cert = None
1785 self.ssl_CN = 'Entropy Repository Service Client'
1786 self.ssl_digest = 'md5'
1787 self.ssl_serial = 1
1788 self.ssl_not_before = 0
1789 self.ssl_not_after = 60*60*24*1 # 1 day
1790 '''
1791
1792 if self.ssl:
1793
1794 if "--nopyopenssl" in sys.argv:
1795 self.pyopenssl = False
1796 else:
1797 try:
1798 from OpenSSL import SSL, crypto
1799 except ImportError:
1800 self.pyopenssl = False
1801
1802
1803 try:
1804 import ssl as ssl_mod
1805 self.ssl_mod = ssl_mod
1806 except ImportError:
1807 pass
1808
1809 '''
1810 if not (self.server_cert and self.server_ca_cert):
1811 raise SSLError('SSLError: %s: %s' % (_("Specified SSL server certificate not available"),)
1812 if not (os.path.isfile(self.server_cert) and \
1813 os.access(self.server_cert,os.R_OK) and \
1814 os.path.isfile(self.server_ca_cert) and \
1815 os.access(self.server_ca_cert,os.R_OK)) and self.pyopenssl:
1816 raise SSLError('SSLError: %s: %s' % (_("Specified SSL server certificate not available"),self.server_cert,))
1817 '''
1818
1819 if self.pyopenssl:
1820
1821 self.SSL_exceptions['WantReadError'] = SSL.WantReadError
1822 self.SSL_exceptions['WantWriteError'] = SSL.WantWriteError
1823 self.SSL_exceptions['WantX509LookupError'] = SSL.WantX509LookupError
1824 self.SSL_exceptions['ZeroReturnError'] = SSL.ZeroReturnError
1825 self.SSL_exceptions['Error'] = SSL.Error
1826 self.SSL_exceptions['SysCallError'] = SSL.SysCallError
1827 self.SSL['m'] = SSL
1828 self.SSL['crypto'] = crypto
1829
1830
1831 self.context = self.SSL['m'].Context(self.SSL['m'].SSLv23_METHOD)
1832
1833
1834
1835 '''
1836 self.ssl_pkey = self.create_ssl_key_pair(self.SSL['crypto'].TYPE_RSA, 1024)
1837 self.context.use_privatekey(self.ssl_pkey)
1838 self.context.use_certificate_file(self.server_cert)
1839 self.context.load_verify_locations(self.server_ca_cert)
1840 self.context.load_client_ca(self.server_cert)
1841 self.ssl_pkey = self.create_ssl_key_pair(self.SSL['crypto'].TYPE_RSA, 1024)
1842 self.ssl_cert = self.create_ssl_certificate(self.ssl_pkey)
1843 self.context.use_privatekey(self.ssl_pkey)
1844 self.context.use_certificate(self.ssl_cert)
1845 self.context.load_client_ca(self.server_cert)
1846 '''
1847
1848 else:
1849 self.ssl = False
1850 self.pyopenssl = False
1851
1852
1854 if not self.pyopenssl:
1855 raise SSLError('SSLError: %s' % (_("OpenSSL Python module not available, you need dev-python/pyopenssl"),))
1856
1857 '''
1858 # this function should do the authentication checking to see that
1859 # the client is who they say they are.
1860 def verify_ssl_cb(self, conn, cert, errnum, depth, ok):
1861 self.check_pyopenssl()
1862 #print 'Got certificate: %s' % cert.get_subject()
1863 #print repr(ok),repr(cert),repr(errnum),repr(depth)
1864 return ok
1865
1866
1867 def create_ssl_key_pair(self, keytype, bits):
1868 if not self.pyopenssl:
1869 raise SSLError('SSLError: %s' % (_("OpenSSL Python module not available, you need dev-python/pyopenssl"),))
1870 pkey = self.SSL['crypto'].PKey()
1871 pkey.generate_key(keytype, bits)
1872 return pkey
1873
1874 def create_ssl_certificate(self, pkey):
1875 self.check_pyopenssl()
1876 myreq = self.create_ssl_certificate_request(pkey, CN = self.ssl_CN)
1877 cert = self.SSL['crypto'].X509()
1878 cert.set_serial_number(self.ssl_serial)
1879 cert.gmtime_adj_notBefore(self.ssl_not_before)
1880 cert.gmtime_adj_notAfter(self.ssl_not_after)
1881 cert.set_issuer(myreq.get_subject())
1882 cert.set_subject(myreq.get_subject())
1883 cert.set_pubkey(myreq.get_pubkey())
1884 cert.sign(pkey, self.ssl_digest)
1885 return cert
1886
1887 def create_ssl_certificate_request(self, pkey, **name):
1888 self.check_pyopenssl()
1889 req = self.SSL['crypto'].X509Req()
1890 subj = req.get_subject()
1891 for (key,value) in name.items():
1892 setattr(subj, key, value)
1893 req.set_pubkey(pkey)
1894 req.sign(pkey, self.ssl_digest)
1895
1896 return req
1897 '''
1898
1900
1901 if gzipped:
1902 data = self.zlib.decompress(data)
1903 obj = self.dumpTools.unserialize_string(data)
1904
1905 return obj
1906
1908 return str(len(data))+self.answers['eos']+data
1909
1911 self.check_socket_connection()
1912 if hasattr(self.sock_conn,'settimeout'):
1913 self.sock_conn.settimeout(self.socket_timeout)
1914 data = self.append_eos(data)
1915 try:
1916
1917 encode_done = False
1918 mydata = data[:]
1919 while 1:
1920 try:
1921 if self.ssl and not self.pyopenssl:
1922 sent = self.sock_conn.write(mydata)
1923 else:
1924 sent = self.sock_conn.send(mydata)
1925 if sent == len(mydata):
1926 break
1927 mydata = mydata[sent:]
1928
1929 except self.SSL_exceptions['WantWriteError']:
1930 self._ssl_poll(select.POLLOUT, 'write')
1931 except self.SSL_exceptions['WantReadError']:
1932 self._ssl_poll(select.POLLIN, 'write')
1933 except UnicodeEncodeError, e:
1934 if encode_done:
1935 raise
1936 mydata = mydata.encode('utf-8')
1937 encode_done = True
1938 continue
1939
1940 except self.SSL_exceptions['Error'], e:
1941 self.disconnect()
1942 raise SSLError('SSLError: %s' % (e,))
1943 except self.socket.sslerror, e:
1944 self.disconnect()
1945 raise SSLError('SSL Socket error: %s' % (e,))
1946 except:
1947 self.disconnect()
1948 raise
1949
1951 self.check_socket_connection()
1952 try:
1953 self.transmit("%s end" % (session_id,))
1954
1955 data = self.receive()
1956 except self.socket.error, e:
1957 if etpUi['debug']:
1958 self.entropyTools.print_traceback()
1959 import pdb
1960 pdb.set_trace()
1961 if e[0] == 32:
1962 return None
1963 raise
1964 except SSLError:
1965 raise
1966 return data
1967
1974
1976 self.check_socket_connection()
1977 self.socket.setdefaulttimeout(self.socket_timeout)
1978 self.transmit('alive %s' % (session,))
1979 data = self.receive()
1980 if data == self.answers['ok']:
1981 return True
1982 return False
1983
1984 - def _ssl_poll(self, filter_type, caller_name):
1985 poller = select.poll()
1986 poller.register(self.sock_conn, filter_type)
1987 res = poller.poll(self.sock_conn.gettimeout() * 1000)
1988 if len(res) != 1:
1989 raise TimeoutError("Connection timed out on %s" % caller_name)
1990
1992
1993 self.check_socket_connection()
1994 if hasattr(self.sock_conn,'settimeout'):
1995 self.sock_conn.settimeout(self.socket_timeout)
1996 self.ssl_prepending = True
1997
1998 def do_receive():
1999 data = ''
2000 if self.ssl and not self.pyopenssl:
2001 data = self.sock_conn.read(1024)
2002 elif self.ssl:
2003 if self.ssl_prepending:
2004 data = self.sock_conn.recv(1024)
2005 self.ssl_prepending = False
2006 while self.sock_conn.pending():
2007 data += self.sock_conn.recv(1024)
2008 else:
2009 data = self.sock_conn.recv(1024)
2010 return data
2011
2012 myeos = self.answers['eos']
2013 while 1:
2014
2015 try:
2016
2017 data = do_receive()
2018 if self.buffer_length == None:
2019 self.buffered_data = ''
2020 if (data == '') or (data == self.answers['cl']):
2021
2022
2023 if not self.quiet:
2024 mytxt = _("command not supported. receive aborted")
2025 self.Output.updateProgress(
2026 "[%s:%s] %s" % (
2027 brown(self.hostname),
2028 bold(str(self.hostport)),
2029 blue(mytxt),
2030 ),
2031 importance = 1,
2032 type = "warning",
2033 header = self.output_header
2034 )
2035 return None
2036 elif len(data) < len(myeos):
2037 if not self.quiet:
2038 mytxt = _("malformed EOS. receive aborted")
2039 self.Output.updateProgress(
2040 "[%s:%s] %s" % (
2041 brown(self.hostname),
2042 bold(str(self.hostport)),
2043 blue(mytxt),
2044 ),
2045 importance = 1,
2046 type = "warning",
2047 header = self.output_header
2048 )
2049 if etpUi['debug']:
2050 self.entropyTools.print_traceback()
2051 import pdb
2052 pdb.set_trace()
2053 return None
2054 mystrlen = data.split(myeos)[0]
2055 self.buffer_length = int(mystrlen)
2056 data = data[len(mystrlen)+1:]
2057 self.buffer_length -= len(data)
2058 self.buffered_data = data
2059 else:
2060 self.buffer_length -= len(data)
2061 self.buffered_data += data
2062
2063 while self.buffer_length > 0:
2064 x = do_receive()
2065 if self.ssl and self.pyopenssl and not x:
2066 self.ssl_prepending = True
2067 self.buffer_length -= len(x)
2068 self.buffered_data += x
2069 self.buffer_length = None
2070 break
2071
2072 except ValueError, e:
2073 if not self.quiet:
2074 mytxt = _("malformed data. receive aborted")
2075 self.Output.updateProgress(
2076 "[%s:%s] %s: %s" % (
2077 brown(self.hostname),
2078 bold(str(self.hostport)),
2079 blue(mytxt),
2080 e,
2081 ),
2082 importance = 1,
2083 type = "warning",
2084 header = self.output_header
2085 )
2086 return None
2087 except self.socket.timeout, e:
2088 if not self.quiet:
2089 mytxt = _("connection timed out while receiving data")
2090 self.Output.updateProgress(
2091 "[%s:%s] %s: %s" % (
2092 brown(self.hostname),
2093 bold(str(self.hostport)),
2094 blue(mytxt),
2095 e,
2096 ),
2097 importance = 1,
2098 type = "warning",
2099 header = self.output_header
2100 )
2101 return None
2102 except self.socket.error, e:
2103 if not self.quiet:
2104 mytxt = _("connection error while receiving data")
2105 self.Output.updateProgress(
2106 "[%s:%s] %s: %s" % (
2107 brown(self.hostname),
2108 bold(str(self.hostport)),
2109 blue(mytxt),
2110 e,
2111 ),
2112 importance = 1,
2113 type = "warning",
2114 header = self.output_header
2115 )
2116 return None
2117 except self.SSL_exceptions['WantX509LookupError']:
2118 continue
2119 except self.SSL_exceptions['WantReadError']:
2120 self._ssl_poll(select.POLLIN, 'read')
2121 except self.SSL_exceptions['WantWriteError']:
2122 self._ssl_poll(select.POLLOUT, 'read')
2123 except self.SSL_exceptions['ZeroReturnError']:
2124 break
2125 except self.SSL_exceptions['SysCallError'], e:
2126 if not self.quiet:
2127 mytxt = _("syscall error while receiving data")
2128 self.Output.updateProgress(
2129 "[%s:%s] %s: %s" % (
2130 brown(self.hostname),
2131 bold(str(self.hostport)),
2132 blue(mytxt),
2133 e,
2134 ),
2135 importance = 1,
2136 type = "warning",
2137 header = self.output_header
2138 )
2139 return None
2140
2141 return self.buffered_data
2142
2144 if not self.quiet:
2145 mytxt = _("Reconnecting to socket")
2146 self.Output.updateProgress(
2147 "[%s:%s] %s" % (
2148 brown(unicode(self.hostname)),
2149 bold(unicode(self.hostport)),
2150 blue(mytxt),
2151 ),
2152 importance = 1,
2153 type = "info",
2154 header = self.output_header
2155 )
2156 self.connect(self.hostname,self.hostport)
2157
2159 if not self.sock_conn:
2160 raise ConnectionError("ConnectionError: %s" % (_("Not connected to host"),))
2161
2163
2164 if self.ssl:
2165 self.real_sock_conn = self.socket.socket(self.socket.AF_INET, self.socket.SOCK_STREAM)
2166 if hasattr(self.real_sock_conn,'settimeout'):
2167 self.real_sock_conn.settimeout(self.socket_timeout)
2168 if self.pyopenssl:
2169 self.sock_conn = self.SSL['m'].Connection(self.context, self.real_sock_conn)
2170 else:
2171 self.sock_conn = self.real_sock_conn
2172
2173
2174
2175 self.real_sock_conn.setblocking(True)
2176 else:
2177 self.sock_conn = self.socket.socket(self.socket.AF_INET, self.socket.SOCK_STREAM)
2178 if hasattr(self.sock_conn,'settimeout'):
2179 self.sock_conn.settimeout(self.socket_timeout)
2180 self.real_sock_conn = self.sock_conn
2181
2182 self.hostname = host
2183 self.hostport = port
2184
2185 try:
2186 self.sock_conn.connect((self.hostname, self.hostport))
2187 if self.ssl and not self.pyopenssl:
2188 if self.ssl_mod is not None:
2189 self.sock_conn = self.ssl_mod.wrap_socket(self.real_sock_conn)
2190 else:
2191 self.sock_conn = self.socket.ssl(self.real_sock_conn)
2192
2193 if not self.quiet:
2194 mytxt = _("Warning: you are using an emergency SSL interface, SSL certificate can't be verified. Please install dev-python/pyopenssl")
2195 self.Output.updateProgress(
2196 "[%s:%s] %s" % (
2197 brown(str(self.hostname)),
2198 bold(str(self.hostport)),
2199 blue(mytxt),
2200 ),
2201 importance = 1,
2202 type = "warning",
2203 header = self.output_header
2204 )
2205 mytxt = _("Service issuer")
2206 self.Output.updateProgress(
2207 "[%s:%s] %s: %s" % (
2208 brown(str(self.hostname)),
2209 bold(str(self.hostport)),
2210 blue(mytxt),
2211 self.sock_conn.issuer()
2212 ),
2213 importance = 1,
2214 type = "warning",
2215 header = self.output_header
2216 )
2217 except self.socket.error, e:
2218 if e[0] == 111:
2219 mytxt = "%s: %s, %s: %s" % (_("Cannot connect to"),host,_("on port"),port,)
2220 raise ConnectionError("ConnectionError: %s" % (mytxt,))
2221 else:
2222 raise
2223
2224 if not self.quiet:
2225 mytxt = _("Successfully connected to host")
2226 self.Output.updateProgress(
2227 "[%s:%s] %s" % (
2228 brown(self.hostname),
2229 bold(str(self.hostport)),
2230 blue(mytxt),
2231 ),
2232 importance = 1,
2233 type = "info",
2234 header = self.output_header
2235 )
2236
2238 if not self.real_sock_conn:
2239 return True
2240 if self.ssl and self.pyopenssl:
2241 self.sock_conn.shutdown()
2242 self.sock_conn.close()
2243 elif self.ssl and not self.pyopenssl:
2244 try:
2245 self.real_sock_conn.shutdown(self.socket.SHUT_RDWR)
2246 except self.socket.error:
2247 pass
2248 del self.sock_conn
2249 self.sock_conn = None
2250 try:
2251 self.real_sock_conn.close()
2252 except self.socket.error:
2253 pass
2254 if not self.quiet:
2255 mytxt = _("Successfully disconnected from host")
2256 self.Output.updateProgress(
2257 "[%s:%s] %s" % (
2258 brown(self.hostname),
2259 bold(str(self.hostport)),
2260 blue(mytxt),
2261 ),
2262 importance = 1,
2263 type = "info",
2264 header = self.output_header
2265 )
2266 self.real_sock_conn = None
2267
2268
2269
2270