admin can split a sentence into 2 sentences
This commit is contained in:
@@ -331,6 +331,166 @@ class VideoRepository:
|
||||
reference_speech_duration_ms=row["reference_speech_duration_ms"],
|
||||
)
|
||||
|
||||
def get_sentence(
|
||||
self,
|
||||
video_hash: str,
|
||||
sentence_index: int,
|
||||
) -> Optional[SentenceBoundary]:
|
||||
normalized_hash = normalize_video_hash(video_hash)
|
||||
with self._connect() as connection:
|
||||
row = connection.execute(
|
||||
"""
|
||||
SELECT * FROM sentences
|
||||
WHERE video_hash = ? AND sentence_index = ?
|
||||
""",
|
||||
(normalized_hash, sentence_index),
|
||||
).fetchone()
|
||||
if row is None:
|
||||
return None
|
||||
return SentenceBoundary(
|
||||
index=row["sentence_index"],
|
||||
start_ms=row["start_ms"],
|
||||
end_ms=row["end_ms"],
|
||||
text=row["text"],
|
||||
language=row["language"],
|
||||
reference_speech_duration_ms=row["reference_speech_duration_ms"],
|
||||
)
|
||||
|
||||
def replace_sentence(
|
||||
self,
|
||||
video_hash: str,
|
||||
sentence_index: int,
|
||||
replacements: List[SentenceBoundary],
|
||||
) -> Optional[List[SentenceBoundary]]:
|
||||
"""Replace one sentence row with one or more contiguous sentence rows."""
|
||||
normalized_hash = normalize_video_hash(video_hash)
|
||||
if not replacements:
|
||||
raise ValueError("At least one replacement sentence is required.")
|
||||
|
||||
with self._connect() as connection:
|
||||
source = connection.execute(
|
||||
"""
|
||||
SELECT * FROM sentences
|
||||
WHERE video_hash = ? AND sentence_index = ?
|
||||
""",
|
||||
(normalized_hash, sentence_index),
|
||||
).fetchone()
|
||||
if source is None:
|
||||
return None
|
||||
|
||||
rows = [
|
||||
SentenceBoundary(
|
||||
index=index,
|
||||
start_ms=replacement.start_ms,
|
||||
end_ms=replacement.end_ms,
|
||||
text=replacement.text.strip(),
|
||||
language=replacement.language,
|
||||
reference_speech_duration_ms=max(
|
||||
1, replacement.reference_speech_duration_ms or 1
|
||||
),
|
||||
)
|
||||
for index, replacement in enumerate(replacements)
|
||||
]
|
||||
previous_end = source["start_ms"]
|
||||
for replacement in rows:
|
||||
if (
|
||||
replacement.start_ms < previous_end
|
||||
or replacement.end_ms <= replacement.start_ms
|
||||
):
|
||||
raise ValueError("Replacement sentence times must be contiguous.")
|
||||
if replacement.end_ms > source["end_ms"]:
|
||||
raise ValueError(
|
||||
"Replacement sentences cannot exceed the source sentence."
|
||||
)
|
||||
previous_end = replacement.end_ms
|
||||
if rows[-1].end_ms != source["end_ms"]:
|
||||
raise ValueError("Replacement sentences must cover the source sentence.")
|
||||
|
||||
# Shift following rows down first. Descending indexes avoid violating
|
||||
# the (video_hash, sentence_index) primary key while making room.
|
||||
added_count = len(rows) - 1
|
||||
if added_count:
|
||||
following = [
|
||||
row["sentence_index"]
|
||||
for row in connection.execute(
|
||||
"""
|
||||
SELECT sentence_index FROM sentences
|
||||
WHERE video_hash = ? AND sentence_index > ?
|
||||
ORDER BY sentence_index DESC
|
||||
""",
|
||||
(normalized_hash, sentence_index),
|
||||
).fetchall()
|
||||
]
|
||||
for old_index in following:
|
||||
connection.execute(
|
||||
"""
|
||||
UPDATE sentences SET sentence_index = ?
|
||||
WHERE video_hash = ? AND sentence_index = ?
|
||||
""",
|
||||
(old_index + added_count, normalized_hash, old_index),
|
||||
)
|
||||
|
||||
first = rows[0]
|
||||
connection.execute(
|
||||
"""
|
||||
UPDATE sentences
|
||||
SET start_ms = ?, end_ms = ?, text = ?, language = ?,
|
||||
reference_speech_duration_ms = ?
|
||||
WHERE video_hash = ? AND sentence_index = ?
|
||||
""",
|
||||
(
|
||||
first.start_ms,
|
||||
first.end_ms,
|
||||
first.text,
|
||||
first.language,
|
||||
first.reference_speech_duration_ms,
|
||||
normalized_hash,
|
||||
sentence_index,
|
||||
),
|
||||
)
|
||||
for replacement in rows[1:]:
|
||||
connection.execute(
|
||||
"""
|
||||
INSERT INTO sentences (
|
||||
video_hash, sentence_index, start_ms, end_ms, text,
|
||||
language, reference_speech_duration_ms
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""",
|
||||
(
|
||||
normalized_hash,
|
||||
replacement.index,
|
||||
replacement.start_ms,
|
||||
replacement.end_ms,
|
||||
replacement.text,
|
||||
replacement.language,
|
||||
replacement.reference_speech_duration_ms,
|
||||
),
|
||||
)
|
||||
connection.execute(
|
||||
"UPDATE videos SET updated_at = ? WHERE video_hash = ?",
|
||||
(utc_now(), normalized_hash),
|
||||
)
|
||||
result_rows = connection.execute(
|
||||
"""
|
||||
SELECT * FROM sentences
|
||||
WHERE video_hash = ? AND sentence_index >= ? AND sentence_index < ?
|
||||
ORDER BY sentence_index
|
||||
""",
|
||||
(normalized_hash, sentence_index, sentence_index + len(rows)),
|
||||
).fetchall()
|
||||
|
||||
return [
|
||||
SentenceBoundary(
|
||||
index=row["sentence_index"],
|
||||
start_ms=row["start_ms"],
|
||||
end_ms=row["end_ms"],
|
||||
text=row["text"],
|
||||
language=row["language"],
|
||||
reference_speech_duration_ms=row["reference_speech_duration_ms"],
|
||||
)
|
||||
for row in result_rows
|
||||
]
|
||||
|
||||
def create_dub_share(
|
||||
self,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user