diff --git a/compiler/error/__init__.py b/compiler/error/__init__.py new file mode 100644 index 00000000..b9ee0a98 --- /dev/null +++ b/compiler/error/__init__.py @@ -0,0 +1,17 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017 Dan Tès +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . diff --git a/compiler/error/compiler.py b/compiler/error/compiler.py new file mode 100644 index 00000000..49f3359b --- /dev/null +++ b/compiler/error/compiler.py @@ -0,0 +1,140 @@ +# Pyrogram - Telegram MTProto API Client Library for Python +# Copyright (C) 2017 Dan Tès +# +# This file is part of Pyrogram. +# +# Pyrogram is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Pyrogram is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with Pyrogram. If not, see . + +import csv +import os +import re +import shutil + +home = "compiler/error" +dest = "pyrogram/api/errors/exceptions" +notice_path = "NOTICE" + + +def snek(s): + # https://stackoverflow.com/questions/1175208/elegant-python-function-to-convert-camelcase-to-snake-case + s = re.sub(r"(.)([A-Z][a-z]+)", r"\1_\2", s) + return re.sub(r"([a-z0-9])([A-Z])", r"\1_\2", s).lower() + + +def caml(s): + s = snek(s).split("_") + return "".join([str(i.title()) for i in s]) + + +def start(): + shutil.rmtree(dest, ignore_errors=True) + os.makedirs(dest) + + files = [i for i in os.listdir("{}/source".format(home))] + + with open(notice_path) as f: + notice = [] + + for line in f.readlines(): + notice.append("# {}".format(line).strip()) + + notice = "\n".join(notice) + + with open("{}/all.py".format(dest), "w") as f_all: + f_all.write(notice + "\n\n") + f_all.write("count = {count}\n\n") + f_all.write("exceptions = {\n") + + count = 0 + + for i in files: + code, name = re.search(r"(\d+)_([A-Z_]+)", i).groups() + + f_all.write(" {}: {{\n".format(code)) + + init = "{}/__init__.py".format(dest) + + if not os.path.exists(init): + with open(init, "w") as f_init: + f_init.write(notice + "\n\n") + + with open(init, "a") as f_init: + f_init.write("from .{}_{} import *\n".format(name.lower(), code)) + + with open("{}/source/{}".format(home, i)) as f_csv, \ + open("{}/{}_{}.py".format(dest, name.lower(), code), "w") as f_class: + reader = csv.reader(f_csv, delimiter="\t") + + super_class = caml(name) + name = " ".join([str(i.capitalize()) for i in re.sub(r"_", " ", name).lower().split(" ")]) + + sub_classes = [] + + for j, row in enumerate(reader): + if j == 0: + continue + + count += 1 + + if not row: # Row is empty (blank line) + continue + + id, message = row + + sub_class = caml(re.sub(r"_X", "_", id)) + + f_all.write(" \"{}\": \"{}\",\n".format(id, sub_class)) + + sub_classes.append((sub_class, id, message)) + + with open("{}/template/class.txt".format(home), "r") as f_class_template: + class_template = f_class_template.read() + + with open("{}/template/sub_class.txt".format(home), "r") as f_sub_class_template: + sub_class_template = f_sub_class_template.read() + + class_template = class_template.format( + notice=notice, + super_class=super_class, + code=code, + name="\"{}\"".format(name), + sub_classes="".join([sub_class_template.format( + sub_class=k[0], + super_class=super_class, + id="\"{}\"".format(k[1]), + message="\"{}\"".format(k[2]) + ) for k in sub_classes]) + ) + + f_class.write(class_template) + + f_all.write(" },\n") + + f_all.write("}\n") + + with open("{}/all.py".format(dest)) as f: + content = f.read() + + with open("{}/all.py".format(dest), "w") as f: + f.write(re.sub("{count}", str(count), content)) + + print("Compiling Errors: [100%]") + + +if "__main__" == __name__: + home = "." + dest = "../../pyrogram/api/errors/exceptions" + notice_path = "../../NOTICE" + + start() diff --git a/compiler/error/source/303_SEE_OTHER.csv b/compiler/error/source/303_SEE_OTHER.csv new file mode 100644 index 00000000..da3ac18d --- /dev/null +++ b/compiler/error/source/303_SEE_OTHER.csv @@ -0,0 +1,5 @@ +id message +FILE_MIGRATE_X The file to be accessed is currently stored in DC{x} +PHONE_MIGRATE_X The phone number a user is trying to use for authorization is associated with DC{x} +NETWORK_MIGRATE_X The source IP address is associated with DC{x} (for registration) +USER_MIGRATE_X The user whose identity is being used to execute queries is associated with DC{x} (for registration) diff --git a/compiler/error/source/400_BAD_REQUEST.csv b/compiler/error/source/400_BAD_REQUEST.csv new file mode 100644 index 00000000..dd82491d --- /dev/null +++ b/compiler/error/source/400_BAD_REQUEST.csv @@ -0,0 +1,29 @@ +id message +FIRSTNAME_INVALID The first name is invalid +LASTNAME_INVALID The last name is invalid +PHONE_NUMBER_INVALID The phone number is invalid +PHONE_CODE_HASH_EMPTY phone_code_hash is missing +PHONE_CODE_EMPTY phone_code is missing +PHONE_CODE_EXPIRED The confirmation code has expired +PHONE_CODE_INVALID The confirmation code is invalid +API_ID_INVALID The api_id/api_hash combination is invalid +PHONE_NUMBER_OCCUPIED The phone number is already in use +PHONE_NUMBER_UNOCCUPIED The phone number is not yet being used +USERS_TOO_FEW Not enough users (to create a chat, for example) +USERS_TOO_MUCH The maximum number of users has been exceeded (to create a chat, for example) +TYPE_CONSTRUCTOR_INVALID The type constructor is invalid +FILE_PART_INVALID The file part number is invalid +FILE_PARTS_INVALID The number of file parts is invalid +FILE_PART_X_MISSING Part {x} of the file is missing from storage +MD5_CHECKSUM_INVALID The MD5 checksums do not match +PHOTO_INVALID_DIMENSIONS The photo dimensions are invalid +FIELD_NAME_INVALID The field with the name FIELD_NAME is invalid +FIELD_NAME_EMPTY The field with the name FIELD_NAME is missing +MSG_WAIT_FAILED A waiting call returned an error +PEER_ID_INVALID The id/access_hash combination is invalid +MESSAGE_EMPTY The message sent is empty +ENCRYPTED_MESSAGE_INVALID The special binding message (bind_auth_key_inner) contains invalid data +INPUT_METHOD_INVALID The method called is invalid +PASSWORD_HASH_INVALID Two-step verification password is invalid +USERNAME_NOT_OCCUPIED The username is not occupied by anyone +USERNAME_INVALID The username is invalid diff --git a/compiler/error/source/401_UNAUTHORIZED.csv b/compiler/error/source/401_UNAUTHORIZED.csv new file mode 100644 index 00000000..54b24dd7 --- /dev/null +++ b/compiler/error/source/401_UNAUTHORIZED.csv @@ -0,0 +1,9 @@ +id message +AUTH_KEY_UNREGISTERED The key is not registered in the system +AUTH_KEY_INVALID The key is invalid +USER_DEACTIVATED The user has been deleted/deactivated +SESSION_REVOKED The authorization has been invalidated, because of the user terminating all sessions +SESSION_EXPIRED The authorization has expired +ACTIVE_USER_REQUIRED The method is only available to already activated users +AUTH_KEY_PERM_EMPTY The method is unavailable for temporary authorization key, not bound to permanent +SESSION_PASSWORD_NEEDED Two-step verification password required diff --git a/compiler/error/source/420_FLOOD.csv b/compiler/error/source/420_FLOOD.csv new file mode 100644 index 00000000..bf404156 --- /dev/null +++ b/compiler/error/source/420_FLOOD.csv @@ -0,0 +1,2 @@ +id message +FLOOD_WAIT_X A wait of {x} seconds is required diff --git a/compiler/error/source/500_INTERNAL_SERVER_ERROR.csv b/compiler/error/source/500_INTERNAL_SERVER_ERROR.csv new file mode 100644 index 00000000..4ee4f042 --- /dev/null +++ b/compiler/error/source/500_INTERNAL_SERVER_ERROR.csv @@ -0,0 +1,2 @@ +id message +AUTH_RESTART User authorization has restarted diff --git a/compiler/error/template/class.txt b/compiler/error/template/class.txt new file mode 100644 index 00000000..0c729eb7 --- /dev/null +++ b/compiler/error/template/class.txt @@ -0,0 +1,11 @@ +{notice} + +from ..error import Error + + +class {super_class}(Error): + CODE = {code} + NAME = {name} + + +{sub_classes} \ No newline at end of file diff --git a/compiler/error/template/sub_class.txt b/compiler/error/template/sub_class.txt new file mode 100644 index 00000000..bc163407 --- /dev/null +++ b/compiler/error/template/sub_class.txt @@ -0,0 +1,5 @@ +class {sub_class}({super_class}): + ID = {id} + MESSAGE = {message} + +