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.

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