int16_t sendProwlNotification(const char* apikey, const char* event, const char* desc) { int16_t result = -1; int32_t data_size; char url[128]; HTTPResponse *response = NULL; char *data = NULL; data = createProwlMessage(apikey, event, desc, &data_size); if(data) { snprintf(url, 128, "%s%s", PROWL_URL, PROWL_ADD); response = sendHTTPData(url, NULL, data, data_size); if(response) { if(response->responseCode == 200) { result = 1; } else { dbg_printf(P_ERROR, "Prowl Notification failed: %s (%d)", getProwlErrorMessage(response->responseCode), response->responseCode); result = -response->responseCode; } HTTPResponse_free(response); } am_free(data); } return result; }
int8_t getRPCVersion(const char* host, uint16_t port, const char* auth) { char url[MAX_URL_LEN]; int8_t result = 0; char *response = NULL; HTTPResponse *res = NULL; const char *JSONstr = "{\n" "\"method\": \"session-get\",\n" "\"arguments\": {}\n" "}"; if(!host) { return 0; } snprintf( url, MAX_URL_LEN, "http://%s:%d/transmission/rpc", host, port); res = sendHTTPData(url, auth, JSONstr, strlen(JSONstr)); if(res != NULL && res->responseCode == 200) { dbg_printf(P_DBG, "[getRPCVersion] got response!"); response = parseResponse(res->data); if(response) { if(!strncmp(response, "success", 7)) { result = parseRPCVersion(res->data); dbg_printf(P_DBG, "[getRPCVersion] RPC version: %d", result); } am_free((void*)response); } HTTPResponse_free(res); } return result; }
int16_t verifyProwlAPIKey(const char* apikey) { int16_t result = -1; char url[128]; HTTPResponse *response = NULL; CURL *curl_session = NULL; if(apikey) { snprintf(url, 128, "%s%s?apikey=%s", PROWL_URL, PROWL_VERIFY, apikey); response = getHTTPData(url, NULL, &curl_session); if(response) { if(response->responseCode == 200) { dbg_printf(P_INFO, "Prowl API key '%s' is valid", apikey); result = 1; } else { dbg_printf(P_ERROR, "Error: Prowl API key '%s' is invalid (%d)!", apikey, response->responseCode); result = -response->responseCode; } HTTPResponse_free(response); } closeCURLSession(curl_session); } return result; }
PRIVATE uint16_t processFeed(auto_handle *session, rss_feed* feed, uint8_t firstrun) { HTTPResponse *response = NULL; CURL *curl_session = NULL; uint32_t item_count = 0; response = getRSSFeed(feed, &curl_session); dbg_printf(P_INFO2, "[processFeed] curl_session=%p", (void*)curl_session); if(!curl_session && response != NULL) { dbg_printf(P_ERROR, "curl_session == NULL but response != NULL"); abort(); } if (response) { if(response->responseCode == 200 && response->data) { simple_list items = parse_xmldata(response->data, response->size, &item_count, &feed->ttl); if(firstrun) { session->max_bucket_items += item_count; dbg_printf(P_INFO2, "History bucket size changed: %d", session->max_bucket_items); } processRSSList(session, items, feed->id); freeList(&items, freeFeedItem); } HTTPResponse_free(response); closeCURLSession(curl_session); } return item_count; }
PRIVATE void processRSSList(auto_handle *session, const simple_list items, uint16_t feedID) { simple_list current_item = items; simple_list current_url = NULL; am_filter filter = NULL; const char * url; char path[4096]; HTTPResponse *response = NULL; while(current_item && current_item->data) { feed_item item = (feed_item)current_item->data; current_url = item->urls; while(current_url && current_url->data) { url = (const char*)current_url->data; if(isMatch(session->filters, url, &filter)) { if(!session->match_only) { get_filename(path, NULL, url, session->download_folder); if (!has_been_downloaded(session->downloads, url) && !file_exists(path)) { dbg_printft(P_MSG, "[%d] Found new download: %s (%s)", feedID, item->name, url); response = downloadFile(url, path, filter->agent); if(response) { if(response->responseCode == 200) { if(session->prowl_key_valid) { prowl_sendNotification(PROWL_NEW_TRAILER, session->prowl_key, item->name); } if(session->download_done_script && *(session->download_done_script)) { callDownloadDoneScript(session->download_done_script, path); } dbg_printf(P_MSG, " Download complete (%dMB) (%.2fkB/s)", response->size / 1024 / 1024, response->downloadSpeed / 1024); /* add url to bucket list */ if (addToBucket(url, &session->downloads, session->max_bucket_items) == 0) { session->bucket_changed = 1; save_state(session->statefile, session->downloads); } } else { dbg_printf(P_ERROR, " Error: Download failed (Error Code %d)", response->responseCode); if(session->prowl_key_valid) { prowl_sendNotification(PROWL_DOWNLOAD_FAILED, session->prowl_key, item->name); } } HTTPResponse_free(response); } } else { dbg_printf(P_MSG, "File downloaded previously: %s", basename(path)); } } else { dbg_printft(P_MSG, "[%s] Match: %s (%s)", feedID, item->name, url); } } current_url = current_url->next; } current_item = current_item->next; } }
PRIVATE HTTPResponse* downloadTorrent(CURL* curl_session, const char* url) { HTTPResponse * torrent = NULL; dbg_printf(P_INFO2, "[downloadTorrent] url=%s, curl_session=%p", url, (void*)curl_session); torrent = getHTTPData(url, NULL, &curl_session); if(torrent && torrent->responseCode != 200) { switch(torrent->responseCode) { case 401: dbg_printf(P_ERROR, "Error downloading torrent (HTTP error %d: Bad authentication)", torrent->responseCode); break; case 403: dbg_printf(P_ERROR, "Error downloading torrent (HTTP error %d: Forbidden)", torrent->responseCode); break; default: dbg_printf(P_ERROR, "Error downloading torrent (HTTP error %d)", torrent->responseCode); } HTTPResponse_free(torrent); torrent = NULL; } return torrent; }
PRIVATE void processRSSList(auto_handle *session, CURL *curl_session, const simple_list items, const rss_feed * feed) { simple_list current_item = items; HTTPResponse *torrent = NULL; char fname[MAXPATHLEN]; char *download_folder = NULL; char *feedID = NULL; char *download_url = NULL; if(!curl_session && !session) { printf("curl_session == NULL && session == NULL\n"); abort(); } if(feed != NULL) { feedID = feed->id; } while(current_item && current_item->data) { feed_item item = (feed_item)current_item->data; if(isMatch(session->filters, item->name, feedID, &download_folder)) { if(!session->match_only) { if(has_been_downloaded(session->downloads, item)) { dbg_printf(P_INFO, "Duplicate torrent: %s", item->name); } else { int8_t result = -1; dbg_printft(P_MSG, "[%s] Found new download: %s (%s)", feedID, item->name, item->url); if(isMagnetURI(item->url)) { result = addMagnetToTM(session, item->url, download_folder); } else { // It's a torrent file // Rewrite torrent URL, if necessary if((feed != NULL) && (feed->url_pattern != NULL) && (feed->url_replace != NULL)) { download_url = rewriteURL(item->url, feed->url_pattern, feed->url_replace); } torrent = downloadTorrent(curl_session, download_url != NULL ? download_url : item->url); if(torrent) { get_filename(fname, torrent->content_filename, item->url, session->torrent_folder); /* add torrent to Transmission */ result = addTorrentToTM(session, torrent->data, torrent->size, fname, download_folder); HTTPResponse_free(torrent); } am_free(download_url); } // process result if( result >= 0) { //result == 0 -> duplicate torrent if(result > 0) { //torrent was added if(session->prowl_key_valid) { prowl_sendNotification(PROWL_NEW_DOWNLOAD, session->prowl_key, item->name); } if(session->toasty_key) { toasty_sendNotification(PROWL_NEW_DOWNLOAD, session->toasty_key, item->name); } if(session->pushalot_key) { pushalot_sendNotification(PUSHALOT_NEW_DOWNLOAD, session->pushalot_key, item->name); } if(session->pushover_key) { pushover_sendNotification(PUSHOVER_NEW_DOWNLOAD, session->pushover_key, item->name); } } /* add url to bucket list */ result = addToBucket(item->guid != NULL ? item->guid : item->url, &session->downloads, session->max_bucket_items); if (result == 0) { session->bucket_changed = 1; save_state(session->statefile, session->downloads); } } else { //an error occurred if(session->prowl_key_valid) { prowl_sendNotification(PROWL_DOWNLOAD_FAILED, session->prowl_key, item->name); } if(session->toasty_key) { toasty_sendNotification(PROWL_DOWNLOAD_FAILED, session->toasty_key, item->name); } if(session->pushalot_key) { pushalot_sendNotification(PUSHALOT_DOWNLOAD_FAILED, session->pushalot_key, item->name); } if(session->pushover_key) { pushover_sendNotification(PUSHOVER_DOWNLOAD_FAILED, session->pushover_key, item->name); } } } } else { dbg_printft(P_MSG, "[%s] Match: %s (%s)", feedID, item->name, item->url); } } current_item = current_item->next; } }