PageRenderTime 44ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/createnfos.py

http://fill-mythvideo-metadata.googlecode.com/
Python | 212 lines | 203 code | 8 blank | 1 comment | 0 complexity | 6016128c62239c29d8240f94a7a1c266 MD5 | raw file
  1. #!/usr/bin/env python2.5
  2. __author__ = "Fabian Rothfuchs"
  3. __license__ = "GNU General Public License v2"
  4. __version__ = "$Revision: 1.03 $"
  5. import MySQLdb
  6. import os.path
  7. from optparse import OptionParser
  8. from shutil import copyfile
  9. class NFOgen:
  10. def __init__(self):
  11. """constructor"""
  12. self.writeCount = 0 #counts written files
  13. self.skipCount = 0 #counts skipped files (always existing)
  14. self.fileCount = 0 #number of files in the database
  15. self.backupCount = 0 #number of backupped files
  16. self.dummyCount = 0 #number pseudo-written of dummy files
  17. self.readOpts()
  18. self.getMySQLConfig()
  19. self.initSQL()
  20. def __del__(self):
  21. """destructor"""
  22. try:
  23. self.options
  24. except AttributeError: #-h option diesnt set self.options and exits immediately
  25. return
  26. print "Found %s files in database" %(self.fileCount)
  27. print "Wrote %s files" %(self.writeCount)
  28. print "Wrote %s dummy files" %(self.dummyCount)
  29. print "Skipped %s files" %(self.skipCount)
  30. self.closeSQL()
  31. def getMySQLConfig(self):
  32. """gather mysql config by using mythtv config file
  33. called by: __init__()
  34. return: None
  35. """
  36. mysql_file = '/etc/mythtv/mysql.txt'
  37. config = {}
  38. try:
  39. f = open(mysql_file,'r')
  40. file = f.read()
  41. f.close()
  42. except IOError, e:
  43. print "Could not open %s ." %(mysql_file,)
  44. for line in file.split("\n"):
  45. if line.startswith("#") or len(line) < 1 or not "=" in line:
  46. continue
  47. key,val = line.split("=")
  48. config[key] = val
  49. self.sql_hostname = config.get('DBHostName','')
  50. self.sql_username = config.get('DBUserName','')
  51. self.sql_password = config.get('DBPassword','')
  52. self.sql_database = config.get('DBName','')
  53. def readOpts(self):
  54. """read options given and store them
  55. called by: __init__()
  56. return: None
  57. """
  58. parser = OptionParser()
  59. parser.add_option("-d", "--dummy", dest="dummy", default=False, action="store_true",
  60. help="do not create, just print files and content")
  61. parser.add_option("-f", "--force", dest="force", default=False, action="store_true",
  62. help="force overwriting of existing files")
  63. parser.add_option("-n", "--no-backup", dest="no_backup", default=False, action="store_true",
  64. help="do NOT create .backup files")
  65. parser.add_option("-q", "--quiet", dest="quiet", default=False, action="store_true",
  66. help="don't print status messages")
  67. parser.add_option("-v", "--verbose", dest="verbose", default=False, action="store_true",
  68. help="print verbose messages")
  69. parser.add_option("-p", "--path", dest="path", default=False, metavar="PATH",
  70. help="specify path where to recover NFO files")
  71. self.options, self.args = parser.parse_args()
  72. def initSQL(self):
  73. """initialize MySQL connection
  74. called by: __init__()
  75. """
  76. self.my_conn = MySQLdb.connect(self.sql_hostname, self.sql_username, self.sql_password, self.sql_database)
  77. self.my_curs = self.my_conn.cursor()
  78. query = "SELECT title, inetref, filename FROM videometadata"
  79. self.my_curs.execute(query)
  80. self.files = self.my_curs.fetchall()
  81. def closeSQL(self):
  82. """close MySQL connection
  83. called by: __del__()
  84. return: None
  85. """
  86. self.my_curs.close()
  87. self.my_conn.close()
  88. def notify(self, content):
  89. """print `content` if not quiet mode
  90. return: None
  91. content: <str>
  92. """
  93. if self.options.quiet:
  94. return
  95. print content
  96. def writeNFO(self, filepath, content):
  97. """write NFO file to path given in `filepath`
  98. called by: self.parseDbEntries()
  99. return: None
  100. filepath: <str>, i.e. /home/me/a.nfo
  101. content: <str>, i.e. blah
  102. """
  103. msg = filepath
  104. if self.options.verbose:
  105. msg = "%s: \n%s" %(filepath, content)
  106. if self.options.dummy:
  107. self.dummyCount += 1
  108. self.notify("Dummy mode: Would write %s" %(msg,))
  109. return
  110. if self.options.path:
  111. index = filepath.rfind("/")
  112. folder = filepath[:index]
  113. filename = filepath[index:]
  114. if not self.options.path.startswith("/"): #relative paths require `pwd`
  115. self.options.path = "%s/%s" %(os.getcwd(), self.options.path)
  116. folder = self.options.path + folder
  117. if not os.path.exists(folder):
  118. os.makedirs(folder)
  119. filepath = folder + filename
  120. if os.path.exists(filepath): #backup procedure
  121. if not self.options.force:
  122. self.writeCount -= 1
  123. print "File exists: %s - please give -f option to overwrite" %filepath
  124. return
  125. else:
  126. if not self.options.no_backup:
  127. self.notify("Backupping file: %s" %filepath)
  128. copyfile(filepath, folder + filename + ".backup")
  129. self.writeCount += 1
  130. self.notify("Writing NFO file: %s" %filepath)
  131. f = open(filepath, 'w')
  132. f.write(content+"\n")
  133. f.close()
  134. self.notify("Wrote %s" %(msg,))
  135. def parseDbEntries(self):
  136. """parse DB entries received in self.initSQL().
  137. called by: main method
  138. return: None
  139. """
  140. c = 0
  141. for entry in self.files:
  142. title, inetref, filepath = entry
  143. filepath = "%s.nfo" %filepath[:filepath.rfind(".")]
  144. if inetref == "00000000" or inetref == "":
  145. continue
  146. c+=1
  147. if inetref.startswith("http://www.thetvdb.com"):
  148. content = "<thetvdb episodeid='%s'/>" %inetref.split("/")[-2]
  149. else:
  150. content = "<imdb id='tt%s'/>" %inetref
  151. self.writeNFO(filepath, content)
  152. if __name__ == "__main__":
  153. n = NFOgen()
  154. n.parseDbEntries()