]> Some of my projects - localmylist-runner.git/commitdiff
Initial LocalMyList-Runner
authorAPTX <marek321@gmail.com>
Sat, 15 Mar 2014 16:34:42 +0000 (17:34 +0100)
committerAPTX <marek321@gmail.com>
Sat, 15 Mar 2014 16:34:42 +0000 (17:34 +0100)
CMakeLists.txt [new file with mode: 0644]
main.cpp [new file with mode: 0644]
plasma-runner-localmylist.desktop [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cf1beec
--- /dev/null
@@ -0,0 +1,23 @@
+project(localmylist-runner)
+cmake_minimum_required(VERSION 2.8)
+
+set(KDE_MIN_VERSION "4.12.0") # for the < 4.2 macro
+find_package(KDE4 4.12.0 REQUIRED)
+include(KDE4Defaults)
+include(MacroLibrary)
+
+add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -std=c++0x)
+
+include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES}
+    /usr/include/LocalMyList)
+
+set(SRCS main.cpp)
+
+# Now make sure all files get to the right place
+kde4_add_plugin(plasma_runner_localmylist ${SRCS})
+target_link_libraries(plasma_runner_localmylist ${KDE4_PLASMA_LIBS} ${KDE4_KIO_LIBS} localmylist)
+
+
+# Install the library and .desktop file
+install(TARGETS plasma_runner_localmylist DESTINATION ${PLUGIN_INSTALL_DIR})
+install(FILES plasma-runner-localmylist.desktop DESTINATION ${SERVICES_INSTALL_DIR})
diff --git a/main.cpp b/main.cpp
new file mode 100644 (file)
index 0000000..6662c27
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,191 @@
+#include <Plasma/AbstractRunner>
+#include <QHash>
+#include <KRun>
+#include <QMutex>
+#include <QThread>
+#include <LocalMyList/MyList>
+#include <LocalMyList/Database>
+
+using namespace LocalMyList;
+
+
+// LML set up can not be in init or prepare. The database can only be used from
+// one thread and all matches can run from different threads.
+class RaiiLml
+{
+public:
+       RaiiLml() : mutex{}, locker{&mutex}
+       {
+               if (MyList::instance()->thread() != QThread::currentThread())
+               {
+                       qWarning("MyList instance created from a different thread");
+                       ok = false;
+                       return;
+               }
+               MyList::instance()->loadLocalSettings();
+               connected_ = MyList::instance()->database()->connect();
+       }
+       ~RaiiLml()
+       {
+               if (!ok) return;
+
+               MyList::instance()->database()->disconnect();
+               MyList::instance()->destroy();
+       }
+
+       operator bool () const { return ok; }
+       bool connected() const { return connected_; }
+
+private:
+       QMutex mutex;
+       QMutexLocker locker;
+       bool ok;
+       bool connected_;
+};
+
+class LocalMyListRunner : public Plasma::AbstractRunner
+{
+       Q_OBJECT
+
+public:
+       LocalMyListRunner(QObject *parent, const QVariantList &args);
+
+       void match(Plasma::RunnerContext &context);
+       void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match);
+       void reloadConfiguration();
+
+protected Q_SLOTS:
+       void init();
+       void prepareForMatchSession();
+       void matchSessionFinished();
+
+private:
+       QString m_path;
+       QString m_triggerWord;
+};
+
+
+
+LocalMyListRunner::LocalMyListRunner(QObject *parent, const QVariantList &args)
+{
+       Q_UNUSED(parent);
+       Q_UNUSED(args);
+       setSpeed(SlowSpeed);
+       setPriority(LowPriority);
+       setHasRunOptions(false);
+}
+
+void LocalMyListRunner::match(Plasma::RunnerContext &context)
+{
+       QString query = context.query();
+
+       if (!query.startsWith(m_triggerWord))
+               return;
+
+       query.remove(0, m_triggerWord.length());
+       QString searchQuery = toSearchQuery(query);
+
+       qDebug("Initialize LML");
+       RaiiLml lml;
+       if (!lml)
+               return;
+
+       if (!lml.connected())
+       {
+               Plasma::QueryMatch match(this);
+               match.setText(i18n("Could not connect to the database"));
+               match.setSubtext(i18n("Make sure you have configured LocalMyList correctly."));
+               match.setType(Plasma::QueryMatch::InformationalMatch);
+               match.setRelevance(0.0);
+               context.addMatch(context.query(), match);
+               return;
+       }
+
+       QList<AnimeTitle> titles = MyList::instance()->database()->myListSearch(searchQuery, 10);
+
+       if (titles.isEmpty())
+               titles = MyList::instance()->database()->myListSearchSimmilar(searchQuery);
+
+       QList<Plasma::QueryMatch> matches;
+
+       QSet<int> fids;
+       for (const AnimeTitle &title : titles)
+       {
+               if (!context.isValid())
+                       break;
+
+               OpenFileData ofd = MyList::instance()->database()->firstUnwatchedByAid(title.aid);
+
+               Plasma::QueryMatch match(this);
+               if (ofd.fid)
+               {
+                       if (fids.contains(ofd.fid))
+                               continue;
+
+                       match.setText(i18n("Play %1 - %2").arg(ofd.animeTitle).arg(ofd.epno));
+                       match.setSubtext(QString("%1")
+                                                        .arg(ofd.episodeTitle));
+
+                       match.setData(ofd.localPath);
+                       match.setType(Plasma::QueryMatch::CompletionMatch);
+
+                       if (title.title.compare(query.trimmed(), Qt::CaseInsensitive))
+                       {
+                               match.setRelevance(1.0);
+                               match.setType(Plasma::QueryMatch::ExactMatch);
+                       }
+                       else
+                       {
+                               match.setRelevance(0.8);
+                       }
+
+                       fids << ofd.fid;
+               }
+               else
+               {
+                       match.setText(i18n("Nothing to watch for %1").arg(title.title));
+                       match.setType(Plasma::QueryMatch::InformationalMatch);
+                       match.setRelevance(0.0);
+               }
+               matches << match;
+       }
+
+       context.addMatches(context.query(), matches);
+}
+
+void LocalMyListRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match)
+{
+       Q_UNUSED(context);
+       KRun *opener = new KRun(match.data().toString(), 0);
+       opener->setRunExecutables(false);
+}
+
+void LocalMyListRunner::reloadConfiguration()
+{
+       m_triggerWord = "lml";
+
+       Plasma::RunnerSyntax syntax(QString("%1:q:").arg(m_triggerWord),
+                                                               i18n("Play the first unwatched episode of :q:"));
+
+       setDefaultSyntax(syntax);
+
+}
+
+void LocalMyListRunner::init()
+{
+       reloadConfiguration();
+       connect(this, SIGNAL(prepare()), this, SLOT(prepareForMatchSession()));
+       connect(this, SIGNAL(teardown()), this, SLOT(matchSessionFinished()));
+}
+
+void LocalMyListRunner::prepareForMatchSession()
+{
+}
+
+void LocalMyListRunner::matchSessionFinished()
+{
+}
+
+K_EXPORT_PLASMA_RUNNER(localmylist, LocalMyListRunner)
+
+#include "main.moc"
diff --git a/plasma-runner-localmylist.desktop b/plasma-runner-localmylist.desktop
new file mode 100644 (file)
index 0000000..f71626b
--- /dev/null
@@ -0,0 +1,18 @@
+[Desktop Entry]
+Name=LocalMyList Files
+Comment=Play first unwatched files from LocalMyList
+Type=Service
+X-KDE-ServiceTypes=Plasma/Runner
+X-KDE-Library=plasma_runner_localmylist
+X-KDE-PluginInfo-Author=APTX
+X-KDE-PluginInfo-Email=
+X-KDE-PluginInfo-Name=localmylist
+X-KDE-PluginInfo-Version=0.1
+X-KDE-PluginInfo-Website=http://aptx.org
+X-KDE-PluginInfo-Category=
+X-KDE-PluginInfo-Depends=
+X-KDE-PluginInfo-License=LGPL
+X-KDE-PluginInfo-EnabledByDefault=true
+
+X-Plasma-SingleRunnerQueryMode=true