1 /***************************************************************************
2           meerkat_client.cpp  --  Requester for Meerkat service
3 
4     copyright            : (C) 2002-2007 by Ewald Arnold
5     email                : ulxmlrpcpp@ewald-arnold.de
6 
7    For an explanation of Meerkat services see:
8     - http://www.oreillynet.com/pub/a/rss/2000/11/14/meerkat_xmlrpc.html
9     - http://www.oreillynet.com/pub/a/rss/2000/05/09/meerkat_api.html
10 
11    For explanation about MySql expressions see
12     http://www.mysql.com/documentation/mysql/bychapter/manual_Regexp.html
13 
14     $Id: meerkat_client.cpp 1151 2009-08-12 15:12:01Z ewald-arnold $
15 
16  ***************************************************************************/
17 
18 /**************************************************************************
19  *
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU Lesser General Public License as
22  * published by the Free Software Foundation; either version 2 of the License,
23  * or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU Lesser General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33  *
34  ***************************************************************************/
35 
36 #include <ulxmlrpcpp/ulxmlrpcpp.h>  // always first header
37 
38 #include <ulxmlrpcpp/ulxr_tcpip_connection.h> // first, don't move: msvc #include bug
39 #include <ulxmlrpcpp/ulxr_http_protocol.h>
40 #include <ulxmlrpcpp/ulxr_requester.h>
41 #include <ulxmlrpcpp/ulxr_value.h>
42 #include <ulxmlrpcpp/ulxr_except.h>
43 
44 #include <cstdlib>
45 #include <iomanip>
46 #include <iostream>
47 
48 using namespace ulxr;
49 
50 
usage(int ret)51 void usage(int ret)
52 {
53  ULXR_COUT
54       << ULXR_PCHAR("Usage: meerkat_client  [options]\n")
55          ULXR_PCHAR(" --channels, -c     lists all available channels.\n")
56          ULXR_PCHAR(" --categories, -e   lists all available categories.\n")
57          ULXR_PCHAR(" --search, -s expr  searches expr in database.\n")
58          ULXR_PCHAR("     where \'expr\' is either a string or an SQL regular expression.\n")
59          ULXR_PCHAR("\n");
60 
61   exit(ret);
62 }
63 
64 
handleFault(MethodResponse & resp)65 int handleFault(MethodResponse &resp)
66 {
67    Struct str = resp.getResult();
68    if (str.hasMember(ULXR_PCHAR("faultCode")))
69    {
70      ULXR_COUT << ULXR_PCHAR("Server reports error: ") << RpcString(str.getMember(ULXR_PCHAR("faultString"))).getString()
71                << ULXR_PCHAR(" (") << Integer(str.getMember(ULXR_PCHAR("faultCode"))).getInteger() << ULXR_PCHAR(")\n");
72      return 1;
73    }
74    else
75    {
76      ULXR_COUT << ULXR_PCHAR("Unexpected return structure: \n")
77                << str.getXml(0)
78                << std::endl;
79      return 1;
80    }
81    /* return 0; */
82 }
83 
84 
showCategories(Requester & client)85 int showCategories(Requester &client)
86 {
87   MethodCall get_Categories (ULXR_PCHAR("meerkat.getCategories"));
88   MethodResponse resp = client.call(get_Categories, ULXR_PCHAR("/meerkat/xml-rpc/server.php"));
89 
90   if (!resp.isOK())
91     return handleFault(resp);
92 
93   Array list = resp.getResult();
94 
95   ULXR_COUT << ULXR_PCHAR("Found ") << list.size() << ULXR_PCHAR(" categories:\n\n");
96   for (unsigned i = 0; i < list.size(); ++i)
97   {
98     Struct entry = list.getItem(i);
99     Integer id = entry.getMember(ULXR_PCHAR("id"));
100     RpcString title = entry.getMember(ULXR_PCHAR("title"));
101     ULXR_COUT << ULXR_PCHAR(" ") << std::setw(5) << id.getInteger() << ULXR_PCHAR("  ") << title.getString() << std::endl;
102   }
103 
104   return 0;
105 }
106 
107 
showChannels(Requester & client)108 int showChannels(Requester &client)
109 {
110   MethodCall get_Channels (ULXR_PCHAR("meerkat.getChannels"));
111   MethodResponse resp = client.call(get_Channels, ULXR_PCHAR("/meerkat/xml-rpc/server.php"));
112 
113   if (!resp.isOK())
114     return handleFault(resp);
115 
116   Array list = resp.getResult();
117 
118   ULXR_COUT << ULXR_PCHAR("Found ") << list.size() << ULXR_PCHAR(" channels:\n\n");
119   for (unsigned i = 0; i < list.size(); ++i)
120   {
121     Struct entry = list.getItem(i);
122     Integer id = entry.getMember(ULXR_PCHAR("id"));
123    RpcString title = entry.getMember(ULXR_PCHAR("title"));
124     ULXR_COUT << ULXR_PCHAR(" ") << std::setw(5)
125               << id.getInteger() << ULXR_PCHAR("  ")
126               << title.getString() << std::endl;
127   }
128 
129   return 0;
130 }
131 
132 
searchdb(Requester & client,const CppString & patt)133 int searchdb(Requester &client, const CppString &patt)
134 {
135   CppString pattern = patt;
136 
137   if (pattern[0] != ULXR_CHAR('/'))
138     pattern = ULXR_CHAR('/')+ pattern + ULXR_CHAR('/';)
139 
140   Struct query;
141   query.addMember(ULXR_PCHAR("search"), RpcString(pattern));
142   query.addMember(ULXR_PCHAR("time_period"), RpcString(ULXR_PCHAR("48HOUR")));
143   query.addMember(ULXR_PCHAR("descriptions"), Integer(76));
144 
145   MethodCall get_Items (ULXR_PCHAR("meerkat.getItems"));
146   get_Items.addParam(query);
147   MethodResponse resp = client.call(get_Items, ULXR_PCHAR("/meerkat/xml-rpc/server.php"));
148 
149   if (!resp.isOK())
150     return handleFault(resp);
151 
152   Value val = resp.getResult();
153 
154   if (!val.isArray())
155   {
156 
157     ULXR_COUT << ULXR_PCHAR("No items found for your query string.\n");
158     return 0;
159   }
160 
161   Array list = val;
162 
163   ULXR_COUT << ULXR_PCHAR("Found ") << list.size() << ULXR_PCHAR(" items:\n\n");
164   for (unsigned i = 0; i < list.size(); ++i)
165   {
166     Struct entry = list.getItem(i);
167     RpcString title = entry.getMember(ULXR_PCHAR("title"));
168     RpcString link = entry.getMember(ULXR_PCHAR("link"));
169     RpcString description = entry.getMember(ULXR_PCHAR("description"));
170 
171     ULXR_COUT << ULXR_PCHAR(" Title: ") << title.getString() << std::endl
172               << ULXR_PCHAR(" Link: ") << link.getString() << std::endl;
173 
174     CppString s = description.getString();
175     if (s.length() != 0)
176       ULXR_COUT << ULXR_PCHAR(" Description: ") <<  s << ULXR_PCHAR("\n");
177 
178     ULXR_COUT << ULXR_PCHAR("\n");
179   }
180   ULXR_COUT << ULXR_PCHAR("\n");
181   return 0;
182 }
183 
184 
main(int argc,char ** argv)185 int main(int argc, char **argv)
186 {
187   try {
188     TcpIpConnection conn (false, ULXR_PCHAR("www.oreillynet.com"), 80);
189     HttpProtocol prot(&conn);
190     Requester client(&prot);
191     MethodResponse resp;
192 
193     if (argc < 2)
194       usage(1);
195 
196     CppString cmd = ULXR_GET_STRING(argv[1]);
197     if (argc == 2)
198     {
199       if (cmd == ULXR_PCHAR("-c") || cmd == ULXR_PCHAR("--channels"))
200         return showChannels(client);
201 
202       else if (cmd == ULXR_PCHAR("-e") || cmd == ULXR_PCHAR("--categories"))
203         return showChannels(client);
204 
205       else if (cmd == ULXR_PCHAR("--help"))
206         usage(0);
207 
208       else
209         usage(1);
210     }
211 
212     else if (argc == 3)
213     {
214       if (cmd == ULXR_PCHAR("-s") || cmd == ULXR_PCHAR("--search"))
215         return searchdb(client, ULXR_GET_STRING(argv[2]));
216 
217       else
218         usage(1);
219     }
220 
221     else
222       usage(1);
223 
224   }
225   catch(Exception &ex)
226   {
227      ULXR_COUT << ULXR_PCHAR("Error occured: ") << ex.why() << std::endl;
228      return 1;
229   }
230   catch(std::exception &ex)
231   {
232      ULXR_COUT << ULXR_PCHAR("Error occured: ") << ULXR_GET_STRING(ex.what()) << std::endl;
233      return 1;
234   }
235   catch(...)
236   {
237      ULXR_COUT << ULXR_PCHAR("unknown Error occured.\n");
238      return 1;
239   }
240 
241   return 0;
242 }
243 
244 /*
245     MethodCall get_ChannelsByCategory ("meerkat.getChannelsByCategory");
246     get_ChannelsByCategory.addParam(Integer(10));
247 
248     MethodCall get_CategoriesBySubstring ("meerkat.getCategoriesBySubstring");
249     get_CategoriesBySubstring.addParam(String ("linux"));
250 
251     MethodCall get_ChannelsBySubstring ("meerkat.getChannelsBySubstring");
252     get_ChannelsBySubstring.addParam(String ("linux"));
253 
254     resp = client.call(get_ChannelsBySubstring, "/meerkat/xml-rpc/server.php");
255     ULXR_COUT << "call result: \n";
256     ULXR_COUT << resp.getXml(0);
257 
258     resp = client.call(get_CategoriesBySubstring, "/meerkat/xml-rpc/server.php");
259     ULXR_COUT << "call result: \n";
260     ULXR_COUT << resp.getXml(0);
261 
262     resp = client.call(get_ChannelsByCategory, "/meerkat/xml-rpc/server.php");
263     ULXR_COUT << "call result: \n";
264     ULXR_COUT << resp.getXml(0);
265 
266     resp = client.call(list_methods, "/meerkat/xml-rpc/server.php");
267     ULXR_COUT << "call result: \n";
268     ULXR_COUT << resp.getXml(0);
269 */
270