Update app.py
Browse files
app.py
CHANGED
@@ -4,7 +4,6 @@ import os
|
|
4 |
from dotenv import load_dotenv
|
5 |
import re
|
6 |
import requests
|
7 |
-
import shutil
|
8 |
|
9 |
# Load environment variables
|
10 |
load_dotenv()
|
@@ -16,10 +15,7 @@ INSTAGRAM_PASSWORD = os.getenv('INSTAGRAM_PASSWORD')
|
|
16 |
def clean_url(url):
|
17 |
"""Clean Instagram URL and extract shortcode"""
|
18 |
try:
|
19 |
-
# Remove query parameters and fragments
|
20 |
cleaned_url = url.split('?')[0].split('#')[0].strip('/')
|
21 |
-
|
22 |
-
# Extract shortcode using regex
|
23 |
patterns = [
|
24 |
r'instagram.com/reel/([A-Za-z0-9_-]+)',
|
25 |
r'instagram.com/p/([A-Za-z0-9_-]+)',
|
@@ -31,7 +27,6 @@ def clean_url(url):
|
|
31 |
if match:
|
32 |
return match.group(1)
|
33 |
|
34 |
-
# If patterns don't match, try getting the last segment
|
35 |
segments = cleaned_url.split('/')
|
36 |
if segments:
|
37 |
return segments[-1]
|
@@ -47,13 +42,9 @@ def download_file(url, path):
|
|
47 |
response = requests.get(url, stream=True)
|
48 |
response.raise_for_status()
|
49 |
|
50 |
-
# Get file size for progress bar
|
51 |
file_size = int(response.headers.get('content-length', 0))
|
52 |
-
|
53 |
-
# Create progress bar
|
54 |
progress_bar = st.progress(0)
|
55 |
|
56 |
-
# Download with progress updates
|
57 |
with open(path, 'wb') as f:
|
58 |
if file_size == 0:
|
59 |
f.write(response.content)
|
@@ -74,16 +65,14 @@ def download_file(url, path):
|
|
74 |
def download_reel(url):
|
75 |
"""Download Instagram reel"""
|
76 |
if not url:
|
77 |
-
return "Please enter a URL"
|
78 |
|
79 |
-
# Clean URL and extract shortcode
|
80 |
shortcode = clean_url(url)
|
81 |
if not shortcode:
|
82 |
-
return "Could not extract valid shortcode from URL"
|
83 |
|
84 |
st.info(f"Extracted shortcode: {shortcode}")
|
85 |
|
86 |
-
# Initialize loader with debugging
|
87 |
loader = instaloader.Instaloader(
|
88 |
download_videos=True,
|
89 |
download_video_thumbnails=False,
|
@@ -94,70 +83,58 @@ def download_reel(url):
|
|
94 |
)
|
95 |
|
96 |
try:
|
97 |
-
# Login
|
98 |
if INSTAGRAM_USERNAME and INSTAGRAM_PASSWORD:
|
99 |
st.info(f"Logging in as {INSTAGRAM_USERNAME}...")
|
100 |
loader.login(INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD)
|
101 |
st.success("Login successful!")
|
102 |
else:
|
103 |
-
return "Missing Instagram credentials"
|
104 |
|
105 |
-
# Create download directory
|
106 |
download_path = os.path.join('reels', shortcode)
|
107 |
os.makedirs(download_path, exist_ok=True)
|
108 |
-
st.info(f"Download directory created: {os.path.abspath(download_path)}")
|
109 |
|
110 |
-
# Get post metadata
|
111 |
st.info("Fetching post metadata...")
|
112 |
post = instaloader.Post.from_shortcode(loader.context, shortcode)
|
113 |
|
114 |
-
# Debug post information
|
115 |
-
st.info(f"Post type: {post.typename}")
|
116 |
-
st.info(f"Is video: {post.is_video}")
|
117 |
-
|
118 |
if post.is_video:
|
119 |
-
# Get video URL
|
120 |
video_url = post.video_url
|
121 |
-
st.info("Video URL obtained")
|
122 |
-
|
123 |
-
# Download video file
|
124 |
video_path = os.path.join(download_path, f"{shortcode}.mp4")
|
125 |
-
st.info("Starting
|
126 |
|
127 |
if download_file(video_url, video_path):
|
128 |
-
# Verify file exists and has size
|
129 |
if os.path.exists(video_path):
|
130 |
size = os.path.getsize(video_path)
|
131 |
if size > 0:
|
132 |
-
return f"
|
133 |
-
Location: {video_path}
|
134 |
-
Size: {size/1024/1024:.2f} MB"""
|
135 |
else:
|
136 |
-
return "Download failed: File is empty"
|
137 |
else:
|
138 |
-
return "Download failed: File not created"
|
139 |
else:
|
140 |
-
return "Failed to download video file"
|
141 |
else:
|
142 |
-
return "Post is not a video"
|
143 |
|
144 |
except instaloader.exceptions.InstaloaderException as e:
|
145 |
-
return f"Instagram error: {str(e)}"
|
146 |
except Exception as e:
|
147 |
-
return f"Unexpected error: {str(e)}
|
148 |
|
149 |
def main():
|
150 |
st.set_page_config(
|
151 |
page_title="Instagram Reel Downloader",
|
152 |
-
page_icon="📱"
|
|
|
153 |
)
|
154 |
|
155 |
st.title('📱 Instagram Reel Downloader')
|
156 |
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
|
|
|
|
161 |
|
162 |
# Input for Reel URL
|
163 |
url = st.text_input('Enter the Instagram Reel URL',
|
@@ -166,20 +143,19 @@ def main():
|
|
166 |
# Download button
|
167 |
if st.button('Download Reel', type='primary'):
|
168 |
if url:
|
169 |
-
with st.spinner('
|
170 |
-
|
171 |
-
st.write(
|
172 |
|
173 |
-
#
|
174 |
-
if os.path.exists(
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
st.write(f"{subindent}{f}")
|
183 |
else:
|
184 |
st.warning('Please enter a URL.')
|
185 |
|
|
|
4 |
from dotenv import load_dotenv
|
5 |
import re
|
6 |
import requests
|
|
|
7 |
|
8 |
# Load environment variables
|
9 |
load_dotenv()
|
|
|
15 |
def clean_url(url):
|
16 |
"""Clean Instagram URL and extract shortcode"""
|
17 |
try:
|
|
|
18 |
cleaned_url = url.split('?')[0].split('#')[0].strip('/')
|
|
|
|
|
19 |
patterns = [
|
20 |
r'instagram.com/reel/([A-Za-z0-9_-]+)',
|
21 |
r'instagram.com/p/([A-Za-z0-9_-]+)',
|
|
|
27 |
if match:
|
28 |
return match.group(1)
|
29 |
|
|
|
30 |
segments = cleaned_url.split('/')
|
31 |
if segments:
|
32 |
return segments[-1]
|
|
|
42 |
response = requests.get(url, stream=True)
|
43 |
response.raise_for_status()
|
44 |
|
|
|
45 |
file_size = int(response.headers.get('content-length', 0))
|
|
|
|
|
46 |
progress_bar = st.progress(0)
|
47 |
|
|
|
48 |
with open(path, 'wb') as f:
|
49 |
if file_size == 0:
|
50 |
f.write(response.content)
|
|
|
65 |
def download_reel(url):
|
66 |
"""Download Instagram reel"""
|
67 |
if not url:
|
68 |
+
return None, "Please enter a URL"
|
69 |
|
|
|
70 |
shortcode = clean_url(url)
|
71 |
if not shortcode:
|
72 |
+
return None, "Could not extract valid shortcode from URL"
|
73 |
|
74 |
st.info(f"Extracted shortcode: {shortcode}")
|
75 |
|
|
|
76 |
loader = instaloader.Instaloader(
|
77 |
download_videos=True,
|
78 |
download_video_thumbnails=False,
|
|
|
83 |
)
|
84 |
|
85 |
try:
|
|
|
86 |
if INSTAGRAM_USERNAME and INSTAGRAM_PASSWORD:
|
87 |
st.info(f"Logging in as {INSTAGRAM_USERNAME}...")
|
88 |
loader.login(INSTAGRAM_USERNAME, INSTAGRAM_PASSWORD)
|
89 |
st.success("Login successful!")
|
90 |
else:
|
91 |
+
return None, "Missing Instagram credentials"
|
92 |
|
|
|
93 |
download_path = os.path.join('reels', shortcode)
|
94 |
os.makedirs(download_path, exist_ok=True)
|
|
|
95 |
|
|
|
96 |
st.info("Fetching post metadata...")
|
97 |
post = instaloader.Post.from_shortcode(loader.context, shortcode)
|
98 |
|
|
|
|
|
|
|
|
|
99 |
if post.is_video:
|
|
|
100 |
video_url = post.video_url
|
|
|
|
|
|
|
101 |
video_path = os.path.join(download_path, f"{shortcode}.mp4")
|
102 |
+
st.info("Starting download...")
|
103 |
|
104 |
if download_file(video_url, video_path):
|
|
|
105 |
if os.path.exists(video_path):
|
106 |
size = os.path.getsize(video_path)
|
107 |
if size > 0:
|
108 |
+
return video_path, f"Download successful! Size: {size/1024/1024:.2f} MB"
|
|
|
|
|
109 |
else:
|
110 |
+
return None, "Download failed: File is empty"
|
111 |
else:
|
112 |
+
return None, "Download failed: File not created"
|
113 |
else:
|
114 |
+
return None, "Failed to download video file"
|
115 |
else:
|
116 |
+
return None, "Post is not a video"
|
117 |
|
118 |
except instaloader.exceptions.InstaloaderException as e:
|
119 |
+
return None, f"Instagram error: {str(e)}"
|
120 |
except Exception as e:
|
121 |
+
return None, f"Unexpected error: {str(e)}"
|
122 |
|
123 |
def main():
|
124 |
st.set_page_config(
|
125 |
page_title="Instagram Reel Downloader",
|
126 |
+
page_icon="📱",
|
127 |
+
initial_sidebar_state="collapsed"
|
128 |
)
|
129 |
|
130 |
st.title('📱 Instagram Reel Downloader')
|
131 |
|
132 |
+
st.markdown("""
|
133 |
+
### Instructions:
|
134 |
+
1. Enter the Instagram reel URL
|
135 |
+
2. Click 'Download Reel'
|
136 |
+
3. After successful download, click 'Download Video' button to save the file
|
137 |
+
""")
|
138 |
|
139 |
# Input for Reel URL
|
140 |
url = st.text_input('Enter the Instagram Reel URL',
|
|
|
143 |
# Download button
|
144 |
if st.button('Download Reel', type='primary'):
|
145 |
if url:
|
146 |
+
with st.spinner('Processing...'):
|
147 |
+
file_path, message = download_reel(url)
|
148 |
+
st.write(message)
|
149 |
|
150 |
+
# If download was successful, show download button
|
151 |
+
if file_path and os.path.exists(file_path):
|
152 |
+
with open(file_path, 'rb') as file:
|
153 |
+
st.download_button(
|
154 |
+
label="Download Video",
|
155 |
+
data=file,
|
156 |
+
file_name=os.path.basename(file_path),
|
157 |
+
mime="video/mp4"
|
158 |
+
)
|
|
|
159 |
else:
|
160 |
st.warning('Please enter a URL.')
|
161 |
|