#!/usr/bin/python3 import requests # Для отправки http-запросов import json import time import argparse import logging as log p = argparse.ArgumentParser() p.add_argument('--verbose', '-v', action='count', default=0) args = p.parse_args() if args.verbose: log.basicConfig(format="%(levelname)s: %(message)s", level=log.DEBUG) log.info("Verbose output.") else: log.basicConfig(format="%(levelname)s: %(message)s") #log.info("This should be verbose.") #log.warning("This is a warning.") #log.error("This is an error.") # Функция для чтения JSON-файла (например, конфига), аргумент - адрес файла в ФС # Возвращает словарь def json_read(file): # Создается локальное окружение (или как эта хуйня зовется), где присутствует дескриптор для нашего файла #log.info("Reading config file:", file) with open(file) as f: config = json.load(f) return config # Функция для получения уведомлений пользователя из Misskey # Возвращает список словарей def get_notifications(url, i, includeTypes=["follow", "mention", "reply", "renote", "quote", "reaction", "pollVote", "receiveFollowRequest", "followRequestAccepted", "groupInvited","app"], markAsRead=True): log.info("Getting notifications from", url) # Формируем URL для доступа к конкретной функции API req_url = url + "/api/i/notifications" body = { "i": i, # Можно включить лишь определенные уведомления, всю эту залупу следует вынести также в аргументы функции, чтоб реагировать на конкретные события, типа подписки или упоминания, по-разному "includeTypes": includeTypes, # Количество уведомлений, которые вытянем "limit": 3, "unreadOnly": False, "markAsRead": markAsRead, } # Отправляем запрос, в тело запроса суем словарь-JSON, которые объявили выше r = requests.post(req_url, json=body) # Если все прошло збс, код HTTP 200, то отдаем получанный список уведомлений if r.status_code == 200: # Можешь раскомментить, глянуть, что это за черт #print(r.json()) return r.json() # Иначе, если не збс, то ругаемся else: print("Fuck") # Функция, создающая пост # 2do: посты с картинками, ... def create_post(url, i, content="", visibility="public", channel="", fileIds=[], renote=False, renoteId=None): print("Post to", url, ":", content) # Аналогично, адрес нужной функции API req_url = url + "/api/notes/create" if renote: body = { "renoteId": renoteId, "i": i } else: body = { # Не ебу, что за noExtract*, надо полуркать, но работает и збс пока что "noExtractMentions": True, "noExtractHashtags": True, "noExtractEmojis": True, "visibility": visibility, "text": content, #"fileIds": fileIds, # Если поставлен канал, то пост только локальный для инстанса "localOnly": channel != "", "i": i } if channel != "": body["channelId"] = channel # Отправляем запрос r = requests.post(req_url, json=body) # Аналогично, проверка на 200, в случае успеха 1 if r.status_code == 200: return 0 else: print("Failed to post:", r.text) return 1 # Пока что можешь не пытаться разобраться, я сам отчасти хз, как это работает, лол def file_upload(file, url, i, isSensitive=False): print("Uploading file to", url) req_url = url + "/api/drive/files/create" with open(file, "rb") as f: fileo = f.read() body = { "isSensitive": False, "force": True, "i":i } body = json.dumps(body) payload = {'json_payload': body, 'i': i } files = {"file": (file, fileo)} r = requests.post(req_url, data=payload, files=files) if r.status_code == 200: return r.json() else: print("Upload failed with code", r.status_code) print(r.text) def get_file_list(url, i): req_url = url + "/api/drive/files" r = requests.post(req_url, json={"i":i}) print(r.json()) ### Сюда надо захуярить еще 100500 функций### # Собсна, содержательная часть программы начинается тут # Читаем конфиг, получаем словарь config = json_read('config.json') create_post(config['url'], config['token'], renote=True, renoteId="8vxi115z0g")