(no commit message)
authorJean-Philippe Orsini <jeanfi@gmail.com>
Mon, 22 Apr 2013 06:53:44 +0000 (06:53 +0000)
committerJean-Philippe Orsini <jeanfi@gmail.com>
Mon, 22 Apr 2013 06:53:44 +0000 (06:53 +0000)
configure.ac
src/Makefile.am
src/glade/prss.glade
src/main.c
src/phttp.c [new file with mode: 0644]
src/prss.gschema.xml [new file with mode: 0644]
src/url.c [new file with mode: 0644]
src/url.h [new file with mode: 0644]

index 0789ce1..923900b 100644 (file)
@@ -40,12 +40,25 @@ GTK_CFLAGS+=" -DGSEAL_ENABLE "
 AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)
 
 AC_SUBST(GTK_CFLAGS)
 AC_SUBST(GTK_LIBS)
 
+# Checks CURL 
+PKG_CHECK_MODULES(CURL, libcurl )
+AC_SUBST(CURL_CFLAGS)
+AC_SUBST(CURL_LIBS)
+
 # Check JSON
 JSON_LIBS=
 PKG_CHECK_MODULES(JSON, json)
 AC_SUBST(JSON_CFLAGS)
 AC_SUBST(JSON_LIBS)
 
 # Check JSON
 JSON_LIBS=
 PKG_CHECK_MODULES(JSON, json)
 AC_SUBST(JSON_CFLAGS)
 AC_SUBST(JSON_LIBS)
 
