Add output for rss items
This commit is contained in:
parent
f028458841
commit
95e822bbc6
@ -10,4 +10,4 @@
|
||||
* Set to 1 to compile and run the test suite
|
||||
*/
|
||||
|
||||
#define _TESTS_ 1
|
||||
#define _TESTS_ 0
|
||||
|
@ -32,11 +32,16 @@ int main(int argc, char** argv) {
|
||||
if(!feed.isOk())
|
||||
exit(-1);
|
||||
|
||||
//display requested attributes
|
||||
|
||||
//display requested attributes and items
|
||||
std::string output = rss_utils::rss_to_list(feed, opts);
|
||||
|
||||
std::cout << output << std::endl;
|
||||
if(opts->items != nullptr){
|
||||
feed.getItems();
|
||||
output += "\n" + rss_utils::rss_to_items(feed, opts);
|
||||
}
|
||||
|
||||
std::cout << output << std::endl;
|
||||
|
||||
delete opts;
|
||||
return 0;
|
||||
|
127
src/options.cpp
127
src/options.cpp
@ -7,29 +7,49 @@
|
||||
#include "options.hpp"
|
||||
|
||||
void help(char* progName){
|
||||
std::cout << "Usage: " << progName << " [-u FEED_URI]\n";
|
||||
std::cout << "Usage: " << progName << " [-u FEED_URI] [CHANNEL FLAGS] ";
|
||||
std::cout << "[-i ITEM_INDEX] [ITEM FLAGS]\n";
|
||||
std::cout << "Options:\n";
|
||||
std::cout << "Required Options:\n";
|
||||
std::cout << " [-u, --uri] URI of the rss stream\n\n";
|
||||
std::cout << " [-u, --uri] URI URI of the rss stream\n\n";
|
||||
|
||||
std::cout << "Channel information:\n";
|
||||
std::cout << " [-t, --title] Get title of 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 << " [-m, --webmaster] Get webMaster's email\n";
|
||||
std::cout << " [-c, --copyright] Get copyright\n";
|
||||
std::cout << " [-p, --pubdate] Get publishing date\n";
|
||||
std::cout << " [-q, --managingeditor] Get Managing Editor\n";
|
||||
std::cout << " [-q, --managingeditor] Get managing editor\n";
|
||||
std::cout << " [-g, --generator] Get generator of this feed\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 << " cached before being updated\n";
|
||||
std::cout << " [-b, --builddate] Get last time the channel's\n";
|
||||
std::cout << " content changed\n\n";
|
||||
std::cout << " content changed\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 << " item in the feed. All following flags will\n";
|
||||
std::cout << " be parsed as item options, till another\n";
|
||||
std::cout << " item is provided\n\n";
|
||||
|
||||
std::cout << "Item options:\n";
|
||||
std::cout << " [-t, --title] Get title of item\n";
|
||||
std::cout << " [-l, --link] Get link\n";
|
||||
std::cout << " [-d, --description] Get description\n";
|
||||
std::cout << " [-a, --author] Get author\n";
|
||||
std::cout << " [-z, --category] Get category list\n";
|
||||
std::cout << " [-f, --comments] Get link to comments\n";
|
||||
std::cout << " [-j, --guid] Get GUID\n";
|
||||
std::cout << " [-p, --pubdate] Get publishing date\n";
|
||||
std::cout << " [-s, --source] Get source of item\n\n";
|
||||
|
||||
std::cout << "General options:\n";
|
||||
std::cout << " [-h, --help] Show this message\n";
|
||||
std::cout << " [-h, --help] Show this message\n\n";
|
||||
|
||||
std::cout << "For more information, refer to the RSS 2.0 documentation\n";
|
||||
std::cout << "https://validator.w3.org/feed/docs/rss2.html\n";
|
||||
|
||||
exit(1);
|
||||
}
|
||||
@ -37,8 +57,13 @@ void help(char* progName){
|
||||
option_flags* parse_options(int argc, char** argv) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
|
||||
item_flags* current_item = nullptr;
|
||||
option_flags* ret = new option_flags;
|
||||
|
||||
ret->item_count = 0;
|
||||
ret->items = nullptr;
|
||||
|
||||
while(true){
|
||||
c = getopt_long(argc, argv, optarg_string,
|
||||
long_options, &option_index);
|
||||
@ -50,13 +75,22 @@ option_flags* parse_options(int argc, char** argv) {
|
||||
ret->uri = std::string(optarg);
|
||||
break;
|
||||
case 't':
|
||||
if(current_item == nullptr)
|
||||
ret->title ^= 1;
|
||||
else
|
||||
current_item->title ^= 1;
|
||||
break;
|
||||
case 'l':
|
||||
if(current_item == nullptr)
|
||||
ret->link ^= 1;
|
||||
else
|
||||
current_item->link ^= 1;
|
||||
break;
|
||||
case 'd':
|
||||
if(current_item == nullptr)
|
||||
ret->description ^= 1;
|
||||
else
|
||||
current_item->description ^= 1;
|
||||
break;
|
||||
case 'e':
|
||||
ret->language ^= 1;
|
||||
@ -68,7 +102,10 @@ option_flags* parse_options(int argc, char** argv) {
|
||||
ret->copyright ^= 1;
|
||||
break;
|
||||
case 'p':
|
||||
if(current_item == nullptr)
|
||||
ret->pubdate ^= 1;
|
||||
else
|
||||
current_item->pubdate ^= 1;
|
||||
break;
|
||||
case 'q':
|
||||
ret->managingeditor ^= 1;
|
||||
@ -85,7 +122,85 @@ option_flags* parse_options(int argc, char** argv) {
|
||||
case 'b':
|
||||
ret->builddate ^= 1;
|
||||
break;
|
||||
case 'i':
|
||||
if(ret->items == nullptr){
|
||||
ret->items = new item_flags[ret->item_count + 1];
|
||||
current_item = &(ret->items[0]);
|
||||
ret->item_count++;
|
||||
current_item->index = optarg ? atoi(optarg) : 0;
|
||||
} else {
|
||||
item_flags* new_flags = new item_flags[ret->item_count + 1];
|
||||
for(unsigned int i=0;i<ret->item_count;++i)
|
||||
new_flags[i] = ret->items[i];
|
||||
delete ret->items;
|
||||
ret->items = new_flags;
|
||||
current_item = &(ret->items[ret->item_count]);
|
||||
ret->item_count++;
|
||||
current_item->index = optarg ? atoi(optarg) : 0;
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
if(current_item == nullptr){
|
||||
std::cerr << "Invalid option in this context: [-a --author]" << std::endl;
|
||||
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
||||
} else
|
||||
current_item->author ^= 1;
|
||||
break;
|
||||
case 'z':
|
||||
if(current_item == nullptr){
|
||||
std::cerr << "Invalid option in this context: [-z --category]" << std::endl;
|
||||
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
||||
} else
|
||||
current_item->category ^= 1;
|
||||
break;
|
||||
case 'f':
|
||||
if(current_item == nullptr){
|
||||
std::cerr << "Invalid option in this context: [-f --comments]" << std::endl;
|
||||
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
||||
} else
|
||||
current_item->comments ^= 1;
|
||||
break;
|
||||
case 'j':
|
||||
if(current_item == nullptr){
|
||||
std::cerr << "Invalid option in this context: [-j --guid]" << std::endl;
|
||||
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
||||
} else
|
||||
current_item->guid ^= 1;
|
||||
break;
|
||||
case 's':
|
||||
if(current_item == nullptr){
|
||||
std::cerr << "Invalid option in this context: [-s --source]" << std::endl;
|
||||
std::cerr << "Did you provide the [-i --index] flag first?" << std::endl;
|
||||
} else
|
||||
current_item->source ^= 1;
|
||||
break;
|
||||
case ':': //go here if flag that requires argument is passed, but no arg given
|
||||
switch(optopt){
|
||||
case 'i':
|
||||
if(ret->items == nullptr){
|
||||
ret->item_count++;
|
||||
ret->items = new item_flags[ret->item_count];
|
||||
current_item = &(ret->items[0]);
|
||||
current_item->index = 1;
|
||||
} else {
|
||||
item_flags* new_flags = new item_flags[ret->item_count + 1];
|
||||
for(unsigned int i=0;i<ret->item_count;++i)
|
||||
new_flags[i] = ret->items[i];
|
||||
delete ret->items;
|
||||
ret->items = new_flags;
|
||||
current_item = &(ret->items[ret->item_count]);
|
||||
ret->item_count++;
|
||||
current_item->index = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Invalid use: option -" << (char)optopt
|
||||
<< " requires an argument" << std::endl;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
std::cerr << "Unknown option: " << (char)optopt << std::endl;
|
||||
case 'h':
|
||||
help(argv[0]);
|
||||
break;
|
||||
|
@ -11,11 +11,12 @@
|
||||
#include <getopt.h>
|
||||
|
||||
//cli options
|
||||
constexpr char optarg_string[] = "u:tldemcpqgowbh";
|
||||
constexpr char optarg_string[] = ":u:tldemcpqgowbi::azfjsh";
|
||||
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"uri", required_argument, 0, 'u'},
|
||||
|
||||
{"title", no_argument, 0, 't'},
|
||||
{"link", no_argument, 0, 'l'},
|
||||
{"description", no_argument, 0, 'd'},
|
||||
@ -28,10 +29,32 @@ static struct option long_options[] =
|
||||
{"docs", no_argument, 0, 'o'},
|
||||
{"ttl", no_argument, 0, 'w'},
|
||||
{"builddate", no_argument, 0, 'b'},
|
||||
|
||||
{"item", optional_argument, 0, 'i'},
|
||||
{"author", no_argument, 0, 'a'},
|
||||
{"category", no_argument, 0, 'z'},
|
||||
{"comments", no_argument, 0, 'f'},
|
||||
{"guid", no_argument, 0, 'j'},
|
||||
{"source", no_argument, 0, 's'},
|
||||
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0},
|
||||
};
|
||||
|
||||
struct item_flags {
|
||||
unsigned int title : 1;
|
||||
unsigned int link : 1;
|
||||
unsigned int description : 1;
|
||||
unsigned int author : 1;
|
||||
unsigned int category : 1;
|
||||
unsigned int comments : 1;
|
||||
unsigned int guid : 1;
|
||||
unsigned int pubdate : 1;
|
||||
unsigned int source : 1;
|
||||
|
||||
int index;
|
||||
};
|
||||
|
||||
struct option_flags {
|
||||
unsigned int title : 1;
|
||||
unsigned int link : 1;
|
||||
@ -46,8 +69,11 @@ struct option_flags {
|
||||
unsigned int ttl : 1;
|
||||
unsigned int builddate : 1;
|
||||
|
||||
item_flags* items;
|
||||
unsigned int item_count;
|
||||
std::string uri;
|
||||
};
|
||||
|
||||
|
||||
void help(char*);
|
||||
option_flags* parse_options(int, char**);
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include "tylers_utils.hpp"
|
||||
|
||||
#include <rapidxml/rapidxml.hpp>
|
||||
#include <rapidxml/rapidxml_print.hpp>
|
||||
|
@ -11,42 +11,30 @@ using namespace rss_utils;
|
||||
std::string rss_utils::rss_to_list(const rss& rss_obj, const option_flags* flags){
|
||||
std::string ret;
|
||||
|
||||
if(flags->title){
|
||||
if(flags->title)
|
||||
ret += rss_obj.getTitle() + "\n";
|
||||
}
|
||||
if(flags->link){
|
||||
if(flags->link)
|
||||
ret += rss_obj.getLink() + "\n";
|
||||
}
|
||||
if(flags->description){
|
||||
if(flags->description)
|
||||
ret += rss_obj.getDescription() + "\n";
|
||||
}
|
||||
if(flags->language){
|
||||
if(flags->language)
|
||||
ret += rss_obj.getLanguage() + "\n";
|
||||
}
|
||||
if(flags->webmaster){
|
||||
if(flags->webmaster)
|
||||
ret += rss_obj.getWebMaster() + "\n";
|
||||
}
|
||||
if(flags->copyright){
|
||||
if(flags->copyright)
|
||||
ret += rss_obj.getCopyright() + "\n";
|
||||
}
|
||||
if(flags->pubdate){
|
||||
if(flags->pubdate)
|
||||
ret += rss_obj.getPubDate() + "\n";
|
||||
}
|
||||
if(flags->managingeditor){
|
||||
if(flags->managingeditor)
|
||||
ret += rss_obj.getManagingEditor() + "\n";
|
||||
}
|
||||
if(flags->generator){
|
||||
if(flags->generator)
|
||||
ret += rss_obj.getGenerator() + "\n";
|
||||
}
|
||||
if(flags->docs){
|
||||
if(flags->docs)
|
||||
ret += rss_obj.getDocs() + "\n";
|
||||
}
|
||||
if(flags->ttl){
|
||||
if(flags->ttl)
|
||||
ret += rss_obj.getTTL() + "\n";
|
||||
}
|
||||
if(flags->builddate){
|
||||
if(flags->builddate)
|
||||
ret += rss_obj.getLastBuildDate() + "\n";
|
||||
}
|
||||
|
||||
if(ret.length() > 0)
|
||||
ret.pop_back();
|
||||
@ -55,3 +43,42 @@ std::string rss_utils::rss_to_list(const rss& rss_obj, const option_flags* flags
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string rss_utils::rss_to_items(const rss& rss_obj, const option_flags* flags){
|
||||
item_flags* items = flags->items;
|
||||
int maxItem = rss_obj.getItemCount();
|
||||
std::string ret;
|
||||
|
||||
for(unsigned int i=0; i < flags->item_count; ++i, ++items){
|
||||
//if has a valid index
|
||||
if(items->index >= 0 && items->index < maxItem){
|
||||
rss_utils::item cur_item = rss_obj[items->index];
|
||||
if(items->title)
|
||||
ret += cur_item.getTitle() + "\n";
|
||||
if(items->link)
|
||||
ret += cur_item.getLink() + "\n";
|
||||
if(items->description)
|
||||
ret += cur_item.getDescription() + "\n";
|
||||
if(items->author)
|
||||
ret += cur_item.getAuthor() + "\n";
|
||||
if(items->category)
|
||||
ret += cur_item.getCategory() + "\n";
|
||||
if(items->comments)
|
||||
ret += cur_item.getComments() + "\n";
|
||||
if(items->guid)
|
||||
ret += cur_item.getGuid() + "\n";
|
||||
if(items->pubdate)
|
||||
ret += cur_item.getPubDate() + "\n";
|
||||
if(items->source)
|
||||
ret += cur_item.getSource() + "\n";
|
||||
} else
|
||||
std::cerr << "Index on item " << i << " is not valid!" << std::endl;
|
||||
}
|
||||
|
||||
if(ret.length() > 0)
|
||||
ret.pop_back();
|
||||
else
|
||||
ret = "<No arguments given for items>";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -13,6 +13,6 @@
|
||||
|
||||
namespace rss_utils {
|
||||
std::string rss_to_list(const rss&, const option_flags*);
|
||||
//std::string rss_to_items(const rss&
|
||||
std::string rss_to_items(const rss&, const option_flags*);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user