paper: Mention grant agreement number in Acknowledgement
[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_id
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
25     def __init__(self, dbCur, directory, name, title, description, tags, category_id):
26         self.dbCur = dbCur
27         self.directory = directory
28
29         self.name = name
30         self.title = title
31         self.description = description
32         self.duration, self.formats = self.findVideosMeta()
33         self.formats_json = json.dumps(self.formats, separators=(',', ':'))
34         self.category_id = category_id
35         
36         tagList = tags.split(',')
37         self.tags = {}
38         for tag in tagList:
39             if tag != '':
40                 self.tags[tag.strip()] = 0
41         self.tags_json = json.dumps(self.tags, separators=(',', ':'))
42         
43     def getVideoResolution(self, fileName):
44         pipe = subprocess.Popen('mediainfo --Inform="Video;%Width%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
45         width = pipe.readline().strip()
46
47         pipe = subprocess.Popen('mediainfo --Inform="Video;%Height%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
48         height = pipe.readline().strip()
49
50         return width + 'x' + height
51
52     def getVideoDar(self, fileName):
53         pipe = subprocess.Popen('mediainfo --Inform="Video;%DisplayAspectRatio/String%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
54         dar = pipe.readline().strip()
55
56         return dar
57
58     def getVideoDuration(self, fileName):
59         pipe = subprocess.Popen('mediainfo --Inform="General;%Duration/String3%" ' + os.path.join(self.directory, fileName), shell=True, stdout=subprocess.PIPE).stdout
60         output = pipe.readline().strip()
61         dotPos = output.find('.')
62         if output[0:2] == '00':
63             duration = output[3:dotPos]
64         else:
65             duration = output[:dotPos]
66
67         return duration
68         
69
70     # Returns a pair with duration and formats list.
71     def findVideosMeta(self):
72         files = [f for f in os.listdir(self.directory) if os.path.isfile(os.path.join(self.directory, f))]
73         files = fnmatch.filter(files, self.name + "_*")
74
75         # Duration not set
76         duration = None
77
78         # Formats list
79         formats = []
80         for f in files:
81             if f.find('.tstream') == -1:
82                 # Duration (set once)
83                 if duration == None:
84                     duration = self.getVideoDuration(f)
85
86                 format_ = {}
87                 format_['res'] = self.getVideoResolution(f)
88                 format_['dar'] = self.getVideoDar(f)
89                 format_['ext'] = f[(f.rfind('.')+1):]
90
91                 fileDef = f[(f.rfind('_')+1):f.rfind('.')]
92                 videoDef = format_['res'].split('x')[1] + 'p'
93                 if fileDef != videoDef:
94                     raise VideoDefException(f)
95
96                 formats.append(format_)
97
98         return (duration, formats)
99
100     def insert(self):
101         #if self.duration == None or self.formats_json == None or self.tags_json == None:
102         query = "INSERT INTO `" + self.tableName + "` (name, title, description, duration, formats, category_id, user_id, tags, date, thumbs_count, default_thumb) VALUES ('" + self.name + "', '" + self.title + "', '" + self.description + "', '" + self.duration + "', '" + self.formats_json + "', " + str(self.category_id) + ", " + str(self.user_id) + ", '" + self.tags_json + "', NOW(), " + str(self.thumbs_count) + ", " + str(self.default_thumb) + ")"
103         self.dbCur.execute(query)    
104     
105     @staticmethod
106     def getAllNames(dbCur, category_id):
107         allNames = set()
108         query = "SELECT name FROM `" + VideosTable.tableName + "` WHERE category_id = " + str(category_id)
109         dbCur.execute(query)
110
111         while(True):
112             row = dbCur.fetchone()
113             if row == None:
114                 break
115             allNames.add(row[0])
116
117         return allNames
118
119
120 class VideoDefException(Exception):
121     def __init__(self, value):
122         self.value = 'Invalid video definition in file name "' + value + '"! '
123
124     def __str__(self):
125         return repr(self.value)
126
127
128 def main():
129     # Check arguments.
130     if len(sys.argv) < 3:
131         sys.stdout.write('usage: ' + sys.argv[0] + ' videos_info_file videos_dir category_id\n')
132         exit(1)
133
134     # Command line arguments
135     fileName = sys.argv[1]
136     directory = sys.argv[2]
137     category_id = int(sys.argv[3])
138     if len(sys.argv) == 4:
139         thumbsDir = sys.argv[3]
140     else:
141         thumbsDir = None
142
143     # Connect to DB
144     dbConn = MySQLdb.connect(host = 'koala.cs.pub.ro', user = 'koala_p2pnext',
145             passwd = 'ahmitairoo', db = 'koala_livinglab')
146     dbCur = dbConn.cursor()
147
148     allNames = VideosTable.getAllNames(dbCur, category_id)
149
150     # Open info file
151     file = open(fileName, 'r')
152
153     # Read videos info file
154     i = 1
155     name = file.readline()
156     while name != '':
157         name = name.strip()
158         title = file.readline().strip()
159         description = file.readline().strip()
160         tags = file.readline().strip()
161         
162         if not name in allNames:
163             sys.stdout.write(str(i) + '. ' + name + '\r')
164             try:
165                 video = VideosTable(dbCur, directory, name, title, description, tags, category_id)
166                 video.insert()
167                 i = i+1
168
169             except VideoDefException as e:
170                 sys.stdout.write('\n' + e.value + '\n')
171
172         name = file.readline()
173
174     # Clean-up
175     dbCur.close()
176     dbConn.close()
177     sys.stdout.write('\n')
178
179     return 0
180
181
182 if __name__ == "__main__":
183     sys.exit(main())