Browse Source

WIP Fix typos and other recommendations from pycharm

plugins
Zykino 2 years ago
parent
commit
a2c76bcbe1
8 changed files with 92 additions and 90 deletions
  1. +5
    -4
      prismedia/cli.py
  2. +18
    -17
      prismedia/core.py
  3. +4
    -2
      prismedia/pluginInterfaces.py
  4. +5
    -4
      prismedia/plugins/interfaces/help.py
  5. +45
    -51
      prismedia/plugins/platforms/peertube.py
  6. +2
    -2
      prismedia/plugins/platforms/youtube.py
  7. +7
    -6
      prismedia/upload.py
  8. +6
    -4
      prismedia/video.py

+ 5
- 4
prismedia/cli.py View File

@ -4,13 +4,14 @@ import video as vid
from yapsy.PluginManager import PluginManagerSingleton from yapsy.PluginManager import PluginManagerSingleton
def helperFunctionnality(options):
def helperFunctionality(options):
pluginManager = PluginManagerSingleton.get() pluginManager = PluginManagerSingleton.get()
optionName = "--hearthbeat"
optionName = "--heartbeat"
if options.get(optionName): if options.get(optionName):
for plugin in pluginManager.getPluginsOfCategory(pi.PluginTypes.PLATFORM): for plugin in pluginManager.getPluginsOfCategory(pi.PluginTypes.PLATFORM):
plugin.plugin_object.hearthbeat()
plugin.plugin_object.heartbeat()
return False return False
else: else:
options.pop(optionName) options.pop(optionName)
@ -46,6 +47,6 @@ def parseOptions(options):
autoOriginalDate = utils.getOption(options, "--auto-original-date", False) autoOriginalDate = utils.getOption(options, "--auto-original-date", False)
if autoOriginalDate: if autoOriginalDate:
# TODO: Implement # TODO: Implement
raise NotImplementedError("--auto-original-date functionnality is not yet implemented.")
raise NotImplementedError("--auto-original-date functionality is not yet implemented.")
return video return video

+ 18
- 17
prismedia/core.py View File

