Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
BasedOnStyle: Google
AccessModifierOffset: -4
ColumnLimit: 120
IndentWidth: 4
IncludeBlocks: Preserve
InsertBraces: true
Expand Down
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.21.0)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "iOS" OR IOS)
set(CMAKE_OSX_ARCHITECTURES "arm64")
Expand All @@ -10,6 +10,8 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden)

set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)

set(GEODE_LINK_NIGHTLY 1)

project(jukebox VERSION 3.4.0)

file(GLOB SOURCES
Expand All @@ -25,9 +27,11 @@ file(GLOB SOURCES
jukebox/jukebox/*.cpp
)

add_library(${PROJECT_NAME} SHARED ${SOURCES})
add_library(${PROJECT_NAME} SHARED ${SOURCES}
jukebox/jukebox/events/file_download_progress.hpp)
target_include_directories(${PROJECT_NAME} PUBLIC jukebox)


set_property(TARGET ${PROJECT_NAME} PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

if (NOT DEFINED ENV{GEODE_SDK})
Expand All @@ -39,4 +43,4 @@ endif()
add_subdirectory($ENV{GEODE_SDK} $ENV{GEODE_SDK}/build)

target_link_libraries(${PROJECT_NAME} geode-sdk)
create_geode_file(${PROJECT_NAME})
setup_geode_mod(${PROJECT_NAME})
15 changes: 0 additions & 15 deletions jukebox/jukebox/download/download.hpp

This file was deleted.

59 changes: 29 additions & 30 deletions jukebox/jukebox/download/hosted.cpp
Original file line number Diff line number Diff line change
@@ -1,48 +1,47 @@
#include <jukebox/download/hosted.hpp>

#include <string_view>

#include <fmt/core.h>
#include <Geode/loader/Mod.hpp>
#include <Geode/Result.hpp>
#include <Geode/loader/Mod.hpp>
#include <Geode/utils/web.hpp>

#include <jukebox/download/download.hpp>
#include <jukebox/events/file_download_progress.hpp>

using namespace geode::prelude;

namespace jukebox {

namespace download {
namespace jukebox::download {

DownloadTask startHostedDownload(const std::string& url) {
arc::Future<Result<ByteVector>> startHostedDownload(const std::string_view url) {
int timeout = Mod::get()->getSettingValue<int>("download-timeout");

if (timeout < 30) {
timeout = 30;
}

return web::WebRequest()
.timeout(std::chrono::seconds(timeout))
.get(url)
.map(
[](web::WebResponse* response) -> DownloadTask::Value {
if (!response->ok()) {
if (response->code() == 502) {
return Err(
"Web request failed. Service is currently "
"unavailable or under maintenance. Please try "
"again later.");
} else {
return Err(fmt::format("Web request failed. Status {}",
response->code()));
}
}
return Ok(std::move(response->data()));
},
[](web::WebProgress* progress) {
return progress->downloadProgress().value_or(0);
});
}
const web::WebResponse response =
co_await web::WebRequest()
.timeout(std::chrono::seconds(timeout))
.onProgress([url = std::string(url)](const web::WebProgress& progress) {
const float actual = progress.downloadProgress().value_or(0.0f);

events::FileDownloadProgress(url).send(events::FileDownloadProgressData{url, actual});
})
.get(std::string(url));

if (!response.ok()) {
if (response.code() == 502) {
co_return Err(
"Web request failed. Service is currently "
"unavailable or under maintenance. Please try "
"again later.");
}

co_return Err(fmt::format("Web request failed. Status {}", response.code()));
}

} // namespace download
co_return Ok(std::move(response).data());
}

} // namespace jukebox
} // namespace jukebox::download
16 changes: 7 additions & 9 deletions jukebox/jukebox/download/hosted.hpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#pragma once

#include <string>
#include <string_view>

#include <jukebox/download/download.hpp>
#include <Geode/Result.hpp>
#include <Geode/utils/general.hpp>
#include <arc/future/Future.hpp>

namespace jukebox {
namespace jukebox::download {

namespace download {
arc::Future<geode::Result<geode::ByteVector>> startHostedDownload(std::string_view url);

DownloadTask startHostedDownload(const std::string& url);

}

} // namespace jukebox
} // namespace jukebox::download
44 changes: 20 additions & 24 deletions jukebox/jukebox/download/youtube.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,35 @@
#include <Geode/Result.hpp>
#include <Geode/utils/web.hpp>

#include <jukebox/download/download.hpp>
#include <jukebox/download/hosted.hpp>

using namespace geode::prelude;
using namespace arc;

web::WebTask getMetadata(const std::string& id);
Result<std::string> getUrlFromMetadataPayload(web::WebResponse* resp);
jukebox::download::DownloadTask onMetadata(web::WebResponse*);
web::WebFuture getMetadata(const std::string& id);
Result<std::string> getUrlFromMetadataPayload(web::WebResponse r);
Future<Result<ByteVector>> onMetadata(web::WebResponse result);

namespace jukebox {
namespace jukebox::download {

namespace download {

DownloadTask startYoutubeDownload(const std::string& id) {
Future<Result<ByteVector>> startYoutubeDownload(const std::string& id) {
if (id.length() != 11) {
return DownloadTask::immediate(Err("Invalid YouTube ID"));
co_return Err("Invalid YouTube ID");
}

return getMetadata(id).chain(
[](web::WebResponse* r) { return onMetadata(r); });
auto metadata = co_await getMetadata(id);
co_return co_await onMetadata(std::move(metadata));
}

} // namespace download

} // namespace jukebox
} // namespace jukebox::download

Result<std::string> getUrlFromMetadataPayload(web::WebResponse* r) {
if (!r->ok()) {
Result<std::string> getUrlFromMetadataPayload(web::WebResponse r) {
if (!r.ok()) {
return Err(fmt::format(
"cobalt metadata query failed with status code {}", r->code()));
"cobalt metadata query failed with status code {}", r.code()));
}

Result<matjson::Value> jsonRes = r->json();
Result<matjson::Value> jsonRes = r.json();
if (jsonRes.isErr()) {
return Err("cobalt metadata query returned invalid JSON");
}
Expand All @@ -57,15 +53,15 @@ Result<std::string> getUrlFromMetadataPayload(web::WebResponse* r) {
return Ok(payload["url"].asString().unwrap());
}

web::WebTask getMetadata(const std::string& id) {
web::WebFuture getMetadata(const std::string& id) {
int timeout = Mod::get()->getSettingValue<int>("download-timeout");

if (timeout < 30) {
timeout = 30;
}

return web::WebRequest()
.timeout(std::chrono::seconds(30))
.timeout(std::chrono::seconds(timeout))
.bodyJSON(matjson::makeObject(
{{"url", fmt::format("https://www.youtube.com/watch?v={}", id)},
{"aFormat", "mp3"},
Expand All @@ -75,11 +71,11 @@ web::WebTask getMetadata(const std::string& id) {
.post("https://api.cobalt.tools/api/json");
}

jukebox::download::DownloadTask onMetadata(web::WebResponse* result) {
Result<std::string> res = getUrlFromMetadataPayload(result);
Future<Result<ByteVector>> onMetadata(web::WebResponse result) {
Result<std::string> res = getUrlFromMetadataPayload(std::move(result));
if (res.isErr()) {
return jukebox::download::DownloadTask::immediate(Err(res.unwrapErr()));
co_return Err(res.unwrapErr());
}

return jukebox::download::startHostedDownload(res.unwrap());
co_return co_await jukebox::download::startHostedDownload(res.unwrap());
}
13 changes: 5 additions & 8 deletions jukebox/jukebox/download/youtube.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@

#include <string>

#include <jukebox/download/download.hpp>
#include <Geode/utils/general.hpp>
#include <arc/future/Future.hpp>

namespace jukebox {
namespace jukebox::download {

namespace download {
arc::Future<geode::Result<geode::ByteVector>> startYoutubeDownload(const std::string& id);

DownloadTask startYoutubeDownload(const std::string& id);

}

}
} // namespace jukebox::download
28 changes: 28 additions & 0 deletions jukebox/jukebox/events/file_download_progress.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#pragma once

#include <string>
#include <string_view>

#include <Geode/loader/Event.hpp>

namespace jukebox::events {

struct FileDownloadProgressData final {
private:
float m_progress;
std::string m_url;

public:
FileDownloadProgressData(std::string url, const float progress) noexcept
: m_progress{progress}, m_url(std::move(url)) {}

[[nodiscard]] float progress() const noexcept { return m_progress; }
[[nodiscard]] std::string_view url() const noexcept { return m_url; }
};

struct FileDownloadProgress
: geode::GlobalEvent<FileDownloadProgress, bool(const FileDownloadProgressData&), std::string> {
using GlobalEvent::GlobalEvent;
};

} // namespace jukebox::events
14 changes: 0 additions & 14 deletions jukebox/jukebox/events/get_song_info.cpp

This file was deleted.

31 changes: 14 additions & 17 deletions jukebox/jukebox/events/get_song_info.hpp
Original file line number Diff line number Diff line change
@@ -1,32 +1,29 @@
#pragma once

#include <string>
#include <string_view>

#include <Geode/loader/Event.hpp>

#include <jukebox/hooks/music_download_manager.hpp>
namespace jukebox::event {

namespace jukebox {

namespace event {

class GetSongInfo : public geode::Event {
struct GetSongInfoData final {
private:
int m_gdId;
std::string m_songName;
std::string m_artistName;
int m_gdSongID;

protected:
friend class ::JBMusicDownloadManager;

GetSongInfo(std::string songName, std::string artistName, int gdSongID);

public:
std::string songName();
std::string artistName();
int gdSongID();
GetSongInfoData(const int gdId, std::string songName, std::string artistName) noexcept
: m_gdId(gdId), m_songName(std::move(songName)), m_artistName(std::move(artistName)) {}

[[nodiscard]] int gdId() const noexcept { return m_gdId; }
[[nodiscard]] std::string_view songName() const noexcept { return m_songName; }
[[nodiscard]] std::string_view artistName() const noexcept { return m_artistName; }
};

} // namespace event
struct GetSongInfo final : geode::GlobalEvent<GetSongInfo, bool(const GetSongInfoData&), int> {
using GlobalEvent::GlobalEvent;
};

} // namespace jukebox
} // namespace jukebox::event
13 changes: 0 additions & 13 deletions jukebox/jukebox/events/manual_song_added.cpp

This file was deleted.

Loading
Loading