From 0879efb8ec903fba14cdd998e6624968455fd5af Mon Sep 17 00:00:00 2001 From: mathdatech Date: Mon, 23 May 2022 20:36:29 +0200 Subject: [PATCH] add 4 directories --- img2toot_v3/config.ini | 18 +++ img2toot_v3/img2toot.py | 117 +++++++++++++++ playlist2toot_v2/config.ini | 30 ++++ playlist2toot_v2/playlist.txt | 3 + playlist2toot_v2/playlist2toot.py | 173 +++++++++++++++++++++++ playlist2toot_v2/requirements.txt | 3 + playlist2toot_v2/ytscraper.py | 82 +++++++++++ tootytvideo_v1/config.ini | 18 +++ tootytvideo_v1/tootytvideo.py | 156 ++++++++++++++++++++ tootytvideo_v1/ytscraper.py | 82 +++++++++++ txt2toot/config.ini | 18 +++ txt2toot/txt/Documen561ezft 2 sans titre | 1 + txt2toot/txt/qzefqefe515zefdcs | 1 + txt2toot/txt/sgrgsrg.txt | 5 + txt2toot/txt/zefbdfberb.txt | 1 + txt2toot/txt2toot.py | 117 +++++++++++++++ 16 files changed, 825 insertions(+) create mode 100755 img2toot_v3/config.ini create mode 100755 img2toot_v3/img2toot.py create mode 100755 playlist2toot_v2/config.ini create mode 100755 playlist2toot_v2/playlist.txt create mode 100755 playlist2toot_v2/playlist2toot.py create mode 100755 playlist2toot_v2/requirements.txt create mode 100755 playlist2toot_v2/ytscraper.py create mode 100755 tootytvideo_v1/config.ini create mode 100755 tootytvideo_v1/tootytvideo.py create mode 100755 tootytvideo_v1/ytscraper.py create mode 100755 txt2toot/config.ini create mode 100755 txt2toot/txt/Documen561ezft 2 sans titre create mode 100755 txt2toot/txt/qzefqefe515zefdcs create mode 100755 txt2toot/txt/sgrgsrg.txt create mode 100755 txt2toot/txt/zefbdfberb.txt create mode 100755 txt2toot/txt2toot.py diff --git a/img2toot_v3/config.ini b/img2toot_v3/config.ini new file mode 100755 index 0000000..0e42c1f --- /dev/null +++ b/img2toot_v3/config.ini @@ -0,0 +1,18 @@ +[mastodon] +client_id= +client_secret= +access_token= +mastodon_hostname=botsin.space + +[toot] +status=Le curvy, c'est la vie ! 😍 +hashtag=#NSFW +;Default visibility is the same as your configuration profil +;but you can override it:'public', 'unlisted', 'private', 'direct' +;visibility=public +;visibility=private +;visibility=unlisted +;Default sensitive is True, but you can override it: +;sensitive=False +;Default spoiler text is None, but you can override it: +;spoiler=''\00 diff --git a/img2toot_v3/img2toot.py b/img2toot_v3/img2toot.py new file mode 100755 index 0000000..402737e --- /dev/null +++ b/img2toot_v3/img2toot.py @@ -0,0 +1,117 @@ +#!/usr/bin/python3 +# coding: utf-8 +# -*- coding: utf-8 -*- + + +from mastodon import Mastodon +import os +import random +import sys +import argparse +from configparser import ConfigParser + +__prog_name__ = 'img2toot' +__version__ = '0.3' +__description__ = 'Toot bot for random local NSFW image for Mastodon' + + +if __name__ == "__main__": + # Read arguments + parser = argparse.ArgumentParser(prog=__prog_name__, + description=__description__) + parser.add_argument('--version', action='version', version=__version__) + parser.add_argument('-d', '--dir', required=True, help="Image\'s directory") + parser.add_argument('-c', '--config', default='config.ini', + help="Config file (default: %(default)s)") + args = parser.parse_args() + config_filepath = args.config + + # Check if config file exists + if not os.path.isfile(config_filepath): + print("Config file %s not found, exiting." % config_filepath) + sys.exit(0) + else: + # Read config file + conf = ConfigParser() + conf.read(config_filepath) + + # Need a directory + if not args.dir: + print("Image\'s directory argument missing") + sys.exit(0) + image_dir = args.dir + "/" + + # Overwrite default settings + if conf.has_option('toot', 'visibility'): + toot_visibility = conf['toot']['visibility'] + else: + toot_visibility = '' + + if conf.has_option('toot', 'sensitive'): + toot_sensitive = conf['toot']['sensitive'] + else: + toot_sensitive = True + + if conf.has_option('toot', 'spoiler'): + toot_spoiler = conf['toot']['spoiler'] + else: + toot_spoiler = None + + # Log into Mastodon if enabled in settings + mastodon_hostname = conf['mastodon']['mastodon_hostname'] + try: + mastodonAPI = Mastodon( + client_id=conf['mastodon']['client_id'], + client_secret=conf['mastodon']['client_secret'], + access_token=conf['mastodon']['access_token'], + api_base_url='https://' + mastodon_hostname) + masto_username = mastodonAPI.account_verify_credentials()['username'] + print ('[ OK ] Sucessfully authenticated on ' + mastodon_hostname + + ' as @' + masto_username) + except BaseException as e: + print ('[ERROR] Error while logging into Mastodon:', str(e)) + sys.exit(0) + + #Prepare media IDs + try: + mfile = random.choice(os.listdir(image_dir)) + image_byte = open(image_dir + mfile, "rb").read() + + if mfile[-3:] == "jpe": + mime = "image/jpeg" + elif mfile[-3:] == "jpg": + mime = "image/jpeg" + elif mfile[-3:] == "png": + mime = "image/png" + elif mfile[-3:] == "gif": + mime = "image/gif" + elif mfile[-3:] == "gifv": + mime = "video/mp4" + elif mfile[-3:] == "mp4": + mime = "video/mp4" + else: + print("Incorrect media file format") + + media_dict = mastodonAPI.media_post(image_byte, mime) + except BaseException as e: + print ('[ERROR] Error while reading media file : ' + str(e)) + sys.exit(0) + + # Post the toot + toot_status = conf['toot']['status'] + toot_status += '\n' + toot_status += conf['toot']['hashtag'] + try: + status = mastodonAPI.status_post( + status=toot_status, + in_reply_to_id=None, + media_ids=[media_dict], + sensitive=toot_sensitive, + visibility=toot_visibility, + spoiler_text=toot_spoiler + ) + print ( + '[ OK ] Posting this on Mastodon account with media attachment : ' + + status['url']) + except BaseException as e: + print ('[ERROR] Error while posting toot:' + str(e)) \ No newline at end of file diff --git a/playlist2toot_v2/config.ini b/playlist2toot_v2/config.ini new file mode 100755 index 0000000..e5d591e --- /dev/null +++ b/playlist2toot_v2/config.ini @@ -0,0 +1,30 @@ +[mastodon] +client_id= +client_secret= +access_token= +mastodon_hostname=botsin.space + +[toot] +status= +hashtag=#PouetRadio #TootRadio +;Default visibility is the same as your configuration profil +;but you can override it:'public', 'unlisted', 'private', 'direct' +;visibility=public +;visibility=private +;visibility=unlisted +;Default sensitive is False, but you can override it: +;sensitive=True +;Default spoiler text is None, but you can override it: +;spoiler=Lorem ipsum + +[preset] +;Default time delay beetween 2 toot (in sec) +delay=180 +;Use the videos duration beetween 2 toot [False, True] +;useduration=False +useduration=True +;Make a thread [False, True] +;thread=False +thread=True +;default thumbnail directory name +dirthumbnail=thumbnails diff --git a/playlist2toot_v2/playlist.txt b/playlist2toot_v2/playlist.txt new file mode 100755 index 0000000..01f599b --- /dev/null +++ b/playlist2toot_v2/playlist.txt @@ -0,0 +1,3 @@ +commentaire1;https://www.youtube.com/watch?v=R7cPptwFZM8;#blues +commentaire2;https://www.youtube.com/watch?v=WK2siEQsADk;#rock +commentaire3;https://www.youtube.com/watch?v=202fjZZO-tI;#bluesrock diff --git a/playlist2toot_v2/playlist2toot.py b/playlist2toot_v2/playlist2toot.py new file mode 100755 index 0000000..32b0bdf --- /dev/null +++ b/playlist2toot_v2/playlist2toot.py @@ -0,0 +1,173 @@ +#!/usr/bin/python3 +# coding: utf-8 +# -*- coding: utf-8 -*- + + +from mastodon import Mastodon +import os +import time +import sys +import argparse +from configparser import ConfigParser +import ytscraper + +__prog_name__ = 'playlist2toot' +__version__ = '0.2' +__description__ = 'Toot a playlist on Mastodon' + + +if __name__ == "__main__": + # Read arguments + parser = argparse.ArgumentParser(prog=__prog_name__, + description=__description__) + parser.add_argument('--version', action='version', version=__version__) + parser.add_argument('-p', '--playlist', required=True, + help="Playlist text file") + parser.add_argument('-c', '--config', default='config.ini', + help="Config file (default: %(default)s)") + args = parser.parse_args() + config_filepath = args.config + + # Check if config file exists + if not os.path.isfile(config_filepath): + print("Config file %s not found, exiting." % config_filepath) + sys.exit(0) + else: + # Read config file + conf = ConfigParser() + conf.read(config_filepath) + + # Load the playlist file + with open(args.playlist, "r") as fichier: + playlist_mem = fichier.readlines() + + # Overwrite default settings + if conf.has_option('toot', 'status'): + toot_status = conf['toot']['status'] + '\n' + else: + toot_status = '' + + if conf.has_option('toot', 'visibility'): + toot_visibility = conf['toot']['visibility'] + else: + toot_visibility = '' + + if conf.has_option('toot', 'sensitive'): + toot_sensitive = conf['toot']['sensitive'] + else: + toot_sensitive = False + + if conf.has_option('toot', 'spoiler'): + toot_spoiler = conf['toot']['spoiler'] + else: + toot_spoiler = None + + #used bay make a thread + if conf.has_option('preset', 'thread'): + toot_lastid = None + + # Log into Mastodon if enabled in settings + print('[ OK ] {} Let the show begin !'.format(time.strftime('%H:%M'))) + mastodon_hostname = conf['mastodon']['mastodon_hostname'] + try: + mastodonAPI = Mastodon( + client_id=conf['mastodon']['client_id'], + client_secret=conf['mastodon']['client_secret'], + access_token=conf['mastodon']['access_token'], + api_base_url='https://' + mastodon_hostname + ) + masto_username = mastodonAPI.account_verify_credentials()['username'] + print('[ OK ] {} Sucessfully authenticated on {} as @{}'.format( + time.strftime('%H:%M'), mastodon_hostname, masto_username)) + except BaseException as e: + print('[ERROR] Error while logging into Mastodon:', str(e)) + sys.exit(0) + + + for i in range(len(playlist_mem)): + # Prepare the toot + if conf.has_option('toot', 'status'): + toot_status = conf['toot']['status'] + '\n' + else: + toot_status = '' + # video commentary + toot_status += playlist_mem[i].split(";")[0] + toot_status += '\n' + # video title + video = ytscraper.scrape_url(playlist_mem[i].split(";")[1]) + toot_status += video.title + toot_status += '\n' + toot_status += video.yturl + # add hashtag + toot_status += '\n' + toot_status += conf['toot']['hashtag'] + toot_status += ' ' + toot_status += playlist_mem[i].split(";")[2] + + # Prepare media IDs + try: + paththumbnail = './' + conf['preset']['dirthumbnail'] + mfile = ytscraper.download_image( + video.thumbnail, + video.videoid, + paththumbnail + ) + image_byte = open(mfile, "rb").read() + + if mfile[-3:] == "jpe": + mime = "image/jpeg" + elif mfile[-3:] == "jpg": + mime = "image/jpeg" + elif mfile[-3:] == "png": + mime = "image/png" + elif mfile[-3:] == "gif": + mime = "image/gif" + elif mfile[-3:] == "gifv": + mime = "video/mp4" + elif mfile[-3:] == "mp4": + mime = "video/mp4" + else: + print("Incorrect media file format") + + media_dict = mastodonAPI.media_post(image_byte, mime) + except BaseException as e: + print ('[ERROR] Error while reading media file : ' + str(e)) + sys.exit(0) + + # Post the toot + try: + status = mastodonAPI.status_post( + status=toot_status, + in_reply_to_id=toot_lastid, + media_ids=[media_dict], + sensitive=toot_sensitive, + visibility=toot_visibility, + spoiler_text=toot_spoiler + ) + print('[ OK ] {} Posting this on Mastodon account : {}'.format( + time.strftime('%H:%M'), status['url'])) + except BaseException as e: + print('[ERROR] Error while posting toot:' + str(e)) + sys.exit(0) + + # make a thread + if conf.getboolean('preset', 'thread'): + toot_lastid = status['id'] + else: + toot_lastid = None + + # make a pause + print('use duration = ' + conf['preset']['useduration']) + print('delay = ' + conf['preset']['delay']) + if conf.getboolean('preset', 'useduration'): + preset_delay = video.durationinseconds + else: + print('delay = ' + conf['preset']['delay']) + preset_delay = int(conf['preset']['delay']) + print('preset_delay = ' + str(preset_delay), type(preset_delay)) + + if i < (len(playlist_mem) - 1): + time.sleep(preset_delay) + + # The End + print('[ OK ] {} The show is over !'.format(time.strftime('%H:%M'))) diff --git a/playlist2toot_v2/requirements.txt b/playlist2toot_v2/requirements.txt new file mode 100755 index 0000000..a9fd822 --- /dev/null +++ b/playlist2toot_v2/requirements.txt @@ -0,0 +1,3 @@ +Mastodon.py +argparse +ConfigParser diff --git a/playlist2toot_v2/ytscraper.py b/playlist2toot_v2/ytscraper.py new file mode 100755 index 0000000..129b633 --- /dev/null +++ b/playlist2toot_v2/ytscraper.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from urllib.request import urlopen, urlretrieve +import re +import os +from datetime import timedelta +from bs4 import BeautifulSoup + +""" +based on youtube-scraper (https://github.com/narfman0/youtube-scraper) +""" + + +class YoutubeScrape(object): + """ Scraper object to hold data """ + def __init__(self, soup): + """ Initialize and scrape """ + self.soup = soup + #self.title = self.parse_string('.watch-title') + self.title = self.parse_string({'name': 'title'}) + self.artist = self.parse_string_o('.yt-user-info') + self.duration = self.parse_string({'itemprop': 'duration'}) + self.durationinseconds = self.parseISO8591(self.duration) + self.durationtime = str(timedelta(seconds=self.durationinseconds)) + self.poster = self.parse_string_o('.yt-user-info') + self.views = self.parse_int('.watch-view-count') + self.published = self.parse_string_o('.watch-time-text') + self.published = re.sub(r'(Published|Uploaded) on', '', + self.published).strip() + #self.like = self.parse_int('#watch-like') + #self.dislike = self.parse_int('#watch-dislike') + self.yturl = self.parse_string({'property': "og:url"}) + self.thumbnail = self.parse_string({'property': "og:image"}) + self.videoid = self.parse_string({'itemprop': 'videoId'}) + + def parse_int(self, selector): + """ Extract one integer element from soup """ + return int(re.sub('[^0-9]', '', self.parse_string_o(selector))) + + def parse_string(self, selector): + """ Extract one particular element from soup """ + return self.soup.find_all(attrs=selector)[0]['content'] + + def parse_string_o(self, selector): + """ Extract one particular element from soup """ + return self.soup.select(selector)[0].get_text().strip() + + def parseISO8591(self, duration): + """ Parse ISO 8591 formated duration """ + regex = re.compile(r'PT((\d{1,3})H)?((\d{1,3})M)?((\d{1,2})S)?') + if duration: + duration = regex.findall(duration) + if len(duration) > 0: + _, hours, _, minutes, _, seconds = duration[0] + duration = [seconds, minutes, hours] + duration = [int(v) if len(v) > 0 else 0 for v in duration] + duration = sum([60**p*v for p, v in enumerate(duration)]) + else: + duration = 30 + else: + duration = 30 + return duration + + +def scrape_html(html): + """ Return meta information about a video """ + soup = BeautifulSoup(html, "html.parser") + return YoutubeScrape(soup) + + +def scrape_url(url): + """ Scrape a given url for youtube information """ + html = urlopen(url) + return YoutubeScrape(BeautifulSoup(html, "html.parser")) + + +def download_image(urlthumbnail, videoid, path): + """Download the thumbnail""" + if not os.path.exists(path): + os.makedirs(path) + local_filename, headers = urlretrieve(urlthumbnail, + path + '/maxresdefault-' + videoid + '.jpg') + return local_filename diff --git a/tootytvideo_v1/config.ini b/tootytvideo_v1/config.ini new file mode 100755 index 0000000..65f9748 --- /dev/null +++ b/tootytvideo_v1/config.ini @@ -0,0 +1,18 @@ +[mastodon] +client_id= +client_secret= +access_token= +mastodon_hostname=botsin.space + +[toot] +status= +hashtag=#PouetRadio #TootRadio +;Default visibility is the same as your configuration profil +;but you can override it:'public', 'unlisted', 'private', 'direct' +;visibility=public +;visibility=private +;visibility=unlisted +;Default sensitive is False, but you can override it: +;sensitive=True +;Default spoiler text is None, but you can override it: +;spoiler=Lorem ipsum diff --git a/tootytvideo_v1/tootytvideo.py b/tootytvideo_v1/tootytvideo.py new file mode 100755 index 0000000..a8fcf19 --- /dev/null +++ b/tootytvideo_v1/tootytvideo.py @@ -0,0 +1,156 @@ +#!/usr/bin/python3 +# coding: utf-8 +# -*- coding: utf-8 -*- + + +from mastodon import Mastodon +import os +import time +import sys +import argparse +from configparser import ConfigParser +import ytscraper + +__prog_name__ = 'tootytvideo' +__version__ = '0.1' +__description__ = 'Toot a youtube video on Mastodon' + + +if __name__ == "__main__": + # Read arguments + parser = argparse.ArgumentParser(prog=__prog_name__, + description=__description__) + parser.add_argument('--version', action='version', version=__version__) + parser.add_argument('-c', '--config', default='config.ini', + help="Config file (default: %(default)s)") + args = parser.parse_args() + config_filepath = args.config + + # Check if config file exists + if not os.path.isfile(config_filepath): + print("Config file %s not found, exiting." % config_filepath) + sys.exit(0) + else: + # Read config file + conf = ConfigParser() + conf.read(config_filepath) + + # Overwrite default settings + if conf.has_option('toot', 'status'): + toot_status = conf['toot']['status'] + '\n' + else: + toot_status = '' + + if conf.has_option('toot', 'visibility'): + toot_visibility = conf['toot']['visibility'] + else: + toot_visibility = '' + + if conf.has_option('toot', 'sensitive'): + toot_sensitive = conf['toot']['sensitive'] + else: + toot_sensitive = False + + if conf.has_option('toot', 'spoiler'): + toot_spoiler = conf['toot']['spoiler'] + else: + toot_spoiler = None + + # Log into Mastodon if enabled in settings + print('[ OK ] {} Login'.format(time.strftime('%H:%M'))) + mastodon_hostname = conf['mastodon']['mastodon_hostname'] + try: + mastodonAPI = Mastodon( + client_id=conf['mastodon']['client_id'], + client_secret=conf['mastodon']['client_secret'], + access_token=conf['mastodon']['access_token'], + api_base_url='https://' + mastodon_hostname + ) + masto_username = mastodonAPI.account_verify_credentials()['username'] + print('[ OK ] {} Sucessfully authenticated on {} as @{}'.format( + time.strftime('%H:%M'), mastodon_hostname, masto_username)) + except BaseException as e: + print('[ERROR] Error while logging into Mastodon:', str(e)) + sys.exit(0) + # Run + resp = True + + while resp: + print('+- New toot -+') + yturl = input('Youtube URL : ') + comment = input('Add a comment : ') + hashtag = input('Add hastag : ') + + # Prepare the toot + if conf.has_option('toot', 'status'): + toot_status = conf['toot']['status'] + '\n' + else: + toot_status = '' + # video commentary + toot_status += comment + toot_status += '\n' + # video title + video = ytscraper.scrape_url(yturl) + toot_status += video.title + toot_status += '\n' + toot_status += video.yturl + # add hashtag + toot_status += '\n' + toot_status += conf['toot']['hashtag'] + toot_status += ' ' + toot_status += hashtag + + # Prepare media IDs + try: + mfile = ytscraper.download_image( + video.thumbnail, + video.videoid, + '.' + ) + image_byte = open(mfile, "rb").read() + + if mfile[-3:] == "jpe": + mime = "image/jpeg" + elif mfile[-3:] == "jpg": + mime = "image/jpeg" + elif mfile[-3:] == "png": + mime = "image/png" + elif mfile[-3:] == "gif": + mime = "image/gif" + elif mfile[-3:] == "gifv": + mime = "video/mp4" + elif mfile[-3:] == "mp4": + mime = "video/mp4" + else: + print("Incorrect media file format") + + media_dict = mastodonAPI.media_post(image_byte, mime) + except BaseException as e: + print ('[ERROR] Error while reading media file : ' + str(e)) + sys.exit(0) + + # Post the toot + try: + status = mastodonAPI.status_post( + status=toot_status, + in_reply_to_id=None, + media_ids=[media_dict], + sensitive=toot_sensitive, + visibility=toot_visibility, + spoiler_text=toot_spoiler + ) + print('[ OK ] {} Posting this on Mastodon account : {}'.format( + time.strftime('%H:%M'), status['url'])) + except BaseException as e: + print('[ERROR] Error while posting toot:' + str(e)) + sys.exit(0) + + # make a pause + r = input('Continue (y/n)? ') + if r.lower() == 'y': + resp = True + else: + resp = False + + # The End + print('[ OK ] {} The show is over !'.format(time.strftime('%H:%M'))) \ No newline at end of file diff --git a/tootytvideo_v1/ytscraper.py b/tootytvideo_v1/ytscraper.py new file mode 100755 index 0000000..129b633 --- /dev/null +++ b/tootytvideo_v1/ytscraper.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +from urllib.request import urlopen, urlretrieve +import re +import os +from datetime import timedelta +from bs4 import BeautifulSoup + +""" +based on youtube-scraper (https://github.com/narfman0/youtube-scraper) +""" + + +class YoutubeScrape(object): + """ Scraper object to hold data """ + def __init__(self, soup): + """ Initialize and scrape """ + self.soup = soup + #self.title = self.parse_string('.watch-title') + self.title = self.parse_string({'name': 'title'}) + self.artist = self.parse_string_o('.yt-user-info') + self.duration = self.parse_string({'itemprop': 'duration'}) + self.durationinseconds = self.parseISO8591(self.duration) + self.durationtime = str(timedelta(seconds=self.durationinseconds)) + self.poster = self.parse_string_o('.yt-user-info') + self.views = self.parse_int('.watch-view-count') + self.published = self.parse_string_o('.watch-time-text') + self.published = re.sub(r'(Published|Uploaded) on', '', + self.published).strip() + #self.like = self.parse_int('#watch-like') + #self.dislike = self.parse_int('#watch-dislike') + self.yturl = self.parse_string({'property': "og:url"}) + self.thumbnail = self.parse_string({'property': "og:image"}) + self.videoid = self.parse_string({'itemprop': 'videoId'}) + + def parse_int(self, selector): + """ Extract one integer element from soup """ + return int(re.sub('[^0-9]', '', self.parse_string_o(selector))) + + def parse_string(self, selector): + """ Extract one particular element from soup """ + return self.soup.find_all(attrs=selector)[0]['content'] + + def parse_string_o(self, selector): + """ Extract one particular element from soup """ + return self.soup.select(selector)[0].get_text().strip() + + def parseISO8591(self, duration): + """ Parse ISO 8591 formated duration """ + regex = re.compile(r'PT((\d{1,3})H)?((\d{1,3})M)?((\d{1,2})S)?') + if duration: + duration = regex.findall(duration) + if len(duration) > 0: + _, hours, _, minutes, _, seconds = duration[0] + duration = [seconds, minutes, hours] + duration = [int(v) if len(v) > 0 else 0 for v in duration] + duration = sum([60**p*v for p, v in enumerate(duration)]) + else: + duration = 30 + else: + duration = 30 + return duration + + +def scrape_html(html): + """ Return meta information about a video """ + soup = BeautifulSoup(html, "html.parser") + return YoutubeScrape(soup) + + +def scrape_url(url): + """ Scrape a given url for youtube information """ + html = urlopen(url) + return YoutubeScrape(BeautifulSoup(html, "html.parser")) + + +def download_image(urlthumbnail, videoid, path): + """Download the thumbnail""" + if not os.path.exists(path): + os.makedirs(path) + local_filename, headers = urlretrieve(urlthumbnail, + path + '/maxresdefault-' + videoid + '.jpg') + return local_filename diff --git a/txt2toot/config.ini b/txt2toot/config.ini new file mode 100755 index 0000000..4da4c00 --- /dev/null +++ b/txt2toot/config.ini @@ -0,0 +1,18 @@ +[mastodon] +client_id= +client_secret= +access_token= +mastodon_hostname=botsin.space + +[toot] +status=le beau texte : +hashtag=#txtbot +;Default visibility is the same as your configuration profil +;but you can override it:'public', 'unlisted', 'private', 'direct' +;visibility=public +;visibility=private +;visibility=unlisted +;Default sensitive is False, but you can override it: +;sensitive=True +;Default spoiler text is None, but you can override it: +;spoiler=Lorem ipsum diff --git a/txt2toot/txt/Documen561ezft 2 sans titre b/txt2toot/txt/Documen561ezft 2 sans titre new file mode 100755 index 0000000..2e9fdaf --- /dev/null +++ b/txt2toot/txt/Documen561ezft 2 sans titre @@ -0,0 +1 @@ +Quibus ita sceleste patratis Paulus cruore perfusus reversusque ad principis castra multos coopertos paene catenis adduxit in squalorem deiectos atque maestitiam, quorum adventu intendebantur eculei uncosque parabat carnifex et tormenta. et ex is proscripti sunt plures actique in exilium alii, non nullos gladii consumpsere poenales. nec enim quisquam facile meminit sub Constantio, ubi susurro tenus haec movebantur, quemquam absolutum. diff --git a/txt2toot/txt/qzefqefe515zefdcs b/txt2toot/txt/qzefqefe515zefdcs new file mode 100755 index 0000000..de02be6 --- /dev/null +++ b/txt2toot/txt/qzefqefe515zefdcs @@ -0,0 +1 @@ +Dum haec in oriente aguntur, Arelate hiemem agens Constantius post theatralis ludos atque circenses ambitioso editos apparatu diem sextum idus Octobres, qui imperii eius annum tricensimum terminabat, insolentiae pondera gravius librans, siquid dubium deferebatur aut falsum, pro liquido accipiens et conperto, inter alia excarnificatum Gerontium Magnentianae comitem partis exulari maerore multavit. diff --git a/txt2toot/txt/sgrgsrg.txt b/txt2toot/txt/sgrgsrg.txt new file mode 100755 index 0000000..0e3ebcc --- /dev/null +++ b/txt2toot/txt/sgrgsrg.txt @@ -0,0 +1,5 @@ +Et quoniam apud eos ut in capite mundi morborum +Cognitis enim pilatorum caesorumque funeribus nemo +Tu autem, Fanni, quod mihi tantum tribui dicis +Coactique aliquotiens nostri pedites ad eos +Huic Arabia est conserta, ex alio latere Nabataeis diff --git a/txt2toot/txt/zefbdfberb.txt b/txt2toot/txt/zefbdfberb.txt new file mode 100755 index 0000000..d8b7772 --- /dev/null +++ b/txt2toot/txt/zefbdfberb.txt @@ -0,0 +1 @@ +Abusus enim multitudine hominum, quam tranquillis in rebus diutius rexit, ex agrestibus habitaculis urbes construxit multis opibus firmas et viribus, quarum ad praesens pleraeque licet Graecis nominibus appellentur, quae isdem ad arbitrium inposita sunt conditoris, primigenia tamen nomina non amittunt, quae eis Assyria lingua institutores veteres indiderunt. diff --git a/txt2toot/txt2toot.py b/txt2toot/txt2toot.py new file mode 100755 index 0000000..9266e34 --- /dev/null +++ b/txt2toot/txt2toot.py @@ -0,0 +1,117 @@ +#!/usr/bin/python3 +# coding: utf-8 +# -*- coding: utf-8 -*- + + +from mastodon import Mastodon +import os +import random +import sys +import argparse +from configparser import ConfigParser + +__prog_name__ = 'txt2toot' +__version__ = '0.1' +__description__ = 'Toot a random text file on Mastodon' + + +if __name__ == "__main__": + # Read arguments + parser = argparse.ArgumentParser(prog=__prog_name__, + description=__description__) + parser.add_argument('--version', action='version', version=__version__) + parser.add_argument('-d', '--dir', required=True, + help="Text file\'s directory") + parser.add_argument('-c', '--config', default='config.ini', + help="Config file (default: %(default)s)") + args = parser.parse_args() + config_filepath = args.config + + # Check if config file exists + if not os.path.isfile(config_filepath): + print("Config file %s not found, exiting." % config_filepath) + sys.exit(0) + else: + # Read config file + conf = ConfigParser() + conf.read(config_filepath) + + # Need a directory + if not args.dir: + print("Image\'s directory argument missing") + sys.exit(0) + txt_dir = args.dir + "/" + + # Overwrite default settings + if conf.has_option('toot', 'status'): + toot_status = conf['toot']['status'] + '\n' + else: + toot_status = '' + + if conf.has_option('toot', 'visibility'): + toot_visibility = conf['toot']['visibility'] + else: + toot_visibility = '' + + if conf.has_option('toot', 'sensitive'): + toot_sensitive = conf['toot']['sensitive'] + else: + toot_sensitive = False + + if conf.has_option('toot', 'spoiler'): + toot_spoiler = conf['toot']['spoiler'] + else: + toot_spoiler = None + + # Log into Mastodon if enabled in settings + mastodon_hostname = conf['mastodon']['mastodon_hostname'] + try: + mastodonAPI = Mastodon( + client_id=conf['mastodon']['client_id'], + client_secret=conf['mastodon']['client_secret'], + access_token=conf['mastodon']['access_token'], + api_base_url='https://' + mastodon_hostname + ) + masto_username = mastodonAPI.account_verify_credentials()['username'] + print ('[ OK ] Sucessfully authenticated on ' + mastodon_hostname + + ' as @' + masto_username) + except BaseException as e: + print ('[ERROR] Error while logging into Mastodon:', str(e)) + sys.exit(0) + + #Prepare media IDs + try: + mfile = random.choice(os.listdir(txt_dir)) + txt_byte = open(txt_dir + mfile, "r").read() + + print(type(txt_byte)) + + #TODO : améliorer avec prise en compte hashtag+txt + + txt_len = len(toot_status) + len(conf['toot']['hashtag']) + print(type(txt_len)) + txt_maxlen = 500 - txt_len + toot_status += txt_byte[:txt_maxlen] + + except BaseException as e: + print ('[ERROR] Error while reading text file : ' + str(e)) + sys.exit(0) + + # Post the toot + toot_status += '\n' + toot_status += conf['toot']['hashtag'] + try: + status = mastodonAPI.status_post( + status=toot_status, + in_reply_to_id=None, + media_ids=None, + sensitive=toot_sensitive, + visibility=toot_visibility, + spoiler_text=toot_spoiler + ) + print ( + '[ OK ] Posting this on Mastodon account with media attachment : ' + + status['url']) + except BaseException as e: + print ('[ERROR] Error while posting toot:' + str(e)) + sys.exit(0) \ No newline at end of file