/* This file is part of cpp-ethereum. cpp-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. cpp-ethereum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ /** @file FileIo.cpp * @author Arkadiy Paronyan arkadiy@ethdev.com * @date 2015 * Ethereum IDE client. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FileIo.h" using namespace dev; using namespace dev::crypto; using namespace dev::mix; FileIo::FileIo(): m_watcher(new QFileSystemWatcher(this)) { connect(m_watcher, &QFileSystemWatcher::fileChanged, this, &FileIo::fileChanged); } void FileIo::openFileBrowser(QString const& _dir) { QDesktopServices::openUrl(QUrl(_dir)); } QString FileIo::pathFromUrl(QString const& _url) { QUrl url(_url); QString path(url.path()); if (url.scheme() == "qrc") path = ":" + path; #ifdef WIN32 if (url.scheme() == "file") { if (path.startsWith("/")) path = path.right(path.length() - 1); if (!url.host().isEmpty()) path = url.host() + ":/" + path; } #endif return path; } void FileIo::makeDir(QString const& _url) { QDir dirPath(pathFromUrl(_url)); if (!dirPath.exists()) dirPath.mkpath(dirPath.path()); } QString FileIo::readFile(QString const& _url) { QFile file(pathFromUrl(_url)); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream stream(&file); QString data = stream.readAll(); return data; } else error(tr("Error reading file %1").arg(_url)); return QString(); } void FileIo::writeFile(QString const& _url, QString const& _data) { QString path = pathFromUrl(_url); m_watcher->removePath(path); QFile file(path); if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream stream(&file); stream << _data; } else error(tr("Error writing file %1").arg(_url)); file.close(); m_watcher->addPath(path); } void FileIo::copyFile(QString const& _sourceUrl, QString const& _destUrl) { if (QUrl(_sourceUrl).scheme() == "qrc") { writeFile(_destUrl, readFile(_sourceUrl)); return; } if (!QFile::copy(pathFromUrl(_sourceUrl), pathFromUrl(_destUrl))) error(tr("Error copying file %1 to %2").arg(_sourceUrl).arg(_destUrl)); } QString FileIo::getHomePath() const { return QDir::homePath(); } void FileIo::moveFile(QString const& _sourceUrl, QString const& _destUrl) { if (!QFile::rename(pathFromUrl(_sourceUrl), pathFromUrl(_destUrl))) error(tr("Error moving file %1 to %2").arg(_sourceUrl).arg(_destUrl)); } bool FileIo::fileExists(QString const& _url) { QFile file(pathFromUrl(_url)); return file.exists(); } QStringList FileIo::makePackage(QString const& _deploymentFolder) { Json::Value manifest; Json::Value entries(Json::arrayValue); QDir deployDir = QDir(pathFromUrl(_deploymentFolder)); dev::RLPStream rlpStr; int k = 1; std::vector files; QMimeDatabase mimeDb; for (auto item: deployDir.entryInfoList(QDir::Files)) { QFile qFile(item.filePath()); if (qFile.open(QIODevice::ReadOnly)) { k++; QFileInfo fileInfo = QFileInfo(qFile.fileName()); Json::Value jsonValue; std::string path = fileInfo.fileName() == "index.html" ? "/" : fileInfo.fileName().toStdString(); jsonValue["path"] = path; //TODO: Manage relative sub folder jsonValue["file"] = "/" + fileInfo.fileName().toStdString(); jsonValue["contentType"] = mimeDb.mimeTypeForFile(qFile.fileName()).name().toStdString(); QByteArray a = qFile.readAll(); bytes data = bytes(a.begin(), a.end()); files.push_back(data); jsonValue["hash"] = toHex(dev::sha3(data).ref()); entries.append(jsonValue); } qFile.close(); } rlpStr.appendList(k); manifest["entries"] = entries; std::stringstream jsonStr; jsonStr << manifest; QByteArray b = QString::fromStdString(jsonStr.str()).toUtf8(); rlpStr.append(bytesConstRef((const unsigned char*)b.data(), b.size())); for (unsigned int k = 0; k < files.size(); k++) rlpStr.append(files.at(k)); bytes dapp = rlpStr.out(); dev::h256 dappHash = dev::sha3(dapp); //encrypt KeyPair key(dappHash); Secp256k1 enc; enc.encrypt(key.pub(), dapp); QUrl url(_deploymentFolder + "package.dapp"); QFile compressed(url.path()); QByteArray qFileBytes((char*)dapp.data(), static_cast(dapp.size())); if (compressed.open(QIODevice::WriteOnly)) { compressed.write(qFileBytes); compressed.flush(); } else error(tr("Error creating package.dapp")); compressed.close(); QStringList ret; ret.append(QString::fromStdString(toHex(dappHash.ref()))); ret.append(qFileBytes.toBase64()); ret.append(url.toString()); return ret; } void FileIo::watchFileChanged(QString const& _path) { m_watcher->addPath(pathFromUrl(_path)); } void FileIo::stopWatching(QString const& _path) { m_watcher->removePath(pathFromUrl(_path)); }