Guest User

daniel

a guest
Jul 17th, 2009
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.76 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. # MythKiwi Bulk Meta Grabber
  4. # Version: 0.3
  5. # Author: Hayden Lovett
  6. # Website: mythkiwi.com
  7.  
  8.  
  9.  
  10.  
  11. #TODO Show which movie is being worked on
  12. #TODO if MPlayer is not installed and is needed, prompt for install
  13. #TODO create folder.jpg posters for each folder
  14. #TODO make password last on the string when calling programs incase they are empty
  15.  
  16. import sys
  17. import os
  18. import datetime
  19. import pygtk
  20. pygtk.require("2.0")
  21. import gtk
  22. import gtk.glade
  23. import MySQLdb
  24. import fileinput
  25. import os.path
  26. #import fnmatch
  27. #import time
  28. #import vte
  29. #import types
  30. #import csv
  31.  
  32.  
  33. ####################################################################
  34.  
  35. class metaupdate:
  36.  
  37. def __init__(self):
  38. #Define some variable defaults
  39. self.getAll = 0
  40. self.getMissing = 1
  41. self.defaultsw = 1
  42. self.defaultswitch = "-Default"
  43.  
  44. self.backupmysql = 1
  45. self.includeMovies = 1
  46.  
  47. self.includeTVshows = 1
  48.  
  49. self.homepath = os.getenv("HOME")
  50.  
  51.  
  52. #Set the Glade file
  53. if os.path.exists('MythKiwi Bulk Meta Grabber/data/GUI.glade'):
  54. self.gladefile = "MythKiwi Bulk Meta Grabber/data/GUI.glade"
  55. else:
  56. self.gladefile = "data/GUI.glade"
  57. self.wTree = gtk.glade.XML(self.gladefile)
  58.  
  59. #Define glade objects to use in script
  60. #Make Video List editable
  61. self.videolistText = self.wTree.get_widget("videolist")
  62. #Make TV Show list editable
  63. self.tvlistText = self.wTree.get_widget("tvlist")
  64.  
  65. self.quit = gtk.main_quit
  66.  
  67. #Define text entry boxes
  68. self.mysqlUsername = gtk.Entry(max=0)
  69. self.mysqlPassword = gtk.Entry(max=0)
  70. self.mysqlHost = gtk.Entry(max=0)
  71. self.mysqlDatabase = gtk.Entry(max=0)
  72.  
  73.  
  74. #mysql test images for mysql page and tab
  75. self.testsuccess = self.wTree.get_widget("testsuccess")
  76. self.testfailed = self.wTree.get_widget("testfailed")
  77. self.testsuccess1 = self.wTree.get_widget("testsuccess1")
  78. self.testfailed1 = self.wTree.get_widget("testfailed1")
  79.  
  80. #Save Mysql Window
  81. self.saveWindow = self.wTree.get_widget("saveWindow")
  82. self.chooseSave = self.wTree.get_widget("chooseSave")
  83.  
  84. #Restore MysqlWindow
  85. self.restoreWindow = self.wTree.get_widget("restoreWindow")
  86. self.chooseRestore = self.wTree.get_widget("chooseRestore")
  87.  
  88.  
  89. #Create our dictionary and connect it
  90. dic = { #"on_skywizard_clicked" : self.skywizard,
  91.  
  92. "on_backupmysql_toggled" : self.backupmysql_toggle,
  93. "on_getmysql_clicked" : self.getmysql,
  94. "on_testmysql_clicked" : self.testmysql,
  95.  
  96. "on_closeAbout_clicked" : self.close_about,
  97. "on_about1_clicked" : self.about_clicked,
  98.  
  99. "on_apply_clicked" : self.startProgram,
  100.  
  101. "on_usefirst_toggled" : self.usefirst_toggled,
  102. "on_scanVideos_clicked" : self.scanVideos,
  103.  
  104.  
  105. "on_allVideos_toggled" : self.getallvideos,
  106. "on_missingVideos_toggled" : self.getvideoswithout,
  107. "on_movies_toggled" : self.includemovies_toggled,
  108. "on_tvshow_toggled" : self.includeTVshows_toggled,
  109.  
  110. "on_restoreMysql_clicked" : self.restoreMysql_clicked,
  111. "on_closeRestoreMysql_clicked" : self.close_restoreWindow,
  112. "on_closeSaveMysql_clicked" : self.close_saveWindow,
  113. "on_restoreApply_clicked" : self.restoreApply,
  114. "on_backupMysql_clicked" : self.backupMysql,
  115. "on_saveApply_clicked" : self.saveApply,
  116.  
  117.  
  118. "on_ProgClose_clicked" : self.ProgClose_clicked,
  119. "on_quit_clicked" : self.quit,
  120. "on_MainWindow_destroy" : self.quit,}
  121. self.wTree.signal_autoconnect(dic)
  122.  
  123.  
  124.  
  125.  
  126.  
  127. #Call Subroutines to Get MySQL Login Info and test it
  128. self.getmysql(self)
  129. self.testmysql(self)
  130.  
  131. #As default load all videos without data
  132. self.getvideos(self)
  133. self.gettvshows(self)
  134.  
  135.  
  136.  
  137.  
  138. ###############################################################################
  139. # default option toggled
  140. def usefirst_toggled(self, widget):
  141. if (self.defaultsw == 1):
  142. print "Default Option Disabled"
  143. self.defaultsw = 0
  144. self.defaultswitch = " "
  145.  
  146. else:
  147. print "Using Default option"
  148. self.defaultsw = 1
  149. self.defaultswitch = "-Default"
  150.  
  151. # Get ALL
  152. def getallvideos(self, widget):
  153. if (self.getAll == 1):
  154. self.getAll = 0
  155. else:
  156. self.getAll = 1
  157. print "Will get Metadata for ALL titles selected"
  158.  
  159. # Get without
  160. def getvideoswithout(self, widget):
  161. if (self.getMissing == 1):
  162. self.getMissing = 0
  163. else:
  164. self.getMissing = 1
  165. print "Will get Metadata only for titles that don't already have data"
  166.  
  167. # Include Movies
  168. def includemovies_toggled(self, widget):
  169. if (self.includeMovies == 1):
  170. self.includeMovies = 0
  171. print "Movies not included"
  172.  
  173. else:
  174. self.includeMovies = 1
  175. print "Movies included"
  176.  
  177. # Include TV shows
  178. def includeTVshows_toggled(self, widget):
  179. if (self.includeTVshows == 1):
  180. self.includeTVshows = 0
  181. print "TV Shows not included"
  182.  
  183. else:
  184. self.includeTVshows = 1
  185. print "TV Shows included"
  186.  
  187.  
  188. # Scan for new videos added to MythVideo
  189. def scanVideos(self, widget):
  190. print "Checking for new videos to add to the database"
  191. os.system('python data/newvideo.py %s %s %s %s &'% (self.mysqlUsername, self.mysqlDatabase, self.mysqlHost, self.mysqlPassword))
  192. #TODO check and remove deleted files
  193.  
  194.  
  195. # Quit the program and close the database
  196. def quit(self, widget):
  197. print "Disconnected from database"
  198. self.cursor.close()
  199. self.db.close()
  200. self.quit
  201.  
  202.  
  203. ######################################################################
  204. # Get list of videos
  205. def getvideos(self, widget):
  206. #fill in Videos missing data area
  207. self.videolistText.get_buffer().insert(self.videolistText.get_buffer().get_end_iter(), "Videos Missing Data")
  208. self.cursor.execute("SELECT title FROM videometadata WHERE inetref='00000000' AND (filename NOT LIKE '% s__e__%' or filename NOT Like '%.s__e__%' or filename NOT Like '%/s__e__%')")
  209. row = self.cursor.fetchone()
  210.  
  211. while row is not None:
  212.  
  213. row = ", ".join([str(c) for c in row])
  214. self.videolistText.get_buffer().insert(self.videolistText.get_buffer().get_end_iter(), "\n" + row)
  215. row = self.cursor.fetchone()
  216.  
  217. #Fill in Already has metadata area
  218. self.videolistText.get_buffer().insert(self.videolistText.get_buffer().get_end_iter(), "\n\n" + "====================\nTitles Already with Data")
  219. self.cursor.execute("SELECT title FROM videometadata WHERE inetref!='00000000' AND not (filename LIKE '% s__e__%' or filename Like '%.s__e__%' or filename Like '%/s__e__%')")
  220. row = self.cursor.fetchone()
  221. while row is not None:
  222.  
  223. row = ", ".join([str(c) for c in row])
  224. self.videolistText.get_buffer().insert(self.videolistText.get_buffer().get_end_iter(), "\n" + row)
  225. row = self.cursor.fetchone()
  226.  
  227.  
  228. # Get list of TV Shows without data
  229. def gettvshows(self, widget):
  230. self.cursor.execute("SELECT title FROM videometadata WHERE plot LIKE 'None' AND (filename LIKE '% s__e__%' or filename Like '%.s__e__%' or filename Like '%/s__e__%')")
  231. row = self.cursor.fetchone()
  232. self.tvlistText.get_buffer().insert(self.tvlistText.get_buffer().get_end_iter(), "Titles Missing Data")
  233.  
  234. while row is not None:
  235. row = ", ".join([str(c) for c in row])
  236. self.tvlistText.get_buffer().insert(self.tvlistText.get_buffer().get_end_iter(), "\n" + row)
  237. row = self.cursor.fetchone()
  238.  
  239.  
  240. #TV shows with data
  241. self.cursor.execute("SELECT title FROM videometadata WHERE plot NOT LIKE 'None' AND (filename LIKE '% s__e__%' or filename Like '%.s__e__%' or filename Like '%/s__e__%')")
  242. row = self.cursor.fetchone()
  243. self.tvlistText.get_buffer().insert(self.tvlistText.get_buffer().get_end_iter(), "\n\n" + "====================\nTitles Already with Data")
  244.  
  245. while row is not None:
  246.  
  247. row = ", ".join([str(c) for c in row])
  248. self.tvlistText.get_buffer().insert(self.tvlistText.get_buffer().get_end_iter(), "\n" + row)
  249. row = self.cursor.fetchone()
  250.  
  251.  
  252. ##########################################
  253. ######### MySQL Login Section ############
  254.  
  255. # Get Mysql Login info from either 1 of 3 locations used by different distros
  256. def getmysql(self, widget):
  257.  
  258. if os.path.exists('%s/.mythtv/mysql.txt' % (self.homepath)):
  259. mysqllogin = file('%s/.mythtv/mysql.txt' % (self.homepath))
  260. elif os.path.exists('/usr/share/mythtv/mysql.txt'):
  261. mysqllogin = file('/usr/share/mythtv/mysql.txt')
  262. else: mysqllogin = file('/etc/mythtv/mysql.txt')
  263.  
  264. for line in mysqllogin:
  265. if 'DBHostName=' in line:
  266. self.mysqlHost = line.replace('DBHostName=','')
  267. self.mysqlHost = self.mysqlHost.replace('\n','')
  268. lbl = self.wTree.get_widget('mysqlHost')
  269. lbl.set_text(self.mysqlHost)
  270.  
  271. if 'DBUserName=' in line:
  272. self.mysqlUsername = line.replace('DBUserName=','')
  273. self.mysqlUsername = self.mysqlUsername.replace('\n','')
  274. lbl = self.wTree.get_widget('mysqlUsername')
  275. lbl.set_text(self.mysqlUsername)
  276.  
  277. if 'DBName=' in line:
  278. self.mysqlDatabase = line.replace('DBName=','')
  279. self.mysqlDatabase = self.mysqlDatabase.replace('\n','')
  280. lbl = self.wTree.get_widget('mysqlDatabase')
  281. lbl.set_text(self.mysqlDatabase)
  282.  
  283. if 'DBPassword=' in line:
  284. self.mysqlPassword = line.replace('DBPassword=','')
  285. self.mysqlPassword = self.mysqlPassword.replace('\n','')
  286. lbl = self.wTree.get_widget('mysqlPassword')
  287. lbl.set_text(self.mysqlPassword)
  288.  
  289.  
  290.  
  291. # Make initial connectin to database and Test MySQL connection
  292. def testmysql(self, widget):
  293. #Get connection details from gui
  294. self.mysqlUsername = self.wTree.get_widget("mysqlUsername").get_text()
  295. self.mysqlPassword = self.wTree.get_widget("mysqlPassword").get_text()
  296. self.mysqlDatabase = self.wTree.get_widget("mysqlDatabase").get_text()
  297. self.mysqlHost = self.wTree.get_widget("mysqlHost").get_text()
  298. try:
  299. self.db = MySQLdb.connect(host=self.mysqlHost, user=self.mysqlUsername, passwd=self.mysqlPassword,db=self.mysqlDatabase)
  300. self.cursor = self.db.cursor()
  301. self.cursor.execute("SELECT NULL")
  302. result = self.cursor.fetchone()
  303. lbl = self.wTree.get_widget('testresult')
  304. lbl.set_text('SUCCESS')
  305. self.testsuccess.show()
  306. self.testsuccess1.show()
  307. self.testfailed.hide()
  308. self.testfailed1.hide()
  309. except:
  310. lbl = self.wTree.get_widget('testresult')
  311. lbl.set_text('Failed')
  312. self.testsuccess.hide()
  313. self.testsuccess1.hide()
  314. self.testfailed.show()
  315. self.testfailed1.show()
  316.  
  317.  
  318. # Toggle Backup MySQL option
  319. def backupmysql_toggle(self, widget):
  320. if (self.backupmysql == 1):
  321. self.backupmysql=0
  322. else:
  323. self.backupmysql=1
  324.  
  325. # Open Backup window
  326. def backupMysql(self, widget):
  327. self.saveWindow.show()
  328.  
  329.  
  330. # Apply on Mysql backup window clicked
  331. def saveApply(self, widget):
  332. saveFile = self.chooseSave.get_filename()
  333. os.system("""mysqldump -u %s -p%s %s > '%s';""" % (self.mysqlUsername, self.mysqlPassword, self.mysqlDatabase, saveFile))
  334. os.system("""chmod 777 '%s'""" % (saveFile))
  335. print "Saved database as %s" % (saveFile)
  336. self.saveWindow.hide()
  337.  
  338. # Close Save Window
  339. def close_saveWindow(self, widget):
  340. self.saveWindow.hide()
  341.  
  342. # Open Restore Mysql window
  343. def restoreMysql_clicked(self, widget):
  344. self.restoreWindow.show()
  345.  
  346.  
  347.  
  348. # Apply on Restore window clicked
  349. def restoreApply(self, widget):
  350. restoreFile = self.chooseRestore.get_filename()
  351. os.system("""mysql -u %s -p%s %s < '%s';""" % (self.mysqlUsername, self.mysqlPassword, self.mysqlDatabase, restoreFile))
  352. print "Restored MySQL Database file %s"% (restoreFile)
  353. self.restoreWindow.hide()
  354.  
  355. # Close Restore window
  356. def close_restoreWindow(self, widget):
  357. self.restoreWindow.hide()
  358.  
  359. ####################################################################################
  360.  
  361. # Open About Window
  362. def about_clicked(self, widget):
  363. about = self.wTree.get_widget("aboutWindow")
  364. about.show ()
  365.  
  366. # Close About Window
  367. def close_about(self, widget):
  368. about = self.wTree.get_widget("aboutWindow")
  369. about.hide()
  370.  
  371.  
  372. # Close Progress screen clicked
  373. def ProgClose_clicked(self, widget):
  374. progress = self.wTree.get_widget("Progress")
  375. progress.hide()
  376.  
  377.  
  378.  
  379.  
  380.  
  381. ############################################################################################
  382. # When APPLY is pressed
  383.  
  384. def startProgram(self, widget):
  385.  
  386.  
  387. # Opening Progress Window
  388.  
  389. #progress = self.wTree.get_widget("Progress")
  390. #progress.show()
  391.  
  392.  
  393. #Create Datestamp Variable
  394. now = datetime.datetime.now()
  395. datestamp = "%s:%s-%s-%s"% (now.date(), now.hour, now.minute, now.second)
  396.  
  397.  
  398.  
  399. #Backup Mysql Database
  400. if (self.backupmysql == 1):
  401. print "Backing up database to %s/%s.sql" % (self.homepath, datestamp)
  402. os.system('mysqldump -u %s -p%s %s > %s/%s.sql;' % (self.mysqlUsername, self.mysqlPassword, self.mysqlDatabase, self.homepath, datestamp))
  403. else:
  404. print "MySQL Database is not being backed up"
  405.  
  406. #Make MythVideo Poster folder if it doesnt exist
  407. self.cursor.execute("SELECT data FROM settings WHERE value='VideoArtworkDir'")
  408. result = self.cursor.fetchone()
  409. VideoArtworkDir = ", ".join([str(c) for c in result])
  410.  
  411. if os.path.exists('%s' % (VideoArtworkDir)):
  412. print 'Using Video Poster Path %s'% (VideoArtworkDir)
  413. else:
  414. print 'Creating new Video Poster Folder at %s'% (VideoArtworkDir)
  415. os.system("mkdir %s" % (VideoArtworkDir))
  416. if not os.path.exists('%s' % (VideoArtworkDir)):
  417. print "\n\nThe Video Poster folder is not writable. \ntype in a terminal \nsudo mkdir %s\n\n" % (VideoArtworkDir)
  418. sys.exit()
  419.  
  420.  
  421.  
  422. #Get MythVideo storage directory
  423. self.cursor.execute("SELECT data FROM settings WHERE value='VideoStartupDir'")
  424. result = self.cursor.fetchone()
  425. VideoDir = ", ".join([str(c) for c in result])
  426.  
  427.  
  428. # Get Metadata for selected videos
  429. if (self.includeMovies == 1):
  430.  
  431.  
  432.  
  433. if (self.getMissing == 1):
  434. self.cursor.execute("SELECT title FROM videometadata WHERE inetref='00000000' AND title NOT LIKE '% s__e__%' and title Not Like '%.s__e__%' and title Not Like '%/s__e__%'")
  435. elif (self.getAll == 1):
  436. self.cursor.execute("SELECT title FROM videometadata WHERE title not Like '% s__e__%' and title Not Like '%.s__e__%' and title Not Like '%/s__e__%'")
  437.  
  438. row = self.cursor.fetchone()
  439. while row is not None:
  440. row = ", ".join([str(c) for c in row])
  441. if os.path.exists('scripts/imdb-bulk-update.pl'):
  442. os.system('perl scripts/imdb-bulk-update.pl -A -Host %s -User %s -Password %s -Title "%s" %s' % (self.mysqlHost, self.mysqlUsername, self.mysqlPassword, row, self.defaultswitch))
  443.  
  444. else:
  445. os.system("perl 'Mythkiwi Bulk Meta Grabber/scripts/imdb-bulk-update.pl' -A -Host %s -User %s -Password %s -Title '%s' %s" % (self.mysqlHost, self.mysqlUsername, self.mysqlPassword, row, self.defaultswitch))
  446. row = self.cursor.fetchone()
  447.  
  448. #Get data for TV shows
  449. if (self.includeTVshows == 1):
  450.  
  451. if (self.getMissing == 1):
  452. self.cursor.execute("SELECT filename FROM videometadata WHERE inetref='00000000' AND (filename LIKE '% s__e__%' or filename Like '%.s__e__%' or filename Like '%/s__e__%')")
  453. elif (self.getAll == 1):
  454. self.cursor.execute("SELECT filename FROM videometadata WHERE filename LIKE '% s__e__%' or filename Like '%.s__e__%' or filename Like '%/s__e__%'")
  455. row = self.cursor.fetchone()
  456. while row is not None:
  457. row = ", ".join([str(c) for c in row])
  458.  
  459.  
  460. (dirName, fileName) = os.path.split(row)
  461. (fileBaseName, fileExtension) = os.path.splitext(fileName)
  462. #make poster first using MPlayer
  463. os.system("mplayer -ss 00:6:20 -nosound -frames 1 -vf scale=400:-2 -vo jpeg:quality=95 '%s'"% (row))
  464.  
  465. os.system("mv -f 00000001.jpg '%s/%s.jpg'"% (VideoArtworkDir, fileBaseName))
  466. if os.path.exists('MythKiwi Bulk Meta Grabber/scripts/ragetvgrab-0.7.pl'):
  467. os.system("perl 'MythKiwi Bulk Meta Grabber/scripts/ragetvgrab-0.7.pl' -import -mythvideo -F '%s' -coverfile '%s/%s.jpg'" % (row, VideoArtworkDir, fileBaseName))
  468.  
  469. else:
  470. os.system("perl scripts/ragetvgrab-0.7.pl -import -mythvideo -F '%s' -coverfile '%s/%s.jpg'" % (row, VideoArtworkDir, fileBaseName))
  471.  
  472. row = self.cursor.fetchone()
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480. print "\n\n============================================================================="
  481. print "All tasks completed"
  482. print "\nFor updates or to check out our other MythTV software head to mythkiwi.com"
  483. print "Any questions or feedback post on the forum\n\n"
  484.  
  485.  
  486.  
  487.  
  488.  
  489. if __name__ == "__main__":
  490. hwg = metaupdate()
  491. gtk.main()
  492.  
Advertisement
Add Comment
Please, Sign In to add comment