@ -6,11 +6,11 @@
# TODO: change `youtube-at` and `peertube-at` that are not easely expendable as options in my opinion # TODO: change `youtube-at` and `peertube-at` that are not easely expendable as options in my opinion
# TODO: remove `--url-only` and `--batch` # TODO: remove `--url-only` and `--batch`
""" """
prismedia - tool to upload videos to different platforms (historicaly Peertube and Youtube)
prismedia - tool to upload videos to different platforms (historically Peertube and Youtube)
Usage: Usage:
prismedia [options] --file=<file> | [<interface> [<parameters>...]] prismedia [options] --file=<file> | [<interface> [<parameters>...]]
prismedia --hearthbeat
prismedia --heartbeat
prismedia -h | --help | -V | --version prismedia -h | --help | -V | --version
Options: Options:
@ -22,7 +22,7 @@ Options:
WARN: tags with punctuation (!, ', ", ?, ...) WARN: tags with punctuation (!, ', ", ?, ...)
are not supported by Mastodon to be published from Peertube are not supported by Mastodon to be published from Peertube
-c, --category=STRING Category for the videos, see below. (default: Films) -c, --category=STRING Category for the videos, see below. (default: Films)
--licence=STRING Creative Common licence tag (for exemple: CC-BY-SA) (default: proprietary)
--licence=STRING Creative Common licence tag (for example: CC-BY-SA) (default: proprietary)
-p, --privacy=STRING Choose between public, unlisted or private. (default: private) -p, --privacy=STRING Choose between public, unlisted or private. (default: private)
--disable-comments Disable comments (Peertube only as YT API does not support) (default: comments are enabled) --disable-comments Disable comments (Peertube only as YT API does not support) (default: comments are enabled)
--nsfw Set the video as No Safe For Work (Peertube only as YT API does not support) (default: video is safe) --nsfw Set the video as No Safe For Work (Peertube only as YT API does not support) (default: video is safe)
@ -52,7 +52,7 @@ Options:
Only relevant if --playlist is set. Only relevant if --playlist is set.
--progress=STRING Set the progress bar view, one of percentage, bigFile, accurate. [default: percentage] --progress=STRING Set the progress bar view, one of percentage, bigFile, accurate. [default: percentage]
--hearthbeat Use some credits to show some activity for you apikey so the platform know it is used and would not inactivate your keys.
--heartbeat Use some credits to show some activity for you apikey so the platform know it is used and would not inactivate your keys.
-h, --help Show this help. Note that calling `help` without the `--` calls a plugin showing a different help for the plugins. -h, --help Show this help. Note that calling `help` without the `--` calls a plugin showing a different help for the plugins.
-V, --version Show the version. -V, --version Show the version.
@ -118,6 +118,7 @@ import logging
VERSION = "prismedia v1.0.0-plugins-alpha" VERSION = "prismedia v1.0.0-plugins-alpha"
def loadPlugins(basePluginsPath): def loadPlugins(basePluginsPath):
pluginManager = PluginManagerSingleton.get() pluginManager = PluginManagerSingleton.get()
pluginManager.setPluginPlaces(basePluginsPath) pluginManager.setPluginPlaces(basePluginsPath)
@ -145,8 +146,8 @@ def main():
# TODO: add the arguments’s verification (copy/adapt the Schema table) # TODO: add the arguments’s verification (copy/adapt the Schema table)
options = docopt(__doc__, version=VERSION) options = docopt(__doc__, version=VERSION)
# Helper functionnalities help the user but do not upload anything
if not cli.helperFunctionnality(options):
# Helper functionalities help the user but do not upload anything
if not cli.helperFunctionality(options):
exit(os.EX_OK) exit(os.EX_OK)
video = cli.parseOptions(options) video = cli.parseOptions(options)
@ -160,15 +161,15 @@ def main():
logger.critical(utils.get_exception_string(e)) logger.critical(utils.get_exception_string(e))
exit(os.EX_CONFIG) exit(os.EX_CONFIG)
list = utils.getOption(options, "--platform", [])
if list:
platforms = pluginManager.getPluginsOf(categories=pi.PluginTypes.PLATFORM, name=[list.split(",")])
listPlatforms = utils.getOption(options, "--platform", [])
if listPlatforms:
platforms = pluginManager.getPluginsOf(categories=pi.PluginTypes.PLATFORM, name=[listPlatforms.split(",")])
else: else:
platforms = pluginManager.getPluginsOfCategory(pi.PluginTypes.PLATFORM) platforms = pluginManager.getPluginsOfCategory(pi.PluginTypes.PLATFORM)
list = utils.getOption(options, "--consumer", None)
if list:
consumers = pluginManager.getPluginsOf(categories=pi.PluginTypes.CONSUMER, name=[list.split(",")])
listConsumers = utils.getOption(options, "--consumer", None)
if listConsumers:
consumers = pluginManager.getPluginsOf(categories=pi.PluginTypes.CONSUMER, name=[listConsumers.split(",")])
else: else:
consumers = pluginManager.getPluginsOfCategory(pi.PluginTypes.CONSUMER) consumers = pluginManager.getPluginsOfCategory(pi.PluginTypes.CONSUMER)
@ -178,14 +179,14 @@ def main():
for plugin in platforms: for plugin in platforms:
# TODO: Check this is needed or not: in case of no plugin or wrong name maybe the list is empty instead of there being a None value # TODO: Check this is needed or not: in case of no plugin or wrong name maybe the list is empty instead of there being a None value
if plugin is None: if plugin is None:
# TODO: log instead to error ? critical ?
# TODO: log instead to error? critical?
print("No plugin installed name `" + plugin.name + "`.") print("No plugin installed name `" + plugin.name + "`.")
exit(os.EX_USAGE) exit(os.EX_USAGE)
try: try:
video.platform[plugin.name] = vid.Platform() video.platform[plugin.name] = vid.Platform()
if not plugin.plugin_object.prepare_options(video, options): if not plugin.plugin_object.prepare_options(video, options):
# A plugin found ill formed options, it should have logged the precises infos
# A plugin found ill formed options, it should have logged the precises info
print(plugin.name + " found a malformed option.") print(plugin.name + " found a malformed option.")
exit(os.EX_CONFIG) exit(os.EX_CONFIG)
except Exception as e: except Exception as e:
@ -195,13 +196,13 @@ def main():
for plugin in consumers: for plugin in consumers:
# TODO: Check this is needed or not: in case of no plugin or wrong name maybe the list is empty instead of there being a None value # TODO: Check this is needed or not: in case of no plugin or wrong name maybe the list is empty instead of there being a None value
if plugin is None: if plugin is None:
# TODO: log instead to error ? critical ?
# TODO: log instead to error? critical?
print("No plugin installed name `" + plugin.name + "`.") print("No plugin installed name `" + plugin.name + "`.")
exit(os.EX_USAGE) exit(os.EX_USAGE)
try: try:
if not plugin.plugin_object.prepare_options(video, options): if not plugin.plugin_object.prepare_options(video, options):
# A plugin found ill formed options, it should have logged the precises infos
# A plugin found ill formed options, it should have logged the precises info
print(plugin.name + " found a malformed option.") print(plugin.name + " found a malformed option.")
exit(os.EX_CONFIG) exit(os.EX_CONFIG)
except Exception as e: except Exception as e:
@ -209,7 +210,7 @@ def main():
exit(os.EX_CONFIG) exit(os.EX_CONFIG)
if video.path == "": if video.path == "":
# TODO: log instead to error ? critical ?
# TODO: log instead to error? critical?
print("No valid path to a video file has been provided.") print("No valid path to a video file has been provided.")
exit(os.EX_USAGE) exit(os.EX_USAGE)

+ 4
- 2
prismedia/pluginInterfaces.py View File

@ -1,6 +1,7 @@
from enum import Enum from enum import Enum
from yapsy.IPlugin import IPlugin from yapsy.IPlugin import IPlugin
class PluginTypes(Enum): class PluginTypes(Enum):
"""Plugin Types possibles to instantiate in this program.""" """Plugin Types possibles to instantiate in this program."""
ALL = "All" ALL = "All"
@ -8,6 +9,7 @@ class PluginTypes(Enum):
PLATFORM = "Platform" PLATFORM = "Platform"
CONSUMER = "Consumer" CONSUMER = "Consumer"
class IPrismediaBasePlugin(IPlugin): class IPrismediaBasePlugin(IPlugin):
""" """
Base for prismedias plugin. Base for prismedias plugin.
@ -41,11 +43,11 @@ class IPlatformPlugin(IPrismediaBasePlugin):
Interface for the Platform plugin category. Interface for the Platform plugin category.
""" """
def hearthbeat(self):
def heartbeat(self):
""" """
If needed for your platform, use a bit of the api so the platform is aware the keys are still in use. If needed for your platform, use a bit of the api so the platform is aware the keys are still in use.
""" """
raise NotImplementedError("`hearthbeat` must be reimplemented by %s" % self)
raise NotImplementedError("`heartbeat` must be reimplemented by %s" % self)
def upload(self, video, options): def upload(self, video, options):
""" """

+ 5
- 4
prismedia/plugins/interfaces/help.py View File

@ -2,10 +2,11 @@ import pluginInterfaces as pi
from yapsy.PluginManager import PluginManagerSingleton from yapsy.PluginManager import PluginManagerSingleton
class Help(pi.IInterfacePlugin): class Help(pi.IInterfacePlugin):
""" """
The help plugin print the usage informations of prismedias plugins.
Use it by simply caling `prismedia help <plugin_name>`.
The help plugin print the usage information of prismedias plugins.
Use it by simply calling `prismedia help <plugin_name>`.
For example `prismedia help help` bring this help. For example `prismedia help help` bring this help.
""" """
@ -20,7 +21,7 @@ class Help(pi.IInterfacePlugin):
for p in parameters: for p in parameters:
plugin = pluginManager.getPluginByName(p, pi.PluginTypes.ALL) plugin = pluginManager.getPluginByName(p, pi.PluginTypes.ALL)
if plugin is None: if plugin is None:
# TODO: log instead to warning ? error ?
# TODO: log instead to warning? error?
print("No plugin was found with name:", p) print("No plugin was found with name:", p)
continue continue
@ -42,7 +43,7 @@ class Help(pi.IInterfacePlugin):
for plugin in pluginManager.getPluginsOfCategory(pi.PluginTypes.CONSUMER): for plugin in pluginManager.getPluginsOfCategory(pi.PluginTypes.CONSUMER):
print("\t" + plugin.name) print("\t" + plugin.name)
# Print a line breack between each plugin help.
# Print a line break between each plugin help.
print() print()
return False return False

+ 45
- 51
prismedia/plugins/platforms/peertube.py View File

@ -12,7 +12,7 @@ import logging
import sys import sys
import datetime import datetime
import pytz import pytz
from os.path import splitext, basename, abspath # TODO: remove me, we already import `os` or at least choose one
from os.path import splitext, basename, abspath # TODO: remove me, we already import `os` or at least choose one
from tzlocal import get_localzone from tzlocal import get_localzone
from configparser import RawConfigParser from configparser import RawConfigParser
@ -23,10 +23,11 @@ from clint.textui.progress import Bar as ProgressBar
logger = logging.getLogger('Prismedia') logger = logging.getLogger('Prismedia')
class Peertube(pi.IPlatformPlugin): class Peertube(pi.IPlatformPlugin):
""" """
Plugin to upload to the Peertube platform. Plugin to upload to the Peertube platform.
The connetions files should be set as # TODO: EXPLAIN HOW TO SETUP THE SECRET FILES
The connections files should be set as # TODO: EXPLAIN HOW TO SETUP THE SECRET FILES
- `publish-at-peertube=DATE`: overrides the default `publish-at=DATE` for this platform. # TODO: Maybe we will use a [<plugin_name>] section on the config fire, explain that. - `publish-at-peertube=DATE`: overrides the default `publish-at=DATE` for this platform. # TODO: Maybe we will use a [<plugin_name>] section on the config fire, explain that.
""" """
SECRETS_FILE = 'peertube_secret' SECRETS_FILE = 'peertube_secret'
@ -74,7 +75,7 @@ class Peertube(pi.IPlatformPlugin):
def __init__(self): def __init__(self):
self.channelCreate = False self.channelCreate = False
self.name = "peertube" # TODO: find if it is possible to get the plugin’s name from inside the plugin
self.name = "peertube" # TODO: find if it is possible to get the plugin’s name from inside the plugin
self.oauth = {} self.oauth = {}
self.secret = {} self.secret = {}
@ -105,24 +106,20 @@ class Peertube(pi.IPlatformPlugin):
client_secret=str(self.secret.get('peertube', 'client_secret')) client_secret=str(self.secret.get('peertube', 'client_secret'))
) )
def convert_peertube_date(self, date): def convert_peertube_date(self, date):
date = datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%S') date = datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%S')
tz = get_localzone() tz = get_localzone()
tz = pytz.timezone(str(tz)) tz = pytz.timezone(str(tz))
return tz.localize(date).isoformat() return tz.localize(date).isoformat()
def get_default_channel(self, user_info): def get_default_channel(self, user_info):
return user_info['videoChannels'][0]['id'] return user_info['videoChannels'][0]['id']
def get_channel_by_name(self, user_info, video): def get_channel_by_name(self, user_info, video):
for channel in user_info["videoChannels"]: for channel in user_info["videoChannels"]:
if channel['displayName'] == video.platform[self.name].channel: if channel['displayName'] == video.platform[self.name].channel:
return channel['id'] return channel['id']
def create_channel(self, instance_url, video): def create_channel(self, instance_url, video):
template = ('Peertube: Channel %s does not exist, creating it.') template = ('Peertube: Channel %s does not exist, creating it.')
logger.info(template % (video.platform[self.name].channel)) logger.info(template % (video.platform[self.name].channel))
@ -139,8 +136,8 @@ class Peertube(pi.IPlatformPlugin):
} }
try: try:
response = self.oauth.post(instance_url + "/api/v1/video-channels/", response = self.oauth.post(instance_url + "/api/v1/video-channels/",
data=data.encode('utf-8'),
headers=headers)
data=data.encode('utf-8'),
headers=headers)
except Exception as e: except Exception as e:
logger.error("Peertube: " + utils.get_exception_string(e)) logger.error("Peertube: " + utils.get_exception_string(e))
@ -151,25 +148,24 @@ class Peertube(pi.IPlatformPlugin):
return jresponse['id'] return jresponse['id']
if response.status_code == 409: if response.status_code == 409:
logger.critical('Peertube: It seems there is a conflict with an existing channel named ' logger.critical('Peertube: It seems there is a conflict with an existing channel named '
+ channel_name + '.'
' Please beware Peertube internal name is compiled from 20 firsts characters of channel name.'
' Also note that channel name are not case sensitive (no uppercase nor accent)'
' Please check your channel name and retry.')
+ channel_name + '.'
' Please beware Peertube internal name is compiled from 20 firsts characters of channel name.'
' Also note that channel name are not case sensitive (no uppercase nor accent)'
' Please check your channel name and retry.')
exit(1) exit(1)
else: else:
logger.critical(('Peertube: Creating channel failed with an unexpected response: ' logger.critical(('Peertube: Creating channel failed with an unexpected response: '
'%s') % response)
'%s') % response)
exit(1) exit(1)
def get_default_playlist(user_info):
def get_default_playlist(self, user_info):
return user_info['videoChannels'][0]['id'] return user_info['videoChannels'][0]['id']
def get_playlist_by_name(instance_url, username, video):
def get_playlist_by_name(self, instance_url, username, video):
start = 0 start = 0
user_playlists = json.loads(self.oauth.get( user_playlists = json.loads(self.oauth.get(
instance_url + "/api/v1/accounts/"+username+"/video-playlists?start="+str(start)+"&count=100").content)
instance_url + "/api/v1/accounts/" + username + "/video-playlists?start=" + str(
start) + "&count=100").content)
total = user_playlists["total"] total = user_playlists["total"]
data = user_playlists["data"] data = user_playlists["data"]
# We need to iterate on pagination as peertube returns max 100 playlists (see #41) # We need to iterate on pagination as peertube returns max 100 playlists (see #41)
@ -179,11 +175,11 @@ class Peertube(pi.IPlatformPlugin):
return playlist['id'] return playlist['id']
start = start + 100 start = start + 100
user_playlists = json.loads(self.oauth.get( user_playlists = json.loads(self.oauth.get(
instance_url + "/api/v1/accounts/"+username+"/video-playlists?start="+str(start)+"&count=100").content)
instance_url + "/api/v1/accounts/" + username + "/video-playlists?start=" + str(
start) + "&count=100").content)
data = user_playlists["data"] data = user_playlists["data"]
def create_playlist(instance_url, video, channel):
def create_playlist(self, instance_url, video, channel):
template = ('Peertube: Playlist %s does not exist, creating it.') template = ('Peertube: Playlist %s does not exist, creating it.')
logger.info(template % (str(video.playlistName))) logger.info(template % (str(video.playlistName)))
# We use files for form-data Content # We use files for form-data Content
@ -197,7 +193,7 @@ class Peertube(pi.IPlatformPlugin):
try: try:
response = self.oauth.post(instance_url + "/api/v1/video-playlists/", response = self.oauth.post(instance_url + "/api/v1/video-playlists/",
files=files)
files=files)
except Exception as e: except Exception as e:
logger.error("Peertube: " + utils.get_exception_string(e)) logger.error("Peertube: " + utils.get_exception_string(e))
@ -208,11 +204,10 @@ class Peertube(pi.IPlatformPlugin):
return jresponse['id'] return jresponse['id']
else: else:
logger.critical(('Peertube: Creating the playlist failed with an unexpected response: ' logger.critical(('Peertube: Creating the playlist failed with an unexpected response: '
'%s') % response)
'%s') % response)
exit(1) exit(1)
def set_playlist(instance_url, video_id, playlist_id):
def set_playlist(self, instance_url, video_id, playlist_id):
logger.info('Peertube: add video to playlist.') logger.info('Peertube: add video to playlist.')
data = '{"videoId":"' + str(video_id) + '"}' data = '{"videoId":"' + str(video_id) + '"}'
@ -221,9 +216,9 @@ class Peertube(pi.IPlatformPlugin):
} }
try: try:
response = self.oauth.post(instance_url + "/api/v1/video-playlists/"+str(playlist_id)+"/videos",
data=data,
headers=headers)
response = self.oauth.post(instance_url + "/api/v1/video-playlists/" + str(playlist_id) + "/videos",
data=data,
headers=headers)
except Exception as e: except Exception as e:
logger.error("Peertube: " + utils.get_exception_string(e)) logger.error("Peertube: " + utils.get_exception_string(e))
@ -232,19 +227,18 @@ class Peertube(pi.IPlatformPlugin):
logger.info('Peertube: Video is successfully added to the playlist.') logger.info('Peertube: Video is successfully added to the playlist.')
else: else:
logger.critical(('Peertube: Configuring the playlist failed with an unexpected response: ' logger.critical(('Peertube: Configuring the playlist failed with an unexpected response: '
'%s') % response)
'%s') % response)
exit(1) exit(1)
def upload_video(self, video, options): def upload_video(self, video, options):
def get_userinfo(instance_url):
return json.loads(self.oauth.get(instance_url + "/api/v1/users/me").content)
def get_userinfo(base_url):
return json.loads(self.oauth.get(base_url + "/api/v1/users/me").content)
def get_file(path):
def get_file(video_path):
mimetypes.init() mimetypes.init()
return (basename(path), open(abspath(path), 'rb'),
mimetypes.types_map[splitext(path)[1]])
return (basename(video_path), open(abspath(video_path), 'rb'),
mimetypes.types_map[splitext(video_path)[1]])
path = video.path path = video.path
instance_url = str(self.secret.get('peertube', 'peertube_url')).rstrip('/') instance_url = str(self.secret.get('peertube', 'peertube_url')).rstrip('/')
@ -257,7 +251,7 @@ class Peertube(pi.IPlatformPlugin):
# https://github.com/requests/toolbelt/issues/205 # https://github.com/requests/toolbelt/issues/205
fields = [ fields = [
("name", video.name), ("name", video.name),
("licence", "1"), # TODO: get licence from video object
("licence", "1"), # TODO: get licence from video object
("description", video.description), ("description", video.description),
("category", str(self.CATEGORY[video.category])), ("category", str(self.CATEGORY[video.category])),
("language", str(self.LANGUAGE[video.language])), ("language", str(self.LANGUAGE[video.language])),
@ -274,7 +268,8 @@ class Peertube(pi.IPlatformPlugin):
continue continue
# Tag more than 30 chars crashes Peertube, so skip tags # Tag more than 30 chars crashes Peertube, so skip tags
if len(strtag) >= 30: if len(strtag) >= 30:
logger.warning("Peertube: Sorry, Peertube does not support tag with more than 30 characters, please reduce tag: " + strtag)
logger.warning(
"Peertube: Sorry, Peertube does not support tag with more than 30 characters, please reduce tag: " + strtag)
logger.warning("Peertube: Meanwhile, this tag will be skipped") logger.warning("Peertube: Meanwhile, this tag will be skipped")
continue continue
# Peertube supports only 5 tags at the moment # Peertube supports only 5 tags at the moment
@ -306,12 +301,13 @@ class Peertube(pi.IPlatformPlugin):
fields.append(("thumbnailfile", get_file(video.thumbnail))) fields.append(("thumbnailfile", get_file(video.thumbnail)))
fields.append(("previewfile", get_file(video.thumbnail))) fields.append(("previewfile", get_file(video.thumbnail)))
if hasattr(video.platform[self.name], "channel"): # TODO: Should always be present
if hasattr(video.platform[self.name], "channel"): # TODO: Should always be present
channel_id = self.get_channel_by_name(user_info, video) channel_id = self.get_channel_by_name(user_info, video)
if not channel_id and self.channelCreate: if not channel_id and self.channelCreate:
channel_id = self.create_channel(instance_url, video) channel_id = self.create_channel(instance_url, video)
elif not channel_id: elif not channel_id:
logger.warning("Peertube: Channel `" + video.platform[self.name].channel + "` is unknown, using default channel.") # TODO: debate if we should have the same message and behavior than playlist : "does not exist, please set --channelCreate"
logger.warning("Peertube: Channel `" + video.platform[
self.name].channel + "` is unknown, using default channel.") # TODO: debate if we should have the same message and behavior than playlist: "does not exist, please set --channelCreate"
channel_id = self.get_default_channel(user_info) channel_id = self.get_default_channel(user_info)
else: else:
channel_id = self.get_default_channel(user_info) channel_id = self.get_default_channel(user_info)
@ -323,8 +319,9 @@ class Peertube(pi.IPlatformPlugin):
if not playlist_id and video.playlistCreate: if not playlist_id and video.playlistCreate:
playlist_id = create_playlist(instance_url, video, channel_id) playlist_id = create_playlist(instance_url, video, channel_id)
elif not playlist_id: elif not playlist_id:
logger.critical("Peertube: Playlist `" + video.playlistName + "` does not exist, please set --playlistCreate"
" if you want to create it")
logger.critical(
"Peertube: Playlist `" + video.playlistName + "` does not exist, please set --playlistCreate"
" if you want to create it")
exit(1) exit(1)
encoder = MultipartEncoder(fields) encoder = MultipartEncoder(fields)
@ -338,8 +335,8 @@ class Peertube(pi.IPlatformPlugin):
'Content-Type': multipart_data.content_type 'Content-Type': multipart_data.content_type
} }
response = self.oauth.post(instance_url + "/api/v1/videos/upload", response = self.oauth.post(instance_url + "/api/v1/videos/upload",
data=multipart_data,
headers=headers)
data=multipart_data,
headers=headers)
if response is not None: if response is not None:
if response.status_code == 200: if response.status_code == 200:
@ -357,10 +354,9 @@ class Peertube(pi.IPlatformPlugin):
set_playlist(instance_url, video_id, playlist_id) set_playlist(instance_url, video_id, playlist_id)
else: else:
logger.critical(('Peertube: The upload failed with an unexpected response: ' logger.critical(('Peertube: The upload failed with an unexpected response: '
'%s') % response)
'%s') % response)
exit(1) exit(1)
# upload_finished = False # upload_finished = False
# def create_callback(encoder, progress_type): # def create_callback(encoder, progress_type):
# upload_size_MB = encoder.len * (1 / (1024 * 1024)) # upload_size_MB = encoder.len * (1 / (1024 * 1024))
@ -396,16 +392,14 @@ class Peertube(pi.IPlatformPlugin):
# #
# return callback # return callback
def hearthbeat(self):
def heartbeat(self):
""" """
If needed for your platform, use a bit of the api so the platform is aware the keys are still in use. If needed for your platform, use a bit of the api so the platform is aware the keys are still in use.
""" """
print("Hearthbeat for peertube (nothing to do)")
print("heartbeat for peertube (nothing to do)")
pass pass
def upload(self, video, options):
# def run(options): # def run(options):
def upload(self, video, options):
logger.info('Peertube: Uploading video...') logger.info('Peertube: Uploading video...')
self.upload_video(video, options) self.upload_video(video, options)

