Navid Arabi commited on
Commit
edb5886
·
1 Parent(s): faa5405

add new ftp host

Browse files
components/dashboard_page.py CHANGED
@@ -5,15 +5,14 @@ from sqlalchemy import orm, func # Added func for count
5
 
6
  from components.header import Header
7
  from utils.logger import Logger # Changed from get_logger to Logger
8
- from utils.gdrive_downloader import PublicFolderAudioLoader
9
  from config import conf
10
  from utils.database import get_db
11
  from data.models import Annotation, AudioTrim, TTSData, AnnotationInterval # Added AnnotationInterval
12
  from data.repository.annotator_workload_repo import AnnotatorWorkloadRepo # For progress
13
 
14
  log = Logger() # Changed from get_logger() to Logger()
15
- LOADER = PublicFolderAudioLoader(conf.GDRIVE_API_KEY)
16
- GDRIVE_FOLDER = conf.GDRIVE_FOLDER
17
 
18
 
19
  class DashboardPage:
@@ -188,12 +187,12 @@ class DashboardPage:
188
  log.error(f"Error fetching progress for user {user_id}: {e}")
189
  return "Annotation Progress: Error" # Added label
190
 
191
- def download_voice_fn(folder_link, filename_to_load, autoplay_on_load=True): # Autoplay here is for the btn_load_voice click
192
  if not filename_to_load:
193
  return None, None, gr.update(value=None, autoplay=False)
194
  try:
195
  log.info(f"Downloading voice: {filename_to_load}, Autoplay: {autoplay_on_load}")
196
- sr, wav = LOADER.load_audio(folder_link, filename_to_load)
197
  return (sr, wav), (sr, wav.copy()), gr.update(value=(sr, wav), autoplay=autoplay_on_load)
198
  except Exception as e:
199
  log.error(f"GDrive download failed for {filename_to_load}: {e}")
@@ -602,7 +601,7 @@ class DashboardPage:
602
  outputs=self.interactive_ui_elements
