Bug 126283 - JJ: an error message should be shown when amarok can not write to db or files
Summary: JJ: an error message should be shown when amarok can not write to db or files
Status: RESOLVED FIXED
Alias: None
Product: amarok
Classification: Applications
Component: general (show other bugs)
Version: 2.3-GIT
Platform: Slackware Linux
: NOR normal
Target Milestone: 2.3.1
Assignee: Amarok Developers
URL:
Keywords: junior-jobs
: 134544 212717 212766 217314 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-04-26 12:29 UTC by richlv
Modified: 2010-02-08 00:34 UTC (History)
6 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description richlv 2006-04-26 12:29:57 UTC
Version:            (using KDE KDE 3.5.2)
Installed from:    Slackware Packages

currently amarok silently complains in console only if db is not writable (for example with sqlite, no write permissions to the file).

but it can create additional files, thus upon next start db is considered to be corrupted and as a result all collection data is lost.

additionally, amarok fails to write all other files (last.fm queue and others), but nothing is shown to user.

if amarok is unable to write to the collection db or any other of the configuration files, it should complain loudly, make sure nothing else gets modified/added to the directory and die gracefully.
Comment 1 Harald Sitter 2007-11-14 20:09:12 UTC

*** This bug has been marked as a duplicate of 122797 ***
Comment 2 richlv 2007-11-16 10:08:25 UTC
reopening, as discussed on irc.

this seems to be a different case, as the other issue deals with warning about non-writable media files, but this deals with configuration, database etc.

for some users, database with all the statistics is very important, so it seems a good idea to warn if there are problems with it as soon as possible.
Comment 3 Matt Howe 2008-06-15 07:47:14 UTC
Tested in 1.4.9.1: I changed the collection.db file to read only and tried to copy a file to the collection from the file browser by right-clicking and selecting 'Copy files to collection'. It appeared to work, no error report appeared. The file WAS successfully copied to the correct directory but was NOT added to the collection. On restarting Amarok, the collection appeared to be intact and I couldn't find any evidence of db corruption.
Comment 4 Matt Howe 2008-06-15 08:57:38 UTC
Still present in 2.x - no error report when failing to edit a read only collection.db.
Comment 5 Gary Steinert 2008-10-20 02:50:54 UTC
Im not sure, but now that collection.db is no longer used, should this bug be closed?

Gary
Comment 6 Mark Kretschmann 2008-10-20 10:56:13 UTC
Yeah. I mean, you could probably make the MySQLe file read-only too, but why anyone would do that is beyond me.
Comment 7 Lydia Pintscher 2008-10-20 22:47:38 UTC
Mark: What about full hard disk? And what about when Amarok can't write tags to files?
Comment 8 richlv 2008-10-21 08:48:01 UTC
or restore from backup with incorrect permissions, as happened to me
Comment 9 Lydia Pintscher 2008-10-29 12:56:22 UTC
moving to 2.1 as this needs new strings which are not going to find their way into 2.0 due to string freeze
Comment 10 Sven Krohlas 2009-03-12 11:31:56 UTC
SVN commit 938565 by krohlas:

* Disable "Guess tags from filename" button, if file is read only.
* Show a error message in the statusbar, if writing to file is not possible

CCBUG: 126283


 M  +2 -0      TagDialog.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=938565
Comment 11 Kuba Serafinowski 2009-08-07 14:43:23 UTC
In case mysqle dir is read-only Amarok just won't start and won't complain, I think it needs a message dialog before collapsing.
Comment 12 Myriam Schweingruber 2009-08-13 11:03:00 UTC
Changed severity. I don't know what is wrong with our query, but this doesn't show up in the one we use currently.
Comment 13 Myriam Schweingruber 2009-09-27 14:09:57 UTC
*** Bug 134544 has been marked as a duplicate of this bug. ***
Comment 14 Myriam Schweingruber 2009-12-04 13:35:25 UTC
*** Bug 217314 has been marked as a duplicate of this bug. ***
Comment 15 Mikko C. 2009-12-05 13:19:18 UTC
*** Bug 212717 has been marked as a duplicate of this bug. ***
Comment 16 Mikko C. 2009-12-05 13:20:07 UTC
*** Bug 212766 has been marked as a duplicate of this bug. ***
Comment 17 Casey Link 2010-02-07 17:13:45 UTC
commit 9673171e441d006f7641382d52cbe32c85218576
Author: Casey Link <unnamedrambler@gmail.com>
Date:   Fri Jan 8 16:53:23 2010 -0700

    Ensure that there exists a collection path in the local collection that
    has enough free space to copy the intended tracks to and still have at least 95%
    of the drive free, with a minimum of 5 megs, and, of course, be writable.
    All collection folders that do not satisfy these conditions are filtered out of the
    collection folder drop down in the organize dialog, so only folders that have enough space
    can be chosen.
    
    If there is not enough free space the organize dialog is not even shown, the
    entire process is aborted with a statusbar()->longmessage explaining the issue.
    
    Also, isWriteable() has been modified to take into account the above conditions.
    i.e., if >= 95% of the each path is full the collection will return that it is
    not writeable.
    
    BUG: 126283

