static gboolean fetch_tweets(gpointer data) { if (!enable) return FALSE; CURL* curl = NULL; CURLcode res = CURLE_OK; long http_status = 0; MEMFILE* mbody = NULL; char* body = NULL; xmlDocPtr doc = NULL; xmlNodeSetPtr nodes = NULL; xmlXPathContextPtr ctx = NULL; xmlXPathObjectPtr path = NULL; mbody = memfopen(); curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_URL, "https://api.twitter.com/1/statuses/public_timeline.xml"); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQUEST_TIMEOUT); curl_easy_setopt(curl, CURLOPT_TIMEOUT, REQUEST_TIMEOUT); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mbody); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); res = curl_easy_perform(curl); if (res == CURLE_OK) curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &http_status); curl_easy_cleanup(curl); body = memfstrdup(mbody); memfclose(mbody); if (res != CURLE_OK) { goto leave; } if (http_status == 304) { goto leave; } if (http_status != 200) { goto leave; } doc = body ? xmlParseDoc((xmlChar*) body) : NULL; if (!doc) goto leave; ctx = xmlXPathNewContext(doc); if (!ctx) goto leave; path = xmlXPathEvalExpression((xmlChar*)"/statuses/status", ctx); if (!path || xmlXPathNodeSetIsEmpty(path->nodesetval)) goto leave; nodes = path->nodesetval; int n, length = xmlXPathNodeSetGetLength(nodes); gchar* first_id = NULL; for(n = 0; n < length; n++) { char* id = NULL; char* user_id = NULL; char* icon = NULL; char* real = NULL; char* user_name = NULL; char* text = NULL; char* date = NULL; xmlNodePtr status = nodes->nodeTab[n]; if (status->type != XML_ATTRIBUTE_NODE && status->type != XML_ELEMENT_NODE && status->type != XML_CDATA_SECTION_NODE) continue; status = status->children; while(status) { if (!strcmp("id", (char*) status->name)) id = (char*) status->children->content; if (!strcmp("created_at", (char*) status->name)) date = (char*) status->children->content; if (!strcmp("text", (char*) status->name)) { if (status->children) text = (char*) status->children->content; } /* user nodes */ if (!strcmp("user", (char*) status->name)) { xmlNodePtr user = status->children; while(user) { if (!strcmp("id", (char*) user->name)) user_id = XML_CONTENT(user); if (!strcmp("name", (char*) user->name)) real = XML_CONTENT(user); if (!strcmp("screen_name", (char*) user->name)) user_name = XML_CONTENT(user); if (!strcmp("profile_image_url", (char*) user->name)) { icon = XML_CONTENT(user); icon = (char*) g_strchomp((gchar*) icon); icon = (char*) g_strchug((gchar*) icon); } user = user->next; } } status = status->next; } if (!first_id) first_id = id; if (id && last_id && !strcmp(id, last_id)) break; if (text && user_id) { NOTIFICATION_INFO* ni = g_new0(NOTIFICATION_INFO, 1); ni->title = g_strdup(user_name); ni->text = g_strdup(text); ni->icon = g_strdup(icon); g_timeout_add(1000 * (n+1), delay_show, ni); } } if (last_id) g_free(last_id); if (first_id) last_id = g_strdup(first_id); leave: if (body) free(body); if (path) xmlXPathFreeObject(path); if (ctx) xmlXPathFreeContext(ctx); if (doc) xmlFreeDoc(doc); g_timeout_add(1000 * length, fetch_tweets, NULL); return FALSE; }
static gchar* get_album_art(const char* artist, const char* album) { CURL* curl = NULL; CURLcode res = CURLE_OK; long http_status = 0; MEMFILE* mbody = NULL; char* body = NULL; xmlDocPtr doc = NULL; xmlNodeSetPtr nodes = NULL; xmlXPathContextPtr ctx = NULL; xmlXPathObjectPtr path = NULL; char* info = g_strdup_printf("%s %s", artist, album); char* qinfo = urlencode_alloc(info); g_free(info); gchar* url = g_strdup_printf( "http://api.search.yahoo.com/ImageSearchService/V1/imageSearch?" "appid=%s&query=%s&type=all&results=10&start=1&format=any&adult_ok=True", "YahooExample", qinfo); mbody = memfopen(); curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQUEST_TIMEOUT); curl_easy_setopt(curl, CURLOPT_TIMEOUT, REQUEST_TIMEOUT); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mbody); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); res = curl_easy_perform(curl); if (res == CURLE_OK) curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &http_status); curl_easy_cleanup(curl); body = memfstrdup(mbody); memfclose(mbody); if (res != CURLE_OK) { goto leave; } if (http_status == 304) { goto leave; } if (http_status != 200) { goto leave; } doc = body ? xmlParseDoc((xmlChar*) body) : NULL; xmlNodePtr node = doc->children; gchar* image_url = NULL; if (strcmp((const char*) node->name, "ResultSet")) goto leave; for (node = node->children; node; node = node->next) { if (strcmp((const char*) node->name, "Result")) continue; for (node = node->children; node; node = node->next) { if (strcmp((const char*) node->name, "Thumbnail")) continue; for (node = node->children; node; node = node->next) { if (strcmp((const char*) node->name, "Url")) continue; image_url = g_strdup(XML_CONTENT(node)); break; } if (image_url) break; } if (image_url) break; } leave: if (body) free(body); if (path) xmlXPathFreeObject(path); if (ctx) xmlXPathFreeContext(ctx); if (doc) xmlFreeDoc(doc); return image_url; }
int main(int argc, char* argv[]) { CURL* curl = NULL; CURLcode res; int status = 0; char error[CURL_ERROR_SIZE]; char fname[256]; char line[256]; char cookie[2048]; char query[2048]; char* buf = NULL; char* ptr = NULL; char* tmp = NULL; char* id; FILE* fp = NULL; MEMFILE* mf; // mem file MEMFILE* hf; // mem file for header // usage if (argc != 2) { fputs("usage: nicodown [video_id]\n", stderr); goto leave; } if (!(ptr = getenv("HOME"))) { #ifdef _WIN32 if (!(ptr = getenv("USERPROFILE"))) { fprintf(stderr, "failed to get HOME directory\n"); goto leave; } #else fprintf(stderr, "failed to get HOME directory\n"); goto leave; #endif } sprintf(fname, "%s/.nicodownrc", ptr); fp = fopen(fname, "r"); if (!fp || !fgets(line, sizeof(line), fp)) { if (fp) fclose(fp); fprintf(stderr, "failed to read ~/.nicodownrc\n"); goto leave; } fclose(fp); tmp = strpbrk(line, "\r\n"); if (tmp) *tmp = 0; ptr = strchr(line, ':'); if (!ptr) { fprintf(stderr, "failed to parse ~/.nicodownrc\n"); goto leave; } *ptr++ = 0; id = argv[1]; if (!strncmp(id, WATCH_URL_BASE, strlen(WATCH_URL_BASE))) { id += strlen(WATCH_URL_BASE); } sprintf(query, "mail_tel=%s&password=%s&next_url=/watch/%s", line, ptr, id); // default filename sprintf(fname, "%s.flv", id); curl = curl_easy_init(); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); // login mf = memfopen(); hf = memfopen(); curl_easy_setopt(curl, CURLOPT_URL, "https://secure.nicovideo.jp/secure/login?site=niconico"); curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); curl_easy_setopt(curl, CURLOPT_HEADERDATA, hf); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, memfwrite); res = curl_easy_perform(curl); if (res != CURLE_OK) { fputs(error, stderr); memfclose(mf); memfclose(hf); goto leave; } // parse cookie memset(cookie, 0, sizeof(cookie)); buf = memfstrdup(hf); tmp = buf; while (tmp = strstr(tmp, "Set-Cookie: ")) { ptr = tmp; tmp = strpbrk(ptr, "\r\n;"); if (tmp) *tmp = 0; strcpy(cookie, ptr + 12); if (strncmp(cookie, "user_session=user", 17) == 0) { curl_easy_setopt(curl, CURLOPT_COOKIE, cookie); break; } tmp++; } free(buf); memfclose(mf); memfclose(hf); mf = memfopen(); hf = memfopen(); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); curl_easy_setopt(curl, CURLOPT_HEADERDATA, hf); // redirect sprintf(query, "http://www.nicovideo.jp/watch/%s", id); curl_easy_setopt(curl, CURLOPT_URL, query); curl_easy_setopt(curl, CURLOPT_POST, 0); res = curl_easy_perform(curl); if (res != CURLE_OK) { fputs(error, stderr); memfclose(mf); memfclose(hf); goto leave; } // parse cookie buf = memfstrdup(hf); ptr = NULL; tmp = buf; while (tmp = strstr(tmp, "Set-Cookie: ")) { ptr = tmp + 12; tmp = strpbrk(ptr, "\r\n;"); if (tmp) *tmp = 0; strcat(cookie, ";"); strcat(cookie, ptr); tmp++; } curl_easy_setopt(curl, CURLOPT_COOKIE, cookie); free(buf); // parse response body buf = memfstrdup(mf); if (buf && strstr(buf, "id=\"login_bar\"")) { free(buf); fprintf(stderr, "failed to login\n"); memfclose(mf); memfclose(hf); goto leave; } free(buf); memfclose(hf); memfclose(mf); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL); curl_easy_setopt(curl, CURLOPT_HEADERDATA, NULL); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, NULL); curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); // get video query, and get filename sprintf(query, "http://www.nicovideo.jp/api/getthumbinfo?v=%s", id); mf = memfopen(); curl_easy_setopt(curl, CURLOPT_URL, query); curl_easy_setopt(curl, CURLOPT_POST, 0); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); res = curl_easy_perform(curl); if (res != CURLE_OK) { fputs(error, stderr); memfclose(mf); goto leave; } #ifdef USE_LIBXML // parse title node { xmlDocPtr doc = NULL; xmlXPathContextPtr xpathctx; xmlXPathObjectPtr xpathobj; doc = xmlParseMemory(mf->data, mf->size); xpathctx = doc ? xmlXPathNewContext(doc) : NULL; xpathobj = xpathctx ? xmlXPathEvalExpression((xmlChar*) "//title", xpathctx) : NULL; if (xpathobj) { int n; xmlNodeSetPtr nodes = xpathobj->nodesetval; for(n = 0; nodes && n < xmlXPathNodeSetGetLength(nodes); n++) { xmlNodePtr node = nodes->nodeTab[n]; if(node->type != XML_ATTRIBUTE_NODE && node->type != XML_ELEMENT_NODE && node->type != XML_CDATA_SECTION_NODE) continue; if (node->type == XML_CDATA_SECTION_NODE) sprintf(fname, "%s.flv", (char*) node->content); else if (node->children) sprintf(fname, "%s.flv", (char*) node->children->content); break; } } if (xpathobj ) xmlXPathFreeObject(xpathobj); if (xpathctx) xmlXPathFreeContext(xpathctx); if (doc) xmlFreeDoc(doc); } #else buf = memfstrdup(mf); ptr = buf ? strstr(buf, "<title>") : NULL; if (ptr) { ptr += 7; tmp = strstr(ptr, "</title>"); if (*tmp) { *tmp = 0; sprintf(fname, "%s.flv", ptr); } } if (buf) free(buf); #endif memfclose(mf); #ifdef _WIN32 { UINT codePage; size_t wcssize; wchar_t* wcsstr; size_t mbssize; char* mbsstr; codePage = CP_UTF8; wcssize = MultiByteToWideChar(codePage, 0, fname, -1, NULL, 0); wcsstr = (wchar_t*) malloc(sizeof(wchar_t) * (wcssize + 1)); wcssize = MultiByteToWideChar(codePage, 0, fname, -1, wcsstr, wcssize + 1); wcsstr[wcssize] = 0; codePage = GetACP(); mbssize = WideCharToMultiByte(codePage, 0, (LPCWSTR) wcsstr,-1,NULL,0,NULL,NULL); mbsstr = (char*) malloc(mbssize+1); mbssize = WideCharToMultiByte(codePage, 0, (LPCWSTR) wcsstr, -1, mbsstr, mbssize, NULL, NULL); mbsstr[mbssize] = 0; strcpy(fname, mbsstr); free(mbsstr); free(wcsstr); } #endif // get video query sprintf(query, "http://flapi.nicovideo.jp/api/getflv?v=%s", id); mf = memfopen(); curl_easy_setopt(curl, CURLOPT_URL, query); curl_easy_setopt(curl, CURLOPT_POST, 0); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mf); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); res = curl_easy_perform(curl); if (res != CURLE_OK) { fputs(error, stderr); memfclose(mf); goto leave; } buf = memfstrdup(mf); ptr = strstr(buf, "url="); if (!ptr) { if (buf) free(buf); fprintf(stderr, "failed to get video info\n"); memfclose(mf); goto leave; } tmp = strstr(ptr, "&"); if (tmp) *tmp = 0; tmp = ptr; while(*tmp) { if (IS_QUOTED(tmp)) { unsigned int num = 0; sscanf(tmp+1, "%02x", &num); *tmp = (char)num; strcpy(tmp + 1, tmp + 3); } tmp++; } strcpy(query, ptr + 4); printf("URL: %s\n", query); free(buf); memfclose(mf); // sanitize filename ptr = fname; while (*ptr) { if (strchr("\\/|:<>\"?*", *ptr)) *ptr = '_'; ptr++; } // download video fp = fopen(fname, "wb"); if (!fp) { fprintf(stderr, "failed to open file: %s\n", fname); goto leave; } curl_easy_setopt(curl, CURLOPT_URL, query); curl_easy_setopt(curl, CURLOPT_POST, 0); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fwrite); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress); curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, (void*)fname); curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, BUFSIZ); /* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); */ res = curl_easy_perform(curl); fclose(fp); if (res != CURLE_OK) { fputs(error, stderr); goto leave; } leave: if (curl) curl_easy_cleanup(curl); printf("\n"); return 0; }
static GdkPixbuf* url2pixbuf(const char* url, GError** error) { GdkPixbuf* pixbuf = NULL; GdkPixbufLoader* loader = NULL; GError* _error = NULL; CURL* curl = NULL; MEMFILE* mbody; MEMFILE* mhead; char* head; char* body; unsigned long size; CURLcode res = CURLE_FAILED_INIT; curl = curl_easy_init(); if (!curl) return NULL; mbody = memfopen(); mhead = memfopen(); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, REQUEST_TIMEOUT); curl_easy_setopt(curl, CURLOPT_TIMEOUT, REQUEST_TIMEOUT); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memfwrite); curl_easy_setopt(curl, CURLOPT_WRITEDATA, mbody); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, memfwrite); curl_easy_setopt(curl, CURLOPT_HEADERDATA, mhead); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); res = curl_easy_perform(curl); curl_easy_cleanup(curl); head = memfstrdup(mhead); memfclose(mhead); body = memfstrdup(mbody); size = mbody->size; memfclose(mbody); if (res == CURLE_OK) { char* ctype; char* csize; ctype = get_http_header_alloc(head, "Content-Type"); csize = get_http_header_alloc(head, "Content-Length"); #ifdef _WIN32 if (ctype && (!strcmp(ctype, "image/jpeg") || !strcmp(ctype, "image/gif"))) { char temp_path[MAX_PATH]; char temp_filename[MAX_PATH]; FILE* fp; GetTempPath(sizeof(temp_path), temp_path); GetTempFileName(temp_path, "growl-for-linux-", 0, temp_filename); fp = fopen(temp_filename, "wb"); if (fp) { fwrite(body, size, 1, fp); fclose(fp); } pixbuf = gdk_pixbuf_new_from_file(temp_filename, NULL); DeleteFile(temp_filename); } else #endif { if (ctype) loader = (GdkPixbufLoader*) gdk_pixbuf_loader_new_with_mime_type(ctype, error); if (csize) size = atol(csize); if (!loader) loader = gdk_pixbuf_loader_new(); if (body && gdk_pixbuf_loader_write(loader, (const guchar*) body, size, &_error)) { pixbuf = gdk_pixbuf_loader_get_pixbuf(loader); } } if (ctype) free(ctype); if (csize) free(csize); if (loader) gdk_pixbuf_loader_close(loader, NULL); } else { _error = g_error_new_literal(G_FILE_ERROR, res, curl_easy_strerror(res)); } free(head); free(body); /* cleanup callback data */ if (error && _error) *error = _error; return pixbuf; }