+# Gsettings
+GLIB_GSETTINGS
+
+# Webkit
+PKG_CHECK_MODULES(WEBKIT, webkitgtk-3.0)
+AC_SUBST(WEBKIT_CFLAGS)
+AC_SUBST(WEBKIT_LIBS)
+
 AC_CONFIG_FILES([
  Makefile
  po/Makefile.in
 AC_CONFIG_FILES([
  Makefile
  po/Makefile.in
index dcc1c1b..d3055e2 100644 (file)
@@ -3,15 +3,27 @@ SUBDIRS=glade
 # -export-dynamic is need for defining handlers in the glade file.
 AM_LDFLAGS = -Wl,--as-needed  -export-dynamic
 
 # -export-dynamic is need for defining handlers in the glade file.
 AM_LDFLAGS = -Wl,--as-needed  -export-dynamic
 
-AM_CPPFLAGS = -Wall -Werror $(GTK_CFLAGS) $(JSON_CFLAGS)
+AM_CPPFLAGS = -Wall -Werror $(CURL_CFLAGS) $(GTK_CFLAGS) $(JSON_CFLAGS) $(WEBKIT_CFLAGS)
 
 DEFS = -DPACKAGE_DATA_DIR=\"$(pkgdatadir)\" -DLOCALEDIR=\"$(localedir)\" @DEFS@
 
 
 DEFS = -DPACKAGE_DATA_DIR=\"$(pkgdatadir)\" -DLOCALEDIR=\"$(localedir)\" @DEFS@
 
-LIBS = $(JSON_LIBS) $(GTK_LIBS)
+LIBS = $(CURL_LIBS) $(JSON_LIBS) $(GTK_LIBS) $(WEBKIT_LIBS)
 
 bin_PROGRAMS = prss
 
 
 bin_PROGRAMS = prss
 
-prss_SOURCES = main.c 
+prss_SOURCES = main.c \
+              phttp.c \
+              phttp.h \
+              ttrss.c \
+              ttrss.h \
+              url.c \
+              url.h \
+              webbrowser.c \
+              webbrowser.h
+
+gsettings_SCHEMAS=prss.gschema.xml
+
+@GSETTINGS_RULES@
 
 dist_man_MANS = prss.1
 
 
 dist_man_MANS = prss.1
 
index 5240d13..4886371 100644 (file)
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
+  <object class="GtkListStore" id="feed_store">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+      <!-- column-name gpointer1 -->
+      <column type="gpointer"/>
+    </columns>
+  </object>
+  <object class="GtkListStore" id="headline_store">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+      <!-- column-name gpointer1 -->
+      <column type="gpointer"/>
+    </columns>
+  </object>
   <object class="GtkWindow" id="window">
     <property name="can_focus">False</property>
   <object class="GtkWindow" id="window">
     <property name="can_focus">False</property>
+    <property name="title" translatable="yes">Pitchoune RSS</property>
+    <property name="default_width">800</property>
+    <property name="default_height">600</property>
     <child>
     <child>
-      <placeholder/>
+      <object class="GtkPaned" id="paned1">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="position">200</property>
+        <property name="position_set">True</property>
+        <child>
+          <object class="GtkScrolledWindow" id="scrolledwindow1">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTreeView" id="feed_tree">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="model">feed_store</property>
+                <property name="headers_visible">False</property>
+                <property name="headers_clickable">False</property>
+                <property name="fixed_height_mode">True</property>
+                <property name="enable_tree_lines">True</property>
+                <signal name="cursor-changed" handler="feed_cursor_changed_cbk" swapped="no"/>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection" id="treeview-selection1"/>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                    <property name="resizable">True</property>
+                    <property name="sizing">fixed</property>
+                    <property name="fixed_width">100</property>
+                    <property name="min_width">1</property>
+                    <property name="title" translatable="yes">Feed</property>
+                    <property name="expand">True</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext5"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="resize">True</property>
+            <property name="shrink">True</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkPaned" id="paned2">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="orientation">vertical</property>
+            <property name="position">300</property>
+            <property name="position_set">True</property>
+            <child>
+              <object class="GtkScrolledWindow" id="scrolledwindow2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <object class="GtkTreeView" id="headline_tree">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="model">headline_store</property>
+                    <signal name="cursor-changed" handler="headline_cursor_changed_cbk" swapped="no"/>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                        <property name="spacing">3</property>
+                        <property name="max_width">0</property>
+                        <property name="title" translatable="yes">Headline</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                          <attributes>
+                            <attribute name="text">0</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">False</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkScrolledWindow" id="webkit_window">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="shadow_type">in</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="resize">True</property>
+                <property name="shrink">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="resize">True</property>
+            <property name="shrink">True</property>
+          </packing>
+        </child>
+      </object>
     </child>
   </object>
 </interface>
     </child>
   </object>
 </interface>
index 22cbb60..35805df 100644 (file)
 #include <getopt.h>
 
 #include <json/json.h>
 #include <getopt.h>
 
 #include <json/json.h>
-
+#include "ttrss.h"
+#include <webkit/webkit.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
+#include "phttp.h"
+#include "webbrowser.h"
+
 static const char *program_name;
 
 static struct option long_options[] = {
 static const char *program_name;
 
 static struct option long_options[] = {
@@ -64,10 +68,111 @@ static void print_help()
        printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 }
 
        printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
 }
 
+GtkTreeView *w_treeview;
+GtkTreeView *w_headlineview;
+
+void update()
+{
+       GSettings *settings;
+       struct feed **feeds;
+       GtkTreeModel *model;
+       GtkTreeIter iter;
+
+       printf("update\n");
+       phttp_init();
+
+       settings = g_settings_new("prss");
+
+       ttrss_login(g_settings_get_string(settings, "url"),
+                   g_settings_get_string(settings, "user"),
+                   g_settings_get_string(settings, "password"));
+
+       model = gtk_tree_view_get_model(GTK_TREE_VIEW(w_treeview));
+       gtk_list_store_clear(GTK_LIST_STORE(model));
+
+       for (feeds = ttrss_get_feeds(); *feeds; feeds++) {
+               gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+
+               gtk_list_store_set(GTK_LIST_STORE(model),
+                                  &iter,
+                                  0, (*feeds)->title,
+                                  1, (*feeds),
+                                  -1);
+
+               printf("add\n");
+       }
+       printf("refresh done\n");
+}
+
+int feed_cursor_changed_cbk(GtkTreeView *treeview, gpointer data)
+{
+       printf("feed_cursor_changed_cbk\n");
+
+       GtkTreePath *path;
+       GtkTreeViewColumn *cols;
+       GtkTreeIter iter;
+       GtkTreeModel *model, *headline_model;
+       GtkListStore *headline_store;
+       struct feed *feed;
+       struct headline **headlines;
+
+       gtk_tree_view_get_cursor(treeview, &path, &cols);
+
+       if (path) {
+               model = gtk_tree_view_get_model(treeview);
+               gtk_tree_model_get_iter(model, &iter, path);
+               gtk_tree_model_get(model, &iter, 1, &feed, -1);
+
+               headline_model = gtk_tree_view_get_model(w_headlineview);
+               headline_store = GTK_LIST_STORE(headline_model);
+               gtk_list_store_clear(headline_store);
+               for (headlines = feed->headlines; *headlines; headlines++) {
+                       gtk_list_store_append(headline_store, &iter);
+
+                       gtk_list_store_set(headline_store,
+                                          &iter,
+                                          0, (*headlines)->title,
+                                          1, (*headlines),
+                                          -1);
+               }
+
+               gtk_tree_path_free(path);
+       }
+
+       return 1;
+}
+
+int headline_cursor_changed_cbk(GtkTreeView *treeview, gpointer data)
+{
+       printf("headline_cursor_changed_cbk\n");
+
+       GtkTreePath *path;
+       GtkTreeViewColumn *cols;
+       GtkTreeIter iter;
+       GtkTreeModel *model;
+       struct headline *headline;
+
+       gtk_tree_view_get_cursor(treeview, &path, &cols);
+
+       if (path) {
+               model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
+               gtk_tree_model_get_iter(model, &iter, path);
+               gtk_tree_model_get(model, &iter, 1, &headline, -1);
+
+               web_load(((struct headline *)headline)->content);
+
+
+
+
+               gtk_tree_path_free(path);
+       }
+
+       return 1;
+}
 
 int main(int argc, char **argv)
 {
 
 int main(int argc, char **argv)
 {
-       GtkWidget *window;
+       GtkWidget *window, *panh;
        GtkBuilder *builder;
        int optc, cmdok, opti;
 
        GtkBuilder *builder;
        int optc, cmdok, opti;
 
@@ -109,6 +214,18 @@ int main(int argc, char **argv)
                 PACKAGE_DATA_DIR G_DIR_SEPARATOR_S "prss.glade",
                 NULL);
        window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
                 PACKAGE_DATA_DIR G_DIR_SEPARATOR_S "prss.glade",
                 NULL);
        window = GTK_WIDGET(gtk_builder_get_object(builder, "window"));
+       w_treeview = GTK_TREE_VIEW(gtk_builder_get_object(builder,
+                                                         "feed_tree"));
+       w_headlineview = GTK_TREE_VIEW(gtk_builder_get_object(builder,
+                                                             "headline_tree"));
+
+       gtk_builder_connect_signals(builder, NULL);
+
+       update();
+
+       panh = GTK_WIDGET(gtk_builder_get_object(builder, "webkit_window"));
+
+       gtk_container_add(GTK_CONTAINER(panh), web_get_widget());
 
        gtk_builder_connect_signals(builder, NULL);
 
 
        gtk_builder_connect_signals(builder, NULL);
 
diff --git a/src/phttp.c b/src/phttp.c
new file mode 100644 (file)
index 0000000..81c8ad7
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2010-2013 jeanfi@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include <locale.h>
+#include <libintl.h>
+#define _(str) gettext(str)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <curl/curl.h>
+#include <json/json.h>
+
+#include "url.h"
+
+struct ucontent {
+       char *data;
+       size_t len;
+};
+
+static CURL *curl;
+
+static size_t cbk_curl(void *buffer, size_t size, size_t nmemb, void *userp)
+{
+       size_t realsize;
+       struct ucontent *mem;
+
+       realsize = size * nmemb;
+       mem = (struct ucontent *)userp;
+
+       mem->data = realloc(mem->data, mem->len + realsize + 1);
+
+       memcpy(&(mem->data[mem->len]), buffer, realsize);
+       mem->len += realsize;
+       mem->data[mem->len] = 0;
+
+       return realsize;
+}
+
+void phttp_init()
+{
+       curl = curl_easy_init();
+}
+
+void phttp_cleanup()
+{
+       curl_easy_cleanup(curl);
+}
+
+json_object *get_json_object(const char *url)
+{
+       struct ucontent chunk;
+       json_object *obj;
+
+       obj = NULL;
+
+       if (!curl)
+               return NULL;
+
+       chunk.data = malloc(1);
+       chunk.len = 0;
+
+       curl_easy_setopt(curl, CURLOPT_URL, url);
+       curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
+       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cbk_curl);
+       curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+       if (curl_easy_perform(curl) == CURLE_OK)
+               obj = json_tokener_parse(chunk.data);
+       else
+               fprintf(stderr, _("Fail to connect to: %s"), url);
+
+       free(chunk.data);
+
+       return obj;
+}
+
+static json_object *post(const char *url, const char *body)
+{
+       struct ucontent chunk;
+       json_object *obj;
+
+       obj = NULL;
+
+       chunk.data = malloc(1);
+       chunk.len = 0;
+
+       curl_easy_setopt(curl, CURLOPT_URL, url);
+       curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
+       curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body);
+       curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(body));
+       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cbk_curl);
+       curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+       if (curl_easy_perform(curl) == CURLE_OK)
+               obj = json_tokener_parse(chunk.data);
+       else
+               fprintf(stderr, _("Fail to connect to: %s"), url);
+       free(chunk.data);
+
+       return obj;
+}
+
+json_object *post_json_object(const char *url, struct json_object *j)
+{
+       return post(url, json_object_to_json_string(j));
+}
diff --git a/src/prss.gschema.xml b/src/prss.gschema.xml
new file mode 100644 (file)
index 0000000..d52f913
--- /dev/null
@@ -0,0 +1,13 @@
+<schemalist>
+  <schema id="prss" path="/apps/prss/">
+    <key name="url" type="s">
+      <default>'http://localhost/tt-rss'</default>
+    </key>
+    <key name="user" type="s">
+      <default>'user'</default>
+    </key>
+    <key name="password" type="s">
+      <default>'password'</default>
+    </key>
+  </schema>
+</schemalist>
\ No newline at end of file
diff --git a/src/url.c b/src/url.c
new file mode 100644 (file)
index 0000000..a08ccd3
--- /dev/null
+++ b/src/url.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010-2013 jeanfi@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+/*
+ * Part of the following code is based on:
+ * http://www.geekhideout.com/urlcode.shtml
+ */
+#include "url.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+char *url_normalize(const char *url)
+{
+       int n = strlen(url);
+       char *ret = strdup(url);
+
+       if (url[n - 1] == '/')
+               ret[n - 1] = '\0';
+
+       return ret;
+}
+
+static char to_hex(char code)
+{
+       static const char hex[] = "0123456789abcdef";
+       return hex[code & 0x0f];
+}
+
+/*
+ * Returns a url-encoded version of str.
+ */
+char *url_encode(const char *str)
+{
+       char *c, *buf, *pbuf;
+
+       buf = malloc(strlen(str) * 3 + 1);
+       pbuf = buf;
+
+       c = (char *)str;
+
+       while (*c) {
+
+               if (isalnum(*c) ||
+                   *c == '.' || *c == '_' || *c == '-' || *c == '~')
+                       *pbuf++ = *c;
+               else {
+                       *pbuf++ = '%';
+                       *pbuf++ = to_hex(*c >> 4);
+                       *pbuf++ = to_hex(*c & 0x0f);
+               }
+               c++;
+       }
+       *pbuf = '\0';
+
+       return buf;
+}
diff --git a/src/url.h b/src/url.h
new file mode 100644 (file)
index 0000000..ed2df80
--- /dev/null
+++ b/src/url.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2010-2013 jeanfi@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef _PLIB_URL_H_
+#define _PLIB_URL_H_
+
+char *url_encode(const char *str);
+char *url_normalize(const char *url);
+
+#endif