On Fri, 2008-08-15 at 23:29 +0100, Adeodato Simó wrote:
> * rodrigo@debian.org [Thu, 14 Aug 2008 17:10:06 -0700]:
>
> > I'm seeking aproval for uploading liferea 1.4.18 to unstable
> > The diff from 1.4.16b, present currently in the archive is large because
> > upstream stopped shipping generated intltool files.
>
> Please send us a cleaned up diff (i.e., only code changes) for review.
rodrigo@nabiki:$ git diff --stat -p -b release/1.4.16b-0.1 -- src xslt
liferea/src/common.c | 6 +-
liferea/src/common.h | 6 +-
liferea/src/db.c | 114 ++++++++++++++++++++++++------------------
liferea/src/feedlist.c | 6 ++
liferea/src/scripting/lua.c | 13 +++--
liferea/src/ui/ui_popup.c | 2 +-
liferea/xslt/item.xml | 2 +-
liferea/xslt/item.xml.in | 2 +-
8 files changed, 89 insertions(+), 62 deletions(-)
diff --git a/liferea/src/common.c b/liferea/src/common.c
index 3201a34..0f45b31 100644
--- a/liferea/src/common.c
+++ b/liferea/src/common.c
@@ -1,7 +1,7 @@
/**
* @file common.c common routines for Liferea
*
- * Copyright (C) 2003-2007 Lars Lindner <lars.lindner@gmail.com>
+ * Copyright (C) 2003-2008 Lars Lindner <lars.lindner@gmail.com>
* Copyright (C) 2004-2006 Nathan J. Conrad <t98502@users.sourceforge.net>
* Copyright (C) 2004 Karl Soderstrom <ks@xanadunet.net>
*
@@ -179,10 +179,10 @@ gchar * common_format_nice_date(time_t date) {
if (!done) {
if (then.tm_year == now.tm_year) {
/* translation hint: date format for dates older than a week but from this year, reorder format codes as necessary */
- e_strftime_fix_am_pm (buf, TIMESTRLEN, _("%b %d %l:%M %p"), &then);
+ e_utf8_strftime_fix_am_pm (buf, TIMESTRLEN, _("%b %d %l:%M %p"), &then);
} else {
/* translation hint: date format for dates from the last years, reorder format codes as necessary */
- e_strftime_fix_am_pm (buf, TIMESTRLEN, _("%b %d %Y"), &then);
+ e_utf8_strftime_fix_am_pm (buf, TIMESTRLEN, _("%b %d %Y"), &then);
}
}
diff --git a/liferea/src/common.h b/liferea/src/common.h
index ec2c52a..0a91ffa 100644
--- a/liferea/src/common.h
+++ b/liferea/src/common.h
@@ -75,9 +75,9 @@ long common_parse_long(gchar *str, long def);
* Returns a formatted date string for the given timestamp.
*
* @param t the timestamp
- * @param date_format a strptime format string (encoded in user locale!)
+ * @param date_format a strptime format string (encoded in UTF-8)
*
- * @returns a new formatted date string (encoded in user locale!)
+ * @returns a new formatted date string (encoded in UTF-8)
*/
gchar * common_format_date(time_t date, const gchar *date_format);
@@ -88,7 +88,7 @@ gchar * common_format_date(time_t date, const gchar *date_format);
*
* @param t the timestamp
*
- * @returns a new formatted date string (encoded in user locale!)
+ * @returns a new formatted date string (encoded in UTF-8)
*/
gchar * common_format_nice_date(time_t date);
diff --git a/liferea/src/db.c b/liferea/src/db.c
index 193d420..9ea43a8 100644
--- a/liferea/src/db.c
+++ b/liferea/src/db.c
@@ -31,6 +31,7 @@
static sqlite3 *db = NULL;
static guint stmtCounter = 0;
+static gboolean transaction = FALSE; /**< single transaction lock, prevents DB re-opening during transaction */
/**
* To avoid loosing statements on crashes, close+reopen the DB from time to time,
@@ -92,7 +93,7 @@ redo:
if (statement->write)
stmtCounter++;
- if (stmtCounter > MAX_STATEMENTS_BEFORE_RECONNECT) {
+ if (!transaction && (stmtCounter > MAX_STATEMENTS_BEFORE_RECONNECT)) {
stmtCounter = 0;
debug1 (DEBUG_DB, "DB reconnect after %d DB write actions...\n", MAX_STATEMENTS_BEFORE_RECONNECT);
db_deinit ();
@@ -418,29 +419,6 @@ open:
db_exec ("CREATE INDEX metadata_idx ON metadata (item_id);");
- /* Set up item removal trigger (does not remove comments!) */
- db_exec ("DROP TRIGGER item_removal;");
- db_exec ("CREATE TRIGGER item_removal DELETE ON itemsets "
- "BEGIN "
- " DELETE FROM items WHERE ROWID = old.item_id; "
- " DELETE FROM metadata WHERE item_id = old.item_id; "
- "END;");
-
- /* Set up item read state update triggers */
- db_exec ("DROP TRIGGER item_insert;");
- db_exec ("CREATE TRIGGER item_insert INSERT ON items "
- "BEGIN "
- " UPDATE itemsets SET read = new.read "
- " WHERE item_id = new.ROWID; "
- "END;");
-
- db_exec ("DROP TRIGGER item_update;");
- db_exec ("CREATE TRIGGER item_update UPDATE ON items "
- "BEGIN "
- " UPDATE itemsets SET read = new.read "
- " WHERE item_id = new.ROWID; "
- "END;");
-
db_exec ("CREATE TABLE subscription ("
" node_id STRING,"
" source STRING,"
@@ -472,15 +450,6 @@ open:
db_exec ("CREATE INDEX subscription_metadata_idx ON subscription_metadata (node_id);");
- /* Set up subscription removal trigger */
- db_exec ("DROP TRIGGER subscription_removal;");
- db_exec ("CREATE TRIGGER subscription_removal DELETE ON subscription "
- "BEGIN "
- " DELETE FROM node WHERE node_id = old.node_id; "
- " DELETE FROM update_state WHERE node_id = old.node_id; "
- " DELETE FROM subscription_metadata WHERE node_id = old.node_id; "
- "END;");
-
db_exec ("CREATE TABLE node ("
" node_id STRING,"
" parent_id STRING,"
@@ -500,29 +469,71 @@ open:
" PRIMARY KEY (node_id)"
");");
- /* view counting triggers are set up in the view preparation code (see db_view_create()) */
-
db_end_transaction ();
debug_end_measurement (DEBUG_DB, "table setup");
- /* Cleanup of DB */
+ /* 2. Removing old triggers */
+ db_exec ("DROP TRIGGER item_insert;");
+ db_exec ("DROP TRIGGER item_update;");
+ db_exec ("DROP TRIGGER item_removal;");
+ db_exec ("DROP TRIGGER subscription_removal;");
- /*
- debug_start_measurement (DEBUG_DB);
- db_exec ("DELETE FROM items WHERE ROWID NOT IN "
- "(SELECT item_id FROM itemsets);");
- debug_end_measurement (DEBUG_DB, "cleanup lost items");
+ /* 3. Cleanup of DB */
- debug_start_measurement (DEBUG_DB);
- db_exec ("DELETE FROM itemsets WHERE item_id NOT IN "
- "(SELECT ROWID FROM items);");
- debug_end_measurement (DEBUG_DB, "cleanup lost itemset entries");
+ if (initial) {
+ debug0 (DEBUG_DB, "Checking for items not referenced in table 'itemsets'...\n");
+ db_exec ("BEGIN; "
+ " CREATE TEMP TABLE tmp_id ( id );"
+ " INSERT INTO tmp_id SELECT ROWID FROM items WHERE ROWID NOT IN (SELECT item_id FROM itemsets);"
+ " DELETE FROM items WHERE ROWID IN (SELECT id FROM tmp_id LIMIT 1000);"
+ " DROP TABLE tmp_id;"
+ "END;");
- debug_start_measurement (DEBUG_DB);
+ debug0 (DEBUG_DB, "Checking for invalid item ids in table 'itemsets'...\n");
+ db_exec ("BEGIN; "
+ " CREATE TEMP TABLE tmp_id ( id );"
+ " INSERT INTO tmp_id SELECT item_id FROM itemsets WHERE item_id NOT IN (SELECT ROWID FROM items);"
+ /* limit to 1000 items as it is very slow */
+ " DELETE FROM itemsets WHERE item_id IN (SELECT id FROM tmp_id LIMIT 1000);"
+ " DROP TABLE tmp_id;"
+ "END;");
+
+ debug0 (DEBUG_DB, "Checking for items without a subscription...\n");
db_exec ("DELETE FROM itemsets WHERE comment = 0 AND node_id NOT IN "
"(SELECT node_id FROM subscription);");
- debug_end_measurement (DEBUG_DB, "cleanup lost node entries");
- */
+
+ debug0 (DEBUG_DB, "DB cleanup finished. Continuing startup.\n");
+ }
+
+ /* 4. Creating triggers (after cleanup so it is not slowed down by triggers) */
+
+ db_exec ("CREATE TRIGGER item_insert INSERT ON items "
+ "BEGIN "
+ " UPDATE itemsets SET read = new.read "
+ " WHERE item_id = new.ROWID; "
+ "END;");
+
+ db_exec ("CREATE TRIGGER item_update UPDATE ON items "
+ "BEGIN "
+ " UPDATE itemsets SET read = new.read "
+ " WHERE item_id = new.ROWID; "
+ "END;");
+
+ /* This trigger does explicitely not remove comments! */
+ db_exec ("CREATE TRIGGER item_removal DELETE ON itemsets "
+ "BEGIN "
+ " DELETE FROM items WHERE ROWID = old.item_id; "
+ " DELETE FROM metadata WHERE item_id = old.item_id; "
+ "END;");
+
+ db_exec ("CREATE TRIGGER subscription_removal DELETE ON subscription "
+ "BEGIN "
+ " DELETE FROM node WHERE node_id = old.node_id; "
+ " DELETE FROM update_state WHERE node_id = old.node_id; "
+ " DELETE FROM subscription_metadata WHERE node_id = old.node_id; "
+ "END;");
+
+ /* Note: view counting triggers are set up in the view preparation code (see db_view_create()) */
}
/* prepare statements */
@@ -549,7 +560,7 @@ open:
"WHERE node_id = ?");
db_new_statement ("itemsetRemoveStmt",
- "DELETE FROM itemsets WHERE parent_item_id = ?");
+ "DELETE FROM itemsets WHERE item_id = ? OR parent_item_id = ?");
db_new_statement ("itemsetRemoveAllStmt",
"DELETE FROM itemsets WHERE parent_node_id = ?");
@@ -964,6 +975,7 @@ db_item_remove (gulong id)
stmt = db_get_statement ("itemsetRemoveStmt");
sqlite3_bind_int (stmt, 1, id);
+ sqlite3_bind_int (stmt, 2, id);
res = sqlite3_step (stmt);
if (SQLITE_DONE != res)
@@ -1174,6 +1186,8 @@ db_begin_transaction (void)
res = sqlite3_exec (db, sql, NULL, NULL, &err);
if (SQLITE_OK != res)
g_warning ("Transaction begin failed (%s) SQL: %s", err, sql);
+ else
+ transaction = TRUE;
sqlite3_free (sql);
sqlite3_free (err);
}
@@ -1188,6 +1202,8 @@ db_end_transaction (void)
res = sqlite3_exec (db, sql, NULL, NULL, &err);
if (SQLITE_OK != res)
g_warning ("Transaction end failed (%s) SQL: %s", err, sql);
+ else
+ transaction = FALSE;
sqlite3_free (sql);
sqlite3_free (err);
}
diff --git a/liferea/src/feedlist.c b/liferea/src/feedlist.c
index 2c95a91..0e4445b 100644
--- a/liferea/src/feedlist.c
+++ b/liferea/src/feedlist.c
@@ -381,6 +381,8 @@ on_menu_allfeedsread (GtkWidget *widget, gpointer user_data)
problems. Use feedlist_schedule_save() instead! */
static gboolean feedlist_schedule_save_cb(gpointer user_data) {
+ g_return_if_fail(NULL != rootNode);
+
/* step 1: request each node to save its state */
feedlist_foreach(node_save);
@@ -511,7 +513,11 @@ feedlist_free_node (nodePtr node)
void
feedlist_free (void)
{
+ if (autoUpdateTimer)
g_source_remove (autoUpdateTimer);
+ if (feedlist_save_timer)
+ g_source_remove (feedlist_save_timer);
+
feedlist_foreach (feedlist_free_node);
node_free (rootNode);
rootNode = NULL;
diff --git a/liferea/src/scripting/lua.c b/liferea/src/scripting/lua.c
index 8b4f263..c1b12ee 100644
--- a/liferea/src/scripting/lua.c
+++ b/liferea/src/scripting/lua.c
@@ -1,7 +1,7 @@
/**
* @file script.c LUA scripting plugin implementation
*
- * Copyright (C) 2006 Lars Lindner <lars.lindner@gmx.net>
+ * Copyright (C) 2006-2008 Lars Lindner <lars.lindner@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -33,18 +33,23 @@ static void lua_init(void) {
luaVM = lua_open();
+ #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
+ luaL_openlibs(luaVM); /* LUA 5.1 allows loading all default modules... */
+ #endif
+
luaL_reg lualibs[] = {
+ #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
+ #else
+ /* LUA 5.0 forces us to load all modules ourselves... */
{"base", luaopen_base},
{"table", luaopen_table},
{"io", luaopen_io},
{"string", luaopen_string},
{"math", luaopen_math},
{"debug", luaopen_debug},
- #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501
- {"package", luaopen_package},
- #else
{"package", luaopen_loadlib},
#endif
+ /* This loads swig generated Liferea module... */
{SWIG_name, SWIG_init},
{NULL, NULL}
};
diff --git a/liferea/src/ui/ui_popup.c b/liferea/src/ui/ui_popup.c
index 7757bda..0b86150 100644
--- a/liferea/src/ui/ui_popup.c
+++ b/liferea/src/ui/ui_popup.c
@@ -141,7 +141,7 @@ void ui_popup_update_menues(void) {
addPopupOption(&item_menu_items, &item_menu_len, _("/Copy Item _URL to Clipboard"), NULL, on_popup_copy_URL_clipboard, 0, NULL, 0);
addPopupOption(&item_menu_items, &item_menu_len, "/", NULL, NULL, 0, "<Separator>", 0);
- addPopupOption(&item_menu_items, &item_menu_len, _("/Toggle _Read Status"), NULL, on_popup_toggle_read, 0, NULL, 0);
+ addPopupOption(&item_menu_items, &item_menu_len, _("/Toggle _Read Status"), NULL, on_popup_toggle_read, 0, "<Separator>", GTK_STOCK_APPLY);
addPopupOption(&item_menu_items, &item_menu_len, _("/Toggle Item _Flag"), NULL, on_popup_toggle_flag, 0, NULL, 0);
addPopupOption(&item_menu_items, &item_menu_len, _("/R_emove Item"), NULL, on_popup_remove_selected, 0, "<StockItem>", GTK_STOCK_DELETE);
diff --git a/liferea/xslt/item.xml b/liferea/xslt/item.xml
index e445e02..aff2256 100644
--- a/liferea/xslt/item.xml
+++ b/liferea/xslt/item.xml
@@ -109,7 +109,7 @@
</td>
<td width="99%">
<xsl:choose>
- <xsl:when test="contains(.,'mp3') or contains(.,'ogg')">
+ <xsl:when test="contains(.,'mp3')">
<span class="xspf_player">
<xsl:variable name="song">
<xsl:call-template name="substring-after-last">
diff --git a/liferea/xslt/item.xml.in b/liferea/xslt/item.xml.in
index 2f0dfa9..4e9fada 100644
--- a/liferea/xslt/item.xml.in
+++ b/liferea/xslt/item.xml.in
@@ -134,7 +134,7 @@
</td>
<td width="99%">
<xsl:choose>
- <xsl:when test="contains(.,'mp3') or contains(.,'ogg')">
+ <xsl:when test="contains(.,'mp3')">
<span class="xspf_player">
<xsl:variable name="song">
<xsl:call-template name="substring-after-last">
Attachment:
signature.asc
Description: This is a digitally signed message part