-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
99 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,6 @@ | |
#include <stdlib.h> | ||
|
||
#include <curl/curl.h> | ||
#include <curl/types.h> | ||
#include <curl/easy.h> | ||
|
||
#include <sys/stat.h> | ||
|
@@ -20,7 +19,6 @@ bool optHtmlLink = false; | |
bool optMessageBoard = false; | ||
bool optMessageBoardLink = false; | ||
bool optOpenBrowser = false; | ||
bool optDelete = false; | ||
bool optShowHelp = false; | ||
bool optShowVersion = false; | ||
|
||
|
@@ -35,21 +33,20 @@ void init(); | |
|
||
bool usage() | ||
{ | ||
printf("usage: imguru [-odpilmbdrhv] [-s max_dimension] source_file ...\n"); | ||
printf("usage: imguru [-odpilmbdhv] [-s max_dimension] source_file ...\n"); | ||
return true; | ||
} | ||
|
||
bool showHelp() | ||
{ | ||
printf("usage: imguru [-odpilmbdrhv] [-s max_dimension] source_file ...\n"); | ||
printf("usage: imguru [-odpilmbdhv] [-s max_dimension] source_file ...\n"); | ||
printf("Uploads one of more images to imgur.com. Supports all image formats supported by Mac OS X and will resize and convert to JPEG before uploading.\n\n"); | ||
printf("-d Display direct link to image (default)\n"); | ||
printf("-p Display link to image page\n"); | ||
printf("-i Display HTML image\n"); | ||
printf("-l Display HTML link\n"); | ||
printf("-m Display message board image code\n"); | ||
printf("-b Display message board link code\n"); | ||
printf("-r Display delete link\n"); | ||
printf("-o Open uploaded images in browser\n"); | ||
printf("-s Resize image to have maximum dimension of max_dimension\n"); | ||
printf("-h Display help\n"); | ||
|
@@ -59,7 +56,7 @@ bool showHelp() | |
|
||
bool showVersion() | ||
{ | ||
printf("imguru v1.0.3 by Roland Rabien ([email protected]) %s.\n", __DATE__); | ||
printf("imguru v1.0.4 by Roland Rabien ([email protected]) %s.\n", __DATE__); | ||
|
||
return true; | ||
} | ||
|
@@ -80,57 +77,101 @@ static size_t outputCallback(void *ptr, size_t size, size_t nmemb, void *data) | |
return sz; | ||
} | ||
|
||
std::string imageIdFromXml(std::string xml) | ||
{ | ||
TiXmlDocument doc; | ||
doc.Parse(xml.c_str()); | ||
|
||
TiXmlElement* root = doc.RootElement(); | ||
if (root) | ||
{ | ||
TiXmlElement* id = root->FirstChildElement("id"); | ||
if (id) | ||
return id->GetText(); | ||
} | ||
|
||
return ""; | ||
|
||
} | ||
|
||
std::string getImageInfo(std::string id) | ||
{ | ||
CURL *curl; | ||
CURLcode res; | ||
|
||
struct curl_slist *headers = NULL; | ||
|
||
std::string output; | ||
|
||
curl = curl_easy_init(); | ||
|
||
headers = curl_slist_append(headers, "Authorization: Client-ID 51f229880e3ea84"); | ||
|
||
if (curl) | ||
{ | ||
std::string url = std::string("https://api.imgur.com/3/image/") + id + "/.xml"; | ||
|
||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); | ||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); | ||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, outputCallback); | ||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&output); | ||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "penis-browser/1.1"); | ||
|
||
res = curl_easy_perform(curl); | ||
|
||
curl_easy_cleanup(curl); | ||
} | ||
|
||
return output; | ||
} | ||
|
||
std::string uploadImage(std::string filename) | ||
{ | ||
CURL *curl; | ||
CURLcode res; | ||
|
||
struct curl_httppost *formpost = NULL; | ||
struct curl_httppost *lastptr = NULL; | ||
|
||
struct curl_slist *headers = NULL; | ||
|
||
std::string output; | ||
|
||
curl_global_init(CURL_GLOBAL_ALL); | ||
|
||
curl_formadd(&formpost, | ||
&lastptr, | ||
CURLFORM_COPYNAME, "key", | ||
CURLFORM_COPYCONTENTS, "02250f10632647a568b7b18e0948372b", | ||
CURLFORM_END); | ||
|
||
|
||
curl = curl_easy_init(); | ||
|
||
curl_formadd(&formpost, | ||
&lastptr, | ||
CURLFORM_COPYNAME, "image", | ||
CURLFORM_FILE, filename.c_str(), | ||
CURLFORM_END); | ||
curl = curl_easy_init(); | ||
|
||
headers = curl_slist_append(headers, "Authorization: Client-ID 51f229880e3ea84"); | ||
if (curl) | ||
{ | ||
curl_easy_setopt(curl, CURLOPT_URL, "http://api.imgur.com/2/upload"); | ||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); | ||
curl_easy_setopt(curl, CURLOPT_URL, "https://api.imgur.com/3/image.xml"); | ||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost); | ||
|
||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, outputCallback); | ||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&output); | ||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "penis-browser/1.1"); | ||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "penis-browser/1.1"); | ||
|
||
res = curl_easy_perform(curl); | ||
|
||
curl_easy_cleanup(curl); | ||
|
||
curl_formfree(formpost); | ||
} | ||
return output; | ||
|
||
return imageIdFromXml(output); | ||
} | ||
|
||
int parseCmdLine(int argc, char* const argv[]) | ||
{ | ||
opterr = 0; | ||
|
||
int c; | ||
while ((c = getopt (argc, argv, "hvodpilmbrds:")) != -1) | ||
while ((c = getopt (argc, argv, "hvodpilmbds:")) != -1) | ||
{ | ||
switch (c) | ||
{ | ||
|
@@ -140,7 +181,6 @@ int parseCmdLine(int argc, char* const argv[]) | |
case 'l': optHtmlLink = true; break; | ||
case 'm': optMessageBoard = true; break; | ||
case 'b': optMessageBoardLink = true; break; | ||
case 'r': optDelete = true; break; | ||
case 'o': optOpenBrowser = true; break; | ||
case 'h': optShowHelp = true; break; | ||
case 'v': optShowVersion = true; break; | ||
|
@@ -158,17 +198,20 @@ int parseCmdLine(int argc, char* const argv[]) | |
} | ||
} | ||
|
||
if (!optDirect && !optImagePage && !optHtmlImage && !optHtmlLink && !optMessageBoard && !optMessageBoardLink && !optDelete) | ||
if (!optDirect && !optImagePage && !optHtmlImage && !optHtmlLink && !optMessageBoard && !optMessageBoardLink) | ||
optDirect = true; | ||
|
||
for (int index = optind; index < argc; index++) | ||
{ | ||
char path[PATH_MAX]; | ||
realpath(argv[index], path); | ||
|
||
struct stat buf; | ||
if (stat(path, &buf) == 0) | ||
optFiles.push_back(std::string(path)); | ||
char* path = realpath(argv[index], NULL); | ||
if (path) | ||
{ | ||
struct stat buf; | ||
if (stat(path, &buf) == 0) | ||
optFiles.push_back(std::string(path)); | ||
|
||
free(path); | ||
} | ||
} | ||
return 0; | ||
} | ||
|
@@ -181,44 +224,35 @@ std::string getVal(std::string xml, std::string key) | |
TiXmlElement* root = doc.RootElement(); | ||
if (root) | ||
{ | ||
TiXmlNode* child = NULL; | ||
|
||
while (child = root->IterateChildren(child)) | ||
{ | ||
TiXmlNode* val = child->FirstChild(key.c_str()); | ||
if (val) | ||
{ | ||
TiXmlElement* e = val->ToElement(); | ||
if (e) | ||
return e->GetText(); | ||
} | ||
} | ||
} | ||
TiXmlElement* child = root->FirstChildElement(key.c_str()); | ||
if (child) | ||
return child->GetText(); | ||
} | ||
|
||
return ""; | ||
} | ||
|
||
bool userOutput(std::string xml) | ||
bool userOutput(std::string id) | ||
{ | ||
if (getVal(xml, "hash").length() == 0) | ||
return false; | ||
|
||
if (id.length() == 0) | ||
return false; | ||
|
||
std::string xml = getImageInfo(id); | ||
|
||
if (optDirect) | ||
printf("%s\n", getVal(xml, "original").c_str()); | ||
printf("%s\n", getVal(xml, "link").c_str()); | ||
if (optImagePage) | ||
printf("%s\n", getVal(xml, "imgur_page").c_str()); | ||
printf("http://imgur.com/%s\n", id.c_str()); | ||
if (optHtmlImage) | ||
printf("<img src=\"%s\" alt=\"Hosted by imgur.com\" />\n", getVal(xml, "original").c_str()); | ||
printf("<img src=\"%s\" alt=\"Hosted by imgur.com\" />\n", getVal(xml, "link").c_str()); | ||
if (optHtmlLink) | ||
printf("<a href=\"%s\" title=\"Hosted by imgur.com\">%s</a>\n", getVal(xml, "original").c_str(), getVal(xml, "original").c_str()); | ||
printf("<a href=\"%s\" title=\"Hosted by imgur.com\">%s</a>\n", getVal(xml, "link").c_str(), getVal(xml, "link").c_str()); | ||
if (optMessageBoard) | ||
printf("[IMG]%s[/IMG]\n", getVal(xml, "original").c_str()); | ||
printf("[IMG]%s[/IMG]\n", getVal(xml, "link").c_str()); | ||
if (optMessageBoardLink) | ||
printf("[URL=%s][IMG]%s[/IMG][/URL]\n", getVal(xml, "original").c_str(), getVal(xml, "original").c_str()); | ||
if (optDelete) | ||
printf("%s\n", getVal(xml, "delete_page").c_str()); | ||
printf("[URL=%s][IMG]%s[/IMG][/URL]\n", getVal(xml, "link").c_str(), getVal(xml, "link").c_str()); | ||
if (optOpenBrowser) | ||
browseTo(getVal(xml, "imgur_page")); | ||
browseTo("http://imgur.com/" + id); | ||
|
||
return true; | ||
} | ||
|
@@ -235,6 +269,8 @@ int main (int argc, char* const argv[]) | |
return 0; | ||
if (optShowVersion && showVersion()) | ||
return 0; | ||
|
||
curl_global_init(CURL_GLOBAL_ALL); | ||
|
||
for (int i = 0; i < optFiles.size(); i++) | ||
{ | ||
|
@@ -247,7 +283,7 @@ int main (int argc, char* const argv[]) | |
|
||
std::string output = uploadImage(processed.c_str()); | ||
if (!userOutput(output)) | ||
fprintf(stderr, "Upload failed for %s. %s.\n", optFiles[i].c_str(), getVal(output, "error_msg").c_str()); | ||
fprintf(stderr, "Upload failed for %s.\n", optFiles[i].c_str()); | ||
} | ||
|
||
for (int i = 0; i < tempFiles.size(); i++) | ||
|