Compare commits

...

10 Commits

Author SHA1 Message Date
a849097a47 Added video guide 2020-08-28 21:47:43 +03:00
fbb399acfc Updated READMEs 2020-08-25 22:16:12 +03:00
7e6a23fa5d PEP8-ed python files 2020-08-25 18:35:38 +03:00
021d471357 Updated links in READMEs 2020-08-25 03:43:47 +03:00
545c5d388d Update .gitignore 2020-08-25 03:36:24 +03:00
7d2ab63dbe Introducing easy install 2020-08-25 03:36:17 +03:00
fe7d0c178a Multilingualized
Now there're English, Russian and Japanese languages
2020-08-24 16:56:41 +03:00
5a622f53cd Added Russian README 2020-08-24 00:28:36 +03:00
cc336d8014 Forgot to update the .exe :3 2020-08-24 00:11:32 +03:00
70ae74dcbb Added notification dialogs 2020-08-24 00:06:33 +03:00
14 changed files with 805 additions and 87 deletions

5
.gitignore vendored
View File

@ -1,3 +1,6 @@
__pycache__
build*
*.spec
_dump
*.exe
*.spec
/config.json

View File

@ -47,15 +47,15 @@
</property>
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>20</pointsize>
<family>Comic Sans MS</family>
<pointsize>22</pointsize>
</font>
</property>
<property name="text">
<string>Newgrounds Audio Downloader by H1K0</string>
<string>&lt;strong&gt;Newgrounds Audio Downloader&lt;/strong&gt; by &lt;em&gt;H1K0&lt;/em&gt;</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
</property>
</widget>
<widget class="QLineEdit" name="input">
@ -69,7 +69,7 @@
</property>
<property name="font">
<font>
<family>Courier New</family>
<family>Maiandra GD</family>
<pointsize>12</pointsize>
</font>
</property>
@ -83,7 +83,7 @@
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="dlbtn">
<widget class="QPushButton" name="btn">
<property name="geometry">
<rect>
<x>20</x>
@ -101,11 +101,14 @@
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="toolTip">
<string>(Enter)</string>
</property>
<property name="text">
<string>Download!</string>
</property>
<property name="shortcut">
<string>Return</string>
<string>Ctrl+S</string>
</property>
</widget>
</widget>
@ -115,9 +118,33 @@
<x>0</x>
<y>0</y>
<width>600</width>
<height>21</height>
<height>23</height>
</rect>
</property>
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>10</pointsize>
</font>
</property>
<widget class="QMenu" name="menu">
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>9</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>ArrowCursor</cursorShape>
</property>
<property name="title">
<string>MENU</string>
</property>
<addaction name="actionSettings"/>
<addaction name="separator"/>
<addaction name="actionHelp"/>
</widget>
<addaction name="menu"/>
</widget>
<action name="settings">
<property name="text">
@ -135,6 +162,36 @@
<string>F1</string>
</property>
</action>
<action name="actionSettings">
<property name="icon">
<iconset>
<normaloff>../settings.ico</normaloff>../settings.ico</iconset>
</property>
<property name="text">
<string>Settings</string>
</property>
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>10</pointsize>
</font>
</property>
<property name="shortcut">
<string>Alt+S</string>
</property>
</action>
<action name="actionHelp">
<property name="icon">
<iconset>
<normaloff>../help.ico</normaloff>../help.ico</iconset>
</property>
<property name="text">
<string>Help</string>
</property>
<property name="shortcut">
<string>F1</string>
</property>
</action>
</widget>
<resources/>
<connections/>

94
GUI/NotificationDialog.ui Normal file
View File

