MisskeyAPI/misskey/misskeyapi.py
2022-10-07 13:04:50 +02:00

607 líneas
16 KiB
Python

import requests
import pdb
class MisskeyAPI:
name = 'Python Wrapper for Misskey API'
__DEFAULT_TIMEOUT = 300
__SCOPE_SETS = [
'read:account',
'read:blocks',
'read:drive',
'read:favorites',
'read:following',
'read:messaging',
'read:mutes',
'read:notifications',
'read:reactions',
'read:pages',
'read:page-likes',
'read:user-groups',
'read:channels',
'read:gallery',
'read:gallery-likes',
'write:account',
'write:blocks',
'write:drive',
'write:following',
'write:messaging',
'write:mutes',
'write:notes',
'write:notifications',
'write:reactions',
'write:votes',
'write:pages',
'write:page-likes',
'write:user-groups',
'write:channels',
'write:gallery',
'write:gallery-likes'
]
def __init__(
self,
api_base_url = None,
callback = None,
permission = __SCOPE_SETS,
name: str = None,
request_timeout = __DEFAULT_TIMEOUT,
session = None,
):
self.api_base_url = api_base_url
if self.api_base_url == None:
raise WrapperError("A Misskey instance's URL is required!")
if self.api_base_url != None:
self.callback = f'{self.api_base_url}/callback'
self.permission = permission
self.request_timeout = request_timeout
self.__name = name
if session:
self.session = session
else:
self.session = requests.Session()
self.__request_timeout = request_timeout
###
# admin
###
def admin_silence_user(self, i=None, userId=None):
params = {
'i': i,
'userId': userId
}
endpoint = self.api_base_url + '/api/admin/silence-user'
response = self.__api_request(endpoint, params)
return response
def admin_suspend_user(self, i=None, userId=None):
params = {
'i': i,
'userId': userId
}
endpoint = self.api_base_url + '/api/admin/suspend-user'
response = self.__api_request(endpoint, params)
return response
def admin_unsilence_user(self, i=None, userId=None):
params = {
'i': i,
'userId': userId
}
endpoint = self.api_base_url + '/api/admin/unsilence-user'
response = self.__api_request(endpoint, params)
return response
def admin_unsuspend_user(self, i=None, userId=None):
params = {
'i': i,
'userId': userId
}
endpoint = self.api_base_url + '/api/admin/unsuspend-user'
response = self.__api_request(endpoint, params)
return response
def i(self, i=None):
params = {
'i': i
}
endpoint = self.api_base_url + '/api/i'
response = self.__api_request(endpoint, params)
return response
def i_notifications(self, i=None, limit=None, sinceId=None, untilId=None, following=False, unreadOnly=False, markAsRead=True, includeTypes=None, excludeTypes=None):
params = {
'i': i,
'limit': limit,
'sinceId': sinceId,
'untilId': untilId,
'following': following,
'unreadOnly': unreadOnly,
'markAsRead': markAsRead,
'includeTypes': includeTypes,
'excludeTypes': excludeTypes
}
endpoint = self.api_base_url + '/api/i/notifications'
response = self.__api_request(endpoint, params)
return response
def my_apps(self, i=None, limit=None, offset=0):
params = {
'i': i,
'limit': limit,
'offset': offset
}
endpoint = self.api_base_url + '/api/my/apps'
response = self.__api_request(endpoint, params)
return response
def app_create(self, name=None, description=None, permission=None, callbackUrl=None, session=None):
params = {
'name': name,
'description': description,
'permission': permission,
'callbackUrl': callbackUrl
}
try:
if session:
ret = session.post(self.api_base_url + '/api/app/create', json=params, timeout=self.request_timeout)
response = ret.json()
else:
response = requests.post(self.api_base_url + '/api/app/create', json=params, timeout=self.request_timeout)
except Exception as e:
raise MisskeyNetworkError("Could not complete request: %s" % e)
return response
def app_show(self, app_id=None, session=None):
params = {
'appId': app_id
}
try:
if session:
ret = session.post(self.api_base_url + '/api/app/show', json=params, timeout=self.request_timeout)
response = ret.json()
else:
response = requests.post(self.api_base_url + '/api/app/show', json=params, timeout=self.request_timeout)
#response = response.json()
except Exception as e:
raise MisskeyNetworkError("Could not complete request: %s" % e)
return response
def auth_accept(self, token=None):
params = {
'token': token,
}
endpoint = self.api_base_url + '/api/auth/accept'
response = self.__api_request(endpoint, params)
return response
def auth_session_generate(self, app_secret=None):
params = {
'appSecret': app_secret,
}
endpoint = self.api_base_url + '/api/auth/session/generate'
response = self.__api_request(endpoint, params)
return response
def auth_session_show(self, token=None):
params = {
'token': token
}
endpoint = self.api_base_url + '/api/auth/session/show'
response = self.__api_request(endpoint, params)
return response
def auth_session_userkey(self, app_secret=None, token=None):
params = {
'appSecret': app_secret,
'token': token
}
endpoint = self.api_base_url + '/api/auth/session/userkey'
response = self.__api_request(endpoint, params)
return response
def charts_federation(self, span=None, limit=None, offset=None):
params = {
'span': span,
'limit': limit,
'offset': None
}
endpoint = self.api_base_url + '/api/charts/federation'
response = self.__api_request(endpoint, params)
return response
def ap_get(self, i=None, uri=None):
params = {
'i': i,
'uri': uri
}
endpoint = self.api_base_url + '/api/ap/get'
response = self.__api_request(endpoint, params)
return response
def ap_show(self, i=None, uri=None):
params = {
'i': i,
'uri': uri
}
endpoint = self.api_base_url + '/api/ap/show'
response = self.__api_request(endpoint, params)
return response
def blocking_create(self, i=None, userId=None):
params = {
'i': i,
'userId': userId,
}
endpoint = self.api_base_url + '/api/blocking/create'
response = self.__api_request(endpoint, params)
return response
def blocking_delete(self, i=None, userId=None):
params = {
'i': i,
'userId': userId,
}
endpoint = self.api_base_url + '/api/blocking/delete'
response = self.__api_request(endpoint, params)
return response
def blocking_list(self, i=None, limit=None, sinceId=None, untilId=None):
params = {
'i': i,
'limit': limit,
'sinceId': sinceId,
'untilId': untilId
}
endpoint = self.api_base_url + '/api/blocking/list'
response = self.__api_request(endpoint, params)
return response
def federation_instances(self):
params = {
}
endpoint = self.api_base_url + '/api/federation/instances'
response = self.__api_request(endpoint, params)
return response
def federation_stats(self, limit=None):
params = {
'limit': limit
}
endpoint = self.api_base_url + '/api/federation/stats'
response = self.__api_request(endpoint, params)
return response
def endpoint(self, endpoint=None):
params = {
'endpoint': endpoint
}
endpoint = self.api_base_url + '/api/endpoint'
response = self.__api_request(endpoint, params)
return response
def endpoints(self):
params = {
}
endpoint = self.api_base_url + '/api/endpoints'
response = self.__api_request(endpoint, params)
return response
def serverinfo(self):
params = {
}
endpoint = self.api_base_url + '/api/server-info'
response = self.__api_request(endpoint, params)
return response
def stats(self):
params = {
}
endpoint = self.api_base_url + '/api/stats'
response = self.__api_request(endpoint, params)
return response
def notes_create(self, i=None, visibility=None, text=None, local_only=True):
params = {
'i': i,
'visibility': visibility,
'text': text,
'localOnly': local_only
}
endpoint = self.api_base_url + '/api/notes/create'
response = self.__api_request(endpoint, params)
return response
def notifications_create(self, i=None, body=None, header=None, icon=None):
params = {
'i': i,
'body': body,
'header': header,
'icon': icon
}
endpoint = self.api_base_url + '/api/notifications/create'
response = self.__api_request(endpoint, params)
return response
def notifications_read(self, i=None, notificationIds=[]):
params = {
'i': i,
'notificationIds': notificationIds
}
endpoint = self.api_base_url + '/api/notifications/read'
response = self.__api_request(endpoint, params)
return response
def users_groups_create(self, i=None, name=None):
params = {
'i': i,
'name': name
}
endpoint = self.api_base_url + '/api/users/groups/create'
response = self.__api_request(endpoint, params)
return response
def users_groups_delete(self, i=None, groupId=None):
params = {
'i': i,
'groupId': groupId
}
endpoint = self.api_base_url + '/api/users/groups/delete'
response = self.__api_request(endpoint, params)
return response
def __api_request(self, endpoint, params):
try:
response = requests.post(url = endpoint, json=params)
except Exception as e:
raise MisskeyNetworkError(f"Could not complete request: {e}")
if response is None:
raise MisskeyIllegalArgumentError("Illegal request.")
if not response.ok:
try:
if isinstance(response, dict) and 'error' in response:
error_msg = response['error']
elif isinstance(response, str):
error_msg = response
else:
error_msg = None
except ValueError:
error_msg = None
if response.status_code == 404:
ex_type = MisskeyNotFoundError
if not error_msg:
error_msg = 'Endpoint not found.'
# this is for compatibility with older versions
# which raised MisskeyAPIError('Endpoint not found.')
# on any 404
elif response.status_code == 400:
ex_type = MisskeyBadRequestError
if not error_msg:
error_msg = response.json()['error']['info']
elif response.status_code == 401:
ex_type = MisskeyUnauthorizedError
elif response.status_code == 500:
ex_type = MisskeyInternalServerError
elif response.status_code == 502:
ex_type = MisskeyBadGatewayError
elif response.status_code == 503:
ex_type = MisskeyServiceUnavailableError
elif response.status_code == 504:
ex_type = MisskeyGatewayTimeoutError
elif response.status_code >= 500 and \
response.status_code <= 511:
ex_type = MisskeyServerError
else:
ex_type = MisskeyAPIError
raise ex_type(
'Misskey API returned error',
response.status_code,
response.reason,
error_msg)
else:
return response
##
# Exceptions
##
class WrapperError(Exception):
"""Wrapper base class"""
class MisskeyBadRequestError(Exception):
"""Bad Request class"""
class MisskeyAPIConfigError(Exception):
"""This class exception"""
class MisskeyError(Exception):
"""Base class for MisskeyAPI exceptions"""
class MisskeyIllegalArgumentError(ValueError, MisskeyError):
"""Raised when an incorrect parameter is passed to a function"""
pass
class MisskeyIOError(IOError, MisskeyError):
"""Base class for MisskeyAPI I/O errors"""
class MisskeyNetworkError(MisskeyIOError):
"""Raised when network communication with the server fails"""
pass
class MisskeyReadTimeout(MisskeyNetworkError):
"""Raised when a stream times out"""
pass
class MisskeyAPIError(MisskeyError):
"""Raised when the Misskey API generates a response that cannot be handled"""
pass
class MisskeyServerError(MisskeyAPIError):
"""Raised if the Server is malconfigured and returns a 5xx error code"""
pass
class MisskeyInternalServerError(MisskeyServerError):
"""Raised if the Server returns a 500 error"""
pass
class MisskeyBadGatewayError(MisskeyServerError):
"""Raised if the Server returns a 502 error"""
pass
class MisskeyServiceUnavailableError(MisskeyServerError):
"""Raised if the Server returns a 503 error"""
pass
class MisskeyGatewayTimeoutError(MisskeyServerError):
"""Raised if the Server returns a 504 error"""
pass
class MisskeyNotFoundError(MisskeyAPIError):
"""Raised when the Misskey API returns a 404 Not Found error"""
pass
class MisskeyUnauthorizedError(MisskeyAPIError):
"""Raised when the Misskey API returns a 401 Unauthorized error
This happens when an OAuth token is invalid or has been revoked,
or when trying to access an endpoint that can't be used without
authentication without providing credentials."""
pass