abstract-react 0.0.0.1__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.
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: abstract_react
3
+ Version: 0.0.0.1
4
+ Home-page: https://github.com/AbstractEndeavors/abstract_react
5
+ Author: putkoff
6
+ Author-email: partners@abstractendeavors.com
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Software Development :: Libraries
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.6
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.6
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: abstract_utilities
22
+ Requires-Dist: abstract_webserver
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: description-content-type
28
+ Dynamic: home-page
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+
32
+ ## Abstract React
33
+
34
+
35
+
@@ -0,0 +1,4 @@
1
+ ## Abstract React
2
+
3
+
4
+
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,34 @@
1
+ from time import time
2
+ import setuptools
3
+ with open("README.md", "r", encoding="utf-8") as fh:
4
+ long_description = fh.read()
5
+ setuptools.setup(
6
+ name='abstract_react',
7
+ version='0.0.0.001',
8
+ author='putkoff',
9
+ author_email='partners@abstractendeavors.com',
10
+ description="",
11
+ long_description=long_description,
12
+ long_description_content_type='text/markdown',
13
+ url='https://github.com/AbstractEndeavors/abstract_react',
14
+ classifiers=[
15
+ 'Development Status :: 3 - Alpha',
16
+ 'Intended Audience :: Developers',
17
+ 'Topic :: Software Development :: Libraries',
18
+ 'License :: OSI Approved :: MIT License',
19
+ 'Programming Language :: Python :: 3',
20
+ 'Programming Language :: Python :: 3.6',
21
+ 'Programming Language :: Python :: 3.7',
22
+ 'Programming Language :: Python :: 3.8',
23
+ 'Programming Language :: Python :: 3.9',
24
+ 'Programming Language :: Python :: 3.10',
25
+ 'Programming Language :: Python :: 3.11',
26
+ 'Programming Language :: Python :: 3.12',
27
+ ],
28
+ install_requires=['abstract_utilities','abstract_webserver'],
29
+ package_dir={"": "src"},
30
+ packages=setuptools.find_packages(where="src"),
31
+ python_requires=">=3.6",
32
+ # Add this line to include wheel format in your distribution
33
+ setup_requires=['wheel'],
34
+ )
@@ -0,0 +1 @@
1
+ from abstract_react import *
@@ -0,0 +1,73 @@
1
+ from abstract_webserver import *
2
+ from .utils import *
3
+ from .import_utils import *
4
+ from .replace_utils import *
5
+ def get_general_layout(item_paths=None,excluded_exts=None,server_dir=None,local_server_dir=None,include_site_view=False):
6
+ excluded_exts = excluded_exts or []
7
+ item_paths = [str(item_path) for item_path in item_paths]
8
+ server_paths = bulk_convert_to_server_docs(item_paths)
9
+ contents = ['']
10
+ paths = ['']
11
+ for i,item_path in enumerate(item_paths):
12
+ item_path = str(item_path)
13
+ server_path = server_paths[i]
14
+ path_only=False
15
+ for key in excluded_exts:
16
+ if server_path and server_path.endswith(key):
17
+ path_only=True
18
+ paths.append(server_path)
19
+ break
20
+ if not path_only:
21
+ data = get_doc_content(item_path)
22
+ if data:
23
+ contents.append(data)
24
+ paths = '\n'.join(paths)
25
+ contents = '\n'.join(contents)
26
+ return paths+contents
27
+ def get_imports_and_content(react_file,tsconfig_path=None,excluded_exts=None,desired_exts=None,server_dir=None,local_server_dir=None,include_site_view=False):
28
+ src_dir = find_src_dir(react_file)
29
+ server_mgr = serverManager(src_dir=src_dir)
30
+ tsconfig_path = tsconfig_path or glob_search(server_mgr.main_dir,'tsconfig',ext='.json')
31
+ if tsconfig_path and isinstance(tsconfig_path,list):
32
+ tsconfig_path = tsconfig_path[0]
33
+ desired_exts = desired_exts or []
34
+ excluded_exts = excluded_exts or []
35
+ item_paths = set()
36
+ react_files = make_list(react_file)
37
+ for react_file in react_files:
38
+ if os.path.isdir(react_file):
39
+ sub_react_files =glob_search(directory,basename,ext=None)
40
+ for sub_react_file in sub_react_files:
41
+ item_paths = get_imports(sub_react_file,tsconfig_path=tsconfig_path,seen=item_paths)
42
+ else:
43
+ item_paths = get_imports(react_file,tsconfig_path=tsconfig_path,seen=item_paths)
44
+ if include_site_view:
45
+ docs = [os.path.join(server_mgr.main_dir,item) for item in os.listdir(server_mgr.main_dir)]
46
+ item_paths = item_paths+docs
47
+ general_layout = get_general_layout(item_paths=item_paths,excluded_exts=excluded_exts,include_site_view=include_site_view)
48
+ return general_layout
49
+ server_dir='/var/www/webserver/clownworld/bolshevid'
50
+ local_server_dir='/home/computron/mnt/webserver/clownworld/bolshevid'
51
+ react_file = '/home/computron/mnt/webserver/clownworld/bolshevid/src/components/BolshevidVideo/BolshevidVideo.tsx'
52
+ tsconfig_path = '/home/computron/mnt/webserver/clownworld/bolshevid/tsconfig.json'
53
+ excluded_exts=['.ts','.js','.css']
54
+ desired_exts=['.tsx']
55
+ output_contents = get_imports_and_content(react_file=react_file,
56
+ tsconfig_path=tsconfig_path,
57
+ excluded_exts=excluded_exts,
58
+ desired_exts=desired_exts,
59
+ local_server_dir=local_server_dir,
60
+ server_dir=server_dir,include_site_view=True)
61
+ # example usage:
62
+ paths = [
63
+ "/home/computron/Downloads/VideoDetails(2).ts",
64
+ "/home/computron/Downloads/VideoPlayer(2).ts",
65
+ "/home/computron/Downloads/MiniPlayer.ts",
66
+ ]
67
+ react_src_dir = "/home/computron/mnt/webserver/clownworld/bolshevid/src"
68
+ backup_dir = '/home/computron/mnt/webserver/clownworld/bolshevid/backups'
69
+ replace_react_files(src_dir=react_src_dir,
70
+ paths=paths,
71
+ backup_dir=backup_dir)
72
+
73
+
@@ -0,0 +1,109 @@
1
+ from .utils import *
2
+ # 1) Read tsconfig.json once
3
+ def load_tsconfig(tsconfig_path: str) -> Tuple[Path, Dict[str, List[str]]]:
4
+ cfg = json.loads(Path(tsconfig_path).read_text())
5
+ opts = cfg.get("compilerOptions", {})
6
+ base_url = Path(cfg.get("compilerOptions", {})
7
+ .get("baseUrl", "."))
8
+ paths = opts.get("paths", {})
9
+ return base_url, paths
10
+
11
+ # 2) Given an import string, resolve to an actual file on disk
12
+ def resolve_import(
13
+ imp: str,
14
+ current_dir: Path,
15
+ project_root: Path,
16
+ base_url: Path,
17
+ path_map: Dict[str, List[str]]
18
+ ) -> Optional[Path]:
19
+ # --- Relative imports ---
20
+ if imp.startswith("."):
21
+ candidate = (current_dir / imp)
22
+ return find_actual_file(candidate)
23
+
24
+ # --- Alias imports from tsconfig paths ---
25
+ for alias_pattern, targets in path_map.items():
26
+ # e.g. alias_pattern = "@components/*"
27
+ if "*" in alias_pattern:
28
+ prefix = alias_pattern.split("*")[0]
29
+ if not imp.startswith(prefix):
30
+ continue
31
+ suffix = imp[len(prefix):]
32
+ for t in targets:
33
+ # e.g. t = "src/components/*"
34
+ tpref = t.split("*")[0]
35
+ candidate = project_root / (tpref + suffix)
36
+ resolved = find_actual_file(candidate)
37
+ if resolved:
38
+ return resolved
39
+ else:
40
+ # exact alias, no wildcard
41
+ if imp == alias_pattern:
42
+ for t in targets:
43
+ candidate = project_root / t
44
+ resolved = find_actual_file(candidate)
45
+ if resolved:
46
+ return resolved
47
+ return None
48
+
49
+ # 3) Try extensions & index files
50
+ def find_actual_file(base: Path) -> Optional[Path]:
51
+ exts = [".ts", ".tsx", ".js", ".jsx", ".json"]
52
+ # try base + each ext
53
+ for e in exts:
54
+ p = base.with_suffix(e)
55
+ if p.is_file():
56
+ return p
57
+ # maybe base already had extension
58
+ if base.is_file():
59
+ return base
60
+ # directory → look for index.*
61
+ if base.is_dir():
62
+ for e in exts:
63
+ idx = base / f"index{e}"
64
+ if idx.is_file():
65
+ return idx
66
+ # fallback glob (will pick first match)
67
+ matches = glob.glob(str(base) + "*")
68
+ if matches:
69
+ return Path(matches[0])
70
+ return None
71
+
72
+ # 4) Walk imports recursively
73
+ def get_imports(
74
+ file_path: Path,
75
+ tsconfig_path: str,
76
+ seen: Optional[Set[Path]] = None
77
+ ) -> List[Path]:
78
+ if seen is None:
79
+ seen = set()
80
+ if isinstance(file_path,str):
81
+ file_path = Path(file_path)
82
+ if isinstance(tsconfig_path,str):
83
+ tsconfig_path = Path(tsconfig_path)
84
+ if file_path in seen or not file_path.is_file():
85
+ return []
86
+ seen = set(seen or ())
87
+ seen.add(file_path)
88
+ project_root = Path(tsconfig_path).parent
89
+ base_url, path_map = load_tsconfig(tsconfig_path)
90
+ current_dir = file_path.parent
91
+ imports: List[Path] = []
92
+ for line in file_path.read_text().splitlines():
93
+ line = line.strip()
94
+ if not line.startswith("import"):
95
+ continue
96
+ # crude split; for more robust parsing you'd use an AST parser
97
+ if " from " in line:
98
+ mod = line.split(" from ")[1].rstrip(";").strip().strip('"\'')
99
+ elif line.startswith("import("):
100
+ mod = line[line.find("(")+1:line.rfind(")")].strip().strip('"\'')
101
+ else:
102
+ continue
103
+
104
+ resolved = resolve_import(mod, current_dir, project_root, base_url, path_map)
105
+ if resolved and resolved not in seen:
106
+ imports.append(resolved)
107
+ # recurse into that file
108
+ imports.extend(get_imports(resolved, tsconfig_path, seen))
109
+ return list(set(imports))
@@ -0,0 +1,51 @@
1
+ from .utils import *
2
+ def get_new_backup_dir(backup_dir=None):
3
+ backup_dir = backup_dir or os.path.join(os.getcwd(),'backups')
4
+ os.makedirs(backup_dir,exist_ok=True)
5
+ new_dirbase = f"backup_{str(int(time.time()))}"
6
+ new_backup_dir = os.path.join(backup_dir,new_dirbase)
7
+ return new_backup_dir
8
+ def create_sub_directories(file_path,directory):
9
+ dirname = os.path.dirname(file_path)
10
+ basename = os.path.basename(file_path)
11
+ dirnames = dirname.split('/')
12
+ full_path = directory
13
+ for part in dirnames:
14
+ full_path = os.path.join(full_path,part)
15
+ os.makedirs(full_path,exist_ok=True)
16
+ return os.path.join(full_path,basename)
17
+ def get_src_relative_path(file_path,src_dir):
18
+ return file_path.split(src_dir)[-1]
19
+ def create_sub_backups_dir(backup_dir,file_path,src_dir):
20
+ sub_path = get_src_relative_path(file_path,src_dir)
21
+ file_path = create_sub_directories(sub_path,backup_dir)
22
+ return file_path
23
+ def save_to_backup_file(backup_dir,file_path,src_dir):
24
+ os.makedirs(backup_dir,exist_ok=True)
25
+ contents = read_from_file(file_path)
26
+ new_file_path = create_sub_backups_dir(backup_dir,file_path,src_dir)
27
+ write_to_file(contents =contents,file_path=new_file_path)
28
+ def save_to_back_replace(raw_file_path,file_path,backup_dir,src_dir):
29
+ contents = read_from_file(raw_file_path)
30
+ save_to_backup_file(backup_dir,file_path,src_dir)
31
+ write_to_file(contents =contents,file_path=file_path)
32
+ def replace_react_files(src_dir: str, paths,backup_dir=None):
33
+ """
34
+ For each path in `paths`, clean off any "(n)" suffix, then
35
+ find all files under src_dir whose name starts with that clean base.
36
+ """
37
+ # allow either a single string or a list
38
+ if isinstance(paths, str):
39
+ paths = paths.splitlines()
40
+ new_backup_dir = get_new_backup_dir(backup_dir=backup_dir)
41
+ for raw in paths:
42
+ p = raw.strip()
43
+ if not p:
44
+ continue
45
+ base = clean_duplicate_filename(p)
46
+ found_paths = glob_search(src_dir,base,'.tsx')
47
+
48
+ input(f'\nLooking for "{base}" → found {len(found_paths)}:')
49
+ for fp in found_paths:
50
+ save_to_back_replace(raw,fp,new_backup_dir,src_dir)
51
+ print(' ', fp)
@@ -0,0 +1,78 @@
1
+ from abstract_utilities import *
2
+ from typing import *
3
+ import json,glob
4
+ from pathlib import Path
5
+ def clean_duplicate_filename(file_path):
6
+ basename = os.path.basename(file_path)
7
+ filename,ext = os.path.splitext(basename)
8
+ if filename.endswith(')') and '(' in filename:
9
+ potential_number = filename.split('(')[-1][:-1]
10
+ new_filename = filename[:-len(str(potential_number))+2]
11
+ for char in potential_number:
12
+ if not is_number(char):
13
+ new_filename = filename
14
+ break
15
+ return new_filename
16
+ # 1) Extract “base” name (e.g. VideoDetails) and keep the extension
17
+ def get_base_name(path: str):
18
+ basename = os.path.basename(path)
19
+ name, ext = os.path.splitext(basename)
20
+ # remove trailing “(123)” if present
21
+ name = re.sub(r'\(\d+\)$', '', name)
22
+ return name, ext
23
+
24
+ # 2) Find all files under `directory` whose filename is:
25
+ # base + optional “(number)” + same extension.
26
+ def find_same_filenames(directory: str, file_path: str):
27
+ base, ext = get_base_name(file_path)
28
+ pattern = re.compile(rf'^{re.escape(base)}(?:\(\d+\))?{re.escape(ext)}$')
29
+ matches = []
30
+ for f in Path(directory).rglob(f'*{ext}'):
31
+ if pattern.match(f.name):
32
+ matches.append(str(f))
33
+ return matches
34
+
35
+ # 3) Your “replace” routine just becomes:
36
+
37
+ def clean_duplicate_filename(file_path: str) -> str:
38
+ """
39
+ Given "/…/VideoDetails(2).ts" or "/…/VideoDetails.ts",
40
+ return "VideoDetails" in either case.
41
+ """
42
+ basename = os.path.basename(file_path)
43
+ name, _ext = os.path.splitext(basename)
44
+ # if it ends with "(digits)", strip that off
45
+ if name.endswith(')') and '(' in name:
46
+ num = name[name.rfind('(')+1:-1]
47
+ if num.isdigit():
48
+ name = name[:name.rfind('(')]
49
+ return name
50
+ def glob_search(directory,basename,ext=None):
51
+ basenames = make_list(basename)
52
+ found_paths = []
53
+ exts = make_list(ext or [])
54
+ for basename in basenames:
55
+ split_filename,split_ext =os.path.splitext(basename)
56
+ filename = split_filename or '*'
57
+ exts = make_list(exts or split_ext or '*')
58
+ for ext in exts:
59
+ pattern = os.path.join(directory, '**', f'{filename}{ext}')
60
+ found_paths+=glob.glob(pattern, recursive=True)
61
+ return found_paths
62
+ def convert_to_Server_doc(path,server_dir=None,local_server_dir=None):
63
+ if isinstance(path,str):
64
+ if server_dir and local_server_dir:
65
+ path = path.replace(local_server_dir,server_dir)
66
+ return path
67
+ def bulk_convert_to_server_docs(paths,server_dir=None,local_server_dir=None):
68
+ if isinstance(paths,str):
69
+ paths = paths.split('\n')
70
+ for i,path in enumerate(paths):
71
+ paths[i]= convert_to_Server_doc(path,server_dir=server_dir,local_server_dir=local_server_dir)
72
+ return paths
73
+ def get_doc_content(file_path,server_dir=None,local_server_dir=None):
74
+ server_doc = convert_to_Server_doc(file_path,server_dir=server_dir,local_server_dir=local_server_dir)
75
+ if os.path.isfile(file_path):
76
+ data = read_from_file(file_path)
77
+ content = f"//{server_doc}\n{data}\n\n"
78
+ return content
@@ -0,0 +1,35 @@
1
+ Metadata-Version: 2.4
2
+ Name: abstract_react
3
+ Version: 0.0.0.1
4
+ Home-page: https://github.com/AbstractEndeavors/abstract_react
5
+ Author: putkoff
6
+ Author-email: partners@abstractendeavors.com
7
+ Classifier: Development Status :: 3 - Alpha
8
+ Classifier: Intended Audience :: Developers
9
+ Classifier: Topic :: Software Development :: Libraries
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.6
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Requires-Python: >=3.6
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: abstract_utilities
22
+ Requires-Dist: abstract_webserver
23
+ Dynamic: author
24
+ Dynamic: author-email
25
+ Dynamic: classifier
26
+ Dynamic: description
27
+ Dynamic: description-content-type
28
+ Dynamic: home-page
29
+ Dynamic: requires-dist
30
+ Dynamic: requires-python
31
+
32
+ ## Abstract React
33
+
34
+
35
+
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ src/abstract_react/__init__.py
5
+ src/abstract_react/abstract_react.py
6
+ src/abstract_react/import_utils.py
7
+ src/abstract_react/replace_utils.py
8
+ src/abstract_react/utils.py
9
+ src/abstract_react.egg-info/PKG-INFO
10
+ src/abstract_react.egg-info/SOURCES.txt
11
+ src/abstract_react.egg-info/dependency_links.txt
12
+ src/abstract_react.egg-info/requires.txt
13
+ src/abstract_react.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ abstract_utilities
2
+ abstract_webserver
@@ -0,0 +1 @@
1
+ abstract_react