Added url parser class to find out which type of url is entered
This commit is contained in:
@@ -9,6 +9,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
add_executable(spotify-downloader
|
add_executable(spotify-downloader
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
src/url_parser.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(external/CLI11)
|
add_subdirectory(external/CLI11)
|
||||||
|
|||||||
10
src/main.cpp
10
src/main.cpp
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
#include "url_parser.hpp"
|
||||||
#include <CLI/CLI.hpp>
|
#include <CLI/CLI.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -25,6 +26,15 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (cmd_download->parsed()) {
|
if (cmd_download->parsed()) {
|
||||||
std::cout << "Target URL: " << url << "\n";
|
std::cout << "Target URL: " << url << "\n";
|
||||||
|
auto parsed = UrlParser::parse(url);
|
||||||
|
|
||||||
|
if (!parsed) {
|
||||||
|
std::cerr << "Unsupported URL\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Type: " << parsed->type << '\n';
|
||||||
|
std::cout << "ID: " << parsed->id << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
111
src/url_parser.cpp
Normal file
111
src/url_parser.cpp
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#include "url_parser.hpp"
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, UrlType type) {
|
||||||
|
switch (type) {
|
||||||
|
case UrlType::SpotifyTrack:
|
||||||
|
return os << "Spotify Track";
|
||||||
|
|
||||||
|
case UrlType::SpotifyPlaylist:
|
||||||
|
return os << "Spotify Playlist";
|
||||||
|
|
||||||
|
case UrlType::SpotifyAlbum:
|
||||||
|
return os << "Spotify Album";
|
||||||
|
|
||||||
|
case UrlType::SpotifyArtist:
|
||||||
|
return os << "Spotify Artist";
|
||||||
|
|
||||||
|
case UrlType::YoutubeVideo:
|
||||||
|
return os << "YouTube Video";
|
||||||
|
|
||||||
|
case UrlType::YoutubePlaylist:
|
||||||
|
return os << "YouTube Playlist";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return os << "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ParsedUrl> UrlParser::parse(const std::string &url) {
|
||||||
|
|
||||||
|
std::smatch match;
|
||||||
|
|
||||||
|
// Spotify
|
||||||
|
{
|
||||||
|
static const std::regex spotify(
|
||||||
|
R"(https?://open\.spotify\.com/(track|playlist|album|artist)/([A-Za-zA-Z0-9]+))");
|
||||||
|
|
||||||
|
if (std::regex_search(url, match, spotify)) {
|
||||||
|
|
||||||
|
const auto resource = match[1].str();
|
||||||
|
const auto id = match[2].str();
|
||||||
|
|
||||||
|
if (resource == "track")
|
||||||
|
return ParsedUrl{UrlType::SpotifyTrack, id};
|
||||||
|
|
||||||
|
if (resource == "playlist")
|
||||||
|
return ParsedUrl{UrlType::SpotifyPlaylist, id};
|
||||||
|
|
||||||
|
if (resource == "album")
|
||||||
|
return ParsedUrl{UrlType::SpotifyAlbum, id};
|
||||||
|
|
||||||
|
if (resource == "artist")
|
||||||
|
return ParsedUrl{UrlType::SpotifyArtist, id};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spotify URI
|
||||||
|
{
|
||||||
|
static const std::regex spotify_uri(
|
||||||
|
R"(spotify:(track|playlist|album|artist):([A-Za-z0-9]+))");
|
||||||
|
|
||||||
|
if (std::regex_search(url, match, spotify_uri)) {
|
||||||
|
|
||||||
|
const auto resource = match[1].str();
|
||||||
|
const auto id = match[2].str();
|
||||||
|
|
||||||
|
if (resource == "track")
|
||||||
|
return ParsedUrl{UrlType::SpotifyTrack, id};
|
||||||
|
|
||||||
|
if (resource == "playlist")
|
||||||
|
return ParsedUrl{UrlType::SpotifyPlaylist, id};
|
||||||
|
|
||||||
|
if (resource == "album")
|
||||||
|
return ParsedUrl{UrlType::SpotifyAlbum, id};
|
||||||
|
|
||||||
|
if (resource == "artist")
|
||||||
|
return ParsedUrl{UrlType::SpotifyArtist, id};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// YouTube Playlist
|
||||||
|
{
|
||||||
|
static const std::regex yt_playlist(
|
||||||
|
R"(https?://(?:www\.)?youtube\.com/playlist\?list=([^&]+))");
|
||||||
|
|
||||||
|
if (std::regex_search(url, match, yt_playlist))
|
||||||
|
return ParsedUrl{UrlType::YoutubePlaylist, match[1].str()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// YouTube Video
|
||||||
|
{
|
||||||
|
static const std::regex yt_video(
|
||||||
|
R"(https?://(?:www\.)?youtube\.com/watch\?.*v=([^&]+))");
|
||||||
|
|
||||||
|
if (std::regex_search(url, match, yt_video))
|
||||||
|
return ParsedUrl{UrlType::YoutubeVideo, match[1].str()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// youtu.be
|
||||||
|
{
|
||||||
|
static const std::regex yt_short(R"(https?://youtu\.be/([^?&]+))");
|
||||||
|
|
||||||
|
if (std::regex_search(url, match, yt_short))
|
||||||
|
return ParsedUrl{UrlType::YoutubeVideo, match[1].str()};
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
28
src/url_parser.hpp
Normal file
28
src/url_parser.hpp
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class UrlType {
|
||||||
|
SpotifyTrack,
|
||||||
|
SpotifyPlaylist,
|
||||||
|
SpotifyAlbum,
|
||||||
|
SpotifyArtist,
|
||||||
|
|
||||||
|
YoutubeVideo,
|
||||||
|
YoutubePlaylist,
|
||||||
|
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParsedUrl {
|
||||||
|
UrlType type;
|
||||||
|
std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, UrlType type);
|
||||||
|
|
||||||
|
class UrlParser {
|
||||||
|
public:
|
||||||
|
static std::optional<ParsedUrl> parse(const std::string &url);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user