File indexing completed on 2024-04-21 05:50:50

0001 /***************************************************************************
0002  *   Copyright (C) 2016 by Arnav Dhamija <arnav.dhamija@gmail.com>         *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA            *
0018  ***************************************************************************/
0019 
0020 #include "stashnotifier.h"
0021 #include "stash_adaptor.h"
0022 
0023 #include <KDirWatch>
0024 #include <KPluginFactory>
0025 
0026 K_PLUGIN_FACTORY_WITH_JSON(StashNotifierFactory, "stashnotifier.json", registerPlugin<StashNotifier>();)
0027 
0028 StashNotifier::StashNotifier(QObject *parent, const QList<QVariant> &var, const QString &daemonService, const QString &daemonPath)
0029     : KDEDModule(parent)
0030     , m_daemonService(daemonService)
0031     , m_daemonPath(daemonPath)
0032 {
0033     dirWatch = new KDirWatch(this);
0034     qDebug() << "Launching stash daemon.";
0035 
0036     new StashNotifierAdaptor(this);
0037     QDBusConnection dbus = QDBusConnection::sessionBus();
0038     dbus.registerObject(m_daemonPath, this);
0039     dbus.registerService(m_daemonService);
0040 
0041     fileSystem = new StashFileSystem(parent);
0042 
0043     connect(dirWatch, &KDirWatch::dirty, this, &StashNotifier::dirty);
0044     connect(dirWatch, &KDirWatch::created, this, &StashNotifier::created);
0045     connect(dirWatch, &KDirWatch::deleted, this, &StashNotifier::removeWatchedPath);
0046     connect(this, &StashNotifier::listChanged, this, &StashNotifier::displayRoot);
0047 }
0048 
0049 StashNotifier::~StashNotifier()
0050 {
0051 }
0052 
0053 QString StashNotifier::encodeString(StashFileSystem::StashNode::iterator node, const QString &path) // format type::stashpath::source
0054 {
0055     QString encodedString;
0056 
0057     switch (node.value().type) {
0058     case StashFileSystem::NodeType::DirectoryNode:
0059         encodedString = "dir";
0060         break;
0061     case StashFileSystem::NodeType::FileNode:
0062         encodedString = "file";
0063         break;
0064     case StashFileSystem::NodeType::SymlinkNode:
0065         encodedString = "symlink";
0066         break;
0067     case StashFileSystem::NodeType::InvalidNode:
0068         encodedString = "invalid";
0069         break;
0070     }
0071 
0072     if (path == "/") {
0073         encodedString += "::" + QStringLiteral("/") + node.key();
0074     } else {
0075         encodedString += "::" + path + QStringLiteral("/") + node.key();
0076     }
0077 
0078     if (node.value().type == StashFileSystem::NodeType::FileNode || node.value().type == StashFileSystem::NodeType::SymlinkNode) {
0079         encodedString += "::" + node.value().source;
0080     } else {
0081         encodedString += "::";
0082     }
0083 
0084     return encodedString;
0085 }
0086 
0087 QString StashNotifier::encodeString(StashFileSystem::StashNodeData nodeData, const QString &path)
0088 {
0089     QString encodedString;
0090 
0091     switch (nodeData.type) {
0092     case StashFileSystem::NodeType::DirectoryNode:
0093         encodedString = "dir";
0094         break;
0095     case StashFileSystem::NodeType::FileNode:
0096         encodedString = "file";
0097         break;
0098     case StashFileSystem::NodeType::SymlinkNode:
0099         encodedString = "symlink";
0100         break;
0101     case StashFileSystem::NodeType::InvalidNode:
0102         encodedString = "invalid";
0103         break;
0104     }
0105 
0106     encodedString += "::" + path;
0107 
0108     if (nodeData.type == StashFileSystem::NodeType::FileNode || nodeData.type == StashFileSystem::NodeType::SymlinkNode) {
0109         encodedString += "::" + nodeData.source;
0110     } else {
0111         encodedString += "::";
0112     }
0113 
0114     return encodedString;
0115 }
0116 
0117 QStringList StashNotifier::fileList(const QString &path) // forwards list over QDBus to the KIO worker
0118 {
0119     QStringList contents;
0120     StashFileSystem::StashNodeData node = fileSystem->findNode(path);
0121     if (node.type != StashFileSystem::NodeType::DirectoryNode) {
0122         contents.append("error::error::InvalidNode");
0123     } else {
0124         for (auto it = node.children->begin(); it != node.children->end(); ++it) {
0125             contents.append(encodeString(it, path));
0126         }
0127     }
0128     return contents;
0129 }
0130 
0131 QString StashNotifier::fileInfo(const QString &path) // forwards data of a single file to the KIO worker
0132 {
0133     QString fileData;
0134     StashFileSystem::StashNodeData node = fileSystem->findNode(path);
0135     fileData = encodeString(node, path);
0136     return fileData;
0137 }
0138 
0139 void StashNotifier::addPath(const QString &source, const QString &stashPath, int fileType)
0140 {
0141     QString processedPath = processString(stashPath);
0142 
0143     if (fileSystem->findNode(stashPath).type == StashFileSystem::NodeType::InvalidNode) {
0144         if (fileType == StashFileSystem::NodeType::DirectoryNode) {
0145             dirWatch->addDir(processedPath);
0146             fileSystem->addFolder(processedPath);
0147         } else if (fileType == StashFileSystem::NodeType::FileNode) {
0148             dirWatch->addFile(source);
0149             fileSystem->addFile(processString(source), stashPath);
0150         } else if (fileType == StashFileSystem::NodeType::SymlinkNode) {
0151             dirWatch->addFile(source);
0152             fileSystem->addSymlink(processString(source), stashPath);
0153         }
0154         emit listChanged();
0155     }
0156 }
0157 
0158 QString StashNotifier::processString(const QString &path)
0159 {
0160     QString processedPath = path.simplified();
0161     if (processedPath.at(processedPath.size() - 1) == '/') {
0162         processedPath.chop(1);
0163     }
0164     return processedPath;
0165 }
0166 
0167 void StashNotifier::removeWatchedPath(const QString &filePath)
0168 {
0169     qDebug() << filePath;
0170     QStringList matchedFiles;
0171     fileSystem->findPathFromSource(filePath, "", matchedFiles, fileSystem->getRoot().children);
0172     foreach (QString file, matchedFiles) {
0173         fileSystem->delEntry(file);
0174     }
0175 }
0176 
0177 void StashNotifier::removePath(const QString &path)
0178 {
0179     QString encodedName = fileInfo(path);
0180     QString filePath = encodedName.split("::", Qt::KeepEmptyParts).at(2);
0181     dirWatch->removeFile(filePath);
0182     fileSystem->delEntry(path);
0183     emit listChanged();
0184 }
0185 
0186 void StashNotifier::nukeStash()
0187 {
0188     qDebug() << "Nuking stash: all files on it will be deleted!";
0189     fileSystem->deleteAllItems();
0190     qDebug() << "Nuked.";
0191 }
0192 
0193 void StashNotifier::pingDaemon()
0194 {
0195     // just to see if this exists in kded5 or whether we need to create a process for it for the test case
0196 }
0197 
0198 bool StashNotifier::copyWithStash(const QString &src, const QString &dest)
0199 {
0200     return fileSystem->copyFile(src, dest);
0201 }
0202 
0203 void StashNotifier::dirty(const QString &path)
0204 {
0205     // nothing to be done here
0206 }
0207 
0208 void StashNotifier::created(const QString &path)
0209 {
0210     // nothing to be done here
0211 }
0212 
0213 #include "stashnotifier.moc"