2b63c52c476c6373ebeeaa72a03c8770d6733c09
[living-lab-site.git] / scripts / auto-publishing / publish_videos.py
1 #!/usr/bin/python
2 #
3 # Copyright Calin-Andrei Burloiu, calin.burloiu@gmail.com
4 #
5 # Automatically publishes videos in P2P-Tube DB based on the video files and
6 # a videos info file. Parameters: videos_info_file videos_directory category
7 #
8 import sys
9 import MySQLdb
10 import os
11 import fnmatch
12 import subprocess
13 import string
14 import json
15
16 # cms_content table
17 class VideosTable:
18     tableName = "videos"
19     user_id = 1
20     thumbs_count = 1
21     default_thumb = 0
22     
23     directory = os.curdir
24     default_video_ext = 'ogv'
25
26     def __init__(self, dbCur, directory, name, title, description, tags, category):
27         self.dbCur = dbCur
28         self.directory = directory
29
30         self.name = name
31         self.title = title
32         self.description = description
33         self.duration, self.formats = self.findVideosMeta()
34         self.formats_json = json.dumps(self.formats, separators=(',', ':'))
35         self.category = category
36         
37         tagList = tags.split(',')
38         self.tags = {}
39         for tag in tagList:
40             self.tags[tag.strip()] = 0
41         self.tags_json = json.dumps(self.tags, separators=(',', ':'))
42         
43     def getVideoDefinition(self, fileName):
44         pipe = subprocess.Popen('mediainfo --Inform="Video;%Height%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
45         height = pipe.readline().strip()
46
47         pipe = subprocess.Popen('mediainfo --Inform="Video;%ScanType%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
48         scanType = pipe.readline().strip()
49         if scanType == '' or scanType == 'Progressive':
50             scanType = 'p'
51         elif scanType == 'Interlaced':
52             scanType = 'i';
53
54         return height + scanType
55
56     def getVideoDuration(self, fileName):
57         pipe = subprocess.Popen('mediainfo --Inform="General;%Duration/String3%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
58         output = pipe.readline().strip()
59         dotPos = output.find('.')
60         if output[0:2] == '00':
61             duration = output[3:dotPos]
62         else:
63             duration = output[:dotPos]
64
65         return duration
66         
67
68     # Returns a pair with duration and formats list.
69     def findVideosMeta(self):
70         files = [f for f in os.listdir(self.directory) if os.path.isfile(os.path.join(self.directory, f))]
71         files = fnmatch.filter(files, self.name + "*")
72
73         # Duration not set
74         duration = None
75
76         # Formats list
77         formats = []
78         for f in files:
79             if f.find('.tstream') == -1:
80                 # Duration (if not set yet)
81                 if duration == None:
82                     duration = self.getVideoDuration(f)
83                 format_ = {}
84                 format_['def'] = f[(f.rfind('_')+1):f.rfind('.')]
85                 ext = f[(f.rfind('.')+1):]
86                 if ext != self.default_video_ext:
87                     format_['ext'] = ext
88                 if format_['def'] != self.getVideoDefinition(f):
89                     raise VideoDefException(f)
90                 formats.append(format_)
91
92         return (duration, formats)
93
94     def insert(self):
95         if self.duration == None or self.formats_json == None or self.tags_json == None:
96             print "Bzzzz"
97         query = "INSERT INTO `" + self.tableName + "` (name, title, description, duration, formats, category, user_id, tags, date, thumbs_count, default_thumb) VALUES ('" + self.name + "', '" + self.title + "', '" + self.description + "', '" + self.duration + "', '" + self.formats_json + "', '" + self.category + "', " + str(self.user_id) + ", '" + self.tags_json + "', NOW(), " + str(self.thumbs_count) + ", " + str(self.default_thumb) + ")"
98         self.dbCur.execute(query)    
99     
100     @staticmethod
101     def getAllNames(dbCur, category):
102         allNames = set()
103         query = "SELECT name FROM `" + VideosTable.tableName + "` WHERE category = '" + category + "'"
104         dbCur.execute(query)
105
106         while(True):
107             row = dbCur.fetchone()
108             if row == None:
109                 break
110             allNames.add(row[0])
111
112         return allNames
113
114
115 class VideoDefException(Exception):
116     def __init__(self, value):
117         self.value = 'Invalid video definition in file name "' + value + '"! '
118
119     def __str__(self):
120         return repr(self.value)
121
122
123 def main():
124     # Check arguments.
125     if len(sys.argv) < 3:
126         sys.stdout.write('usage: ' + sys.argv[0] + ' videos_info_file videos_dir category\n')
127         exit(1)
128
129     # Command line arguments
130     fileName = sys.argv[1]
131     directory = sys.argv[2]
132     category = sys.argv[3]
133     if len(sys.argv) == 4:
134         thumbsDir = sys.argv[3]
135     else:
136         thumbsDir = None
137
138     # Connect to DB
139     dbConn = MySQLdb.connect(host = 'koala.cs.pub.ro', user = 'koala_p2pnext',
140             passwd = 'ahmitairoo', db = 'koala_livinglab')
141     dbCur = dbConn.cursor()
142
143     allNames = VideosTable.getAllNames(dbCur, category)
144
145     # Open info file
146     file = open(fileName, 'r')
147
148     # Read videos info file
149     i = 1
150     name = file.readline()
151     while name != '':
152         name = name.strip()
153         title = file.readline().strip()
154         description = file.readline().strip()
155         tags = file.readline().strip()
156         
157         if not name in allNames:
158             sys.stdout.write(str(i) + '. ' + name + '\r')
159             try:
160                 video = VideosTable(dbCur, directory, name, title, description, tags, category)
161                 video.insert()
162                 i = i+1
163
164             except VideoDefException as e:
165                 sys.stdout.write('\n' + e.value + '\n')
166
167         name = file.readline()
168
169     # Clean-up
170     dbCur.close()
171     dbConn.close()
172
173     return 0
174
175
176 if __name__ == "__main__":
177     sys.exit(main())