bulkrename

Bulk file/directory renaming utility, similar to rangers built-in bulkrename command
git clone git://git.deurzen.net/bulkrename
Log | Files | Refs | LICENSE

commit b45bcec75d5f2339258680345765978ae7613325
Author: deurzen <max@deurzen.net>
Date:   Wed,  6 Sep 2017 12:06:12 +0200

initial commit

Diffstat:
AMakefile | 0
AREADME.md | 1+
Adatastructures/Datastructures.h | 13+++++++++++++
Adatastructures/Node.h | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ahandlers/FileHandler.cpp | 32++++++++++++++++++++++++++++++++
Ahandlers/FileHandler.h | 34++++++++++++++++++++++++++++++++++
Ahandlers/StateHandler.cpp | 30++++++++++++++++++++++++++++++
Ahandlers/StateHandler.h | 24++++++++++++++++++++++++
Amain.cpp | 29+++++++++++++++++++++++++++++
9 files changed, 224 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile diff --git a/README.md b/README.md @@ -0,0 +1 @@ +# bulkrename diff --git a/datastructures/Datastructures.h b/datastructures/Datastructures.h @@ -0,0 +1,13 @@ +#ifndef BULKRENAME_DATASTRUCTURES_H +#define BULKRENAME_DATASTRUCTURES_H + +namespace ds +{ + enum class Type + { + FILE, + DIR + }; +} + +#endif //BULKRENAME_DATASTRUCTURES_H diff --git a/datastructures/Node.h b/datastructures/Node.h @@ -0,0 +1,61 @@ +#ifndef BULKRENAME_NODE_H +#define BULKRENAME_NODE_H + +#include "Datastructures.h" +#include <string> +#include <utility> +#include <boost/filesystem/operations.hpp> +#include <iostream> + +class File; +class Directory; + +class Node { +public: + ds::Type type() const { return t; } + std::string name() const { return n; } + + virtual const Node* fwd() const = 0; + virtual File* getfile() = 0; + virtual void setnewname(const std::string& s) = 0; + +protected: + explicit Node(ds::Type type, std::string s): t(type), n(std::move(s)) {} + + ds::Type t{}; + std::string n{}; + +}; + +class File: public Node { +public: + explicit File(const std::string& s): Node(ds::Type::FILE, s), nn(Node::name()) {} + + const Node* fwd() const override { return nullptr; }; + File* getfile() override { return this; } + + void setnewname(const std::string& s) override { nn = s; } + std::string getnewname() { return nn; } + bool valid() { return nn != name(); } + void move(std::string prefix) const { + boost::filesystem::rename(prefix + name(), prefix + nn); + } + +private: + std::string nn{}; +}; + +class Directory: public Node { +public: + explicit Directory(const std::string& s, Node& n): Node(ds::Type::DIR, s), next(&n) {} + + const Node* fwd() const override { return next; } + File* getfile() override { return next->getfile(); } + + void setnewname(const std::string& s) override { } + +private: + Node* next; +}; + +#endif //BULKRENAME_NODE_H diff --git a/handlers/FileHandler.cpp b/handlers/FileHandler.cpp @@ -0,0 +1,32 @@ +// +// Created by deurzen on 9/1/17. +// + +#include <cstdlib> +#include <cstring> +#include "FileHandler.h" + +void FileHandler::write_out(const std::vector<Node*> &nodes) { + for (Node* n : nodes) { + out << n->getfile()->name() << std::endl; + } + out.close(); +} + +void FileHandler::read_in(const std::vector<Node*> &nodes) { + in.open(tmpfile.c_str()); + for (Node* n : nodes) { + std::string name; + std::getline(in, name); + if(!in) throw std::runtime_error("amount of new files does not match amount of old files"); + n->getfile()->setnewname(name); + } + in.close(); +} + +void FileHandler::rename(const std::vector<Node*> &nodes) const { + for (Node* n : nodes) { + File* file = n->getfile(); + if (file->valid()) file->move(n->name()); + } +} diff --git a/handlers/FileHandler.h b/handlers/FileHandler.h @@ -0,0 +1,34 @@ +#ifndef BULKRENAME_FILEHANDLER_H +#define BULKRENAME_FILEHANDLER_H + +#include "../datastructures/Datastructures.h" +#include "../datastructures/Node.h" +#include <fstream> +#include <iostream> +#include <string> +#include <vector> +#include <cstdio> + +class FileHandler { +public: + FileHandler() { + char *tmpname = strdup("/tmp/tmpfileXXXXXXXXXX"); + mkstemp(tmpname); + out = std::ofstream(tmpname); + tmpfile = tmpname; + } + + ~FileHandler() { remove(tmpfile.c_str()); }; + + void write_out(const std::vector<Node*>& nodes); + void edit() const { system((std::string("vim ")+tmpfile).c_str()); } + void read_in(const std::vector<Node*>& nodes); + void rename(const std::vector<Node*>& nodes) const; + +private: + std::string tmpfile; + std::ifstream in; + std::ofstream out; +}; + +#endif //BULKRENAME_FILEHANDLER_H diff --git a/handlers/StateHandler.cpp b/handlers/StateHandler.cpp @@ -0,0 +1,30 @@ +// +// Created by deurzen on 9/1/17. +// + +#include <iostream> +#include "StateHandler.h" +#include "../datastructures/Node.h" + +void StateHandler::populate(boost::filesystem::recursive_directory_iterator dir) +{ + boost::filesystem::recursive_directory_iterator end; + for (; dir != end; ++dir) + if (is_regular_file(dir->path())) + nodes.push_back(convert(dir->path())); +} + +Node* StateHandler::convert(boost::filesystem::path path) +{ + std::string dir, file; + dir = path.parent_path().string() + "/"; + file = path.filename().string(); + + File* f = new File(file); + return new Directory(dir, *f); +} + +void StateHandler::print() { + for (Node* f : nodes) + std::cout << f->name() << f->fwd()->name() << std::endl; +} diff --git a/handlers/StateHandler.h b/handlers/StateHandler.h @@ -0,0 +1,24 @@ +#ifndef BULKRENAME_STATEHANDLER_H +#define BULKRENAME_STATEHANDLER_H + +#include <vector> +#include <string> +#include <boost/filesystem/operations.hpp> +#include "../datastructures/Node.h" + +class StateHandler { +public: + StateHandler() = default; + ~StateHandler() = default; + + void populate(boost::filesystem::recursive_directory_iterator dir); + Node* convert(boost::filesystem::path path); + + void print(); + const std::vector<Node*> getnodes() const { return nodes; } + +private: + std::vector<Node*> nodes; +}; + +#endif //BULKRENAME_STATEHANDLER_H diff --git a/main.cpp b/main.cpp @@ -0,0 +1,28 @@ +#include <string> +#include "handlers/StateHandler.h" +#include "handlers/FileHandler.h" +#include <boost/filesystem.hpp> +using namespace std; + +int main(int argc, char **argv) { + using boost::filesystem::recursive_directory_iterator; + + StateHandler sh; + recursive_directory_iterator dir( (argc > 1) ? argv[1] : "." ); + sh.populate(dir); + + FileHandler fh; + fh.write_out(sh.getnodes()); + fh.edit(); + + try { + fh.read_in(sh.getnodes()); + } catch(const std::runtime_error& e) { + std::cerr << "bulkrename: " << e.what() << std::endl; + } + + fh.rename(sh.getnodes()); + + + return 0; +} +\ No newline at end of file