diff --git a/create_app.py b/create_app.py
new file mode 100755
index 0000000..eb709f5
--- /dev/null
+++ b/create_app.py
@@ -0,0 +1,154 @@
+#! /usr/bin/env python3
+
+# CreatePleromaApp, a python script to generate OAuth tokens for fedi
+# Copyright (C) 2024 Anon <@Anon@yandere.cc>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import getpass
+import os
+import re
+import sys
+import argparse
+from mastodon import Mastodon, MastodonIllegalArgumentError, MastodonAPIError, MastodonIOError
+
+
+class CreateAppError(Exception):
+ pass
+
+
+# Modify this section to suit your default preferances
+def default(key):
+ defaults={
+ "app": "app",
+ "domain": "https://yandere.cc",
+ "scopes": "write",
+ }
+ return defaults[key]
+
+
+def printerr(s, end=None):
+ print(s, file=sys.stderr, end=end if end != None else os.linesep)
+
+def inputerr(q):
+ sys.stdout.flush()
+ sys.stderr.flush()
+ printerr(q, end="")
+ return input()
+
+# Function to format user input consistently with lables
+def _input(lable, ans=""):
+ if ans:
+ q = "{} (Default: {}): ".format(
+ lable, ans)
+ return inputerr(q) or ans
+ else:
+ q = "{}: ".format(lable)
+ return inputerr(q)
+
+
+def get_client_id_and_secret(app, permissions, domain):
+ try:
+ return Mastodon.create_app(app, scopes=permissions, api_base_url=domain)
+ except MastodonIOError:
+ raise CreateAppError("An error occurred. Make sure the domain name is correct.")
+
+
+def get_api(client_id, client_secret, domain):
+ api = Mastodon(
+ client_id,
+ client_secret,
+ api_base_url=domain,
+ feature_set="pleroma"
+ )
+ return api
+
+
+def get_token(api, email, password, permissions):
+ try:
+ token = api.log_in(email, password, scopes=permissions)
+ return token
+ except MastodonIllegalArgumentError:
+ raise CreateAppError("Username or Password is incorrect.")
+ except MastodonAPIError:
+ raise CreateAppError("Could not grant scopes:", ", ".join(permissions))
+
+
+def main():
+ # Parser
+ parser = argparse.ArgumentParser(
+ description="A script to generate OAuth tokens for fedi",
+ epilog="",
+ add_help=True)
+ _ = parser.parse_args()
+
+ try:
+ # Settings Dictionary
+ settings = {}
+
+ # Create App
+ printerr("Generate and register Mastodon App")
+ printerr("You can just hit enter to accept the default for prompts that have them")
+ printerr("Ctrl+C to Quit\n")
+
+ # Get instance information
+ app_name = _input("Enter your app name", default("app"))
+ settings["API_BASE_URL"] = _input("URL of Instance", default("domain"))
+ email = _input("Enter your email")
+ password = getpass.getpass("Enter password: ")
+ printerr("Scopes: read, write, follow, push")
+ printerr("Separate each scope with a comma (example above).")
+ printerr("!!! Accept the default unless you intend to modify Yandere Lewd Bot !!!")
+ ans = _input("Scopes", default("scopes"))
+ ans = re.sub(r"\s+", "", ans, flags=re.UNICODE)
+ permissions = ans.split(",")
+ printerr("Granting: {}".format(str(permissions)))
+
+ # Begin logging in
+ settings["CLIENT_ID"], settings["CLIENT_SECRET"] =\
+ get_client_id_and_secret(
+ app_name,
+ permissions,
+ settings["API_BASE_URL"]
+ )
+ api = get_api(
+ settings["CLIENT_ID"],
+ settings["CLIENT_SECRET"],
+ settings["API_BASE_URL"]
+ )
+
+ settings["ACCESS_TOKEN"] = get_token(api, email, password, permissions)
+
+ # Output the user's new credentials
+ for k, v in settings.items():
+ v = settings[k]
+ print("{}={}".format(k, v))
+
+ printerr("Success :)")
+ return 0
+ except (KeyboardInterrupt, EOFError):
+ printerr("\nUser Quit :|")
+ return 1
+ except CreateAppError as e:
+ printerr(e)
+ printerr("Error :(")
+ return 2
+ except Exception as e:
+ printerr(e)
+ printerr("Unhandled Exception ¯\\_(ツ)_/¯")
+ return 3
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index f9fc8bb..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Mastodon.py
-cryptography
\ No newline at end of file
diff --git a/run.sh b/run.sh
index c77a466..e381ef3 100755
--- a/run.sh
+++ b/run.sh
@@ -1,7 +1,7 @@
#! /usr/bin/env bash
-# Create Pleroma App, automate the creation of pleroma apps
-# Copyright (C) 2022 Anon <@Anon@yandere.cc>
+# CreatePleromaApp, a python script to generate OAuth tokens for fedi
+# Copyright (C) 2024 Anon <@Anon@yandere.cc>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -21,8 +21,8 @@ ABS_PATH="$(readlink -f "$0")"
RUN_DIR="$(dirname "$ABS_PATH")"
# Relative paths to the virtual environment and main.py
-VENV='./venv/bin/activate'
-ENTRY='./src/create_app.py'
+VENV='${RUN_DIR}/venv/bin/activate'
+ENTRY='${RUN_DIR}/create_app.py'
# cd into the bot's root path, set up the virtual environment, and run
cd "$RUN_DIR"
diff --git a/src/create_app.py b/src/create_app.py
deleted file mode 100755
index 646f875..0000000
--- a/src/create_app.py
+++ /dev/null
@@ -1,216 +0,0 @@
-#! /usr/bin/env python3
-
-# Create Pleroma App, a python script to generate OAuth tokens for fedi
-# Copyright (C) 2022 Anon <@Anon@yandere.cc>
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program 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 General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-import getpass
-import re
-import sys
-import datetime
-import argparse
-import contextlib
-import os
-from pprint import pformat
-from mastodon import Mastodon, MastodonIllegalArgumentError, MastodonAPIError, MastodonIOError
-from collections import OrderedDict
-
-
-class CreateAppError(Exception):
- pass
-
-
-# Modify this section to suit your default preferances
-def default(key):
- defaults={
- "app": "app",
- "domain": "https://yandere.cc",
- "scopes": "write",
- "encrypt": "y",
- "cfg": None,
- "long_date_format": "%m/%d/%Y %I:%M%p"
- }
- return defaults[key]
-
-
-# Function to format user input consistently with lables
-def _input(lable, ans=None):
- if ans:
- q = "{} (Default: {}): ".format(
- lable, ans)
- return input(q) or ans
- else:
- q = "{}: ".format(lable)
- return input(q)
-
-
-def get_client_id_and_secret(app, permissions, domain):
- try:
- return Mastodon.create_app(app, scopes=permissions, api_base_url=domain)
- except MastodonIOError:
- raise CreateAppError("An error occurred. Make sure the domain name is correct.")
-
-
-def get_api(client_id, client_secret, domain):
- api = Mastodon(client_id, client_secret, api_base_url=domain)
- return api
-
-
-def get_token(api, email, password, permissions):
- try:
- token = api.log_in(email, password, scopes=permissions)
- return token
- except MastodonIllegalArgumentError:
- raise CreateAppError("Username or Password is incorrect.")
- except MastodonAPIError:
- raise CreateAppError("Could not grant scopes:", ", ".join(permissions))
-
-
-def get_cfg(cfg_name):
- try:
- import importlib
- cfg = importlib.import_module(cfg_name)
- return cfg
- except ImportError:
- raise CreateAppError("Cannot import module:", cfg_name, "Make sure you omitted the .py extension and try again")
-
-
-def package_settings(app, domain, client_id, client_secret, token):
- settings_server = OrderedDict([
- ("app_name", app),
- ("api_base_url", domain),
- ("client_id", client_id),
- ("client_secret", client_secret),
- ("access_token", token)
- ])
- return settings_server
-
-
-def get_setting_reminder(fmt):
- dt_now = datetime.datetime.now()
- dt_now = dt_now.replace(year=dt_now.year + 1)
- settings_reminder = dt_now.strftime(fmt)
- return settings_reminder
-
-
-def credentials_py(label, setting):
- return "{} = {}".format(label, pformat(setting))
-
-
-def credentials_ini(label, setting):
- r = "[{}]".format(label)
- for k, v in setting.items():
- r += "\n{}={}".format(k, v)
- return r
-
-
-def main():
- # Default time localization
- long_date_format = default("long_date_format")
-
- # Parser
- parser = argparse.ArgumentParser(
- description="A script to generate OAuth tokens for fedi",
- epilog="",
- add_help=True)
- parser.add_argument("-c", "--config", help="Use time localization settings from a pyhton config file (omit the .py extension)", default=None)
- parser.add_argument("-k", "--keyfile", help="Keyfile used for decryption", default=None)
- parser.add_argument("--plain", help="Output credentials in plain ini format", action="store_true")
- parser.add_argument("--minimal", help="Only print OAuth credentials, ignoring encryption settings", action="store_true")
- arguments = parser.parse_args()
-
- try:
- # Custom time localization
- # This is mainly intended to be used with bots configured with python files
- # This python file should contain the following dictionary with a key value pair of:
- # settings_time = {"long_date_format": "%m/%d/%Y %I:%M%p"}
- load_config = arguments.config or default("cfg")
- if load_config:
- cfg = get_cfg(load_config)
- long_date_format = cfg.settings_time["long_date_format"]
-
- # Create App
- print("Generate and register Mastodon App")
- print("You can just hit enter to accept the default for prompts that have them")
- print("Ctrl+C to Quit\n")
-
- # Get instance information
- app = _input("Enter your app name", default("app"))
- domain = _input("URL of Instance", default("domain"))
- email = _input("Enter your email")
- password = getpass.getpass("Enter password: ")
- print("Scopes: read, write, follow, push")
- print("Separate each scope with a comma (example above).")
- print("!!! Accept the default unless you intend to modify Yandere Lewd Bot !!!")
- ans = _input("Scopes", default("scopes"))
- ans = re.sub(r"\s+", "", ans, flags=re.UNICODE)
- permissions = ans.split(",")
- print("Granting:", permissions)
-
- # Begin logging in
- client_id, client_secret = get_client_id_and_secret(app, permissions, domain)
- api = get_api(client_id, client_secret, domain)
- token = get_token(api, email, password, permissions)
-
- # Credentials (unencrypted)
- encrypt, salt = False, ""
- settings_server = package_settings(app, domain, client_id, client_secret, token)
- reminder = get_setting_reminder(long_date_format)
-
- # Encrypt
- if not arguments.minimal:
- with contextlib.suppress(ImportError):
- import FediBotEncryption
- ans = _input("Do you want to encrypt your credentials? (y/n)", default("encrypt"))
- if ans.upper() in ("Y", "YES"):
- encrypt = True
- salt, settings_server = FediBotEncryption.settings_server_encrypt(settings_server, arguments.keyfile)
-
- settings_encrypt = OrderedDict([
- ("encrypt", encrypt),
- ("salt", salt),
- ("keyfile", arguments.keyfile)
- ])
- settings_reminder = OrderedDict([
- ("settings_reminder", reminder)
- ])
-
- # Credential formatting functions
- formatted_credentials = credentials_ini if arguments.plain else credentials_py
-
- # Output the user's new credentials
- print("Copy to your config file!!!")
- print(formatted_credentials("settings_server", settings_server))
- if not arguments.minimal:
- print("\n{}\n".format(formatted_credentials("settings_reminder", settings_reminder)))
- print(formatted_credentials("settings_encrypt", settings_encrypt))
-
- print("Success :)")
- return 0
- except (KeyboardInterrupt, EOFError):
- print("User Quit :|")
- return 1
- except CreateAppError as e:
- print(e)
- print("Error :(")
- return 2
- except Exception as e:
- print(e)
- print("Unhandled Exception ¯\\_(ツ)_/¯")
- return 3
-
-
-if __name__ == "__main__":
- sys.exit(main())