Bug 95891

Summary: Loss of data when akregator crashes
Product: [Applications] akregator Reporter: Jean-Marc Tremeaux <naku>
Component: generalAssignee: kdepim bugs <kdepim-bugs>
Status: RESOLVED WORKSFORME    
Severity: normal    
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Debian testing   
OS: Linux   
Latest Commit: Version Fixed In:

Description Jean-Marc Tremeaux 2004-12-27 19:45:57 UTC
Version:            (using KDE KDE 3.3.2)
Installed from:    Debian testing/unstable Packages
OS:                Linux

My feed list is not saved if akregator crashes. So I loose the last feeds I've added / modified. This can also happens for example if I close KDE "violently" (i.e. CTRL+ALT+Backspace). 

So far, to make sure I don't loose data, i have to close / reopen akregator each time I make a modification on the feed list.
The wanted behavior would be to save the list to the disk immediatly as I make a modification (or add/delete a feed).

How to reproduce :
- Add a feed
- kill akregator (kill -11 akregator)
- Re-start akregator : changes are lost
Comment 1 Teemu Rytilahti 2004-12-27 22:19:46 UTC
Yup, this is known. Don't know if this is a feature or a bug, but if we'd save the settings for example everytime something has changed we should make it possible to undo them too. I have removed accidentally some feeds and such, and then I've just killed aKregator and everything is there like they should be...
Comment 2 Frank Osterfeld 2004-12-31 09:24:14 UTC
We could also add an auto-save function where the user can set a time interval for auto-saving the feed list.
Comment 3 Frank Osterfeld 2005-01-08 10:56:34 UTC
CVS commit by osterfeld: 

Autosave the feed list every 5 minutes. A backup is created once per session, so you can undo 
unwanted changes.
CCBUG: 95891


  M +36 -9     akregator_part.cpp   1.127
  M +8 -5      akregator_part.h   1.56
  M +1 -1      akregator_view.cpp   1.206


--- kdepim/akregator/src/akregator_part.cpp  #1.126:1.127
@@ -155,4 +155,5 @@ Part::Part( QWidget *parentWidget, const
 {
     m_mergedPart = 0;
+    m_backedUpList = false;
     // we need an instance
     setInstance( AkregatorFactory::instance() );
@@ -181,4 +182,8 @@ Part::Part( QWidget *parentWidget, const
     connect(kapp, SIGNAL(shutDown()), this, SLOT(slotOnShutdown()));
     
+    m_autosaveTimer = new QTimer(this);
+    connect(m_autosaveTimer, SIGNAL(timeout()), this, SLOT(slotSaveFeedList()));
+    m_autosaveTimer->start(5*60*1000); // 5 minutes
+    
     // set our XML-UI resource file
     setXMLFile("akregator_part.rc", true);
@@ -189,6 +194,7 @@ void Part::slotOnShutdown()
 {
     m_shuttingDown = true;
+    m_autosaveTimer->stop();
     saveSettings();
-    saveFeedList();
+    slotSaveFeedList();
     m_view->slotOnShutdown();
 }
@@ -253,4 +259,5 @@ void Part::newArticle(Feed *src, const M
 void Part::readProperties(KConfig* config)
 {
+    m_backedUpList = false;
     if(m_view)
         m_view->readProperties(config);
@@ -451,16 +458,40 @@ bool Part::closeURL()
 
 
-bool Part::saveFeedList()
+void Part::slotSaveFeedList()
 {
     // don't save to the standard feed list, when it wasn't completely loaded before
     if (!m_standardListLoaded)
-        return false;
+        return;
+    
     // m_file is always local, so we use QFile
     QFile file(m_file);
+
+    // the first time we overwrite the feed list, we create a backup
+    if (!m_backedUpList)
+    {
+        if (file.open(IO_ReadOnly))
+        {
+            QFile backup(m_file + "~");
+            if (backup.open(IO_WriteOnly))
+            {
+                // since the feed list is a text file, this should be ok
+                QTextStream in(&file);
+                QTextStream out(&backup);
+                while (!in.atEnd())
+                    out << in.readLine();
+
+                backup.close();
+                m_backedUpList = true;
+            }
+            
+            file.close();
+        }
+    }
+    
     if (file.open(IO_WriteOnly) == false)
     {
         //FIXME: allow to save the feedlist into different location -tpr 20041118
         KMessageBox::error(m_view, i18n("Access denied: cannot save feed list (%1)").arg(m_file), i18n("Write error") );
-        return false;
+        return;
     }
 
@@ -472,11 +503,7 @@ bool Part::saveFeedList()
     // Archive data files are saved elsewhere.
 
-    QDomDocument doc = m_view->feedListToOPML();
-
-    stream << doc.toString();
+    stream << m_view->feedListToOPML().toString();
 
     file.close();
-
-    return true;
 }
 

--- kdepim/akregator/src/akregator_part.h  #1.55:1.56
@@ -19,4 +19,6 @@ typedef KPIM::Part MyBasePart;
 #include "akregator_partiface.h"
 
+class QTimer;
+
 class KAboutData;
 class KConfig;
@@ -121,9 +123,4 @@ namespace Akregator
             virtual void saveProperties(KConfig* config);
 
-            /**
-             Saves the feed list.
-             @return Whether the feed list was successfully saved */
-            bool saveFeedList();
-
             /** @return Whether the tray icon is enabled or not */
             virtual bool isTrayIconEnabled() const;
@@ -141,4 +138,7 @@ namespace Akregator
             virtual void saveSettings();
 
+            /** Saves the standard feed list to it's default location */
+            void slotSaveFeedList();
+            
         signals:
             void showPart();
@@ -188,4 +188,7 @@ namespace Akregator
             View* m_view;
             TrayIcon* m_trayIcon;
+            QTimer* m_autosaveTimer;
+            /** did we backup the feed list already? */
+            bool m_backedUpList; 
             
             

--- kdepim/akregator/src/akregator_view.cpp  #1.205:1.206
@@ -1567,5 +1567,5 @@ void View::saveProperties(KConfig* confi
 {   
     // save the feedlist, fixes #84528, at least partially -tpr 20041025
-    m_part->saveFeedList();
+    m_part->slotSaveFeedList();
     // save filter settings
     config->writeEntry("searchLine", m_searchLine->text());


Comment 4 Eckhart Wörner 2005-05-02 19:41:30 UTC
The solution of storing it every 5 minutes looks strange for me. On the one hand, you cannot be sure that the feed list is saved, on the other hand it's not possible to undo your changes by killing Akregator because you cannot be sure it's not saved yet.
Comment 5 Frank Osterfeld 2005-08-16 22:54:36 UTC
Ideally there was a modified signal in FeedList connected to a slot in Part that saves the feed list.
Comment 6 Jean-Marc Tremeaux 2006-03-24 16:49:23 UTC
Didn't have any loss of data for some time, so the fix seems fine to me and I'm marking this bug as resolved (reporter).