NeoPy commited on
Commit
8b0f313
Β·
verified Β·
1 Parent(s): a021395

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +187 -64
app.py CHANGED
@@ -1,81 +1,204 @@
1
  import gradio as gr
2
  import requests
 
3
  import re
4
- from urllib.parse import urlparse
5
  import os
 
 
6
 
7
- def validate_url(url):
8
- """Validate if the URL is a valid soundgasm.net link."""
9
- pattern = r'^https?://soundgasm\.net/u/[\w-]+/[\w-]+'
10
- return bool(re.match(pattern, url.strip()))
11
-
12
- def extract_audio_url(page_content):
13
- """Extract the direct audio URL from the Soundgasm page content."""
14
- audio_pattern = r'(https?://media\.soundgasm\.net/sounds/[\w-]+\.(?:mp3|m4a))'
15
- match = re.search(audio_pattern, page_content)
16
- return match.group(1) if match else None
17
-
18
- def download_audio(url):
19
- """Download audio from a soundgasm.net link."""
20
  try:
21
- # Validate URL
22
- if not validate_url(url):
23
- return "Invalid Soundgasm.net URL. Please provide a valid link."
24
-
25
- # Get the page content
26
- headers = {
27
- 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
28
- }
29
- response = requests.get(url.strip(), headers=headers, timeout=10)
30
  response.raise_for_status()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- # Extract audio URL
33
- audio_url = extract_audio_url(response.text)
34
- if not audio_url:
35
- return "Could not find audio file in the provided link."
36
-
37
- # Download the audio
38
- audio_response = requests.get(audio_url, headers=headers, stream=True, timeout=10)
39
- audio_response.raise_for_status()
40
-
41
- # Extract filename from URL
42
- parsed_url = urlparse(audio_url)
43
- filename = os.path.basename(parsed_url.path)
44
-
45
- # Save the audio file temporarily
46
- temp_dir = "downloads"
47
- os.makedirs(temp_dir, exist_ok=True)
48
- file_path = os.path.join(temp_dir, filename)
49
-
50
- with open(file_path, 'wb') as f:
51
- for chunk in audio_response.iter_content(chunk_size=8192):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  if chunk:
53
  f.write(chunk)
54
-
55
- return file_path
56
-
57
- except requests.exceptions.RequestException as e:
58
- return f"Error downloading audio: {str(e)}"
 
 
 
 
59
  except Exception as e:
60
- return f"An unexpected error occurred: {str(e)}"
61
-
62
- # Gradio Blocks UI
63
- with gr.Blocks(title="Soundgasm Audio Downloader") as demo:
64
- gr.Markdown("# Soundgasm Audio Downloader")
65
- gr.Markdown("Enter a Soundgasm.net link to download the audio file.")
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  with gr.Row():
68
- url_input = gr.Textbox(label="Soundgasm URL", placeholder="https://soundgasm.net/u/username/audio-title")
69
- download_button = gr.Button("Download Audio")
70
-
71
- output = gr.File(label="Downloaded Audio")
72
- error_message = gr.Textbox(label="Status", interactive=False)
73
-
74
- download_button.click(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  fn=download_audio,
76
- inputs=url_input,
77
- outputs=[output, error_message]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  )
79
 
80
  if __name__ == "__main__":
81
- demo.launch()
 
 
1
  import gradio as gr
2
  import requests
3
+ from bs4 import BeautifulSoup
4
  import re
 
5
  import os
6
+ import tempfile
7
+ from urllib.parse import urlparse
8
 
9
+ def get_audio_url(url):
10
+ """Extract audio URL from soundgasm.net page"""
 
 
 
 
 
 
 
 
 
 
 
11
  try:
12
+ response = requests.get(url)
 
 
 
 
 
 
 
 
13
  response.raise_for_status()
14
+ soup = BeautifulSoup(response.text, 'html.parser')
15
+
16
+ # Try to find the audio source from the <audio> tag directly
17
+ audio_tag = soup.find('audio', {'id': 'jp_audio_0'})
18
+ if audio_tag and 'src' in audio_tag.attrs:
19
+ return audio_tag['src']
20
+
21
+ # If not found, try to extract from the JavaScript part
22
+ script_tags = soup.find_all('script')
23
+ for script in script_tags:
24
+ if script.string:
25
+ match = re.search(r'm4a: "(https://media.soundgasm.net/sounds/[a-f0-9]+\.m4a)"', script.string)
26
+ if match:
27
+ return match.group(1)
28
+ return None
29
+ except Exception as e:
30
+ print(f"Error extracting audio URL: {e}")
31
+ return None
32
 