603
  ).then(
604
  fn=download_voice_fn,
605
- inputs=[gr.State(GDRIVE_FOLDER), self.filename, gr.State(True)], # Autoplay TRUE
606
  outputs=[self.audio, self.original_audio_state, self.audio],
607
  ).then(
608
  fn=self._apply_multiple_trims_fn,
 
5
 
6
  from components.header import Header
7
  from utils.logger import Logger # Changed from get_logger to Logger
8
+ from utils.cloud_server_audio_loader import CloudServerAudioLoader
9
  from config import conf
10
  from utils.database import get_db
11
  from data.models import Annotation, AudioTrim, TTSData, AnnotationInterval # Added AnnotationInterval
12
  from data.repository.annotator_workload_repo import AnnotatorWorkloadRepo # For progress
13
 
14
  log = Logger() # Changed from get_logger() to Logger()
15
+ LOADER = CloudServerAudioLoader(conf.FTP_URL)
 
16
 
17
 
18
  class DashboardPage:
 
187
  log.error(f"Error fetching progress for user {user_id}: {e}")
188
  return "Annotation Progress: Error" # Added label
189
 
190
+ def download_voice_fn(filename_to_load, autoplay_on_load=True): # Autoplay here is for the btn_load_voice click
191
  if not filename_to_load:
192
  return None, None, gr.update(value=None, autoplay=False)
193
  try:
194
  log.info(f"Downloading voice: {filename_to_load}, Autoplay: {autoplay_on_load}")
195
+ sr, wav = LOADER.load_audio(filename_to_load)
196
  return (sr, wav), (sr, wav.copy()), gr.update(value=(sr, wav), autoplay=autoplay_on_load)
197
  except Exception as e:
198
  log.error(f"GDrive download failed for {filename_to_load}: {e}")
 
601
  outputs=self.interactive_ui_elements
602
  ).then(
603
  fn=download_voice_fn,
604
+ inputs=[self.filename, gr.State(True)], # Autoplay TRUE
605
  outputs=[self.audio, self.original_audio_state, self.audio],
606
  ).then(
607
  fn=self._apply_multiple_trims_fn,
config.py CHANGED
@@ -12,8 +12,7 @@ class Config(BaseSettings):
12
  DB_NAME: str = os.getenv("DB_NAME", "defaultdb")
13
  HF_TOKEN: str = os.environ.get("HF_TOKEN")
14
  HF_TTS_DS_REPO: str = os.environ.get("HF_TTS_DS_REPO")
15
- GDRIVE_API_KEY: str = os.environ.get("GDRIVE_API_KEY")
16
- GDRIVE_FOLDER: str = os.environ.get("GDRIVE_FOLDER")
17
 
18
  APP_TITLE: str = "Gooya TTS Annotation Tools"
19
 
 
12
  DB_NAME: str = os.getenv("DB_NAME", "defaultdb")
13
  HF_TOKEN: str = os.environ.get("HF_TOKEN")
14
  HF_TTS_DS_REPO: str = os.environ.get("HF_TTS_DS_REPO")
15
+ FTP_URL: str = os.environ.get("FTP_URL")
 
16
 
17
  APP_TITLE: str = "Gooya TTS Annotation Tools"
18
 
test/gdrive_test.py DELETED
@@ -1,22 +0,0 @@
1
- import gradio as gr
2
- from utils.gdrive_downloader import PublicFolderAudioLoader
3
- from config import conf
4
-
5
- LOADER = PublicFolderAudioLoader(conf.GDRIVE_API_KEY)
6
-
7
- def fetch_audio(folder_link, filename):
8
- sr, wav = LOADER.load_audio(folder_link, filename)
9
- return (sr, wav)
10
-
11
- demo = gr.Interface(
12
- fn=fetch_audio,
13
- inputs=[
14
- gr.Textbox(label="Folder URL or ID",
15
- value=conf.GDRIVE_FOLDER),
16
- gr.Textbox(label="Filename (e.g. 0001.wav)")
17
- ],
18
- outputs=gr.Audio(label="🔊 Audio"),
19
- )
20
-
21
- if __name__ == "__main__":
22
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
utils/cloud_server_audio_loader.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # cloud_server_audio_loader.py
2
+
3
+ import io
4
+ import requests
5
+ import numpy as np
6
+ from pydub import AudioSegment
7
+
8
+ class CloudServerAudioLoader:
9
+ def __init__(self, base_url: str) -> None:
10
+ if not base_url.endswith("/"):
11
+ base_url += "/"
12
+ self.base_url = base_url
13
+
14
+ def _download_to_buf(self, filename: str) -> io.BytesIO:
15
+ url = self.base_url + filename
16
+ resp = requests.get(url, stream=True)
17
+ if resp.status_code != 200:
18
+ raise FileNotFoundError(f"'{filename}' not found. HTTP {resp.status_code}")
19
+ buf = io.BytesIO(resp.content)
20
+ buf.seek(0)
21
+ return buf
22
+
23
+ def load_audio(self, filename: str) -> tuple[int, np.ndarray]:
24
+ buf = self._download_to_buf(filename)
25
+ seg = AudioSegment.from_file(buf)
26
+ samples = np.array(seg.get_array_of_samples())
27
+
28
+ if seg.channels > 1:
29
+ samples = samples.reshape(-1, seg.channels)
30
+
31
+ if np.issubdtype(samples.dtype, np.integer):
32
+ max_int = np.iinfo(samples.dtype).max
33
+ samples = samples.astype(np.float32)
34
+ samples /= max_int
35
+ else:
36
+ max_val = np.abs(samples).max()
37
+ if max_val > 1:
38
+ samples = samples / max_val
39
+ samples = samples.astype(np.float32)
40
+ # --------------------------------------------------------
41
+
42
+ return seg.frame_rate, samples
utils/gdrive_downloader.py DELETED
@@ -1,98 +0,0 @@
1
- # gdrive_downloader.py
2
-
3
- from __future__ import annotations
4
- import io
5
- import re
6
- import numpy as np
7
- from pydub import AudioSegment
8
- from googleapiclient.discovery import build
9
- from googleapiclient.http import MediaIoBaseDownload
10
-
11
-
12
- def extract_folder_id(url_or_id: str) -> str:
13
- """
14
- اگر کاربر لینک فولدر بدهد ← ID را برمی‌گرداند.
15
- اگر خودش ID باشد همان را برمی‌گرداند.
16
- """
17
- s = url_or_id.strip()
18
- if "/" not in s and "?" not in s:
19
- return s # احتمالاً خودش ID است
20
- m = re.search(r"/folders/([a-zA-Z0-9_-]{10,})", s)
21
- if not m:
22
- raise ValueError("Cannot extract folder id from url")
23
- return m.group(1)
24
-
25
-
26
- class PublicFolderAudioLoader:
27
- """
28
- دانلودر فایل صوتی از فولدر عمومی گوگل‌درایو بدون ذخیره روی دیسک.
29
-
30
- Parameters
31
- ----------
32
- api_key : str
33
- Google API Key (کیِ عمومی؛ نه OAuth, نه سرویس‌اکانت).
34
- """
35
-
36
- def __init__(self, api_key: str) -> None:
37
- self.svc = build("drive", "v3", developerKey=api_key, cache_discovery=False)
38
-
39
- # ---------- helpers ---------- #
40
- def _file_id_by_name(self, folder_id: str, filename: str) -> str:
41
- q = (
42
- f"'{folder_id}' in parents "
43
- f"and name = '{filename}' "
44
- f"and trashed = false"
45
- )
46
- rsp = (
47
- self.svc.files()
48
- .list(q=q, fields="files(id,name)", pageSize=5, supportsAllDrives=True)
49
- .execute()
50
- )
51
- files = rsp.get("files", [])
52
- if not files:
53
- raise FileNotFoundError(f"'{filename}' not found in folder {folder_id}")
54
- return files[0]["id"]
55
-
56
- def _download_to_buf(self, file_id: str) -> io.BytesIO:
57
- request = self.svc.files().get_media(fileId=file_id, supportsAllDrives=True)
58
- buf = io.BytesIO()
59
- downloader = MediaIoBaseDownload(buf, request)
60
- done = False
61
- while not done:
62
- _, done = downloader.next_chunk()
63
- buf.seek(0)
64
- return buf
65
-
66
- # ---------- public ---------- #
67
- def load_audio(
68
- self,
69
- folder_url_or_id: str,
70
- filename: str,
71
- ) -> tuple[int, np.ndarray]:
72
- # """
73
- # فایل را به `(sample_rate, np.ndarray)` نرمال‌شده در بازه‌ی [-1,1] تبدیل می‌کند.
74
- # """
75
- folder_id = extract_folder_id(folder_url_or_id)
76
- file_id = self._file_id_by_name(folder_id, filename)
77
- buf = self._download_to_buf(file_id)
78
- seg = AudioSegment.from_file(buf)
79
- samples = np.array(seg.get_array_of_samples())
80
-
81
- # اگر چندکاناله بود، شکل دهیم
82
- if seg.channels > 1:
83
- samples = samples.reshape(-1, seg.channels)
84
-
85
- # ---------------------- نرمال‌سازی ----------------------
86
- if np.issubdtype(samples.dtype, np.integer):
87
- max_int = np.iinfo(samples.dtype).max # ← قبل از cast
88
- samples = samples.astype(np.float32)
89
- samples /= max_int # ← از max_int استفاده می‌کنیم
90
- else:
91
- # در حالت float
92
- max_val = np.abs(samples).max()
93
- if max_val > 1:
94
- samples = samples / max_val
95
- samples = samples.astype(np.float32)
96
- # --------------------------------------------------------
97
-
98
- return seg.frame_rate, samples