Skip to content

Commit

Permalink
update webss(add chrome driver) and memes(reacts, hmm, lol, ...) + ca…
Browse files Browse the repository at this point in the history
…rbon + autopic(DB supported)
  • Loading branch information
rking32 committed May 5, 2020
1 parent 142c615 commit b9e2735
Show file tree
Hide file tree
Showing 20 changed files with 480 additions and 223 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,6 @@ gen
unknown_errors.txt
logs/
bin/
resources/base_profile_pic.jpg
resources/mdfy_profile_pic.jpg
pictest.py
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,8 @@ async def testing(message: Message):
* [@uaudIth](https://t.me/uaudIth)
* [@K_E_N_W_A_Y](https://t.me/K_E_N_W_A_Y)
* [@nawwasl](https://t.me/nawwasl)
* [@THARUKA](https://t.me/TharukaN97)
* [@TharukaN97](https://t.me/TharukaN97)
* [@Supun97](https://t.me/Supun97)
* [@gotstc](https://t.me/gotstc)

### Copyright & License 👮
Expand Down
11 changes: 6 additions & 5 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,6 @@
"description": "Your Languge ( ex: if english => 'en' )",
"required": false
},
"SCREENSHOT_API": {
"description": "get API key from 'https://screenshotlayer.com'",
"required": false

},
"CURRENCY_API": {
"description": "get API key from 'https://free.currencyconverterapi.com'",
"required": false
Expand Down Expand Up @@ -97,6 +92,12 @@
"buildpacks": [
{
"url": "https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git"
}, {
"url": "https://github.com/opendoor-labs/heroku-buildpack-p7zip"
}, {
"url": "https://github.com/heroku/heroku-buildpack-google-chrome"
}, {
"url": "https://github.com/heroku/heroku-buildpack-chromedriver"
}, {
"url": "https://github.com/heroku/heroku-buildpack-apt.git"
}, {
Expand Down
6 changes: 3 additions & 3 deletions config.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ DOWN_PATH = "downloads/"
PREFERRED_LANGUAGE = ""


# get API key from 'https://screenshotlayer.com'
SCREENSHOT_API = ""

# get API Key from 'https://free.currencyconverterapi.com/'
CURRENCY_API = ""


# add default city for weather
WEATHER_DEFCITY = ""


# Weather API get it from 'https://openweathermap.org/'
OPEN_WEATHER_MAP = ""


# GDrive Folder ID
G_DRIVE_PARENT_ID = ""

Expand Down
Binary file added resources/font.ttf
Binary file not shown.
18 changes: 7 additions & 11 deletions userge/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@


class Config:
"""
Configs to setup Userge.
"""
"""Configs to setup Userge"""

API_ID = int(os.environ.get("API_ID", 12345))

Expand Down Expand Up @@ -75,6 +73,10 @@ class Config:

G_DRIVE_IS_TD = bool(os.environ.get("G_DRIVE_IS_TD", False))

GOOGLE_CHROME_DRIVER = os.environ.get("GOOGLE_CHROME_DRIVER", None)

GOOGLE_CHROME_BIN = os.environ.get("GOOGLE_CHROME_BIN", None)

LOG_CHANNEL_ID = int(os.environ.get("LOG_CHANNEL_ID", 0))

UPSTREAM_REPO = os.environ.get("UPSTREAM_REPO", "https://github.com/UsergeTeam/Userge")
Expand All @@ -91,6 +93,8 @@ class Config:

WELCOME_DELETE_TIMEOUT = 120

AUTOPIC_TIMEOUT = 60

ALLOWED_CHATS = Filters.chat([])

CMD_TRIGGER = os.environ.get("CMD_TRIGGER", '.')
Expand All @@ -112,26 +116,19 @@ class Config:

if Config.HEROKU_API_KEY:
_LOG.info("Checking Heroku App...")

for heroku_app in heroku3.from_key(Config.HEROKU_API_KEY).apps():
if heroku_app and Config.HEROKU_APP_NAME and \
heroku_app.name == Config.HEROKU_APP_NAME:

_LOG.info("Heroku App : %s Found...", heroku_app.name)

Config.HEROKU_APP = heroku_app
Config.HEROKU_GIT_URL = heroku_app.git_url.replace(
"https://", "https://api:" + Config.HEROKU_API_KEY + "@")

if not os.path.isdir(os.path.join(os.getcwd(), '.git')):
tmp_heroku_git_path = os.path.join(os.getcwd(), 'tmp_heroku_git')

_LOG.info("Cloning Heroku GIT...")

Repo.clone_from(Config.HEROKU_GIT_URL, tmp_heroku_git_path)
shutil.move(os.path.join(tmp_heroku_git_path, '.git'), os.getcwd())
shutil.rmtree(tmp_heroku_git_path)

break

if not os.path.exists('bin'):
Expand All @@ -145,7 +142,6 @@ class Config:
"bin/cmrudl"}

_LOG.info("Checking BINs...")

for binary, path in _BINS.items():
if not os.path.exists(path):
_LOG.debug("Downloading %s...", binary)
Expand Down
59 changes: 41 additions & 18 deletions userge/core/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Userge(RawClient):
def __init__(self) -> None:
self._help_dict: Dict[str, Dict[str, str]] = {}
self._imported: List[ModuleType] = []
self._tasks: List[Callable[[Any], Any]] = []
self._channel = self.getCLogger(__name__)
_LOG.info(_LOG_STR, "Setting Userge Configs")
super().__init__(Config.HU_STRING_SESSION,
Expand All @@ -60,8 +61,7 @@ def getCLogger(self, name: str) -> CLogger:

def conversation(self,
chat_id: Union[str, int],
*,
timeout: Union[int, float] = 10,
*, timeout: Union[int, float] = 10,
limit: int = 10) -> Conv:
"""\nThis returns new conversation object.
Expand All @@ -87,8 +87,7 @@ async def send_read_acknowledge(self,
chat_id: Union[int, str],
message: Union[List[RawMessage],
Optional[RawMessage]] = None,
*,
max_id: Optional[int] = None,
*, max_id: Optional[int] = None,
clear_mentions: bool = False) -> bool:
"""\nMarks messages as read and optionally clears mentions.
Expand Down Expand Up @@ -135,7 +134,7 @@ async def send_read_acknowledge(self,
return await self.read_history(chat_id=chat_id, max_id=max_id)
return False

async def get_user_dict(self, user_id: int) -> Dict[str, str]:
async def get_user_dict(self, user_id: Union[int, str]) -> Dict[str, str]:
"""This will return user `Dict` which contains
`id`(chat id), `fname`(first name), `lname`(last name),
`flname`(full name), `uname`(username) and `mention`.
Expand Down Expand Up @@ -307,14 +306,15 @@ def on_cmd(self,
filter_my_trigger = Filters.create(lambda _, query: \
query.text.startswith(trigger) if trigger else True)
sudo_filter = Filters.create(lambda _, query: \
query.from_user and query.from_user.id in Config.SUDO_USERS and \
(query.text.startswith(Config.SUDO_TRIGGER) if trigger else True))
(query.from_user
and query.from_user.id in Config.SUDO_USERS
and (query.text.startswith(Config.SUDO_TRIGGER) if trigger else True)))
sudo_cmd_filter = Filters.create(lambda _, __: \
cname.lstrip(trigger) in Config.ALLOWED_COMMANDS)
if filter_me:
filters_ = filters_ & (
((Filters.outgoing | Filters.me) & filter_my_trigger) | \
(Filters.incoming & sudo_filter & sudo_cmd_filter))
filters_ = (filters_
& (((Filters.outgoing | Filters.me) & filter_my_trigger)
| (Filters.incoming & sudo_filter & sudo_cmd_filter)))
return self._build_decorator(log=f"On {pattern}", filters=filters_,
group=group, **kwargs)

Expand All @@ -341,6 +341,11 @@ def on_left_member(self,
filters=Filters.left_chat_member & leaving_chats,
group=group)

def add_task(self, func: Callable[[Any], Any]) -> Callable[[Any], Any]:
"""add tasks"""
self._tasks.append(func)
return func

def get_help(self,
key: str = '',
all_cmds: bool = False) -> Tuple[Union[str, List[str]], Union[bool, str]]:
Expand All @@ -349,8 +354,10 @@ def get_help(self,
"""
if not key and not all_cmds:
return sorted(list(self._help_dict)), True # names of all modules
if not key.startswith(Config.CMD_TRIGGER) and key in self._help_dict and \
(len(self._help_dict[key]) > 1 or list(self._help_dict[key])[0].lstrip(Config.CMD_TRIGGER) != key):
if (not key.startswith(Config.CMD_TRIGGER)
and key in self._help_dict
and (len(self._help_dict[key]) > 1
or list(self._help_dict[key])[0].lstrip(Config.CMD_TRIGGER) != key)):
return sorted(list(self._help_dict[key])), False # all commands for that module

dict_ = {x: y for _, i in self._help_dict.items() for x, y in i.items()}
Expand Down Expand Up @@ -443,9 +450,9 @@ def _build_decorator(self,
log: str,
filters: Filters,
group: int,
**kwargs: Union[str, bool, Dict[
str, Union[str, List[str], Dict[
str, str]]]]) -> Callable[[_PYROFUNC], _PYROFUNC]:
**kwargs: Union[str, bool,
Dict[str, Union[str, List[str], Dict[str, str]]]]
) -> Callable[[_PYROFUNC], _PYROFUNC]:
def _decorator(func: _PYROFUNC) -> _PYROFUNC:
async def _template(_: RawClient, __: RawMessage) -> None:
await func(Message(_, __, **kwargs))
Expand Down Expand Up @@ -490,7 +497,7 @@ async def reload_plugins(self) -> int:
_LOG.info(_LOG_STR, f"Reloaded {len(reloaded)} Plugins => {reloaded}")
return len(reloaded)

async def restart(self) -> None:
async def restart(self, update_req: bool = False) -> None:
"""Restart the Userge"""
_LOG.info(_LOG_STR, "Restarting Userge")
await self.stop()
Expand All @@ -500,13 +507,29 @@ async def restart(self) -> None:
os.close(handler.fd)
except Exception as c_e:
_LOG.error(_LOG_STR, c_e)
if update_req:
os.system("pip3 install -r requirements.txt")
os.execl(sys.executable, sys.executable, '-m', 'userge')
sys.exit()

def begin(self) -> None:
"""This will start the Userge"""
_LOG.info(_LOG_STR, "Starting Userge")
nest_asyncio.apply()
Conv.init(self)
self.run()
loop = asyncio.get_event_loop()
run = loop.run_until_complete
_LOG.info(_LOG_STR, "Starting Userge")
run(self.start())
running_tasks: List[asyncio.Task] = []
for task in self._tasks:
running_tasks.append(loop.create_task(task()))
_LOG.info(_LOG_STR, "Idling Userge")
run(Userge.idle())
_LOG.info(_LOG_STR, "Exiting Userge")
for task in running_tasks:
task.cancel()
run(self.stop())
for task in asyncio.all_tasks():
task.cancel()
run(loop.shutdown_asyncgens())
loop.close()
115 changes: 115 additions & 0 deletions userge/plugins/fun/autopic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Copyright (C) 2020 by UsergeTeam@Github, < https://github.com/UsergeTeam >.
#
# This file is part of < https://github.com/UsergeTeam/Userge > project,
# and is released under the "GNU v3.0 License Agreement".
# Please see < https://github.com/uaudith/Userge/blob/master/LICENSE >
#
# All rights reserved.


import os
import base64
import asyncio
import datetime
import textwrap
from shutil import copyfile

import aiofiles
from PIL import Image, ImageFont, ImageDraw

from userge import userge, Message, Config, get_collection

SAVED_SETTINGS = get_collection("CONFIGS")

__tmp__ = SAVED_SETTINGS.find_one({'_id': 'UPDATE_PIC'})

UPDATE_PIC = False
BASE_PIC = "resources/base_profile_pic.jpg"
MDFY_PIC = "resources/mdfy_profile_pic.jpg"
if __tmp__:
UPDATE_PIC = __tmp__['on']
if not os.path.exists(BASE_PIC):
with open(BASE_PIC, "wb") as media_file_:
media_file_.write(base64.b64decode(__tmp__['media']))

del __tmp__

LOG = userge.getLogger(__name__)


@userge.on_cmd("autopic", about={
'header': "set profile picture",
'usage': "{tr}autopic\n{tr}autopic [image path]\nset timeout using {tr}sappto"})
async def autopic(message: Message):
global UPDATE_PIC
await message.edit('`processing...`')
if UPDATE_PIC:
if isinstance(UPDATE_PIC, asyncio.Task):
UPDATE_PIC.cancel()
UPDATE_PIC = False
SAVED_SETTINGS.update_one({'_id': 'UPDATE_PIC'},
{"$set": {'on': False}}, upsert=True)
await message.edit('auto profile picture updation has been **stopped**',
del_in=5, log=__name__)
return
image_path = message.input_str
store = False
if os.path.exists(BASE_PIC) and not image_path:
pass
elif not image_path:
profile_photo = await userge.get_profile_photos("me", limit=1)
if not profile_photo:
await message.err("sorry, couldn't find any picture!")
return
await userge.download_media(profile_photo[0], file_name=BASE_PIC)
store = True
else:
if not os.path.exists(image_path):
await message.err("input path not found!")
return
if os.path.exists(BASE_PIC):
os.remove(BASE_PIC)
copyfile(image_path, BASE_PIC)
store = True
data_dict = {'on': True}
if store:
async with aiofiles.open(BASE_PIC, "rb") as media_file:
media = base64.b64encode(await media_file.read())
data_dict['media'] = media
SAVED_SETTINGS.update_one({'_id': 'UPDATE_PIC'},
{"$set": data_dict}, upsert=True)
await message.edit(
'auto profile picture updation has been **started**', del_in=3, log=__name__)
UPDATE_PIC = asyncio.create_task(apic_worker())


@userge.add_task
async def apic_worker():
user_dict = await userge.get_user_dict('me')
user = '@' + user_dict['uname'] if user_dict['uname'] else user_dict['flname']
while UPDATE_PIC:
img = Image.open(BASE_PIC)
i_width, i_height = img.size
s_font = ImageFont.truetype("resources/font.ttf", int((35 / 640)*i_width))
l_font = ImageFont.truetype("resources/font.ttf", int((50 / 640)*i_width))
draw = ImageDraw.Draw(img)
current_h, pad = 10, 0
for user in textwrap.wrap(user, width=20):
u_width, u_height = draw.textsize(user, font=l_font)
draw.text(xy=((i_width - u_width) / 2, int((current_h / 640)*i_width)), text=user,
font=l_font, fill=(255, 255, 255))
current_h += u_height + pad
tim = datetime.datetime.now(
tz=datetime.timezone(datetime.timedelta(minutes=30, hours=5)))
date_time = (f"DATE: {tim.day}.{tim.month}.{tim.year}\n"
f"TIME: {tim.hour}:{tim.minute}:{tim.second}\n"
"UTC+5:30")
d_width, d_height = draw.textsize(date_time, font=s_font)
draw.multiline_text(
xy=((i_width - d_width) / 2, i_height - d_height - int((20 / 640)*i_width)),
text=date_time, fill=(255, 255, 255), font=s_font, align="center")
img.convert('RGB').save(MDFY_PIC)
await userge.set_profile_photo(MDFY_PIC)
os.remove(MDFY_PIC)
LOG.info("profile photo has been updated!")
await asyncio.sleep(Config.AUTOPIC_TIMEOUT)
Loading

0 comments on commit b9e2735

Please sign in to comment.