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 12f7cad06c5a7a13acd2335df7c91f874a404177
parent b45bcec75d5f2339258680345765978ae7613325
Author: deurzen <m.vandeurzen@student.ru.nl>
Date:   Thu,  4 Apr 2019 10:15:46 +0200

refactors code, adds proper make procedure

Diffstat:
MMakefile | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abin/bulkrename | 0
Ddatastructures/Datastructures.h | 13-------------
Ddatastructures/Node.h | 61-------------------------------------------------------------
Dhandlers/FileHandler.cpp | 32--------------------------------
Dhandlers/FileHandler.h | 34----------------------------------
Dhandlers/StateHandler.cpp | 30------------------------------
Dhandlers/StateHandler.h | 24------------------------
Dmain.cpp | 29-----------------------------
Aobj/filehandler.d | 1+
Aobj/filehandler.o | 0
Aobj/main.d | 2++
Aobj/main.o | 0
Aobj/statehandler.d | 1+
Aobj/statehandler.o | 0
Asrc/filehandler.cc | 40++++++++++++++++++++++++++++++++++++++++
Asrc/filehandler.hh | 34++++++++++++++++++++++++++++++++++
Asrc/main.cc | 30++++++++++++++++++++++++++++++
Asrc/node.hh | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/statehandler.cc | 32++++++++++++++++++++++++++++++++
Asrc/statehandler.hh | 25+++++++++++++++++++++++++
21 files changed, 289 insertions(+), 223 deletions(-)

diff --git a/Makefile b/Makefile @@ -0,0 +1,55 @@ +PROJECT = bulkrename + +CC = g++ +CXXFLAGS ?= -std=c++17 +CXXFLAGS += -lboost_system -lboost_filesystem + +OBJDIR = obj +SRCDIR = src + +DEPS = $(OBJ_FILES:%.o=%.d) + +TARGET = bin/$(PROJECT) + +H_FILES := $(shell find $(SRCDIR) -name '*.hh') +SRC_FILES := $(shell find $(SRCDIR) -name '*.cc') +OBJ_FILES := $(patsubst src/%.cc,obj/%.o,${SRC_FILES}) + +all: build + +install: + install $(RELEASE) /usr/$(BIN) + +bin: + @[ -d bin ] || mkdir bin + +obj: + @[ -d obj ] || mkdir obj + +notify-build: + @echo building + +notify-link: + @echo + @echo linking + +build: notify-build bin obj ${OBJ_FILES} notify-link + ${CC} ${CXXFLAGS} ${OBJ_FILES} -o ${TARGET} + +-include $(DEPS) + +obj/%.o: obj + +obj/%.o: src/%.cc + ${CC} ${CXXFLAGS} -MMD -c $< -o $@ + +.PHONY: tags +tags: + @echo + @echo generating tags + @ctags -R --exclude=.git --c++-kinds=+p --fields=+iaS --extras=+q . + +.PHONY: clean +clean: + @echo cleaning + @rm -rf ./bin ./obj diff --git a/bin/bulkrename b/bin/bulkrename Binary files differ. diff --git a/datastructures/Datastructures.h b/datastructures/Datastructures.h @@ -1,13 +0,0 @@ -#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 @@ -1,61 +0,0 @@ -#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 @@ -1,32 +0,0 @@ -// -// 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 @@ -1,34 +0,0 @@ -#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 @@ -1,30 +0,0 @@ -// -// 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 @@ -1,24 +0,0 @@ -#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 @@ -1,28 +0,0 @@ -#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 diff --git a/obj/filehandler.d b/obj/filehandler.d @@ -0,0 +1 @@ +obj/filehandler.o: src/filehandler.cc src/filehandler.hh src/node.hh diff --git a/obj/filehandler.o b/obj/filehandler.o Binary files differ. diff --git a/obj/main.d b/obj/main.d @@ -0,0 +1,2 @@ +obj/main.o: src/main.cc src/statehandler.hh src/node.hh \ + src/filehandler.hh diff --git a/obj/main.o b/obj/main.o Binary files differ. diff --git a/obj/statehandler.d b/obj/statehandler.d @@ -0,0 +1 @@ +obj/statehandler.o: src/statehandler.cc src/statehandler.hh src/node.hh diff --git a/obj/statehandler.o b/obj/statehandler.o Binary files differ. diff --git a/src/filehandler.cc b/src/filehandler.cc @@ -0,0 +1,40 @@ +#include "filehandler.hh" + +#include <cstdlib> +#include <cstring> + + +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/src/filehandler.hh b/src/filehandler.hh @@ -0,0 +1,34 @@ +#ifndef __BULKRENAME_FILEHANDLER_GUARD__ +#define __BULKRENAME_FILEHANDLER_GUARD__ + +#include "node.hh" + +#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_GUARD__ diff --git a/src/main.cc b/src/main.cc @@ -0,0 +1,30 @@ +#include "statehandler.hh" +#include "filehandler.hh" + +#include <string> +#include <boost/filesystem.hpp> + + +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; +} diff --git a/src/node.hh b/src/node.hh @@ -0,0 +1,69 @@ +#ifndef __BULKRENAME_NODE_GUARD__ +#define __BULKRENAME_NODE_GUARD__ + +#include <string> +#include <utility> +#include <boost/filesystem/operations.hpp> +#include <iostream> + +enum class nodetype_t +{ + file, + dir +}; + +class File; +class Directory; + +class Node { +public: + nodetype_t 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(nodetype_t type, ::std::string s): t(type), n(::std::move(s)) {} + + nodetype_t t{}; + ::std::string n{}; + +}; + +class File: public Node { +public: + explicit File(const ::std::string& s): Node(nodetype_t::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(const ::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(nodetype_t::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_GUARD__ diff --git a/src/statehandler.cc b/src/statehandler.cc @@ -0,0 +1,32 @@ +#include "statehandler.hh" +#include "node.hh" + +#include <iostream> + + +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/src/statehandler.hh b/src/statehandler.hh @@ -0,0 +1,25 @@ +#ifndef __BULKRENAME_STATEHANDLER_GUARD__ +#define __BULKRENAME_STATEHANDLER_GUARD__ + +#include <boost/filesystem/operations.hpp> +#include "node.hh" + +#include <vector> +#include <string> + +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_GUARD__