diff --git a/.gitignore b/.gitignore index 534dc86..a09db3e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ __pycache__ build* -*.spec \ No newline at end of file +*.spec +/config.json \ No newline at end of file diff --git a/GUI/MainWindow.ui b/GUI/MainWindow.ui index b970a90..b9ec680 100644 --- a/GUI/MainWindow.ui +++ b/GUI/MainWindow.ui @@ -47,15 +47,15 @@ - Century Gothic - 20 + Comic Sans MS + 22 - Newgrounds Audio Downloader by H1K0 + <strong>Newgrounds Audio Downloader</strong> by <em>H1K0</em> - Qt::AlignCenter + Qt::AlignBottom|Qt::AlignHCenter @@ -69,7 +69,7 @@ - Courier New + Maiandra GD 12 @@ -83,7 +83,7 @@ true - + 20 @@ -101,11 +101,14 @@ PointingHandCursor + + (Enter) + Download! - Return + Ctrl+S @@ -115,9 +118,33 @@ 0 0 600 - 21 + 23 + + + Century Gothic + 10 + + + + + + Century Gothic + 9 + + + + ArrowCursor + + + MENU + + + + + + @@ -135,6 +162,36 @@ F1 + + + + ../settings.ico../settings.ico + + + Settings + + + + Century Gothic + 10 + + + + Alt+S + + + + + + ../help.ico../help.ico + + + Help + + + F1 + + diff --git a/GUI/NotificationDialog.ui b/GUI/NotificationDialog.ui index 3618756..1231cbc 100644 --- a/GUI/NotificationDialog.ui +++ b/GUI/NotificationDialog.ui @@ -10,6 +10,24 @@ 150 + + + 0 + 0 + + + + + 400 + 150 + + + + + 400 + 150 + + ACHTUNG! @@ -28,12 +46,12 @@ - Century Gothic + Maiandra GD 16 - TextLabel + ACHTUNG! Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop diff --git a/GUI/ProgressDialog.ui b/GUI/ProgressDialog.ui index 1aaf5f6..b18e0da 100644 --- a/GUI/ProgressDialog.ui +++ b/GUI/ProgressDialog.ui @@ -39,20 +39,23 @@ 20 - 30 + 20 451 - 21 + 31 - Courier New + Maiandra GD 14 Downloading... + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + @@ -70,7 +73,7 @@ 100 - 0 + 54 true diff --git a/GUI/SettingsDialog.ui b/GUI/SettingsDialog.ui new file mode 100644 index 0000000..d9f755a --- /dev/null +++ b/GUI/SettingsDialog.ui @@ -0,0 +1,230 @@ + + + Dialog + + + + 0 + 0 + 400 + 240 + + + + + 0 + 0 + + + + + 400 + 240 + + + + + 400 + 240 + + + + Settings + + + + ../settings.ico../settings.ico + + + + + 30 + 190 + 341 + 32 + + + + + Cooper Black + 14 + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + 20 + 20 + 351 + 41 + + + + + 851MkPOP + 22 + + + + Settings + + + Qt::AlignCenter + + + + + + 10 + 50 + 371 + 20 + + + + Qt::Horizontal + + + + + + 20 + 90 + 351 + 31 + + + + + Century Gothic + 14 + 50 + false + + + + Language + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + 20 + 120 + 351 + 51 + + + + + + + + Courier New + 14 + + + + (E) + + + English + + + E + + + true + + + + + + + + Century Gothic + 14 + + + + (R) + + + Русский + + + R + + + + + + + true + + + + Rounded Mplus 1c + 14 + + + + (N) + + + 日本語 + + + N + + + + + + + + + + btnx + accepted() + Dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + btnx + rejected() + Dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/NGAudioDownloader.exe b/NGAudioDownloader.exe index 5bb381e..a89cb10 100644 Binary files a/NGAudioDownloader.exe and b/NGAudioDownloader.exe differ diff --git a/NGAudioDownloader.py b/NGAudioDownloader.py index 15a10d1..42b83fd 100644 --- a/NGAudioDownloader.py +++ b/NGAudioDownloader.py @@ -8,21 +8,46 @@ from PyQt5.Qt import QThread, pyqtSignal from PyQt5 import QtCore from requests import get as load from bs4 import BeautifulSoup as parse -from time import sleep +from langswitch import switch +import webbrowser as web +from configer import config class GUI(QMainWindow): def __init__(self): super().__init__() loadUi('GUI/MainWindow.ui',self) - self.dlbtn.clicked.connect(self.download) + self.applylang() + self.btn.clicked.connect(self.download) + self.actionSettings.triggered.connect(self.show_settings) + self.actionHelp.triggered.connect(self.show_help) + + def applylang(self): + self.title.setText(switch['title'][config["lang"]]) + chfont(self.title,switch['title'][f'font_{config["lang"]}']) + self.input.setPlaceholderText(switch['placeholder'][config["lang"]]) + chfont(self.input,switch['placeholder'][f'font_{config["lang"]}']) + self.btn.setText(switch['btn'][config["lang"]]) + chfont(self.btn,switch['btn'][f'font_{config["lang"]}']) + self.menu.setTitle(switch['menu'][config["lang"]]) + chfont(self.menubar,switch['menu'][f'font_{config["lang"]}']) + self.actionSettings.setText(switch['settings'][config["lang"]]) + self.actionHelp.setText(switch['helpbtn'][config["lang"]]) def download(self): # Validating input songID=self.input.text() + if not songID: + self.notification=NotificationDialog(switch['empinp'][config["lang"]]) + self.notification.exec() + return + elif not songID.isdigit(): + self.notification=NotificationDialog(switch['typerr'][config["lang"]]) + self.notification.exec() + return page=parse(load(f'https://www.newgrounds.com/audio/listen/{songID}').text,'html.parser') if page.find(id='pageerror') is not None: - self.notification=NotificationDialog('Incorrect input or the song doesn\'t exist!') + self.notification=NotificationDialog(switch['404'][config["lang"]]) self.notification.exec() return self.songTitle=page.find('title').text @@ -34,27 +59,36 @@ class GUI(QMainWindow): if page[i]!='\\': link+=page[i] i+=1 # Locating file - self.dist=QFileDialog.getSaveFileName(self,'Save File', - link.split('/')[-1], - 'MP3 Audio File (*.mp3)')[0] + self.dist=QFileDialog.getSaveFileName(self,switch['savefile'][config["lang"]], + link.split('/')[-1], + 'MP3 Audio File (*.mp3)')[0] if not self.dist: return # Downloading self.file=load(link,stream=True) self.progress=ProgressDialog() - self.progress.label.setText(f'Downloading "{self.songTitle}"...') - self.progress.setWindowTitle(f'Downloading "{self.songTitle}"...') + self.progress.label.setText(switch['downloading'][config["lang"]](self.songTitle)) + self.progress.setWindowTitle(switch['downloading'][config["lang"]](self.songTitle)) self.progress.bar.setValue(0) self.progress.exec() + def show_settings(self): + self.settings=SettingsDialog() + self.settings.exec() + + def show_help(self): + if config["lang"]=='en': web.open('https://github.com/H1K0/NGAudioDownloader/blob/master/README.md#newgrounds-audio-downloader--',new=2) + else: web.open(f'https://github.com/H1K0/NGAudioDownloader/blob/master/README-{config["lang"].upper()}.md#newgrounds-audio-downloader--',new=2) + def keyPressEvent(self,event): - if event.key()==16777216: - self.close() + if event.key()==16777216: self.close() + elif event.key()==16777220: self.download() class ProgressDialog(QDialog): def __init__(self): super().__init__() loadUi('GUI/ProgressDialog.ui',self) + chfont(self.label,switch['downloading'][f'font_{config["lang"]}']) self.setWindowFlags(self.windowFlags()&~QtCore.Qt.WindowCloseButtonHint) self.thread=DownloadThread() self.thread.got_chunk.connect(lambda done:self.bar.setValue(done)) @@ -81,7 +115,7 @@ class DownloadThread(QThread): def finish(self): global ngad ngad.progress.hide() - ngad.notification=NotificationDialog(f'"{ngad.songTitle}" has been downloaded successfully!') + ngad.notification=NotificationDialog(switch['success'][config["lang"]](ngad.songTitle)) ngad.notification.exec() self.deleteLater() @@ -91,14 +125,47 @@ class NotificationDialog(QDialog): super().__init__() loadUi('GUI/NotificationDialog.ui',self) self.label.setText(msg) + chfont(self.label,switch['ntf'][f'font_{config["lang"]}']) self.setWindowFlags(self.windowFlags()&~QtCore.Qt.WindowCloseButtonHint) + ngad.input.clear() self.btn.clicked.connect(self.accept) def accept(self): - ngad.input.clear() self.close() +class SettingsDialog(QDialog): + def __init__(self): + super().__init__() + loadUi('GUI/SettingsDialog.ui',self) + self.setWindowTitle(switch['settings'][config["lang"]]) + self.title.setText(switch['settings'][config["lang"]]) + self.label_lang.setText(switch['lang'][config["lang"]]) + chfont(self.label_lang,switch['lang'][f'font_{config["lang"]}']) + if config["lang"]=='en': + self.rbtn_en.setChecked(True) + elif config["lang"]=='ru': + self.rbtn_ru.setChecked(True) + elif config["lang"]=='jp': + self.rbtn_jp.setChecked(True) + self.newlang=config["lang"] + self.rbtn_en.toggled.connect(lambda:self.chlang('en')) + self.rbtn_ru.toggled.connect(lambda:self.chlang('ru')) + self.rbtn_jp.toggled.connect(lambda:self.chlang('jp')) + self.accepted.connect(self.updlang) + + def chlang(self,newlang): + if newlang!=config["lang"]: + self.newlang=newlang + + def updlang(self): + config["lang"]=self.newlang + ngad.applylang() + + +def chfont(unit,font): unit.setStyleSheet(f'font-family:{font}') + + if __name__ == '__main__': from sys import argv app=QApplication(argv) diff --git a/README-JP.md b/README-JP.md new file mode 100644 index 0000000..afc6bd8 --- /dev/null +++ b/README-JP.md @@ -0,0 +1,33 @@ +# [Newgrounds](https://newgrounds.com) Audio Downloader ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg) ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg) + +ま、Newgroundsと言えば、普通はオーディオページに結構見付かりやすいダウンロードボタンがあるけど、そのボタンのない奴もある。それも時々、素晴らしくて絶対にダウンロードしたいってゆ奴も出てくるんだ。そうなったらどうしろってんだ? + +**これ**を使うんだ。 + +[英語](README.md)と[ロシア語](README-RU.md)のREADMEもある。 + +## 要求仕様 + +- ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg) +- `PyQt5`ライブラリ +- `requests`ライブラリ +- `bs4`ライブラリ +- `click`ライブラリ + +それともただ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg)だけを持ってこの[exeちゃん](NGAudioDownloader.exe)を使う。 + +## 使用法 + +簡単なもんだ。コイツを実行して、NSI(*Newgrounds song ID*)を入力して、Enterボタン押して、ダウンロード開始だ! + +### ショートカットキー + +- `Enter`でダウンロード開始 +- `Alt + S`で設定画面を開く +- `F1`でヘルプを読む + +### スクショ + +![スタート画面](https://i.ibb.co/pJpVMRS/2020-08-24-16-45-40-Newgrounds-Audio-Downloader.png) + +![設定画面](https://i.ibb.co/DzbvPz0/2020-08-24-16-45-48.png) \ No newline at end of file diff --git a/README-RU.md b/README-RU.md index 6267983..18a1ae6 100644 --- a/README-RU.md +++ b/README-RU.md @@ -1,4 +1,4 @@ -# Newgrounds Audio Downloader ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg) ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg) +# [Newgrounds](https://newgrounds.com) Audio Downloader ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg) ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg) _Или по-славянски: качалка музлишка с ньюграундс._ @@ -6,7 +6,7 @@ _Или по-славянски: качалка музлишка с ньюгра Однако времена меняются, и теперь даже забаненные песенки можно скачать с помощью **этой самой проги**. -При желании можно почитать [редмишку для ~~пендосов~~ инглишменов](README.md). +При желании можно почитать [ридмишку для пендосов и инглишменов](README.md) или [ридмишку для япошек](README-JP.md). ## Требования @@ -22,12 +22,14 @@ _Или по-славянски: качалка музлишка с ньюгра Проще пареной репы. Тупо запускаешь код, вбиваешь айдишник трека и — вуаля! — скачивание пошло! -## Скрины +### Горячие клавиши -![Стартовый экран](https://i.ibb.co/rFGPM8x/2020-08-23-23-10-48-Newgrounds-Audio-Downloader.png) +- `Enter` запускает скачивание +- `Alt + S` вызывает диалог настроек +- `F1` вызывает ~~скорую~~ помощь -![Диалог с прогрессбаром](https://i.ibb.co/6tV9cjH/2020-08-23-23-12-03-Downloading-Mysterious-Planet.png) +### Скрины -![Уведомление о завершении скачивания](https://i.ibb.co/bbsTVDH/2020-08-23-23-59-51-ACHTUNG.png) +![Стартовый экран](https://i.ibb.co/8Y4FMDP/2020-08-24-16-43-16-Newgrounds-Audio-Downloader.png) -![Уведомление о некорректном вводе / ERROR 404](https://i.ibb.co/LzygXPd/2020-08-24-00-01-48-ACHTUNG.png) \ No newline at end of file +![Диалог настроек](https://i.ibb.co/RSXvxDh/2020-08-24-16-43-28.png) \ No newline at end of file diff --git a/README.md b/README.md index 450fa4b..46d978d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -# Newgrounds Audio Downloader ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg) ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg) +# [Newgrounds](https://newgrounds.com) Audio Downloader ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg) ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg) Well, usually there's a download button on the audio page, but what to do if direct downloads are not allowed by the creator even though you love this song too much? You just use **this**. -You can also read the [Russian README](README-RU.md). +You can also read the [Russian README](README-RU.md) or [Japanese README](README-JP.md). ## Requirements @@ -20,12 +20,14 @@ Or you just use the [`NGAudioDownloader.exe`](NGAudioDownloader.exe) so all you It's easy as pie. You just run the downloader, enter your song ID and your file is being downloaded! -## Screenshots +### Shortcuts -![Start screen shot](https://i.ibb.co/rFGPM8x/2020-08-23-23-10-48-Newgrounds-Audio-Downloader.png) +- `Enter` starts download +- `Alt + S` calls settings dialog +- `F1` calls help -![ProgressBar dialog](https://i.ibb.co/6tV9cjH/2020-08-23-23-12-03-Downloading-Mysterious-Planet.png) +### Screenshots -![Download completion notification](https://i.ibb.co/bbsTVDH/2020-08-23-23-59-51-ACHTUNG.png) +![Start screen shot](https://i.ibb.co/qr366Xb/2020-08-24-16-41-06-Newgrounds-Audio-Downloader.png) -![Incorrect input / ERROR 404 notification](https://i.ibb.co/LzygXPd/2020-08-24-00-01-48-ACHTUNG.png) \ No newline at end of file +![Settings dialog](https://i.ibb.co/dkzb5jN/2020-08-24-16-41-14-Settings.png) \ No newline at end of file diff --git a/configer.py b/configer.py new file mode 100644 index 0000000..fb50218 --- /dev/null +++ b/configer.py @@ -0,0 +1,31 @@ +from json import load,dump +from os import access,F_OK + + +default={ + "lang":"en" +} + + +class Config: + def __init__(self): + if access('config.json',F_OK): + with open('config.json',encoding='utf-8') as file: + self.data=load(file) + else: + self.data=default + self.update() + + def __getitem__(self,key): + return self.data[key] + + def __setitem__(self,key,value): + self.data[key]=value + self.update() + + def update(self): + with open('config.json','w',encoding='utf-8') as file: + dump(self.data,file) + + +config=Config() \ No newline at end of file diff --git a/help.ico b/help.ico new file mode 100644 index 0000000..83b8f56 Binary files /dev/null and b/help.ico differ diff --git a/langswitch.py b/langswitch.py new file mode 100644 index 0000000..564f5a3 --- /dev/null +++ b/langswitch.py @@ -0,0 +1,90 @@ +switch={ + "title":{ + "en":"Newgrounds Audio Downloader by H1K0", + "ru":"Newgrounds Audio Downloader от H1K0", + "jp":"H1K0Newgrounds Audio Downloader", + "font_en":"Comic Sans MS", + "font_ru":"Comic Sans MS", + "font_jp":"UD Digi Kyokasho N-R" + }, + "placeholder":{ + "en":"Enter Newgrounds song ID.", + "ru":"Введи айдишник трека на Newgrounds.", + "jp":"NSIを入力しよう!", + "font_en":"Maiandra GD", + "font_ru":"Courier New", + "font_jp":"Rounded Mplus 1c" + }, + "btn":{ + "en":"Download!", + "ru":"Скачать!", + "jp":"ダウンロード!", + "font_en":"Cooper Black", + "font_ru":"851CHIKARA-DZUYOKU-KANA-A", + "font_jp":"Nagurigaki Crayon" + }, + "ntf":{ + "font_en":"Maiandra GD", + "font_ru":"Courier New", + "font_jp":"Rounded Mplus 1c" + }, + "empinp":{ + "en":"Hey-hey, don't leave the input empty!", + "ru":"Эй, ну хоть что-нибудь напиши!", + "jp":"おいおい、何も入力してねえんじゃねえかよ!" + }, + "typerr":{ + "en":"Newgrounds song ID consists of digits only!", + "ru":"Айдишник трека состоит только из цифр!", + "jp":"NSIは数字だけだ!" + }, + "404":{ + "en":"And there's no song with this ID!", + "ru":"А нет песенки с таким айдишником!", + "jp":"そのNSIの曲は存在してないな!" + }, + "savefile":{ + "en":"Save file", + "ru":"Сохранить файл", + "jp":"ファイル保存" + }, + "downloading":{ + "en":lambda songTitle:f'Downloading «{songTitle}»...', + "ru":lambda songTitle:f'Скачивание трека «{songTitle}»...', + "jp":lambda songTitle:f'「{songTitle}」ダウンロード中・・・', + "font_en":"Maiandra GD", + "font_ru":"Courier New", + "font_jp":"Rounded Mplus 1c" + }, + "success":{ + "en":lambda songTitle:f'«{songTitle}» has been downloaded successfully!', + "ru":lambda songTitle:f'«{songTitle}»: скачано!', + "jp":lambda songTitle:f'「{songTitle}」ダウンロード完了!' + }, + "menu":{ + "en":"MENU", + "ru":"МЕНЮ", + "jp":"メニュー", + "font_en":"Century Gothic", + "font_ru":"Century Gothic", + "font_jp":"Rounded Mplus 1c" + }, + "settings":{ + "en":"Settings", + "ru":"Настройки", + "jp":"設定" + }, + "helpbtn":{ + "en":"Help", + "ru":"Помощь", + "jp":"ヘルプ" + }, + "lang":{ + "en":"Language", + "ru":"Язык", + "jp":"言語", + "font_en":"Century Gothic", + "font_ru":"Century Gothic", + "font_jp":"Rounded Mplus 1c" + } +} \ No newline at end of file diff --git a/settings.ico b/settings.ico new file mode 100644 index 0000000..9c14507 Binary files /dev/null and b/settings.ico differ