Skip to content

Commit 68a4493

Browse files
authored
Merge pull request #85 from iautolab/chore/fix-bugs-and-hygiene
chore: fix bugs and code hygiene issues
2 parents 629a65f + 9b30a3b commit 68a4493

10 files changed

Lines changed: 51 additions & 33 deletions

File tree

openlrc/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
from openlrc.openlrc import LRCer, TranscriptionConfig, TranslationConfig
66

77
__all__ = ("LRCer", "TranscriptionConfig", "TranslationConfig", "ModelConfig", "list_chatbot_models", "ModelProvider")
8-
__version__ = "1.5.2"
8+
__version__ = "1.6.1"
99
__author__ = "zh-plus"

openlrc/agents.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(
100100
self,
101101
src_lang,
102102
target_lang,
103-
info: TranslateInfo = TranslateInfo(),
103+
info: TranslateInfo | None = None,
104104
chatbot_model: str | ModelConfig = "gpt-4.1-nano",
105105
fee_limit: float = 0.8,
106106
proxy: str | None = None,
@@ -119,6 +119,8 @@ def __init__(
119119
base_url_config (Optional[dict]): Configuration for the base URL of the API.
120120
"""
121121
super().__init__()
122+
if info is None:
123+
info = TranslateInfo()
122124
self.chatbot_model = chatbot_model
123125
self.info = info
124126
self.chatbot = self._initialize_chatbot(chatbot_model, fee_limit, proxy, base_url_config)
@@ -149,9 +151,9 @@ def _parse_responses(self, resp) -> tuple[list[str], str, str]:
149151
translations = self._extract_translations(content)
150152

151153
return [t.strip() for t in translations], summary.strip(), scene.strip()
152-
except Exception as e:
154+
except Exception:
153155
logger.error(f"Failed to extract contents from response: {content}")
154-
raise e
156+
raise
155157

156158
def _extract_tag_content(self, content: str, tag: str) -> str:
157159
"""
@@ -203,7 +205,7 @@ def translate_chunk(
203205
self,
204206
chunk_id: int,
205207
chunk: list[tuple[int, str]],
206-
context: TranslationContext = TranslationContext(),
208+
context: TranslationContext | None = None,
207209
use_glossary: bool = True,
208210
) -> tuple[list[str], TranslationContext]:
209211
"""
@@ -218,6 +220,8 @@ def translate_chunk(
218220
Returns:
219221
Tuple[List[str], TranslationContext]: The translated texts and updated context.
220222
"""
223+
if context is None:
224+
context = TranslationContext()
221225
user_input = self.prompter.format_texts(chunk)
222226
guideline = context.guideline if use_glossary else context.non_glossary_guideline
223227
messages_list = [
@@ -251,7 +255,7 @@ def __init__(
251255
self,
252256
src_lang,
253257
target_lang,
254-
info: TranslateInfo = TranslateInfo(),
258+
info: TranslateInfo | None = None,
255259
chatbot_model: str | ModelConfig = "gpt-4.1-nano",
256260
retry_model: str | ModelConfig | None = None,
257261
fee_limit: float = 0.8,
@@ -272,6 +276,8 @@ def __init__(
272276
base_url_config (Optional[dict]): Configuration for the base URL of the API.
273277
"""
274278
super().__init__()
279+
if info is None:
280+
info = TranslateInfo()
275281
self.src_lang = src_lang
276282
self.target_lang = target_lang
277283
self.info = info
@@ -426,7 +432,7 @@ def __init__(
426432
self,
427433
src_lang,
428434
target_lang,
429-
info: TranslateInfo = TranslateInfo(),
435+
info: TranslateInfo | None = None,
430436
chatbot_model: str | ModelConfig = "gpt-4.1-nano",
431437
fee_limit: float = 0.8,
432438
proxy: str | None = None,
@@ -445,6 +451,8 @@ def __init__(
445451
base_url_config (Optional[dict]): Configuration for the base URL of the API.
446452
"""
447453
super().__init__()
454+
if info is None:
455+
info = TranslateInfo()
448456
self.src_lang = src_lang
449457
self.target_lang = target_lang
450458
self.info = info

openlrc/chatbot.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import os
77
import random
88
import re
9-
import time
109
from collections.abc import Callable
1110
from copy import deepcopy
1211

@@ -80,7 +79,7 @@ def __init__(self, model_name, temperature=1, top_p=1, retry=8, max_async=16, fe
8079
self.model_info = Models.get_model(model_name, beta)
8180
self.model_name = model_name
8281
except ValueError:
83-
raise ValueError(f"Invalid model {model_name}.")
82+
raise ValueError(f"Invalid model {model_name}.") from None
8483

8584
self.temperature = temperature
8685
self.top_p = top_p
@@ -175,7 +174,7 @@ def message(
175174
)
176175
except ChatBotException as e:
177176
logger.error(f"Failed to message with GPT. Error: {e}")
178-
raise e
177+
raise
179178
finally:
180179
logger.info(f"Translation fee for this call: {self.api_fees[-1]:.4f} USD")
181180
logger.info(f"Total bot translation fee: {sum(self.api_fees):.4f} USD")
@@ -257,6 +256,9 @@ def _resolve_client_settings(api_key: str | None, base_url_config: dict | None)
257256

258257
raise ValueError("No API key found. Set OPENAI_API_KEY or pass api_key explicitly.")
259258

259+
def __enter__(self):
260+
return self
261+
260262
def __exit__(self, exc_type, exc_val, exc_tb):
261263
asyncio.run(self.async_client.close())
262264

@@ -318,7 +320,7 @@ async def _create_achat(
318320
) as e:
319321
sleep_time = self._get_sleep_time(e)
320322
logger.warning(f"{type(e).__name__}: {e}. Wait {sleep_time}s before retry. Retry num: {i + 1}.")
321-
time.sleep(sleep_time)
323+
await asyncio.sleep(sleep_time)
322324

323325
if not response:
324326
raise ChatBotException("Failed to create a chat.")
@@ -424,7 +426,7 @@ async def _create_achat(
424426
) as e:
425427
sleep_time = self._get_sleep_time(e)
426428
logger.warning(f"{type(e).__name__}: {e}. Wait {sleep_time}s before retry. Retry num: {i + 1}.")
427-
time.sleep(sleep_time)
429+
await asyncio.sleep(sleep_time)
428430

429431
if not response:
430432
raise ChatBotException("Failed to create a chat.")
@@ -552,7 +554,7 @@ async def _create_achat(
552554
self.update_fee(response)
553555
if not response.text:
554556
logger.warning(f"Get None response. Wait 15s. Retry num: {i + 1}.")
555-
time.sleep(15)
557+
await asyncio.sleep(15)
556558
continue
557559

558560
response_text = remove_stop(response.text, stop_sequences)

openlrc/logger.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
)
1818
handler.setFormatter(formatter)
1919

20-
logger = logging.getLogger()
20+
logger = logging.getLogger("openlrc")
2121
logger.handlers.clear() # Clear existing handlers
2222
logger.addHandler(handler)
23+
logger.propagate = False
2324

2425
logger.setLevel("INFO")

openlrc/openlrc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ def run(
679679
logger.warning("No audio/video file given. Skip LRCer.run()")
680680
return []
681681

682-
if isinstance(paths, str) or isinstance(paths, Path):
682+
if isinstance(paths, (str, Path)):
683683
paths = [paths]
684684

685685
paths = list(map(Path, paths))
@@ -743,7 +743,7 @@ def clear_temp_files(self, paths):
743743
744744
This method removes temporary folders and generated wave files from video processing.
745745
"""
746-
temp_folders = set([path.parent for path in paths])
746+
temp_folders = {path.parent for path in paths}
747747
for folder in temp_folders:
748748
assert folder.name == "preprocessed", f"Not a temporary folder: {folder}"
749749

openlrc/preprocess.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,10 @@ def __init__(
4343
self,
4444
audio_paths: str | Path | list[str] | list[Path],
4545
output_folder: str = "preprocessed",
46-
options: dict = default_preprocess_options,
46+
options: dict | None = None,
4747
):
48+
if options is None:
49+
options = dict(default_preprocess_options)
4850
paths_list = audio_paths if isinstance(audio_paths, list) else [audio_paths]
4951
self.audio_paths: list[Path] = [Path(p) for p in paths_list]
5052
self.output_paths = [p.parent / output_folder for p in self.audio_paths]
@@ -61,7 +63,7 @@ def noise_suppression(self, audio_paths: list[Path], atten_lim_db: int = 15):
6163
if not audio_paths:
6264
return []
6365

64-
if "atten_lim_db" in self.options.keys():
66+
if "atten_lim_db" in self.options:
6567
atten_lim_db = self.options["atten_lim_db"]
6668

6769
model, df_state, _ = init_df()

openlrc/subtitle.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ def from_file(filename):
6060
return Subtitle.from_lrc(filename)
6161
elif suffix == ".srt":
6262
return Subtitle.from_srt(filename)
63+
else:
64+
raise ValueError(f"Unsupported subtitle format: {suffix!r}")
6365

6466
def __len__(self):
6567
return len(self.segments)

openlrc/transcribe.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def sentence_split(self, segments: list[Segment], lang: str):
148148
Returns:
149149
list: List of sentence-split segments.
150150
"""
151-
if lang not in LANGUAGE_CODES.keys():
151+
if lang not in LANGUAGE_CODES:
152152
logger.warning(f"Language {lang} not supported. Skipping sentence split.")
153153
return segments
154154

openlrc/translate.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def translate(
162162
texts: str | list[str],
163163
src_lang: str,
164164
target_lang: str,
165-
info: TranslateInfo = TranslateInfo(),
165+
info: TranslateInfo | None = None,
166166
compare_path: Path = Path("translate_intermediate.json"),
167167
) -> list[str]:
168168
"""
@@ -185,6 +185,9 @@ def translate(
185185
Returns:
186186
List[str]: List of translated texts.
187187
"""
188+
if info is None:
189+
info = TranslateInfo()
190+
188191
if not isinstance(texts, list):
189192
texts = [texts]
190193

@@ -414,7 +417,7 @@ def translate(self, texts: str | list[str], src_lang, target_lang, info=None):
414417
try:
415418
request = requests.post(self.constructed_url, params=params, headers=self.headers, json=body, timeout=20)
416419
except TimeoutError:
417-
raise RuntimeError("Failed to connect to Microsoft Translator API.")
420+
raise RuntimeError("Failed to connect to Microsoft Translator API.") from None
418421
response = request.json()
419422

420423
return json.dumps(response, sort_keys=True, ensure_ascii=False, indent=4, separators=(",", ": "))

openlrc/utils.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -310,24 +310,24 @@ def get_similarity(text1, text2):
310310

311311

312312
def merge_subtitle(video_path, subtitle_path, output_path):
313-
def convert2ffmpeg_path(path):
314-
abs_path = str(Path(path).absolute()).replace("\\", "/")
315-
316-
abs_path = abs_path[0] + "\\\\" + abs_path[1:]
317-
318-
return abs_path
319-
320313
# check ffmpeg
321314
try:
322-
subprocess.check_output("ffmpeg -version", shell=True)
315+
subprocess.check_output(["ffmpeg", "-version"])
323316
except FileNotFoundError:
324-
raise RuntimeError("ffmpeg is not installed. Please install ffmpeg first.")
317+
raise RuntimeError("ffmpeg is not installed. Please install ffmpeg first.") from None
325318

326-
subtitle_path = convert2ffmpeg_path(subtitle_path)
319+
subtitle_abs = str(Path(subtitle_path).absolute())
327320
style = "FontSize=24,Bold=1"
328321
subprocess.call(
329-
f'ffmpeg -y -i "{video_path}" -vf subtitles="{subtitle_path}":force_style=\'{style}\' "{output_path}"',
330-
shell=True,
322+
[
323+
"ffmpeg",
324+
"-y",
325+
"-i",
326+
str(video_path),
327+
"-vf",
328+
f"subtitles={subtitle_abs}:force_style='{style}'",
329+
str(output_path),
330+
]
331331
)
332332

333333
logger.info(f"Subtitled video saved to {output_path}")

0 commit comments

Comments
 (0)