Skip to content

Commit

Permalink
Merge pull request #4 from bbtufty/discord
Browse files Browse the repository at this point in the history
Add Discord webhook
  • Loading branch information
bbtufty authored Oct 19, 2024
2 parents 3f81d1c + 58d3acf commit cfcef1a
Show file tree
Hide file tree
Showing 13 changed files with 217 additions and 41 deletions.
Binary file modified docs/img/gui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ NXBrew-dl

NXBrew-dl is intended to be an easy-to-user interface to download ROMs, DLC and update files for NSP. It does so via
a GUI interface, allowing users to download items in bulk and keeping things up-to-date. NXBrew-dl connects to
JDownloader to allow for easy download/extraction from multiple sites.
JDownloader to allow for easy download/extraction from multiple sites, and can optionally post info on the downloads
to Discord.

As of now, this is in extremely early development. It will parse and download many ROMs, but be aware that currently
if multiple regions exist, it will only download the US release. This will be upgrade in a future release.
Expand Down
6 changes: 5 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ downloading!
Because we prefer 1Fichier links over anything else, we strongly suggest investing in a premium
account if you'll be downloading a lot of files. An hour is a long time to wait!

Finally, we have ROM options. These are whether you prefer NSP or XCI files, and whether you would like to download
We then have ROM options. These are whether you prefer NSP or XCI files, and whether you would like to download
associated updates and DLC, if available.

Finally, we have the Discord integration. If a URL is set here, then NXBrew-dl will post a summary of downloaded files
via the Discord webhook. For details on how to set this up, see
`here <https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks>`_.

The right shows the NXBrew index. Each is flagged with various properties, such as whether it has an NSP or XCI file,
updates, and DLC. By clicking the "DL?" button, you add to the list. You can filter using the search bar at the top.
By clicking run, you will queue up downloads.
4 changes: 2 additions & 2 deletions nxbrew_dl/gui/gui_nxbrew_dl.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ def __init__(self):
"""NXBrew-dl Main Window
TODO:
- Executable
- Discord webhook
- Region/language priorities
"""

Expand Down Expand Up @@ -216,6 +214,7 @@ def load_config(
"jd_device": self.ui.lineEditJDownloaderDevice,
"jd_user": self.ui.lineEditJDownloaderUser,
"jd_pass": self.ui.lineEditJDownloaderPass,
"discord_url": self.ui.lineEditDiscordURL,
}

for field in text_fields:
Expand Down Expand Up @@ -256,6 +255,7 @@ def save_config(
"jd_device": self.ui.lineEditJDownloaderDevice.text(),
"jd_user": self.ui.lineEditJDownloaderUser.text(),
"jd_pass": self.ui.lineEditJDownloaderPass.text(),
"discord_url": self.ui.lineEditDiscordURL.text(),
}

for field in text_fields:
Expand Down
22 changes: 22 additions & 0 deletions nxbrew_dl/gui/layout_nxbrew_dl.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,23 @@ def setupUi(self, nxbrew_dl):

self.verticalLayoutConfig.addItem(self.verticalSpacerConfigBottom)

self.labelDiscordURL = QLabel(self.centralwidget)
self.labelDiscordURL.setObjectName(u"labelDiscordURL")

self.verticalLayoutConfig.addWidget(self.labelDiscordURL)

self.lineEditDiscordURL = QLineEdit(self.centralwidget)
self.lineEditDiscordURL.setObjectName(u"lineEditDiscordURL")
sizePolicy1.setHeightForWidth(self.lineEditDiscordURL.sizePolicy().hasHeightForWidth())
self.lineEditDiscordURL.setSizePolicy(sizePolicy1)
self.lineEditDiscordURL.setEchoMode(QLineEdit.EchoMode.Normal)

self.verticalLayoutConfig.addWidget(self.lineEditDiscordURL)

self.verticalSpacer_5 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)

self.verticalLayoutConfig.addItem(self.verticalSpacer_5)


self.horizontalLayoutConfigGames.addLayout(self.verticalLayoutConfig)

Expand Down Expand Up @@ -365,6 +382,11 @@ def retranslateUi(self, nxbrew_dl):
self.checkBoxDownloadDLC.setStatusTip(QCoreApplication.translate("nxbrew_dl", u"If available, will download DLCs", None))
#endif // QT_CONFIG(statustip)
self.checkBoxDownloadDLC.setText(QCoreApplication.translate("nxbrew_dl", u"Download DLCs", None))
self.labelDiscordURL.setText(QCoreApplication.translate("nxbrew_dl", u"Discord Webhook URL:", None))
#if QT_CONFIG(statustip)
self.lineEditDiscordURL.setStatusTip(QCoreApplication.translate("nxbrew_dl", u"Webhook URL for Discord", None))
#endif // QT_CONFIG(statustip)
self.lineEditDiscordURL.setText("")
self.labelSearch.setText(QCoreApplication.translate("nxbrew_dl", u"Search:", None))
self.pushButtonRefresh.setText(QCoreApplication.translate("nxbrew_dl", u"Refresh", None))
___qtablewidgetitem = self.tableGames.horizontalHeaderItem(0)
Expand Down
39 changes: 39 additions & 0 deletions nxbrew_dl/gui/layout_nxbrew_dl.ui
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,45 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelDiscordURL">
<property name="text">
<string>Discord Webhook URL:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditDiscordURL">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="statusTip">
<string>Webhook URL for Discord</string>
</property>
<property name="text">
<string/>
</property>
<property name="echoMode">
<enum>QLineEdit::EchoMode::Normal</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
Expand Down
99 changes: 86 additions & 13 deletions nxbrew_dl/nxbrew_dl/nxbrew.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
import nxbrew_dl
from ..gui.gui_utils import get_gui_logger
from ..util import (
discord_push,
load_yml,
load_json,
save_json,
get_html_page,
get_languages,
get_thumb_url,
get_dl_dict,
bypass_ouo,
)
Expand All @@ -24,6 +26,14 @@
"update": "Updates",
}

