Scripting way to upload videos to peertube and youtube
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
7.2 KiB

  1. #!/usr/bin/python
  2. # coding: utf-8
  3. from configparser import RawConfigParser, NoOptionError, NoSectionError
  4. from os.path import dirname, splitext, basename, isfile, getmtime
  5. import re
  6. import unidecode
  7. import logging
  8. import datetime
  9. logger = logging.getLogger('Prismedia')
  10. VALID_PRIVACY_STATUSES = ('public', 'private', 'unlisted')
  11. VALID_CATEGORIES = (
  12. "music", "films", "vehicles",
  13. "sports", "travels", "gaming", "people",
  14. "comedy", "entertainment", "news",
  15. "how to", "education", "activism", "science & technology",
  16. "science", "technology", "animals"
  17. )
  18. VALID_LANGUAGES = ('arabic', 'english', 'french',
  19. 'german', 'hindi', 'italian',
  20. 'japanese', 'korean', 'mandarin',
  21. 'portuguese', 'punjabi', 'russian', 'spanish')
  22. VALID_PROGRESS = ('percentage', 'bigfile', 'accurate')
  23. def validateVideo(path):
  24. supported_types = ['video/mp4']
  25. detected_type = magic.from_file(path, mime=True)
  26. if detected_type not in supported_types:
  27. print("File", path, "detected type is '" + detected_type + "' which is not one of", supported_types)
  28. force_file = ['y', 'yes']
  29. is_forcing = input("Are you sure you selected the correct file? (y/N)")
  30. if is_forcing.lower() not in force_file:
  31. return False
  32. return path
  33. def validateCategory(category):
  34. if category.lower() in VALID_CATEGORIES:
  35. return True
  36. else:
  37. return False
  38. def validatePrivacy(privacy):
  39. if privacy.lower() in VALID_PRIVACY_STATUSES:
  40. return True
  41. else:
  42. return False
  43. # TODO: remove me?
  44. # def validatePlatform(platform):
  45. # for plfrm in platform.split(','):
  46. # if plfrm.lower().replace(" ", "") not in VALID_PLATFORM:
  47. # return False
  48. #
  49. # return True
  50. def validateLanguage(language):
  51. if language.lower() in VALID_LANGUAGES:
  52. return True
  53. else:
  54. return False
  55. def validatePublishDate(publishDate):
  56. # Check date format and if date is future
  57. try:
  58. now = datetime.datetime.now()
  59. publishAt = datetime.datetime.strptime(publishDate, '%Y-%m-%dT%H:%M:%S')
  60. if now >= publishAt:
  61. return False
  62. except ValueError:
  63. return False
  64. return True
  65. def validateOriginalDate(originalDate):
  66. # Check date format and if date is past
  67. try:
  68. now = datetime.datetime.now()
  69. originalDate = datetime.datetime.strptime(originalDate, '%Y-%m-%dT%H:%M:%S')
  70. if now <= originalDate:
  71. return False
  72. except ValueError:
  73. return False
  74. return True
  75. def validateThumbnail(thumbnail):
  76. supported_types = ['image/jpg', 'image/jpeg']
  77. if os.path.exists(thumbnail) and \
  78. magic.from_file(thumbnail, mime=True) in supported_types:
  79. return thumbnail
  80. else:
  81. return False
  82. def validateLogLevel(loglevel):
  83. numeric_level = getattr(logging, loglevel, None)
  84. if not isinstance(numeric_level, int):
  85. return False
  86. return True
  87. def validateProgress(progress):
  88. for prgs in progress.split(','):
  89. if prgs.lower().replace(" ", "") not in VALID_PROGRESS:
  90. return False
  91. return True
  92. def ask_overwrite(question):
  93. while True:
  94. reply = str(input(question + ' (Yes/[No]): ') or "No").lower().strip()
  95. if reply[:1] == 'y':
  96. return True
  97. if reply[:1] == 'n':
  98. return False
  99. def remove_empty_kwargs(**kwargs):
  100. good_kwargs = {}
  101. if kwargs is not None:
  102. for key, value in kwargs.items():
  103. if value:
  104. good_kwargs[key] = value
  105. return good_kwargs
  106. def searchOriginalDate(options):
  107. fileModificationDate = str(getmtime(options.get('--file'))).split('.')
  108. return datetime.datetime.fromtimestamp(int(fileModificationDate[0])).isoformat()
  109. # return the nfo as a RawConfigParser object
  110. def loadNFO(filename):
  111. try:
  112. logger.info("Loading " + filename + " as NFO")
  113. nfo = RawConfigParser()
  114. nfo.read(filename, encoding='utf-8')
  115. return nfo
  116. except Exception as e:
  117. logger.critical("Problem loading NFO file " + filename + ": " + str(e))
  118. exit(1)
  119. return False
  120. def parseNFO(options):
  121. video_directory = dirname(options.get('--file'))
  122. directory_name = basename(video_directory)
  123. nfo_txt = False
  124. nfo_directory = False
  125. nfo_videoname = False
  126. nfo_file = False
  127. nfo_cli = False
  128. if isfile(video_directory + "/" + "nfo.txt"):
  129. nfo_txt = loadNFO(video_directory + "/" + "nfo.txt")
  130. elif isfile(video_directory + "/" + "NFO.txt"):
  131. nfo_txt = loadNFO(video_directory + "/" + "NFO.txt")
  132. if isfile(video_directory + "/" + directory_name + ".txt"):
  133. nfo_directory = loadNFO(video_directory + "/" + directory_name + ".txt")
  134. if options.get('--name'):
  135. if isfile(video_directory + "/" + options.get('--name')):
  136. nfo_videoname = loadNFO(video_directory + "/" + options.get('--name') + ".txt")
  137. video_file = splitext(basename(options.get('--file')))[0]
  138. if isfile(video_directory + "/" + video_file + ".txt"):
  139. nfo_file = loadNFO(video_directory + "/" + video_file + ".txt")
  140. if options.get('--nfo'):
  141. if isfile(options.get('--nfo')):
  142. nfo_cli = loadNFO(options.get('--nfo'))
  143. else:
  144. logger.critical("Given NFO file does not exist, please check your path.")
  145. exit(1)
  146. # If there is no NFO and strict option is enabled, then stop there
  147. if options.get('--withNFO'):
  148. if not isinstance(nfo_cli, RawConfigParser) and \
  149. not isinstance(nfo_file, RawConfigParser) and \
  150. not isinstance(nfo_videoname, RawConfigParser) and \
  151. not isinstance(nfo_directory, RawConfigParser) and \
  152. not isinstance(nfo_txt, RawConfigParser):
  153. logger.critical("You have required the strict presence of NFO but none is found, please use a NFO.")
  154. exit(1)
  155. # We need to load NFO in this exact order to keep the priorities
  156. # options in cli > nfo_cli > nfo_file > nfo_videoname > nfo_directory > nfo_txt
  157. for nfo in [nfo_cli, nfo_file, nfo_videoname, nfo_directory, nfo_txt]:
  158. if nfo:
  159. # We need to check all options and replace it with the nfo value if not defined (None or False)
  160. for key, value in options.items():
  161. key = key.replace("--", "")
  162. try:
  163. # get string options
  164. if value is None and nfo.get('video', key):
  165. options['--' + key] = nfo.get('video', key)
  166. # get boolean options
  167. elif value is False and nfo.getboolean('video', key):
  168. options['--' + key] = nfo.getboolean('video', key)
  169. except NoOptionError:
  170. continue
  171. except NoSectionError:
  172. logger.critical(nfo + " misses section [video], please check syntax of your NFO.")
  173. exit(1)
  174. return options
  175. def cleanString(toclean):
  176. toclean = unidecode.unidecode(toclean)
  177. cleaned = re.sub('[^A-Za-z0-9]+', '', toclean)
  178. return cleaned
  179. def getOption(options, optionName, defaultValue = None):
  180. value = options.get(optionName)
  181. options.pop(optionName)
  182. if value is None:
  183. return defaultValue
  184. return value