diff --git a/src/collection/sqlcollection/SqlCollectionLocation.cpp b/src/collection/sqlcollection/SqlCollectionLocation.cpp
index bbf4c3e..7186963 100644
--- a/src/collection/sqlcollection/SqlCollectionLocation.cpp
+++ b/src/collection/sqlcollection/SqlCollectionLocation.cpp
@@ -34,6 +34,7 @@
 #include <QFile>
 #include <QFileInfo>
 
+#include <kdiskfreespaceinfo.h>
 #include <kjob.h>
 #include <KLocale>
 #include <KSharedPtr>
@@ -69,10 +70,32 @@ SqlCollectionLocation::actualLocation() const
 {
     return MountPointManager::instance()->collectionFolders();
 }
+
 bool
 SqlCollectionLocation::isWritable() const
 {
-    return true;
+    // The collection is writeable if there exists a path that has less than
+    // 95% free space.
+    bool path_exists_with_space = false;
+    bool path_exists_writeable = false;
+    QStringList folders = actualLocation();
+    foreach(QString path, folders)
+    {
+        float used = KDiskFreeSpaceInfo::freeSpaceInfo( path ).used();
+        float total = KDiskFreeSpaceInfo::freeSpaceInfo( path ).size();
+
+        if( total <= 0 ) // protect against div by zero
+            continue; //How did this happen?
+
+        float percentage_used = used / total;
+        if( percentage_used < 0.95 )
+            path_exists_with_space = true;
+
+        QFileInfo info( path );
+        if( info.isWritable() )
+            path_exists_writeable = true;
+    }
+    return path_exists_with_space && path_exists_writeable;
 }
 
 bool
@@ -143,9 +166,52 @@ SqlCollectionLocation::remove( const Meta::TrackPtr &track )
 void
 SqlCollectionLocation::showDestinationDialog( const Meta::TrackList &tracks, bool removeSources )
 {
+    DEBUG_BLOCK
     setGoingToRemoveSources( removeSources );
+
+    int transfersize = 0;
+    foreach( Meta::TrackPtr track, tracks )
+        transfersize += track->filesize();
+
+    QStringList actual_folders = actualLocation(); // the folders in the collection
+    QStringList available_folders; // the folders which have freespace available
+    foreach(QString path, actual_folders)
+    {
+        if( path.isEmpty() )
+            continue;
+        debug() << "Path" << path;
+        float used = KDiskFreeSpaceInfo::freeSpaceInfo( path ).used();
+        float total = KDiskFreeSpaceInfo::freeSpaceInfo( path ).size();
+        float free_space = total - used;
+
+        debug() << "Free space" << free_space;
+        debug() << "transfersize" << transfersize;
+
+        if( total <= 0 ) // protect against div by zero
+            continue; //How did this happen?
+
+        float percentage_used = used / total;
+        debug() << "percentage_used" << percentage_used;
+
+        QFileInfo info( path );
+
+        // since bad things happen when drives become totally full, we define full as 95% capacity used
+        // also we make sure there is at least 5 megabytes free
+        // finally, ensure the path is writeable
+        if( ( free_space - transfersize ) > 1024*1024*5 && ( percentage_used + transfersize ) < 0.95 && info.isWritable())
+            available_folders << path;
+    }
+
+    if( available_folders.size() <= 0 )
+    {
+        debug() << "No space available or not writable";
+        The::statusBar()->longMessage( i18n( "The collection does not have enough free space available or is not writable." ), StatusBar::Error );
+        abort();
+        return;
+    }
+
     OrganizeCollectionDialog *dialog = new OrganizeCollectionDialog( tracks,
-                MountPointManager::instance()->collectionFolders(),
+                available_folders,
                 The::mainWindow(), //parent
                 "", //name is unused
                 true, //modal
@@ -180,7 +246,10 @@ SqlCollectionLocation::slotDialogAccepted()
                                                      files,
                                                      i18n("Move Files") ) == KMessageBox::Continue;
         if( !del )
+        {
             abort();
+            return;
+        }
     }
     slotShowDestinationDialogDone();
 }
