mirror of https://github.com/coddrago/Heroku
Drop heroku support, remove redundant code, remake badge and installer
parent
d794520826
commit
dfb8473685
|
@ -38,22 +38,7 @@ def _safe_input(*args, **kwargs):
|
|||
try:
|
||||
return input(*args, **kwargs)
|
||||
except (EOFError, OSError):
|
||||
print()
|
||||
print("=" * 30)
|
||||
print(
|
||||
"""
|
||||
Hello. If you are seeing this, it means YOU ARE DOING SOMETHING WRONG!
|
||||
It is likely that you tried to deploy to heroku - you cannot do this via the web interface.
|
||||
To deploy to heroku, go to https://friendly-telegram.gitlab.io/heroku to learn more
|
||||
|
||||
If you're not using heroku, then you are using a non-interactive prompt but
|
||||
you have not got a session configured, meaning authentication to Telegram is impossible.
|
||||
|
||||
THIS ERROR IS YOUR FAULT. DO NOT REPORT IT AS A BUG!
|
||||
|
||||
Goodbye."""
|
||||
)
|
||||
sys.exit(1)
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
return None
|
||||
|
|
102
hikka/heroku.py
102
hikka/heroku.py
|
@ -1,102 +0,0 @@
|
|||
# TODO: Replace heroku installer
|
||||
"""Handles heroku uploads"""
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
|
||||
import heroku3
|
||||
from git import Repo
|
||||
from git.exc import InvalidGitRepositoryError
|
||||
from telethon.sessions import StringSession
|
||||
|
||||
from . import utils
|
||||
|
||||
|
||||
def publish(clients, key, api_token=None, create_new=True, full_match=False):
|
||||
"""Push to heroku"""
|
||||
logging.debug("Configuring heroku...")
|
||||
|
||||
data = json.dumps(
|
||||
{
|
||||
getattr(client, "phone", ""): StringSession.save(client.session)
|
||||
for client in clients
|
||||
}
|
||||
)
|
||||
app, config = get_app(data, key, api_token, create_new, full_match)
|
||||
|
||||
config["authorization_strings"] = data
|
||||
config["heroku_api_token"] = key
|
||||
|
||||
if api_token is not None:
|
||||
config["api_id"] = api_token.ID
|
||||
config["api_hash"] = api_token.HASH
|
||||
|
||||
app.update_buildpacks(
|
||||
[
|
||||
"https://github.com/heroku/heroku-buildpack-python",
|
||||
"https://github.com/hikariatama/Heroku-BuildPack",
|
||||
"https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest",
|
||||
]
|
||||
)
|
||||
|
||||
repo = get_repo()
|
||||
url = app.git_url.replace("https://", f"https://api:{key}@")
|
||||
|
||||
if "heroku" in repo.remotes:
|
||||
remote = repo.remote("heroku")
|
||||
remote.set_url(url)
|
||||
else:
|
||||
remote = repo.create_remote("heroku", url)
|
||||
|
||||
remote.push(refspec="HEAD:refs/heads/master")
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def get_app(
|
||||
authorization_strings, key, api_token=None, create_new=True, full_match=False
|
||||
):
|
||||
heroku = heroku3.from_key(key)
|
||||
app = None
|
||||
|
||||
for poss_app in heroku.apps():
|
||||
config = poss_app.config()
|
||||
|
||||
if "authorization_strings" not in config:
|
||||
continue
|
||||
|
||||
if api_token is None or (
|
||||
config["api_id"] == api_token.ID and config["api_hash"] == api_token.HASH
|
||||
):
|
||||
if full_match and config["authorization_strings"] != authorization_strings:
|
||||
continue
|
||||
|
||||
app = poss_app
|
||||
break
|
||||
|
||||
if app is None:
|
||||
if api_token is None or not create_new:
|
||||
logging.error("%r", {app: repr(app.config) for app in heroku.apps()})
|
||||
raise RuntimeError("Could not identify app!")
|
||||
|
||||
app = heroku.create_app(stack_id_or_name="heroku-18", region_id_or_name="us")
|
||||
config = app.config()
|
||||
|
||||
return app, config
|
||||
|
||||
|
||||
def get_repo():
|
||||
"""Helper to get the repo, making it if not found"""
|
||||
try:
|
||||
repo = Repo(os.path.dirname(utils.get_base_dir()))
|
||||
except InvalidGitRepositoryError:
|
||||
repo = Repo.init(os.path.dirname(utils.get_base_dir()))
|
||||
origin = repo.create_remote(
|
||||
"origin", "https://github.com/hikariatama/Hikka"
|
||||
)
|
||||
origin.fetch()
|
||||
repo.create_head("master", origin.refs.master)
|
||||
repo.heads.master.set_tracking_branch(origin.refs.master)
|
||||
repo.heads.master.checkout(True)
|
||||
return repo
|
|
@ -218,7 +218,6 @@ class Modules:
|
|||
self._initial_registration = True
|
||||
self.added_modules = None
|
||||
self.use_inline = use_inline
|
||||
self._fs = "DYNO" not in os.environ
|
||||
|
||||
def register_all(self, babelfish, mods=None): # skipcq: PYL-W0613
|
||||
# TODO: remove babelfish
|
||||
|
@ -237,7 +236,7 @@ class Modules:
|
|||
)
|
||||
]
|
||||
|
||||
if self._fs and use_fs_for_modules():
|
||||
if use_fs_for_modules():
|
||||
mods += [
|
||||
os.path.join(LOADED_MODULES_DIR, mod)
|
||||
for mod in filter(
|
||||
|
@ -288,7 +287,7 @@ class Modules:
|
|||
|
||||
cls_name = ret.__class__.__name__
|
||||
|
||||
if self._fs and use_fs_for_modules():
|
||||
if use_fs_for_modules():
|
||||
path = os.path.join(LOADED_MODULES_DIR, f"{cls_name}.py")
|
||||
|
||||
if not os.path.isfile(path) and origin == "<string>":
|
||||
|
@ -490,7 +489,7 @@ class Modules:
|
|||
worked += [module.__module__]
|
||||
|
||||
name = module.__class__.__name__
|
||||
if self._fs and use_fs_for_modules():
|
||||
if use_fs_for_modules():
|
||||
path = os.path.join(LOADED_MODULES_DIR, f"{name}.py")
|
||||
|
||||
if os.path.isfile(path):
|
||||
|
|
251
hikka/main.py
251
hikka/main.py
|
@ -18,22 +18,17 @@
|
|||
|
||||
import argparse
|
||||
import asyncio
|
||||
import atexit
|
||||
import collections
|
||||
import functools
|
||||
import importlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import random
|
||||
import signal
|
||||
import socket
|
||||
import sqlite3
|
||||
import sys
|
||||
import time
|
||||
|
||||
import requests
|
||||
from requests import get
|
||||
from telethon import TelegramClient, events
|
||||
from telethon.errors.rpcerrorlist import (
|
||||
|
@ -47,7 +42,7 @@ from telethon.network.connection import ConnectionTcpMTProxyRandomizedIntermedia
|
|||
from telethon.sessions import StringSession, SQLiteSession
|
||||
from telethon.tl.functions.channels import DeleteChannelRequest
|
||||
|
||||
from . import utils, loader, heroku
|
||||
from . import utils, loader
|
||||
from .database import backend, frontend
|
||||
from .dispatcher import CommandDispatcher
|
||||
from .translations.core import Translator
|
||||
|
@ -105,10 +100,7 @@ save_config_key("use_fs_for_modules", get_config_key("use_fs_for_modules"))
|
|||
|
||||
|
||||
def gen_port():
|
||||
# In case of heroku you always need to use 8080
|
||||
if "DYNO" in os.environ:
|
||||
return 8080
|
||||
|
||||
# TODO: Oktato 8080 default
|
||||
# But for own server we generate new free port, and assign to it
|
||||
|
||||
port = get_config_key("port")
|
||||
|
@ -145,7 +137,6 @@ def parse_arguments():
|
|||
)
|
||||
parser.add_argument("--phone", "-p", action="append")
|
||||
parser.add_argument("--token", "-t", action="append", dest="tokens")
|
||||
parser.add_argument("--heroku", action="store_true")
|
||||
parser.add_argument("--no-nickname", "-nn", dest="no_nickname", action="store_true")
|
||||
parser.add_argument("--no-inline", dest="use_inline", action="store_false")
|
||||
parser.add_argument("--hosting", "-lh", dest="hosting", action="store_true")
|
||||
|
@ -183,30 +174,12 @@ def parse_arguments():
|
|||
action="store",
|
||||
help="MTProto proxy secret",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--heroku-web-internal",
|
||||
dest="heroku_web_internal",
|
||||
action="store_true",
|
||||
help="This is for internal use only. If you use it, things will go wrong.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--heroku-deps-internal",
|
||||
dest="heroku_deps_internal",
|
||||
action="store_true",
|
||||
help="This is for internal use only. If you use it, things will go wrong.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--docker-deps-internal",
|
||||
dest="docker_deps_internal",
|
||||
action="store_true",
|
||||
help="This is for internal use only. If you use it, things will go wrong.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--heroku-restart-internal",
|
||||
dest="heroku_restart_internal",
|
||||
action="store_true",
|
||||
help="This is for internal use only. If you use it, things will go wrong.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--root",
|
||||
dest="disable_root_check",
|
||||
|
@ -245,15 +218,7 @@ def get_phones(arguments):
|
|||
)
|
||||
)
|
||||
|
||||
authtoken = os.environ.get("authorization_strings", False) # for heroku
|
||||
if authtoken and not arguments.setup:
|
||||
try:
|
||||
authtoken = json.loads(authtoken)
|
||||
except json.decoder.JSONDecodeError:
|
||||
logging.warning("authtoken invalid")
|
||||
authtoken = False
|
||||
|
||||
if arguments.setup or (arguments.tokens and not authtoken):
|
||||
if arguments.setup:
|
||||
authtoken = {}
|
||||
if arguments.tokens:
|
||||
for token in arguments.tokens:
|
||||
|
@ -311,30 +276,6 @@ def get_proxy(arguments):
|
|||
return None, ConnectionTcpFull
|
||||
|
||||
|
||||
def sigterm(app, signum, handler): # skipcq: PYL-W0613
|
||||
if app is not None:
|
||||
dyno = os.environ["DYNO"]
|
||||
if dyno.startswith("web") and app.process_formation()["web"].quantity:
|
||||
# If we are just idling, start the worker, but otherwise shutdown gracefully
|
||||
app.scale_formation_process("worker-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK", 1)
|
||||
elif (
|
||||
dyno.startswith("restarter")
|
||||
and app.process_formation()[
|
||||
"restarter-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK"
|
||||
].quantity
|
||||
):
|
||||
# If this dyno is restarting, it means we should start the web dyno
|
||||
app.batch_scale_formation_processes(
|
||||
{
|
||||
"web": 1,
|
||||
"worker-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK": 0,
|
||||
"restarter-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK": 0,
|
||||
}
|
||||
)
|
||||
# This ensures that we call atexit hooks and close FDs when Heroku kills us un-gracefully
|
||||
sys.exit(143) # SIGTERM + 128
|
||||
|
||||
|
||||
class SuperList(list):
|
||||
"""
|
||||
Makes able: await self.allclients.send_message("foo", "bar")
|
||||
|
@ -383,8 +324,6 @@ def main(): # noqa: C901
|
|||
if arguments.web
|
||||
else None
|
||||
)
|
||||
elif arguments.heroku_web_internal:
|
||||
raise RuntimeError("Web required but unavailable")
|
||||
else:
|
||||
web = None
|
||||
|
||||
|
@ -396,17 +335,16 @@ def main(): # noqa: C901
|
|||
if web:
|
||||
loop.run_until_complete(web.start(arguments.port))
|
||||
print("Web mode ready for configuration") # noqa: T001
|
||||
if not arguments.heroku_web_internal:
|
||||
port = str(web.port)
|
||||
if platform.system() == "Linux" and not os.path.exists(
|
||||
"/etc/os-release"
|
||||
):
|
||||
print(f"Please visit http://localhost:{port}")
|
||||
else:
|
||||
ipaddress = get("https://api.ipify.org").text
|
||||
print(
|
||||
f"Please visit http://{ipaddress}:{port} or http://localhost:{port}"
|
||||
)
|
||||
port = str(web.port)
|
||||
if platform.system() == "Linux" and not os.path.exists(
|
||||
"/etc/os-release"
|
||||
):
|
||||
print(f"Please visit http://localhost:{port}")
|
||||
else:
|
||||
ipaddress = get("https://api.ipify.org").text
|
||||
print(
|
||||
f"Please visit http://{ipaddress}:{port} or http://localhost:{port}"
|
||||
)
|
||||
loop.run_until_complete(web.wait_for_api_token_setup())
|
||||
api_token = web.api_token
|
||||
else:
|
||||
|
@ -414,47 +352,6 @@ def main(): # noqa: C901
|
|||
importlib.invalidate_caches()
|
||||
api_token = get_api_token(arguments)
|
||||
|
||||
if os.environ.get("authorization_strings", False):
|
||||
if (
|
||||
os.environ.get("DYNO", False)
|
||||
or arguments.heroku_web_internal
|
||||
or arguments.heroku_deps_internal
|
||||
):
|
||||
app, _ = heroku.get_app(
|
||||
os.environ["authorization_strings"],
|
||||
os.environ["heroku_api_token"],
|
||||
api_token,
|
||||
False,
|
||||
True,
|
||||
)
|
||||
if arguments.heroku_web_internal:
|
||||
app.scale_formation_process("worker-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK", 0)
|
||||
signal.signal(signal.SIGTERM, functools.partial(sigterm, app))
|
||||
elif arguments.heroku_deps_internal:
|
||||
try:
|
||||
app.scale_formation_process("web", 0)
|
||||
app.scale_formation_process(
|
||||
"worker-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK", 0
|
||||
)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
if e.response.status_code != 404:
|
||||
# The dynos don't exist on the very first deployment, so don't try to scale
|
||||
raise
|
||||
else:
|
||||
atexit.register(
|
||||
functools.partial(
|
||||
app.scale_formation_process,
|
||||
"restarter-DO-NOT-TURN-ON-OR-THINGS-WILL-BREAK",
|
||||
1,
|
||||
)
|
||||
)
|
||||
elif arguments.heroku_restart_internal:
|
||||
signal.signal(signal.SIGTERM, functools.partial(sigterm, app))
|
||||
while True:
|
||||
time.sleep(60)
|
||||
elif os.environ.get("DYNO", False):
|
||||
signal.signal(signal.SIGTERM, functools.partial(sigterm, app))
|
||||
|
||||
if authtoken:
|
||||
for phone, token in authtoken.items():
|
||||
try:
|
||||
|
@ -482,31 +379,26 @@ def main(): # noqa: C901
|
|||
if not web.running.is_set():
|
||||
loop.run_until_complete(web.start(arguments.port))
|
||||
print("Web mode ready for configuration") # noqa: T001
|
||||
if not arguments.heroku_web_internal:
|
||||
port = str(web.port)
|
||||
if platform.system() == "Linux" and not os.path.exists(
|
||||
"/etc/os-release"
|
||||
):
|
||||
print(f"Please visit http://localhost:{port}")
|
||||
else:
|
||||
ipaddress = get("https://api.ipify.org").text
|
||||
print(
|
||||
f"Please visit http://{ipaddress}:{port} or http://localhost:{port}"
|
||||
)
|
||||
port = str(web.port)
|
||||
if platform.system() == "Linux" and not os.path.exists(
|
||||
"/etc/os-release"
|
||||
):
|
||||
print(f"Please visit http://localhost:{port}")
|
||||
else:
|
||||
ipaddress = get("https://api.ipify.org").text
|
||||
print(
|
||||
f"Please visit http://{ipaddress}:{port} or http://localhost:{port}"
|
||||
)
|
||||
loop.run_until_complete(web.wait_for_clients_setup())
|
||||
arguments.heroku = web.heroku_api_token
|
||||
clients = web.clients
|
||||
for client in clients:
|
||||
if arguments.heroku:
|
||||
session = StringSession()
|
||||
else:
|
||||
session = SQLiteSession(
|
||||
os.path.join(
|
||||
arguments.data_root
|
||||
or os.path.dirname(utils.get_base_dir()),
|
||||
f"hikka-+{'X' * (len(client.phone) - 5)}{client.phone[-4:]}",
|
||||
)
|
||||
session = SQLiteSession(
|
||||
os.path.join(
|
||||
arguments.data_root
|
||||
or os.path.dirname(utils.get_base_dir()),
|
||||
f"hikka-+{'X' * (len(client.phone) - 5)}{client.phone[-4:]}",
|
||||
)
|
||||
)
|
||||
|
||||
session.set_dc(
|
||||
client.session.dc_id,
|
||||
|
@ -514,44 +406,20 @@ def main(): # noqa: C901
|
|||
client.session.port,
|
||||
)
|
||||
session.auth_key = client.session.auth_key
|
||||
if not arguments.heroku:
|
||||
session.save()
|
||||
session.save()
|
||||
client.session = session
|
||||
else:
|
||||
try:
|
||||
phone = input("Please enter your phone: ")
|
||||
phones = {phone.split(":", maxsplit=1)[0]: phone}
|
||||
except EOFError:
|
||||
print("=" * 30)
|
||||
print(
|
||||
"Hello. If you are seeing this, it means YOU ARE DOING SOMETHING WRONG!\n"
|
||||
"It is likely that you tried to deploy to heroku -\n"
|
||||
"you cannot do this via the web interface.\n"
|
||||
"\n"
|
||||
"To deploy to heroku, go to\n"
|
||||
"https://friendly-telegram.gitlab.io/heroku to learn more\n"
|
||||
"\n"
|
||||
"In addition, you seem to have forked the hikka repo. THIS IS WRONG!\n"
|
||||
"You should remove the forked repo, and read https://friendly-telegram.gitlab.io\n"
|
||||
"\n"
|
||||
"If you're not using Heroku, then you are using a non-interactive prompt but\n"
|
||||
"you have not got a session configured, meaning authentication to Telegram is\n"
|
||||
"impossible.\n"
|
||||
"\n"
|
||||
"THIS ERROR IS YOUR FAULT. DO NOT REPORT IT AS A BUG!\n"
|
||||
"Goodbye.\n"
|
||||
)
|
||||
|
||||
sys.exit(1)
|
||||
except (EOFError, OSError):
|
||||
raise
|
||||
|
||||
for phone_id, phone in phones.items():
|
||||
if arguments.heroku:
|
||||
session = StringSession()
|
||||
else:
|
||||
session = os.path.join(
|
||||
arguments.data_root or os.path.dirname(utils.get_base_dir()),
|
||||
f"hikka{(('-' + phone_id) if phone_id else '')}",
|
||||
)
|
||||
session = os.path.join(
|
||||
arguments.data_root or os.path.dirname(utils.get_base_dir()),
|
||||
f"hikka{(('-' + phone_id) if phone_id else '')}",
|
||||
)
|
||||
|
||||
try:
|
||||
client = TelegramClient(
|
||||
|
@ -589,24 +457,6 @@ def main(): # noqa: C901
|
|||
)
|
||||
continue
|
||||
|
||||
if arguments.heroku:
|
||||
if isinstance(arguments.heroku, str):
|
||||
key = arguments.heroku
|
||||
else:
|
||||
key = input(
|
||||
"Please enter your Heroku API key (from https://dashboard.heroku.com/account): "
|
||||
).strip()
|
||||
|
||||
app = heroku.publish(clients, key, api_token)
|
||||
print(
|
||||
"Installed to heroku successfully! Type .help in Telegram for help."
|
||||
) # noqa: T001
|
||||
if web:
|
||||
web.redirect_url = app.web_url
|
||||
web.ready.set()
|
||||
loop.run_until_complete(web.root_redirected.wait())
|
||||
return
|
||||
|
||||
loop.set_exception_handler(
|
||||
lambda _, x: logging.error(
|
||||
"Exception on event loop! %s",
|
||||
|
@ -679,7 +529,7 @@ async def amain(first, client, allclients, web, arguments):
|
|||
return False
|
||||
|
||||
db = frontend.Database(
|
||||
db, arguments.heroku_deps_internal or arguments.docker_deps_internal
|
||||
db, arguments.docker_deps_internal
|
||||
)
|
||||
await db.init()
|
||||
|
||||
|
@ -688,9 +538,7 @@ async def amain(first, client, allclients, web, arguments):
|
|||
for handler in handlers:
|
||||
handler.setLevel(db.get(__name__, "loglevel", logging.WARNING))
|
||||
|
||||
to_load = None
|
||||
if arguments.heroku_deps_internal or arguments.docker_deps_internal:
|
||||
to_load = ["loader.py"]
|
||||
to_load = ["loader.py"] if arguments.docker_deps_internal else None
|
||||
|
||||
babelfish = Translator(
|
||||
db.get(__name__, "langpacks", []),
|
||||
|
@ -703,14 +551,14 @@ async def amain(first, client, allclients, web, arguments):
|
|||
modules = loader.Modules()
|
||||
no_nickname = arguments.no_nickname
|
||||
|
||||
if not (arguments.heroku_deps_internal or arguments.docker_deps_internal):
|
||||
if not arguments.docker_deps_internal:
|
||||
if web:
|
||||
await web.add_loader(client, modules, db)
|
||||
await web.start_if_ready(len(allclients), arguments.port)
|
||||
if not web_only:
|
||||
dispatcher = CommandDispatcher(modules, db, no_nickname)
|
||||
client.dispatcher = dispatcher
|
||||
if arguments.heroku_deps_internal or arguments.docker_deps_internal:
|
||||
if arguments.docker_deps_internal:
|
||||
# Loader has installed all dependencies
|
||||
return # We are done
|
||||
|
||||
|
@ -742,24 +590,17 @@ async def amain(first, client, allclients, web, arguments):
|
|||
|
||||
build = repo.heads[0].commit.hexsha
|
||||
diff = repo.git.log(["HEAD..origin/master", "--oneline"])
|
||||
upd = r"\33[31mUpdate required" if diff else r"Up-to-date"
|
||||
upd = r"Update required" if diff else r"Up-to-date"
|
||||
|
||||
termux = bool(
|
||||
os.popen('echo $PREFIX | grep -o "com.termux"').read()
|
||||
) # skipcq: BAN-B605, BAN-B607
|
||||
is_heroku = os.environ.get("DYNO", False)
|
||||
|
||||
_platform = r"Termux" if termux else (r"Heroku" if is_heroku else "VDS")
|
||||
_platform = "Termux" if termux else "Unknown"
|
||||
|
||||
logo1 = f"""
|
||||
)
|
||||
( ( /(
|
||||
) ) ( ( )())
|
||||
(()/( ) ) |((_)
|
||||
/((_)_((_)((_)|_((_)
|
||||
(_)/ __| __| __| |/ /
|
||||
| (_ | _|| _| ' <
|
||||
___|___|___|_|_\\
|
||||
|
||||
█ █ █ █▄▀ █▄▀ ▄▀█
|
||||
█▀█ █ █ █ █ █ █▀█
|
||||
|
||||
• Build: {build[:7]}
|
||||
• Version: {'.'.join(list(map(str, list(__version__))))}
|
||||
|
@ -774,7 +615,7 @@ async def amain(first, client, allclients, web, arguments):
|
|||
f"=== VERSION: {'.'.join(list(map(str, list(__version__))))} ==="
|
||||
)
|
||||
logging.info(
|
||||
f"=== PLATFORM: {'Termux' if termux else ('Heroku' if is_heroku else 'VDS')} ==="
|
||||
f"=== PLATFORM: {_platform} ==="
|
||||
)
|
||||
except Exception:
|
||||
logging.exception(
|
||||
|
|
|
@ -13,16 +13,7 @@ class Web:
|
|||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self.app.router.add_get("/", self.root)
|
||||
self.app.router.add_get("/is_restart_complete", lambda r: True)
|
||||
self.app.router.add_post("/restart", self.restart)
|
||||
|
||||
@aiohttp_jinja2.template("root.jinja2")
|
||||
async def root(self, request):
|
||||
return {}
|
||||
|
||||
async def restart(self, request):
|
||||
cl = self.client_data[list(self.client_data.keys())[0]]
|
||||
m = await cl[1].send_message("me", "<b>Restarting...</b>")
|
||||
for mod in cl[0].modules:
|
||||
if mod.__class__.__name__ == "UpdaterMod":
|
||||
await mod.restart_common(m)
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
# Friendly Telegram (telegram userbot)
|
||||
# Copyright (C) 2018-2021 The Authors
|
||||
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
# Modded by GeekTG Team
|
||||
|
||||
if (Test-Path "Friendly-Telegram" -PathType Container)
|
||||
{
|
||||
if (Test-Path (Join-Path "Friendly-Telegram" "Friendly-Telegram") -PathType Container)
|
||||
{
|
||||
Set-Location "Friendly-Telegram"
|
||||
}
|
||||
python -m friendly-telegram
|
||||
exit
|
||||
}
|
||||
|
||||
Write-Output("Downloading Python...")
|
||||
Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.9.6/python-3.9.6.exe" -OutFile (Join-Path $env:TEMP "python-installer.exe")
|
||||
Write-Output("Installing Python...")
|
||||
Start-Process (Join-Path $env:TEMP "python-installer.exe") @("/quiet"; "InstallAllUsers=0"; "PrependPath=1"; "Include_test=0"; "InstallLauncherAllUsers=0") -Wait
|
||||
Write-Output("Locating Git...")
|
||||
$ret = Invoke-RestMethod -Uri "https://api.github.com/repos/git-for-windows/git/releases" -Headers @{ 'User-Agent' = 'Friendly-Telegram installer' }
|
||||
foreach ($release in $ret)
|
||||
{
|
||||
$asset_id = $release.assets | Where { $_.name -Match ("^Git-[0-9]+\.[0-9]+\.[0-9]+-" + (Get-WmiObject -Class Win32_OperatingSystem -ComputerName $env:computername -ea 0).OSArchitecture + ".exe$") } | % { $_.id }
|
||||
if (-not [string]::IsNullOrEmpty($asset_id))
|
||||
{
|
||||
break
|
||||
}
|
||||
}
|
||||
if ( [string]::IsNullOrEmpty($asset_id))
|
||||
{
|
||||
Write-Error "Unable to locate Git"
|
||||
exit
|
||||
}
|
||||
$download_url = "https://api.github.com/repos/git-for-windows/git/releases/assets/" + $asset_id
|
||||
Write-Output("Downloading Git...")
|
||||
Invoke-WebRequest -Uri $download_url -OutFile (Join-Path $env:TEMP "git-scm-installer.exe") -Headers @{ 'User-Agent' = 'Friendly-Telegram installer'; 'Accept' = 'application/octet-stream' }
|
||||
Write-Output("Installing Git...")
|
||||
Start-Process (Join-Path $env:TEMP "git-scm-installer.exe") @("/VERYSILENT"; "/NORESTART"; "/NOCANCEL"; "/SP-"; "/CURRENTUSER"; "/NOCLOSEAPPLICATIONS"; "/NORESTARTAPPLICATIONS"; '/COMPONENTS=""') -Wait
|
||||
Write-Output("Done")
|
||||
|
||||
# https://stackoverflow.com/a/31845512
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
git clone https://github.com/GeekTG/Friendly-Telegram
|
||||
|
||||
Set-Location Friendly-Telegram
|
||||
python -m pip install -r requirements.txt
|
||||
python -m friendly-telegram
|
||||
python -m friendly-telegram --heroku # Stopgap
|
75
install.sh
75
install.sh
|
@ -20,7 +20,7 @@ runin() {
|
|||
# Runs the arguments and spins once per line of stdout (tee'd to logfile), also piping stderr to logfile
|
||||
{ "$@" 2>>../hikka-install.log || return $?; } | while read -r line; do
|
||||
spin
|
||||
printf "%s\n" "$line" >>../ftg-install.log
|
||||
printf "%s\n" "$line" >>../hikka-install.log
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -41,25 +41,42 @@ errorout() {
|
|||
cat hikka-install.log
|
||||
}
|
||||
|
||||
banner() {
|
||||
clear
|
||||
clear
|
||||
printf "\n\e[7;30;41m ) \e[0m"
|
||||
printf "\n\e[7;30;41m ( ( /( \e[0m"
|
||||
printf "\n\e[7;30;41m )\\ ) ( ( )\\()) \e[0m"
|
||||
printf "\n\e[7;30;41m(()/( )\\ )\\ |((_)\\ \e[0m"
|
||||
printf "\n\e[7;30;41m /((\e[7;30;42m_\e[7;30;41m)\e[7;30;42m_\e[7;30;41m((\e[7;30;42m_\e[7;30;41m)((\e[7;30;42m_\e[7;30;41m)|\e[7;30;42m_\e[7;30;41m((\e[7;30;42m_\e[7;30;41m) \e[0m"
|
||||
printf "\n\e[7;30;41m(_)\e[0m\e[7;30;42m/ __| __| __| |/ / \e[0m"
|
||||
printf "\n\e[7;30;42m | (_ | _|| _| ' < \e[0m"
|
||||
printf "\n\e[7;30;42m \\___|___|___|_|\\_\\ \e[0m\n\n"
|
||||
|
||||
} # TODO: Replace banner
|
||||
|
||||
##############################################################################
|
||||
|
||||
banner
|
||||
printf '%s\n' "The process takes around 3-7 minutes"
|
||||
printf '%s' "Installing now... "
|
||||
clear
|
||||
clear
|
||||
# Adapted from https://github.com/Silejonu/bash_loading_animations/blob/main/bash_loading_animations.sh
|
||||
|
||||
BLA_metro=('[ ]' '[= ]' '[== ]' '[=== ]' '[==== ]' '[===== ]' '[ ===== ]' '[ ======]' '[ =====]' '[ ====]' '[ ===]' '[ ==]' '[ =]' '[ ]' '[ ======]' '[ ===== ]' '[===== ]' '[==== ]' '[=== ]' '[== ]' '[= ]' '[ ]')
|
||||
|
||||
BLA::play_loading_animation_loop() {
|
||||
while true ; do
|
||||
for frame in ${!BLA_metro[*]} ; do
|
||||
printf "\r%s" " ${BLA_metro[$frame]}"
|
||||
sleep "0.05"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
BLA::start_loading_animation() {
|
||||
tput civis # Hide the terminal cursor
|
||||
BLA::play_loading_animation_loop &
|
||||
BLA_loading_animation_pid="${!}"
|
||||
}
|
||||
|
||||
BLA::stop_loading_animation() {
|
||||
kill "${BLA_loading_animation_pid}" &> /dev/null
|
||||
printf "\r%s" " "
|
||||
printf "\n"
|
||||
tput cnorm # Restore the terminal cursor
|
||||
}
|
||||
|
||||
printf "\n\e[1;35;47m \e[0m"
|
||||
printf "\n\e[1;35;47m █ █ █ █▄▀ █▄▀ ▄▀█ \e[0m"
|
||||
printf "\n\e[1;35;47m █▀█ █ █ █ █ █ █▀█ \e[0m"
|
||||
printf "\n\e[1;35;47m \e[0m"
|
||||
printf "\n\n\e[3;34;40m Installing...\e[0m\n\n"
|
||||
BLA::start_loading_animation
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
@ -74,6 +91,7 @@ if [ ! x"" = x"$DYNO" ] && ! command -v python >/dev/null; then
|
|||
# We are running in a heroku dyno without python, time to get ugly!
|
||||
runout git clone https://github.com/heroku/heroku-buildpack-python || {
|
||||
endspin "Bootstrap download failed!"
|
||||
BLA::stop_loading_animation
|
||||
exit 1
|
||||
}
|
||||
rm -rf .heroku .cache .profile.d requirements.txt runtime.txt .env
|
||||
|
@ -83,6 +101,7 @@ if [ ! x"" = x"$DYNO" ] && ! command -v python >/dev/null; then
|
|||
STACK=heroku-18 runout bash heroku-buildpack-python/bin/compile /app /app/.cache /app/.env ||
|
||||
{
|
||||
endspin "Bootstrap install failed!"
|
||||
BLA::stop_loading_animation
|
||||
exit 1
|
||||
}
|
||||
rm -rf .cache
|
||||
|
@ -92,12 +111,13 @@ fi
|
|||
if [ -d "Hikka/hikka" ]; then
|
||||
cd Hikka || {
|
||||
endspin "Error: Install git package and re-run installer"
|
||||
BLA::stop_loading_animation
|
||||
exit 6
|
||||
}
|
||||
DIR_CHANGED="yes"
|
||||
fi
|
||||
if [ -f ".setup_complete" ] || [ -d "hikka" -a ! x"" = x"$DYNO" ]; then
|
||||
# If ftg is already installed by this script, or its in Heroku and installed
|
||||
# If hikka is already installed by this script, or its in Heroku and installed
|
||||
PYVER=""
|
||||
if echo "$OSTYPE" | grep -qE '^linux-gnu.*'; then
|
||||
PYVER="3"
|
||||
|
@ -106,6 +126,7 @@ if [ -f ".setup_complete" ] || [ -d "hikka" -a ! x"" = x"$DYNO" ]; then
|
|||
clear
|
||||
banner
|
||||
"python$PYVER" -m hikka "$@"
|
||||
BLA::stop_loading_animation
|
||||
exit $?
|
||||
elif [ "$DIR_CHANGED" = "yes" ]; then
|
||||
cd ..
|
||||
|
@ -121,8 +142,9 @@ if echo "$OSTYPE" | grep -qE '^linux-gnu.*' && [ -f '/etc/debian_version' ]; the
|
|||
# Relaunch as root, preserving arguments
|
||||
if command -v sudo >/dev/null; then
|
||||
endspin "Restarting as root..."
|
||||
echo "Relaunching" >>ftg-install.log
|
||||
echo "Relaunching" >>hikka-install.log
|
||||
sudo "$BASH" -c '. <('"$(command -v curl >/dev/null && echo 'curl -Ls' || echo 'wget -qO-')"' https://github.com/hikariatama/Hikka/master/install.sh) '"$*"
|
||||
BLA::stop_loading_animation
|
||||
exit $?
|
||||
else
|
||||
PKGMGR="true"
|
||||
|
@ -138,8 +160,9 @@ elif echo "$OSTYPE" | grep -qE '^linux-gnu.*' && [ -f '/etc/arch-release' ]; the
|
|||
# Relaunch as root, preserving arguments
|
||||
if command -v sudo >/dev/null; then
|
||||
endspin "Restarting as root..."
|
||||
echo "Relaunching" >>ftg-install.log
|
||||
echo "Relaunching" >>hikka-install.log
|
||||
sudo "$BASH" -c '. <('"$(command -v curl >/dev/null && echo 'curl -Ls' || echo 'wget -qO-')"' https://github.com/hikariatama/Hikka/master/install.sh) '"$*"
|
||||
BLA::stop_loading_animation
|
||||
exit $?
|
||||
else
|
||||
PKGMGR="true"
|
||||
|
@ -158,6 +181,7 @@ elif echo "$OSTYPE" | grep -qE '^darwin.*'; then
|
|||
PYVER="3"
|
||||
else
|
||||
endspin "Unrecognised OS. Please follow https://t.me/hikka_talks"
|
||||
BLA::stop_loading_animation
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -165,6 +189,7 @@ fi
|
|||
|
||||
runout $PKGMGR "python$PYVER" git || { # skipcq
|
||||
errorout "Core install failed."
|
||||
BLA::stop_loading_animation
|
||||
exit 2
|
||||
}
|
||||
|
||||
|
@ -194,10 +219,12 @@ ${SUDO_CMD}rm -rf Hikka
|
|||
# shellcheck disable=SC2086
|
||||
runout ${SUDO_CMD}git clone https://github.com/hikariatama/Hikka/ || {
|
||||
errorout "Clone failed."
|
||||
BLA::stop_loading_animation
|
||||
exit 3
|
||||
}
|
||||
cd Hikka || {
|
||||
endspin "Error: Install git package and re-run installer"
|
||||
BLA::stop_loading_animation
|
||||
exit 7
|
||||
}
|
||||
# shellcheck disable=SC2086
|
||||
|
@ -205,13 +232,17 @@ runin ${SUDO_CMD}"python$PYVER" -m pip install --upgrade pip setuptools wheel --
|
|||
# shellcheck disable=SC2086
|
||||
runin ${SUDO_CMD}"python$PYVER" -m pip install -r requirements.txt --upgrade --user --no-warn-script-location --disable-pip-version-check || {
|
||||
errorin "Requirements failed!"
|
||||
BLA::stop_loading_animation
|
||||
exit 4
|
||||
}
|
||||
endspin "Installation successful. Launching setup interface..."
|
||||
rm -f ../ftg-install.log
|
||||
rm -f ../hikka-install.log
|
||||
touch .setup_complete
|
||||
# shellcheck disable=SC2086,SC2015
|
||||
${SUDO_CMD}"python$PYVER" -m hikka "$@" || {
|
||||
echo "Python scripts failed"
|
||||
BLA::stop_loading_animation
|
||||
exit 5
|
||||
}
|
||||
|
||||
BLA::stop_loading_animation
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
icon: https://apps.okteto.com/movies/icon.png
|
||||
deploy:
|
||||
- okteto build -t okteto.dev/api:${OKTETO_GIT_COMMIT} api
|
||||
- okteto build -t okteto.dev/frontend:${OKTETO_GIT_COMMIT} frontend
|
||||
- helm upgrade --install movies chart --set tag=${OKTETO_GIT_COMMIT}
|
|
@ -4,9 +4,6 @@ Telethon-Mod==1.24.6
|
|||
# Config
|
||||
pythondialog==3.5.3
|
||||
|
||||
# Heroku
|
||||
heroku3==5.1.4
|
||||
|
||||
# Python Git Library
|
||||
gitpython==3.1.27
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@
|
|||
}
|
||||
|
||||
body {
|
||||
/*background: linear-gradient(-45deg, #007700 0%, #004400 100%);*/
|
||||
transition: all 2s ease;
|
||||
background: #16181d;
|
||||
}
|
||||
|
@ -264,10 +263,7 @@
|
|||
</div>
|
||||
<div class="blur">
|
||||
<div class="title">Hikka</div>
|
||||
<div class="description">Ultimate userbot.<br>Best <span style="color:#28a0dc">Telegram</span> userbot.<br><b>Ever</b>.</div>
|
||||
<div class="center">
|
||||
<div class="button" id="restart">Restart</div>
|
||||
</div>
|
||||
<div class="description">Fresh and cute<br><span style="color:#28a0dc">Telegram</span> userbot.</div>
|
||||
</div>
|
||||
<div class="darken"></div>
|
||||
<div id="root">
|
||||
|
@ -281,37 +277,6 @@
|
|||
$(document).ready(function() {
|
||||
$('.bg').hide().delay(2000).fadeIn(500);
|
||||
});
|
||||
$("#restart").click(() => {
|
||||
Swal.fire({
|
||||
title: 'Are you sure, you want to restart?',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Restart',
|
||||
showLoaderOnConfirm: true,
|
||||
preConfirm: () => {
|
||||
return fetch("/restart", {method: "POST"})
|
||||
.then(function(response) {
|
||||
$("#restart").fadeOut(100);
|
||||
$(".description").html('Restarting...');
|
||||
$(".bg").fadeOut(() => {
|
||||
$(".bg").css({'background-image': 'url(https://github.com/hikariatama/assets/raw/master/moon.png)'});
|
||||
$(".bg").delay(1000).fadeIn(500);
|
||||
});
|
||||
setTimeout(() => {
|
||||
setInterval(() => {
|
||||
fetch("/is_restart_complete", {method: "GET"})
|
||||
.then(() => {window.location.reload();})
|
||||
}, 1000);
|
||||
}, 3000);
|
||||
})
|
||||
.catch(error => {
|
||||
Swal.showValidationMessage(
|
||||
'Restart failed: ' + error.toString()
|
||||
)
|
||||
})
|
||||
},
|
||||
allowOutsideClick: () => !Swal.isLoading()
|
||||
})
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
Loading…
Reference in New Issue