mdcci 2.2__tar.gz → 2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mdcci-2.2 → mdcci-2.4}/PKG-INFO +1 -1
- {mdcci-2.2 → mdcci-2.4}/pyproject.toml +1 -1
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/lpro.py +55 -2
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/lpro_s.py +61 -2
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/scmpy.py +209 -30
- {mdcci-2.2 → mdcci-2.4}/src/mdcci.egg-info/PKG-INFO +1 -1
- {mdcci-2.2 → mdcci-2.4}/setup.cfg +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/__init__.py +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/__init__.py +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/bible.txt +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/keys.py +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/main.py +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci/scripts/session.py +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci.egg-info/SOURCES.txt +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci.egg-info/dependency_links.txt +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci.egg-info/entry_points.txt +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci.egg-info/requires.txt +0 -0
- {mdcci-2.2 → mdcci-2.4}/src/mdcci.egg-info/top_level.txt +0 -0
{mdcci-2.2 → mdcci-2.4}/PKG-INFO
RENAMED
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "mdcci"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.4"
|
|
8
8
|
description = "Extended LPro - MProcs simplified - A Life program by tderk, originally LPro.py and Destiny [2024]"
|
|
9
9
|
requires-python = ">=3.8"
|
|
10
10
|
readme = "README.md"
|
|
@@ -80,6 +80,49 @@ def change_username(provided_name=None):
|
|
|
80
80
|
|
|
81
81
|
omit_result = False
|
|
82
82
|
current_ddd = [""]
|
|
83
|
+
jot_log = None
|
|
84
|
+
jot_active = False
|
|
85
|
+
jot_file_path = ""
|
|
86
|
+
|
|
87
|
+
def jot(path=None):
|
|
88
|
+
import os
|
|
89
|
+
global jot_log, jot_active, jot_file_path
|
|
90
|
+
if not jot_active:
|
|
91
|
+
jot_file_path = path if path else "JOT.txt"
|
|
92
|
+
folder = os.path.dirname(jot_file_path)
|
|
93
|
+
if folder and not os.path.isdir(folder):
|
|
94
|
+
print(f"{ORANGE}[JOT] Folder not found: {folder}{RESET}")
|
|
95
|
+
return
|
|
96
|
+
jot_log = open(jot_file_path, "a", buffering=1)
|
|
97
|
+
jot_active = True
|
|
98
|
+
print(f"{GREEN}[JOT] Recording started -> {jot_file_path}{RESET}")
|
|
99
|
+
else:
|
|
100
|
+
jot_log.close()
|
|
101
|
+
jot_active = False
|
|
102
|
+
print(f"{ORANGE}[JOT] Recording stopped -> {jot_file_path}{RESET}")
|
|
103
|
+
jot_log = None
|
|
104
|
+
jot_file_path = ""
|
|
105
|
+
|
|
106
|
+
def jot_write(msg):
|
|
107
|
+
global jot_log, jot_active
|
|
108
|
+
if jot_active and jot_log:
|
|
109
|
+
jot_log.write(msg + "\n")
|
|
110
|
+
jot_log.flush()
|
|
111
|
+
|
|
112
|
+
print_orig = print
|
|
113
|
+
def jot_print(*args, **kwargs):
|
|
114
|
+
global jot_log, jot_active
|
|
115
|
+
if 'file' in kwargs and kwargs['file'] == z:
|
|
116
|
+
print_orig(*args, **kwargs)
|
|
117
|
+
return
|
|
118
|
+
text = " ".join(str(a) for a in args)
|
|
119
|
+
clean_text = re.sub(r'\x1b\[[0-9;]*m', '', text)
|
|
120
|
+
if jot_active and jot_log:
|
|
121
|
+
jot_log.write(clean_text + "\n")
|
|
122
|
+
jot_log.flush()
|
|
123
|
+
print_orig(*args, **kwargs)
|
|
124
|
+
|
|
125
|
+
print = jot_print
|
|
83
126
|
|
|
84
127
|
def main():
|
|
85
128
|
|
|
@@ -695,7 +738,7 @@ def main():
|
|
|
695
738
|
print(alert, value, random_letters, rrchar_str, kkchar_str, cchat, hchar_str, ct, file=z)
|
|
696
739
|
|
|
697
740
|
def version():
|
|
698
|
-
title = usr + "" + " " + "" + f"snowtiger >>> {ORANGE}I.S. (Incubator Studios) Outbeat Produce:{RESET} {GREEN}MProcs-9.
|
|
741
|
+
title = usr + "" + " " + "" + f"snowtiger >>> {ORANGE}I.S. (Incubator Studios) Outbeat Produce:{RESET} {GREEN}MProcs-9.2{RESET} {ORANGE}by tderk{RESET} - {ORANGE}Established Lpro.py (Life-pro) and Destiny [2024]{RESET}"
|
|
699
742
|
title2 = f"| {BLUE}Indicative: @USVirtualUni && © Medicine, Computable (N_2025) && FNTCCI{RESET} |"
|
|
700
743
|
title3 = f"{ORANGE}All Rights Reserved{RESET} - {BLUE}Medicci.ca{RESET}"
|
|
701
744
|
title4 = f"- {RED}(P0cket Un1-Ver$e){RESET}"
|
|
@@ -917,7 +960,7 @@ def main():
|
|
|
917
960
|
|
|
918
961
|
def commands():
|
|
919
962
|
print()
|
|
920
|
-
print(" version | switch/lpro-s [lx] | [blank input] for nano / 1-nano [n1/3 spaces] | morn [m] | nano characters [nanochars/nnc] | katakana [kata/b] | jamo [hangu/n] | chi [++] | ans [@@] | ruh [%%] | profile | note / journal / save | pwd / ls / cd / clear [cl] / mkdir / rm | type-text | Term-Search [tsearch] | search | scmpy / scm [social media]")
|
|
963
|
+
print(" version | switch/lpro-s [lx] | [blank input] for nano / 1-nano [n1/3 spaces] | morn [m] | nano characters [nanochars/nnc] | katakana [kata/b] | jamo [hangu/n] | chi [++] | ans [@@] | ruh [%%] | profile | note / journal / save | pwd / ls / cd / clear [cl] / mkdir / rm | type-text | Term-Search [tsearch] | search | scmpy / scm [social media] | jot [JOT] (record terminal to file)")
|
|
921
964
|
print()
|
|
922
965
|
print(" FNTCCI: tinien [single space/**], ntag, fcci-monitor [fstart/fcci] | synthesis: cbmp, cmbpc, xcbmp, xcbmpc, hbmp, hbmpc, xhbmp, xhbmpc, jbmp, jbmpc, xjbmp, xjbmpc, fbmp, xfbmp")
|
|
923
966
|
print()
|
|
@@ -8662,6 +8705,7 @@ def main():
|
|
|
8662
8705
|
print()
|
|
8663
8706
|
print(file=z)
|
|
8664
8707
|
choice = input(usr)
|
|
8708
|
+
jot_write(f"{usr}{choice}")
|
|
8665
8709
|
ct = datetime.datetime.now()
|
|
8666
8710
|
print(usr, choice, ct, file=z)
|
|
8667
8711
|
|
|
@@ -8676,6 +8720,15 @@ def main():
|
|
|
8676
8720
|
scmpy.scmpy_main()
|
|
8677
8721
|
return "continue"
|
|
8678
8722
|
|
|
8723
|
+
if choice == "jot" or choice == "JOT":
|
|
8724
|
+
if jot_active:
|
|
8725
|
+
jot()
|
|
8726
|
+
else:
|
|
8727
|
+
path = input("Path (Enter for ./JOT.txt): ").strip()
|
|
8728
|
+
jot(path if path else "JOT.txt")
|
|
8729
|
+
jot_write(f"=== JOT Session: {datetime.datetime.now()} ===")
|
|
8730
|
+
return "continue"
|
|
8731
|
+
|
|
8679
8732
|
if choice == "nano chars" or choice == "nano characters" or choice == "nano-characters" or choice == "nanochars" or choice == "nano-chars" or choice == "nnc" or choice == 'NNC':
|
|
8680
8733
|
select_charset()
|
|
8681
8734
|
|
|
@@ -79,6 +79,55 @@ def change_username(provided_name=None):
|
|
|
79
79
|
|
|
80
80
|
omit_result = False
|
|
81
81
|
current_ddd = [""]
|
|
82
|
+
jot_log = None
|
|
83
|
+
jot_active = False
|
|
84
|
+
jot_file_path = ""
|
|
85
|
+
|
|
86
|
+
def jot(path=None):
|
|
87
|
+
import os
|
|
88
|
+
global jot_log, jot_active, jot_file_path
|
|
89
|
+
if not jot_active:
|
|
90
|
+
jot_file_path = path if path else "JOT.txt"
|
|
91
|
+
folder = os.path.dirname(jot_file_path)
|
|
92
|
+
if folder and not os.path.isdir(folder):
|
|
93
|
+
print(f"{ORANGE}[JOT] Folder not found: {folder}{RESET}")
|
|
94
|
+
return
|
|
95
|
+
jot_log = open(jot_file_path, "a", buffering=1)
|
|
96
|
+
jot_active = True
|
|
97
|
+
print(f"{GREEN}[JOT] Recording started -> {jot_file_path}{RESET}")
|
|
98
|
+
else:
|
|
99
|
+
jot_log.close()
|
|
100
|
+
jot_active = False
|
|
101
|
+
print(f"{ORANGE}[JOT] Recording stopped -> {jot_file_path}{RESET}")
|
|
102
|
+
jot_log = None
|
|
103
|
+
jot_file_path = ""
|
|
104
|
+
|
|
105
|
+
def jot_write(msg):
|
|
106
|
+
global jot_log, jot_active
|
|
107
|
+
if jot_log and jot_active:
|
|
108
|
+
jot_log.write(msg + "\n")
|
|
109
|
+
jot_log.flush()
|
|
110
|
+
|
|
111
|
+
print_orig = print
|
|
112
|
+
|
|
113
|
+
class SkipLog:
|
|
114
|
+
pass
|
|
115
|
+
|
|
116
|
+
skip_log = SkipLog()
|
|
117
|
+
|
|
118
|
+
def jot_print(*args, **kwargs):
|
|
119
|
+
global jot_log, jot_active
|
|
120
|
+
f = kwargs.get('file')
|
|
121
|
+
if f is skip_log or (hasattr(f, 'name') and 'MProcs' in f.name):
|
|
122
|
+
return print_orig(*args, file=None, **kwargs)
|
|
123
|
+
text = " ".join(str(a) for a in args)
|
|
124
|
+
clean_text = re.sub(r'\x1b\[[0-9;]*m', '', text)
|
|
125
|
+
if jot_active and jot_log:
|
|
126
|
+
jot_log.write(clean_text + "\n")
|
|
127
|
+
jot_log.flush()
|
|
128
|
+
print_orig(*args, **kwargs)
|
|
129
|
+
|
|
130
|
+
print = jot_print
|
|
82
131
|
|
|
83
132
|
def main():
|
|
84
133
|
|
|
@@ -692,7 +741,7 @@ def main():
|
|
|
692
741
|
print(alert, value, random_letters, kkchar_str, cchat, hchar_str, rrchar_str, ct)
|
|
693
742
|
|
|
694
743
|
def version():
|
|
695
|
-
title = usr + "" + " " + "" + f"snowtiger >>> {ORANGE}I.S. (Incubator Studios) Outbeat Produce:{RESET} {GREEN}MProcs-9.
|
|
744
|
+
title = usr + "" + " " + "" + f"snowtiger >>> {ORANGE}I.S. (Incubator Studios) Outbeat Produce:{RESET} {GREEN}MProcs-9.2-s{RESET} {ORANGE}by tderk{RESET} - {ORANGE}Established Lpro.py (Life-pro) and Destiny [2024]{RESET}"
|
|
696
745
|
title2 = f"| {BLUE}Indicative: @USVirtualUni && © Medicine, Computable (N_2025) && FNTCCI{RESET} |"
|
|
697
746
|
title3 = f"{ORANGE}All Rights Reserved{RESET} - {BLUE}Medicci.ca{RESET}"
|
|
698
747
|
title4 = f"- {RED}(P0cket Un1-Ver$e){RESET}"
|
|
@@ -900,7 +949,7 @@ def main():
|
|
|
900
949
|
|
|
901
950
|
def commands():
|
|
902
951
|
print()
|
|
903
|
-
print(" version | switch/lpro [lx] | [blank input] for nano / 1-nano [n1/3 spaces] | morn [m] | nano characters [nanochars/nnc] | katakana [kata/b] | jamo [hangu/n] | chi [++] | ans [@@] | ruh [%%] | profile | pwd / ls / cd / clear [cl] / mkdir / rm | type-text | Term-Search [tsearch] | fsearch | scmpy / scm [social media]")
|
|
952
|
+
print(" version | switch/lpro [lx] | [blank input] for nano / 1-nano [n1/3 spaces] | morn [m] | nano characters [nanochars/nnc] | katakana [kata/b] | jamo [hangu/n] | chi [++] | ans [@@] | ruh [%%] | profile | pwd / ls / cd / clear [cl] / mkdir / rm | type-text | Term-Search [tsearch] | fsearch | scmpy / scm [social media] | jot [JOT] (record terminal to file)")
|
|
904
953
|
print()
|
|
905
954
|
print(" FNTCCI: tinien [single space/**], ntag, fcci-monitor [fstart/fcci] | synthesis: xcbmp, xcbmpc, xhbmp, xhbmpc, xjbmp, xjbmpc, xfbmp")
|
|
906
955
|
print()
|
|
@@ -6618,6 +6667,7 @@ def main():
|
|
|
6618
6667
|
global usr
|
|
6619
6668
|
print()
|
|
6620
6669
|
choice = input(usr)
|
|
6670
|
+
jot_write(f"{usr}{choice}")
|
|
6621
6671
|
ct = datetime.datetime.now()
|
|
6622
6672
|
|
|
6623
6673
|
if choice == "version" or choice == "about" or choice == "intro":
|
|
@@ -6637,6 +6687,15 @@ def main():
|
|
|
6637
6687
|
scmpy.check_dependencies()
|
|
6638
6688
|
return "continue"
|
|
6639
6689
|
|
|
6690
|
+
if choice == "jot" or choice == "JOT":
|
|
6691
|
+
if jot_active:
|
|
6692
|
+
jot()
|
|
6693
|
+
else:
|
|
6694
|
+
path = input("Path (Enter for ./JOT.txt): ").strip()
|
|
6695
|
+
jot(path if path else "JOT.txt")
|
|
6696
|
+
jot_write(f"=== JOT Session: {datetime.datetime.now()} ===")
|
|
6697
|
+
return "continue"
|
|
6698
|
+
|
|
6640
6699
|
if choice == "nano chars" or choice == "nano characters" or choice == "nano-characters" or choice == "nanochars" or choice == "nano-chars" or choice == "nnc" or choice == "NNC":
|
|
6641
6700
|
select_charset()
|
|
6642
6701
|
|
|
@@ -971,11 +971,20 @@ def display_videos():
|
|
|
971
971
|
print(f"=== YOUTUBE RESULTS ({len(CACHED_VIDEOS)} videos) ===\n")
|
|
972
972
|
for i, v in enumerate(CACHED_VIDEOS):
|
|
973
973
|
title = v.get('title', 'No title')
|
|
974
|
-
video_id = v.get('vid', '')
|
|
974
|
+
video_id = v.get('vid', v.get('videoId', ''))
|
|
975
975
|
url_link = v.get('url', f'https://youtube.com/watch?v={video_id}')
|
|
976
976
|
print(f"{i+1}. {title}")
|
|
977
977
|
print(f" {url_link}")
|
|
978
978
|
print()
|
|
979
|
+
if CACHED_VIDEOS:
|
|
980
|
+
num = input(f"Open video # (1-{len(CACHED_VIDEOS)}) or Enter to skip: ").strip()
|
|
981
|
+
if num.isdigit():
|
|
982
|
+
idx = int(num) - 1
|
|
983
|
+
if 0 <= idx < len(CACHED_VIDEOS):
|
|
984
|
+
video_id = CACHED_VIDEOS[idx].get('vid', CACHED_VIDEOS[idx].get('videoId', ''))
|
|
985
|
+
url = CACHED_VIDEOS[idx].get('url', f'https://youtube.com/watch?v={video_id}')
|
|
986
|
+
print(f"Opening: {url}")
|
|
987
|
+
open_in_browser(url)
|
|
979
988
|
|
|
980
989
|
def download_file(url, filepath, show_progress=True):
|
|
981
990
|
if show_progress:
|
|
@@ -1009,7 +1018,13 @@ def download_by_number(items, number, folder, is_image=False, prefix=""):
|
|
|
1009
1018
|
|
|
1010
1019
|
os.makedirs(folder, exist_ok=True)
|
|
1011
1020
|
base = f"{prefix}_{number}" if prefix else f"download_{number}"
|
|
1012
|
-
|
|
1021
|
+
from urllib.parse import urlparse
|
|
1022
|
+
parsed = urlparse(url)
|
|
1023
|
+
path = parsed.path
|
|
1024
|
+
if '.' in path and len(path.split('.')[-1]) >= 3:
|
|
1025
|
+
ext = path.split('.')[-1][:4].lower()
|
|
1026
|
+
else:
|
|
1027
|
+
ext = 'png'
|
|
1013
1028
|
filepath = unique_filename(folder, base, ext)
|
|
1014
1029
|
print(f"Downloading to {filepath}...")
|
|
1015
1030
|
download_file(url, filepath)
|
|
@@ -1024,9 +1039,13 @@ def download_all_images(items, folder, prefix="img"):
|
|
|
1024
1039
|
url = item.get('image', '')
|
|
1025
1040
|
if not url:
|
|
1026
1041
|
continue
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1042
|
+
from urllib.parse import urlparse
|
|
1043
|
+
parsed = urlparse(url)
|
|
1044
|
+
path = parsed.path
|
|
1045
|
+
if '.' in path and len(path.split('.')[-1]) >= 3:
|
|
1046
|
+
ext = path.split('.')[-1][:4].lower()
|
|
1047
|
+
else:
|
|
1048
|
+
ext = 'png'
|
|
1030
1049
|
base = f"{prefix}_{i+1}"
|
|
1031
1050
|
filepath = unique_filename(folder, base, ext)
|
|
1032
1051
|
filename = os.path.basename(filepath)
|
|
@@ -1354,13 +1373,52 @@ def ai_image(prompt):
|
|
|
1354
1373
|
for i, url in enumerate(urls):
|
|
1355
1374
|
print(f"{i+1}. {url}")
|
|
1356
1375
|
|
|
1357
|
-
def list_images():
|
|
1376
|
+
def list_images(path='.', add_to_cache=True, allow_upload=True):
|
|
1358
1377
|
import os
|
|
1359
|
-
|
|
1378
|
+
folder = path if path != '.' else os.getcwd()
|
|
1379
|
+
if not os.path.isdir(folder):
|
|
1380
|
+
print(f"Folder not found: {folder}")
|
|
1381
|
+
return
|
|
1382
|
+
images = [f for f in os.listdir(folder) if f.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp'))]
|
|
1360
1383
|
if images:
|
|
1361
|
-
print("Images:")
|
|
1384
|
+
print(f"Images in {folder}:")
|
|
1362
1385
|
for i, f in enumerate(images):
|
|
1363
1386
|
print(f" {i+1}. {f}")
|
|
1387
|
+
view_opt = input(f"\nView image # (1-{len(images)}), 'c' to cache, 'p' to post, or Enter to skip: ").strip()
|
|
1388
|
+
if view_opt.isdigit():
|
|
1389
|
+
i = int(view_opt) - 1
|
|
1390
|
+
if 0 <= i < len(images):
|
|
1391
|
+
filepath = os.path.abspath(os.path.join(folder, images[i]))
|
|
1392
|
+
view_with_w3m(f"file://{filepath}", images[i])
|
|
1393
|
+
CACHED_IMAGES.append({
|
|
1394
|
+
'title': images[i],
|
|
1395
|
+
'image': f"file://{filepath}",
|
|
1396
|
+
'thumbnail': f"file://{filepath}"
|
|
1397
|
+
})
|
|
1398
|
+
elif view_opt.lower() == 'c':
|
|
1399
|
+
idx = input(f"Add to cache # (1-{len(images)}): ").strip()
|
|
1400
|
+
if idx.isdigit():
|
|
1401
|
+
i = int(idx) - 1
|
|
1402
|
+
if 0 <= i < len(images):
|
|
1403
|
+
filepath = os.path.join(folder, images[i])
|
|
1404
|
+
CACHED_IMAGES.append({
|
|
1405
|
+
'title': images[i],
|
|
1406
|
+
'image': f"file://{os.path.abspath(filepath)}",
|
|
1407
|
+
'thumbnail': f"file://{os.path.abspath(filepath)}"
|
|
1408
|
+
})
|
|
1409
|
+
print(f"Added to cache: {images[i]}")
|
|
1410
|
+
elif view_opt.lower() == 'p' and allow_upload:
|
|
1411
|
+
img_idx = input(f"Image # (1-{len(images)}): ").strip()
|
|
1412
|
+
if img_idx.isdigit():
|
|
1413
|
+
i = int(img_idx) - 1
|
|
1414
|
+
if 0 <= i < len(images):
|
|
1415
|
+
msg = input("Message: ").strip()
|
|
1416
|
+
where = input("Post to: 1=FB, 2=Tumblr, 3=Both: ").strip() or "3"
|
|
1417
|
+
fp = os.path.abspath(os.path.join(folder, images[i]))
|
|
1418
|
+
if where in ('1', '3'):
|
|
1419
|
+
fb_post_image_file(fp, msg)
|
|
1420
|
+
if where in ('2', '3'):
|
|
1421
|
+
tumblr_post_photo('', msg, tags_list=None, local_file=fp)
|
|
1364
1422
|
else:
|
|
1365
1423
|
print("No images found.")
|
|
1366
1424
|
|
|
@@ -1371,16 +1429,112 @@ def view_image(filename):
|
|
|
1371
1429
|
else:
|
|
1372
1430
|
print(f"File not found: {filename}")
|
|
1373
1431
|
|
|
1374
|
-
def list_videos():
|
|
1432
|
+
def list_videos(path='.'):
|
|
1375
1433
|
import os
|
|
1376
|
-
|
|
1434
|
+
folder = path if path != '.' else os.getcwd()
|
|
1435
|
+
if not os.path.isdir(folder):
|
|
1436
|
+
print(f"Folder not found: {folder}")
|
|
1437
|
+
return
|
|
1438
|
+
videos = [f for f in os.listdir(folder) if f.lower().endswith(('.mp4', '.mkv', '.avi', '.webm', '.mov'))]
|
|
1377
1439
|
if videos:
|
|
1378
|
-
print("Videos:")
|
|
1440
|
+
print(f"Videos in {folder}:")
|
|
1379
1441
|
for i, f in enumerate(videos):
|
|
1380
1442
|
print(f" {i+1}. {f}")
|
|
1443
|
+
idx = input(f"\nOpen video # (1-{len(videos)}) or Enter to skip: ").strip()
|
|
1444
|
+
if idx.isdigit():
|
|
1445
|
+
i = int(idx) - 1
|
|
1446
|
+
if 0 <= i < len(videos):
|
|
1447
|
+
filepath = os.path.abspath(os.path.join(folder, videos[i]))
|
|
1448
|
+
print(f"Opening {videos[i]}...")
|
|
1449
|
+
open_in_browser(f"file://{filepath}")
|
|
1450
|
+
CACHED_VIDEOS.append({
|
|
1451
|
+
'title': videos[i],
|
|
1452
|
+
'url': f"file://{filepath}"
|
|
1453
|
+
})
|
|
1381
1454
|
else:
|
|
1382
1455
|
print("No videos found.")
|
|
1383
1456
|
|
|
1457
|
+
def list_text_files(path='.', add_to_cache=True, allow_post=True):
|
|
1458
|
+
import os
|
|
1459
|
+
folder = path if path != '.' else os.getcwd()
|
|
1460
|
+
if not os.path.isdir(folder):
|
|
1461
|
+
print(f"Folder not found: {folder}")
|
|
1462
|
+
return
|
|
1463
|
+
texts = [f for f in os.listdir(folder) if f.lower().endswith(('.txt', '.md', '.html', '.json', '.xml'))]
|
|
1464
|
+
if texts:
|
|
1465
|
+
print(f"Text files in {folder}:")
|
|
1466
|
+
for i, f in enumerate(texts):
|
|
1467
|
+
print(f" {i+1}. {f}")
|
|
1468
|
+
if add_to_cache:
|
|
1469
|
+
idx = input(f"\nAdd to text cache # (1-{len(texts)}) or Enter to skip: ").strip()
|
|
1470
|
+
if idx.isdigit():
|
|
1471
|
+
i = int(idx) - 1
|
|
1472
|
+
if 0 <= i < len(texts):
|
|
1473
|
+
filepath = os.path.join(folder, texts[i])
|
|
1474
|
+
try:
|
|
1475
|
+
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
1476
|
+
content = f.read()
|
|
1477
|
+
ai_texts.append({
|
|
1478
|
+
'text': content,
|
|
1479
|
+
'source': 'file',
|
|
1480
|
+
'filename': texts[i],
|
|
1481
|
+
'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
|
|
1482
|
+
})
|
|
1483
|
+
print(f"Added to text cache: {texts[i]}")
|
|
1484
|
+
except Exception as e:
|
|
1485
|
+
print(f"Error reading file: {e}")
|
|
1486
|
+
if allow_post:
|
|
1487
|
+
opt = input("Post this text? (y/n): ").strip().lower()
|
|
1488
|
+
if opt == 'y':
|
|
1489
|
+
num = input("Which # to post: ").strip()
|
|
1490
|
+
if num.isdigit():
|
|
1491
|
+
i = int(num) - 1
|
|
1492
|
+
if 0 <= i < len(texts):
|
|
1493
|
+
filepath = os.path.join(folder, texts[i])
|
|
1494
|
+
caption = input("Caption: ").strip()
|
|
1495
|
+
where = input("Post to: 1=FB, 2=Tumblr, 3=Both: ").strip() or "3"
|
|
1496
|
+
content = convert_text_for_upload(filepath)
|
|
1497
|
+
if where in ('1', '3'):
|
|
1498
|
+
fb_post_text(content if content else caption)
|
|
1499
|
+
if where in ('2', '3'):
|
|
1500
|
+
tumblr_post_text(texts[i], content or caption)
|
|
1501
|
+
else:
|
|
1502
|
+
print("No text files found.")
|
|
1503
|
+
|
|
1504
|
+
def convert_text_for_upload(filepath):
|
|
1505
|
+
import os, re
|
|
1506
|
+
ext = filepath.rsplit('.', 1)[-1].lower()
|
|
1507
|
+
ansi_escape = re.compile(r'\x1b\[[0-9;]*[A-Za-z]')
|
|
1508
|
+
def strip_ansi(text):
|
|
1509
|
+
return ansi_escape.sub('', text)
|
|
1510
|
+
if ext in ('html', 'htm'):
|
|
1511
|
+
try:
|
|
1512
|
+
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
1513
|
+
content = f.read()
|
|
1514
|
+
from bs4 import BeautifulSoup
|
|
1515
|
+
soup = BeautifulSoup(content, 'html.parser')
|
|
1516
|
+
return strip_ansi(soup.get_text(separator='\n', strip=True))
|
|
1517
|
+
except:
|
|
1518
|
+
return None
|
|
1519
|
+
elif ext == 'json':
|
|
1520
|
+
try:
|
|
1521
|
+
import json
|
|
1522
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
1523
|
+
data = json.load(f)
|
|
1524
|
+
return json.dumps(data, indent=2)
|
|
1525
|
+
except:
|
|
1526
|
+
return None
|
|
1527
|
+
elif ext == 'xml':
|
|
1528
|
+
try:
|
|
1529
|
+
import xml.etree.ElementTree as ET
|
|
1530
|
+
tree = ET.parse(filepath)
|
|
1531
|
+
return strip_ansi(ET.tostring(tree.getroot(), encoding='unicode'))
|
|
1532
|
+
except:
|
|
1533
|
+
return None
|
|
1534
|
+
else:
|
|
1535
|
+
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
1536
|
+
return strip_ansi(f.read())
|
|
1537
|
+
|
|
1384
1538
|
def open_url(url):
|
|
1385
1539
|
open_in_browser(url)
|
|
1386
1540
|
|
|
@@ -1528,7 +1682,12 @@ VIEW:
|
|
|
1528
1682
|
list - List cached images
|
|
1529
1683
|
open - Open link in browser
|
|
1530
1684
|
view - Open image in browser
|
|
1531
|
-
|
|
1685
|
+
lv - List YouTube results (with option to open)
|
|
1686
|
+
|
|
1687
|
+
LOCAL FILES:
|
|
1688
|
+
li - List images from folder (add to cache/post)
|
|
1689
|
+
ltxt - List text files (add to cache/post)
|
|
1690
|
+
lvv - List local videos
|
|
1532
1691
|
|
|
1533
1692
|
POSTING (Facebook):
|
|
1534
1693
|
fbpost - Post text
|
|
@@ -1570,6 +1729,29 @@ OTHER:
|
|
|
1570
1729
|
""")
|
|
1571
1730
|
|
|
1572
1731
|
def scmpy_main():
|
|
1732
|
+
required_deps = ['requests', 'requests_oauthlib', 'beautifulsoup4', 'lxml', 'PIL']
|
|
1733
|
+
missing = []
|
|
1734
|
+
for dep in required_deps:
|
|
1735
|
+
try:
|
|
1736
|
+
__import__(dep)
|
|
1737
|
+
except ImportError:
|
|
1738
|
+
missing.append(dep)
|
|
1739
|
+
if missing:
|
|
1740
|
+
print("\n=== Missing Dependencies ===")
|
|
1741
|
+
for dep in missing:
|
|
1742
|
+
print(f" - {dep}")
|
|
1743
|
+
print("\nInstall now? [Y/n]: ", end='', flush=True)
|
|
1744
|
+
try:
|
|
1745
|
+
resp = input().strip().lower()
|
|
1746
|
+
except:
|
|
1747
|
+
resp = 'y'
|
|
1748
|
+
if resp in ['', 'y', 'yes']:
|
|
1749
|
+
import subprocess
|
|
1750
|
+
for dep in missing:
|
|
1751
|
+
print(f"Installing {dep}...")
|
|
1752
|
+
subprocess.run([sys.executable, '-m', 'pip', 'install', dep], capture_output=True)
|
|
1753
|
+
else:
|
|
1754
|
+
print("Some features may not work.")
|
|
1573
1755
|
load_history()
|
|
1574
1756
|
show_help = True
|
|
1575
1757
|
|
|
@@ -1696,26 +1878,23 @@ Type 'h' for help, 'x' to exit
|
|
|
1696
1878
|
else:
|
|
1697
1879
|
print("No images to view!")
|
|
1698
1880
|
|
|
1699
|
-
elif choice in ['
|
|
1881
|
+
elif choice in ['li', 'limg', 'localimg']:
|
|
1882
|
+
path = input("Folder (default .): ").strip() or "."
|
|
1883
|
+
list_images(path, add_to_cache=True, allow_upload=True)
|
|
1884
|
+
|
|
1885
|
+
elif choice in ['ltxt', 'txtfiles', 'localtxt']:
|
|
1886
|
+
path = input("Folder (default .): ").strip() or "."
|
|
1887
|
+
list_text_files(path, add_to_cache=True, allow_post=True)
|
|
1888
|
+
|
|
1889
|
+
elif choice in ['lvv', 'lvid', 'localvid']:
|
|
1890
|
+
path = input("Folder (default .): ").strip() or "."
|
|
1891
|
+
list_videos(path)
|
|
1892
|
+
|
|
1893
|
+
elif choice in ['videos', 'vid', 'youtubes', 'lv']:
|
|
1700
1894
|
if CACHED_VIDEOS:
|
|
1701
|
-
|
|
1702
|
-
print(" 1. List videos")
|
|
1703
|
-
print(" 2. Open video in browser")
|
|
1704
|
-
opt = input("Choose (1-2): ").strip()
|
|
1705
|
-
if opt == '1':
|
|
1706
|
-
display_videos()
|
|
1707
|
-
elif opt == '2':
|
|
1708
|
-
num = input(f"Video number (1-{len(CACHED_VIDEOS)}): ").strip()
|
|
1709
|
-
try:
|
|
1710
|
-
idx = int(num) - 1
|
|
1711
|
-
if 0 <= idx < len(CACHED_VIDEOS):
|
|
1712
|
-
url = CACHED_VIDEOS[idx].get('url', '')
|
|
1713
|
-
print(f"Opening: {url}")
|
|
1714
|
-
open_in_browser(url)
|
|
1715
|
-
except:
|
|
1716
|
-
print("Invalid")
|
|
1895
|
+
display_videos()
|
|
1717
1896
|
else:
|
|
1718
|
-
print("No videos searched yet!")
|
|
1897
|
+
print("No videos searched yet! Run 'yt' first.")
|
|
1719
1898
|
|
|
1720
1899
|
elif choice in ['open', 'o', 'url', 'link']:
|
|
1721
1900
|
if CACHED_LINKS:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|