@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>150</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>150</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>150</height>
</size>
</property>
<property name="windowTitle">
<string>ACHTUNG!</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../icon.ico</normaloff>../icon.ico</iconset>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>331</width>
<height>61</height>
</rect>
</property>
<property name="font">
<font>
<family>Maiandra GD</family>
<pointsize>16</pointsize>
</font>
</property>
<property name="text">
<string>ACHTUNG!</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="indent">
<number>0</number>
</property>
</widget>
<widget class="QPushButton" name="btn">
<property name="geometry">
<rect>
<x>280</x>
<y>100</y>
<width>81</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Cooper Black</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>OK!</string>
</property>
<property name="shortcut">
<string>Return</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -39,20 +39,23 @@
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<y>20</y>
<width>451</width>
<height>21</height>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Courier New</family>
<family>Maiandra GD</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="text">
<string>Downloading...</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
<widget class="QProgressBar" name="bar">
<property name="geometry">
@ -63,11 +66,14 @@
<height>25</height>
</rect>
</property>
<property name="cursor">
<cursorShape>BusyCursor</cursorShape>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>0</number>
<number>54</number>
</property>
<property name="textVisible">
<bool>true</bool>

230
GUI/SettingsDialog.ui Normal file
View File

@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>240</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>400</width>
<height>240</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>400</width>
<height>240</height>
</size>
</property>
<property name="windowTitle">
<string>Settings</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>../settings.ico</normaloff>../settings.ico</iconset>
</property>
<widget class="QDialogButtonBox" name="btnx">
<property name="geometry">
<rect>
<x>30</x>
<y>190</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="font">
<font>
<family>Cooper Black</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="title">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>351</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<family>851MkPOP</family>
<pointsize>22</pointsize>
</font>
</property>
<property name="text">
<string>Settings</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="Line" name="hr">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>371</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QLabel" name="label_lang">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>351</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>14</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>Language</string>
</property>
<property name="alignment">
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
</property>
</widget>
<widget class="QWidget" name="horizontalLayoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>120</y>
<width>351</width>
<height>51</height>
</rect>
</property>
<layout class="QHBoxLayout" name="lang_select">
<item>
<widget class="QRadioButton" name="rbtn_en">
<property name="font">
<font>
<family>Courier New</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="toolTip">
<string>(E)</string>
</property>
<property name="text">
<string>English</string>
</property>
<property name="shortcut">
<string>E</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbtn_ru">
<property name="font">
<font>
<family>Century Gothic</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="toolTip">
<string>(R)</string>
</property>
<property name="text">
<string>Русский</string>
</property>
<property name="shortcut">
<string>R</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbtn_jp">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<family>Rounded Mplus 1c</family>
<pointsize>14</pointsize>
</font>
</property>
<property name="toolTip">
<string>(N)</string>
</property>
<property name="text">
<string>日本語</string>
</property>
<property name="shortcut">
<string>N</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>btnx</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>btnx</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -8,88 +8,189 @@ 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.inprocess=False
def __init__(self):
super().__init__()
loadUi('GUI/MainWindow.ui', self)
self.applylang()
self.btn.clicked.connect(self.download)
self.actionSettings.triggered.connect(self.show_settings)
self.actionHelp.triggered.connect(self.show_help)
def download(self):
self.inprocess=True
# Validating input
songID=self.input.text()
page=parse(load(f'https://www.newgrounds.com/audio/listen/{songID}').text,'html.parser')
if page.find(id='pageerror') is not None:
self.input.clear()
return
songTitle=page.find('title').text
# Getting download link
link='http://audio.ngfiles.com/'
page=str(page)
i=page.find('audio.ngfiles.com')+len('audio.ngfiles.com/')
while not link.endswith('.mp3'):
if page[i]!='\\': link+=page[i]
i+=1
# Locating file
dist=QFileDialog.getSaveFileName(self,'Save File',
link.split('/')[-1],
'MP3 Audio File (*.mp3)')[0]
if not dist: return
# Downloading
file=load(link,stream=True)
global progress
progress.label.setText(f'Downloading "{songTitle}"...')
progress.setWindowTitle(f'Downloading "{songTitle}"...')
progress.bar.setValue(0)
progress.show()
self.thread=DownloadThread(file,dist)
self.thread.got_chunk.connect(lambda done:progress.bar.setValue(done))
self.thread.finished.connect(self.thread.finish)
self.thread.start()
self.input.clear()
self.inprocess=False
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('https://www.newgrounds.com/audio/listen/'
f'{songID}').text, 'html.parser')
if page.find(id='pageerror') is not None:
self.notification = NotificationDialog(
switch['404'][config["lang"]])
self.notification.exec()
return
self.songTitle = page.find('title').text
# Getting download link
link = 'http://audio.ngfiles.com/'
page = str(page)
i = page.find('audio.ngfiles.com')+len('audio.ngfiles.com/')
while not link.endswith('.mp3'):
if page[i] != '\\':
link += page[i]
i += 1
# Locating file
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(
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('https://github.com/H1K0/NGAudioDownloader/blob/master/'
f'README-{config["lang"].upper()}.md#'
'newgrounds-audio-downloader--', new=2)
def keyPressEvent(self, event):
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)
self.setWindowFlags(self.windowFlags()&~QtCore.Qt.WindowCloseButtonHint)
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))
self.thread.finished.connect(self.thread.finish)
self.thread.start()
class DownloadThread(QThread):
got_chunk=pyqtSignal(object)
got_chunk = pyqtSignal(object)
def __init__(self,file,dist):
super().__init__()
self.file,self.dist=file,dist
def __init__(self): super().__init__()
def run(self):
global progress
total=self.file.headers.get('content-length')
if total is None: total=-1
else: total=int(total)
downloaded=0
with open(self.dist,'wb') as out:
for data in self.file.iter_content(chunk_size=max(total//100,1024)):
downloaded+=len(data)
out.write(data)
self.got_chunk.emit(100*downloaded//total)
def run(self):
total = ngad.file.headers.get('content-length')
if total is None:
total = -1
else:
total = int(total)
downloaded = 0
with open(ngad.dist, 'wb') as out:
for data in (ngad.file.
iter_content(chunk_size=max(total//100, 1024))):
downloaded += len(data)
out.write(data)
self.got_chunk.emit(100*downloaded//total)
def finish(self):
global progress
progress.hide()
self.deleteLater()
def finish(self):
global ngad
ngad.progress.hide()
ngad.notification = NotificationDialog(
switch['success'][config["lang"]](ngad.songTitle))
ngad.notification.exec()
self.deleteLater()
class NotificationDialog(QDialog):
def __init__(self, msg):
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):
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)
ngad=GUI()
progress=ProgressDialog()
app = QApplication(argv)
ngad = GUI()
ngad.show()
sys.exit(app.exec_())
sys.exit(app.exec_())

43
README-JP.md Normal file
View File

@ -0,0 +1,43 @@
# [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#newgrounds-audio-downloader--)と[ロシア語](README-RU.md#newgrounds-audio-downloader--)の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)だけを持って、この[アーカイブ](NGAudioDownloader.zip)をダウンロードして、[exeちゃん](NGAudioDownloader.exe)を使って楽になってもいい。
## 早速始めたい!
### 一般人の方(法)
ま、[`NGAudioDownloader.zip`](https://github.com/H1K0/NGAudioDownloader/raw/master/NGAudioDownloader.zip)をダウンロードして、ソイツをどっかで解凍して、`NGAudioDownloader.exe`を実行させるだけ。
<big>※注意:</big>コイツに時計のように正常に作動して欲しいってんなら、絶対に、アーカイブから抽出されたファイルを**移動/削除したりすんじゃねえぞ**
### Pythonistの方(法)
ま、[リポジトリ全体をダウンロード](https://github.com/H1K0/NGAudioDownloader/archive/master.zip)して、`NGAudioDownloader.py`を実行だ。はい、終了~!
## で、後はどうするの?
簡単なもんやろ。コイツを実行して、NSI(*Newgrounds song ID*)を入力して、`Enter`ボタン押して、ダウンロード開始だ!
### どこ押したらいい?
- `Enter`でダウンロード開始
- `Alt + S`で設定画面を開く
- `F1`でヘルプを読む
## あのー、なんかビデオガイドとかないんですかー?
Pythonistならもう分かってる筈なんだから、[一般人向けのビデオガイド](https://yadi.sk/i/9krScj2BHcr3Rg)。

45
README-RU.md Normal file
View File

@ -0,0 +1,45 @@
# [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)
_Или по-славянски: качалка музлишка с ньюграундс._
Ну, вообще-то на нг обычно есть кнопка для скачивания, однако иногда авторы запрещают прямое скачивание, и как бы сильно тебе ни нравилась песенка, ты не сможешь ее так просто заполучить.
Однако времена меняются, и теперь даже забаненные песенки можно скачать с помощью **этой самой проги**.
При желании можно почитать [ридмишку для пендосов и инглишменов](README.md#newgrounds-audio-downloader--) или [ридмишку для япошек](README-JP.md#newgrounds-audio-downloader--).
## Что расчехлять?
- ![(Питон 3+)](https://img.shields.io/badge/Питон-3+-blue.svg)
- Либа `PyQt5`
- Либа `requests`
- Либа `bs4`
- Либа `click`
Или же можно тупо скачать [архивчик](NGAudioDownloader.zip), жмыхнуть ехешник и вообще не париться, если у тебя ![Винда XP+](https://img.shields.io/badge/Винда-XP+-brightgreen.svg).
## Ну чо, пацаны, поехали!
### Старт юзверя
Короче, скачиваешь [`NGAudioDownloader.zip`](https://github.com/H1K0/NGAudioDownloader/raw/master/NGAudioDownloader.zip), извлекаешь куда-нибудь и фигачишь `NGAudioDownloader.exe`.
<big>※И ДА:</big> если хочешь, чтобы качалка работала, как швейцарские часики, **не смей перемещать/удалять** какие-либо файлы, извлеченные из архива! Иначе огребешь **БАН**. <span title="Это морда пажылого борова палучаеца." style="cursor:help">;-\
### Старт питониста
Короче, [скачиваешь весь репозиторий](https://github.com/H1K0/NGAudioDownloader/archive/master.zip) и фигачишь `NGAudioDownloader.py`. Финита. :3
## Ок, че дальше?
Проще пареной репы. Тупо запускаешь код, вбиваешь айдишник трека и — вуаля! — скачивание пошло!
### Куды тыкать-то?
- `Enter` запускает скачивание
- `Alt + S` вызывает диалог настроек
- `F1` вызывает ~~скорую~~ помощь
## А видеогайда нет?
Ну, предполагается, что питонисты и так прошаренные, так что вот [видеогайд для юзверей](https://yadi.sk/i/9krScj2BHcr3Rg).

View File

@ -1,10 +1,12 @@
# 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**.
## Requirements
You can also read the [Russian README](README-RU.md#newgrounds-audio-downloader--) or [Japanese README](README-JP.md#newgrounds-audio-downloader--).
## So, what do I actually need?
- ![(Python 3+)](https://img.shields.io/badge/Python-3+-blue.svg)
- `PyQt5` library
@ -12,14 +14,30 @@ You just use **this**.
- `bs4` library
- `click` library
Or you just use the [`NGAudioDownloader.exe`](NGAudioDownloader.exe) so all you need is ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg).
Or you just use the `.exe` file from [`NGAudioDownloader.zip`](NGAudioDownloader.zip) so all you need is ![Windows XP+](https://img.shields.io/badge/Windows-XP+-brightgreen.svg).
## Usage
## Let's get it started!
### I'm a civilian
You just download [`NGAudioDownloader.zip`](https://github.com/H1K0/NGAudioDownloader/raw/master/NGAudioDownloader.zip), extract it somewhere and run the `NGAudioDownloader.exe`.
<big>※NOTE:</big> if you want this downloader working correctly **DO NOT move/delete** any files extracted from the archive!
### I'm a pythonist
You just [download the whole repository](https://github.com/H1K0/NGAudioDownloader/archive/master.zip) and run `NGAudioDownloader.py`. That's all. :3
## What should I do then?
It's easy as pie. You just run the downloader, enter your song ID and your file is being downloaded!
## Screenshots
### Where should I press?
![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)
## Is there any video guide?
Well, pythonists are considered already understanding how it all works, so here's the [video guide for civilians](https://yadi.sk/i/9krScj2BHcr3Rg).

31
configer.py Normal file
View File

@ -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()

BIN
help.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

90
langswitch.py Normal file
View File

@ -0,0 +1,90 @@
switch = {
"title": {
"en": "<strong>Newgrounds Audio Downloader</strong> by <em>H1K0</em>",
"ru": "<strong>Newgrounds Audio Downloader</strong> от <em>H1K0</em>",
"jp": "<em>H1K0</em> の <strong>Newgrounds Audio Downloader</strong>",
"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"
}
}

BIN
settings.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB