class Main(object): '''Main class''' def __init__(self): '''Constructor of the Main class''' # parse the command line rtargs = CliParse() self.args = rtargs.arguments # read the configuration file cfgparse = ConfParse(self.args.pathtoconf) self.cfgvalues = cfgparse.confvalues self.twp = TootWasPosted(self.cfgvalues) # activate the mastodon api self.api = Mastodon(client_id=self.cfgvalues['clientcred'], access_token=self.cfgvalues['usercred'], api_base_url=self.cfgvalues['instanceurl']) self.main() def main(self): '''Main of the Main class''' for user in self.cfgvalues['userstoboost']: lasttoots = self.api.account_statuses( self.api.account_search(user, limit=1)[0]['id']) lasttoots.reverse() if self.args.limit: lasttoots = lasttoots[(len(lasttoots) - self.args.limit):] tootstosend = [] # test if the last 20 toots were posted for lasttoot in lasttoots: if not self.twp.wasposted(lasttoot['id']): Validate(self.cfgvalues, self.args, self.api, lasttoot) sys.exit(0)
def main(): ''' メインルーチン ''' # Mastodon初期化 mastodon = Mastodon(client_id=CID_FILE, access_token=TOKEN_FILE, api_base_url=URL) # 対象アカウントのユーザーIDを取得する。 user_list = mastodon.account_search(USERNAME, limit=1) user_id = user_list[0]['id'] # 対象アカウントの最新トゥート10件を取得する user_toots = mastodon.account_statuses(user_id, limit=1) # トゥートのアプリ名があれば表示する if user_toots[0]['reblog'] is None: print(check_appname(user_toots[0])) # 通常のトゥートの場合 else: print(check_appname(user_toots[0]['reblog'])) # ブーストされたトゥートの場合
from mastodon import Mastodon import pyperclip from datetime import datetime, timezone, timedelta import yaml config = yaml.safe_load(open("./config.yml")) mastodon = Mastodon(client_id=config['mastodon']['client_id'], client_secret=config['mastodon']['client_secret'], access_token=config['mastodon']['access_token'], api_base_url=config['mastodon']['api_base_url']) one_week_ago = datetime.now(timezone.utc) - timedelta(days=8) account = mastodon.account_search(q=config['mastodon']['account_query'], limit=1) def get_toots(max_id=None): toots = [] for toot in mastodon.account_statuses(account[0].id, max_id=max_id): if toot.created_at > one_week_ago: toots.append(toot) max_id = toot.id else: max_id = None if (max_id != None): toots = toots + get_toots(max_id)
runparams['instance'] = INSTANCE ## Create actual instance mastodon = Mastodon( client_id = '.pytooter_clientcred.txt', access_token = '.pytooter_usercred.txt', api_base_url=INSTANCE ) if 'runcount' not in runparams: runparams['runcount'] = 1 else: runparams['runcount']+=1 if 'my_id' not in runparams: my_id = mastodon.account_search(runparams['botname'])[0]['id'] runparams['my_id'] = my_id else: my_id = runparams['my_id'] if DEBUG: print('Found my id %i' % my_id) my_followed = mastodon.account_following(my_id) my_followed_list=[my_id] total_followed=0 for user in my_followed: if 'id' in user: my_followed_list.append(user['id']) total_followed+=1
from mastodon import Mastodon url = sys.argv[1] cid_file = 'client_id.txt' token_file = 'access_token.txt' username = '******' mastodon = Mastodon(client_id=cid_file, access_token=token_file, api_base_url=url) # 対象アカウントのユーザーIDを取得する。 user_list = mastodon.account_search(username, limit=1) user_id = user_list[0]['id'] # 対象アカウントのフォロー数を表示する。 user_dict = mastodon.account(user_id) print(user_dict['following_count'])
class App(): def __init__(self): self.mastodon = Mastodon( api_base_url=os.environ["BASE_URL"], client_id=os.environ["OAUTH_CLIENT_ID"], client_secret=os.environ["OAUTH_CLIENT_SECRET"], access_token=os.environ["OAUTH_ACCESS_TOKEN"], ) def run(self): self.ws = WebSocketApp( self.mastodon.api_base_url.replace("https", "wss").replace("http", "ws") \ + "/api/v1/streaming/" + "?access_token=%s&stream=public" % self.mastodon.access_token, on_error = self.on_error, on_message = self.on_message, on_close = self.on_close ) self.ws.run_forever() def follow(self, account): try: if account["locked"] or "#dnf" in account["note"].lower(): logging.info("Account %s is locked or has #dnf in their note" % account["acct"]) return except KeyError: pass user = user_table.find_one({"uid": account["id"]}) if user: logging.info("Already following or told not to follow %s" % account["acct"]) return self.mastodon.account_follow(account["id"]) logging.info("Now following %s" % account["acct"]) user_table.insert({ "acct": account["acct"], "uid": account["id"], "following": True }) def on_error(self, ws, error): pass # print(error) def on_message(self, ws, message): event_data = json.loads(message) payload_data = json.loads(event_data["payload"]) # print("Event: %s" % event_data["event"]) # pprint(payload_data) if event_data["event"] == "update": self.follow(payload_data["account"]) for account in payload_data["mentions"]: # Get all the account info accts = self.mastodon.account_search(account["acct"]) if len(accts) == 0: self.follow(account) else: self.follow(accts[0]) def on_close(self, ws): print("WS CLOSED")
mastodon = Mastodon(client_id='.pytooter_clientcred.txt', api_base_url=INSTANCE) mastodon.log_in(username, password, to_file='.pytooter_usercred.txt') ## Create actual instance mastodon = Mastodon(client_id='.pytooter_clientcred.txt', access_token='.pytooter_usercred.txt', api_base_url=INSTANCE) if os.path.exists('.Autofollow.state.json'): with open('.Autofollow.state.json', 'r') as file: runparams = json.load(file) else: runparams = {'since_id': 0} my_id = mastodon.account_search('@followbot')[0]['id'] if DEBUG: print('Found my id %i' % my_id) my_followed = mastodon.account_following(my_id) my_followed_list = [my_id] total_followed = 0 for user in my_followed: my_followed_list.append(user['id']) total_followed += 1 if DEBUG: print('I am currently already following %i persons' % total_followed) toots = mastodon.timeline_public(since_id=runparams['since_id'])
if __name__ == '__main__': args = get_args() # ハッシュタグ指定かユーザID指定のどちらか一方だけ。両方指定されたらハッシュタグ優先 if args.hashtag: terms_for_dirname = args.hashtag.split(",") terms_for_search = args.hashtag.split(",") func = mastodon.timeline_hashtag elif args.acct: terms_for_dirname = args.acct.split(",") terms_for_search = [] # ID を username へ for acct in terms_for_dirname: sleep(2) users = mastodon.account_search(acct) # pp(users) for user in users: if user['acct'] == acct: terms_for_search.append(user["id"]) break func = mastodon.account_statuses else: exit() for dirname, term in zip(terms_for_dirname, terms_for_search): save_dir = os.path.join(SAVE_DIR, dirname) os.makedirs(save_dir, exist_ok=True) max_id = None
class YGGProvider(Interface): def __init__(self, **options): self.load_config(options) with app.app_context(): super().__init__("ygg", subdomain=self.config["subdomain"], url_prefix="/ygg") self.init_scraper() self.init_masto() self.tracker_url = None timing = options["update_tld_period"] if timing > 0: Timer(timing, self.update_domain).start() # app.add_url_rule("/provider/ygg/torrent/<int:id>", view_func=self.download_torrent) def init_scraper(self): self.scraper = YggTorrentScraper(create_cfhandler()) key = app.get_key(self.config["keyname"]) if key: login, _, password = key.partition(":") if not self.scraper.login(login, password): raise RuntimeWarning(f"could not loggin to yggtorrent") else: raise RuntimeWarning("ygg key file do not exist") def init_masto(self): token = app.get_key(self.config["masto_keyname"]) self.masto = Mastodon(api_base_url=self.config["masto_url"], access_token=token) self.update_domain() def convert_options(self, options): media_type = options.get("type") table = { "movie": ("films_&_videos", ("film", "animation")), "show": ("films_&_videos", ("emission_tv", "serie_tv")), "game": ("jeux_video", options.get("platform", ())) } entry = table.get(media_type, None) if entry is not None: options["category"], options["subcategory"] = entry return options def gen_torrent_url(self, torrent): return "/provider/ygg/torrent" + torrent.url.partition("id=")[2] def convert_to_content(self, torrent): return { "provider": "ygg", "type": "torrent", "name": torrent.name, "size": torrent.size, "uri": self.gen_torrent_url(torrent), "data": { "uploaded": torrent.uploaded_datetime.strftime("%Y-%m-%d"), "completed": torrent.completed, "seeders": torrent.seeders, "leechers": torrent.leechers } } def get_max_torrent(self, options): n = options.get("max_content", None) if n is not None and n.isdigit(): return int(n) return self.config["max_torrent"] def query_content(self, details, options): options = self.convert_options(options) release_year = " " + details["release_date"].split("-")[0] options.update(name=details["title"] + release_year) torrents = self.scraper.search(options) if self.config["search_with_original_title"]: options.update(name=details["original_title"] + release_year) torrents.extend(self.scraper.search(options)) for _, torrent in zip(range(self.get_max_torrent(options)), torrents): torrent_details = self.scraper.extract_details(torrent) yield self.convert_to_content(torrent_details) @route("/torrent/<int:id>") def get_torrent(self, id): url = f"{make_ygg_url()}/engine/download_torrent?id={id}" response = self.scraper.session.get(url) return torrent_parser.decode(response.content) def exchange_url(self, url): self.tracker_url = url try: data = self.get_torrent(randint(1000, 5000)) except Exception as e: logging.error(e) else: return data["announce"] def spoof_torrent(self, id): data = self.get_torrent(id) if self.tracker_url is None: from . import tracker self.tracker_url = tracker.exchange_url(data["announce"]) data["announce"] = self.tracker_url return torrent_parser.encode(data) def download_torrent(self, id): try: data = self.spoof_torrent(id) except Exception as e: logging.error(e) return abort(status.INTERNAL_SERVER_ERROR) return Response(data, mimetype="application/x-bittorrent") def load_config(self, options): options.setdefault("masto_url", "https://mamot.fr/") options.setdefault("account_id", "*****@*****.**") options.setdefault("masto_keyname", "masto") options.setdefault("tld_pattern", r"[^\.]+\.yggtorrent\.([^/\"]+)") options.setdefault("update_tld_period", "10:00:00") # every 10 hours options.setdefault("keyname", "ygg") options.setdefault("search_with_original_title", True) options.setdefault("max_torrent", 4) options.setdefault("subdomain", openflix_config.API_SUBDOMAIN) if type(options["update_tld_period"]) == str: period = options["update_tld_period"] options["update_tld_period"] = t_to_sec(period) self.config = options @expose def update_domain(self): accounts = self.masto.account_search(self.config["account_id"]) for account in accounts: website = get_first_occ(account.fields, "Website") if website: match = re.search(self.config["tld_pattern"], website.value) if match: set_yggtorrent_tld(match.group(1)) @expose def set_ygg_tld(self, tld): set_yggtorrent_tld(tld) @expose def get_ygg_tld(self, type, id): return get_yggtorrent_tld()