OwlPath/src/owlpath.vala

196 lines
5.0 KiB
Vala

namespace Owl {
public delegate bool VisitFileLambda (Owl.Path file);
public class Path {
static string ALPHABET_STRING = "abcdefghijklmnopqrstuvwxyz";
GLib.File file;
bool is_tmp;
private static string get_random_string () {
var random_generator = new GLib.Rand ();
string final_string = "valatmp-";
for (uint64 i = 0; i < 12; i++) {
var random_number = random_generator.next_int () % ALPHABET_STRING.length;
final_string += ALPHABET_STRING[random_number].to_string ();
}
return final_string;
}
public static Owl.Path cwd () {
return new Owl.Path (GLib.File.new_for_path ("."));
}
public Path (GLib.File file) {
this.file = file;
}
public Path.from_path (string path) {
this.file = GLib.File.new_for_path (path);
}
public Path.tempdir () throws GLib.Error {
this.is_tmp = true;
var file = GLib.File.new_for_path(GLib.Environment.get_tmp_dir () + Config.WS + get_random_string ());
while (file.query_exists ()) {
file = GLib.File.new_for_path(GLib.Environment.get_tmp_dir () + Config.WS + get_random_string ());
}
file.make_directory ();
this.file = file;
}
~Path () {
if (this.is_tmp) {
try {
this.@delete ();
} catch (GLib.Error error) {
GLib.critical (error.message);
}
}
}
public void spew (string content) throws GLib.Error {
GLib.FileUtils.set_contents (this.get_path (), content);
}
public void copy (Owl.Path destination) throws GLib.Error {
this.file.copy (destination.file, GLib.FileCopyFlags.OVERWRITE);
}
public void copy_contents (Owl.Path destination) throws GLib.Error {
if (!this.is_dir ()) {
GLib.critical ("Destination is not a directory at copy_contents.\n");
return;
}
if (!destination.exists ()) {
destination.mkpath ();
}
this.visit (true, (inner_file) => {
try {
if (!inner_file.is_dir ()) {
var dest_file = destination.child(this.get_relative(inner_file));
dest_file.parent ().mkpath ();
inner_file.copy(dest_file);
}
} catch (GLib.Error error) {
GLib.critical (error.message);
return false;
}
return true;
});
}
public string slurp () throws GLib.Error {
string output;
GLib.FileUtils.get_contents (this.get_path (), out output);
return output;
}
public GLib.FileOutputStream replace () throws GLib.Error {
return this.file.replace (null, false, GLib.FileCreateFlags.PRIVATE);
}
public GLib.FileOutputStream create () throws GLib.Error {
return this.file.create (GLib.FileCreateFlags.PRIVATE);
}
public Owl.Path child (string relative_path) throws GLib.Error {
GLib.File child_file = this.file.resolve_relative_path (relative_path);
return new Owl.Path (child_file);
}
public string? get_relative (Owl.Path descendant) {
return this.file.get_relative_path (descendant.file);
}
public void mkpath () throws GLib.Error {
this.file.make_directory_with_parents ();
}
public bool exists () {
return this.file.query_exists ();
}
public Owl.Path parent () {
return new Owl.Path (this.file.get_parent ());
}
public void @delete () throws GLib.Error {
if (!this.is_dir ()) {
this.file.delete ();
return;
}
foreach (Owl.Path inner_file in this.children ()) {
inner_file.delete ();
}
this.file.delete ();
}
public GLib.File get_file () {
return this.file;
}
public string? get_path () {
return this.file.get_path ();
}
public string basename () {
return this.file.get_basename ();
}
public GLib.List<Owl.Path> children() {
var children = new GLib.List<Owl.Path> ();
if (!this.is_dir ()) {
GLib.critical ("You cannot list children if the target is not a directory.\n");
return children;
}
try {
GLib.FileEnumerator enumerator = this.file.enumerate_children (
"standard::*",
FileQueryInfoFlags.NONE);
GLib.FileInfo info;
while ((info = enumerator.next_file (null)) != null) {
GLib.File inner_file = file.resolve_relative_path (info.get_name ());
children.append (new Owl.Path (inner_file));
}
} catch (GLib.Error error) {
GLib.critical (error.message);
return children;
}
return children;
}
public bool visit (bool recursive, Owl.VisitFileLambda lambda, bool visit_upper_dir = true) {
if (!this.is_dir ()) {
GLib.critical ("Unable to visit non directory\n");
return false;
}
if (visit_upper_dir) {
bool continue_visit = lambda (this);
if (!continue_visit) {
return false;
}
}
foreach (Owl.Path inner_file in this.children ()) {
bool continue_visit = lambda (inner_file);
if (!continue_visit) {
return false;
}
if (recursive && inner_file.is_dir ()) {
continue_visit = inner_file.visit (true, lambda, false);
if (!continue_visit) {
return false;
}
}
}
return true;
}
public bool is_dir () {
return this.query () == GLib.FileType.DIRECTORY;
}
private GLib.FileType query () {
return this.file.query_file_type (GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
}
}
}