Comment 18 Casey Link 2010-02-08 00:34:34 UTC
commit 9673171e441d006f7641382d52cbe32c85218576
Author: Casey Link <unnamedrambler@gmail.com>
Date:   Fri Jan 8 16:53:23 2010 -0700

    Ensure that there exists a collection path in the local collection that
    has enough free space to copy the intended tracks to and still have at least 95%
    of the drive free, with a minimum of 5 megs, and, of course, be writable.
    All collection folders that do not satisfy these conditions are filtered out of the
    collection folder drop down in the organize dialog, so only folders that have enough space
    can be chosen.
    
    If there is not enough free space the organize dialog is not even shown, the
    entire process is aborted with a statusbar()->longmessage explaining the issue.
    
    Also, isWriteable() has been modified to take into account the above conditions.
    i.e., if >= 95% of the each path is full the collection will return that it is
    not writeable.
    
    BUG: 126283

diff --git a/src/collection/sqlcollection/SqlCollectionLocation.cpp b/src/collection/sqlcollection/SqlCollectionLocation.cpp
index bbf4c3e..7186963 100644
--- a/src/collection/sqlcollection/SqlCollectionLocation.cpp
+++ b/src/collection/sqlcollection/SqlCollectionLocation.cpp
@@ -34,6 +34,7 @@
 #include <QFile>
 #include <QFileInfo>
 
+#include <kdiskfreespaceinfo.h>
 #include <kjob.h>
 #include <KLocale>
 #include <KSharedPtr>
@@ -69,10 +70,32 @@ SqlCollectionLocation::actualLocation() const
 {
     return MountPointManager::instance()->collectionFolders();
 }
+
 bool
 SqlCollectionLocation::isWritable() const
 {
-    return true;
+    // The collection is writeable if there exists a path that has less than
+    // 95% free space.
+    bool path_exists_with_space = false;
+    bool path_exists_writeable = false;
+    QStringList folders = actualLocation();
+    foreach(QString path, folders)
+    {
+        float used = KDiskFreeSpaceInfo::freeSpaceInfo( path ).used();
+        float total = KDiskFreeSpaceInfo::freeSpaceInfo( path ).size();
+
+        if( total <= 0 ) // protect against div by zero
+            continue; //How did this happen?
+
+        float percentage_used = used / total;
+        if( percentage_used < 0.95 )
+            path_exists_with_space = true;
+
+        QFileInfo info( path );
+        if( info.isWritable() )
+            path_exists_writeable = true;
+    }
+    return path_exists_with_space && path_exists_writeable;
 }
 
 bool
@@ -143,9 +166,52 @@ SqlCollectionLocation::remove( const Meta::TrackPtr &track )
 void
 SqlCollectionLocation::showDestinationDialog( const Meta::TrackList &tracks, bool removeSources )
 {
+    DEBUG_BLOCK
     setGoingToRemoveSources( removeSources );
+
+    int transfersize = 0;
+    foreach( Meta::TrackPtr track, tracks )
+        transfersize += track->filesize();
+
+    QStringList actual_folders = actualLocation(); // the folders in the collection
+    QStringList available_folders; // the folders which have freespace available
+    foreach(QString path, actual_folders)
+    {
+        if( path.isEmpty() )
+            continue;
+        debug() << "Path" << path;
+        float used = KDiskFreeSpaceInfo::freeSpaceInfo( path ).used();
+        float total = KDiskFreeSpaceInfo::freeSpaceInfo( path ).size();
+        float free_space = total - used;
+
+        debug() << "Free space" << free_space;
+        debug() << "transfersize" << transfersize;
+
+        if( total <= 0 ) // protect against div by zero
+            continue; //How did this happen?
+
+        float percentage_used = used / total;
+        debug() << "percentage_used" << percentage_used;
+
+        QFileInfo info( path );
+
+        // since bad things happen when drives become totally full, we define full as 95% capacity used
+        // also we make sure there is at least 5 megabytes free
+        // finally, ensure the path is writeable
+        if( ( free_space - transfersize ) > 1024*1024*5 && ( percentage_used + transfersize ) < 0.95 && info.isWritable())
+            available_folders << path;
+    }
+
+    if( available_folders.size() <= 0 )
+    {
+        debug() << "No space available or not writable";
+        The::statusBar()->longMessage( i18n( "The collection does not have enough free space available or is not writable." ), StatusBar::Error );
+        abort();
+        return;
+    }
+
     OrganizeCollectionDialog *dialog = new OrganizeCollectionDialog( tracks,
-                MountPointManager::instance()->collectionFolders(),
+                available_folders,
                 The::mainWindow(), //parent
                 "", //name is unused
                 true, //modal
@@ -180,7 +246,10 @@ SqlCollectionLocation::slotDialogAccepted()
                                                      files,
                                                      i18n("Move Files") ) == KMessageBox::Continue;
         if( !del )
+        {
             abort();
+            return;
+        }
     }
     slotShowDestinationDialogDone();
 }