33
+ def get_audio_title(url):
34
+ """Extract audio title from soundgasm.net page"""
35
+ try:
36
+ response = requests.get(url)
37
+ response.raise_for_status()
38
+ soup = BeautifulSoup(response.text, 'html.parser')
39
+
40
+ title_element = soup.find('div', class_='jp-title')
41
+ if title_element:
42
+ return title_element.get_text(strip=True)
43
+ return "Unknown Title"
44
+ except Exception as e:
45
+ print(f"Error extracting title: {e}")
46
+ return "Unknown Title"
47
+
48
+ def download_audio(url, progress=gr.Progress()):
49
+ """Download audio from soundgasm.net URL"""
50
+ if not url:
51
+ return None, "Please enter a valid soundgasm.net URL"
52
+
53
+ if "soundgasm.net" not in url:
54
+ return None, "Please enter a valid soundgasm.net URL"
55
+
56
+ progress(0.1, desc="Extracting audio URL...")
57
+
58
+ # Get audio URL
59
+ audio_url = get_audio_url(url)
60
+ if not audio_url:
61
+ return None, "Could not find audio URL on the page. Please check if the URL is correct."
62
+
63
+ progress(0.3, desc="Getting audio title...")
64
+
65
+ # Get audio title for filename
66
+ title = get_audio_title(url)
67
+ safe_title = re.sub(r'[^\w\s-]', '', title).strip()
68
+ safe_title = re.sub(r'[-\s]+', '-', safe_title)
69
+
70
+ progress(0.5, desc="Downloading audio...")
71
+
72
+ try:
73
+ # Download the audio file
74
+ response = requests.get(audio_url, stream=True)
75
+ response.raise_for_status()
76
+
77
+ # Create temporary file
78
+ temp_dir = tempfile.gettempdir()
79
+ filename = f"{safe_title}.m4a"
80
+ filepath = os.path.join(temp_dir, filename)
81
+
82
+ total_size = int(response.headers.get('content-length', 0))
83
+ downloaded = 0
84
+
85
+ with open(filepath, 'wb') as f:
86
+ for chunk in response.iter_content(chunk_size=8192):
87
  if chunk:
88
  f.write(chunk)
89
+ downloaded += len(chunk)
90
+ if total_size > 0:
91
+ progress_val = 0.5 + (downloaded / total_size) * 0.4
92
+ progress(progress_val, desc=f"Downloading... {downloaded}/{total_size} bytes")
93
+
94
+ progress(1.0, desc="Download complete!")
95
+
96
+ return filepath, f"Successfully downloaded: {title}"
97
+
98
  except Exception as e:
99
+ return None, f"Error downloading audio: {str(e)}"
 
 
 
 
 
100
 
101
+ def validate_url(url):
102
+ """Validate if the URL is a valid soundgasm.net URL"""
103
+ if not url:
104
+ return "Please enter a URL"
105
+
106
+ if "soundgasm.net" not in url:
107
+ return "Please enter a valid soundgasm.net URL"
108
+
109
+ try:
110
+ parsed = urlparse(url)
111
+ if not parsed.scheme or not parsed.netloc:
112
+ return "Please enter a valid URL with http:// or https://"
113
+ except:
114
+ return "Invalid URL format"
115
+
116
+ return ""
117
+
118
+ # Create Gradio interface
119
+ with gr.Blocks(title="Soundgasm Audio Downloader", theme=gr.themes.Soft()) as demo:
120
+ gr.Markdown(
121
+ """
122
+ # 🎡 Soundgasm Audio Downloader
123
+
124
+ Download audio files from soundgasm.net links using only requests and BeautifulSoup4.
125
+
126
+ **Instructions:**
127
+ 1. Paste a soundgasm.net audio URL in the input field
128
+ 2. Click "Download Audio" to start the download
129
+ 3. The audio file will be available for download once processing is complete
130
+
131
+ **Supported URLs:** `https://soundgasm.net/u/username/audio-title`
132
+ """
133
+ )
134
+
135
  with gr.Row():
136
+ with gr.Column(scale=3):
137
+ url_input = gr.Textbox(
138
+ label="Soundgasm URL",
139
+ placeholder="https://soundgasm.net/u/username/audio-title",
140
+ lines=1
141
+ )
142
+
143
+ url_validation = gr.Textbox(
144
+ label="URL Validation",
145
+ interactive=False,
146
+ visible=False
147
+ )
148
+
149
+ with gr.Column(scale=1):
150
+ download_btn = gr.Button("Download Audio", variant="primary", size="lg")
151
+
152
+ with gr.Row():
153
+ status_output = gr.Textbox(
154
+ label="Status",
155
+ interactive=False,
156
+ lines=2
157
+ )
158
+
159
+ with gr.Row():
160
+ file_output = gr.File(
161
+ label="Downloaded Audio File",
162
+ file_count="single",
163
+ file_types=[".m4a", ".mp3", ".wav"]
164
+ )
165
+
166
+ # Event handlers
167
+ url_input.change(
168
+ fn=validate_url,
169
+ inputs=[url_input],
170
+ outputs=[url_validation]
171
+ )
172
+
173
+ download_btn.click(
174
  fn=download_audio,
175
+ inputs=[url_input],
176
+ outputs=[file_output, status_output],
177
+ show_progress=True
178
+ )
179
+
180
+ # Example URLs
181
+ gr.Markdown(
182
+ """
183
+ ### Example URLs:
184
+ - `https://soundgasm.net/u/aasimaraudio/Let-Me-Help-You-Relieve-Your-Work-Related-Stress-Will-Ya`
185
+ - `https://soundgasm.net/u/username/audio-title`
186
+
187
+ ### Features:
188
+ - βœ… Extract audio URLs using requests and BeautifulSoup4
189
+ - βœ… Download audio files in original quality
190
+ - βœ… Automatic filename generation from audio title
191
+ - βœ… Progress tracking during download
192
+ - βœ… Error handling and validation
193
+
194
+ ### Technical Details:
195
+ - Uses only `requests` and `bs4` libraries as requested
196
+ - Extracts audio URLs from HTML and JavaScript content
197
+ - Supports m4a audio format (soundgasm's default format)
198
+ - No external dependencies beyond the specified libraries
199
+ """
200
  )
201
 
202
  if __name__ == "__main__":
203
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=False)
204
+