1+ #!/usr/bin/env python3
2+ """
3+ Processes additions from additions_added.json and updates TSV files by replacing id_add with id values.
4+ Filters out already processed IDs to avoid duplicates and tracks processed additions.
5+ """
6+
7+ import json
8+ import csv
9+ from pathlib import Path
10+ from typing import Dict , List , Set
11+ from gui2 .paths import Gui2Paths
12+ from tools .paths_dps import DPSPaths
13+
14+
15+ def load_additions_data (json_path : Path ) -> Dict [str , int ]:
16+ """
17+ Load additions data from JSON file and create id_add -> id mapping.
18+
19+ Args:
20+ json_path: Path to the additions_added.json file
21+
22+ Returns:
23+ Dictionary mapping id_add (string) to id (integer)
24+ """
25+ with open (json_path , 'r' , encoding = 'utf-8' ) as f :
26+ additions_data = json .load (f )
27+
28+ # Create mapping from id_add to id
29+ id_mapping = {}
30+ for entry in additions_data :
31+ id_add = str (entry ['id_add' ])
32+ id_val = entry ['id' ]
33+ id_mapping [id_add ] = id_val
34+
35+ return id_mapping
36+
37+
38+ def load_processed_ids (processed_path : Path ) -> Set [str ]:
39+ """
40+ Load already processed id_add values from the processed file.
41+
42+ Args:
43+ processed_path: Path to the addition_processed.json file
44+
45+ Returns:
46+ Set of already processed id_add values
47+ """
48+ if not processed_path .exists ():
49+ return set ()
50+
51+ try :
52+ with open (processed_path , 'r' , encoding = 'utf-8' ) as f :
53+ processed_data = json .load (f )
54+ return set (processed_data )
55+ except (json .JSONDecodeError , FileNotFoundError ):
56+ return set ()
57+
58+
59+ def save_processed_ids (processed_path : Path , processed_ids : Set [str ]) -> None :
60+ """
61+ Save processed id_add values to the processed file.
62+
63+ Args:
64+ processed_path: Path to the addition_processed.json file
65+ processed_ids: Set of processed id_add values to save
66+ """
67+ # Load existing processed IDs
68+ existing_ids = load_processed_ids (processed_path )
69+
70+ # Merge with new processed IDs
71+ all_processed_ids = existing_ids .union (processed_ids )
72+
73+ # Save back to file
74+ with open (processed_path , 'w' , encoding = 'utf-8' ) as f :
75+ json .dump (list (all_processed_ids ), f , indent = 2 )
76+
77+
78+ def replace_ids_in_tsv (tsv_path : Path , id_mapping : Dict [str , int ]) -> int :
79+ """
80+ Replace id_add with id in a TSV file.
81+
82+ Args:
83+ tsv_path: Path to the TSV file to update
84+ id_mapping: Dictionary mapping id_add (string) to id (integer)
85+
86+ Returns:
87+ Number of replacements made
88+ """
89+ if not tsv_path .exists ():
90+ print (f"Warning: TSV file { tsv_path } does not exist" )
91+ return 0
92+
93+ replacements = 0
94+
95+ # Read the TSV file
96+ with open (tsv_path , 'r' , encoding = 'utf-8' ) as f :
97+ lines = f .readlines ()
98+
99+ # Process each line
100+ updated_lines = []
101+ for line_num , line in enumerate (lines , 1 ):
102+ updated_line = line
103+ for id_add , id_val in id_mapping .items ():
104+ # Replace id_add with id in the line
105+ if id_add in line :
106+ updated_line = updated_line .replace (id_add , str (id_val ))
107+ if updated_line != line :
108+ replacements += 1
109+ print (f"Replaced '{ id_add } ' with '{ id_val } ' in { tsv_path .name } line { line_num } " )
110+
111+ updated_lines .append (updated_line )
112+
113+ # Write the updated content back to the file
114+ with open (tsv_path , 'w' , encoding = 'utf-8' ) as f :
115+ f .writelines (updated_lines )
116+
117+ return replacements
118+
119+
120+ def process_additions () -> None :
121+ """
122+ Main function to process additions and update TSV files.
123+ """
124+ # Initialize path objects
125+ pthgui = Gui2Paths ()
126+ pthdps = DPSPaths ()
127+
128+ # Load additions data
129+ print ("Loading additions data..." )
130+ id_mapping = load_additions_data (pthgui .additions_added_path )
131+ print (f"Found { len (id_mapping )} additions to process" )
132+
133+ # Load already processed IDs
134+ print ("Loading already processed IDs..." )
135+ processed_ids = load_processed_ids (pthdps .addition_processed )
136+ print (f"Already processed { len (processed_ids )} additions" )
137+
138+ # Filter out already processed IDs
139+ new_id_mapping = {id_add : id_val for id_add , id_val in id_mapping .items ()
140+ if id_add not in processed_ids }
141+
142+ if not new_id_mapping :
143+ print ("No new additions to process" )
144+ return
145+
146+ print (f"Processing { len (new_id_mapping )} new additions" )
147+
148+ # Replace IDs in TSV files
149+ print (f"Updating SBS TSV file: { pthdps .sbs_path } " )
150+ sbs_replacements = replace_ids_in_tsv (pthdps .sbs_path , new_id_mapping )
151+
152+ print (f"Updating Russian TSV file: { pthdps .russian_path } " )
153+ russian_replacements = replace_ids_in_tsv (pthdps .russian_path , new_id_mapping )
154+
155+ # Update processed IDs file
156+ print ("Updating processed IDs file..." )
157+ save_processed_ids (pthdps .addition_processed , set (new_id_mapping .keys ()))
158+
159+ print (f"Processing complete!" )
160+ print (f"- SBS replacements: { sbs_replacements } " )
161+ print (f"- Russian replacements: { russian_replacements } " )
162+ print (f"- Total new additions processed: { len (new_id_mapping )} " )
163+
164+
165+ if __name__ == "__main__" :
166+ process_additions ()
0 commit comments