Skip to content

Commit

Permalink
Fix Bug Multiple Entries
Browse files Browse the repository at this point in the history
Thks to jshsakura
  • Loading branch information
Leinad4Mind committed May 14, 2024
1 parent 07fa2c3 commit 177b3e2
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 119 deletions.
12 changes: 1 addition & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,6 @@ We help you download at the fastest possible speed without having to wait for ea
</p>
<br/>
<br/>
<p align="center">
<img src="https://raw.githubusercontent.com/leinad4mind/1fichier-dl/main/screenshots/preview_settings1.png"></img>
</p>

<p align="center">
<b>Supports multiple simultaneous downloads and can be increased or decreased depending on the environment.</b>
</p>
<br/>
<br/>

## 😼 Introduction to key features

Expand All @@ -66,8 +57,6 @@ We help you download at the fastest possible speed without having to wait for ea

⭐ In addition to the `1ficher` link, when you directly enter a shortened `URL` such as `ouo.io`, an automatic link that bypasses `reCAPTCHA` is added.

⭐ Supports simultaneous proxy downloads using `Threading` (basic 3 experimental)

⭐ The default download folder path is the Windows ‘Download’ folder.

_Your life is short. Don't wait any longer._
Expand Down Expand Up @@ -115,6 +104,7 @@ _Your life is short. Don't wait any longer._
- Added exception handling when adding duplicate downloads with the same file name (processing required after actual 1fichier URL parsing)
- Supports asynchronous download using `Asyncio` instead of `Threading`, which is slow when downloading simultaneously (increases speed)
- In addition to the basic specification ‘1ficher’, it is necessary to check whether programs from other similar download sites are supported.
- Supports simultaneous proxy downloads using `Threading`
<br/>
<br/>

Expand Down
1 change: 1 addition & 0 deletions build command.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pyinstaller --windowed --noconsole --onefile --noconfirm --clean --hiddenimport=_cffi_backend --additional-hooks-dir=. --icon=core/gui/res/ico.ico --add-data "core/gui/res/*.*;res/" .\1fichier-dl.py
2 changes: 1 addition & 1 deletion core/download/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ def get_link_info(url: str) -> list:
return [name, size]
except:
logging.debug(__name__+' Exception')
return None
return ['Error', '- MB']


def is_valid_link(url: str) -> bool:
Expand Down
183 changes: 104 additions & 79 deletions core/download/workers.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,90 +36,115 @@ def __init__(self, actions, cached_download='', password=''):
@pyqtSlot()
def run(self):
self.valid_links = []

if isinstance(self.links, str):
self.valid_links = [self.links]
else:
links = self.links.toPlainText().splitlines()
for link in links:
logging.debug('valid_links:'+str(link.strip()))
# If the shortened URL is ouo bypass, recaptcha bypass
if 'ouo.io' in link:
link = ouo_bypass(url=link)['bypassed_link']
logging.debug('bypassed link: ' + str(link))

link = link.strip()
if is_valid_link(link):
if not 'https://' in link[0:8] and not 'http://' in link[0:7]:
link = f'https://{link}'
if '&' in link:
link = link.split('&')[0]
self.valid_links.append(link)

if not self.valid_links:
self.signals.alert_signal.emit(
'The link(s) you inserted were not valid.')
self.invalid_links = []

try:
if self.links.toPlainText():
links = self.links.toPlainText().splitlines()
for link in links:
link = link.strip()
logging.debug('Processing link: ' + str(link))
# If the shortened URL is ouo bypass, recaptcha bypass
try:
if 'ouo.io' in link:
bypassed = ouo_bypass(url=link)
link = bypassed['bypassed_link']
logging.debug('Bypassed link: ' + str(link))
except Exception as e:
logging.error(f"Failed to bypass ouo.io link {link}: {e}")
self.invalid_links.append(link)
continue

# Link validation
try:
if is_valid_link(link):
if not (link.startswith('https://') or link.startswith('http://')):
link = f'https://{link}'
link = link.split('&')[0]
self.valid_links.append(link)
else:
raise ValueError(f'Invalid link format: {link}')
except ValueError as ve:
logging.warning(ve)
self.invalid_links.append(link)
self.signals.alert_signal.emit(f'Invalid link format: {link}')
continue # Continue to next link

if len(self.invalid_links) > 0 :
self.gui.hide_loading_overlay()
# Reset link input window
self.gui.add_btn.setEnabled(True)
self.gui.links.setEnabled(True)
self.gui.password.setEnabled(True)