+ 2
- 2
prismedia/plugins/platforms/youtube.py View File

@ -373,7 +373,7 @@ def resumable_upload(request, resource, method, options):
time.sleep(sleep_seconds) time.sleep(sleep_seconds)
def hearthbeat():
def heartbeat():
"""Use the minimums credits possibles of the API so google does not readuce to 0 the allowed credits. """Use the minimums credits possibles of the API so google does not readuce to 0 the allowed credits.
This apparently happens after 90 days without any usage of credits. This apparently happens after 90 days without any usage of credits.
For more info see the official documentations: For more info see the official documentations:
@ -384,7 +384,7 @@ def hearthbeat():
try: try:
get_playlist_by_name(youtube, "Foo") get_playlist_by_name(youtube, "Foo")
except HttpError as e: except HttpError as e:
logger.error('Youtube: An HTTP error %d occurred on hearthbeat:\n%s' %
logger.error('Youtube: An HTTP error %d occurred on heartbeat:\n%s' %
(e.resp.status, e.content)) (e.resp.status, e.content))

+ 7
- 6
prismedia/upload.py View File

@ -7,7 +7,7 @@ prismedia - tool to upload videos to Peertube and Youtube
Usage: Usage:
prismedia --file=<FILE> [options] prismedia --file=<FILE> [options]
prismedia -f <FILE> --tags=STRING [options] prismedia -f <FILE> --tags=STRING [options]
prismedia --hearthbeat
prismedia --heartbeat
prismedia -h | --help prismedia -h | --help
prismedia --version prismedia --version
@ -52,7 +52,7 @@ Options:
Only relevant if --playlist is set. Only relevant if --playlist is set.
--progress=STRING Set the progress bar view, one of percentage, bigFile (MB), accurate (KB). --progress=STRING Set the progress bar view, one of percentage, bigFile (MB), accurate (KB).
--hearthbeat Use some credits to show some activity for you apikey so the platform know it is used and would not put your quota to 0 (only Youtube currently)
--heartbeat Use some credits to show some activity for you apikey so the platform know it is used and would not put your quota to 0 (only Youtube currently)
-h --help Show this help. -h --help Show this help.
--version Show version. --version Show version.
@ -109,7 +109,6 @@ if sys.version_info[0] < 3:
import os import os
import datetime import datetime
import logging import logging
logger = logging.getLogger('Prismedia')
from docopt import docopt from docopt import docopt
@ -117,6 +116,8 @@ from . import yt_upload
from . import pt_upload from . import pt_upload
from . import utils from . import utils
logger = logging.getLogger('Prismedia')
try: try:
# noinspection PyUnresolvedReferences # noinspection PyUnresolvedReferences
from schema import Schema, And, Or, Optional, SchemaError, Hook, Use from schema import Schema, And, Or, Optional, SchemaError, Hook, Use
@ -289,15 +290,15 @@ def main():
Optional('--playlist'): Or(None, str), Optional('--playlist'): Or(None, str),
Optional('--playlistCreate'): bool, Optional('--playlistCreate'): bool,
Optional('--progress'): Or(None, And(str, validateProgress, error="Sorry, progress visualisation not supported")), Optional('--progress'): Or(None, And(str, validateProgress, error="Sorry, progress visualisation not supported")),
'--hearthbeat': bool,
'--heartbeat': bool,
'--help': bool, '--help': bool,
'--version': bool, '--version': bool,
# This allow to return all other options for further use: https://github.com/keleshev/schema#extra-keys # This allow to return all other options for further use: https://github.com/keleshev/schema#extra-keys
object: object object: object
}) })
if options.get('--hearthbeat'):
yt_upload.hearthbeat()
if options.get('--heartbeat'):
yt_upload.heartbeat()
exit(0) exit(0)
# We need to validate early options first as withNFO and logs options should be prioritized # We need to validate early options first as withNFO and logs options should be prioritized

