00001
00002
00003 """
00004 This Python script is intended to find metadata for a video file or video
00005 directory with multiple video files. Perform movie data lookups using the
00006 imdbpy.py script.
00007
00008 Written by Pekka Jääskeläinen (gmail: pekka.jaaskelainen) 2006-2007.
00009
00010 The metadata is searched with following steps:
00011
00012 - search for a file which contains the IMDb ID:
00013 - look for imdb.nfo
00014 - look for imdb.url
00015 - look for [filenamebody].nfo
00016 - look for [filenamebody].imdb
00017 - if not found, look for any file in the directory with suffix .nfo
00018
00019 - look for the title derived from the file name / directory. Should detect the
00020 following cases:
00021 - if it's a DVD directory (a directory containing a sub directory VIDEO_TS):
00022 - use the directory name as the search string
00023 - otherwise remove suffix and possible known tags, etc. and use the
00024 resulting string as a search string (a directory with multiple videos)
00025
00026 Stores the fetched metadata (output from imdbpy.py -D imdbid) to
00027 [filenamebody].metadata.
00028
00029 In case it's a video directory (a directory with 2 or more video files for the
00030 same title, or a DVD directory) the file name is video.metadata.
00031
00032 A crontab entry for the script to insert automatically data of new video files
00033 to MythDB every hour:
00034
00035 0 * * * * find_meta.py -r /videos
00036
00037 In which /videos is the root of your MythVideo files.
00038 """
00039
00040 import sys
00041 import optparse
00042 import re
00043 import os
00044 import glob
00045 import fileinput
00046 import imdbpy
00047 import shlex
00048 import socket
00049 import urllib
00050 import fetch_poster
00051 import distutils.file_util
00052
00053 try:
00054
00055 from MythTV import MythDB, MythVideo
00056 mythdb = MythDB()
00057 mythvideo = MythVideo()
00058 except:
00059 print "MythTV module cannot be initialized, MythDB importing disabled."
00060 mythdb = None
00061 mythvideo = None
00062
00063 from stat import *
00064
00065 verbose=False
00066
00067 try:
00068
00069 import readline
00070 except:
00071 pass
00072
00073 interactive = False
00074 recursive = False
00075 dbimport = False
00076 poster_search = True
00077
00078
00079 aka_language = None
00080
00081
00082 import_from_files = False
00083
00084
00085 overwrite = False
00086
00087
00088 metafiles = False
00089
00090 videoExtensions = ["avi", "mpg", "wmv", "mkv"]
00091
00092
00093
00094
00095 dirMetadataFileName = "video.metadata"
00096
00097
00098
00099 skipDirs = ["/Sample", "/Sub", "/VIDEO_TS"]
00100
00101
00102
00103 poster_dir = "./"
00104
00105 def print_verbose(string):
00106 global verbose
00107 if verbose:
00108 print string
00109 return
00110
00111 db = None
00112
00113 def find_imdb_id_from_text_file(textFile):
00114
00115 if os.access(textFile, os.R_OK):
00116 print_verbose("Scanning %s for IMDb ID" % textFile)
00117
00118 regexps = []
00119
00120
00121
00122 regexps.append(re.compile(".*imdb.com/title/tt(?P<imdb_id>\d+)/?.*"))
00123
00124 for line in fileinput.input(textFile):
00125
00126 for regexp in regexps:
00127 m = regexp.match(line)
00128 if m is not None:
00129 imdb_id = m.group("imdb_id")
00130 print_verbose("Found IMDb ID '%s'" % (imdb_id))
00131 fileinput.close()
00132 return imdb_id
00133 fileinput.close()
00134 else:
00135 return None
00136
00137 def strip_extension(path):
00138 suffix_pos = path.rfind(".")
00139 if suffix_pos != -1:
00140 return path[0: suffix_pos]
00141 else:
00142 return path
00143
00144 def cleanup_title(title):
00145 title = title.replace("_", " ").replace(".", " ").replace("-", " ")
00146 cut_point_strings = [
00147 "hdtv", "xvid", "dvd", "proper", "720p", "limited",
00148 "dsr", "pdtv", "cd", "disk", "disc"]
00149 lowest_cutpoint = len(title)
00150 for string in cut_point_strings:
00151 pos = title.lower().rfind(string)
00152 if pos > 0 and pos < lowest_cutpoint:
00153 lowest_cutpoint = pos
00154
00155 title = title[0:lowest_cutpoint]
00156 return title.strip()
00157
00158 def parse_meta(variable, oldvalue, emptyvalue="", meta=""):
00159 """
00160 Parses a single metadata from a metadata string (returned by the imdbpy.py, etc.).
00161
00162 variable is the metadata to find
00163 oldvalue if we are replacing an old value for the metadata
00164 emptyvalue what is considered an empty value for the metadata (e.g. "None", "")
00165 meta the metadata string
00166 """
00167 global overwrite
00168 if not overwrite and oldvalue is not None and oldvalue != emptyvalue:
00169 return oldvalue
00170
00171 return imdbpy.parse_meta(meta, variable)
00172
00173 def detect_disc_number(allfiles, file):
00174 """
00175 Detect the number of disc of the video file considering all the discs
00176 that are part of the title.
00177
00178 Returns None if cannot detect the disc number.
00179 """
00180
00181 if len(allfiles) < 2 or file not in allfiles:
00182 return None
00183
00184
00185
00186
00187 size = len(allfiles[0])
00188 differing = False
00189 for f in allfiles:
00190 if len(f) != size:
00191 return None
00192 if f != file:
00193 differing = True
00194
00195 if not differing:
00196 return None
00197
00198
00199
00200
00201
00202
00203
00204
00205 startpos = 0
00206 for startpos in range(len(file)):
00207 c = allfiles[0][startpos]
00208 allequal = True
00209 for f in allfiles:
00210 if f[startpos] != c:
00211 allequal = False
00212 break
00213 if not allequal:
00214
00215 break
00216
00217 endpos = len(file) - 1
00218 for endpos in reversed(range(len(file))):
00219 c = allfiles[0][endpos]
00220 allequal = True
00221 for f in allfiles:
00222 if f[endpos] != c:
00223 allequal = False
00224 break
00225 if not allequal:
00226
00227 break
00228 endpos = endpos + 1
00229
00230
00231 disc_str = file[startpos:endpos].lower()
00232
00233 disc = -1
00234 try:
00235 disc = int(disc_str)
00236 except:
00237
00238 alpha = ["a", "b", "c", "d", "e"]
00239 for i in range(len(alpha)):
00240 if alpha[i] == disc_str:
00241 return i + 1
00242
00243 if disc == -1:
00244 return None
00245 else:
00246 return disc
00247
00248 def save_metadata_to_mythdb(videopath, metadata):
00249 """
00250 Updates the given metadata for the given video path.
00251
00252 Detects if the given title is a dvd-rip dir with multiple videos and
00253 adds metadata for all the videos separately and chains the videos
00254 together.
00255 """
00256 files_str = parse_meta("Files", "", "", metadata)
00257 if files_str is not None:
00258 files = files_str.split(",")
00259
00260 if len(files) > 1:
00261
00262
00263
00264 child = -1
00265
00266
00267 for file in reversed(files):
00268 child = save_video_metadata_to_mythdb(
00269 videopath + "/" + file, metadata,
00270 child, disc = detect_disc_number(files, file))
00271 return
00272
00273 return save_video_metadata_to_mythdb(videopath, metadata)
00274
00275 def save_video_metadata_to_mythdb(videopath, metadata, child=-1, disc=None):
00276 """
00277 Updates the given metadata for the given video file.
00278
00279 child can be set to the id of the child video (video to be played after this one).
00280 disc can be set to the disc number in case of multifile title (the disc number
00281 is appended to the title string to enable differentiating the titles in
00282 file browse mode.
00283
00284 Returns the id of the inserted metadata.
00285 """
00286 global overwrite, db, poster_dir, poster_search, aka_language
00287
00288
00289 if videopath.endswith('/'):
00290 videopath = videopath[0:-1]
00291 videopath = os.path.abspath(videopath)
00292
00293 print_verbose("Inserting metadata to MythDB for %s." % videopath)
00294
00295 (intid, title, category, director, plot, rating, inetref, year,
00296 userrating, length, filename, coverfile, childid, playcommand) = \
00297 (None, None, 0, None, None, None, None,
00298 0.0, None, 0, None, None, child, "")
00299
00300 intid = mythvideo.getMetadataId(videopath)
00301 has_metadata = mythvideo.hasMetadata(videopath)
00302 if intid is not None :
00303 if not overwrite and has_metadata:
00304 print_verbose("Metadata already exist in MythDB, not overwriting it.")
00305 return None
00306 else:
00307 print_verbose("Entry exists in MythDB with default metadata. Updating.")
00308 mythvideo.setMetadata({'filename': videopath}, id=intid)
00309 else:
00310 print_verbose("No metadata in MythDB, creating a new one.")
00311
00312
00313 intid = mythvideo.setMetadata({'filename': videopath})
00314
00315 def parse_metadata(variable, oldvalue, emptyvalue="", meta=metadata):
00316 return parse_meta(variable, oldvalue, emptyvalue, meta)
00317
00318 if title is None:
00319 title = parse_metadata('Title', title)
00320
00321 if title is None:
00322 title = cleanup_title(os.path.basename(videopath))
00323
00324 inetref = parse_metadata('IMDb', inetref, '00000000')
00325
00326 if inetref == None:
00327 inetref = '00000000'
00328
00329 if poster_search:
00330 print_verbose("Fetching a poster image...")
00331 coverfile = find_poster_image(title, inetref)
00332 if coverfile is not None:
00333 print_verbose("Found a poster.")
00334 else:
00335 print_verbose("Poster not found.")
00336
00337 akas = parse_metadata('AKA', None)
00338 if aka_language is not None and akas is not None:
00339 for aka in akas.split(', '):
00340
00341
00342 akaRegexp = ".+::\[%s\].*" % aka_language
00343 m = re.match(akaRegexp, aka)
00344 if m is not None:
00345 aka_title = aka.split("::")[0]
00346 if aka_title != title:
00347 title = aka_title + " (" + title + ")"
00348 print_verbose("Found AKA: %s" % title)
00349 break
00350
00351 if disc is not None:
00352 title += " [disc" + unicode(disc) + "]"
00353
00354 year = parse_metadata('Year', year, 0)
00355
00356 if year is None:
00357 year = 0
00358
00359 director = parse_metadata('Director', director, 'Unknown')
00360
00361 if director == None:
00362 director = "Unknown"
00363
00364 plot = parse_metadata('Plot', plot, "None")
00365 if plot == None:
00366 plot = ""
00367
00368 userrating = parse_metadata('UserRating', userrating, 0.0)
00369
00370 try:
00371 float(userrating)
00372 except:
00373 userrating = 0.0
00374
00375 rating = parse_metadata('MovieRating', rating, "Unknown")
00376
00377 if rating is None:
00378 rating = "Unknown"
00379
00380 length = parse_metadata('Runtime', length, 0)
00381 try:
00382 length = length.split(",")[0]
00383 length = int(length)
00384 except:
00385 print_verbose("Chose runtime: %s" % length)
00386 try:
00387 length = length.split(":")[1]
00388 length = int(length)
00389 except:
00390 try:
00391 length = length.split("(")[0]
00392 length = int(length)
00393 except:
00394 length = 0
00395
00396 filename = videopath
00397
00398 genrestring = parse_metadata('Genres', "", "")
00399 genres = []
00400 if genrestring is not None and len(genrestring) > 0:
00401 genres = genrestring.split(",")
00402
00403 if len(genres) < 1:
00404 print_verbose("No genres.")
00405 category = mythvideo.getGenreId("Unknown")
00406 else:
00407
00408 category = mythvideo.getGenreId(genres[0])
00409
00410 if coverfile == None:
00411 coverfile = "No cover"
00412
00413 mythvideo.setMetadata({'showlevel': 1, 'browse': 1, 'childid': childid,
00414 'playcommand': playcommand, 'title': title.encode('utf8'),
00415 'director': director.encode('utf8'), 'plot': plot.encode('utf8'),
00416 'rating': rating, 'inetref': inetref, 'category': category,
00417 'year': year, 'userrating': userrating, 'length': length,
00418 'filename': filename, 'coverfile': coverfile}, intid)
00419 return intid
00420
00421 def find_poster_image(title, imdb_id):
00422 """
00423 Tries to find a poster image for the given IMDb id.
00424
00425 First looks if the image already exist, if not, tries to fetch it using
00426 the fetch_poster.py. Returns None in case a poster image couldn't be found,
00427 otherwise returns the base name of the poster image file.
00428 """
00429 global poster_dir,overwrite
00430 image_extensions = ["png", "jpg", "bmp"]
00431
00432 poster_files = []
00433 for ext in image_extensions:
00434 poster_files += glob.glob("%s/%s.%s" % (poster_dir, imdb_id, ext))
00435
00436 if len(poster_files) == 0 or overwrite:
00437
00438 posters = fetch_poster.find_best_posters(\
00439 title, count=1, accept_horizontal=True, imdb_id=imdb_id)
00440
00441 if len(posters) == 0:
00442 return None
00443
00444 poster = posters[0]
00445
00446 filename = os.path.basename(poster.file_name)
00447 (name, extension) = os.path.splitext(filename)
00448 local_filename = poster_dir + "/" + imdb_id + extension
00449 if os.path.exists(local_filename):
00450 if overwrite:
00451 os.remove(local_filename)
00452 else:
00453 return local_filename
00454 distutils.file_util.move_file(poster.file_name, local_filename)
00455
00456 os.chmod(local_filename, S_IREAD | S_IRUSR | S_IRGRP | S_IROTH)
00457 return local_filename
00458 else:
00459 print_verbose("Found existing cover image.")
00460 return poster_files[0]
00461 return None
00462
00463 def save_metadata_to_file(fileName, metadata):
00464 global overwrite
00465
00466 if os.path.exists(fileName) and not overwrite:
00467 print_verbose("Metadata already exists, not overwriting.")
00468 return
00469
00470 if metadata is not None:
00471 print_verbose("Writing metadata to '%s'" % fileName)
00472 f = open(fileName, 'w')
00473 f.write(metadata.encode("utf8"))
00474 f.close()
00475
00476 def save_metadata(videopath, metadata_filename, metadata):
00477 """
00478 Saves metadata for the given video path to the given metadata_filename.
00479
00480 Metadata should be a single string.
00481 """
00482 global dbimport, metafiles
00483
00484 print_verbose("Metadata:")
00485 print_verbose(metadata)
00486
00487 if metafiles:
00488 save_metadata_to_file(metadata_filename, metadata)
00489 if dbimport:
00490 save_metadata_to_mythdb(videopath, metadata)
00491
00492 def find_metadata_for_video_path(pathName):
00493 global interactive
00494
00495 fileName = os.path.basename(pathName)
00496 dirName = os.path.dirname(pathName)
00497 print_verbose("Scanning file %s..." % fileName)
00498
00499 if os.path.isdir(pathName):
00500 title = os.path.basename(dirName)
00501 nfos = [dirName + "/imdb.nfo",
00502 dirName + "/imdb.url"]
00503 else:
00504 file_body = strip_extension(fileName)
00505 title = file_body
00506
00507 nfos = [dirName + "/imdb.nfo",
00508 dirName + "/imdb.url",
00509 dirName + "/" + file_body + ".nfo",
00510 dirName + "/" + file_body + ".imdb"]
00511
00512
00513 for nfo in glob.glob(dirName + "/*.nfo"):
00514 if nfo not in nfos:
00515 nfos.append(nfo)
00516
00517 imdb_id = None
00518 source_nfo = None
00519 for nfo in nfos:
00520 imdb_id = find_imdb_id_from_text_file(nfo)
00521 if imdb_id is not None:
00522 source_nfo = nfo
00523 break
00524
00525 title = unicode(cleanup_title(title), "utf8", "ignore")
00526 if imdb_id is None:
00527
00528
00529 print_verbose("Title search '%s'" % title)
00530
00531 candidates = imdbpy.title_search(title)
00532 if candidates is None or len(candidates) == 0:
00533
00534 pass
00535 if candidates is not None and len(candidates) > 0:
00536 index = 0
00537 if (len(candidates) == 2) and (candidates[0][0] == candidates[1][0]):
00538 imdb_id = candidates[0][0]
00539 elif len(candidates) > 1:
00540 import pdb; pdb.set_trace()
00541 print "Got multiple candidates for title search '%s'. " % title
00542 if not interactive:
00543 print "Use the '-a' or '-i' switch to choose the correct one."
00544 for candidate in candidates:
00545 print "%s) %s (%d)" % (candidate[0], candidate[1].encode("utf8"), candidate[2])
00546
00547 if interactive:
00548 answer = raw_input("?)")
00549 if answer is None or len(answer) == 0:
00550 return None
00551
00552 print_verbose("Chose %s" % answer)
00553 imdb_id = answer
00554 else:
00555 return None
00556 else:
00557 imdb_id = candidates[0][0]
00558 else:
00559 print "Couldn't find IMDb ID for '%s'" % pathName
00560 return None
00561
00562 print_verbose("Querying IMDb for meta data for ID %s..." % imdb_id)
00563 try:
00564 meta = imdbpy.fetch_metadata(imdb_id)
00565 if meta is not None:
00566 if meta.series_episode:
00567 title, season, episode = imdbpy.detect_series_title(title)
00568 if meta.season is None:
00569 meta.season = season
00570 if meta.episode is None:
00571 meta.episode = episode
00572 metadata = meta.toMetadataString()
00573 metadata += "IMDb:%s" % imdb_id + "\n"
00574 return metadata
00575 except:
00576 print_verbose("Problem occured fetching metadata for ID %s..." % imdb_id)
00577 return None
00578
00579 def video_file_list_metadata(videoPaths):
00580 videoPaths = [os.path.basename(v) for v in videoPaths]
00581 videoPaths.sort()
00582
00583 return "Files:%s" % (",".join(videoPaths)) + "\n"
00584
00585 def load_metadata_file(metadata_filename):
00586 """
00587 Loads a metadata file if found, returns None otherwise.
00588 """
00589 metadata = None
00590 try:
00591 f = open(metadata_filename)
00592 metadata = unicode("", "utf8").join(f.readlines())
00593 f.close()
00594 except:
00595 pass
00596 return metadata
00597
00598 def detect_dvd_backup(dirName):
00599 """
00600 If the given directory is detected as a directory with a dvd backup, meta data is
00601 searched for the directory title name (in addition to the directory-wide imdb files).
00602 """
00603 global import_from_files
00604 videoTs = dirName + "/VIDEO_TS"
00605 if not (os.path.exists(videoTs) and os.path.isdir(videoTs)):
00606 return False
00607
00608 print_verbose('A DVD backup directory with DVD directory structure detected.')
00609
00610 metadata_target = dirName + "/" + dirMetadataFileName
00611
00612 metadata = None
00613 if import_from_files:
00614 metadata = load_metadata_file(metadata_target)
00615
00616 if metadata is None:
00617 if should_be_skipped(dirName, metadata_target):
00618 return True
00619 metadata = find_metadata_for_video_path(dirName + "/VIDEO_TS")
00620
00621 if metadata is not None:
00622 save_metadata(dirName, metadata_target, metadata)
00623 return True
00624
00625 def detect_compressed_dvd_backup_dir(dirName):
00626 """
00627 If the given directory is detected as a directory with one or more files of
00628 a single title, fetches the meta data and returns true.
00629 """
00630 global videoExtensions, import_from_files
00631 maxFilesPerTitle = 3
00632
00633 foundVideos = None
00634
00635
00636
00637 for ext in videoExtensions:
00638 videos = glob.glob(dirName + "/*." + ext)
00639
00640 if 1 < len(videos) <= maxFilesPerTitle:
00641 if foundVideos is not None:
00642
00643 return False
00644
00645
00646 filename_length = len(videos[0])
00647 for video in videos:
00648 title, season, episode = \
00649 imdbpy.detect_series_title(cleanup_title(video))
00650 if title is not None and season is not None and episode is not None:
00651 print_verbose("'%s' looks like a TV-series episode." % video)
00652 print_verbose("title: %s season: %s episode: %s" % \
00653 (title, season, episode))
00654 return False
00655
00656
00657
00658 for video in videos:
00659 disc = detect_disc_number(videos, video)
00660 if disc is None:
00661 print_verbose("Did not detect disc number for %s." % video)
00662 return False
00663 else:
00664 print_verbose("Found disc %d." % disc)
00665
00666 foundVideos = videos
00667 elif len(videos) > maxFilesPerTitle:
00668 return False
00669
00670 metadata_target = dirName + "/" + dirMetadataFileName
00671 if foundVideos is not None:
00672 print_verbose('DVD rip directory detected.')
00673
00674
00675 first_file = foundVideos[0]
00676 if should_be_skipped(first_file, metadata_target):
00677 print_verbose("Skipping '%s'." % dirName)
00678 return True
00679
00680
00681
00682
00683 metadata = None
00684 if import_from_files:
00685 metadata = load_metadata_file(metadata_target)
00686
00687 if metadata is None:
00688 metadata = find_metadata_for_video_path(foundVideos[0])
00689
00690 if metadata is not None:
00691
00692 metadata += video_file_list_metadata(foundVideos)
00693 save_metadata(dirName, metadata_target, metadata)
00694 return True
00695
00696 return False
00697
00698 def scan_file(pathName, imdb_id = None):
00699 global import_from_files
00700
00701 metadata_target = strip_extension(pathName) + ".metadata";
00702
00703 if should_be_skipped(pathName, metadata_target):
00704 print_verbose("Skipping '%s'." % pathName)
00705 return
00706
00707 metadata = None
00708 if import_from_files:
00709 metadata = load_metadata_file(metadata_target)
00710
00711 if imdb_id is not None:
00712 meta = imdbpy.fetch_metadata(imdb_id)
00713 if meta.series_episode:
00714 fileName = os.path.basename(pathName)
00715 t, season, episode = imdbpy.detect_series_title(fileName)
00716 if meta.season is None:
00717 meta.season = season
00718 if meta.episode is None:
00719 meta.episode = episode
00720 metadata = meta.toMetadataString()
00721 metadata += "IMDb:%s" % imdb_id + "\n"
00722
00723 if metadata is None:
00724 metadata = find_metadata_for_video_path(pathName)
00725
00726 if metadata is not None:
00727 save_metadata(pathName, metadata_target, metadata)
00728
00729 def scan_directory(dirName, imdb_id = None):
00730 global videoExtensions
00731 dirName = dirName.replace("[", "?").replace("]", "?")
00732 print_verbose("Scanning directory %s..." % dirName)
00733
00734 if detect_compressed_dvd_backup_dir(dirName):
00735 return
00736
00737 if imdb_id is not None:
00738 metadata = imdbpy.metadata_search(imdb_id)
00739 if metadata is not None:
00740 metadata += "IMDb:%s" % imdb_id + "\n"
00741 save_metadata(dirName, dirName + "/video.metadata", metadata)
00742 return
00743
00744
00745 if detect_dvd_backup(dirName):
00746 return
00747
00748
00749 foundVideos = []
00750 for ext in videoExtensions:
00751 videos = glob.glob(dirName + "/*." + ext)
00752 if videos is not None and len(videos) > 0:
00753 foundVideos += videos
00754
00755 if len(foundVideos) == 0:
00756 return
00757
00758 print_verbose("Found %d videos." % len(foundVideos))
00759
00760 for video in foundVideos:
00761 scan_file(video)
00762
00763 def should_be_skipped(path, meta_file = None):
00764 """
00765 Returns true in case the given path should be skipped in the scan.
00766 """
00767 global skipDirs, overwrite, dbimport, metafiles
00768
00769 if path.endswith("/"):
00770 path = path[0:-1]
00771
00772
00773 for skip in skipDirs:
00774 if path.lower().endswith(skip.lower()):
00775 return True
00776
00777
00778
00779
00780 if not overwrite:
00781 need_mythdb_data = dbimport and not mythvideo.hasMetadata(path)
00782 need_metadata_file = metafiles
00783 if metafiles and meta_file is not None:
00784 need_metadata_file = not os.path.exists(meta_file)
00785 if not need_mythdb_data and not need_metadata_file:
00786 return True
00787
00788 return False
00789
00790 def scan(pathName, imdb_id = None):
00791 global recursive
00792 metadata = None
00793 metadata_target = None
00794 if os.path.isdir(pathName):
00795 if recursive:
00796 for root, dirs, files in os.walk(pathName):
00797 if should_be_skipped(root):
00798 print_verbose("Skipping '%s'." % root)
00799 continue
00800 scan_directory(root)
00801 else:
00802 if should_be_skipped(pathName):
00803 print_verbose("Skipping '%s'." % pathName)
00804 return
00805 scan_directory(pathName, imdb_id)
00806 elif os.path.isfile(pathName):
00807 if should_be_skipped(pathName):
00808 print_verbose("Skipping '%s'." % pathName)
00809 return
00810 scan_file(pathName, imdb_id)
00811 else:
00812 raise IOError("File not found")
00813 return
00814
00815 def main():
00816 global verbose, overwrite, interactive, recursive, dbimport
00817 global import_from_files, metafiles, poster_dir, poster_search
00818 global aka_language
00819
00820 usage = "usage: %prog [options] videopath1 [videopath2 videopath3...]"
00821
00822 p = optparse.OptionParser(usage=usage)
00823 p.add_option('--version', '-v', action="store_true", default=False,
00824 help="Display 1-line describing name, version, author etc.")
00825 p.add_option('--overwrite', '-o', action="store_true", default=False,
00826 help="Overwrite existing metadata.")
00827 p.add_option('--wordy', '-w', action="store_true", default=False,
00828 help="Verbose mode, be wordy while scanning for the info.")
00829 p.add_option('--interactive', '-i', action="store_true", default=False,
00830 help="Allow the script to ask questions from the user to find the meta data.")
00831 p.add_option('--recursive', '-r', action="store_true", default=False,
00832 help="Traverse sub directories of the given directory recursively.")
00833
00834 p.add_option('--no_dbimport', '-n', action="store_true", default=False,
00835 help="Do not import metadata directly to MythDB.")
00836 p.add_option('--fromfiles', '-f', action="store_true", default=False,
00837 help="Import data to MythDB from .metadata files if found. Requires -d.")
00838 p.add_option('--metafiles', '-m', action="store_true", default=False,
00839 help="Write metadata to *.metadata ascii files.")
00840
00841 p.add_option('--answer', '-a', action="store", type="string", dest="imdb_id",
00842 help="Fetch metadata with the given IMDb ID for the path (must be a single path).")
00843
00844 p.add_option('--prune', '-p', action="store_true", default=False,
00845 help="Prune metadata of deleted files from MythDB.")
00846 p.add_option('--skip_poster_search', '-s', action="store_true", default=False,
00847 help="Skip poster search.")
00848 p.add_option('--lang_code', '-l', action="store", type="string", dest="lang_code",
00849 default=None,
00850 help="Add the title name in the given country (two letter code, e.g., 'fi') "\
00851 "to the movie title.")
00852
00853 options, arguments = p.parse_args()
00854
00855 if options.version:
00856 print "MythVideo Metadata Finder (c) Pekka Jääskeläinen 2006-2007"
00857 sys.exit(0)
00858
00859 verbose = options.wordy
00860 overwrite = options.overwrite
00861 interactive = options.interactive
00862 recursive = options.recursive
00863 dbimport = not options.no_dbimport
00864 import_from_files = options.fromfiles and dbimport
00865 metafiles = options.metafiles
00866 prune = options.prune
00867 poster_search = not options.skip_poster_search
00868 aka_language = options.lang_code
00869
00870 if not (metafiles or dbimport):
00871 print "You must define writing to either MythDB import (-d) or metadata files (-m)."
00872 sys.exit(1)
00873
00874 if not prune and len(arguments) < 1:
00875 print "Please give the paths to be scanned as argument."
00876 sys.exit(1)
00877 paths = arguments
00878
00879 if options.imdb_id is not None:
00880 if recursive:
00881 print "Manual IMDb ID must be given in recursive mode."
00882 sys.exit(1)
00883 if len(arguments) > 1:
00884 print "Manual IMDb ID must be given for a single path only (%d given)." % len(arguments)
00885 sys.exit(1)
00886 print_verbose("IMDb ID %s given manually." % options.imdb_id)
00887
00888 if dbimport or prune:
00889 if not mythdb:
00890 print "You must have the MythTV module to make direct DB importing to work"
00891 sys.exit(1)
00892 poster_dir = mythdb.getSetting("VideoArtworkDir", socket.gethostname())
00893 if not mythdb:
00894 print "Could not get VideoArtworkDir setting for the current host."
00895 sys.exit(1)
00896
00897 if prune:
00898 mythvideo.pruneMetadata()
00899
00900 for path in paths:
00901
00902 if not os.path.exists(path):
00903 print "'%s' does not exist." % path
00904 sys.exit(1)
00905
00906 scan(path, options.imdb_id)
00907
00908 sys.exit(0)
00909
00910 if __name__ == '__main__':
00911 main()