for link in self.valid_links:
if '/dir/' in link:
folder = requests.get(f'{link}?json=1')
folder = folder.json()
for f in folder:
link = f['link']
info = [f['filename'], convert_size(int(f['size']))]
info.extend(['Added', None, '0 B/s', ''])
row = []

for val in info:
data = QStandardItem(val)
data.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(data)

if f['password'] == 1:
password = QStandardItem(self.password)
row.append(password)
self.gui.hide_loading_overlay()
else:
no_password = QStandardItem('No password')
no_password.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(no_password)

self.signals.download_signal.emit(
row, link, True, self.dl_name, self.progress)
if self.cached_download:
self.cached_downloads.remove(self.cached_download)
else:
info = get_link_info(link)
if info is not None:
is_private = True if info[0] == 'Private File' else False
info[0] = self.dl_name if self.dl_name else info[0]
info.extend(['Added', None, '0 B/s', ''])
row = []

for val in info:
data = QStandardItem(val)
data.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(data)

if is_private:
password = QStandardItem(self.password)
row.append(password)
self.gui.hide_loading_overlay()
else:
no_password = QStandardItem('No password')
no_password.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(no_password)

self.signals.download_signal.emit(
row, link, True, self.dl_name, self.progress)
if self.cached_download:
self.cached_downloads.remove(self.cached_download)

# 링크 추가 문구 원복
self.gui.add_links_complete()
else :
for link in self.valid_links:
try:
if '/dir/' in link:
folder = requests.get(f'{link}?json=1')
folder = folder.json()
for f in folder:
link = f['link']
info = [f['filename'], convert_size(int(f['size']))]
info.extend(['Waiting', None, '0 B/s', ''])
row = []

for val in info:
data = QStandardItem(val)
data.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(data)

if f['password'] == 1:
password = QStandardItem(self.password)
row.append(password)
self.gui.hide_loading_overlay()
else:
no_password = QStandardItem('No password')
no_password.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(no_password)

self.signals.download_signal.emit(
row, link, True, self.dl_name, self.progress)
if self.cached_download:
self.cached_downloads.remove(self.cached_download)
else:
info = get_link_info(link)
if info is not None:
# parsing Avoid errors
if info[0] == 'Error':
self.signals.alert_signal.emit(f'We couldn\'t get the actual information for the file to download.\n{link}')
self.gui.hide_loading_overlay()
else:
is_private = True if info[0] == 'Private File' else False
info[0] = self.dl_name if self.dl_name else info[0]
info.extend(['Waiting', None, '0 B/s', ''])
row = []

for val in info:
data = QStandardItem(val)
data.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(data)

if is_private:
password = QStandardItem(self.password)
row.append(password)
self.gui.hide_loading_overlay()
else:
no_password = QStandardItem('No password')
no_password.setFlags(data.flags() & ~Qt.ItemIsEditable)
row.append(no_password)

self.signals.download_signal.emit(
row, link, True, self.dl_name, self.progress)
if self.cached_download:
self.cached_downloads.remove(self.cached_download)
except Exception as e:
logging.error(f"Error processing link {link}: {e}")
continue

except Exception as e:
logging.error(f"Unexpected error in run method: {e}")

class DownloadWorker(QRunnable):
def __init__(self, link, table_model, data, settings, dl_name=''):
Expand Down
92 changes: 68 additions & 24 deletions core/gui/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def __init__(self, gui):
self.filter_thread = QThreadPool()
self.download_thread = QThreadPool()
# Limits concurrent downloads to 1.
self.download_thread.setMaxThreadCount(3)
self.download_thread.setMaxThreadCount(1)
self.download_workers = []
self.gui = gui
self.handle_init()
Expand Down Expand Up @@ -283,19 +283,47 @@ def change_theme(self, theme=None):
qdarktheme.setup_theme("dark")
# self.gui.app.setPalette(dark_theme)

def get_language(self):
language = os.getenv('LANGUAGE') or 'en' # Get language from environment variable
return language

def set_language(self, language=None):
if language:
self.gui.theme_select.setCurrentIndex(language)

if(self.gui.theme_select.currentIndex()) :
return 'kr'
else :
return 'en'

def load_messages(self, language):
messages = {}
messages_file = f'messages_{language}.txt'

with open(messages_file, 'r', encoding='utf-8') as f:
for line in f:
key, value = line.strip().split(',')
messages[key] = value

return messages

