FileLocationCheckTask checks all file locations on the current host, removing all locations where the file does not exist on path.
#include "mylistfiltermodel.h"
#include "unknownfilelookuptask.h"
#include "addrelatedepisodestask.h"
+#include "filelocationchecktask.h"
#include "reportengine.h"
#ifndef LOCALMYLIST_NO_ANIDBUDPCLIENT
# include "renamesettingsdialog.h"
LocalMyList::instance()->database()->clearFailedPendingMyListUpdateRequests();
}
+void MainWindow::on_actionCheckFileLocations_triggered()
+{
+ MyList::instance()->executeTask(new FileLocationCheckTask());
+}
+
void MainWindow::on_actionRemoveKnownUnknownFiles_triggered()
{
LocalMyList::instance()->executeTask(new UnknownFileLookupTask());
void on_actionClearAnimeTitleData_triggered();
void on_actionClearFailedRequests_triggered();
+ void on_actionCheckFileLocations_triggered();
+
void on_actionRemoveKnownUnknownFiles_triggered();
void on_actionRenameScript_triggered();
<addaction name="actionImportMyList"/>
<addaction name="actionImportTitlesFromWeb"/>
<addaction name="actionImportTitles"/>
+ <addaction name="actionAddRelatedEpisodeInfo"/>
<addaction name="separator"/>
<addaction name="actionHandleRequests"/>
<addaction name="actionRenameFiles"/>
<addaction name="actionClearStartedPendingRequests"/>
<addaction name="actionClearStartedMyListUpdates"/>
<addaction name="actionClearFileRenames"/>
- <addaction name="actionAddRelatedEpisodeInfo"/>
+ <addaction name="actionCheckFileLocations"/>
<addaction name="separator"/>
<addaction name="actionClearDatabase"/>
<addaction name="actionClearMyListData"/>
<string>About LocalMyList...</string>
</property>
</action>
+ <action name="actionCheckFileLocations">
+ <property name="text">
+ <string>Check File Locations</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
return exec(q);
}
+QList<FileLocation> Database::getFileLocationBatch(int startLocationId, int limit)
+{
+ // TODO this is a seq scan
+ QSqlQuery q = prepareOneShot(QString(
+ "SELECT %1 "
+ " FROM file_location fl "
+ " WHERE location_id >= :startLocationId "
+ " AND host_id = :hostId "
+ " LIMIT :limit "
+ ).arg(fileLocationFields()));
+
+ q.bindValue(":startLocationId", startLocationId);
+ q.bindValue(":hostId", MyList::instance()->hostId());
+ q.bindValue(":limit", limit);
+
+ QList<FileLocation> ret;
+
+ if (!exec(q))
+ return ret;
+
+ QSqlResultIterator it(q);
+ while (q.next())
+ {
+ FileLocation fl;
+ readFileLocationData(it, fl);
+ ret << fl;
+ }
+
+ return ret;
+}
+
Anime Database::getAnime(int aid)
{
Anime a;
bool setFileLocation(const LocalMyList::FileLocation &fileLocation);
bool removeFileLocation(int locationId);
+ QList<LocalMyList::FileLocation> getFileLocationBatch(int startLocationId, int limit);
+
LocalMyList::Anime getAnime(int aid);
QList<LocalMyList::Episode> getEpisodes(int aid);
LocalMyList::Episode getEpisode(int eid);
--- /dev/null
+#include "filelocationchecktask.h"
+
+#include "database.h"
+#include <QFileInfo>
+
+#include <QDebug>
+
+namespace LocalMyList {
+
+FileLocationCheckTask::FileLocationCheckTask(QObject *parent) :
+ AbstractTask(parent)
+{
+}
+
+bool FileLocationCheckTask::canUseThreads() const
+{
+ return true;
+}
+
+void FileLocationCheckTask::start()
+{
+ lastLocationId = 1;
+ workUnit();
+}
+
+void FileLocationCheckTask::workUnit()
+{
+ db->transaction();
+ QList<FileLocation> fileLocations = db->getFileLocationBatch(lastLocationId, OPERATIONS_PER_UNIT);
+
+ for (const FileLocation &fl : fileLocations)
+ {
+ if (!QFileInfo(fl.path).exists())
+ {
+ db->log(QObject::tr("Removing file location %1: %2. File does not exist.")
+ .arg(fl.locationId)
+ .arg(fl.path));
+ db->removeFileLocation(fl.locationId);
+ }
+ lastLocationId = fl.locationId;
+ }
+ db->commit();
+
+ ++lastLocationId;
+
+ if (fileLocations.count() == OPERATIONS_PER_UNIT)
+ emit nextWorkUnit();
+ else
+ emit finished();
+}
+
+} // namespace LocalMyList
--- /dev/null
+#ifndef FILELOCATIONCHECKTASK_H
+#define FILELOCATIONCHECKTASK_H
+
+#include "abstracttask.h"
+
+namespace LocalMyList {
+
+class LOCALMYLISTSHARED_EXPORT FileLocationCheckTask : public AbstractTask
+{
+ Q_OBJECT
+public:
+ explicit FileLocationCheckTask(QObject *parent = 0);
+
+ virtual bool canUseThreads() const;
+
+public slots:
+ virtual void start();
+
+private slots:
+ void workUnit();
+
+private:
+ int lastLocationId;
+};
+
+} // namespace LocalMyList
+
+#endif // FILELOCATIONCHECKTASK_H
--- /dev/null
+#include "../../filelocationchecktask.h"
\ No newline at end of file
sqlquery.cpp \
sqlasyncquery.cpp \
sqlasyncqueryinternal.cpp \
- asyncquerytask.cpp
+ asyncquerytask.cpp \
+ filelocationchecktask.cpp
HEADERS += \
localmylist_global.h \
sqlasyncquery.h \
sqlasyncqueryinternal.h \
asyncquerytask.h \
- sqlresultiteratorinterface.h
+ sqlresultiteratorinterface.h \
+ filelocationchecktask.h
CONV_HEADERS += \
include/LocalMyList/AbstractTask \
include/LocalMyList/MyListModel \
include/LocalMyList/MyListNode \
include/LocalMyList/Settings \
- include/LocalMyList/UnknownFileLookupTask
+ include/LocalMyList/UnknownFileLookupTask \
+ include/LocalMyList/FileLocationCheckTask
!noscript {
QT *= script