From 487cd1fbce895728f985f98b450259c80f000274 Mon Sep 17 00:00:00 2001 From: rking32 Date: Thu, 23 Apr 2020 20:23:33 +0530 Subject: [PATCH] optimizing userge --- README.md | 4 + app.json | 5 +- requirements.txt | 2 +- resources/tutorial.jpg | Bin 0 -> 58001 bytes userge/config.py | 4 +- userge/core/_userge/client.py | 108 ++++- userge/core/_userge/message.py | 21 +- userge/plugins/admin/gadmin.py | 168 +++----- userge/plugins/admin/lock.py | 56 +-- userge/plugins/fun/alive.py | 2 +- userge/plugins/fun/convert.py | 27 +- userge/plugins/fun/memes.py | 214 ++++------ userge/plugins/fun/type.py | 15 +- userge/plugins/help.py | 2 +- userge/plugins/misc/download.py | 14 +- userge/plugins/misc/gdrive.py | 570 ++++++++++++--------------- userge/plugins/misc/upload.py | 13 +- userge/plugins/misc/zip.py | 36 +- userge/plugins/tools/all.py | 2 +- userge/plugins/tools/cancel.py | 3 +- userge/plugins/tools/cleardir.py | 2 +- userge/plugins/tools/delete.py | 2 +- userge/plugins/tools/ids.py | 9 +- userge/plugins/tools/json.py | 9 +- userge/plugins/tools/loader.py | 11 +- userge/plugins/tools/logs.py | 2 +- userge/plugins/tools/ping.py | 2 +- userge/plugins/tools/repo.py | 2 +- userge/plugins/tools/restart.py | 22 +- userge/plugins/tools/sd.py | 10 +- userge/plugins/tools/search.py | 4 +- userge/plugins/tools/timeout.py | 34 +- userge/plugins/tools/updater.py | 28 +- userge/plugins/utils/admins.py | 18 +- userge/plugins/utils/afk.py | 26 +- userge/plugins/utils/direct_links.py | 18 +- userge/plugins/utils/dogbin.py | 18 +- userge/plugins/utils/executor.py | 42 +- userge/plugins/utils/filters.py | 20 +- userge/plugins/utils/google.py | 22 +- userge/plugins/utils/header.py | 24 +- userge/plugins/utils/notes.py | 30 +- userge/plugins/utils/pmpermit.py | 78 ++-- userge/plugins/utils/purge.py | 20 +- userge/plugins/utils/speedtest.py | 2 +- userge/plugins/utils/sudo.py | 52 +-- userge/plugins/utils/thumbnail.py | 13 +- userge/plugins/utils/translate.py | 40 +- userge/plugins/utils/ud.py | 14 +- userge/plugins/utils/webss.py | 2 +- userge/plugins/utils/welcome.py | 117 +++--- userge/plugins/utils/whois.py | 14 +- userge/plugins/utils/wikipedia.py | 19 +- userge/versions.py | 2 +- 54 files changed, 839 insertions(+), 1155 deletions(-) create mode 100644 resources/tutorial.jpg diff --git a/README.md b/README.md index 7735f02a6..0d9b85476 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,10 @@ async def testing(message: Message): > TODO: add Docker Support. +### Video Tutorial 🎥 + + [![Tutorial](resources/tutorial.jpg)](https://youtu.be/-XJj686zeiY) + ### Support & Discussions 👥 > Head over to the [Discussion Group](https://t.me/slbotsbugs) and [Update Channel](https://t.me/theUserge) diff --git a/app.json b/app.json index 3a3759a75..3b5b8af86 100644 --- a/app.json +++ b/app.json @@ -1,13 +1,16 @@ { "name": "Userge", "description": "telegram pluggable userbot", + "logo": "https://imgur.com/download/Inyeb1S", "keywords": [ "userge", "telegram", "pluggable", "userbot" ], - "repository": "https://github.com/uaudith/Userge", + "repository": "https://github.com/UsergeTeam/Userge", + "website": "https://github.com/Userge", + "success_url": "https://t.me/theUserge", "env": { "APP_ID": { "description": "Get this value from https://my.telegram.org" diff --git a/requirements.txt b/requirements.txt index 119c6134a..e0db4f287 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,6 +23,6 @@ selenium setuptools>=40.3.0 speedtest-cli tgcrypto -urbandict +urbandict==0.5 wget wikipedia diff --git a/resources/tutorial.jpg b/resources/tutorial.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b4eb986eea98ece31742c8f91d13050957a61088 GIT binary patch literal 58001 zcmeFa2Ut_vx-L8;Xi!Q-dW`}K3Wx}()L=nGR60>wR6t4uM5?qPND+a62rN+n=|zb2 zPNWNp^dca=BalFV5JK`#*IsMyy~;iJoO}QM-~a5p!ZT-*k(rq}#vJ1t@ArQ1H=qyF z$AN=aFKb-}AP@*}1^ff(!@xy=Y2QBRzP(IPD0KgRrUNXTtSrpTEPRJJV4OnyaA6^S zLBYdfC&dqoNQnvxN}N3|bxKxVULG#4sCw?S%1Jr-(?3oE*}s233o{EZD=Y8mBZ5ax z|Cb;14*)yUp3c1h14IPa!wz9!htL}VH~>KQf>-A_i^amfr>bDo_-wtmPzzNK^>QV7eP$!?!$on z2e^57`S_0>6PGxCLSEs_*>j3Y7cXgC*1V#1)xglm7>sy?y-y zgI|XxCa0!nX6NP?7Kv-?q>arj@;2p1y&zyce|`L|V!x{wJ6NwhjEoG7&>!`J?C}6M z26o21M`ZUMIWjG_KOkSCF@mnc zNY7$#p6WZ@T5OGKwIs-rE3$nH&sS~Wa^zG^UZG9Ul{L-Yn0BjH;>D)#!}zic)TWUE zyv<)NBc&Ee2ZG*A(g6x=1T%J=4m5Vr0cPbUIzWP#(}7w8I`A|ZmLq|Sr2`W-o_Jc| z7JRD>LzKtVe<5Oap(}{h7j$6KmSHhWat1@bH7Y{~l6PBn*OI8$;e?`U6dgFfgWZ`y zkP`q(O4v4v#_jQp4$LE*>3~lr9pKQUO0DwHflj|E+O`hun7>-qU)S_kJN>WsCxc1U7~(OE>%biJC+SiLne9i;#)2XKF$NVmGa0-<{n5 zLHjlEP3hE>xTKC0=UB(xN zeh)ETSVcsQ`XN2N?bh8zm1)`rprxTXC%%=n9<$R6Ir_hQ`0KP&9~G0KdK#R-@3%dg z7j+J?4EM4Y^L~Nc^$kXG@<;#jPLq z9C1C|mjg(og#FuXClsx2TG|Ot7+NKzYnkaZsop8Z?m_VmK6TWLN)u$S3efDd>VyW8 z*BjS7lNtw*>8)kPYs>K}Cm8DB7WjyVY17j^(<+lM|IuT(7-PQQ&5?^FMVoOuB7&=zRrw=~s4vr?cx^zwr8sQR;!_TQ+?bG0S+d8K;{x@xs;&2nCr4iq5^kRenb#6soajY!mN zF=TS}6Tbw)XV*4)Png8d+kw;Bht7Dv?v{}H05hrl_)Zb%K9S?9D*++>3rw~eM}KWO z;mNYg_%gp8Z;|Q?u_8Ci_bfDpH5K#gzUXnxHoGf=vIfGN^PG^*-&>e}hxb2j2OYqE zgV8G5sr@ze)rhG%s^2_jA+mBpDU#EufqQh4MMJZE%?+FVN&Ll{r=ofR$gI1UrNHe z{I`!8*`w;;sKcIR@b4CD1MG|r6Egcw8#3u}t z|8}7GtC;PsZ)99Q9CplQ(4b=sVe&TT%n=P}_N@QuwCMDxs@E~*&=A*MZlaij{_N7{ z(`gS(O%9*FVydVT1@P{oU+3r6TZr`dC?9QaZ+{XqS{PJTt_jrb&gy!8oA=h;mzNpn z8aVlEdH-B5&e5{`;3cVKlh=fZm_^lGc2c{m!AkzTRcqT5{}hu@|vTH`5mq5 zdvclGxoBEk**yhEN@mpwrU?}ibt2x8-ds{FeW7?eq9l?tk=47V<%1Jrn*P-Cqedrp(tKB7CPY^{8n0<`g?pQijaxr%#-i z6HmlH2=3_5vEx?b{kk_JZF9^{M@36%#3!Qo$i>9haiDh&c_$4wF_k!4P+Q95@ z`|)SCVxGOa^}68su|W=iyZaLqey432iU~Y{#dg(4?XpJ~N{1qv-_B*3zDg2rW8aWmbdK3Z zCXweZJZrF!#djZO5iMII-y1P3wr{kl-7l&zpSXvNosj0K+f=fsuyIysPi-@b-VZ2S zO+kC$v5!DnMaX@iaa6H)6XJm*tTz~5$FN=cSeD1 z$+MLTibhU)2|(P*jM@?cf*M*0-+iP3GAm)*C;m_b%>O$&6Os)yHB8G2IG32s($E$Y z7I5M^4FTe-xwGpg0MTWuqrY&&v4EzK<+n}gx5(>9H2cf_D;q*G4ZEw4sg!(`{~WQQ zMVn9FpR$NvLNU;RkI#PC{TC<-6YlvR%aYjwegUh$g4TbF=YNKNB`aJLbO4T++PX*w z@?9_r$uJ%erlVzym*7(-As{NWUi@ZBwPiT{uWX6RD|Dbwd?%%%azT_17$&WR0SSK? zEPsuk|BmB_fFRq2f~>J2hRO@0oz#y?<)mB3b; zP~3*Zokyt@)GZd_-bb9w4^Th zbZ2hqmRH$LI>6uicc`b%_u^kbyZ#z|6xqO?QSa_fGyqZ`}LJN4;CbsKJ`_$ko({M;|>9z zQ^F*Gf7SMjKa}tID**RD_DA0DPq{#~!~d#l`agNzyf?5F9WutG`PUaf_1|6864w2S)Hz zBcD|wy#75|x!FVMdUeFna--*`zg>9$1=d~LfqQ|sg>4`2#tft(K6XOmy1>{hvfF}@ zEIILNb^lk?(u39(V5i5cbU-%J6^S_WN^$Jy$H%)9$`rA>VjPV z*}LFXR@V{Y`ESnlkNHY|9qeuQ#Y~_x8gjjc`yO7}| zE;Y9mVT;)o@23MBlq3qXF7%V@e}Do0UFWRdSwJ5bl%>yMI`ACz!$$p}6ZnA@^o-09 z1MRA7(#8U8O<}{~frTVl2OQNrOV@K2r5~Q;R|wyJc>9i*F0`c>*$cYZ9f>g7?&>Zr zmBzPT2adxUI)LwmtTp-Ke}tMzD9VP;j2VI|Hx~$g;0;=h+-_2hnvmqRvYzF&J7wXQ zUn-sxE{3@O&gP-+AY1T!i0LeQIFnlq7L5o*`J-EPlZOKM|wuSJ)&ikB+$Z%_cTvO$lGyu$@F>xF#* zv!W$k3+5^1MB4-M4wZ&VLi-BVTDU_Rl- z{(doaaPBa&pKFE=2+7OlP*oBacup^@G5c#;&yT$Y6_~oXR2m0Wyz3aDskA8ntMp9! zwv*O0Xl~Hv9CCq`q0+y4<+e&`>hj%-xmNx z_>eYDqeg&MI}Dm{g>^Sy(H$+!$Ffw+z%XWhU#(;Eo?_B$Rea?fO>ub(l#viaHx z=R--e7=F?#IFqOM^-xWl)LWNQ3+qd&EToCBDGXJV@^0uxpaW|o;ZTv;6+aEfaY%0% zu#wqS+{%Mq=zmum49=zp=G>Bkg%1v}H+^~LBp4|>TVEyUCsKX7XY&d1J`%DbQkW>S zJ$rYU61L^E$8)lwMM-8j4;rg-No;d^CRMd!1?JT3uY#C_)d`HTnY3olKd;#cuucob zjyB_WPVJ&wa#x#m+l>5Acm%NA$Yb9?YwSKe50bvEyrZ`(1+cZkL$~CGe!Lk)A9i z4riInCOK&nj-Oy6JgI!5t~%W@ZIb)&?0a!%VgEgtBcrvK``q%hO{=|YF0Y|qzMgqG zn6TL~q`ypEh208p-JEIB?b1n| zwg%OGo(Qu|Ty`C!m9XUaDQAo56rcM<_h*?+Rz(dioa!g|dRzci9RqdvWgpG5u&Ifb zQ2pCyp7EL4?6fh<&{X#NxTFpr-7LFfcSOx>i@kAhDfl*QJ-?v|&ZD9;nI}yeu1E>) z*4cP^z!IZ4z0p$guvUN$L}!AWA8rsq0;3!G6J*Qrthblwz!S8NLuzh4AGSBK1Uoqv zl*nI2C{5*#ome{OM2$nc2kklg(>_C+5h8gYl`U{VTU}UaeC#W&c}OCksv}$eI{ej5 zot2(N%(HD|&P~sY4MSFUq)6y<{`^kaB& zT>Na555ldeV0{45<}X9_>H5y`LC-?dhQ;IHs7PuGaN+%Z(((st?%WtF8Err`#tFYl zSGRguao5ujWvm+H1#j$l)<1ftQ>0tUb-`hZW54;#ZLJT7A&*xr@Pub|@5u&rn`@tV z`6Je(23RyDqhnFY@O)bap87F}4w%vWtzf#sUJ`0JCU1tuFoW* z&q3~3Ag=a#-0UqnbwE*!#5FD~O9nw1Te?DK@bbi|%U5@EoPMg<6n+6&;h5*wXp4Py zt@y#^Q+H5=eDOxa-fGeO3u88g{0?<9RwcafFp|P7zsxdoeuI19t>V&((vB~8%_E^% zEnFnEm>iQO6Qj~}tBK{6gI6M!)!|1xmnK&7#?eHfp{IFbViz9<&R{I(eRCsl>V&JZ~v;bfZvY!}5eb!UV`gPedGOy)eAMt@ro?^8rwJf6GDiy7ka~>4JqB z88R}$b71Pbi5n?Sn7=G+>65a_%H=i=+6N)OjPhZpAy`w_h*P5SaS%}?-jl{>CBwY> z)da~prcdM6FO`g5R{7W|ihU~>MpzBSGv=!(JDkaTdv(ji%com?r1jtid=#GNjSuj- zg`SdOyO=Ya8Fw=_PHN7QEv0h5sFtOb8_PSU+g=B~I-wu>7EpT-)0w82f$F600=1)L zHx=2b8f_hacBg7>CK6J>pDGtNOa{XuN0o+YHPf^gkd1U_%pnyHnaFBo;ds`?TZK0Y zx3PS;A22mTgiD5uBzLcNTnqeCTNySaHRbb;%Vk3zGL9m&BgaT`rkHV24AH2LdV%cZ zO`xG=ogZ;cBTY-S__^xLtPbkb_!@z(5jGffjg&Jn;}^i_j;GTy!=$w2OfK9X8Uqz|La$>IT)hd^1MtaW2O(nDoFY`{TW~mp!LiwyCz4JB|KP?9U&gDB4h=qXj&rs$$p~af>79Bv&*nkx! zv89hYvDhz^?p!L05rVydz^@^ndk&AYXgMit1!cr|%|yJ&bk|HN!}V7t1!H(piLqVX z8v?E+z4a^CLuOvEm3LfRw#Ze7GmMzFqn*V#n!7¬SUfdu5R+OA)L3}ZnxO(_ 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 E06aGhR{#J2 literal 0 HcmV?d00001 diff --git a/userge/config.py b/userge/config.py index 75f17f6bb..24b7d4aa0 100644 --- a/userge/config.py +++ b/userge/config.py @@ -78,6 +78,8 @@ class Config: HEROKU_GIT_URL = None + PUSHING = False + MSG_DELETE_TIMEOUT = 120 WELCOME_DELETE_TIMEOUT = 120 @@ -136,7 +138,7 @@ class Config: LOG.info("Downloading BINs...") for binary, path in BINS.items(): - LOG.debug(f"Downloading {binary}...") + LOG.debug("Downloading %s...", binary) downloader = SmartDL(binary, path, progress_bar=False) downloader.start() os.chmod(path, 0o755) diff --git a/userge/core/_userge/client.py b/userge/core/_userge/client.py index 634011d59..65f0102aa 100644 --- a/userge/core/_userge/client.py +++ b/userge/core/_userge/client.py @@ -196,14 +196,14 @@ async def send_message(self, def on_cmd(self, command: str, - about: str, + about: Union[str, Dict[str, str]], group: int = 0, name: str = '', trigger: str = '.', filter_me: bool = True, - **kwargs: Union[str, bool]) -> Callable[[PYROFUNC], PYROFUNC]: + **kwargs: Union[str, bool, Dict[str, str]]) -> Callable[[PYROFUNC], PYROFUNC]: """ - Decorator for handling messages. + \nDecorator for handling messages. Example: @userge.on_cmd('test', about='for testing') @@ -211,8 +211,19 @@ def on_cmd(self, Parameters: command (``str``): command name to execute (without trigger!). - about (``str``): - help string for command. + about (``str`` | ``dict``): + help string or dict for command. + { + 'header': ``str``, + 'description': ``str``, + 'flags': ``str`` | ``dict``, + 'options': ``str`` | ``dict``, + 'types': ``str`` | ``list``, + 'usage': ``str``, + 'examples': ``str`` | ``list``, + 'others': ``str``, + 'any_title': ``str`` | ``list`` | ``dict`` + } group (``int``, *optional*): The group identifier, defaults to 0. name (``str``, *optional*): @@ -331,13 +342,93 @@ def get_help(self, def __add_help(self, module: str, cname: str = '', - chelp: str = '', + chelp: Union[str, Dict[str, str]] = '', **_: Union[str, bool]) -> None: if cname: LOG.debug(LOG_STR, f"Updating Help Dict => [ {cname} : {chelp} ]") mname = module.split('.')[-1] + if isinstance(chelp, dict): + tmp_chelp = '' + + if 'header' in chelp: + tmp_chelp += f"__**{chelp['header'].title()}**__" + del chelp['header'] + + if 'description' in chelp: + tmp_chelp += ("\n\n📝 --**Description**-- :\n\n " + f"__{chelp['description'].capitalize()}__") + del chelp['description'] + + if 'flags' in chelp: + tmp_chelp += f"\n\n⛓ --**Available Flags**-- :\n" + + if isinstance(chelp['flags'], dict): + for f_n, f_d in chelp['flags'].items(): + tmp_chelp += f"\n ▫ `{f_n}` : __{f_d.lower()}__" + else: + tmp_chelp += f"\n {chelp['flags']}" + del chelp['flags'] + + if 'options' in chelp: + tmp_chelp += f"\n\n🕶 --**Available Options**-- :\n" + + if isinstance(chelp['options'], dict): + for o_n, o_d in chelp['options'].items(): + tmp_chelp += f"\n ▫ `{o_n}` : __{o_d.lower()}__" + else: + tmp_chelp += f"\n {chelp['options']}" + del chelp['options'] + + if 'types' in chelp: + tmp_chelp += f"\n\n🎨 --**Supported Types**-- :\n\n" + + if isinstance(chelp['types'], list): + for _opt in chelp['types']: + tmp_chelp += f" `{_opt}` ," + else: + tmp_chelp += f" {chelp['types']}" + del chelp['types'] + + if 'usage' in chelp: + tmp_chelp += f"\n\n✒ --**Usage**-- :\n\n`{chelp['usage']}`" + del chelp['usage'] + + if 'examples' in chelp: + tmp_chelp += f"\n\n✏ --**Examples**-- :\n" + + if isinstance(chelp['examples'], list): + for ex_ in chelp['examples']: + tmp_chelp += f"\n `{ex_}`\n" + else: + tmp_chelp += f"\n `{chelp['examples']}`" + del chelp['examples'] + + if 'others' in chelp: + tmp_chelp += f"\n\n📎 --**Others**-- :\n\n{chelp['others']}" + del chelp['others'] + + if chelp: + for t_n, t_d in chelp.items(): + tmp_chelp += f"\n\n⚙ --**{t_n.title()}**-- :\n" + + if isinstance(t_d, dict): + for o_n, o_d in t_d.items(): + tmp_chelp += f"\n ▫ `{o_n}` : __{o_d.lower()}__" + + elif isinstance(t_d, list): + tmp_chelp += '\n' + for _opt in t_d: + tmp_chelp += f" `{_opt}` ," + + else: + tmp_chelp += '\n' + tmp_chelp += t_d + + chelp = tmp_chelp + del tmp_chelp + if mname in self.__help_dict: self.__help_dict[mname].update({cname: chelp}) @@ -348,7 +439,8 @@ def __build_decorator(self, log: str, filters: Filters, group: int, - **kwargs: Union[str, bool]) -> Callable[[PYROFUNC], PYROFUNC]: + **kwargs: Union[ + str, bool, Dict[str, str]]) -> Callable[[PYROFUNC], PYROFUNC]: def __decorator(func: PYROFUNC) -> PYROFUNC: @@ -441,6 +533,8 @@ async def restart(self) -> None: os.execl(sys.executable, sys.executable, '-m', 'userge') + sys.exit() + def begin(self) -> None: """ This will start the Userge. diff --git a/userge/core/_userge/message.py b/userge/core/_userge/message.py index cb611643a..a9ffd8a9e 100644 --- a/userge/core/_userge/message.py +++ b/userge/core/_userge/message.py @@ -126,23 +126,12 @@ def __msg_to_dict(message: RawMessage) -> Dict[str, object]: if '_client' in kwargs_: del kwargs_['_client'] - if '_Message__channel' in kwargs_: - del kwargs_['_Message__channel'] + for key_ in ['channel', 'filtered', 'process_canceled', + 'filtered_input_str', 'flags', 'kwargs']: + tmp_ = '_Message__' + key_ - if '_Message__filtered' in kwargs_: - del kwargs_['_Message__filtered'] - - if '_Message__process_canceled' in kwargs_: - del kwargs_['_Message__process_canceled'] - - if '_Message__filtered_input_str' in kwargs_: - del kwargs_['_Message__filtered_input_str'] - - if '_Message__flags' in kwargs_: - del kwargs_['_Message__flags'] - - if '_Message__kwargs' in kwargs_: - del kwargs_['_Message__kwargs'] + if tmp_ in kwargs_: + del kwargs_[tmp_] return kwargs_ diff --git a/userge/plugins/admin/gadmin.py b/userge/plugins/admin/gadmin.py index 13bbfcd42..4aec99310 100644 --- a/userge/plugins/admin/gadmin.py +++ b/userge/plugins/admin/gadmin.py @@ -6,6 +6,7 @@ # # All rights reserved. + import time from pyrogram import ChatPermissions from pyrogram.errors import (FloodWait, @@ -18,6 +19,7 @@ CHANNEL = userge.getCLogger(__name__) + async def is_admin(message: Message): check_user = await userge.get_chat_member(message.chat.id, message.from_user.id) user_type = check_user.status @@ -36,6 +38,7 @@ async def is_admin(message: Message): else: return True + async def is_sudoadmin(message: Message): check_user = await userge.get_chat_member(message.chat.id, message.from_user.id) user_type = check_user.status @@ -55,20 +58,11 @@ async def is_sudoadmin(message: Message): return True -@userge.on_cmd("promote", about="""\ -__use this to promote group members__ - -**Usage:** - -`Provides admin rights to the person in the supergroup.` - -[NOTE: Requires proper admin rights in the chat!!!] - - -**Example:** - - `.promote [username | userid] or [reply to user]`""") - +@userge.on_cmd("promote", about={ + 'header': "use this to promote group members", + 'description': "Provides admin rights to the person in the supergroup.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'examples': ".promote [username | userid] or [reply to user]"}) async def promote_usr(message: Message): """ this function can promote members in tg group @@ -179,20 +173,11 @@ async def promote_usr(message: Message): text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("demote", about="""\ -__use this to demote group members__ - -**Usage:** - -`Remove admin rights from admin in the supergroup.` - -[NOTE: Requires proper admin rights in the chat!!!] - - -**Example:** - - `.demote [username | userid] or [reply to user]`""") - +@userge.on_cmd("demote", about={ + 'header': "use this to demote group members", + 'description': "Remove admin rights from admin in the supergroup.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'examples': ".demote [username | userid] or [reply to user]"}) async def demote_usr(message: Message): """ this function can demote members in tg group @@ -301,20 +286,12 @@ async def demote_usr(message: Message): await message.edit( text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("ban", about="""\ -__use this to ban group members__ - -**Usage:** - -`Ban member from supergroup.` - -[NOTE: Requires proper admin rights in the chat!!!] - - -**Example:** - - `.ban [username | userid] or [reply to user] :reason (optional)`""") +@userge.on_cmd("ban", about={ + 'header': "use this to ban group members", + 'description': "Ban member from supergroup.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'examples': ".ban [username | userid] or [reply to user] :reason (optional)"}) async def ban_usr(message: Message): """ this function can ban user from tg group @@ -388,20 +365,12 @@ async def ban_usr(message: Message): await message.edit( text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("unban", about="""\ -__use this to unban group members__ - -**Usage:** - -`Unban member from supergroup.` - -[NOTE: Requires proper admin rights in the chat!!!] - - -**Example:** - - `.unban [username | userid] or [reply to user]`""") +@userge.on_cmd("unban", about={ + 'header': "use this to unban group members", + 'description': "Unban member from supergroup.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'examples': ".unban [username | userid] or [reply to user]"}) async def unban_usr(message: Message): """ this function can unban user from tg group @@ -484,20 +453,12 @@ async def unban_usr(message: Message): await message.edit( text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("kick", about="""\ -__use this to kick group members__ - -**Usage:** - -`Kick member from supergroup. member can rejoin the group again if they want.` - -[NOTE: Requires proper admin rights in the chat!!!] - - -**Example:** - - `.kick [username | userid] or [reply to user]""") +@userge.on_cmd("kick", about={ + 'header': "use this to kick group members", + 'description': "Kick member from supergroup. member can rejoin the group again if they want.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'examples': ".kick [username | userid] or [reply to user]"}) async def kick_usr(message: Message): """ this function can kick user from tg group @@ -590,26 +551,18 @@ async def kick_usr(message: Message): await message.edit( text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("mute", about="""\ -__use this to mute group members__ - -**Usage:** - -`Mute member in the supergroup. you can only use one flag for command` - -[NOTE: Requires proper admin rights in the chat!!!] - -**Available Flags:** -`-m` : __minutes__ -`-h` : __hours__ -`-d` : __days__ - - -**Example:** - - `.mute -flag [username | userid] or [reply to user] :reason (optional)` - `.mute -d1 @someusername/userid/replytouser SPAM` (mute for one day:reason SPAM)""") +@userge.on_cmd("mute", about={ + 'header': "use this to mute group members", + 'description': "Mute member in the supergroup. you can only use one flag for command.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'flags': { + '-m': "minutes", + '-h': "hours", + '-d': "days"}, + 'examples': [ + ".mute -flag [username | userid] or [reply to user] :reason (optional)", + ".mute -d1 @someusername/userid/replytouser SPAM (mute for one day:reason SPAM)"]}) async def mute_usr(message: Message): """ this function can mute user from tg group @@ -833,20 +786,12 @@ async def mute_usr(message: Message): await message.edit( text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("unmute", about="""\ -__use this to unmute group members__ - -**Usage:** - -`Unmute member from supergroup.` - -[NOTE: Requires proper admin rights in the chat!!!] - - -**Example:** - - `.unmute [username | userid] or [reply to user]`""") +@userge.on_cmd("unmute", about={ + 'header': "use this to unmute group members", + 'description': "Unmute member from supergroup.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'examples': ".unmute [username | userid] or [reply to user]"}) async def unmute_usr(message: Message): """ this function can unmute user from tg group @@ -967,24 +912,15 @@ async def unmute_usr(message: Message): await message.edit( text=r"`i don't have proper permission to do that! ¯\_(ツ)_/¯`", del_in=0) -@userge.on_cmd("zombies", about="""\ -__use this to clean zombie accounts__ - -**Usage:** - -`check & remove zombie (deleted) accounts from supergroup.` - -[NOTE: Requires proper admin rights in the chat!!!] - -**Available Flags:** - -`-c` : __clean__ - -**Example:** - - `.zombies [check deleted accounts in group]` - `.zombies -c [remove deleted accounts from group]`""") +@userge.on_cmd("zombies", about={ + 'header': "use this to clean zombie accounts", + 'description': "check & remove zombie (deleted) accounts from supergroup.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'flags': {'-c': "clean"}, + 'examples': [ + ".zombies [check deleted accounts in group]", + ".zombies -c [remove deleted accounts from group]"]}) async def zombie_clean(message: Message): """ this function can remove deleted accounts from tg group diff --git a/userge/plugins/admin/lock.py b/userge/plugins/admin/lock.py index 143a8228d..85883920b 100644 --- a/userge/plugins/admin/lock.py +++ b/userge/plugins/admin/lock.py @@ -13,22 +13,15 @@ CHANNEL = userge.getCLogger(__name__) -@userge.on_cmd("lock", about="""\ -__use this to lock group permissions__ -**Usage:** - -`Allows you to lock some common permission types in the chat.` - -[NOTE: Requires proper admin rights in the chat!!!] - -**Available types to Lock Permissions:** - -`all, msg, media, polls, invite, pin, info, webprev, animations, games, stickers, inlinebots` - -**Example:** - - `.lock [all | type]`""") +@userge.on_cmd("lock", about={ + 'header': "use this to lock group permissions", + 'description': "Allows you to lock some common permission types in the chat.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'types': [ + 'all', 'msg', 'media', 'polls', 'invite', 'pin', 'info', + 'webprev', 'inlinebots', 'animations', 'games', 'stickers'], + 'examples': ".lock [all | type]"}) async def lock_perm(message: Message): """ this function can lock chat permissions from tg group @@ -159,22 +152,14 @@ async def lock_perm(message: Message): text=r"`i don't have permission to do that >︿<`", del_in=0) -@userge.on_cmd("unlock", about="""\ -__use this to unlock group permissions__ - -**Usage:** - -`Allows you to unlock some common permission types in the chat.` - -[NOTE: Requires proper admin rights in the chat!!!] - -**Available types to Unlock Permissions:** - -`all, msg, media, polls, invite, pin, info, web preview, other [animations, games, stickers, inline bots]` - -**Example:** - - `.unlock [all | type]`""") +@userge.on_cmd("unlock", about={ + 'header': "use this to unlock group permissions", + 'description': "Allows you to unlock some common permission types in the chat.\n" + "[NOTE: Requires proper admin rights in the chat!!!]", + 'types': [ + 'all', 'msg', 'media', 'polls', 'invite', 'pin', 'info', + 'webprev', 'inlinebots', 'animations', 'games', 'stickers'], + 'examples': ".unlock [all | type]"}) async def unlock_perm(message: Message): """ this function can unlock chat permissions from tg group @@ -315,12 +300,9 @@ async def unlock_perm(message: Message): text=r"`i don't have permission to do that >︿<`", del_in=0) -@userge.on_cmd("vperm", about="""\ -__use this to view group permissions__ - -**Usage:** - -`Allows you to view permission types on/off status in the chat.`""") +@userge.on_cmd("vperm", about={ + 'header': "use this to view group permissions", + 'description': "Allows you to view permission types on/off status in the chat."}) async def view_perm(message: Message): """ this function can check chat permissions from tg group diff --git a/userge/plugins/fun/alive.py b/userge/plugins/fun/alive.py index c91976283..5723efeb4 100644 --- a/userge/plugins/fun/alive.py +++ b/userge/plugins/fun/alive.py @@ -14,7 +14,7 @@ LOGO_STICKER_ID, LOGO_STICKER_REF = None, None -@userge.on_cmd("alive", about="__This command is just for fun XD__") +@userge.on_cmd("alive", about={'header': "This command is just for fun"}) async def alive(message: Message): await message.delete() diff --git a/userge/plugins/fun/convert.py b/userge/plugins/fun/convert.py index 51dfc1073..7454d4722 100644 --- a/userge/plugins/fun/convert.py +++ b/userge/plugins/fun/convert.py @@ -10,12 +10,9 @@ from userge import userge, Message -@userge.on_cmd("small", about="""\ -__Make caps smaller__ - -**Usage:** - - `.small [text | reply to msg]`""") +@userge.on_cmd("small", about={ + 'header': "Make caps smaller", + 'usage': ".small [text | reply to msg]"}) async def small_(message: Message): text = message.input_str if message.reply_to_message: @@ -29,12 +26,9 @@ async def small_(message: Message): "ᴀʙᴄᴅᴇꜰɢʜɪᴊᴋʟᴍɴᴏᴘqʀꜱᴛᴜᴠᴡxʏᴢ"))) -@userge.on_cmd("lower", about="""\ -__Convert text to lowwer__ - -**Usage:** - - `.lower [text | reply to msg]`""") +@userge.on_cmd("lower", about={ + 'header': "Convert text to lowwer", + 'usage': ".lower [text | reply to msg]"}) async def lower_(message: Message): text = message.input_str if message.reply_to_message: @@ -47,12 +41,9 @@ async def lower_(message: Message): await message.edit(text.lower()) -@userge.on_cmd("upper", about="""\ -__Convert text to upper__ - -**Usage:** - - `.upper [text | reply to msg]`""") +@userge.on_cmd("upper", about={ + 'header': "Convert text to upper", + 'usage': ".upper [text | reply to msg]"}) async def upper_(message: Message): text = message.input_str if message.reply_to_message: diff --git a/userge/plugins/fun/memes.py b/userge/plugins/fun/memes.py index 2e90615d5..9c4c957fe 100644 --- a/userge/plugins/fun/memes.py +++ b/userge/plugins/fun/memes.py @@ -258,81 +258,79 @@ "(ノಠ ∩ಠ)ノ彡( \\o°o)\\", "“ヽ(´▽`)ノ”",) -@userge.on_cmd(":/$", about="__Check yourself, hint: `:/`__", name="kek", trigger='') +@userge.on_cmd(r"(?:\.kek|:/)$", + about={'header': "Check yourself, hint: `:/`"}, name=".kek", trigger='') async def kek_(message: Message): """kek""" kek = ["/", "\\"] - for i in range(1, 15): + for i in range(1, 9): time.sleep(0.3) await message.edit(":" + kek[i % 2]) -@userge.on_cmd("-_-$", about="__Check yourself, hint: `-_-`__", name="lol", trigger='') +@userge.on_cmd(r"(?:\.lol|-_-)$", + about={'header': "Check yourself, hint: `-_-`"}, name=".lol", trigger='') async def lol_(message: Message): """lol""" lol = "-_ " - for i in range(15): + for i in range(9): if i % 3 == 0: lol = "-_ " lol = lol[:-1] + "_-" await message.edit(lol, parse_mode="html") -@userge.on_cmd(";_;$", about="__Like `-_-` but crying, hint: `;_;`__", name="fun", trigger='') +@userge.on_cmd(r"(?:\.fun|;_;)$", + about={'header': "Check yourself, hint: `;_;`"}, name=".fun", trigger='') async def fun_(message: Message): """fun""" fun = ";_ " - for i in range(15): + for i in range(9): if i % 3 == 0: fun = ";_ " fun = fun[:-1] + "_;" await message.edit(fun, parse_mode="html") -@userge.on_cmd("Oof$", about="__Ooooof__", trigger='') +@userge.on_cmd("Oof$", about={'header': "Ooooof"}, trigger='') async def Oof_(message: Message): """Oof""" Oof = "Oo " - for _ in range(15): + for _ in range(6): Oof = Oof[:-1] + "of" await message.edit(Oof) -@userge.on_cmd("Hmm$", about="__Hmmmmm__", trigger='') +@userge.on_cmd("Hmm$", about={'header': "Hmmmmm"}, trigger='') async def Hmm_(message: Message): """Hmm""" Hmm = "Hm " - for _ in range(15): + for _ in range(4): Hmm = Hmm[:-1] + "mm" await message.edit(Hmm) -@userge.on_cmd("fp$", about="__Facepalm :P__") +@userge.on_cmd("fp$", about={'header': "Facepalm :P"}) async def facepalm_(message: Message): """facepalm_""" await message.edit("🤦‍♂") -@userge.on_cmd("cry$", about="__y u du dis, i cri__") +@userge.on_cmd("cry$", about={'header': "y u du dis, i cri"}) async def cry_(message: Message): """cry""" await message.edit(choice(CRI), parse_mode="html") -@userge.on_cmd("insult$", about="__Check yourself ;)__") +@userge.on_cmd("insult$", about={'header': "Check yourself ;)"}) async def insult_(message: Message): """insult""" await message.edit(choice(INSULT_STRINGS), parse_mode="html") -@userge.on_cmd("hi", about="""\ -__Greet everyone!__ - -**Usage:** - - `.hi` - `.hi [emoji | character]` - `.hi [emoji | character] [emoji | character]`""") +@userge.on_cmd("hi", about={ + 'header': "Greet everyone!", + 'usage': ".hi\n.hi [emoji | character]\n.hi [emoji | character] [emoji | character]"}) async def hi_(message: Message): """hi""" input_str = message.input_str @@ -365,43 +363,43 @@ async def hi_(message: Message): await message.edit(pay) -@userge.on_cmd("react$", about="__Make your userbot react to everything__") +@userge.on_cmd("react$", about={'header': "Make your userbot react to everything"}) async def react_(message: Message): """react""" await message.edit(choice(FACEREACTS), parse_mode="html") -@userge.on_cmd("shg$", about="__Shrug at it !!__") +@userge.on_cmd("shg$", about={'header': "Shrug at it !!"}) async def shrugger(message: Message): """shrugger""" await message.edit(choice(SHGS), parse_mode="html") -@userge.on_cmd("chase$", about="__You better start running__") +@userge.on_cmd("chase$", about={'header': "You better start running"}) async def chase_(message: Message): """chase""" await message.edit(choice(CHASE_STR), parse_mode="html") -@userge.on_cmd("run$", about="__Let Me Run, run, RUNNN!__") +@userge.on_cmd("run$", about={'header': "Let Me Run, run, RUNNN!"}) async def run_(message: Message): """run""" await message.edit(choice(RUNS_STR), parse_mode="html") -@userge.on_cmd("metoo$", about="__Haha yes__") +@userge.on_cmd("metoo$", about={'header': "Haha yes"}) async def metoo_(message: Message): """metoo""" await message.edit(choice(METOOSTR), parse_mode="html") -@userge.on_cmd("10iq$", about="__You retard !!__", name="10iq") +@userge.on_cmd("10iq$", about={'header': "You retard !!"}, name="10iq") async def iqless(message: Message): """iqless""" await message.edit("♿") -@userge.on_cmd("moon$", about="__kensar moon animation__") +@userge.on_cmd("moon$", about={'header': "kensar moon animation"}) async def moon_(message: Message): """moon""" deq = deque(list("🌗🌘🌑🌒🌓🌔🌕🌖")) @@ -416,7 +414,7 @@ async def moon_(message: Message): await message.delete() -@userge.on_cmd("clock$", about="__kensar clock animation__") +@userge.on_cmd("clock$", about={'header': "kensar clock animation"}) async def clock_(message: Message): """clock""" deq = deque(list("🕙🕘🕗🕖🕕🕔🕓🕒🕑🕐🕛")) @@ -431,12 +429,9 @@ async def clock_(message: Message): await message.delete() -@userge.on_cmd("bt$", about="""\ -__Believe me, you will find this useful__ - -**Usage:** - - `.bt [reply to msg]`""") +@userge.on_cmd("bt$", about={ + 'header': "Believe me, you will find this useful", + 'usage': ".bt [reply to msg]"}) async def bluetext(message: Message): """bluetext""" if message.reply_to_message: @@ -445,12 +440,9 @@ async def bluetext(message: Message): "/ARE /YOU /A /STUPID /ANIMAL /WHICH /IS /ATTRACTED /TO /COLOURS?") -@userge.on_cmd("f (.+)", about="""\ -__Pay Respects__ - -**Usage:** - - `.f [emoji | character]`""") +@userge.on_cmd("f (.+)", about={ + 'header': "Pay Respects", + 'usage': ".f [emoji | character]"}) async def payf_(message: Message): """payf""" paytext = message.input_str @@ -463,12 +455,9 @@ async def payf_(message: Message): await message.edit(pay) -@userge.on_cmd("clap", about="""\ -__Praise people!__ - -**Usage:** - - .clap [input | reply to msg]""") +@userge.on_cmd("clap", about={ + 'header': "Praise people!", + 'usage': ".clap [input | reply to msg]"}) async def clap_(message: Message): """clap""" input_str = message.input_or_reply_str @@ -484,14 +473,10 @@ async def clap_(message: Message): await message.edit(reply_text) -@userge.on_cmd("(\\w+)say (.+)", about=f"""\ -__cow which says things__ - -**Usage:** - - `.[any cowacter]say [text]` - - __cowacters:__ `{'`, `'.join(cow.COWACTERS)}`""", name="cowsay") +@userge.on_cmd("(\\w+)say (.+)", about={ + 'header': "cow which says things", + 'usage': ".[any cowacter]say [text]", + 'cowacters': f"`{'`, `'.join(cow.COWACTERS)}`"}, name="cowsay") async def cowsay_(message: Message): """cowsay""" arg = message.matches[0].group(1).lower() @@ -510,12 +495,9 @@ async def cowsay_(message: Message): await message.edit(f"`{cheese.milk(text).replace('`', '´')}`") -@userge.on_cmd("coinflip", about="""\ -__Flip a coin !!__ - -**Usage:** - - `.coinflip [heads | tails]`""") +@userge.on_cmd("coinflip", about={ + 'header': "Flip a coin !!", + 'usage': ".coinflip [heads | tails]"}) async def coin_(message: Message): """coin""" r = choice(["heads", "tails"]) @@ -551,12 +533,9 @@ async def coin_(message: Message): await message.edit("The coin landed on: **Tails**.") -@userge.on_cmd("slap", about="""\ -__reply to slap them with random objects !!__ - -**Usage:** - - .slap [input | reply to msg]""") +@userge.on_cmd("slap", about={ + 'header': "reply to slap them with random objects !!", + 'usage': ".slap [input | reply to msg]"}) async def slap_(message: Message): """slap""" u_id = message.input_str @@ -587,15 +566,9 @@ async def slap_(message: Message): "`Can't slap this person, need to fetch some sticks and stones !!`") -@userge.on_cmd("(yes|no|maybe|decide)$", about="""\ -__Make a quick decision__ - -**Usage:** - - `.decide` - `.yes` - `.no` - `.maybe`""", name="decide") +@userge.on_cmd("(yes|no|maybe|decide)$", about={ + 'header': "Make a quick decision", + 'examples': ['.decide', '.yes', '.no', '.maybe']}, name="decide") async def decide_(message: Message): """decide""" decision = message.matches[0].group(1).lower() @@ -623,12 +596,9 @@ async def decide_(message: Message): os.remove(path) -@userge.on_cmd("cp", about="""\ -__Copypasta the famous meme__ - -**Usage:** - - .cp [input | reply to msg]""") +@userge.on_cmd("cp", about={ + 'header': "Copypasta the famous meme", + 'usage': ".cp [input | reply to msg]"}) async def copypasta(message: Message): """copypasta""" input_str = message.input_or_reply_str @@ -663,12 +633,9 @@ async def copypasta(message: Message): await message.edit(reply_text) -@userge.on_cmd("vapor", about="""\ -__Vaporize everything!__ - -**Usage:** - - .vapor [input | reply to msg]""") +@userge.on_cmd("vapor", about={ + 'header': "Vaporize everything!", + 'usage': ".vapor [input | reply to msg]"}) async def vapor_(message: Message): """vapor""" input_str = message.input_or_reply_str @@ -692,12 +659,9 @@ async def vapor_(message: Message): await message.edit("".join(reply_text)) -@userge.on_cmd("str", about="""\ -__Stretch it__ - -**Usage:** - - .str [input | reply to msg]""") +@userge.on_cmd("str", about={ + 'header': "Stretch it", + 'usage': ".str [input | reply to msg]"}) async def stretch(message: Message): """stretch""" input_str = message.input_or_reply_str @@ -710,12 +674,9 @@ async def stretch(message: Message): sub(r"([aeiouAEIOUaeiouAEIOUаеиоуюяыэё])", (r"\1" * randint(3, 10)), input_str)) -@userge.on_cmd("zal", about="""\ -__Invoke the feeling of chaos__ - -**Usage:** - - .zal [input | reply to msg]""") +@userge.on_cmd("zal", about={ + 'header': "Invoke the feeling of chaos", + 'usage': ".zal [input | reply to msg]"}) async def zal_(message: Message): """zal""" input_str = message.input_or_reply_str @@ -747,12 +708,9 @@ async def zal_(message: Message): await message.edit("".join(reply_text)) -@userge.on_cmd("owo", about="""\ -__UwU__ - -**Usage:** - - .owo [input | reply to msg]""") +@userge.on_cmd("owo", about={ + 'header': "UwU", + 'usage': ".owo [input | reply to msg]"}) async def owo_(message: Message): """owo""" input_str = message.input_or_reply_str @@ -772,12 +730,9 @@ async def owo_(message: Message): await message.edit(reply_text) -@userge.on_cmd("mock", about="""\ -__Do it and find the real fun__ - -**Usage:** - - .mock [input | reply to msg]""") +@userge.on_cmd("mock", about={ + 'header': "Do it and find the real fun", + 'usage': ".mock [input | reply to msg]"}) async def mock_(message: Message): """mock""" input_str = message.input_or_reply_str @@ -799,12 +754,9 @@ async def mock_(message: Message): await message.edit("".join(reply_text)) -@userge.on_cmd("lfy", about="""\ -__Let me Google that for you real quick !!__ - -**Usage:** - - `.lfy [query | reply to msg]`""") +@userge.on_cmd("lfy", about={ + 'header': "Let me Google that for you real quick !!", + 'usage': ".lfy [query | reply to msg]"}) async def lfy_(message: Message): """lfy_""" query = message.input_or_reply_str @@ -822,24 +774,14 @@ async def lfy_(message: Message): await message.edit(f"Here you are, help yourself.\n[{query}]({r.json()['shorturl']})") -@userge.on_cmd("scam", about="""\ -__Create fake chat actions, for fun.__ - -**Available Actions:** - - `typing` (default), `playing`, - `upload_photo`, `upload_video`, - `upload_audio`, `upload_document`, - `upload_video_note`, `record_video`, - `record_audio`, `record_video_note`, - `find_location`, `choose_contact` - -**Usage:** - - `.scam` - `.scam [action]` - `.scam [time]` - `.scam [action] [time]`""") +@userge.on_cmd("scam", about={ + 'header': "Create fake chat actions, for fun.", + 'available actions': [ + 'typing (default)', 'playing', 'upload_photo', 'upload_video', + 'upload_audio', 'upload_document', 'upload_video_note', + 'record_video', 'record_audio', 'record_video_note', + 'find_location', 'choose_contact'], + 'usage': ".scam\n.scam [action]\n.scam [time]\n.scam [action] [time]"}) async def scam_(message: Message): """scam""" options = ('typing', 'upload_photo', 'record_video', 'upload_video', 'record_audio', diff --git a/userge/plugins/fun/type.py b/userge/plugins/fun/type.py index 82ae4afe5..e05c858ec 100644 --- a/userge/plugins/fun/type.py +++ b/userge/plugins/fun/type.py @@ -13,12 +13,9 @@ from userge import userge, Message -@userge.on_cmd("type", about="""\ -__Simulate a typewriter__ - -**Usage:** - - `.type [text | reply to msg]`""") +@userge.on_cmd("type", about={ + 'header': "Simulate a typewriter", + 'usage': ".type [text | reply to msg]"}) async def type_(message: Message): text = message.input_or_reply_str @@ -39,11 +36,11 @@ async def type_(message: Message): typing_text = old_text + typing_symbol try: - await message.try_to_edit(typing_text) + await message.try_to_edit(typing_text, sudo=False) time.sleep(s_t) - await message.try_to_edit(old_text) + await message.try_to_edit(old_text, sudo=False) time.sleep(s_t) except FloodWait as x_e: - time.sleep(x_e.x) \ No newline at end of file + time.sleep(x_e.x) diff --git a/userge/plugins/help.py b/userge/plugins/help.py index 72f3c67df..fc9d3939b 100644 --- a/userge/plugins/help.py +++ b/userge/plugins/help.py @@ -10,7 +10,7 @@ from userge import userge, Message -@userge.on_cmd("help", about="__to know how to use **USERGE** commands__") +@userge.on_cmd("help", about={'header': "Guide to use USERGE commands"}) async def helpme(message: Message): out, is_mdl_or_key = userge.get_help(message.input_str) cmd = message.input_str diff --git a/userge/plugins/misc/download.py b/userge/plugins/misc/download.py index b2d6d2015..1504be10d 100644 --- a/userge/plugins/misc/download.py +++ b/userge/plugins/misc/download.py @@ -19,16 +19,10 @@ LOGGER = userge.getLogger(__name__) -@userge.on_cmd("download", about="""\ -__download files to server__ - -**Usage:** - - `.download [url | reply to telegram media]` - -**Example:** - - `.download https://speed.hetzner.de/100MB.bin | testing upload.bin`""") +@userge.on_cmd("download", about={ + 'header': "Download files to server", + 'usage': ".download [url | reply to telegram media]", + 'examples': ".download https://speed.hetzner.de/100MB.bin | testing upload.bin"}) async def down_load_media(message: Message): await message.edit("Trying to Download...") diff --git a/userge/plugins/misc/gdrive.py b/userge/plugins/misc/gdrive.py index 9cb503337..0720ccd04 100644 --- a/userge/plugins/misc/gdrive.py +++ b/userge/plugins/misc/gdrive.py @@ -17,12 +17,15 @@ from threading import Thread from datetime import datetime from mimetypes import guess_type +from functools import wraps from httplib2 import Http + from googleapiclient.discovery import build from googleapiclient.errors import HttpError from googleapiclient.http import MediaFileUpload, MediaIoBaseDownload from oauth2client.client import OAuth2WebServerFlow from oauth2client.client import HttpAccessTokenRefreshError, FlowExchangeError + from userge import userge, Message, Config, get_collection from userge.utils import humanbytes, time_formatter @@ -705,6 +708,19 @@ def _del_perms(self, file_id: str) -> str: return removed_perms +def creds_dec(func): + + @wraps(func) + async def wrapper(self): + if CREDS: + await func(self) + + else: + await self._Worker__message.edit("Please run `.gsetup` first", del_in=5) + + return wrapper + + class Worker(GDrive): """ Worker Class for GDrive. @@ -827,29 +843,27 @@ async def reset_parent(self) -> None: await self.__message.edit("`Parents Reset successfully`", del_in=5) + @creds_dec async def search(self) -> None: """ Search files in GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive Search...`") - try: - out = await self._search( - self.__message.filtered_input_str, self.__message.flags) - - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) - return + await self.__message.edit("`Loading GDrive Search...`") + try: + out = await self._search( + self.__message.filtered_input_str, self.__message.flags) - await self.__message.edit_or_send_as_file( - out, disable_web_page_preview=True, - caption=f"search results for `{self.__message.filtered_input_str}`") + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) + return - else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, + caption=f"search results for `{self.__message.filtered_input_str}`") + @creds_dec async def list_folder(self) -> None: """ List files in GDrive folder or root. @@ -865,116 +879,107 @@ async def list_folder(self) -> None: await self.__message.err("Please send me a folder link") return - if CREDS: - await self.__message.edit("`Loading GDrive List...`") - - root = not bool(file_id) + await self.__message.edit("`Loading GDrive List...`") - try: - out = await self._search('*', self.__message.flags, file_id, root) + root = not bool(file_id) - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) - return + try: + out = await self._search('*', self.__message.flags, file_id, root) - await self.__message.edit_or_send_as_file( - out, disable_web_page_preview=True, caption=f"list results for `{file_id}`") + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) + return - else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, caption=f"list results for `{file_id}`") + @creds_dec async def upload(self) -> None: """ Upload file/folder to GDrive. """ - if CREDS: - upload_file_name = self.__message.input_str - - if not os.path.exists(upload_file_name): - await self.__message.err("invalid file path provided?") - return - - await self.__message.edit("`Loading GDrive Upload...`") + upload_file_name = self.__message.input_str - Thread(target=self._upload, args=(upload_file_name,)).start() - start_t = datetime.now() + if not os.path.exists(upload_file_name): + await self.__message.err("invalid file path provided?") + return - while not self._is_finished: - if self.__message.process_is_canceled: - self._cancel() + await self.__message.edit("`Loading GDrive Upload...`") - if self._progress is not None: - await self.__message.try_to_edit(self._progress) + Thread(target=self._upload, args=(upload_file_name,)).start() + start_t = datetime.now() - await asyncio.sleep(3) + while not self._is_finished: + if self.__message.process_is_canceled: + self._cancel() - end_t = datetime.now() - m_s = (end_t - start_t).seconds + if self._progress is not None: + await self.__message.try_to_edit(self._progress) - if isinstance(self._output, HttpError): - out = f"**ERROR** : `{self._output._get_reason()}`" + await asyncio.sleep(3) - elif self._output is not None and not self._is_canceled: - out = f"**Uploaded Successfully** __in {m_s} seconds__\n\n{self._output}" + end_t = datetime.now() + m_s = (end_t - start_t).seconds - elif self._output is not None and self._is_canceled: - out = self._output + if isinstance(self._output, HttpError): + out = f"**ERROR** : `{self._output._get_reason()}`" - else: - out = "`failed to upload.. check logs?`" + elif self._output is not None and not self._is_canceled: + out = f"**Uploaded Successfully** __in {m_s} seconds__\n\n{self._output}" - await self.__message.edit(out, disable_web_page_preview=True, log=True) + elif self._output is not None and self._is_canceled: + out = self._output else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + out = "`failed to upload.. check logs?`" + + await self.__message.edit(out, disable_web_page_preview=True, log=True) + @creds_dec async def download(self) -> None: """ Download file/folder from GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive Download...`") - - if not os.path.isdir(Config.DOWN_PATH): - os.mkdir(Config.DOWN_PATH) + await self.__message.edit("`Loading GDrive Download...`") - file_id, _ = self.__get_file_id() + if not os.path.isdir(Config.DOWN_PATH): + os.mkdir(Config.DOWN_PATH) - Thread(target=self._download, args=(file_id,)).start() - start_t = datetime.now() + file_id, _ = self.__get_file_id() - while not self._is_finished: - if self.__message.process_is_canceled: - self._cancel() + Thread(target=self._download, args=(file_id,)).start() + start_t = datetime.now() - if self._progress is not None: - await self.__message.try_to_edit(self._progress) + while not self._is_finished: + if self.__message.process_is_canceled: + self._cancel() - await asyncio.sleep(3) + if self._progress is not None: + await self.__message.try_to_edit(self._progress) - end_t = datetime.now() - m_s = (end_t - start_t).seconds + await asyncio.sleep(3) - if isinstance(self._output, HttpError): - out = f"**ERROR** : `{self._output._get_reason()}`" + end_t = datetime.now() + m_s = (end_t - start_t).seconds - elif self._output is not None and not self._is_canceled: - out = f"**Downloaded Successfully** __in {m_s} seconds__\n\n`{self._output}`" + if isinstance(self._output, HttpError): + out = f"**ERROR** : `{self._output._get_reason()}`" - elif self._output is not None and self._is_canceled: - out = self._output + elif self._output is not None and not self._is_canceled: + out = f"**Downloaded Successfully** __in {m_s} seconds__\n\n`{self._output}`" - else: - out = "`failed to download.. check logs?`" - - await self.__message.edit(out, disable_web_page_preview=True, log=True) + elif self._output is not None and self._is_canceled: + out = self._output else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + out = "`failed to download.. check logs?`" + await self.__message.edit(out, disable_web_page_preview=True, log=True) + + @creds_dec async def copy(self) -> None: """ Copy file/folder in GDrive. @@ -984,43 +989,40 @@ async def copy(self) -> None: await self.__message.edit("First set parent path by `.gset`", del_in=5) return - if CREDS: - await self.__message.edit("`Loading GDrive Copy...`") - - file_id, _ = self.__get_file_id() - - Thread(target=self._copy, args=(file_id,)).start() - start_t = datetime.now() + await self.__message.edit("`Loading GDrive Copy...`") - while not self._is_finished: - if self.__message.process_is_canceled: - self._cancel() + file_id, _ = self.__get_file_id() - if self._progress is not None: - await self.__message.try_to_edit(self._progress) + Thread(target=self._copy, args=(file_id,)).start() + start_t = datetime.now() - await asyncio.sleep(3) + while not self._is_finished: + if self.__message.process_is_canceled: + self._cancel() - end_t = datetime.now() - m_s = (end_t - start_t).seconds + if self._progress is not None: + await self.__message.try_to_edit(self._progress) - if isinstance(self._output, HttpError): - out = f"**ERROR** : `{self._output._get_reason()}`" + await asyncio.sleep(3) - elif self._output is not None and not self._is_canceled: - out = f"**Copied Successfully** __in {m_s} seconds__\n\n{self._output}" + end_t = datetime.now() + m_s = (end_t - start_t).seconds - elif self._output is not None and self._is_canceled: - out = self._output + if isinstance(self._output, HttpError): + out = f"**ERROR** : `{self._output._get_reason()}`" - else: - out = "`failed to copy.. check logs?`" + elif self._output is not None and not self._is_canceled: + out = f"**Copied Successfully** __in {m_s} seconds__\n\n{self._output}" - await self.__message.edit(out, disable_web_page_preview=True, log=True) + elif self._output is not None and self._is_canceled: + out = self._output else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + out = "`failed to copy.. check logs?`" + + await self.__message.edit(out, disable_web_page_preview=True, log=True) + @creds_dec async def move(self) -> None: """ Move file/folder in GDrive. @@ -1030,367 +1032,297 @@ async def move(self) -> None: await self.__message.edit("First set parent path by `.gset`", del_in=5) return - if CREDS: - await self.__message.edit("`Loading GDrive Move...`") - - file_id, _ = self.__get_file_id() + await self.__message.edit("`Loading GDrive Move...`") - try: - link = await self._move(file_id) + file_id, _ = self.__get_file_id() - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) + try: + link = await self._move(file_id) - else: - await self.__message.edit( - f"`{file_id}` **Moved Successfully**\n\n{link}", log=True) + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit( + f"`{file_id}` **Moved Successfully**\n\n{link}", log=True) + @creds_dec async def delete(self) -> None: """ Delete file/folder in GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive Delete...`") + await self.__message.edit("`Loading GDrive Delete...`") - file_id, _ = self.__get_file_id() + file_id, _ = self.__get_file_id() - try: - await self._delete(file_id) - - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) + try: + await self._delete(file_id) - else: - await self.__message.edit( - f"`{file_id}` **Deleted Successfully**", del_in=5, log=True) + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit( + f"`{file_id}` **Deleted Successfully**", del_in=5, log=True) + @creds_dec async def empty(self) -> None: """ Empty GDrive Trash. """ - if CREDS: - await self.__message.edit("`Loading GDrive Empty Trash...`") - try: - await self._empty_trash() - - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) + await self.__message.edit("`Loading GDrive Empty Trash...`") + try: + await self._empty_trash() - else: - await self.__message.edit( - "`Empty the Trash Successfully`", del_in=5, log=True) + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit( + "`Empty the Trash Successfully`", del_in=5, log=True) + @creds_dec async def get(self) -> None: """ Get details for file/folder in GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive GetDetails...`") + await self.__message.edit("`Loading GDrive GetDetails...`") - file_id, _ = self.__get_file_id() + file_id, _ = self.__get_file_id() - try: - meta_data = await self._get(file_id) + try: + meta_data = await self._get(file_id) - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) - return + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) + return - out = f"**I Found these Details for** `{file_id}`\n\n{meta_data}" + out = f"**I Found these Details for** `{file_id}`\n\n{meta_data}" - await self.__message.edit_or_send_as_file( - out, disable_web_page_preview=True, - caption=f"metadata for `{file_id}`") - - else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, + caption=f"metadata for `{file_id}`") + @creds_dec async def get_perms(self) -> None: """ Get all Permissions of file/folder in GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive GetPermissions...`") + await self.__message.edit("`Loading GDrive GetPermissions...`") - file_id, _ = self.__get_file_id() - - try: - out = await self._get_perms(file_id) + file_id, _ = self.__get_file_id() - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) - return + try: + out = await self._get_perms(file_id) - out = f"**I Found these Permissions for** `{file_id}`\n\n{out}" + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) + return - await self.__message.edit_or_send_as_file( - out, disable_web_page_preview=True, - caption=f"view perm results for `{file_id}`") + out = f"**I Found these Permissions for** `{file_id}`\n\n{out}" - else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, + caption=f"view perm results for `{file_id}`") + @creds_dec async def set_perms(self) -> None: """ Set Permissions to file/folder in GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive SetPermissions...`") - - file_id, _ = self.__get_file_id() + await self.__message.edit("`Loading GDrive SetPermissions...`") - try: - link = await self._set_perms(file_id) + file_id, _ = self.__get_file_id() - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) + try: + link = await self._set_perms(file_id) - else: - out = f"**Set Permissions successfully for** `{file_id}`\n\n{link}" - await self.__message.edit(out, disable_web_page_preview=True) + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + out = f"**Set Permissions successfully for** `{file_id}`\n\n{link}" + await self.__message.edit(out, disable_web_page_preview=True) + @creds_dec async def del_perms(self) -> None: """ Remove all permisiions of file/folder in GDrive. """ - if CREDS: - await self.__message.edit("`Loading GDrive DelPermissions...`") + await self.__message.edit("`Loading GDrive DelPermissions...`") - file_id, _ = self.__get_file_id() - - try: - out = await self._del_perms(file_id) + file_id, _ = self.__get_file_id() - except HttpError as h_e: - LOG.exception(h_e) - await self.__message.err(h_e._get_reason()) - return + try: + out = await self._del_perms(file_id) - out = f"**Removed These Permissions successfully from** `{file_id}`\n\n{out}" + except HttpError as h_e: + LOG.exception(h_e) + await self.__message.err(h_e._get_reason()) + return - await self.__message.edit_or_send_as_file( - out, disable_web_page_preview=True, - caption=f"removed perm results for `{file_id}`") + out = f"**Removed These Permissions successfully from** `{file_id}`\n\n{out}" - else: - await self.__message.edit("Please run `.gsetup` first", del_in=5) + await self.__message.edit_or_send_as_file( + out, disable_web_page_preview=True, + caption=f"removed perm results for `{file_id}`") -@userge.on_cmd("gsetup", about="__Setup GDrive Creds__") +@userge.on_cmd("gsetup", about={'header': "Setup GDrive Creds"}) async def gsetup_(message: Message): """gsetup""" await Worker(message).setup() -@userge.on_cmd("gconf", about="""\ -__Confirm GDrive Setup__ - -**Usage:** - - `.gconf [auth token]`""") +@userge.on_cmd("gconf", about={ + 'header': "Confirm GDrive Setup", + 'usage': ".gconf [auth token]"}) async def gconf_(message: Message): """gconf""" await Worker(message).confirm_setup() -@userge.on_cmd("gclear", about="__Clear GDrive Creds__") +@userge.on_cmd("gclear", about={'header': "Clear GDrive Creds"}) async def gclear_(message: Message): """gclear""" await Worker(message).clear() -@userge.on_cmd("gset", about="""\ -__Set parent id__ - - set destination by setting parent_id (root path). - this path is like working directory :) - -**Usage:** - - `.gset [drive folder link]` - - **drive folder link should be like this!** - ```https://drive.google.com/drive/folders/{file_id}``` - ```https://drive.google.com/drive/folderview?id={file_id}```""") +@userge.on_cmd("gset", about={ + 'header': "Set parent id", + 'description': "set destination by setting parent_id (root path). " + "this path is like working directory :)", + 'usage': ".gset [drive folder link]", + 'others': "**drive folder link should be like this!**\n" + "```https://drive.google.com/drive/folders/{file_id}```" + "```https://drive.google.com/drive/folderview?id={file_id}```"}) async def gset_(message: Message): """gset""" await Worker(message).set_parent() -@userge.on_cmd("greset", about="__Reset parent id__") +@userge.on_cmd("greset", about={'header': "Reset parent id"}) async def greset_(message: Message): """greset""" await Worker(message).reset_parent() -@userge.on_cmd("gfind", about="""\ -__Search files in GDrive__ - -**Available Flags:** - - `-l` : add limit to search (default limit 20) - `-f` : add to do a force search - -**Usage:** - - `.gfind [search query]` - `.gfind -l10 [search query]`""") +@userge.on_cmd("gfind", about={ + 'header': "Search files in GDrive", + 'flags': { + '-l': "add limit to search (default limit 20)", + '-f': "add to do a force search"}, + 'usage': ".gfind [search query]\n.gfind -l10 [search query]"}) async def gfind_(message: Message): """gfind""" await Worker(message).search() -@userge.on_cmd("gls", about="""\ -__List files in GDrive Folder or Root__ - -**Usage:** - - `.gls` for view content in root - `.gls -l10` add limit to it - `.gls [drive folder link]` (default limit 20) - `.gls -l10 [drive folder link]` (add limit) - - **drive folder link should be like this!** - ```https://drive.google.com/drive/folders/{file_id}``` - ```https://drive.google.com/drive/folderview?id={file_id}```""") +@userge.on_cmd("gls", about={ + 'header': "List files in GDrive Folder or Root", + 'flags': {'-l': "add limit to list (default limit 20)"}, + 'usage': ".gls for view content in root\n.gls -l10 add limit to it\n" + ".gls [drive folder link] (default limit 20)\n" + ".gls -l10 [drive folder link] (add limit)", + 'others': "**drive folder link should be like this!**\n" + "```https://drive.google.com/drive/folders/{file_id}```" + "```https://drive.google.com/drive/folderview?id={file_id}```"}) async def gls_(message: Message): """gls""" await Worker(message).list_folder() -@userge.on_cmd("gup", about="""\ -__Upload files to GDrive__ - - set destination by setting parent_id, - use `.gset` to set parent_id (root path). - -**Usage:** - - `.gup [file | folder path]`""") +@userge.on_cmd("gup", about={ + 'header': "Upload files to GDrive", + 'description': "set destination by setting parent_id, " + "use `.gset` to set parent_id (root path).", + 'usage': ".gup [file | folder path]"}) async def gup_(message: Message): """gup""" await Worker(message).upload() -@userge.on_cmd("gdown", about="""\ -__Download files from GDrive__ - -**Usage:** - - `.gdown [file_id | file/folder link]`""") +@userge.on_cmd("gdown", about={ + 'header': "Download files from GDrive", + 'usage': ".gdown [file_id | file/folder link]"}) async def gdown_(message: Message): """gdown""" await Worker(message).download() -@userge.on_cmd("gcopy", about="""\ -__Copy files in GDrive__ - - set destination by setting parent_id, - use `.gset` to set parent_id (root path). - -**Usage:** - - `.gcopy [file_id | file/folder link]`""") +@userge.on_cmd("gcopy", about={ + 'header': "Copy files in GDrive", + 'description': "set destination by setting parent_id, " + "use `.gset` to set parent_id (root path).", + 'usage': ".gcopy [file_id | file/folder link]"}) async def gcopy_(message: Message): """gcopy""" await Worker(message).copy() -@userge.on_cmd("gmove", about="""\ -__Move files in GDrive__ - - set destination by setting parent_id, - use `.gset` to set parent_id (root path). - -**Usage:** - - `.gmove [file_id | file/folder link]`""") +@userge.on_cmd("gmove", about={ + 'header': "Move files in GDrive", + 'description': "set destination by setting parent_id, " + "use `.gset` to set parent_id (root path).", + 'usage': ".gmove [file_id | file/folder link]"}) async def gmove_(message: Message): """gmove""" await Worker(message).move() -@userge.on_cmd("gdel", about="""\ -__Delete files in GDrive__ - -**Usage:** - - `.gdel [file_id | file/folder link]`""") +@userge.on_cmd("gdel", about={ + 'header': "Delete files in GDrive", + 'usage': ".gdel [file_id | file/folder link]"}) async def gdel_(message: Message): """gdel""" await Worker(message).delete() -@userge.on_cmd("gempty", about="""__Empty the Trash__""") +@userge.on_cmd("gempty", about={'header': "Empty the Trash"}) async def gempty_(message: Message): """gempty""" await Worker(message).empty() -@userge.on_cmd("gget", about="""\ -__Get metadata to given link in GDrive__ - -**Usage:** - - `.gget [file_id | file/folder link]`""") +@userge.on_cmd("gget", about={ + 'header': "Get metadata from the given link in GDrive", + 'usage': ".gget [file_id | file/folder link]"}) async def gget_(message: Message): """gget""" await Worker(message).get() -@userge.on_cmd("ggetperm", about="""\ -__Get permissions of file/folder in GDrive__ - -**Usage:** - - `.ggetperm [file_id | file/folder link]`""") +@userge.on_cmd("ggetperm", about={ + 'header': "Get permissions of file/folder in GDrive", + 'usage': ".ggetperm [file_id | file/folder link]"}) async def ggetperm_(message: Message): """ggetperm""" await Worker(message).get_perms() -@userge.on_cmd("gsetperm", about="""\ -__Set permissions to file/folder in GDrive__ - -**Usage:** - - `.gsetperm [file_id | file/folder link]`""") +@userge.on_cmd("gsetperm", about={ + 'header': "Set permissions to file/folder in GDrive", + 'usage': ".gsetperm [file_id | file/folder link]"}) async def gsetperm_(message: Message): """gsetperm""" await Worker(message).set_perms() -@userge.on_cmd("gdelperm", about="""\ -__Remove all permissions of file/folder in GDrive__ - -**Usage:** - - `.gdelperm [file_id | file/folder link]`""") +@userge.on_cmd("gdelperm", about={ + 'header': "Remove all permissions of file/folder in GDrive", + 'usage': ".gdelperm [file_id | file/folder link]"}) async def gdelperm_(message: Message): """gdelperm""" await Worker(message).del_perms() diff --git a/userge/plugins/misc/upload.py b/userge/plugins/misc/upload.py index be038b4dd..76f4f494e 100644 --- a/userge/plugins/misc/upload.py +++ b/userge/plugins/misc/upload.py @@ -24,15 +24,10 @@ THUMB_PATH = Config.DOWN_PATH + "thumb_image.jpg" -@userge.on_cmd("upload", about="""\ -__upload files to telegram__ - -**Usage:** - - `.upload [file or folder path] -` - Available flags :: - -d upload as document""", - del_pre=True) +@userge.on_cmd("upload", about={ + 'header': "Upload files to telegram", + 'flags': {'-d': "upload as document"}, + 'usage': ".upload [flags] [file or folder path]"}, del_pre=True) async def uploadtotg(message: Message): flags = message.flags path_ = message.filtered_input_str diff --git a/userge/plugins/misc/zip.py b/userge/plugins/misc/zip.py index 5d807728b..ed3da16a1 100644 --- a/userge/plugins/misc/zip.py +++ b/userge/plugins/misc/zip.py @@ -16,6 +16,7 @@ from zipfile import ZipFile from threading import Thread from multiprocessing import Pool, Lock + from userge import userge, Message, Config from userge.utils import humanbytes @@ -245,12 +246,9 @@ def get_info(self) -> list: return z_f.infolist() -@userge.on_cmd('zip', about="""\ -__Zip file / folder__ - -**Usage:** - - `.zip [file path]`""") +@userge.on_cmd('zip', about={ + 'header': "Zip file / folder", + 'usage': ".zip [file path]"}) async def zip_(message: Message): """zip""" @@ -258,9 +256,11 @@ async def zip_(message: Message): if not file_path: await message.err("missing file path!") + return if not exists(file_path): await message.err("file path not exists!") + return start_t = datetime.now() z_obj = Zip(file_path) @@ -296,12 +296,9 @@ async def zip_(message: Message): f"**zipped** `{file_path}` into `{z_obj.final_file_path}` in {m_s} seconds.", log=True) -@userge.on_cmd('unzip', about="""\ -__UnZip zip file__ - -**Usage:** - - `.unzip [zip file path]`""") +@userge.on_cmd('unzip', about={ + 'header': "UnZip zip file", + 'usage': ".unzip [zip file path]"}) async def unzip_(message: Message): """unzip""" @@ -309,12 +306,15 @@ async def unzip_(message: Message): if not file_path: await message.err("missing file path!") + return if not exists(file_path): await message.err("file path not exists!") + return if not file_path.endswith(".zip"): await message.err("unsupported file type!") + return start_t = datetime.now() z_obj = Zip(file_path) @@ -350,12 +350,9 @@ async def unzip_(message: Message): f"**unzipped** `{file_path}` into `{z_obj.final_file_path}` in {m_s} seconds.", log=True) -@userge.on_cmd('zipinfo', about="""\ -__File content of Zip file__ - -**Usage:** - - `.zipinfo [zip file]`""") +@userge.on_cmd('zipinfo', about={ + 'header': "File content of Zip file", + 'usage': ".zipinfo [zip file]"}) async def zipinfo_(message: Message): """zipinfo""" @@ -363,12 +360,15 @@ async def zipinfo_(message: Message): if not file_path: await message.err("missing file path!") + return if not exists(file_path): await message.err("file path not exists!") + return if not file_path.endswith(".zip"): await message.err("unsupported file type!") + return z_obj = Zip(file_path) infos = z_obj.get_info() diff --git a/userge/plugins/tools/all.py b/userge/plugins/tools/all.py index 471beb0e3..1f09446cc 100644 --- a/userge/plugins/tools/all.py +++ b/userge/plugins/tools/all.py @@ -11,7 +11,7 @@ from .. import get_all_plugins -@userge.on_cmd("all", about="__list all plugins in plugins/ path__") +@userge.on_cmd("all", about={'header': "list all plugins in plugins/ path"}) async def getplugins(message: Message): raw_ = get_all_plugins() all_plugins = ['/'.join(i.split('.')) for i in raw_] diff --git a/userge/plugins/tools/cancel.py b/userge/plugins/tools/cancel.py index 365a61de6..4f85704f1 100644 --- a/userge/plugins/tools/cancel.py +++ b/userge/plugins/tools/cancel.py @@ -10,8 +10,7 @@ from userge import userge, Message -@userge.on_cmd("cancel", about="\ -__Reply this to message you want to cancel__") +@userge.on_cmd("cancel", about={'header': "Reply this to message you want to cancel"}) async def cancel_(message: Message): replied = message.reply_to_message diff --git a/userge/plugins/tools/cleardir.py b/userge/plugins/tools/cleardir.py index a3f752960..c4ea067ea 100644 --- a/userge/plugins/tools/cleardir.py +++ b/userge/plugins/tools/cleardir.py @@ -13,7 +13,7 @@ from userge import userge, Message, Config -@userge.on_cmd("cleardir", about="__Clear the current working directory__") +@userge.on_cmd("cleardir", about={'header': "Clear the current working directory"}) async def clear_dir(message: Message): if not os.path.isdir(Config.DOWN_PATH): await message.edit( diff --git a/userge/plugins/tools/delete.py b/userge/plugins/tools/delete.py index df9a24e91..4d12bbab7 100644 --- a/userge/plugins/tools/delete.py +++ b/userge/plugins/tools/delete.py @@ -10,7 +10,7 @@ from userge import userge, Message -@userge.on_cmd("del", about="__delete replied message__") +@userge.on_cmd("del", about={'header': "delete replied message"}) async def del_msg(message: Message): msg_ids = [message.message_id] diff --git a/userge/plugins/tools/ids.py b/userge/plugins/tools/ids.py index b21a22301..6adf496ad 100644 --- a/userge/plugins/tools/ids.py +++ b/userge/plugins/tools/ids.py @@ -10,12 +10,9 @@ from userge import userge, Message -@userge.on_cmd("ids", about="""\ -__display ids__ - -**Usage:** - -reply `.ids` any message, file or just send this command""") +@userge.on_cmd("ids", about={ + 'header': "display ids", + 'usage': "reply .ids any message, file or just send this command"}) async def getids(message: Message): out_str = f"💁 Current Chat ID: `{message.chat.id}`" diff --git a/userge/plugins/tools/json.py b/userge/plugins/tools/json.py index 176caad3d..e02370eca 100644 --- a/userge/plugins/tools/json.py +++ b/userge/plugins/tools/json.py @@ -10,12 +10,9 @@ from userge import userge, Message -@userge.on_cmd("json", about="""\ -__message object to json__ - -**Usage:** - - reply `.json` to any message""") +@userge.on_cmd("json", about={ + 'header': "message object to json", + 'usage': "reply .json to any message"}) async def jsonify(message: Message): the_real_message = str(message.reply_to_message) if message.reply_to_message \ else str(message) diff --git a/userge/plugins/tools/loader.py b/userge/plugins/tools/loader.py index 6e550fd32..f6a58b977 100644 --- a/userge/plugins/tools/loader.py +++ b/userge/plugins/tools/loader.py @@ -14,12 +14,9 @@ from userge.plugins import ROOT -@userge.on_cmd('load', about="""\ -__Load Userge plugin__ - -**Usage:** - - `.load [reply to userge plugin]`""") +@userge.on_cmd('load', about={ + 'header': "Load Userge plugin", + 'usage': ".load [reply to userge plugin]"}) async def load_cmd_handler(message: Message): await message.edit("Loading...") replied = message.reply_to_message @@ -47,7 +44,7 @@ async def load_cmd_handler(message: Message): await message.edit("`Reply to Plugin`") -@userge.on_cmd('reload', about="__Reload all plugins__") +@userge.on_cmd('reload', about={'header': "Reload all plugins"}) async def reload_cmd_handler(message: Message): await message.edit("`Reloading All Plugins`") diff --git a/userge/plugins/tools/logs.py b/userge/plugins/tools/logs.py index 2ca4e00fb..fc798beff 100644 --- a/userge/plugins/tools/logs.py +++ b/userge/plugins/tools/logs.py @@ -10,7 +10,7 @@ from userge import userge, Message -@userge.on_cmd("logs", about="__check userge logs__") +@userge.on_cmd("logs", about={'header': "check userge logs"}) async def check_logs(message: Message): """check logs""" await message.edit("`checking logs ...`") diff --git a/userge/plugins/tools/ping.py b/userge/plugins/tools/ping.py index 903238e2f..feea6c486 100644 --- a/userge/plugins/tools/ping.py +++ b/userge/plugins/tools/ping.py @@ -11,7 +11,7 @@ from userge import userge, Message -@userge.on_cmd("ping", about="__check how long it takes to ping your userbot__") +@userge.on_cmd("ping", about={'header': "check how long it takes to ping your userbot"}) async def pingme(message: Message): start = datetime.now() diff --git a/userge/plugins/tools/repo.py b/userge/plugins/tools/repo.py index f742e5841..6d4479fab 100644 --- a/userge/plugins/tools/repo.py +++ b/userge/plugins/tools/repo.py @@ -10,7 +10,7 @@ from userge import userge, Message, Config, versions -@userge.on_cmd("repo", about="__get repo link and details__") +@userge.on_cmd("repo", about={'header': "get repo link and details"}) async def see_repo(message: Message): """see repo""" diff --git a/userge/plugins/tools/restart.py b/userge/plugins/tools/restart.py index 6e613270d..c8f01ece1 100644 --- a/userge/plugins/tools/restart.py +++ b/userge/plugins/tools/restart.py @@ -7,29 +7,31 @@ # All rights reserved. +import time import asyncio from userge import userge, Message, Config LOG = userge.getLogger(__name__) -CHANNEL = userge.getCLogger(__name__) -@userge.on_cmd('restart', about="""\ -__Restarts the bot and reload all plugins__ - -**Usage:** - - `.restart` : normal restart. - `.restart -h` : use this only if you are using heroku.""") +@userge.on_cmd('restart', about={ + 'header': "Restarts the bot and reload all plugins", + 'flags': {'-h': "restart heroku dyno"}, + 'usage': ".restart\n.restart -h"}) async def restart_cmd_handler(message: Message): - await message.edit("Restarting Userge Services", log=True) + if Config.PUSHING: + await message.err("Can't Restart, Updation Found!") + return + + await message.edit("Restarting Userge Services", log=__name__) LOG.info("USERGE Services - Restart initiated") if Config.HEROKU_APP and '-h' in message.flags: await message.edit( '`Heroku app found, trying to restart dyno...\nthis will take upto 30 sec`', del_in=3) Config.HEROKU_APP.restart() + time.sleep(30) else: - await message.edit("finalizing...", del_in=2) + await message.edit("finalizing...", del_in=1) asyncio.get_event_loop().create_task(userge.restart()) diff --git a/userge/plugins/tools/sd.py b/userge/plugins/tools/sd.py index 06c01d67b..f62f223b8 100644 --- a/userge/plugins/tools/sd.py +++ b/userge/plugins/tools/sd.py @@ -10,13 +10,9 @@ from userge import userge, Message -@userge.on_cmd("sd (?:(\\d+)?\\s?(.+))", about="""\ -__make self-destructable messages__ - -**Usage:** - - `.sd [test]` - `.sd [timeout in seconds] [text]`""") +@userge.on_cmd("sd (?:(\\d+)?\\s?(.+))", about={ + 'header': "make self-destructable messages", + 'usage': ".sd [test]\n.sd [timeout in seconds] [text]"}) async def selfdestruct(message: Message): seconds = int(message.matches[0].group(1) or 0) text = str(message.matches[0].group(2)) diff --git a/userge/plugins/tools/search.py b/userge/plugins/tools/search.py index 857d4d90d..964d526ba 100644 --- a/userge/plugins/tools/search.py +++ b/userge/plugins/tools/search.py @@ -10,7 +10,9 @@ from userge import userge, Message -@userge.on_cmd("s", about="__to search commands in **USERGE**__") +@userge.on_cmd("s", about={ + 'header': "search commands in USERGE", + 'examples': ".s wel"}) async def search(message: Message): cmd = message.input_str diff --git a/userge/plugins/tools/timeout.py b/userge/plugins/tools/timeout.py index 38cffadab..344869591 100644 --- a/userge/plugins/tools/timeout.py +++ b/userge/plugins/tools/timeout.py @@ -23,17 +23,10 @@ del __tmp_msg__, __tmp_wel__ -@userge.on_cmd("sdelto (\\d+)", about="""\ -__Set auto message delete timeout__ - -**Userge:** - - `.sdelto [timeout in seconds]` - -**Example:** - - `.sdelto 15` - `.sdelto 0` : for disable deletion""") +@userge.on_cmd("sdelto (\\d+)", about={ + 'header': "Set auto message delete timeout", + 'usage': ".sdelto [timeout in seconds]", + 'examples': ".sdelto 15\n.sdelto 0 : for disable deletion"}) async def set_delete_timeout(message: Message): """set delete timeout""" @@ -55,7 +48,7 @@ async def set_delete_timeout(message: Message): del_in=3) -@userge.on_cmd("vdelto", about="__View auto message delete timeout__") +@userge.on_cmd("vdelto", about={'header': "View auto message delete timeout"}) async def view_delete_timeout(message: Message): """view delete timeout""" @@ -69,17 +62,10 @@ async def view_delete_timeout(message: Message): del_in=3) -@userge.on_cmd("swelto (\\d+)", about="""\ -__Set auto welcome/left message delete timeout__ - -**Userge:** - - `.swelto [timeout in seconds]` - -**Example:** - - `.swelto 15` - `.swelto 0` : for disable deletion""") +@userge.on_cmd("swelto (\\d+)", about={ + 'header': "Set auto welcome/left message delete timeout", + 'usage': ".swelto [timeout in seconds]", + 'examples': ".swelto 15\n.swelto 0 : for disable deletion"}) async def set_welcome_timeout(message: Message): """set welcome/left timeout""" @@ -101,7 +87,7 @@ async def set_welcome_timeout(message: Message): del_in=3) -@userge.on_cmd("vwelto", about="__View auto welcome/left message delete timeout__") +@userge.on_cmd("vwelto", about={'header': "View auto welcome/left message delete timeout"}) async def view_welcome_timeout(message: Message): """view welcome/left timeout""" diff --git a/userge/plugins/tools/updater.py b/userge/plugins/tools/updater.py index e4ed98560..32015bb84 100644 --- a/userge/plugins/tools/updater.py +++ b/userge/plugins/tools/updater.py @@ -20,18 +20,22 @@ UPSTREAM_REMOTE = 'upstream' -@userge.on_cmd("update", about="""\ -__Check Updates or Update Userge__ - -**Usage:** - - `.update` : check updates from default branch - `.update -dev` : check updates from dev branch - `.update -run` : run updater from default branch - `.update -run -dev` : run updater from dev branch""", del_pre=True) +@userge.on_cmd("update", about={ + 'header': "Check Updates or Update Userge", + 'flags': { + '-run': "run updater", + '-branch_name': "select branch"}, + 'usage': ".update : check updates from default branch\n" + ".update -dev : check updates from dev branch\n" + ".update -run : run updater from default branch\n" + ".update -run -dev : run updater from dev branch"}, del_pre=True) async def check_update(message: Message): """check or do updates""" + if Config.PUSHING: + await message.edit("`Please wait....\nAlready updating!`", del_in=3) + return + await message.edit("`Checking for updates, please wait....`") try: @@ -96,6 +100,8 @@ async def check_update(message: Message): await message.edit_or_send_as_file(changelog_str + out, disable_web_page_preview=True) else: + Config.PUSHING = True + await message.edit(f'`New update found for [{branch}], trying to update...`') repo.git.reset('--hard', 'FETCH_HEAD') @@ -103,7 +109,7 @@ async def check_update(message: Message): if Config.HEROKU_GIT_URL: await message.edit( - '`Heroku app found, pushing update...\nthis will take upto 1 min`', del_in=3) + '`Heroku app found, pushing update...\nthis will take upto 2 min`', del_in=3) if "heroku" in repo.remotes: remote = repo.remote("heroku") @@ -120,3 +126,5 @@ async def check_update(message: Message): '__Now restarting... Wait for a while!__`', del_in=3) asyncio.get_event_loop().create_task(userge.restart()) + + Config.PUSHING = False diff --git a/userge/plugins/utils/admins.py b/userge/plugins/utils/admins.py index ad10dacdb..e95004502 100644 --- a/userge/plugins/utils/admins.py +++ b/userge/plugins/utils/admins.py @@ -10,17 +10,13 @@ from userge import userge, Message -@userge.on_cmd("admins", about="""\ -__View or mention admins in chat__ - -**Available Flags:** -`-m` : __mention all admins__ -`-mc` : __only mention creator__ -`-id` : __show ids__ - -**Usage:** - - `.admins [any flag] [chatid]`""") +@userge.on_cmd("admins", about={ + 'header': "View or mention admins in chat", + 'flags': { + '-m': "mention all admins", + '-mc': "only mention creator", + '-id': "show ids"}, + 'usage': ".admins [any flag] [chatid]"}) async def mentionadmins(message: Message): mentions = "🛡 **Admin List** 🛡\n" chat_id = message.filtered_input_str diff --git a/userge/plugins/utils/afk.py b/userge/plugins/utils/afk.py index 895d6e1c2..ec6d4ca67 100644 --- a/userge/plugins/utils/afk.py +++ b/userge/plugins/utils/afk.py @@ -38,15 +38,11 @@ IS_AFK_FILTER = Filters.create(lambda _, __: bool(IS_AFK)) -@userge.on_cmd("afk", about="""\ -__Set to AFK mode__ - - Sets your status as AFK. Responds to anyone who tags/PM's - you telling you are AFK. Switches off AFK when you type back anything. - -**Usage:** - - `.afk` or `.afk [reason]`""") +@userge.on_cmd("afk", about={ + 'header': "Set to AFK mode", + 'description': "Sets your status as AFK. Responds to anyone who tags/PM's.\n" + "you telling you are AFK. Switches off AFK when you type back anything.", + 'usage': ".afk or .afk [reason]"}) async def active_afk(message: Message): global REASON, IS_AFK, TIME @@ -55,7 +51,7 @@ async def active_afk(message: Message): REASON = message.input_str await CHANNEL.log(f"You went AFK! : `{REASON}`") - await message.edit("You went AFK!", del_in=1) + await message.edit("`You went AFK!`", del_in=1) AFK_COLLECTION.drop() SAVED_SETTINGS.update_one( @@ -68,11 +64,12 @@ async def handle_afk_incomming(message: Message): user_id = message.from_user.id chat = message.chat user_dict = await userge.get_user_dict(user_id) + afk_time = time_formatter(round(time.time() - TIME)) if user_id in USERS: - if not (USERS[user_id][0] + USERS[user_id][1]) % randint(2, 5): + if not (USERS[user_id][0] + USERS[user_id][1]) % randint(2, 4): if REASON: - out_str = f"I'm still **AFK**.\nReason: `{REASON}`" + out_str = f"I'm still **AFK**.\nReason: `{REASON}`\nLast Seen: `{afk_time} ago`" else: out_str = choice(AFK_REASONS) @@ -86,7 +83,7 @@ async def handle_afk_incomming(message: Message): else: if REASON: - out_str = f"I'm **AFK** right now.\nReason: `{REASON}`" + out_str = f"I'm **AFK** right now.\nReason: `{REASON}`\nLast Seen: `{afk_time} ago`" else: out_str = choice(AFK_REASONS) @@ -124,8 +121,7 @@ async def handle_afk_outgoing(message: Message): IS_AFK = False afk_time = time_formatter(round(time.time() - TIME)) - await CHANNEL.log("I'm no longer AFK!") - replied: Message = await message.reply(f"I'm no longer AFK!") + replied: Message = await message.reply(f"`I'm no longer AFK!`", log=__name__) if USERS: p_msg = '' diff --git a/userge/plugins/utils/direct_links.py b/userge/plugins/utils/direct_links.py index 0f6a321f3..a726ac515 100644 --- a/userge/plugins/utils/direct_links.py +++ b/userge/plugins/utils/direct_links.py @@ -20,18 +20,12 @@ from userge.utils import humanbytes -@userge.on_cmd("direct", about="""\ -__Generate a direct download link__ - -**Supported Links**: - - `Google Drive` , `MEGA.nz` , `Cloud Mail` - `Yandex.Disk` , `AFH` , `ZippyShare` - `MediaFire` , `SourceForge` , `OSDN` , `GitHub` - -**Usage**: - - `.direct [link]`""") +@userge.on_cmd("direct", about={ + 'header': "Generate a direct download link", + 'supported links': [ + 'Google Drive', 'MEGA.nz', 'Cloud Mail', 'Yandex.Disk', 'AFH', + 'ZippyShare', 'MediaFire', 'SourceForge', 'OSDN', 'GitHub'], + 'usage': ".direct [link]"}) async def direct_(message: Message): """direct links generator""" diff --git a/userge/plugins/utils/dogbin.py b/userge/plugins/utils/dogbin.py index 5c4a9f60f..765a886bb 100644 --- a/userge/plugins/utils/dogbin.py +++ b/userge/plugins/utils/dogbin.py @@ -17,12 +17,9 @@ DOGBIN_URL = "https://del.dog/" -@userge.on_cmd("paste", about="""\ -__Pastes text or text_file to dogbin__ - -**Usage**: - - `.paste [text | reply to msg]`""") +@userge.on_cmd("paste", about={ + 'header': "Pastes text or text_file to dogbin", + 'usage': ".paste [text | reply to msg]"}) async def paste_(message: Message): """pastes the text directly to dogbin""" @@ -68,12 +65,9 @@ async def paste_(message: Message): await message.err("Failed to reach Dogbin") -@userge.on_cmd("getpaste", about="""\ -__Gets the content of a del.dog paste__ - -**Usage**: - - `.getpaste [del.dog link]`""") +@userge.on_cmd("getpaste", about={ + 'header': "Gets the content of a del.dog paste", + 'usage': ".getpaste [del.dog link]"}) async def get_paste_(message: Message): """fetches the content of a dogbin URL""" diff --git a/userge/plugins/utils/executor.py b/userge/plugins/utils/executor.py index fb80017bb..0fdad40c3 100644 --- a/userge/plugins/utils/executor.py +++ b/userge/plugins/utils/executor.py @@ -16,16 +16,10 @@ from userge.utils import runcmd -@userge.on_cmd("eval", about="""\ -__run python code line | lines__ - -**Usage:** - - `.eval [code lines] - -**Example:** - - `.eval print('Userge')`""") +@userge.on_cmd("eval", about={ + 'header': "run python code line | lines", + 'usage': ".eval [code lines]", + 'examples': ".eval print('Userge')"}) async def eval_(message: Message): cmd = await init_func(message) @@ -78,16 +72,10 @@ async def aexec(code): caption=cmd) -@userge.on_cmd("exec", about="""\ -__run shell commands__ - -**Usage:** - - `.exec [commands] - -**Example:** - - `.exec echo "Userge"`""") +@userge.on_cmd("exec", about={ + 'header': "run shell commands", + 'usage': ".exec [commands]", + 'examples': ".exec echo \"Userge\""}) async def exec_(message: Message): cmd = await init_func(message) @@ -110,16 +98,10 @@ async def exec_(message: Message): caption=cmd) -@userge.on_cmd("term", about="""\ -__run terminal commands__ - -**Usage:** - - `.term [commands] - -**Example:** - - `.term echo "Userge"`""") +@userge.on_cmd("term", about={ + 'header': "run terminal commands", + 'usage': ".term [commands]", + 'examples': ".term echo \"Userge\""}) async def term_(message: Message): cmd = await init_func(message) diff --git a/userge/plugins/utils/filters.py b/userge/plugins/utils/filters.py index 25bea884f..32ee017c2 100644 --- a/userge/plugins/utils/filters.py +++ b/userge/plugins/utils/filters.py @@ -35,7 +35,7 @@ def _filter_deleter(chat_id: int, name: str) -> None: _filter_updater(flt['chat_id'], flt['name'], flt['content']) -@userge.on_cmd("filters", about="__List all saved filters__") +@userge.on_cmd("filters", about={'header': "List all saved filters"}) async def filters_active(message: Message): out = '' if message.chat.id in FILTERS_DATA: @@ -49,12 +49,9 @@ async def filters_active(message: Message): await message.err("There are no saved filters in this chat") -@userge.on_cmd("delfilter", about="""\ -__Deletes a filter by name__ - -**Usage:** - - `.delfilter [filter name]`""") +@userge.on_cmd("delfilter", about={ + 'header': "Deletes a filter by name", + 'usage': ".delfilter [filter name]"}) async def delete_filters(message: Message): filter_ = message.input_str @@ -72,12 +69,9 @@ async def delete_filters(message: Message): @userge.on_cmd(r"addfilter (\w[^\|]*)(?:\s?\|\s?([\s\S]+))?", - about="""\ -__Adds a filter by name__ - -**Usage:** - - `.addfilter [filter name] | [content | reply to msg]`""") + about={ + 'header': "Adds a filter by name", + 'usage': ".addfilter [filter name] | [content | reply to msg]"}) async def add_filter(message: Message): filter_ = message.matches[0].group(1).strip() content = message.matches[0].group(2) diff --git a/userge/plugins/utils/google.py b/userge/plugins/utils/google.py index 6a8f641fd..f4b722676 100644 --- a/userge/plugins/utils/google.py +++ b/userge/plugins/utils/google.py @@ -11,21 +11,13 @@ from userge import userge, Message -@userge.on_cmd("google", about="""\ -__do a Google search__ - -**Available Flags:** - - `-p` : __page of results to return (default to 1)__ - `-l` : __limit the number of returned results (defaults to 5)(max 10)__ - -**Usage:** - - `.google [flags] [query | reply to msg]` - -**Example:** - - `.google -p4 -l10 github-userge`""") +@userge.on_cmd("google", about={ + 'header': "do a Google search", + 'flags': { + '-p': "page of results to return (default to 1)", + '-l': "limit the number of returned results (defaults to 5)(max 10)"}, + 'usage': ".google [flags] [query | reply to msg]", + 'examples': ".google -p4 -l10 github-userge"}) async def gsearch(message: Message): await message.edit("Processing ...") diff --git a/userge/plugins/utils/header.py b/userge/plugins/utils/header.py index e8584fb47..ff7549934 100644 --- a/userge/plugins/utils/header.py +++ b/userge/plugins/utils/header.py @@ -11,22 +11,14 @@ from userge import userge, Message -@userge.on_cmd("head", about="""\ -__View headers in URL__ - -**Available Flags:** - - `-r` : __allow redirects__ - `-s` : __allow streams__ - `-t` : __request timeout__ - -**Usage:** - - `.head [flags] [url]` - -**Example:** - - `.head -r -s -t5 https://www.google.com`""") +@userge.on_cmd("head", about={ + 'header': "View headers in URL", + 'flags': { + '-r': "allow redirects", + '-s': "allow streams", + '-t': "request timeout"}, + 'usage': ".head [flags] [url]", + 'examples': ".head -r -s -t5 https://www.google.com"}) async def req_head(message: Message): await message.edit("Processing ...") diff --git a/userge/plugins/utils/notes.py b/userge/plugins/utils/notes.py index ca55d9bdb..1ab6c88bb 100644 --- a/userge/plugins/utils/notes.py +++ b/userge/plugins/utils/notes.py @@ -12,7 +12,7 @@ NOTES_COLLECTION = get_collection("notes") -@userge.on_cmd("notes", about="__List all saved notes__") +@userge.on_cmd("notes", about={'header': "List all saved notes"}) async def notes_active(message: Message): out = '' for note in NOTES_COLLECTION.find({'chat_id': message.chat.id}, {'name': 1}): @@ -25,12 +25,9 @@ async def notes_active(message: Message): await message.err("There are no saved notes in this chat") -@userge.on_cmd("delnote", about="""\ -__Deletes a note by name__ - -**Usage:** - - `.delnote [note name]`""") +@userge.on_cmd("delnote", about={ + 'header': "Deletes a note by name", + 'usage': ".delnote [note name]"}) async def remove_notes(message: Message): notename = message.input_str @@ -47,13 +44,9 @@ async def remove_notes(message: Message): @userge.on_cmd(r"(?:#|get\s)(\w[\w_]*)", - about="""\ -__Gets a note by name__ - -**Usage:** - - `#[notename]` - `get notename`""", + about={ + 'header': "Gets a note by name", + 'usage': "#[notename]\nget notename"}, group=-1, name="note", trigger='', @@ -70,12 +63,9 @@ async def note(message: Message): @userge.on_cmd(r"addnote (\w[\w_]*)(?:\s([\s\S]+))?", - about="""\ -__Adds a note by name__ - -**Usage:** - - `.addnote [note name] [content | reply to msg]`""") + about={ + 'header': "Adds a note by name", + 'usage': ".addnote [note name] [content | reply to msg]"}) async def add_note(message: Message): notename = message.matches[0].group(1) content = message.matches[0].group(2) diff --git a/userge/plugins/utils/pmpermit.py b/userge/plugins/utils/pmpermit.py index d6d845160..dd0da2e80 100644 --- a/userge/plugins/utils/pmpermit.py +++ b/userge/plugins/utils/pmpermit.py @@ -39,18 +39,12 @@ del _pm, _pmMsg -@userge.on_cmd("allow", about="""\ -__allows someone to contact__ - - Ones someone is allowed, Userge will not interfere or handle such private chats - -**syntax:** - - `.allow <@username>` - `.allow ` - - reply `.allow` to a message - do `.allow` in the private chat""") +@userge.on_cmd("allow", about={ + 'header': "allows someone to contact", + 'description': "Ones someone is allowed, " + "Userge will not interfere or handle such private chats", + 'usage': ".allow [username | userID]\nreply .allow to a message, " + "do .allow in the private chat"}) async def allow(message: Message): userid = await get_id(message) if userid: @@ -69,18 +63,12 @@ async def allow(message: Message): await message.edit("I need to reply to a user or provide the username/id or be in a private chat") -@userge.on_cmd("nopm", about="""\ -__Activates guarding on inbox__ - - Ones someone is allowed, Userge will not interfere or handle such private chats - -**syntax:** - - `.nopm <@username>` - `.nopm ` - - reply `.nopm` to a message - do `.nopm` in the private chat""") +@userge.on_cmd("nopm", about={ + 'header': "Activates guarding on inbox", + 'description': "Ones someone is allowed, " + "Userge will not interfere or handle such private chats", + 'usage': ".nopm [username | userID]\nreply .nopm to a message, " + "do .nopm in the private chat"}) async def denyToPm(message: Message): userid = await get_id(message) if userid: @@ -149,13 +137,12 @@ async def outgoing_auto_approve(message: Message): await CHANNEL.log(f"**#AUTO_APPROVED**\n{user_dict['mention']}") -@userge.on_cmd("pmguard", about="""\ -__Switchs the pm permiting module on__ - - This is switched off in default. - You can switch pmguard On or Off with this command. - When you turn on this next time, - the previously allowed chats will be there !""") +@userge.on_cmd("pmguard", about={ + 'header': "Switchs the pm permiting module on", + 'description': "This is switched off in default. " + "You can switch pmguard On or Off with this command. " + "When you turn on this next time, " + "the previously allowed chats will be there !"}) async def pmguard(message: Message): global allowAllPms, pmCounter if allowAllPms: @@ -168,21 +155,16 @@ async def pmguard(message: Message): SAVED_SETTINGS.update_one({'_id': 'PM GUARD STATUS'}, {"$set": {'data': allowAllPms}}, upsert=True) -@userge.on_cmd("setpmmsg", about="""\ -__Sets the reply message__ - - You can change the default message which userge gives on - un-invited PMs - -**Available options:** - - `{fname}` : __add first name__ - `{lname}` : __add last name__ - `{flname}` : __add full name__ - `{uname}` : __username__ - `{chat}` : __chat name__ - `{mention}` : __mention user__ -""") +@userge.on_cmd("setpmmsg", about={ + 'header': "Sets the reply message", + 'description': "You can change the default message which userge gives on un-invited PMs", + 'options': { + '{fname}': "add first name", + '{lname}': "add last name", + '{flname}': "add full name", + '{uname}': "username", + '{chat}': "chat name", + '{mention}': "mention user"}}) async def set_custom_nopm_message(message: Message): global noPmMessage await message.edit('`Custom NOpm message saved`', log=True) @@ -196,8 +178,6 @@ async def set_custom_nopm_message(message: Message): SAVED_SETTINGS.update_one({'_id': 'CUSTOM NOPM MESSAGE'}, {"$set": {'data': string}}, upsert=True) -@userge.on_cmd("vpmmsg", about="""\ -__Displays the reply message for uninvited PMs__ -""") +@userge.on_cmd("vpmmsg", about={'header': "Displays the reply message for uninvited PMs"}) async def view_current_noPM_msg(message: Message): await message.edit(noPmMessage) diff --git a/userge/plugins/utils/purge.py b/userge/plugins/utils/purge.py index 27b9616d3..65c63d2ef 100644 --- a/userge/plugins/utils/purge.py +++ b/userge/plugins/utils/purge.py @@ -13,20 +13,12 @@ LOG = userge.getLogger(__name__) -@userge.on_cmd("purge", about="""\ -__purge messages from user__ - -**Usage:** - - reply `.purge` to the start message to purge. - use `.purge [user_id | user_name]` to purge messages from that user - or use `-u` flag to get user_id from replied message. - -**Example:** - - `.purge` - `.purge -u` - `.purge [user_id | user_name]`""") +@userge.on_cmd("purge", about={ + 'header': "purge messages from user", + 'flags': {'-u': "get user_id from replied message"}, + 'usage': "reply .purge to the start message to purge.\n" + "use .purge [user_id | user_name] to purge messages from that user or use flags", + 'examples': ['.purge', '.purge -u', '.purge [user_id | user_name]']}) async def purge_(message: Message): if message.reply_to_message: start_t = datetime.now() diff --git a/userge/plugins/utils/speedtest.py b/userge/plugins/utils/speedtest.py index 1f0ee436a..22a7e240c 100644 --- a/userge/plugins/utils/speedtest.py +++ b/userge/plugins/utils/speedtest.py @@ -16,7 +16,7 @@ CHANNEL = userge.getCLogger(__name__) -@userge.on_cmd("speedtest", about="__test your server speed__") +@userge.on_cmd("speedtest", about={'header': "test your server speed"}) async def speedtst(message: Message): await message.edit("`Running speed test . . .`") diff --git a/userge/plugins/utils/sudo.py b/userge/plugins/utils/sudo.py index c0544d05f..e1ebd34d7 100644 --- a/userge/plugins/utils/sudo.py +++ b/userge/plugins/utils/sudo.py @@ -22,12 +22,9 @@ Config.ALLOWED_COMMANDS.add(i['_id']) -@userge.on_cmd("addsudo", about="""\ -__add sudo user__ - -**Usage** : - - `.addsudo [username | reply to msg]`""") +@userge.on_cmd("addsudo", about={ + 'header': "add sudo user", + 'usage': ".addsudo [username | reply to msg]"}) async def add_sudo(message: Message): user_id = message.input_str if message.reply_to_message: @@ -54,17 +51,10 @@ async def add_sudo(message: Message): await message.edit(f"user : `{user['id']}` added to **SUDO**!", del_in=5) -@userge.on_cmd("delsudo", about="""\ -__delete sudo user__ - -**Available Flags** : - - `-all` : __remove all sudo users__ - -**Usage** : - - `.delsudo [user_id | reply to msg]` - `.delsudo -all`""") +@userge.on_cmd("delsudo", about={ + 'header': "delete sudo user", + 'flags': {'-all': "remove all sudo users"}, + 'usage': ".delsudo [user_id | reply to msg]\n.delsudo -all"}) async def del_sudo(message: Message): user_id = message.filtered_input_str if message.reply_to_message: @@ -99,7 +89,7 @@ async def del_sudo(message: Message): await message.edit(f"user : `{user_id}` removed from **SUDO**!", del_in=5) -@userge.on_cmd("vsudo", about="__view sudo users__") +@userge.on_cmd("vsudo", about={'header': "view sudo users"}) async def view_sudo(message: Message): if not Config.SUDO_USERS: await message.edit("**SUDO** users not found!", del_in=5) @@ -112,12 +102,9 @@ async def view_sudo(message: Message): await message.edit(out_str, del_in=0) -@userge.on_cmd("addscmd", about="""\ -__add sudo command__ - -**Usage** : - - `.addscmd [command name]`""") +@userge.on_cmd("addscmd", about={ + 'header': "add sudo command", + 'usage': ".addscmd [command name]"}) async def add_sudo_cmd(message: Message): cmd = message.input_str @@ -136,17 +123,10 @@ async def add_sudo_cmd(message: Message): await message.edit(f"cmd : `{cmd}` added to **SUDO**!", del_in=5) -@userge.on_cmd("delscmd", about="""\ -__delete sudo commands__ - -**Available Flags** : - - `-all` : __remove all sudo commands__ - -**Usage** : - - `.delscmd [command name]` - `.delscmd -all`""") +@userge.on_cmd("delscmd", about={ + 'header': "delete sudo commands", + 'flags': {'-all': "remove all sudo commands"}, + 'usage': ".delscmd [command name]\n.delscmd -all"}) async def del_sudo_cmd(message: Message): cmd = message.filtered_input_str @@ -172,7 +152,7 @@ async def del_sudo_cmd(message: Message): await message.edit(f"cmd : `{cmd}` removed from **SUDO**!", del_in=5) -@userge.on_cmd("vscmd", about="__view sudo cmds__") +@userge.on_cmd("vscmd", about={'header': "view sudo cmds"}) async def view_sudo_cmd(message: Message): if not Config.ALLOWED_COMMANDS: await message.edit("**SUDO** cmds not found!", del_in=5) diff --git a/userge/plugins/utils/thumbnail.py b/userge/plugins/utils/thumbnail.py index 47dff8dd3..c090c7023 100644 --- a/userge/plugins/utils/thumbnail.py +++ b/userge/plugins/utils/thumbnail.py @@ -17,12 +17,9 @@ CHANNEL = userge.getCLogger(__name__) -@userge.on_cmd('sthumb', about="""\ -__Save thumbnail__ - -**Usage:** - - `.sthumb [reply to any photo]`""") +@userge.on_cmd('sthumb', about={ + 'header': "Save thumbnail", + 'usage': ".sthumb [reply to any photo]"}) async def save_thumb_nail(message: Message): await message.edit("processing ...") if message.reply_to_message is not None and message.reply_to_message.photo: @@ -47,7 +44,7 @@ async def save_thumb_nail(message: Message): await message.edit("Reply to a photo to save custom thumbnail", del_in=3) -@userge.on_cmd('dthumb', about="__Delete thumbnail__") +@userge.on_cmd('dthumb', about={'header': "Delete thumbnail"}) async def clear_thumb_nail(message: Message): await message.edit("`processing ...`") @@ -57,7 +54,7 @@ async def clear_thumb_nail(message: Message): await message.edit("✅ Custom thumbnail deleted succesfully.", del_in=3) -@userge.on_cmd('vthumb', about="__View thumbnail__") +@userge.on_cmd('vthumb', about={'header': "View thumbnail"}) async def get_thumb_nail(message: Message): await message.edit("processing ...") if os.path.exists(THUMB_PATH): diff --git a/userge/plugins/utils/translate.py b/userge/plugins/utils/translate.py index 2f416257a..973e25af4 100644 --- a/userge/plugins/utils/translate.py +++ b/userge/plugins/utils/translate.py @@ -13,31 +13,21 @@ from userge import userge, Message, Config -@userge.on_cmd("tr", about=f"""\ -__Translate the given text using Google Translate__ - -**Supported Languages:** -__{dumps(LANGUAGES, indent=4, sort_keys=True)}__ - -**Usage:** - -__from english to sinhala__ - `.tr -en -si i am userge` - -__from auto detected language to sinhala__ - `.tr -si i am userge` - -__from auto detected language to preferred__ - `.tr i am userge` - -__reply to message you want to translate from english to sinhala__ - `.tr -en -si` - -__reply to message you want to translate from auto detected language to sinhala__ - `.tr -si` - -__reply to message you want to translate from auto detected language to preferred__ - `.tr`""", del_pre=True) +@userge.on_cmd("tr", about={ + 'header': "Translate the given text using Google Translate", + 'supported languages': dumps(LANGUAGES, indent=4, sort_keys=True), + 'usage': "from english to sinhala\n" + ".tr -en -si i am userge\n\n" + "from auto detected language to sinhala\n" + ".tr -si i am userge\n\n" + "from auto detected language to preferred\n" + ".tr i am userge\n\n" + "reply to message you want to translate from english to sinhala\n" + ".tr -en -si\n\n" + "reply to message you want to translate from auto detected language to sinhala\n" + ".tr -si\n\n" + "reply to message you want to translate from auto detected language to preferred\n" + ".tr"}, del_pre=True) async def translateme(message: Message): translator = Translator() diff --git a/userge/plugins/utils/ud.py b/userge/plugins/utils/ud.py index 5da489be9..eb679eae5 100644 --- a/userge/plugins/utils/ud.py +++ b/userge/plugins/utils/ud.py @@ -12,16 +12,10 @@ from userge import userge, Message -@userge.on_cmd("ud", about="""\ -__Searches Urban Dictionary for the query__ - -**Usage:** - - `.ud [query]` - -**Exaple:** - - `.ud userge`""") +@userge.on_cmd("ud", about={ + 'header': "Searches Urban Dictionary for the query", + 'usage': ".ud [query]", + 'examples': ".ud userge"}) async def urban_dict(message: Message): await message.edit("Processing...") query = message.input_str diff --git a/userge/plugins/utils/webss.py b/userge/plugins/utils/webss.py index bb62a2397..f0d4c138e 100644 --- a/userge/plugins/utils/webss.py +++ b/userge/plugins/utils/webss.py @@ -15,7 +15,7 @@ CHANNEL = userge.getCLogger(__name__) -@userge.on_cmd("webss", about="__Get snapshot of a website__") +@userge.on_cmd("webss", about={'header': "Get snapshot of a website"}) async def webss(message: Message): if Config.SCREENSHOT_API is None: await message.edit( diff --git a/userge/plugins/utils/welcome.py b/userge/plugins/utils/welcome.py index 05834c3e9..b5acd7774 100644 --- a/userge/plugins/utils/welcome.py +++ b/userge/plugins/utils/welcome.py @@ -39,113 +39,104 @@ LEFT_CHATS.add(i.get('_id')) -@userge.on_cmd("setwelcome", about="""\ -__Creates a welcome message in current chat :)__ - -**Available options:** - - `{fname}` : __add first name__ - `{lname}` : __add last name__ - `{flname}` : __add full name__ - `{uname}` : __username__ - `{chat}` : __chat name__ - `{mention}` : __mention user__ - -**Supported Media Types:** - - `audio` , `animation`, `document`, - `photo`, `sticker`, `voice`, - `video_note`, `video` - - **max media size limt** : 10MB ! - -**Example:** - - `.setwelcome Hi {mention}, Welcome to {chat} chat` - or reply to supported media - - reply `.setwelcome` to text message or supported media with text""") +@userge.on_cmd("setwelcome", about={ + 'header': "Creates a welcome message in current chat", + 'options': { + '{fname}': "add first name", + '{lname}': "add last name", + '{flname}': "add full name", + '{uname}': "username", + '{chat}': "chat name", + '{mention}': "mention user"}, + 'types': [ + 'audio', 'animation', 'document', 'photo', + 'sticker', 'voice', 'video_note', 'video'], + 'examples': [ + ".setwelcome Hi {mention}, Welcome to {chat} chat\n" + "or reply to supported media", + "reply .setwelcome to text message or supported media with text"], + 'others': "**max media size limt** : 10MB !"}) async def setwel(msg: Message): await raw_set(msg, 'Welcome', WELCOME_COLLECTION, WELCOME_CHATS) -@userge.on_cmd("setleft", about="""\ -__Creates a left message in current chat :)__ - -**Available options:** - - `{fname}` : __add first name__ - `{lname}` : __add last name__ - `{flname}` : __add full name__ - `{uname}` : __username__ - `{chat}` : __chat name__ - `{mention}` : __mention user__ - -**Supported Media Types:** - - `audio` , `animation`, `document`, - `photo`, `sticker`, `voice`, - `video_note`, `video` - - **max media size limt** : 10MB ! - -**Example:** - - `.setleft {flname},
Why you left :(
` - or reply to supported media - - reply `.setleft` to text message or supported media with text""") +@userge.on_cmd("setleft", about={ + 'header': "Creates a left message in current chat", + 'options': { + '{fname}': "add first name", + '{lname}': "add last name", + '{flname}': "add full name", + '{uname}': "username", + '{chat}': "chat name", + '{mention}': "mention user"}, + 'types': [ + 'audio', 'animation', 'document', 'photo', + 'sticker', 'voice', 'video_note', 'video'], + 'examples': [ + ".setleft {flname}, Why you left :(\n" + "or reply to supported media", + "reply .setleft to text message or supported media with text"], + 'others': "**max media size limt** : 10MB !"}) async def setleft(msg: Message): await raw_set(msg, 'Left', LEFT_COLLECTION, LEFT_CHATS) -@userge.on_cmd("nowelcome", about="\ -__Disables and removes welcome message in the current chat__") +@userge.on_cmd("nowelcome", about={ + 'header': "Disables and removes welcome message in the current chat"}) async def nowel(msg: Message): await raw_no(msg, 'Welcome', WELCOME_COLLECTION, WELCOME_CHATS) -@userge.on_cmd("noleft", about="__Disables and removes left message in the current chat__") +@userge.on_cmd("noleft", about={ + 'header': "Disables and removes left message in the current chat"}) async def noleft(msg: Message): await raw_no(msg, 'Left', LEFT_COLLECTION, LEFT_CHATS) -@userge.on_cmd("dowelcome", about="__Turns on welcome message in the current chat__") +@userge.on_cmd("dowelcome", about={ + 'header': "Turns on welcome message in the current chat"}) async def dowel(msg: Message): await raw_do(msg, 'Welcome', WELCOME_COLLECTION, WELCOME_CHATS) -@userge.on_cmd("doleft", about="__Turns on left message in the current chat :)__") +@userge.on_cmd("doleft", about={ + 'header': "Turns on left message in the current chat :)"}) async def doleft(msg: Message): await raw_do(msg, 'Left', LEFT_COLLECTION, LEFT_CHATS) -@userge.on_cmd("delwelcome", about="__Delete welcome message in the current chat :)__") +@userge.on_cmd("delwelcome", about={ + 'header': "Delete welcome message in the current chat :)"}) async def delwel(msg: Message): await raw_del(msg, 'Welcome', WELCOME_COLLECTION, WELCOME_CHATS) -@userge.on_cmd("delleft", about="__Delete left message in the current chat :)__") +@userge.on_cmd("delleft", about={ + 'header': "Delete left message in the current chat :)"}) async def delleft(msg: Message): await raw_del(msg, 'Left', LEFT_COLLECTION, LEFT_CHATS) -@userge.on_cmd("lswelcome", about="__Shows the activated chats for welcome__") +@userge.on_cmd("lswelcome", about={ + 'header': "Shows the activated chats for welcome"}) async def lswel(msg: Message): await raw_ls(msg, 'Welcome', WELCOME_COLLECTION) -@userge.on_cmd("lsleft", about="__Shows the activated chats for left__") +@userge.on_cmd("lsleft", about={ + 'header': "Shows the activated chats for left"}) async def lsleft(msg: Message): await raw_ls(msg, 'Left', LEFT_COLLECTION) -@userge.on_cmd("vwelcome", about="__Shows welcome message in current chat__") +@userge.on_cmd("vwelcome", about={ + 'header': "Shows welcome message in current chat"}) async def viewwel(msg: Message): await raw_view(msg, 'Welcome', WELCOME_COLLECTION) -@userge.on_cmd("vleft", about="__Shows left message in current chat__") +@userge.on_cmd("vleft", about={ + 'header': "Shows left message in current chat"}) async def viewleft(msg: Message): await raw_view(msg, 'Left', LEFT_COLLECTION) diff --git a/userge/plugins/utils/whois.py b/userge/plugins/utils/whois.py index 6cdad11d1..9398ccddf 100644 --- a/userge/plugins/utils/whois.py +++ b/userge/plugins/utils/whois.py @@ -11,16 +11,10 @@ from userge import userge, Message -@userge.on_cmd("whois", about="""\ -__use this to get any user details__ - -**Usage:** - -`just reply to any user message or add user_id or username` - -**Example:** - - `.whois [user_id | username]`""") +@userge.on_cmd("whois", about={ + 'header': "use this to get any user details", + 'usage': "just reply to any user message or add user_id or username", + 'examples': ".whois [user_id | username]"}) async def who_is(message: Message): await message.edit("`Collecting Whois Info.. Hang on!`") user_id = message.input_str diff --git a/userge/plugins/utils/wikipedia.py b/userge/plugins/utils/wikipedia.py index 7590634a2..ee4418667 100644 --- a/userge/plugins/utils/wikipedia.py +++ b/userge/plugins/utils/wikipedia.py @@ -11,20 +11,11 @@ from userge import userge, Message -@userge.on_cmd("wiki", about="""\ -__do a Wikipedia search__ - -**Available Flags:** - - `-l` : __limit the number of returned results (defaults to 5)__ - -**Usage:** - - `.wiki [flags] [query | reply to msg]` - -**Example:** - - `.wiki -l5 userge`""") +@userge.on_cmd("wiki", about={ + 'header': "do a Wikipedia search", + 'flags': {'-l': "limit the number of returned results (defaults to 5)"}, + 'usage': ".wiki [flags] [query | reply to msg]", + 'examples': ".wiki -l5 userge"}) async def wiki_pedia(message: Message): await message.edit("Processing ...") diff --git a/userge/versions.py b/userge/versions.py index b4ea95e90..7e86bd220 100644 --- a/userge/versions.py +++ b/userge/versions.py @@ -14,7 +14,7 @@ __version_mjaor__ = 0 __version_minor__ = 1 __version_micro__ = 3 -__version_beta__ = 9 +__version_beta__ = 10 __version__ = "{}.{}.{}".format(__version_mjaor__, __version_minor__,