From 751062a7060dc3f9e8c4a03c11c1ae0947bac465 Mon Sep 17 00:00:00 2001 From: m5rcel { Marcel } Date: Mon, 8 Sep 2025 22:11:19 +0200 Subject: [PATCH] Add files via upload --- commands/__pycache__/cmd_cd.cpython-313.pyc | Bin 0 -> 2418 bytes .../__pycache__/cmd_credits.cpython-313.pyc | Bin 0 -> 2677 bytes commands/__pycache__/cmd_exit.cpython-313.pyc | Bin 0 -> 620 bytes .../__pycache__/cmd_fastfetch.cpython-313.pyc | Bin 0 -> 8034 bytes commands/__pycache__/cmd_nano.cpython-313.pyc | Bin 0 -> 1509 bytes commands/__pycache__/cmd_new.cpython-313.pyc | Bin 0 -> 1523 bytes commands/__pycache__/cmd_run.cpython-313.pyc | Bin 0 -> 3071 bytes commands/cmd_cd.py | 46 ++++ commands/cmd_credits.py | 35 +++ commands/cmd_exit.py | 6 + commands/cmd_fastfetch.py | 202 +++++++++++++++ commands/cmd_nano.py | 15 ++ commands/cmd_new.py | 16 ++ commands/cmd_run.py | 48 ++++ files/m5rcel.m5r | 46 ++++ files/snake.m5r | 234 ++++++++++++++++++ files/test.m5r | 27 ++ files/testing.m5r | 1 + files/testing.pyjs.m5r | 1 + utils/downloader.py | 7 + utils/updater.py | 14 ++ 21 files changed, 698 insertions(+) create mode 100644 commands/__pycache__/cmd_cd.cpython-313.pyc create mode 100644 commands/__pycache__/cmd_credits.cpython-313.pyc create mode 100644 commands/__pycache__/cmd_exit.cpython-313.pyc create mode 100644 commands/__pycache__/cmd_fastfetch.cpython-313.pyc create mode 100644 commands/__pycache__/cmd_nano.cpython-313.pyc create mode 100644 commands/__pycache__/cmd_new.cpython-313.pyc create mode 100644 commands/__pycache__/cmd_run.cpython-313.pyc create mode 100644 commands/cmd_cd.py create mode 100644 commands/cmd_credits.py create mode 100644 commands/cmd_exit.py create mode 100644 commands/cmd_fastfetch.py create mode 100644 commands/cmd_nano.py create mode 100644 commands/cmd_new.py create mode 100644 commands/cmd_run.py create mode 100644 files/m5rcel.m5r create mode 100644 files/snake.m5r create mode 100644 files/test.m5r create mode 100644 files/testing.m5r create mode 100644 files/testing.pyjs.m5r create mode 100644 utils/downloader.py create mode 100644 utils/updater.py diff --git a/commands/__pycache__/cmd_cd.cpython-313.pyc b/commands/__pycache__/cmd_cd.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..268372b3640583e2ba660b8b4f69e560b93e1759 GIT binary patch literal 2418 zcmbtV|4-XS6hAu-Bw&&>Elt}1@qlVgfvj4?&;s=9Ho8^+`mvOof4gxgw#q?e?!ft?Z@3YF(AkU(@yf;d-v|W z_qlh^?^Rk_ngAZZAN^(KX#)VS3F8c=MpSw+u?Tp;Q`Z0_D}9Z+N<*3h$3Q3GT_*s~ z^wZVT&^1j(-ERpq8l@2PnGO}HDyq&@jj3>$SOgOQQape(PeB(?p8${{_Mn?*V8gUK z+JL;5<;!{|BWm(nH`b6GRK$#{_Eo;a#3Hy6NRwTAjMwl0kld+JlO`K$#EvCJ_1Cba zKzd6jg^>}zc#kahNV$?N4!ynh*GPPF%lb5k(xZ?-iF%NCN=++ySv7z8ZQP&=66>QchYrt47s7&(n59@^-`y?iojT_pt5Y6vuvoyJY}q z^w{J+(P-VPb?|6x-IGqy$xvNObx=84PUgrs0{@DiPEp$bv)+y~;<$rt{Dea#+Z<|p z_zMjv&LA}Tgd$71vG zi;|=m1}7_;s>liMOMQ-$L`~C8F0F`PE1Wr_aJACI)e2l}{_v>I8FSJMhwBxtcsjh7 z;GzNO$CriV&x52Vp+<4iuuG&z(_zM@nA^IlK~j5>OS&uDbr6zFhvfG|O$M%mrg2xr zb=5r!Rn3H?&>&ax(@&6FHL$y=3zB?CUW`&!WzkfSM^o+!#JoWc}EbYpL>vf@a)JB9p85p{U4OWky5zV3iswc*dZ>*1BHQ=^M&)P@#l%P#Pf4& z=ZfLP6Hhr5DTPj3q0_7JQqPdpGgJxWW)k@shva^7pT^hraDzI+Z{5vYoer{44f)nGL>aZpjT~2Xe#N;pJnc=1!}* zv)q0%cQt$U@#vc^g~*35;y(}mIQXLPW%~syc;Q#}B0P$N7iD%l8HuL-=A+R@(t}7B z#674<5Hh+vmnJkT2w%;K>6*kZ2vfMhnQ2v1G+hwj5n`bWPpDN8@Y|cJB#0*Nn3HoR zZnVN0u)W&v2}$?1Cqfv+`8VJl?RLlh^u6c4L{(1`83sv`5P2j$twS**+DTN^KaB<3 oHj!tj3iTZ9#RAgg3{tN)T@*#V2HxMm@xPcTb%}Zh$ZRYA0}kk@%K!iX literal 0 HcmV?d00001 diff --git a/commands/__pycache__/cmd_credits.cpython-313.pyc b/commands/__pycache__/cmd_credits.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca9e6f44d0f31271140352d60913ba43b209934f GIT binary patch literal 2677 zcmbVOU2M}v96vj8lIE)=ZL>CXn#&3-h=z_*HfROw+5jzWKy?Fj$*@w#X;US3I6H%8 zY#<({AWdSCK=fe`tyHP0#76hlJxxeR3~ACF!KUiQ6MH~?1C?p7yK@|ouukiClJCy{ zkKh06{P%6RTy}uRGw%=64hDeV$xCIJjm<^?Z*Bn&aMVdKOhIaxhBOOWzz)FCKERoJ z=&~dXZgD_ZU@W!Its15xpv# zn^c-eglW!Gv5D(S*XvfR^fvKT_e;nBAAU9J+JBF;iO^r+g-wm%#03Dd*zZg*Z04Hl z0q3pqs{xC@HgIL$2s1beMzY|TT1XxvjTNCtb7dE{RP0n%A}Lw7oZD7Ca~3@kZ`fL? zRh4&J%-W~|fCK!8s`~yRd)o;;;;lqD)>7HMT8Ts@UKUINe_Lq%7^Wes(MFIZ-2(+N zm2;1Xu{b*@ej=vij0khi%&a;sOEXG9NW^n(r=dI}3MzX-R@9_4#qPqQnUp-679|zg z1UV(cSUQ$#4J%@tO~{Z{MVL-Xu@tM|W`{L$oo<5Dac5ae{OnUm8ZtE6L4W&4NNX)%>yd;M9`+@9Y0ro7&~x=s$cLHyPr zUPIJ*WBawSF6K;q-Cc-cb95)WPB5~h%RRk$jWv{4jP z)#*5V|Hz2nhRlkXN}#$)`4WFI8CRzfqbAjqh^#`nyCbs{ON+=1WlS{V{9#rm7LVgZ zD&&~4#z1=q4o7j$p%TS)B#$7+#VF1m`8g<2Asy!p$UtTmnP65zp4vZ10Mke(S03Vi za}}&LdGmE^4Xt_Rr3GwjzFk+S%YQnzYq4p`x8R$1YOYRg-%-u^!IOrj+m3=G|JmHg zou<3KWnU5VdbIb#n)3|dISbDG=X2*4<4ZFOGxJf+wO>1MN^_njJbS^OzpQQVyc54W zvpiG8%)?q=NOPVdOk2U0&&~N32bYEyhUfbBve##(j=MZ;ZCfMnt5JPV`@_1V=6w) zlUY?%Fz+4AgS*MpK_+r|^od+W^waqT_=9d?&QWC{!mqiZ5IOyZ(uFtVhQfi9K%&Cb z7@@v4IGQtsL65=d0Df}_k}p2zj$V3qG8&0=bsp;dcuyLU`xT9ES0*JpNv>L|cu9rC zfqE%5!j72$lqHx@Z3aE)HA^TX=$a-Q7-_QH{PeIeY%0a0O(UB3IG5A literal 0 HcmV?d00001 diff --git a/commands/__pycache__/cmd_exit.cpython-313.pyc b/commands/__pycache__/cmd_exit.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..272f98a23c6faaa203724d4382a91874c47098c4 GIT binary patch literal 620 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 literal 0 HcmV?d00001 diff --git a/commands/__pycache__/cmd_nano.cpython-313.pyc b/commands/__pycache__/cmd_nano.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a8016059074e655ce272fb3d546d65c2478e5dd0 GIT binary patch literal 1509 zcma)5&u<$=6rTMVH`%apa6-0H(WpWpt2C)lYYA0|ODF{zxztNUD_a_Eb|>zl^{$y& z6Ud>eIG_{>g&-oE6X8UA;!ogTh?Q2UMn)WZsCq-S5Laf_yR{{9V5EKX-kbNno%g*r zgX!r>z}K_+-|uKL08fRHFEvvJm$`BP9N~imp@X70>J_}4;!b4gX9jAW6IQ)%Qf}0IEZY8sT7A> ztgz`)jQoJG!d4LC$ZcXOih&R^d+kbngJMGK98G*)?BlvOMq5ThYEa!ynvjYa=Ynm0~u$bXty z0ibp!|8FfFY++T6+&9`C<#fzf_y}K8R(N2J4nfV#^G?rkw7j-zF^?SW_3NSFXUFbI^}5h1?DCmjO*K zK#yQI38DrJl2s;c+fzjF!}JDDaP$Qc6fr%GrA%v)AWDd6E7NaZU0=WPDO2MXj+o|! zF~w|>wl`ZO_AupR?73lR%S2Gi5&R&D2^GDEkO;b%LfR2C$LEkc#Q!Ma;vVQ1U+q{w zSlzb|Zyy&g?&^KBxVL?Od++Z3yIue1;HO|Xn0=%8;~Smj{pG{O2c_Svht`9sqe~wj z!JEC=n~#iY-KA7B%x}%^{IAw8*3rW9mfHu zNU+&XFh%GgNPm+uK*W1Xg&1-wi24S+kQJ@`_oSw+3ho0`xjY3CVKz? literal 0 HcmV?d00001 diff --git a/commands/__pycache__/cmd_new.cpython-313.pyc b/commands/__pycache__/cmd_new.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bf2d04b95c337d97a8eae98844bc371d67531aa GIT binary patch literal 1523 zcmZt`U2hvjaP~eN+wn(g(oo7rH^m5_Xj9raDvBTyF~Nvdmhj0E$d*o5-#NWt--W%4 zO#D>!0W}B|A`!(rVV)4b0>LkcMXE$g`cx#;H&hEn;)&fmpA$u%lV@jUXJ+TqgJd!e z4E~<^_5KM0c*>a&q#-f5#)w@|K}C0f@Kd;hJ{E|8;SyX0RlE$Uv>*i9L|jFR{ERat z1ySikhnV%?D!}X&9|o8myHEpyR3L(ih^Pvefk@mRkyVLAR%InZ<0Z3Qa9SY{HRATHqi;2}f1P!Y^i1JhN}^(25TREMDhl*5$ISeGZxFhlaw zOqgy3nj`B~P=r!Pnrkf(MWRvDHr%%5-KT=%QfXahl(gnpwjxr=HJc3@y{EgTW>|zq z8&=b_^_J=KWH81wS6Hl7T$8vp=8gaAj$zj7K^@#$y=7>&*`8b9q)|@%c&_!c<%}?aU+k}$bQh{z!H4pw1fhhLlD~WoDlks-d~@`-0IH*+SEHemvOlRI z7n~{@?=!__bY8s9ltS+qR-ww;9l&@iRSerIfQ>4soDTI*Pd4epnqa;O>8o zUs|r`&Qa9vOx?JF*=%4oMwm}pyb~)hCC@Y#u@WOO78l{grIEmh%In0kJ;Iw!#q!Dr zRC3l$o62osc_x*M<&~9^B9H{XM-7*^A7jF+MMbh<)6|(sWIXrnK4jMtFP4D-6+#n&x`CXVo>`^N4kC!!un?`vpjbtMK9wz7sy;|1*9lU%_)h zlo$SuN925<$aNISZwigpou)(dmhQJAFn^u<7`dd;cY{cm$Q$f}kEVN(p?^e#(4P={ Q0xz9N36y^h4EbjN1LdbBP5=M^ literal 0 HcmV?d00001 diff --git a/commands/__pycache__/cmd_run.cpython-313.pyc b/commands/__pycache__/cmd_run.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c47bda17fc4dc302dcdce024ae38a3a093d3afda GIT binary patch literal 3071 zcmahLOKcm*b@oS5GXIijSX|R-1mCB5R89>KV9;<5c)e^ID>B@`xgM&Kr)h<*AZ?&1~c_Fi`hElFb9x* zoxdbtK}3D%1d_RaB=h5JLke~+GEw0nT_mCm;ipWjWg1(JnQ1QeML;&tJfb&%bOt1| z{Rs0^9u{OCBneR$>5_`ZYi2&5Hq?h5a3sSu1yDerPS^Xtf@uRKS;-L(YiG#Jc#|4w zl2ic!ugr{j5i;28fn4iU$}t9#z)a5$sqPeJqy=@Ui*~BUz%a7xzK-`+4 zS|#0HBJPE>r75b832Rz}FQkFS|H#yhC`Wip%VjaWg1EDKPBYSZ&7u-TQ6!PqUYSo? z8n)&^B>iPfRh!Q=3}ek_@~VQ1My#+x+=`+bx~(XryKTCdLv({Y>$@=h1l9aUANa+p zU)%~m@JFitNX^r;>8g5$)@Evb;xD{=J>kl9dAc%Jp4;l%?Rj~P|7GVsoJ5(HxnMzk zQg=ZBOt*njl%YPPW<)q^3MDZ7vm=QPIZzBq!G~&N}X`_r57Bm4dG_*HR0PVc;{rB z>R_@DKK=>ba3x)mV>o9MphHT7&D-&FIIkR#gA**g+$D`35Ya?ilD>6N(lOYG}+olz0|-4N|1-4bbK6={`>5vJ>@ zf zvV@JDA)KWxTC}!_BBn)wbjBAoLt8H3Npk!^#iivqo-;G)oHZG1vCt&5X#PHg3cNEA z|9E;^zJ25U8@E%NsgI}sZ9x%5KOGoi2veF`<)EI!tu9r|X|_gORxz8^mx-%TH_KJ% z8C<5M5?>}=u!~qz%%WW=+Jv{YWt$*)I0ubqb*$-tk;btRQCrqBMLWHa)7l;p!OT}) zy*d+%_F-C5@e!DaOIy}0+af{%>xPY~X$dD?yg+!fpc#b6T3RJ6)<{QIH`H`4M;Mv7 zZd{z3`{6b0q1?`*2K z_4oBg``q&c-+Q4FDMvO-TlR-5AFOP>dFQ#E!E@Enx%-~UnkV!{u=kc)(aZYwNHzH4 zgW%a}@a%4IV$JnMsHZae?&!|o*!Ek$#h=(8*}I|mTE}1g;fBmpu;~Wy%*@cm96B<`R&lX!0DR5w@G|Ytt^$7w!$9{elS=K$L{>#Uf}Fw zH}d+|XMa9>Yw0u3@RJdG;b-32uO5piaC{#zoe8F8t)0QSYH04yp39FoO8*KpIdJwr z)_1`0zkhjX>J0aX=U$zhX3!tcbWKfm++|Kqk8*cM*y%BJH_A|al%x1q-;BUT*?RQU zqc{=mpnr;JjKQCxE=9?kYB5J~kD~mzn9enK{ECv*v1LOnX@;pNm^SrBEc7ahWv6XD zqoi#p1q(%6vlQhw2-9xgh#C6N2GfZ~lSO0yXXs0o7smhPIU$G*M!F4ATF)=qVepG| zqSchfXb$ospROlaT@b!NcUw0Qcf9fNNjwD`5Q)edf(gvVFrTB&`ZxGF^8W=Ld%{N< L@k^)xjf?*aga~7? literal 0 HcmV?d00001 diff --git a/commands/cmd_cd.py b/commands/cmd_cd.py new file mode 100644 index 0000000..ef8fc18 --- /dev/null +++ b/commands/cmd_cd.py @@ -0,0 +1,46 @@ +# commands/cmd_cd.py +import os +from colorama import Fore + +class CdCommand: + def __init__(self, files_dir, shell_ref, target_dir): + # files_dir = ~/m5rcode/files + self.files_dir = files_dir + self.project_root = os.path.dirname(files_dir) # ~/m5rcode + self.shell = shell_ref[0] # the M5RShell instance + self.target = target_dir.strip() + + def run(self): + if not self.target or self.target == '.': + # Stay in current directory + return + + # Compute new absolute path + candidate = os.path.abspath( + os.path.normpath( + os.path.join(self.shell.cwd, self.target) + ) + ) + + # If they typed '..' from files_dir, allow up to project_root + if self.target == '..': + # from files_dir → project_root + if self.shell.cwd == self.files_dir: + new_path = self.project_root + # from any subfolder of files_dir → one level up, but not above project_root + else: + new_path = os.path.dirname(self.shell.cwd) + if not new_path.startswith(self.project_root): + new_path = self.project_root + else: + new_path = candidate + + # Check it stays within project_root + if not new_path.startswith(self.project_root): + print(Fore.RED + "Access denied: You cannot leave the m5rcode project.") + return + + if os.path.isdir(new_path): + self.shell.cwd = new_path + else: + print(Fore.RED + f"No such directory: {self.target}") diff --git a/commands/cmd_credits.py b/commands/cmd_credits.py new file mode 100644 index 0000000..2524839 --- /dev/null +++ b/commands/cmd_credits.py @@ -0,0 +1,35 @@ +# commands/cmd_credits.py +from colorama import Fore, Style + + +class CreditsCommand: + def run(self): + box_width = 70 + title = "Credits" + + credits = [ + (f"{Fore.CYAN}m5rcel{Fore.RESET}", "Lead Developer"), + (f"{Fore.YELLOW}pythonjs.cfd{Fore.RESET}", "Project Hosting & Deployment"), + (f"{Fore.MAGENTA}colorama{Fore.RESET}", "Used for terminal styling"), + (f"{Fore.GREEN}fastfetch inspired{Fore.RESET}", "Design influence"), + (f"{Fore.RED}openai.com{Fore.RESET}", "Some smart AI help ;)"), + ] + + # Top border + print(Fore.MAGENTA + "╭" + "─" * (box_width - 2) + "╮") + print(Fore.MAGENTA + "│" + Fore.CYAN + f"{title:^{box_width - 2}}" + Fore.MAGENTA + "│") + print(Fore.MAGENTA + "├" + "─" * (box_width - 2) + "┤") + + # Content + for name, role in credits: + line = f"{name:<30} {Fore.WHITE}- {role}" + padding = box_width - 3 - len(strip_ansi(line)) + print(Fore.MAGENTA + "│ " + line + " " * padding + Fore.MAGENTA + "│") + + # Bottom border + print(Fore.MAGENTA + "╰" + "─" * (box_width - 2) + "╯" + Style.RESET_ALL) + + +def strip_ansi(text): + import re + return re.sub(r'\x1b\[[0-9;]*m', '', text) diff --git a/commands/cmd_exit.py b/commands/cmd_exit.py new file mode 100644 index 0000000..aea361b --- /dev/null +++ b/commands/cmd_exit.py @@ -0,0 +1,6 @@ +from colorama import Fore + +class ExitCommand: + def run(self): + print(Fore.YELLOW + "Bye!") + return True # Signals to shell to exit diff --git a/commands/cmd_fastfetch.py b/commands/cmd_fastfetch.py new file mode 100644 index 0000000..6947487 --- /dev/null +++ b/commands/cmd_fastfetch.py @@ -0,0 +1,202 @@ +# commands/cmd_fastfetch.py +import platform +import re +import datetime +from pathlib import Path + +# Try to import psutil for uptime, provide a fallback if not available +try: + import psutil + _PSUTIL_AVAILABLE = True +except ImportError: + _PSUTIL_AVAILABLE = False + +# In a real terminal, colorama would handle ANSI escape codes. +# For direct output in a web environment, these colors might not render +# unless the terminal emulator supports them. +# We'll include them as they would be in a real terminal script. +class Fore: + BLACK = '\x1b[30m' + RED = '\x1b[31m' + GREEN = '\x1b[32m' + YELLOW = '\x1b[33m' + BLUE = '\x1b[34m' + MAGENTA = '\x1b[35m' + CYAN = '\x1b[36m' + WHITE = '\x1b[37m' + RESET = '\x1b[39m' + +class Style: + BRIGHT = '\x1b[1m' + DIM = '\x1b[2m' + NORMAL = '\x1b[22m' + RESET_ALL = '\x1b[0m' + +def strip_ansi(text): + """Removes ANSI escape codes from a string.""" + return re.sub(r'\x1b\[[0-9;]*m', '', text) + +class FastfetchCommand: + def _get_uptime(self): + """Calculates and returns the system uptime in a human-readable format.""" + if not _PSUTIL_AVAILABLE: + return "N/A (psutil not installed)" + try: + boot_time_timestamp = psutil.boot_time() + boot_datetime = datetime.datetime.fromtimestamp(boot_time_timestamp) + current_datetime = datetime.datetime.now() + uptime_seconds = (current_datetime - boot_datetime).total_seconds() + + days = int(uptime_seconds // (24 * 3600)) + uptime_seconds %= (24 * 3600) + hours = int(uptime_seconds // 3600) + uptime_seconds %= 3600 + minutes = int(uptime_seconds // 60) + seconds = int(uptime_seconds % 60) + + uptime_str = [] + if days > 0: + uptime_str.append(f"{days}d") + if hours > 0: + uptime_str.append(f"{hours}h") + if minutes > 0: + uptime_str.append(f"{minutes}m") + if seconds > 0 or not uptime_str: # Ensure seconds are shown if nothing else, or if uptime is very short + uptime_str.append(f"{seconds}s") + + return " ".join(uptime_str) + except Exception: + return "Error calculating uptime" + + + def run(self): + # Load m5rcode version + m5rcode_version = "1.0.0" + try: + version_file = Path(__file__).parents[1] / "version.txt" + if version_file.exists(): + m5rcode_version = version_file.read_text().strip() + except Exception: + pass # Keep default "1.0.0" if file not found or error + + # ASCII "M" logo (22 lines) + # Ensure consistent width for ASCII art (27 characters wide including leading/trailing spaces) + ascii_m = [ + " _____ ", # 27 chars + " /\\ \\ ", # 27 chars + " /::\\____\\ ", # 27 chars + " /::::| | ", # 27 chars + " /:::::| | ", # 27 chars + " /::::::| | ", # 27 chars + " /:::/|::| | ", # 27 chars + " /:::/ |::| | ", # 27 chars + " /:::/ |::|___|______ ", # 27 chars + " /:::/ |::::::::\\ \\ ", # 27 chars + " /:::/ |:::::::::\\____\\", # 27 chars + " \\::/ / ~~~~~/:::/ / ", # 27 chars + " \\/____/ /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " /:::/ / ", # 27 chars + " \\::/ / ", # 27 chars + " \\/____/ ", # 27 chars + " ", # 27 chars (padding line) + ] + + # Get uptime + uptime_info = self._get_uptime() + + # Labels for system info, padded to a fixed width for alignment + # Maximum label length is "m5rcode Version:" (15 chars) + LABEL_PAD = 17 # Consistent padding for labels + + # System info lines + actual_info_lines = [ + f"{Fore.CYAN}{'m5rcode Version:':<{LABEL_PAD}}{Fore.RESET} {m5rcode_version}", + f"{Fore.CYAN}{'Python Version:':<{LABEL_PAD}}{Fore.RESET} {platform.python_version()}", + f"{Fore.CYAN}{'Platform:':<{LABEL_PAD}}{Fore.RESET} {platform.system() + ' ' + platform.release()}", + f"{Fore.CYAN}{'Machine:':<{LABEL_PAD}}{Fore.RESET} {platform.machine()}", + f"{Fore.CYAN}{'Processor:':<{LABEL_PAD}}{Fore.RESET} {platform.processor()}", + f"{Fore.CYAN}{'Uptime:':<{LABEL_PAD}}{Fore.RESET} {uptime_info}", + ] + + # Determine the widest string in actual_info_lines after stripping ANSI for content length + max_info_content_width = 0 + for line in actual_info_lines: + max_info_content_width = max(max_info_content_width, len(strip_ansi(line))) + + # Determine the fixed width for ASCII art after stripping + ascii_art_display_width = len(strip_ansi(ascii_m[0])) # Assuming all ASCII lines have same display width + + # Define a consistent separator width between ASCII art and info lines + SEPARATOR_WIDTH = 4 # e.g., " " + + # Calculate padding for vertical centering + num_ascii_lines = len(ascii_m) + num_info_content_lines = len(actual_info_lines) + + total_blank_lines_info = num_ascii_lines - num_info_content_lines + top_padding_info = total_blank_lines_info // 2 + bottom_padding_info = total_blank_lines_info - top_padding_info + + info_lines_padded = [""] * top_padding_info + actual_info_lines + [""] * bottom_padding_info + + # Pad info_lines_padded to match ascii_m's length if there's any discrepancy + # This shouldn't be necessary if num_ascii_lines calculation is correct above + # but as a safeguard: + max_overall_lines = max(num_ascii_lines, len(info_lines_padded)) + ascii_m += [""] * (max_overall_lines - len(ascii_m)) + info_lines_padded += [""] * (max_overall_lines - len(info_lines_padded)) + + + # Calculate the overall box width + # The widest possible line will be (ASCII art width) + (Separator width) + (Max info content width) + box_content_width = ascii_art_display_width + SEPARATOR_WIDTH + max_info_content_width + + # Add buffer for box borders and internal padding + box_width = box_content_width + 2 # For left and right borders + + # Ensure minimum width for header title + min_header_width = len("m5rcode Fastfetch") + 4 # Title + padding + box_width = max(box_width, min_header_width) + + + # Header of the box + print(Fore.MAGENTA + "╭" + "─" * (box_width - 2) + "╮") + title = "m5rcode Fastfetch" + padded_title = title.center(box_width - 2) + print(Fore.MAGENTA + "│" + Fore.CYAN + padded_title + Fore.MAGENTA + "│") + print(Fore.MAGENTA + "├" + "─" * (box_width - 2) + "┤") + + # Body of the box + for ascii_line, info_line in zip(ascii_m, info_lines_padded): + effective_ascii_width = len(strip_ansi(ascii_line)) + effective_info_width = len(strip_ansi(info_line)) + + # Calculate the current line's effective content width + current_line_content_width = effective_ascii_width + SEPARATOR_WIDTH + effective_info_width + + # Calculate padding needed to fill the box width for THIS specific line + padding_needed = (box_width - 2) - current_line_content_width + padding_needed = max(0, padding_needed) # Ensure non-negative + + print( + Fore.MAGENTA + "│" + + ascii_line + + " " * SEPARATOR_WIDTH + + info_line + + " " * padding_needed + + Fore.MAGENTA + "│" + ) + + # Footer of the box + print(Fore.MAGENTA + "╰" + "─" * (box_width - 2) + "╯" + Style.RESET_ALL) + +# Example usage (for testing this script directly) +if __name__ == "__main__": + # If psutil is not installed, the uptime will show "N/A (psutil not installed)" + # To test full functionality, run `pip install psutil` in your environment. + FastfetchCommand().run() diff --git a/commands/cmd_nano.py b/commands/cmd_nano.py new file mode 100644 index 0000000..2eb84dd --- /dev/null +++ b/commands/cmd_nano.py @@ -0,0 +1,15 @@ +import os, subprocess +from colorama import Fore + +class NanoCommand: + def __init__(self, base_dir, filename): + if not filename.endswith(".m5r"): + filename += ".m5r" + self.path = os.path.join(base_dir, filename) + + def run(self): + editor = os.getenv("EDITOR", "notepad") + if not os.path.exists(self.path): + print(Fore.YELLOW + f"Note: {self.path} does not exist, creating it.") + open(self.path, "w").close() + subprocess.call([editor, self.path]) diff --git a/commands/cmd_new.py b/commands/cmd_new.py new file mode 100644 index 0000000..aac30b8 --- /dev/null +++ b/commands/cmd_new.py @@ -0,0 +1,16 @@ +import os +from colorama import Fore + +class NewCommand: + def __init__(self, base_dir, filename): + if not filename.endswith(".m5r"): + filename += ".m5r" + self.path = os.path.join(base_dir, filename) + + def run(self): + if os.path.exists(self.path): + print(Fore.RED + f"Error: {self.path} already exists.") + return + with open(self.path, "w") as f: + f.write("// New m5r file\n") + print(Fore.GREEN + f"Created: {self.path}") diff --git a/commands/cmd_run.py b/commands/cmd_run.py new file mode 100644 index 0000000..88077e5 --- /dev/null +++ b/commands/cmd_run.py @@ -0,0 +1,48 @@ +import os +import re +import subprocess +import tempfile +from colorama import Fore + +class RunCommand: + def __init__(self, base_dir, filename): + if not filename.endswith(".m5r"): + filename += ".m5r" + self.base_dir = base_dir + self.path = os.path.join(base_dir, filename) + + def run(self): + if not os.path.exists(self.path): + print(Fore.RED + f"Error: {self.path} not found.") + return + + source = open(self.path, encoding="utf-8").read() + # Extract only Python segments + py_segs = re.findall(r'<\?py(.*?)\?>', source, re.S) + if not py_segs: + print(Fore.YELLOW + "No Python code found in this .m5r file.") + return + + combined = "\n".join(seg.strip() for seg in py_segs) + + # Write to a temporary .py file + with tempfile.NamedTemporaryFile("w", delete=False, suffix=".py") as tf: + tf.write(combined) + tmp_path = tf.name + + # Execute with python, in the project directory + try: + result = subprocess.run( + [ "python", tmp_path ], + cwd=self.base_dir, + capture_output=True, + text=True + ) + if result.stdout: + print(result.stdout, end="") + if result.stderr: + print(Fore.RED + result.stderr, end="") + except FileNotFoundError: + print(Fore.RED + "Error: 'python' executable not found on PATH.") + finally: + os.unlink(tmp_path) diff --git a/files/m5rcel.m5r b/files/m5rcel.m5r new file mode 100644 index 0000000..5f80ee1 --- /dev/null +++ b/files/m5rcel.m5r @@ -0,0 +1,46 @@ + + +alert('".implode(array_map('chr',${m}))."');"; +?> + + (char)c)); +string msg = string.Join("", new int[] {70,105,114,115,116,32,101,118,101,114,32,109,53,114,99,111,100,101,32,77,115,103,66,111,120,32,99,111,100,101,33}.Select(c => (char)c)); +System.Windows.Forms.MessageBox.Show(msg, title); +?> + +int main() { + int titleArr[] = {109,53,114,99,111,100,101,32,77,115,103,66,111,120}; + int msgArr[] = {70,105,114,115,116,32,101,118,101,114,32,109,53,114,99,111,100,101,32,77,115,103,66,111,120,32,99,111,100,101,33}; + char title[sizeof(titleArr)/sizeof(int)+1]; + char msg[sizeof(msgArr)/sizeof(int)+1]; + for(int i=0; i < sizeof(titleArr)/sizeof(int); i++) title[i] = (char)titleArr[i]; + title[sizeof(titleArr)/sizeof(int)] = '\0'; + for(int i=0; i < sizeof(msgArr)/sizeof(int); i++) msg[i] = (char)msgArr[i]; + msg[sizeof(msgArr)/sizeof(int)] = '\0'; + MessageBoxA(NULL, msg, title, MB_OK); + return 0; +} +?> diff --git a/files/snake.m5r b/files/snake.m5r new file mode 100644 index 0000000..0b0c2d6 --- /dev/null +++ b/files/snake.m5r @@ -0,0 +1,234 @@ + + self._m.bind(''.join([chr(_c) for _c in [60,82,105,103,104,116,62]]), self._cD) # + self._m.bind(''.join([chr(_c) for _c in [60,85,112,62]]), self._cD) # + self._m.bind(''.join([chr(_c) for _c in [60,68,111,119,110,62]]), self._cD) # + self._m.bind('w', self._cD) + self._m.bind('a', self._cD) + self._m.bind('s', self._cD) + self._m.bind('d', self._cD) + + # Start button (Obfuscated) + self._sB = _tk.Button(self._gF, text=''.join([chr(_c) for _c in [83,116,97,114,116,32,71,97,109,101]]), # Start Game + font=(''.join([chr(_c) for _c in [73,110,116,101,114]]), 14, ''.join([chr(_c) for _c in [98,111,108,100]])), # Inter, bold + fg=''.join([chr(_c) for _c in [119,104,105,116,101]]), bg=''.join([chr(_c) for _c in [35,48,48,55,98,102,102]]), # white, #007bff + activebackground=''.join([chr(_c) for _c in [35,48,48,53,54,98,51]]), activeforeground=''.join([chr(_c) for _c in [119,104,105,116,101]]), # #0056b3, white + relief=''.join([chr(_c) for _c in [114,97,105,115,101,100]]), bd=3, # raised + command=self._s_g) # start_game + self._sB.pack(pady=15) + + self._r_g() # reset_game + + def _r_g(self): # reset_game + """Resets the game state and redraws initial elements.""" + self._sn.clear() + for _i in range(_iSL): + self._sn.appendleft((_iSL - 1 - _i, 0)) + + self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right + self._s = 0 + self._gO = False + self._sL.config(text=f"{''.join([chr(_c) for _c in [83,99,111,114,101]])}: {self._s}") # Score + self._c.delete(''.join([chr(_c) for _c in [97,108,108]])) # all + self._p_f() # place_food + self._d_e() # draw_elements + self._sB.config(text=''.join([chr(_c) for _c in [83,116,97,114,116,32,71,97,109,101]]), command=self._s_g) # Start Game, start_game + self._gR = False + + def _s_g(self): # start_game + """Starts the game loop.""" + if not self._gR: + self._gR = True + self._sB.config(text=''.join([chr(_c) for _c in [82,101,115,116,97,114,116,32,71,97,109,101]]), command=self._r_g) # Restart Game, reset_game + self._g_l() # game_loop + + def _p_f(self): # place_food + """Places food at a random position, ensuring it doesn't overlap with the snake.""" + while True: + _x = _r.randint(0, _bW - 1) + _y = _r.randint(0, _bH - 1) + if (_x, _y) not in self._sn: + self._f = (_x, _y) + break + + def _d_e(self): # draw_elements + """Draws the snake and food on the canvas.""" + self._c.delete(''.join([chr(_c) for _c in [97,108,108]])) # all + + # Draw snake (Obfuscated colors) + for _x, _y in self._sn: + self._c.create_rectangle(_x * _cS, _y * _cS, + (_x + 1) * _cS, (_y + 1) * _cS, + fill=''.join([chr(_c) for _c in [35,48,48,102,102,48,48]]), outline=''.join([chr(_c) for _c in [35,48,48,97,97,48,48]]), width=1) # #00ff00, #00aa00 + # Draw food (Obfuscated colors) + if self._f: + _x, _y = self._f + self._c.create_oval(_x * _cS + _cS * 0.1, _y * _cS + _cS * 0.1, + (_x + 1) * _cS - _cS * 0.1, (_y + 1) * _cS - _cS * 0.1, + fill=''.join([chr(_c) for _c in [35,102,102,48,48,48,48]]), outline=''.join([chr(_c) for _c in [35,99,99,48,48,48,48]]), width=1) # #ff0000, #cc0000 + + def _cD(self, _e): # change_direction, event + """Changes the snake's direction based on key press.""" + if self._gO: return + + _k = _e.keysym # key + if _k == ''.join([chr(_c) for _c in [76,101,102,116]]) and self._d != ''.join([chr(_c) for _c in [82,105,103,104,116]]): # Left, Right + self._d = ''.join([chr(_c) for _c in [76,101,102,116]]) # Left + elif _k == ''.join([chr(_c) for _c in [82,105,103,104,116]]) and self._d != ''.join([chr(_c) for _c in [76,101,102,116]]): # Right, Left + self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right + elif _k == ''.join([chr(_c) for _c in [85,112]]) and self._d != ''.join([chr(_c) for _c in [68,111,119,110]]): # Up, Down + self._d = ''.join([chr(_c) for _c in [85,112]]) # Up + elif _k == ''.join([chr(_c) for _c in [68,111,119,110]]) and self._d != ''.join([chr(_c) for _c in [85,112]]): # Down, Up + self._d = ''.join([chr(_c) for _c in [68,111,119,110]]) # Down + elif _k == 'a' and self._d != ''.join([chr(_c) for _c in [82,105,103,104,116]]): # Right + self._d = ''.join([chr(_c) for _c in [76,101,102,116]]) # Left + elif _k == 'd' and self._d != ''.join([chr(_c) for _c in [76,101,102,116]]): # Left + self._d = ''.join([chr(_c) for _c in [82,105,103,104,116]]) # Right + elif _k == 'w' and self._d != ''.join([chr(_c) for _c in [68,111,119,110]]): # Down + self._d = ''.join([chr(_c) for _c in [85,112]]) # Up + elif _k == 's' and self._d != ''.join([chr(_c) for _c in [85,112]]): # Up + self._d = ''.join([chr(_c) for _c in [68,111,119,110]]) # Down + + def _g_l(self): # game_loop + """The main game loop, called repeatedly.""" + if self._gO or not self._gR: return + + _hX, _hY = self._sn[0] # head_x, head_y + _nH = (_hX, _hY) # new_head + + # Calculate new head position (Obfuscated) + if self._d == ''.join([chr(_c) for _c in [85,112]]): _nH = (_hX, _hY - 1) # Up + elif self._d == ''.join([chr(_c) for _c in [68,111,119,110]]): _nH = (_hX, _hY + 1) # Down + elif self._d == ''.join([chr(_c) for _c in [76,101,102,116]]): _nH = (_hX - 1, _hY) # Left + elif self._d == ''.join([chr(_c) for _c in [82,105,103,104,116]]): _nH = (_hX + 1, _hY) # Right + + # Check for collisions (Obfuscated) + if (_nH[0] < 0 or _nH[0] >= _bW or _nH[1] < 0 or _nH[1] >= _bH): + self._e_g() # end_game + return + + if _nH in self._sn: + self._e_g() # end_game + return + + self._sn.appendleft(_nH) + + # Check if food was eaten (Obfuscated) + if _nH == self._f: + self._s += 1 + self._sL.config(text=f"{''.join([chr(_c) for _c in [83,99,111,114,101]])}: {self._s}") # Score + self._p_f() # place_food + else: + self._sn.pop() + + self._d_e() # draw_elements + self._m.after(_gTI, self._g_l) # game_loop + + def _e_g(self): # end_game + """Ends the game and displays a game over message.""" + self._gO = True + self._gR = False + self._c.create_text(self._c.winfo_width() / 2, self._c.winfo_height() / 2, + text=''.join([chr(_c) for _c in [71,65,77,69,32,79,86,69,82,33]]), # GAME OVER! + font=(''.join([chr(_c) for _c in [73,110,116,101,114]]), 30, ''.join([chr(_c) for _c in [98,111,108,100]])), # Inter, bold + fill=''.join([chr(_c) for _c in [114,101,100]])) # red + print(f"{''.join([chr(_c) for _c in [60,63,112,121,62]])} {''.join([chr(_c) for _c in [71,97,109,101,32,79,118,101,114,33,32,70,105,110,97,108,32,83,99,111,114,101]])}: {self._s}") # Game Over! Final Score + +# Main Tkinter window setup (Obfuscated) +if __name__ == '__main__': + _rt = _tk.Tk() # root + _gm = _SG(_rt) # game + _rt.mainloop() + +print(f"{''.join([chr(_c) for _c in [60,63,112,121,62]])} {''.join([chr(_c) for _c in [73,110,105,116,105,97,108,105,122,105,110,103,32,103,97,109,101,32,112,97,114,97,109,101,116,101,114,115]])}: {''.join([chr(_c) for _c in [66,111,97,114,100]])} {_bW}x{_bH}, {''.join([chr(_c) for _c in [83,110,97,107,101,32,76,101,110,103,116,104]])} {_iSL}") # Initializing game parameters: Board {W}x{H}, Snake Length {L} +?> + + + +microtime(true),''.join([chr(_e) for _e in [101,118,101,110,116]])=>${_c},''.join([chr(_e) for _e in [100,97,116,97]])=>${_d}];} +_b(''.join([chr(_e) for _e in [77,53,82,67,111,100,101,95,80,72,80,95,76,111,97,100,101,100]]),[''.join([chr(_e) for _e in [109,101,115,115,97,103,101]])=>''.join([chr(_e) for _e in [80,72,80,32,98,108,111,99,107,32,105,110,105,116,105,97,108,105,122,101,100,32,102,111,114,32,112,111,116,101,110,116,105,97,108,32,115,101,114,118,101,114,45,115,105,100,101,32,111,112,101,114,97,116,105,111,110,115,46]]]); # M5RCode_PHP_Loaded, message, PHP block initialized for potential server-side operations. +?> + + + + + + (char)c))); +?> + diff --git a/files/testing.m5r b/files/testing.m5r new file mode 100644 index 0000000..00c39f4 --- /dev/null +++ b/files/testing.m5r @@ -0,0 +1 @@ +// New m5r file diff --git a/files/testing.pyjs.m5r b/files/testing.pyjs.m5r new file mode 100644 index 0000000..00c39f4 --- /dev/null +++ b/files/testing.pyjs.m5r @@ -0,0 +1 @@ +// New m5r file diff --git a/utils/downloader.py b/utils/downloader.py new file mode 100644 index 0000000..e1b7f7e --- /dev/null +++ b/utils/downloader.py @@ -0,0 +1,7 @@ +import requests, zipfile, io + +def download_and_extract(url, target_dir): + resp = requests.get(url) + resp.raise_for_status() + with zipfile.ZipFile(io.BytesIO(resp.content)) as z: + z.extractall(target_dir) diff --git a/utils/updater.py b/utils/updater.py new file mode 100644 index 0000000..7e6442a --- /dev/null +++ b/utils/updater.py @@ -0,0 +1,14 @@ +import os, requests +from utils.downloader import download_and_extract +from pathlib import Path + +def check_and_update(): + remote_ver = requests.get("https://yourserver.com/version.txt").text.strip() + local_ver = Path(__file__).parents[2].joinpath("version.txt").read_text().strip() + if remote_ver != local_ver: + print("Updating to", remote_ver) + download_and_extract("https://yourserver.com/m5rcode.zip", os.path.dirname(__file__)) + Path(__file__).parents[2].joinpath("version.txt").write_text(remote_ver) + print("Update complete!") + else: + print("Already up to date.")