From 77684af25efe1e3d3ca4e3462aed42c3489c0558 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Orsini Date: Thu, 25 Apr 2013 07:10:22 +0000 Subject: [PATCH] --- src/Makefile.am | 2 + src/Makefile.in | 9 ++- src/io.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io.h | 50 +++++++++++++++ src/ttrss.c | 55 +++++++++++++++- 5 files changed, 305 insertions(+), 5 deletions(-) create mode 100644 src/io.c create mode 100644 src/io.h diff --git a/src/Makefile.am b/src/Makefile.am index 042d0f2..e4850c8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,6 +14,8 @@ bin_PROGRAMS = prss prss_SOURCES = main.c \ http.c \ http.h \ + io.c \ + io.h \ ttrss.c \ ttrss.h \ ttrss_model.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 41e5e30..34b4319 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -64,9 +64,9 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) -am_prss_OBJECTS = main.$(OBJEXT) http.$(OBJEXT) ttrss.$(OBJEXT) \ - ttrss_model.$(OBJEXT) ttrss_ws.$(OBJEXT) url.$(OBJEXT) \ - webbrowser.$(OBJEXT) +am_prss_OBJECTS = main.$(OBJEXT) http.$(OBJEXT) io.$(OBJEXT) \ + ttrss.$(OBJEXT) ttrss_model.$(OBJEXT) ttrss_ws.$(OBJEXT) \ + url.$(OBJEXT) webbrowser.$(OBJEXT) prss_OBJECTS = $(am_prss_OBJECTS) prss_LDADD = $(LDADD) DEFAULT_INCLUDES = -I.@am__isrc@ @@ -295,6 +295,8 @@ AM_CPPFLAGS = -Wall -Werror $(CURL_CFLAGS) $(GTK_CFLAGS) $(JSON_CFLAGS) $(WEBKIT prss_SOURCES = main.c \ http.c \ http.h \ + io.c \ + io.h \ ttrss.c \ ttrss.h \ ttrss_model.c \ @@ -393,6 +395,7 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/http.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/io.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttrss.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttrss_model.Po@am__quote@ diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..e5bfdbb --- /dev/null +++ b/src/io.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2011-2012 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 +#include +#include +#include + +#include "io.h" + +/* Directory separator is \ when cross-compiling for MS Windows + systems */ +#if defined(__MINGW32__) +#define DIRSEP ('\\') +#else +#define DIRSEP '/' +#endif + +#define FCOPY_BUF_SZ 4096 + +static int file_copy(FILE *src, FILE *dst) +{ + int ret = 0; + char *buf = malloc(FCOPY_BUF_SZ); + int n; + + if (!buf) + return FILE_COPY_ERROR_ALLOC_BUFFER; + + while (!ret) { + n = fread(buf, 1, FCOPY_BUF_SZ, src); + if (n) { + if (fwrite(buf, 1, n, dst) != n) + ret = FILE_COPY_ERROR_WRITE; + } else { + if (!feof(src)) + ret = FILE_COPY_ERROR_READ; + else + break; + } + } + + free(buf); + + return ret; +} + +int fcopy(const char *src, const char *dst) +{ + FILE *fsrc, *fdst; + int ret = 0; + + fsrc = fopen(src, "r"); + + if (fsrc) { + fdst = fopen(dst, "w+"); + + if (fdst) { + ret = file_copy(fsrc, fdst); + fclose(fdst); + } else { + ret = FILE_COPY_ERROR_OPEN_DST; + } + + fclose(fsrc); + } else { + ret = FILE_COPY_ERROR_OPEN_SRC; + } + + return ret; +} + +char *path_append(const char *odir, const char *name) +{ + char *dir; + + dir = malloc(strlen(odir)+1+strlen(name)+1); + + strcpy(dir, odir); + if (odir[strlen(odir) - 1] != '/' && name[0] != '/') + strcat(dir, "/"); + strcat(dir, name); + + return dir; +} + +void mkdirs(const char *dirs, mode_t mode) +{ + char *c = (char *)dirs; + char *dir = malloc(strlen(dirs) + 1); + + int i = 0; + while (*c) { + if ((*c == DIRSEP || *c == '\0') && c != dirs) { + strncpy(dir, dirs, i); + dir[i] = '\0'; + mkdir(dir, mode); + } + + c++; + i++; + } + + mkdir(dirs, mode); + + free(dir); +} + +static int is_file(const char *path) +{ + struct stat st; + + int ret = lstat(path, &st); + + if (ret == 0 && S_ISREG(st.st_mode)) + return 1; + + return 0; +} + +static long file_get_size(const char *path) +{ + FILE *fp; + + if (!is_file(path)) + return -1; + + fp = fopen(path, "rb"); + if (fp) { + long size; + + if (fseek(fp, 0, SEEK_END) == -1) + return -1; + + size = ftell(fp); + + fclose(fp); + + return size; + } + + return -1; +} + +char *file_get_content(const char *fpath) +{ + long size; + + char *page; + + size = file_get_size(fpath); + if (size == -1) { + page = NULL; + + } else if (size == 0) { + page = malloc(1); + *page = '\0'; + + } else { + FILE *fp = fopen(fpath, "rb"); + if (fp) { + page = malloc(size + 1); + if (!page || size != fread(page, 1, size, fp)) { + free(page); + return NULL; + } + + *(page + size) = '\0'; + + fclose(fp); + } else { + page = NULL; + } + } + + return page; +} + diff --git a/src/io.h b/src/io.h new file mode 100644 index 0000000..189c3d1 --- /dev/null +++ b/src/io.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2011-2012 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 _PRSS_IO_H_ +#define _PRSS_IO_H_ + +/* + * Convenience functions for copying files. + */ + + +enum file_copy_code { + FILE_COPY_OK = 0, + FILE_COPY_ERROR_OPEN_SRC = 1, + FILE_COPY_ERROR_OPEN_DST, + FILE_COPY_ERROR_READ, + FILE_COPY_ERROR_WRITE, + FILE_COPY_ERROR_ALLOC_BUFFER +}; + +/* + * Copies file 'src' to 'dst'. + * + * Returns FILE_COPY_OK on success otherwise error code. + */ +int fcopy(const char *src, const char *dst); + +char *path_append(const char *odir, const char *name); + +void mkdirs(const char *dirs, mode_t mode); + +char *file_get_content(const char *fpath); + +#endif diff --git a/src/ttrss.c b/src/ttrss.c index 3ec22f8..ecde0a5 100644 --- a/src/ttrss.c +++ b/src/ttrss.c @@ -20,18 +20,69 @@ #include #include +#include #include #include "http.h" +#include "io.h" #include "ttrss_ws.h" #include "url.h" static struct feed **data; +static char *cache_dir; + +static const char *get_cache_dir() +{ + char *home; + + if (!cache_dir) { + home = getenv("HOME"); + + if (!home) + return NULL; + + cache_dir = path_append(home, ".prss/cache"); + mkdirs(cache_dir, 0777); + } + + return cache_dir; +} + +static void file_set_content(const char *path, const char *content) +{ + FILE *fp; + + fp = fopen(path, "w"); + if (fp) { + fwrite(content, 1, strlen(content), fp); + fclose(fp); + } +} const char *ttrss_get_headline_content(struct headline *h) { - if (!h->content) - h->content = ws_get_article_content(h->id); + const char *cache_dir; + char *path, *content; + + if (!h->content) { + cache_dir = get_cache_dir(); + if (cache_dir) { + path = g_strdup_printf("%s/%d", cache_dir, h->id); + + content = file_get_content(path); + + if (content) { + h->content = content; + } else { + h->content = ws_get_article_content(h->id); + + if (h->content) + file_set_content(path, h->content); + } + + free(path); + } + } return h->content; } -- 2.7.4