|
@@ -321,6 +321,61 @@ void append_global_bttv_mapping(CURL *curl,
|
|
append_bttv_emotes_array(result.value.array, mapping, downloads);
|
|
append_bttv_emotes_array(result.value.array, mapping, downloads);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+void append_channel_twitch_mapping(CURL *curl,
|
|
|
|
+ const char *emotes_url,
|
|
|
|
+ FILE *mapping,
|
|
|
|
+ Fixed_Array<Curl_Download, 1024> *downloads)
|
|
|
|
+{
|
|
|
|
+ curl_buffer.clean();
|
|
|
|
+
|
|
|
|
+ auto res = curl_perform_to_string_buffer(curl, emotes_url, &curl_buffer);
|
|
|
|
+ if (res != CURLE_OK) {
|
|
|
|
+ println(stderr, "curl_perform_to_string_buffer() failed: ",
|
|
|
|
+ curl_easy_strerror(res));
|
|
|
|
+ abort();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Memory memory = {};
|
|
|
|
+ memory.capacity = JSON_MEMORY_BUFFER_CAPACITY;
|
|
|
|
+ memory.buffer = json_memory_buffer;
|
|
|
|
+
|
|
|
|
+ String source = {
|
|
|
|
+ curl_buffer.size,
|
|
|
|
+ curl_buffer.data
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ Json_Result result = parse_json_value(&memory, source);
|
|
|
|
+ if (result.is_error) {
|
|
|
|
+ print_json_error(stdout, result, source, emotes_url);
|
|
|
|
+ abort();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ expect_json_type(result.value, JSON_OBJECT);
|
|
|
|
+ auto channel_emotes = json_object_value_by_key(result.value.object, SLT("emotes"));
|
|
|
|
+ expect_json_type(channel_emotes, JSON_ARRAY);
|
|
|
|
+
|
|
|
|
+ FOR_JSON (Json_Array, emote, channel_emotes.array) {
|
|
|
|
+ expect_json_type(emote->value, JSON_OBJECT);
|
|
|
|
+ auto emote_code = json_object_value_by_key(emote->value.object, SLT("code"));
|
|
|
|
+ expect_json_type(emote_code, JSON_STRING);
|
|
|
|
+ auto emote_id = json_object_value_by_key(emote->value.object, SLT("id"));
|
|
|
|
+ expect_json_type(emote_id, JSON_NUMBER);
|
|
|
|
+
|
|
|
|
+ Curl_Download download = {};
|
|
|
|
+
|
|
|
|
+ download.file.write("emotes/emote-");
|
|
|
|
+ download.file.write(downloads->size);
|
|
|
|
+ download.file.write(".png");
|
|
|
|
+
|
|
|
|
+ download.url.write("https://static-cdn.jtvnw.net/emoticons/v1/");
|
|
|
|
+ download.url.write(emote_id.string.data, emote_id.string.len);
|
|
|
|
+ download.url.write("/3.0");
|
|
|
|
+
|
|
|
|
+ println(mapping, emote_code.string, ",", download.file);
|
|
|
|
+ downloads->push(download);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
void append_channel_bttv_mapping(CURL *curl,
|
|
void append_channel_bttv_mapping(CURL *curl,
|
|
const char *emotes_url,
|
|
const char *emotes_url,
|
|
FILE *mapping,
|
|
FILE *mapping,
|
|
@@ -486,6 +541,12 @@ int main(int argc, char **argv)
|
|
char channel_url_buffer[1024];
|
|
char channel_url_buffer[1024];
|
|
String_Buffer channel_url = {sizeof(channel_url_buffer), channel_url_buffer};
|
|
String_Buffer channel_url = {sizeof(channel_url_buffer), channel_url_buffer};
|
|
|
|
|
|
|
|
+
|
|
|
|
+ // TODO: emote_downloader does not download global Twitch emotes
|
|
|
|
+ sprint(&channel_url, "https://api.twitchemotes.com/api/v4/channels/", channel_id);
|
|
|
|
+ append_channel_twitch_mapping(curl, channel_url.data, mapping, &downloads);
|
|
|
|
+ channel_url.size = 0;
|
|
|
|
+
|
|
append_global_bttv_mapping(curl, "https://api.betterttv.net/3/cached/emotes/global", mapping, &downloads);
|
|
append_global_bttv_mapping(curl, "https://api.betterttv.net/3/cached/emotes/global", mapping, &downloads);
|
|
|
|
|
|
sprint(&channel_url, "https://api.betterttv.net/3/cached/users/twitch/", channel_id);
|
|
sprint(&channel_url, "https://api.betterttv.net/3/cached/users/twitch/", channel_id);
|
|
@@ -500,6 +561,7 @@ int main(int argc, char **argv)
|
|
|
|
|
|
size_t transfers = 0;
|
|
size_t transfers = 0;
|
|
for (transfers = 0; transfers < min(downloads.size, MAX_PARALLEL); ++transfers) {
|
|
for (transfers = 0; transfers < min(downloads.size, MAX_PARALLEL); ++transfers) {
|
|
|
|
+ println(stdout, "Scheduling ", downloads.elements[transfers].url);
|
|
add_download_to_multi_handle(downloads.elements[transfers], cm);
|
|
add_download_to_multi_handle(downloads.elements[transfers], cm);
|
|
}
|
|
}
|
|
|
|
|