DISCORD_MAPPING = {
"base_game_nsp": "Base Game",
"base_game_xci": "Base Game",
"dlc": "DLC",
"update": "Update",
}


class NXBrew:

def __init__(
Expand Down Expand Up @@ -78,6 +88,12 @@ def __init__(
self.logger.info(f"Connecting to device {jd_device_name}")
self.jd_device = jd.get_device(jd_device_name)

# Discord stuff
discord_url = self.user_config.get("discord_url", "")
if discord_url == "":
discord_url = None
self.discord_url = discord_url

self.to_download = to_download

def run(self):
Expand All @@ -99,7 +115,7 @@ def run(self):

self.logger.info("Cleaning up")

self.clean_downloads()
self.clean_up_cache()

self.logger.info("All done!")

Expand Down Expand Up @@ -134,6 +150,15 @@ def download_game(
cache_filename="game.html",
)

# Get thumbnail, and add to cache if not there
thumb_url = get_thumb_url(
soup,
)
if "thumb_url" not in self.user_cache[url]:
self.logger.debug("Adding thumbnail URL to cache")
self.user_cache[url]["thumb_url"] = thumb_url

# Get languages
langs = get_languages(
soup,
lang_dict=self.general_config["languages"],
Expand Down Expand Up @@ -261,10 +286,21 @@ def download_game(

# Update and save out cache
self.user_cache[url][dl_key].append(dl_info["full_name"])
save_json(self.user_cache,
self.user_cache_file,
sort_key="name",
)
save_json(
self.user_cache,
self.user_cache_file,
sort_key="name",
)

# Post to discord
if self.discord_url is not None:
self.post_to_discord(
name=name,
url=url,
added_type=DISCORD_MAPPING[dl_key],
description=dl_info["full_name"],
thumb_url=thumb_url,
)

def run_jdownloader(
self,
Expand Down Expand Up @@ -432,8 +468,40 @@ def run_jdownloader(

return True

def clean_downloads(self):
"""Remove items from the cache and on disk, if needed"""
def post_to_discord(
self, name, url, added_type="Base Game", description=None, thumb_url=None
):
"""Post summary as a discord message
Args:
name (str): Game name
url (str): URL for the ROM
added_type (str): Type of added link. Defaults to "Base Game"
description (str): Description of the link. Defaults to None
thumb_url (str): Thumbnail URL. Defaults to None
"""

embeds = [
{
"author": {
"name": name,
"url": url,
},
"title": added_type,
"description": description,
"thumbnail": {"url": thumb_url},
}
]

discord_push(
url=self.discord_url,
embeds=embeds,
)

return True

def clean_up_cache(self):
"""Remove items from the cache and on disk, if needed, and do a final save"""

# First, scan through for any games that are no longer check
games = [g for g in self.to_download]
Expand All @@ -450,7 +518,9 @@ def clean_downloads(self):
for i, g in enumerate(games_to_delete):

for dl_dir in DL_MAPPING:
g_dir = os.path.join(self.user_config["download_dir"], DL_MAPPING[dl_dir], g)
g_dir = os.path.join(
self.user_config["download_dir"], DL_MAPPING[dl_dir], g
)
if os.path.exists(g_dir):
shutil.rmtree(g_dir)

Expand All @@ -461,17 +531,20 @@ def clean_downloads(self):
for key in ["dlc", "update"]:
if not self.user_config[f"download_{key}"]:
self.logger.info(f"Removing {key} from cache and disk")
out_dir = os.path.join(self.user_config["download_dir"], DL_MAPPING[key])
out_dir = os.path.join(
self.user_config["download_dir"], DL_MAPPING[key]
)
if os.path.exists(out_dir):
shutil.rmtree(out_dir)

for d in self.user_cache:
self.user_cache[d].pop(key, [])

# Save out the cache
save_json(self.user_cache,
self.user_cache_file,
sort_key="name",
)
save_json(
self.user_cache,
self.user_cache_file,
sort_key="name",
)

return True
5 changes: 4 additions & 1 deletion nxbrew_dl/util/__init__.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
from .discord_tools import discord_push
from .download_tools import get_dl_dict, bypass_ouo
from .html_tools import get_html_page, get_game_dict, get_languages
from .html_tools import get_html_page, get_game_dict, get_languages, get_thumb_url
from .io_tools import load_yml, save_yml, load_json, save_json
from .regex_tools import check_has_filetype, get_game_name

__all__ = [
"discord_push",
"get_dl_dict",
"bypass_ouo",
"get_html_page",
"get_game_dict",
"check_has_filetype",
"get_game_name",
"get_languages",
"get_thumb_url",
"load_yml",
"save_yml",
"load_json",
Expand Down
20 changes: 20 additions & 0 deletions nxbrew_dl/util/discord_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from discordwebhook import Discord


def discord_push(
url,
embeds,
):
"""Post a message to Discord
Args:
url (str): Discord URL
embeds (list): List of dictionaries of embeds
"""

discord = Discord(url=url)
discord.post(
embeds=embeds,
)

return True
Loading

0 comments on commit cfcef1a

Please sign in to comment.