Add cli options for new accessors functions

This commit is contained in:
Clortox 2021-07-25 22:32:46 -04:00
parent 3ec8a71f9a
commit dc5749137e
6 changed files with 216 additions and 47 deletions

View File

@ -43,8 +43,6 @@ int main(int argc, char** argv) {
output += "\n" + rss_utils::rss_to_items(feed, opts); output += "\n" + rss_utils::rss_to_items(feed, opts);
} }
std::cout << "Item count: " << feed.getItemCount() << std::endl;
std::cout << output << std::endl; std::cout << output << std::endl;
delete opts; delete opts;

View File

@ -17,17 +17,27 @@ void help(char* progName){
std::cout << " [-t, --title] Get title of channel\n"; std::cout << " [-t, --title] Get title of channel\n";
std::cout << " [-l, --link] Get link to channel\n"; std::cout << " [-l, --link] Get link to channel\n";
std::cout << " [-d, --description] Get description of channel\n"; std::cout << " [-d, --description] Get description of channel\n";
std::cout << " [-e, --language] Get language code of channel\n"; std::cout << " [-L, --language] Get language code of channel\n";
std::cout << " [-m, --webmaster] Get webMaster's email\n"; std::cout << " [-m, --webmaster] Get webMaster's email\n";
std::cout << " [-c, --copyright] Get copyright\n"; std::cout << " [-c, --copyright] Get copyright\n";
std::cout << " [-p, --pubdate] Get publishing date\n"; std::cout << " [-p, --pubdate] Get publishing date\n";
std::cout << " [-q, --managingeditor] Get managing editor\n"; std::cout << " [-e, --managingeditor] Get managing editor\n";
std::cout << " [-g, --generator] Get generator of this feed\n"; std::cout << " [-g, --generator] Get generator of this feed\n";
std::cout << " [-o, --docs] Get link to RSS documentation\n"; std::cout << " [-o, --docs] Get link to RSS documentation\n";
std::cout << " [-w, --ttl] Get ttl, time that channel can be\n"; std::cout << " [-w, --ttl] Get ttl, time that channel can be\n";
std::cout << " cached before being updated\n"; std::cout << " cached before being updated\n";
std::cout << " [-b, --builddate] Get last time the channel's\n"; std::cout << " [-b, --builddate] Get last time the channel's\n";
std::cout << " content changed\n"; std::cout << " content changed\n";
std::cout << " [-Q, --imageurl] Get channel image URL\n";
std::cout << " [-I, --imagetitle] Get image title, same as ALT in html\n";
std::cout << " [-E, --imagelink] Get link to site, image will act as a link\n";
std::cout << " [-W, --imagewidth] Get width of image\n";
std::cout << " [-H, --imageheight] Get height of image\n";
std::cout << " [-D, --clouddomain] Get domain of feed update service\n";
std::cout << " [-P, --cloudport] Get port of feed update service\n";
std::cout << " [-A, --cloudpath] Get path to access for feed update service\n";
std::cout << " [-R, --cloudregister] Get register procedure for feed update service\n";
std::cout << " [-O, --cloudprotocol] Get protocol feed update service uses\n";
std::cout << " [-i, --item] INDEX Provide index of item to display\n"; std::cout << " [-i, --item] INDEX Provide index of item to display\n";
std::cout << " If no index is provided, assume the first\n"; std::cout << " If no index is provided, assume the first\n";
std::cout << " item in the feed. All following flags will\n"; std::cout << " item in the feed. All following flags will\n";
@ -39,11 +49,14 @@ void help(char* progName){
std::cout << " [-l, --link] Get link\n"; std::cout << " [-l, --link] Get link\n";
std::cout << " [-d, --description] Get description\n"; std::cout << " [-d, --description] Get description\n";
std::cout << " [-a, --author] Get author\n"; std::cout << " [-a, --author] Get author\n";
std::cout << " [-z, --category] Get category list\n"; std::cout << " [-C, --category] Get category list\n";
std::cout << " [-f, --comments] Get link to comments\n"; std::cout << " [-f, --comments] Get link to comments\n";
std::cout << " [-j, --guid] Get GUID\n"; std::cout << " [-G, --guid] Get GUID\n";
std::cout << " [-p, --pubdate] Get publishing date\n"; std::cout << " [-p, --pubdate] Get publishing date\n";
std::cout << " [-s, --source] Get source of item\n\n"; std::cout << " [-s, --source] Get source of item\n";
std::cout << " [-U, --enclosureurl] Get enclosure URL\n";
std::cout << " [-T, --enclosuretype] Get enclosure MIME type\n";
std::cout << " [-K, --enclosurelength]Get enclosure length, in bytes\n\n";
std::cout << "General options:\n"; std::cout << "General options:\n";
std::cout << " [-h, --help] Show this message\n\n"; std::cout << " [-h, --help] Show this message\n\n";
@ -92,11 +105,11 @@ option_flags* parse_options(int argc, char** argv) {
else else
current_item->description ^= 1; current_item->description ^= 1;
break; break;
case 'e': case 'L':
if(current_item == nullptr) if(current_item == nullptr)
ret->language ^= 1; ret->language ^= 1;
else else
std::cerr << "-e option not understood in context of --item; ignoring" << std::endl; std::cerr << "-L option not understood in context of --item; ignoring" << std::endl;
break; break;
case 'm': case 'm':
if(current_item == nullptr) if(current_item == nullptr)
@ -116,11 +129,11 @@ option_flags* parse_options(int argc, char** argv) {
else else
current_item->pubdate ^= 1; current_item->pubdate ^= 1;
break; break;
case 'q': case 'e':
if(current_item == nullptr) if(current_item == nullptr)
ret->managingeditor ^= 1; ret->managingeditor ^= 1;
else else
std::cerr << "-q option not understood in context of --item; ignoring" << std::endl; std::cerr << "-e option not understood in context of --item; ignoring" << std::endl;
break; break;
case 'g': case 'g':
if(current_item == nullptr) if(current_item == nullptr)
@ -146,6 +159,66 @@ option_flags* parse_options(int argc, char** argv) {
else else
std::cerr << "-b option not understood in context of --item; ignoring" << std::endl; std::cerr << "-b option not understood in context of --item; ignoring" << std::endl;
break; break;
case 'Q':
if(current_item == nullptr)
ret->imageurl ^= 1;
else
std::cerr << "-Q option not understood in context of --item; ignoring" << std::endl;
break;
case 'I':
if(current_item == nullptr)
ret->imagetitle ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'E':
if(current_item == nullptr)
ret->imagelink ^= 1;
else
std::cerr << "-E option not understood in context of --item; ignoring" << std::endl;
break;
case 'W':
if(current_item == nullptr)
ret->imagewidth ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'H':
if(current_item == nullptr)
ret->imageheight ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'D':
if(current_item == nullptr)
ret->clouddomain ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'P':
if(current_item == nullptr)
ret->cloudport ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'A':
if(current_item == nullptr)
ret->cloudpath ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'R':
if(current_item == nullptr)
ret->cloudregister ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'O':
if(current_item == nullptr)
ret->cloudprotocol ^= 1;
else
std::cerr << "-I option not understood in context of --item; ignoring" << std::endl;
break;
case 'i': case 'i':
if(ret->items == nullptr){ if(ret->items == nullptr){
ret->items = new item_flags[ret->item_count + 1]; ret->items = new item_flags[ret->item_count + 1];
@ -170,9 +243,9 @@ option_flags* parse_options(int argc, char** argv) {
} else } else
current_item->author ^= 1; current_item->author ^= 1;
break; break;
case 'z': case 'C':
if(current_item == nullptr){ if(current_item == nullptr){
std::cerr << "Invalid option in this context: [-z --category]" << std::endl; std::cerr << "Invalid option in this context: [-C --category]" << std::endl;
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl; std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
} else } else
current_item->category ^= 1; current_item->category ^= 1;
@ -184,9 +257,9 @@ option_flags* parse_options(int argc, char** argv) {
} else } else
current_item->comments ^= 1; current_item->comments ^= 1;
break; break;
case 'j': case 'G':
if(current_item == nullptr){ if(current_item == nullptr){
std::cerr << "Invalid option in this context: [-j --guid]" << std::endl; std::cerr << "Invalid option in this context: [-G --guid]" << std::endl;
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl; std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
} else } else
current_item->guid ^= 1; current_item->guid ^= 1;
@ -198,6 +271,27 @@ option_flags* parse_options(int argc, char** argv) {
} else } else
current_item->source ^= 1; current_item->source ^= 1;
break; break;
case 'U':
if(current_item == nullptr){
std::cerr << "Invalid option in this context: [-U --enclosureurl]" << std::endl;
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
} else
current_item->enclosureurl ^= 1;
break;
case 'T':
if(current_item == nullptr){
std::cerr << "Invalid option in this context: [-T --enclosuretype]" << std::endl;
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
} else
current_item->enclosuretype ^= 1;
break;
case 'K':
if(current_item == nullptr){
std::cerr << "Invalid option in this context: [-K --enclosurelength]" << std::endl;
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
} else
current_item->enclosurelength ^= 1;
break;
case ':': //go here if flag that requires argument is passed, but no arg given case ':': //go here if flag that requires argument is passed, but no arg given
switch(optopt){ switch(optopt){
case 'i': case 'i':

View File

@ -11,7 +11,7 @@
#include <getopt.h> #include <getopt.h>
//cli options //cli options
constexpr char optarg_string[] = ":u:tldemcpqgowbi::azfjsh"; constexpr char optarg_string[] = ":u:i::tldLmcpegowbQIEWCHDPAROacfGsUTK";
static struct option long_options[] = static struct option long_options[] =
{ {
@ -20,23 +20,39 @@ static struct option long_options[] =
{"title", no_argument, 0, 't'}, {"title", no_argument, 0, 't'},
{"link", no_argument, 0, 'l'}, {"link", no_argument, 0, 'l'},
{"description", no_argument, 0, 'd'}, {"description", no_argument, 0, 'd'},
{"language", no_argument, 0, 'e'}, {"language", no_argument, 0, 'L'},
{"webmaster", no_argument, 0, 'm'}, {"webmaster", no_argument, 0, 'm'},
{"copyright", no_argument, 0, 'c'}, {"copyright", no_argument, 0, 'c'},
{"pubdate", no_argument, 0, 'p'}, {"pubdate", no_argument, 0, 'p'},
{"managingeditor", no_argument, 0, 'q'}, {"managingeditor", no_argument, 0, 'e'},
{"generator", no_argument, 0, 'g'}, {"generator", no_argument, 0, 'g'},
{"docs", no_argument, 0, 'o'}, {"docs", no_argument, 0, 'o'},
{"ttl", no_argument, 0, 'w'}, {"ttl", no_argument, 0, 'w'},
{"builddate", no_argument, 0, 'b'}, {"builddate", no_argument, 0, 'b'},
{"imageurl", no_argument, 0, 'Q'},
{"imagetitle", no_argument, 0, 'I'},
{"imagelink", no_argument, 0, 'E'},
{"imagewidth", no_argument, 0, 'W'},
{"imageheight", no_argument, 0, 'H'},
{"clouddomain", no_argument, 0, 'D'},
{"cloudport", no_argument, 0, 'P'},
{"cloudpath", no_argument, 0, 'A'},
{"cloudregister", no_argument, 0, 'R'},
{"cloudprotocl", no_argument, 0, 'O'},
{"item", optional_argument, 0, 'i'}, {"item", optional_argument, 0, 'i'},
{"author", no_argument, 0, 'a'}, {"author", no_argument, 0, 'a'},
{"category", no_argument, 0, 'z'}, {"category", no_argument, 0, 'C'},
{"comments", no_argument, 0, 'f'}, {"comments", no_argument, 0, 'f'},
{"guid", no_argument, 0, 'j'}, {"guid", no_argument, 0, 'G'},
{"source", no_argument, 0, 's'}, {"source", no_argument, 0, 's'},
{"enclosureurl", no_argument, 0, 'U'},
{"enclosuretype", no_argument, 0, 'T'},
{"enclosurelength", no_argument,0, 'K'},
{"help", no_argument, 0, 'h'}, {"help", no_argument, 0, 'h'},
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
@ -52,6 +68,10 @@ struct item_flags {
unsigned int pubdate : 1; unsigned int pubdate : 1;
unsigned int source : 1; unsigned int source : 1;
unsigned int enclosureurl : 1;
unsigned int enclosuretype : 1;
unsigned int enclosurelength : 1;
int index; int index;
}; };
@ -69,6 +89,18 @@ struct option_flags {
unsigned int ttl : 1; unsigned int ttl : 1;
unsigned int builddate : 1; unsigned int builddate : 1;
unsigned int imageurl : 1;
unsigned int imagetitle : 1;
unsigned int imagelink : 1;
unsigned int imagewidth : 1;
unsigned int imageheight : 1;
unsigned int clouddomain : 1;
unsigned int cloudport : 1;
unsigned int cloudpath : 1;
unsigned int cloudregister : 1;
unsigned int cloudprotocol : 1;
item_flags* items; item_flags* items;
unsigned int item_count; unsigned int item_count;
std::string uri; std::string uri;

View File

@ -328,7 +328,7 @@ std::string rss::getCloudPath() const {
return attr->value(); return attr->value();
} }
std::string rss::getRegisterProcedure() const { std::string rss::getCloudRegisterProcedure() const {
if(!_ok) if(!_ok)
return ""; return "";
@ -342,7 +342,7 @@ std::string rss::getRegisterProcedure() const {
return attr->value(); return attr->value();
} }
std::string rss::getProtocol() const { std::string rss::getCloudProtocol() const {
if(!_ok) if(!_ok)
return ""; return "";
@ -451,7 +451,6 @@ bool rss::parse(const std::string& rss_str){
std::string rss::cdata_to_string(const rapidxml::xml_node<>* node) const{ std::string rss::cdata_to_string(const rapidxml::xml_node<>* node) const{
//this will dig till were past the cdata //this will dig till were past the cdata
std::cout << "in cdata" << std::endl;
const rapidxml::xml_node<>* tmp = node; const rapidxml::xml_node<>* tmp = node;
while(tmp->value()[0] == '\0'){ //if string is empty while(tmp->value()[0] == '\0'){ //if string is empty
tmp = tmp->first_node(); tmp = tmp->first_node();
@ -468,7 +467,6 @@ size_t rss_utils::write_to_string(void* ptr, size_t size, size_t nmemb, std::str
std::string item::cdata_to_string(const rapidxml::xml_node<>* node) const{ std::string item::cdata_to_string(const rapidxml::xml_node<>* node) const{
//this will dig till were past the cdata //this will dig till were past the cdata
std::cout << "in cdata" << std::endl;
const rapidxml::xml_node<>* tmp = node; const rapidxml::xml_node<>* tmp = node;
while(tmp->value()[0] == '\0'){ //if string is empty while(tmp->value()[0] == '\0'){ //if string is empty
tmp = tmp->first_node(); tmp = tmp->first_node();

View File

@ -64,8 +64,8 @@ namespace rss_utils {
std::string getCloudDomain() const; std::string getCloudDomain() const;
int getCloudPort() const; int getCloudPort() const;
std::string getCloudPath() const; std::string getCloudPath() const;
std::string getRegisterProcedure() const; std::string getCloudRegisterProcedure() const;
std::string getProtocol() const; std::string getCloudProtocol() const;
int getItemCount() const; int getItemCount() const;
std::vector<item> getItems(); std::vector<item> getItems();

View File

@ -35,6 +35,26 @@ std::string rss_utils::rss_to_list(const rss& rss_obj, const option_flags* flags
ret += rss_obj.getTTL() + "\n"; ret += rss_obj.getTTL() + "\n";
if(flags->builddate) if(flags->builddate)
ret += rss_obj.getLastBuildDate() + "\n"; ret += rss_obj.getLastBuildDate() + "\n";
if(flags->imageurl)
ret += rss_obj.getImageURL() + "\n";
if(flags->imagetitle)
ret += rss_obj.getImageTitle() + "\n";
if(flags->imagelink)
ret += rss_obj.getImageLink() + "\n";
if(flags->imagewidth)
ret += rss_obj.getImageWidth() + "\n";
if(flags->imageheight)
ret += rss_obj.getImageHeight() + "\n";
if(flags->clouddomain)
ret += rss_obj.getCloudDomain() +"\n";
if(flags->cloudport)
ret += rss_obj.getCloudPort() + "\n";
if(flags->cloudpath)
ret += rss_obj.getCloudPath() + "\n";
if(flags->cloudregister)
ret += rss_obj.getCloudRegisterProcedure() + "\n";
if(flags->cloudprotocol)
ret += rss_obj.getCloudProtocol() + "\n";
if(ret.length() > 0) if(ret.length() > 0)
ret.pop_back(); ret.pop_back();
@ -56,7 +76,7 @@ std::string rss_utils::rss_to_items(const rss& rss_obj, const option_flags* flag
for(unsigned int i=0; i < flags->item_count; ++i, ++items){ for(unsigned int i=0; i < flags->item_count; ++i, ++items){
//if has a valid index //if has a valid index
if(items->index >= 0 && items->index < maxItem){ if(items->index >= 0 && items->index < maxItem) {
rss_utils::item cur_item = rss_obj[items->index]; rss_utils::item cur_item = rss_obj[items->index];
if(items->title) if(items->title)
ret += cur_item.getTitle() + "\n"; ret += cur_item.getTitle() + "\n";
@ -76,6 +96,13 @@ std::string rss_utils::rss_to_items(const rss& rss_obj, const option_flags* flag
ret += cur_item.getPubDate() + "\n"; ret += cur_item.getPubDate() + "\n";
if(items->source) if(items->source)
ret += cur_item.getSource() + "\n"; ret += cur_item.getSource() + "\n";
if(items->enclosureurl)
ret += cur_item.getEnclosureURL() + "\n";
if(items->enclosuretype)
ret += cur_item.getEnclosureType() + "\n";
if(items->enclosurelength)
ret += std::to_string(cur_item.getEnclosureLength()) + "\n";
} else } else
std::cerr << "Index on item " << i << " is not valid!" << std::endl; std::cerr << "Index on item " << i << " is not valid!" << std::endl;
} }
@ -113,6 +140,26 @@ bool rss_utils::rss_opts_empty(const option_flags* flags){
return false; return false;
if(flags->builddate) if(flags->builddate)
return false; return false;
if(flags->imageurl)
return false;
if(flags->imagetitle)
return false;
if(flags->imagelink)
return false;
if(flags->imagewidth)
return false;
if(flags->imageheight)
return false;
if(flags->clouddomain)
return false;
if(flags->cloudport)
return false;
if(flags->cloudpath)
return false;
if(flags->cloudregister)
return false;
if(flags->cloudprotocol)
return false;
return true; return true;