def save_settings(self):
with open(abs_config('app/settings'), 'wb') as f:
settings = []
settings.append(self.gui.dl_directory_input.text())
# Download Directory - 0
settings.append(self.gui.dl_directory_input.text())
# Theme - 1
settings.append(self.gui.theme_select.currentIndex())
settings.append(self.gui.timeout_input.value())
# Timeout - 2
settings.append(self.gui.timeout_input.value())
# Proxy Settings - 3
settings.append(self.gui.proxy_settings_input.text())
# Number of multi downloads
settings.append(self.gui.thread_input.value())
# Thread Settings - 4
settings.append(1)
# settings.append(self.gui.thread_input.value())
# Select language
# Lang Settings - 5
# settings.append(self.gui.lang_select.currentIndex())
pickle.dump(settings, f)
self.settings = settings
self.gui.settings.hide()
Expand Down Expand Up @@ -549,6 +577,15 @@ def settings_win(self):
vbox.setAlignment(Qt.AlignTop)
form_layout = QFormLayout()

# Change Lang
# form_layout.addRow(QLabel('Language:'))

# self.lang_select = QComboBox()
# self.lang_select.addItems(['Korean', 'English'])
# self.lang_select.currentIndexChanged.connect(
# self.actions.set_language)
# form_layout.addRow(self.lang_select)

# Change Directory
form_layout.addRow(QLabel('Download directory:'))

Expand Down Expand Up @@ -594,14 +631,14 @@ def settings_win(self):
form_layout_c = QFormLayout()

# Timeout
form_layout_c.addRow(QLabel('Timeout (Default 30s):'))
self.timeout_input = QSpinBox()
if self.actions.settings is not None:
self.timeout_input.setValue(self.actions.settings[2])
else:
self.timeout_input.setValue(30)
# form_layout_c.addRow(QLabel('Timeout (Default 30s):'))
# self.timeout_input = QSpinBox()
# if self.actions.settings is not None:
# self.timeout_input.setValue(self.actions.settings[2])
# else:
# self.timeout_input.setValue(30)

form_layout_c.addRow(self.timeout_input)
# form_layout_c.addRow(self.timeout_input)

# Proxy settings
form_layout_c.addRow(QLabel('Enter proxy list directly:'))
Expand Down Expand Up @@ -668,17 +705,24 @@ def add_links_complete(self):
self.links.clear()

def add_to_download_list(self):
# Disable the 'Add to download list' button.
self.add_btn.setText("Adding to download list...")
self.add_btn.setEnabled(False)

# It takes the entered link and converts it into a list.
links_text = self.links.toPlainText()
download_links = links_text.split('\n')
self.links.setDisabled(True)
self.password.setDisabled(True)

for link in download_links:
if link.strip(): # Append only if the line is not blank.
# Use 'add_links' to add download links.
self.actions.add_links(link)

if(links_text) :
add_links_texts = []
# Disable the 'Add to download list' button.
self.add_btn.setText("Adding to download list...")
self.add_btn.setEnabled(False)

download_links = links_text.split('\n')
self.links.setDisabled(True)
self.password.setDisabled(True)

for link in download_links:
if link.strip(): # Append only if the line is not blank.
add_links_texts.append(link)

# Use 'add_links' to add download links.
self.actions.add_links('\n'.join(add_links_texts))
else:
alert('Please enter a list of download links.')
7 changes: 4 additions & 3 deletions https_proxy_list.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
https://raw.githubusercontent.com/r00tee/Proxy-List/main/Https.txt
https://raw.githubusercontent.com/r00tee/Proxy-List/main/Socks5.txt
https://raw.githubusercontent.com/Zaeem20/FREE_PROXIES_LIST/master/https.txt
https://raw.githubusercontent.com/roosterkid/openproxylist/main/HTTPS_RAW.txt
https://raw.githubusercontent.com/ErcinDedeoglu/proxies/main/proxies/https.txt
https://raw.githubusercontent.com/casals-ar/proxy.casals.ar/main/https
https://raw.githubusercontent.com/SevenworksDev/proxy-list/main/proxies/https.txt
https://raw.githubusercontent.com/ErcinDedeoglu/proxies/main/proxies/https.txt
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
PyQt5==5.15.9
PyQt5
lxml==4.9.3
curl_cffi==0.5.7
urllib3==2.0.4
requests
beautifulsoup4
pyqtdarktheme
pyinstaller==5.13.2
#pyinstaller==5.13.0 # python -m pip uninstall pyinstalle, python ./waf all --target-arch=64bit

0 comments on commit 177b3e2

Please sign in to comment.