prthm11 commited on
Commit
cca3e97
Β·
verified Β·
1 Parent(s): 8e85a71

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +242 -226
app.py CHANGED
@@ -84,22 +84,27 @@ llm = ChatGroq(
84
 
85
  app = Flask(__name__)
86
 
87
- backdrop_images_path = r"app\blocks\Backdrops"
88
- sprite_images_path = r"app\blocks\sprites"
89
- code_blocks_image_path = r"app\blocks\code_blocks"
90
-
91
  count = 0
92
 
93
- BASE_DIR = Path("/app")
94
- BLOCKS_DIR = BASE_DIR / "blocks"
95
- STATIC_DIR = BASE_DIR / "static"
96
- GEN_PROJECT_DIR = BASE_DIR / "generated_projects"
 
 
 
 
97
  BACKDROP_DIR = BLOCKS_DIR / "Backdrops"
98
  SPRITE_DIR = BLOCKS_DIR / "sprites"
99
  CODE_BLOCKS_DIR = BLOCKS_DIR / "code_blocks"
100
  # === new: outputs rooted under BASE_DIR ===
101
  OUTPUT_DIR = BASE_DIR / "outputs"
102
 
 
 
 
 
 
103
  # Global variables to hold the model and index, loaded only once.
104
  MODEL = None
105
  FAISS_INDEX = None
@@ -1422,11 +1427,15 @@ def similarity_matching(sprites_data: dict, project_folder: str, top_k: int = 1,
1422
  import json
1423
  os.makedirs(project_folder, exist_ok=True)
1424
 
1425
- backdrop_base_path = os.path.normpath(str(BACKDROP_DIR))
1426
- sprite_base_path = os.path.normpath(str(SPRITE_DIR))
1427
- code_blocks_path = os.path.normpath(str(CODE_BLOCKS_DIR))
 
 
 
 
 
1428
 
1429
- project_json_path = os.path.join(project_folder, "project.json")
1430
 
1431
  # -------------------------
1432
  # Build sprite images list (BytesIO) from sprites_data
@@ -1935,265 +1944,272 @@ def similarity_matching(sprites_data: dict, project_folder: str, top_k: int = 1,
1935
 
1936
  # print("---")
1937
  # add at top of file
1938
- import shutil
1939
- import json
1940
- import os
1941
- from pathlib import Path
1942
-
1943
- # normalize base paths once before the loop
1944
- sprite_base_p = Path(sprite_base_path).resolve(strict=False)
1945
- backdrop_base_p = Path(backdrop_base_path).resolve(strict=False)
1946
- project_folder_p = Path(project_folder)
1947
- project_folder_p.mkdir(parents=True, exist_ok=True)
1948
-
1949
- copied_sprite_folders = set()
1950
- copied_backdrop_folders = set()
1951
-
1952
- def display_like_windows_no_lead(p: Path) -> str:
1953
- """
1954
- For human-readable logs only β€” convert Path to a string like:
1955
- "app\\blocks\\Backdrops\\Castle 2.sb3" (no leading slash).
1956
- """
1957
- s = p.as_posix() # forward-slash string, safe for Path objects
1958
- if s.startswith("/"):
1959
- s = s[1:]
1960
- return s.replace("/", "\\")
1961
-
1962
- def is_subpath(child: Path, parent: Path) -> bool:
1963
- """Robust membership test: is child under parent?"""
1964
- try:
1965
- # use non-strict resolve only if needed, but avoid exceptions
1966
- child.relative_to(parent)
1967
- return True
1968
- except Exception:
1969
- return False
1970
-
1971
- # Flatten unique matched indices (if not already)
1972
- matched_indices = sorted({idx for lst in per_sprite_matched_indices for idx in lst})
1973
- print("matched_indices------------------>", matched_indices)
1974
-
1975
- for matched_idx in matched_indices:
1976
- # defensive check
1977
- if not (0 <= matched_idx < len(paths_list)):
1978
- print(f" ⚠ matched_idx {matched_idx} out of range, skipping")
1979
- continue
1980
-
1981
- matched_image_path = paths_list[matched_idx]
1982
- matched_path_p = Path(matched_image_path).resolve(strict=False) # keep as Path
1983
- matched_folder_p = matched_path_p.parent # Path object
1984
- matched_filename = matched_path_p.name
1985
-
1986
- # Prepare display-only string (do NOT reassign matched_folder_p)
1987
- matched_folder_display = display_like_windows_no_lead(matched_folder_p)
1988
 
1989
- print(f"Processing matched image: {matched_image_path}")
1990
- print(f" - Folder: {matched_folder_display}")
1991
- print(f" - Sprite path: {display_like_windows_no_lead(sprite_base_p)}")
1992
- print(f" - Backdrop path: {display_like_windows_no_lead(backdrop_base_p)}")
1993
- print(f" - Filename: {matched_filename}")
1994
 
1995
- # Use a canonical string to store in the copied set (POSIX absolute-ish)
1996
- folder_key = matched_folder_p.as_posix()
1997
 
1998
- # ---------- SPRITE ----------
1999
- if is_subpath(matched_folder_p, sprite_base_p) and folder_key not in copied_sprite_folders:
2000
- print(f"Processing SPRITE folder: {matched_folder_display}")
2001
- copied_sprite_folders.add(folder_key)
 
 
 
 
 
2002
 
2003
- sprite_json_path = matched_folder_p / "sprite.json"
2004
- print("sprite_json_path----------------------->", sprite_json_path)
2005
- print("copied sprite folder----------------------->", copied_sprite_folders)
2006
- if sprite_json_path.exists() and sprite_json_path.is_file():
2007
- try:
2008
- with sprite_json_path.open("r", encoding="utf-8") as f:
2009
- sprite_info = json.load(f)
2010
- project_data.append(sprite_info)
2011
- print(f" βœ“ Successfully read sprite.json from {matched_folder_display}")
2012
- except Exception as e:
2013
- print(f" βœ— Failed to read sprite.json in {matched_folder_display}: {repr(e)}")
2014
- else:
2015
- print(f" ⚠ No sprite.json in {matched_folder_display}")
2016
 
2017
- # copy non-matching files from the sprite folder (except matched image and sprite.json)
2018
- try:
2019
- sprite_files = list(matched_folder_p.iterdir())
2020
- except Exception as e:
2021
- sprite_files = []
2022
- print(f" βœ— Failed to list files in {matched_folder_display}: {repr(e)}")
2023
 
2024
- print(f" Files in sprite folder: {[p.name for p in sprite_files]}")
2025
- for p in sprite_files:
2026
- fname = p.name
2027
- if fname in (matched_filename, "sprite.json"):
2028
- print(f" Skipping {fname} (matched image or sprite.json)")
2029
- continue
2030
- if p.is_file():
2031
- dst = project_folder_p / fname
2032
- try:
2033
- shutil.copy2(str(p), str(dst))
2034
- print(f" βœ“ Copied sprite asset: {p} -> {dst}")
2035
- except Exception as e:
2036
- print(f" βœ— Failed to copy sprite asset {p}: {repr(e)}")
2037
- else:
2038
- print(f" Skipping {fname} (not a file)")
2039
 
2040
- # ---------- BACKDROP ----------
2041
- if is_subpath(matched_folder_p, backdrop_base_p) and folder_key not in copied_backdrop_folders:
2042
- print(f"Processing BACKDROP folder: {matched_folder_display}")
2043
- copied_backdrop_folders.add(folder_key)
2044
- print("backdrop_base_path----------------------->", display_like_windows_no_lead(backdrop_base_p))
2045
- print("copied backdrop folder----------------------->", copied_backdrop_folders)
2046
 
2047
- # copy matched backdrop image
2048
- backdrop_src = matched_folder_p / matched_filename
2049
- backdrop_dst = project_folder_p / matched_filename
2050
- if backdrop_src.exists() and backdrop_src.is_file():
2051
- try:
2052
- shutil.copy2(str(backdrop_src), str(backdrop_dst))
2053
- print(f" βœ“ Copied matched backdrop image: {backdrop_src} -> {backdrop_dst}")
2054
- except Exception as e:
2055
- print(f" βœ— Failed to copy matched backdrop image {backdrop_src}: {repr(e)}")
2056
- else:
2057
- print(f" ⚠ Matched backdrop source not found: {backdrop_src}")
2058
 
2059
- # copy other files from folder (skip project.json and matched image)
2060
- try:
2061
- backdrop_files = list(matched_folder_p.iterdir())
2062
- except Exception as e:
2063
- backdrop_files = []
2064
- print(f" βœ— Failed to list files in {matched_folder_display}: {repr(e)}")
2065
 
2066
- print(f" Files in backdrop folder: {[p.name for p in backdrop_files]}")
2067
- for p in backdrop_files:
2068
- fname = p.name
2069
- if fname in (matched_filename, "project.json"):
2070
- print(f" Skipping {fname} (matched image or project.json)")
2071
- continue
2072
- if p.is_file():
2073
- dst = project_folder_p / fname
2074
- try:
2075
- shutil.copy2(str(p), str(dst))
2076
- print(f" βœ“ Copied backdrop asset: {p} -> {dst}")
2077
- except Exception as e:
2078
- print(f" βœ— Failed to copy backdrop asset {p}: {repr(e)}")
2079
- else:
2080
- print(f" Skipping {fname} (not a file)")
2081
 
2082
- # read project.json to extract Stage/targets
2083
- pj = matched_folder_p / "project.json"
2084
- if pj.exists() and pj.is_file():
2085
- try:
2086
- with pj.open("r", encoding="utf-8") as f:
2087
- bd_json = json.load(f)
2088
- stage_count = 0
2089
- for tgt in bd_json.get("targets", []):
2090
- if tgt.get("isStage"):
2091
- backdrop_data.append(tgt)
2092
- stage_count += 1
2093
- print(f" βœ“ Successfully read project.json from {matched_folder_display}, found {stage_count} stage(s)")
2094
- except Exception as e:
2095
- print(f" βœ— Failed to read project.json in {matched_folder_display}: {repr(e)}")
2096
- else:
2097
- print(f" ⚠ No project.json in {matched_folder_display}")
2098
 
2099
- print("---")
2100
- # for matched_idx in matched_indices:
2101
- # matched_image_path = paths_list[matched_idx]
2102
- # matched_folder = os.path.dirname(matched_image_path)
2103
- # matched_filename = os.path.basename(matched_image_path)
2104
-
2105
- # print(f"Processing matched image: {matched_image_path}")
2106
- # print(f" - Folder: {matched_folder}")
2107
- # print(f" - Sprite path: {sprite_base_path}")
2108
- # print(f" - Backdrop path: {backdrop_base_path}")
2109
- # print(f" - Filename: {matched_filename}")
2110
-
2111
- # # If it's a sprite (under SPRITE_DIR) -> copy sprite assets and read sprite.json
2112
- # if matched_folder.startswith(sprite_base_path) and matched_folder not in copied_sprite_folders:
2113
- # print(f"Processing SPRITE folder: {matched_folder}")
2114
- # copied_sprite_folders.add(matched_folder)
2115
- # sprite_json_path = os.path.join(matched_folder, "sprite.json")
2116
- # print("sprite_json_path----------------------->",sprite_json_path)
2117
- # print("copied sprite folder----------------------->",copied_sprite_folders)
2118
- # if os.path.exists(sprite_json_path):
2119
  # try:
2120
- # with open(sprite_json_path, "r", encoding="utf-8") as f:
2121
  # sprite_info = json.load(f)
2122
  # project_data.append(sprite_info)
2123
- # print(f" βœ“ Successfully read sprite.json from {matched_folder}")
2124
  # except Exception as e:
2125
- # print(f" βœ— Failed to read sprite.json in {matched_folder}: {e}")
2126
  # else:
2127
- # print(f" ⚠ No sprite.json in {matched_folder}")
2128
-
2129
- # # copy non-matching files from the sprite folder (except the matched image and sprite.json)
2130
- # sprite_files = os.listdir(matched_folder)
2131
- # print(f" Files in sprite folder: {sprite_files}")
2132
- # for fname in sprite_files:
 
 
 
 
 
 
2133
  # if fname in (matched_filename, "sprite.json"):
2134
  # print(f" Skipping {fname} (matched image or sprite.json)")
2135
  # continue
2136
- # src = os.path.join(matched_folder, fname)
2137
- # dst = os.path.join(project_folder, fname)
2138
- # if os.path.isfile(src):
2139
  # try:
2140
- # shutil.copy2(src, dst)
2141
- # print(f" βœ“ Copied sprite asset: {src} -> {dst}")
2142
  # except Exception as e:
2143
- # print(f" βœ— Failed to copy sprite asset {src}: {e}")
2144
  # else:
2145
  # print(f" Skipping {fname} (not a file)")
2146
-
2147
- # # If it's a backdrop (under BACKDROP_DIR) -> copy backdrop assets and read project.json for stage
2148
- # if matched_folder.startswith(backdrop_base_path) and matched_folder not in copied_backdrop_folders:
2149
- # print(f"Processing BACKDROP folder: {matched_folder}")
2150
- # copied_backdrop_folders.add(matched_folder)
2151
- # print("backdrop_base_path----------------------->",backdrop_base_path)
2152
- # print("copied backdrop folder----------------------->",copied_backdrop_folders)
 
2153
  # # copy matched backdrop image
2154
- # backdrop_dst = os.path.join(project_folder, matched_filename)
 
 
 
 
 
 
 
 
 
 
 
2155
  # try:
2156
- # shutil.copy2(matched_image_path, backdrop_dst)
2157
- # print(f" βœ“ Copied matched backdrop image: {matched_image_path} -> {backdrop_dst}")
2158
  # except Exception as e:
2159
- # print(f" βœ— Failed to copy matched backdrop image {matched_image_path}: {e}")
2160
-
2161
- # # copy other files from folder (skip project.json and matched image)
2162
- # backdrop_files = os.listdir(matched_folder)
2163
- # print(f" Files in backdrop folder: {backdrop_files}")
2164
- # for fname in backdrop_files:
2165
  # if fname in (matched_filename, "project.json"):
2166
  # print(f" Skipping {fname} (matched image or project.json)")
2167
  # continue
2168
- # src = os.path.join(matched_folder, fname)
2169
- # dst = os.path.join(project_folder, fname)
2170
- # if os.path.isfile(src):
2171
  # try:
2172
- # shutil.copy2(src, dst)
2173
- # print(f" βœ“ Copied backdrop asset: {src} -> {dst}")
2174
  # except Exception as e:
2175
- # print(f" βœ— Failed to copy backdrop asset {src}: {e}")
2176
  # else:
2177
  # print(f" Skipping {fname} (not a file)")
2178
-
2179
  # # read project.json to extract Stage/targets
2180
- # pj = os.path.join(matched_folder, "project.json")
2181
- # if os.path.exists(pj):
2182
  # try:
2183
- # with open(pj, "r", encoding="utf-8") as f:
2184
  # bd_json = json.load(f)
2185
  # stage_count = 0
2186
  # for tgt in bd_json.get("targets", []):
2187
  # if tgt.get("isStage"):
2188
  # backdrop_data.append(tgt)
2189
  # stage_count += 1
2190
- # print(f" βœ“ Successfully read project.json from {matched_folder}, found {stage_count} stage(s)")
2191
  # except Exception as e:
2192
- # print(f" βœ— Failed to read project.json in {matched_folder}: {e}")
2193
  # else:
2194
- # print(f" ⚠ No project.json in {matched_folder}")
2195
-
2196
  # print("---")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2197
 
2198
  # --- Merge into final Scratch project.json (identical logic to before)
2199
  final_project = {
 
84
 
85
  app = Flask(__name__)
86
 
 
 
 
 
87
  count = 0
88
 
89
+ # BASE_DIR = Path("/app")
90
+ # BLOCKS_DIR = BASE_DIR / "blocks"
91
+ # STATIC_DIR = BASE_DIR / "static"
92
+ # GEN_PROJECT_DIR = BASE_DIR / "generated_projects"
93
+ BASE_DIR = Path(os.getenv("APP_BASE_DIR", Path(__file__).resolve().parent)) # fallback to code location
94
+ LOGS_DIR = BASE_DIR / "logs"
95
+ for d in (BASE_DIR / "blocks", BASE_DIR / "static", BASE_DIR / "generated_projects", LOGS_DIR, BASE_DIR / "outputs"):
96
+ d.mkdir(parents=True, exist_ok=True)
97
  BACKDROP_DIR = BLOCKS_DIR / "Backdrops"
98
  SPRITE_DIR = BLOCKS_DIR / "sprites"
99
  CODE_BLOCKS_DIR = BLOCKS_DIR / "code_blocks"
100
  # === new: outputs rooted under BASE_DIR ===
101
  OUTPUT_DIR = BASE_DIR / "outputs"
102
 
103
+
104
+ backdrop_images_path = str(BACKDROP_DIR)
105
+ sprite_images_path = str(SPRITE_DIR)
106
+ code_blocks_image_path = str(CODE_BLOCKS_DIR)
107
+
108
  # Global variables to hold the model and index, loaded only once.
109
  MODEL = None
110
  FAISS_INDEX = None
 
1427
  import json
1428
  os.makedirs(project_folder, exist_ok=True)
1429
 
1430
+ # backdrop_base_path = os.path.normpath(str(BACKDROP_DIR)).resolve()
1431
+ # sprite_base_path = os.path.normpath(str(SPRITE_DIR)).resolve()
1432
+ # code_blocks_path = os.path.normpath(str(CODE_BLOCKS_DIR)).resolve()
1433
+ # project_json_path = os.path.join(project_folder, "project.json").resolve()
1434
+ backdrop_base_path = BACKDROP_DIR.resolve()
1435
+ sprite_base_path = SPRITE_DIR.resolve()
1436
+ code_blocks_path = CODE_BLOCKS_DIR.resolve()
1437
+ project_json_path = (Path(project_folder) / "project.json").resolve()
1438
 
 
1439
 
1440
  # -------------------------
1441
  # Build sprite images list (BytesIO) from sprites_data
 
1944
 
1945
  # print("---")
1946
  # add at top of file
1947
+ # import shutil
1948
+ # import json
1949
+ # import os
1950
+ # from pathlib import Path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1951
 
1952
+ # # normalize base paths once before the loop
1953
+ # sprite_base_p = Path(sprite_base_path).resolve(strict=False)
1954
+ # backdrop_base_p = Path(backdrop_base_path).resolve(strict=False)
1955
+ # project_folder_p = Path(project_folder)
1956
+ # project_folder_p.mkdir(parents=True, exist_ok=True)
1957
 
1958
+ # copied_sprite_folders = set()
1959
+ # copied_backdrop_folders = set()
1960
 
1961
+ # def display_like_windows_no_lead(p: Path) -> str:
1962
+ # """
1963
+ # For human-readable logs only β€” convert Path to a string like:
1964
+ # "app\\blocks\\Backdrops\\Castle 2.sb3" (no leading slash).
1965
+ # """
1966
+ # s = p.as_posix() # forward-slash string, safe for Path objects
1967
+ # if s.startswith("/"):
1968
+ # s = s[1:]
1969
+ # return s.replace("/", "\\")
1970
 
1971
+ # def is_subpath(child: Path, parent: Path) -> bool:
1972
+ # """Robust membership test: is child under parent?"""
1973
+ # try:
1974
+ # # use non-strict resolve only if needed, but avoid exceptions
1975
+ # child.relative_to(parent)
1976
+ # return True
1977
+ # except Exception:
1978
+ # return False
 
 
 
 
 
1979
 
1980
+ # # Flatten unique matched indices (if not already)
1981
+ # matched_indices = sorted({idx for lst in per_sprite_matched_indices for idx in lst})
1982
+ # print("matched_indices------------------>", matched_indices)
 
 
 
1983
 
1984
+ # for matched_idx in matched_indices:
1985
+ # # defensive check
1986
+ # if not (0 <= matched_idx < len(paths_list)):
1987
+ # print(f" ⚠ matched_idx {matched_idx} out of range, skipping")
1988
+ # continue
 
 
 
 
 
 
 
 
 
 
1989
 
1990
+ # matched_image_path = paths_list[matched_idx]
1991
+ # matched_path_p = Path(matched_image_path).resolve(strict=False) # keep as Path
1992
+ # matched_folder_p = matched_path_p.parent # Path object
1993
+ # matched_filename = matched_path_p.name
 
 
1994
 
1995
+ # # Prepare display-only string (do NOT reassign matched_folder_p)
1996
+ # matched_folder_display = display_like_windows_no_lead(matched_folder_p)
 
 
 
 
 
 
 
 
 
1997
 
1998
+ # print(f"Processing matched image: {matched_image_path}")
1999
+ # print(f" - Folder: {matched_folder_display}")
2000
+ # print(f" - Sprite path: {display_like_windows_no_lead(sprite_base_p)}")
2001
+ # print(f" - Backdrop path: {display_like_windows_no_lead(backdrop_base_p)}")
2002
+ # print(f" - Filename: {matched_filename}")
 
2003
 
2004
+ # # Use a canonical string to store in the copied set (POSIX absolute-ish)
2005
+ # folder_key = matched_folder_p.as_posix()
 
 
 
 
 
 
 
 
 
 
 
 
 
2006
 
2007
+ # # ---------- SPRITE ----------
2008
+ # if is_subpath(matched_folder_p, sprite_base_p) and folder_key not in copied_sprite_folders:
2009
+ # print(f"Processing SPRITE folder: {matched_folder_display}")
2010
+ # copied_sprite_folders.add(folder_key)
 
 
 
 
 
 
 
 
 
 
 
 
2011
 
2012
+ # sprite_json_path = matched_folder_p / "sprite.json"
2013
+ # print("sprite_json_path----------------------->", sprite_json_path)
2014
+ # print("copied sprite folder----------------------->", copied_sprite_folders)
2015
+ # if sprite_json_path.exists() and sprite_json_path.is_file():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2016
  # try:
2017
+ # with sprite_json_path.open("r", encoding="utf-8") as f:
2018
  # sprite_info = json.load(f)
2019
  # project_data.append(sprite_info)
2020
+ # print(f" βœ“ Successfully read sprite.json from {matched_folder_display}")
2021
  # except Exception as e:
2022
+ # print(f" βœ— Failed to read sprite.json in {matched_folder_display}: {repr(e)}")
2023
  # else:
2024
+ # print(f" ⚠ No sprite.json in {matched_folder_display}")
2025
+
2026
+ # # copy non-matching files from the sprite folder (except matched image and sprite.json)
2027
+ # try:
2028
+ # sprite_files = list(matched_folder_p.iterdir())
2029
+ # except Exception as e:
2030
+ # sprite_files = []
2031
+ # print(f" βœ— Failed to list files in {matched_folder_display}: {repr(e)}")
2032
+
2033
+ # print(f" Files in sprite folder: {[p.name for p in sprite_files]}")
2034
+ # for p in sprite_files:
2035
+ # fname = p.name
2036
  # if fname in (matched_filename, "sprite.json"):
2037
  # print(f" Skipping {fname} (matched image or sprite.json)")
2038
  # continue
2039
+ # if p.is_file():
2040
+ # dst = project_folder_p / fname
 
2041
  # try:
2042
+ # shutil.copy2(str(p), str(dst))
2043
+ # print(f" βœ“ Copied sprite asset: {p} -> {dst}")
2044
  # except Exception as e:
2045
+ # print(f" βœ— Failed to copy sprite asset {p}: {repr(e)}")
2046
  # else:
2047
  # print(f" Skipping {fname} (not a file)")
2048
+
2049
+ # # ---------- BACKDROP ----------
2050
+ # if is_subpath(matched_folder_p, backdrop_base_p) and folder_key not in copied_backdrop_folders:
2051
+ # print(f"Processing BACKDROP folder: {matched_folder_display}")
2052
+ # copied_backdrop_folders.add(folder_key)
2053
+ # print("backdrop_base_path----------------------->", display_like_windows_no_lead(backdrop_base_p))
2054
+ # print("copied backdrop folder----------------------->", copied_backdrop_folders)
2055
+
2056
  # # copy matched backdrop image
2057
+ # backdrop_src = matched_folder_p / matched_filename
2058
+ # backdrop_dst = project_folder_p / matched_filename
2059
+ # if backdrop_src.exists() and backdrop_src.is_file():
2060
+ # try:
2061
+ # shutil.copy2(str(backdrop_src), str(backdrop_dst))
2062
+ # print(f" βœ“ Copied matched backdrop image: {backdrop_src} -> {backdrop_dst}")
2063
+ # except Exception as e:
2064
+ # print(f" βœ— Failed to copy matched backdrop image {backdrop_src}: {repr(e)}")
2065
+ # else:
2066
+ # print(f" ⚠ Matched backdrop source not found: {backdrop_src}")
2067
+
2068
+ # # copy other files from folder (skip project.json and matched image)
2069
  # try:
2070
+ # backdrop_files = list(matched_folder_p.iterdir())
 
2071
  # except Exception as e:
2072
+ # backdrop_files = []
2073
+ # print(f" βœ— Failed to list files in {matched_folder_display}: {repr(e)}")
2074
+
2075
+ # print(f" Files in backdrop folder: {[p.name for p in backdrop_files]}")
2076
+ # for p in backdrop_files:
2077
+ # fname = p.name
2078
  # if fname in (matched_filename, "project.json"):
2079
  # print(f" Skipping {fname} (matched image or project.json)")
2080
  # continue
2081
+ # if p.is_file():
2082
+ # dst = project_folder_p / fname
 
2083
  # try:
2084
+ # shutil.copy2(str(p), str(dst))
2085
+ # print(f" βœ“ Copied backdrop asset: {p} -> {dst}")
2086
  # except Exception as e:
2087
+ # print(f" βœ— Failed to copy backdrop asset {p}: {repr(e)}")
2088
  # else:
2089
  # print(f" Skipping {fname} (not a file)")
2090
+
2091
  # # read project.json to extract Stage/targets
2092
+ # pj = matched_folder_p / "project.json"
2093
+ # if pj.exists() and pj.is_file():
2094
  # try:
2095
+ # with pj.open("r", encoding="utf-8") as f:
2096
  # bd_json = json.load(f)
2097
  # stage_count = 0
2098
  # for tgt in bd_json.get("targets", []):
2099
  # if tgt.get("isStage"):
2100
  # backdrop_data.append(tgt)
2101
  # stage_count += 1
2102
+ # print(f" βœ“ Successfully read project.json from {matched_folder_display}, found {stage_count} stage(s)")
2103
  # except Exception as e:
2104
+ # print(f" βœ— Failed to read project.json in {matched_folder_display}: {repr(e)}")
2105
  # else:
2106
+ # print(f" ⚠ No project.json in {matched_folder_display}")
2107
+
2108
  # print("---")
2109
+ for matched_idx in matched_indices:
2110
+ matched_image_path = paths_list[matched_idx]
2111
+ # matched_folder = os.path.dirname(matched_image_path)
2112
+ matched_folder = str(Path(matched_image_path).parent.resolve())
2113
+ matched_filename = os.path.basename(matched_image_path)
2114
+
2115
+ print(f"Processing matched image: {matched_image_path}")
2116
+ print(f" - Folder: {matched_folder}")
2117
+ print(f" - Sprite path: {sprite_base_path}")
2118
+ print(f" - Backdrop path: {backdrop_base_path}")
2119
+ print(f" - Filename: {matched_filename}")
2120
+
2121
+ # If it's a sprite (under SPRITE_DIR) -> copy sprite assets and read sprite.json
2122
+ # if matched_folder.startswith(sprite_base_path) and matched_folder not in copied_sprite_folders:
2123
+ if is_subpath(matched_folder, sprite_base_path) and matched_folder not in copied_sprite_folders:
2124
+ print(f"Processing SPRITE folder: {matched_folder}")
2125
+ copied_sprite_folders.add(matched_folder)
2126
+ # sprite_json_path = os.path.join(matched_folder, "sprite.json")
2127
+ sprite_json_path = str(Path(matched_folder) / "sprite.json")
2128
+ print("sprite_json_path----------------------->",sprite_json_path)
2129
+ print("copied sprite folder----------------------->",copied_sprite_folders)
2130
+ if os.path.exists(sprite_json_path):
2131
+ try:
2132
+ with open(sprite_json_path, "r", encoding="utf-8") as f:
2133
+ sprite_info = json.load(f)
2134
+ project_data.append(sprite_info)
2135
+ print(f" βœ“ Successfully read sprite.json from {matched_folder}")
2136
+ except Exception as e:
2137
+ print(f" βœ— Failed to read sprite.json in {matched_folder}: {e}")
2138
+ else:
2139
+ print(f" ⚠ No sprite.json in {matched_folder}")
2140
+
2141
+ # copy non-matching files from the sprite folder (except the matched image and sprite.json)
2142
+ sprite_files = os.listdir(matched_folder)
2143
+ print(f" Files in sprite folder: {sprite_files}")
2144
+ for fname in sprite_files:
2145
+ if fname in (matched_filename, "sprite.json"):
2146
+ print(f" Skipping {fname} (matched image or sprite.json)")
2147
+ continue
2148
+ src = os.path.join(matched_folder, fname)
2149
+ dst = os.path.join(project_folder, fname)
2150
+ if os.path.isfile(src):
2151
+ try:
2152
+ shutil.copy2(src, dst)
2153
+ print(f" βœ“ Copied sprite asset: {src} -> {dst}")
2154
+ except Exception as e:
2155
+ print(f" βœ— Failed to copy sprite asset {src}: {e}")
2156
+ else:
2157
+ print(f" Skipping {fname} (not a file)")
2158
+
2159
+ # If it's a backdrop (under BACKDROP_DIR) -> copy backdrop assets and read project.json for stage
2160
+ # if matched_folder.startswith(backdrop_base_path) and matched_folder not in copied_backdrop_folders:
2161
+ if is_subpath(matched_folder, backdrop_base_path) and matched_folder not in copied_backdrop_folders:
2162
+ print(f"Processing BACKDROP folder: {matched_folder}")
2163
+ copied_backdrop_folders.add(matched_folder)
2164
+ print("backdrop_base_path----------------------->",backdrop_base_path)
2165
+ print("copied backdrop folder----------------------->",copied_backdrop_folders)
2166
+ # copy matched backdrop image
2167
+ backdrop_dst = os.path.join(project_folder, matched_filename)
2168
+ try:
2169
+ shutil.copy2(matched_image_path, backdrop_dst)
2170
+ print(f" βœ“ Copied matched backdrop image: {matched_image_path} -> {backdrop_dst}")
2171
+ except Exception as e:
2172
+ print(f" βœ— Failed to copy matched backdrop image {matched_image_path}: {e}")
2173
+
2174
+ # copy other files from folder (skip project.json and matched image)
2175
+ backdrop_files = os.listdir(matched_folder)
2176
+ print(f" Files in backdrop folder: {backdrop_files}")
2177
+ for fname in backdrop_files:
2178
+ if fname in (matched_filename, "project.json"):
2179
+ print(f" Skipping {fname} (matched image or project.json)")
2180
+ continue
2181
+ # src = os.path.join(matched_folder, fname)
2182
+ # dst = os.path.join(project_folder, fname)
2183
+ src = Path(matched_folder) / fname
2184
+ dst = Path(project_folder) / fname
2185
+ if os.path.isfile(src):
2186
+ try:
2187
+ shutil.copy2(src, dst)
2188
+ print(f" βœ“ Copied backdrop asset: {src} -> {dst}")
2189
+ except Exception as e:
2190
+ print(f" βœ— Failed to copy backdrop asset {src}: {e}")
2191
+ else:
2192
+ print(f" Skipping {fname} (not a file)")
2193
+
2194
+ # read project.json to extract Stage/targets
2195
+ # pj = os.path.join(matched_folder, "project.json")
2196
+ pj = str(Path(matched_folder) / "project.json")
2197
+ if os.path.exists(pj):
2198
+ try:
2199
+ with open(pj, "r", encoding="utf-8") as f:
2200
+ bd_json = json.load(f)
2201
+ stage_count = 0
2202
+ for tgt in bd_json.get("targets", []):
2203
+ if tgt.get("isStage"):
2204
+ backdrop_data.append(tgt)
2205
+ stage_count += 1
2206
+ print(f" βœ“ Successfully read project.json from {matched_folder}, found {stage_count} stage(s)")
2207
+ except Exception as e:
2208
+ print(f" βœ— Failed to read project.json in {matched_folder}: {e}")
2209
+ else:
2210
+ print(f" ⚠ No project.json in {matched_folder}")
2211
+
2212
+ print("---")
2213
 
2214
  # --- Merge into final Scratch project.json (identical logic to before)
2215
  final_project = {