+ 6
- 4
prismedia/video.py View File

@ -1,5 +1,6 @@
from os.path import dirname, splitext, basename, isfile, normpath, expanduser from os.path import dirname, splitext, basename, isfile, normpath, expanduser
class Platform(object): class Platform(object):
""" """
Store data representing a Platform. Store data representing a Platform.
@ -13,6 +14,7 @@ class Platform(object):
def __repr__(self): def __repr__(self):
return str(self.__dict__) return str(self.__dict__)
# TODO: Add container for `with-*` and a `isValid` method to check that all `with-*` options are present # TODO: Add container for `with-*` and a `isValid` method to check that all `with-*` options are present
# TODO: We need some list (using enum?) for the commons licences, language, privacy, categories options # TODO: We need some list (using enum?) for the commons licences, language, privacy, categories options
class Video(object): class Video(object):
@ -59,13 +61,13 @@ class Video(object):
elif isfile(path): elif isfile(path):
self._path = path self._path = path
else: else:
# TODO: log instead to debug ? info ?
# TODO: log instead to debug? info?
print("The path `" + value + "` does not point to a video") print("The path `" + value + "` does not point to a video")
self._path = "" self._path = ""
@property @property
def thumbnail(self): def thumbnail(self):
if not self._thumbnail is None:
if self._thumbnail is not None:
return self._thumbnail return self._thumbnail
else: else:
result = None result = None
@ -89,7 +91,7 @@ class Video(object):
elif isfile(video_directory + video_file + ".jpeg"): elif isfile(video_directory + video_file + ".jpeg"):
result = video_directory + video_file + ".jpeg" result = video_directory + video_file + ".jpeg"
# TODO: move to caller. Logging the output is its resporsability
# TODO: move to caller. Logging the output is its responsibility
# Display some info after research # Display some info after research
# if not result: # if not result:
# logger.debug("No thumbnail has been found, continuing") # logger.debug("No thumbnail has been found, continuing")
@ -104,7 +106,7 @@ class Video(object):
@property @property
def name(self): def name(self):
if not self._name is None:
if self._name is not None:
return self._name return self._name
else: else:
return splitext(basename(self.path))[0] return splitext(basename(self.path))[0]

Loading…
Cancel
Save