diff --git a/README.md b/README.md index d3d3474..49fef6f 100644 --- a/README.md +++ b/README.md @@ -7,35 +7,35 @@ Just go [there](https://github.com/JeFaitDesSpaghettis/HMCD/releases) or build i ## Build To build you'll git cmake and curl development packages.
Then run these commands:
-    ```git clone "https://github.com/JeFaitDesSpaghettis/HMCD"```
-    ```cd "./HMCD"```
-    ```cmake -G"MinGW Makefiles" -B"./build" -S"./"```
-    ```cmake --build "./build" -j8```
-    ```cmake --build "./build" --target install``` (optional)
-    ```cmake --build "./build" --target uninstall``` (to uninstall)
+    `git clone "https://github.com/JeFaitDesSpaghettis/HMCD"`
+    `cd "./HMCD"`
+    `cmake -G"MinGW Makefiles" -B"./build" -S"./"`
+    `cmake --build "./build" -j8`
+    `cmake --build "./build" --target install` (optional)
+    `cmake --build "./build" --target uninstall` (to uninstall)
## Explanation The url of a page uses the following scheme:
-```[XXXXXXXX]/comic/book/[BOOK_ID]/[CHAPTER]/[PAGE].jpg```
+`[XXXXXXXX]/comic/book/[BOOK_ID]/[CHAPTER]/[PAGE].jpg`
Where:
-+ ```XXXXXXXX``` is the cdn, it can be either
++ `XXXXXXXX` is the cdn, it can be either
"https://d2tpbmzklky1cl.cloudfront.net/manga/static" (global)
OR
"https://comicstatic.bh3.com/new_static_v2" (china)
-+ ```BOOK_ID``` is an 4 digit integer starting from 1001(and growing up) indicating thebook
-* ```CHAPTER``` is a non zero padded integer starting at 1 indicating the chapter
-+ ```PAGE``` is zero padded 4 digit integer starting at 0001
++ `BOOK_ID` is an 4 digit integer starting from 1001(and growing up) indicating thebook
+* `CHAPTER` is a non zero padded integer starting at 1 indicating the chapter
++ `PAGE` is zero padded 4 digit integer starting at 0001
They will be then downloaded using the following scheme:
[OUT_DIR]_[BOOK_ID]/Chapter[CHAPTER]/[CHAPTER][PAGE].jpg
Where:
-+ ```OUT_DIR``` is either "./GBBook" or "./CNBook"
-* ```BOOK_ID``` is an 4 digit integer starting from 1001(and growing up) indicating the book
-+ ```CHAPTER``` is a zero padded 2 digit integer starting at 1 indicating the chapter
-* ```CHAPTER``` is reused again in the page file name for having all pages in one directory
++ `OUT_DIR` is either "./GBBook" or "./CNBook"
+* `BOOK_ID` is an 4 digit integer starting from 1001(and growing up) indicating the book
++ `CHAPTER` is a zero padded 2 digit integer starting at 1 indicating the chapter
+* `CHAPTER` is reused again in the page file name for having all pages in one directory
without having the page names non conflicting
-* ```PAGE``` is zero padded 2 digit integer starting +* `PAGE` is zero padded 2 digit integer starting ## Why? It allows you to download the official hi3 manhuas releases in a easy way. \ diff --git a/include/HMCDCore/HMCD.h b/include/HMCDCore/HMCD.h index 77b0a42..5934abe 100644 --- a/include/HMCDCore/HMCD.h +++ b/include/HMCDCore/HMCD.h @@ -89,7 +89,7 @@ typedef struct _HmcdBook typedef struct _HmcdServer { unsigned int book_count; //!< Number of books available on this server - HMCD_SERVER_ID dl_server; //!< Server identifier indicated by the HMCD_SERVER_ID enum + HMCD_SERVER_ID server_id; //!< Server identifier indicated by the HMCD_SERVER_ID enum const char* base_url; //!< Base url for books (not ending in /) char* out_dir; //!< Default output directory HmcdBook books[]; //!< Array of books available @@ -167,10 +167,13 @@ static const HmcdServer HMCD_CN_SERVER = } }; +// Enable logs to stdout void hmcd_enable_logs(bool enable); +// Check if logs are enabled bool hmcd_enabled_logs(); +// Return NULL if server_id unrecognized const char* hmcd_get_server_name(HMCD_SERVER_ID server_id); // Check that certificate for https is here @@ -181,10 +184,11 @@ int hmcd_set_https_cert(CURL* curl_handle, const char* certificate_path); unsigned long long int hmcd_get_dir_size(const char* dir_name); // Get chapter count +// Returns 0 on error unsigned int hmcd_get_chap_cnt(const HmcdServer* target_server, unsigned int book_index); // Download book -// return != 0 means error +// Return != 0 on error int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsigned int first_chap, unsigned int last_chap); #ifdef __cplusplus diff --git a/include/HMCDCore/HMCPPD.hpp b/include/HMCDCore/HMCPPD.hpp new file mode 100644 index 0000000..f136e77 --- /dev/null +++ b/include/HMCDCore/HMCPPD.hpp @@ -0,0 +1,120 @@ +#ifndef HMCDPPD_HPP +#define HMCDPPD_HPP + +#include "HMCD.h" + +#include +#include +#include + +#include +#include +#include +#include + +namespace hmcppd +{ + // Download server + typedef HMCD_SERVER_ID SERVER_ID; + + /** + * Structure representing a book + */ + typedef struct _Book + { + std::uint32_t book_id; //!< ID of the book starting at 1001 + std::string book_name; //!< Name of the book, may be unicode + }Book; + + class DlServer + { + // PUBLIC FUNCTIONS + + public: DlServer(SERVER_ID server_id) + { + if (server_id == SERVER_ID::HMCD_CHINA) + dl_server = const_cast(&HMCD_CN_SERVER); + else if (server_id == SERVER_ID::HMCD_GLOBAL) + dl_server = const_cast(&HMCD_GLB_SERVER); + else throw std::runtime_error("Unrecognized server_id = " + std::to_string(server_id) + "\n"); + } + + public: DlServer() = delete; + + public: ~DlServer() + { + ; + } + + public: void enable_logs(bool enable) { hmcd_enable_logs(enable); } + + public: bool enabled_logs() { return hmcd_enabled_logs(); } + + public: std::string get_server_name() + { + const char* server_name = hmcd_get_server_name(dl_server->server_id); + if (!server_name) + throw std::runtime_error( + "get_server_name() failed, unrecognized server_id = " + std::to_string(dl_server->server_id) + "\n"); + return std::string(server_name); + } + + public: std::uint64_t get_dir_size(std::string dir_name) + { return static_cast(hmcd_get_dir_size(dir_name.c_str())); } + + public: unsigned int get_chap_cnt(unsigned int book_index) + { + unsigned int chap_count = hmcd_get_chap_cnt(dl_server, book_index); + if (chap_count == 0) + throw std::runtime_error("get_chap_cnt() failed\n"); + return chap_count; + } + + public: void dl_book(unsigned int book_index, unsigned int first_chap, unsigned int last_chap) + { + int result = hmcd_dl_book(dl_server, book_index, first_chap, last_chap); + if (result != 0) + throw std::runtime_error("dl_book() failed\n"); + } + + public: void switch_server() + { + switch (dl_server->server_id) + { + case SERVER_ID::HMCD_CHINA: + dl_server = const_cast(&HMCD_GLB_SERVER); + break; + case SERVER_ID::HMCD_GLOBAL: + dl_server = const_cast(&HMCD_CN_SERVER); + break; + default: + throw std::runtime_error("Unrecognized server_id = " + std::to_string(dl_server->server_id) + "\n"); + break; + } + } + + // GETTERS - SETTERS + + public: std::uint32_t get_book_count() { return dl_server->book_count; } + + public: SERVER_ID get_server_id() { return dl_server->server_id; } + + public: std::string get_out_dir() { return std::string(dl_server->out_dir); } + + public: std::vector get_books() + { + std::vector Books; + Books.resize(dl_server->book_count); + for (size_t index = 0; index < dl_server->book_count; index++) + Books[index] = {dl_server->books[index].book_id, std::string(dl_server->books[index].book_name)}; + return Books; + } + + // VARIABLES + + // Server + private: HmcdServer* dl_server = nullptr; + }; +} + +#endif /* HMCDPPD_HPP */ \ No newline at end of file diff --git a/src/HMCDCore/HMCD.c b/src/HMCDCore/HMCD.c index b114ee0..4c7fe54 100644 --- a/src/HMCDCore/HMCD.c +++ b/src/HMCDCore/HMCD.c @@ -148,6 +148,7 @@ unsigned long long int hmcd_get_dir_size(const char* dir_name) for (size_t index = 0; index < file_count; index++) free(file_list[index]); free(file_list); + return 0; } unsigned long long int total_dir_sz = 0; for (size_t index = 0; index < file_count; index++) @@ -163,6 +164,10 @@ unsigned int hmcd_get_chap_cnt(const HmcdServer* target_server, unsigned int boo { HMCD_ASSERT_W_ERR_LOG(book_index < target_server->book_count, "book_index(%i) is out of range", book_index) +#ifdef _WIN32 + SetConsoleOutputCP(CP_UTF8); +#endif + const char* target_base_url = target_server->base_url; unsigned int book_id = target_server->books[book_index].book_id; const char* book_name = target_server->books[book_index].book_name; @@ -171,7 +176,7 @@ unsigned int hmcd_get_chap_cnt(const HmcdServer* target_server, unsigned int boo "Getting chapter count of %s (%i %s)...", book_name, book_id, - hmcd_get_server_name(target_server->dl_server)) + hmcd_get_server_name(target_server->server_id)) CURL* check_handle; HMCD_CURL_INIT_W_ERR_CHK(check_handle, , 0) @@ -212,7 +217,7 @@ unsigned int hmcd_get_chap_cnt(const HmcdServer* target_server, unsigned int boo "%s (%i %s) has %i chapters", book_name, book_id, - hmcd_get_server_name(target_server->dl_server), + hmcd_get_server_name(target_server->server_id), (chap_count - 1)) curl_easy_cleanup(check_handle); @@ -238,6 +243,10 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig { HMCD_ASSERT_W_ERR_LOG(book_index < target_server->book_count, "book_index(%i) is out of range", book_index) +#ifdef _WIN32 + SetConsoleOutputCP(CP_UTF8); +#endif + const char* target_base_url = target_server->base_url; const char* target_out_dir = target_server->out_dir; unsigned int book_id = target_server->books[book_index].book_id; @@ -246,7 +255,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig HMCD_LOG("Downloading %s (%i %s chapter %i to %i)...", book_name, book_id, - hmcd_get_server_name(target_server->dl_server), + hmcd_get_server_name(target_server->server_id), first_chap, last_chap); @@ -267,7 +276,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig { HMCD_LOG_ERR("hmcd_set_https_cert(dl_handle, \"./cacert.pem\") failed"); curl_easy_cleanup(dl_handle); - return -4; + return -2; } curl_easy_setopt(dl_handle, CURLOPT_VERBOSE, 0L); curl_easy_setopt(dl_handle, CURLOPT_NOPROGRESS, 1L); @@ -320,7 +329,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig free(chap_dirname); free(book_dirname); curl_easy_cleanup(dl_handle);, - -9) + -3) curl_easy_getinfo(dl_handle, CURLINFO_HTTP_CODE, &http_code); // If page exists @@ -333,7 +342,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig free(chap_dirname); free(book_dirname); curl_easy_cleanup(dl_handle);, - -6) + -5) // Download it and write the data curl_easy_setopt(dl_handle, CURLOPT_URL, page_url); @@ -349,7 +358,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig free(chap_dirname); free(book_dirname); curl_easy_cleanup(dl_handle);, - -10) + -6) curl_easy_getinfo(dl_handle, CURLINFO_HTTP_CODE, &http_code); // If somehow we can't get it @@ -389,7 +398,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig free(chap_dirname); free(book_dirname); curl_easy_cleanup(dl_handle); - return -5; + return -4; } } free(chap_url); @@ -400,7 +409,7 @@ int hmcd_dl_book(const HmcdServer* target_server, unsigned int book_index, unsig HMCD_LOG("Downloaded %s (%i %s chapter %i to %i) in %f (seconds)", book_name, book_id, - hmcd_get_server_name(target_server->dl_server), + hmcd_get_server_name(target_server->server_id), first_chap, last_chap, elapsed_sec);