| Draft documentation | Contained in the Draft distribution. |
File::Atomism::utils - Misc file handling stuff
Utilities for manipulating and creating filenames.
A collection of standard perl functions and utilities for messing with filenames. These are generally useful for manipulating files in an 'atomised' directory, see File::Atomism.
Access some values useful for constructing temporary filenames:
my $hostname = Hostname(); my $pid = Pid(); my $unixdate = Unixdate();
Retrieve the inode of a file like so:
my $inode = Inode ('/path/to/my-house.jpg');
Access the directory and filename given a path:
Dir ('/path/to/my-house.jpg');
File ('/path/to/my-house.jpg');
.returns '/path/to/' and 'my-house.jpg' respectively.
Retrieve the file extension (.doc, .txt, .jpg) of a file like so:
my $extension = Extension ('my-house.jpg');
Ask for a temporary filename like so:
my $tempname = TempFilename ('/path/to/');
or
my $tempname = TempFilename ('/path/to/myfile.yml');
A unique filepath based on the directory, hostname, current PID and extension (if supplied, otherwise .tmp will be appended) will be returned:
/path/to/.foo.example.com-666.tmp
/path/to/.foo.example.com-666.yml
Ask for a permanent filename like so:
my $filename = PermFilename ('/path/to/.foo.example.com-666.yml');
A unique filepath based on the hostname, current PID, inode of the temporary file, date and file extension will be supplied:
/path/to/foo.example.com-666-1234-1095026759.yml
Alternatively you can specify the final extension as a second parameter:
my $filename = PermFilename ('/path/to/.foo.example.com-666.tmp', 'yml');
Write to the undo buffer like so:
Journal ([['persistent-file1.yml', '.temp-file1.yml'], [ ... ] ]);
Undo the most recent change to the journal by supplying a directory path to the Undo() method:
Undo ('/path/to');
Undo the most recent undo() with the Redo() method. Usage is the same as for Undo():
Redo ('/path/to');
| Draft documentation | Contained in the Draft distribution. |
package File::Atomism::utils;
use strict; use warnings; use File::stat; use File::Spec; use Exporter; use File::Path qw /mkpath/; use Sys::Hostname qw /hostname/; use Time::HiRes qw /gettimeofday/; use Cwd qw /abs_path/; our $CONFDIR = $ENV{ATOMISM_CONF} || $ENV{HOME} ."/.atomism"; use vars qw /@ISA @EXPORT_OK/; @ISA = qw /Exporter/; @EXPORT_OK = qw /Hostname Pid Inode Unixdate Dir File Extension TempFilename PermFilename Journal Undo Redo/;
sub Hostname { eval {hostname} || 'localhost.localdomain'; } sub Pid { $$; } sub Unixdate { time; }
sub Inode { my $filename = shift; my $stat = stat ($filename) || return 0; $stat->ino; }
sub Dir { my $path = shift; my ($volume, $dir, $file) = File::Spec->splitpath ($path); return $dir; } sub File { my $path = shift; my ($volume, $dir, $file) = File::Spec->splitpath ($path); return $file; }
sub Extension { my $filename = shift; return 0 unless ($filename =~ /[^.]\.[a-z0-9_]+$/); $filename =~ s/.*\.//; $filename =~ s/[^a-z0-9_]//gi; return $filename; }
sub TempFilename { my $path = shift; my $ext = Extension ($path) || 'tmp'; Dir ($path) .".". Hostname ."-". Pid .".". $ext; }
sub PermFilename { my $path = shift; my $ext = shift || Extension ($path); Dir ($path) . Hostname ."-". Pid ."-". Inode ($path) ."-". Unixdate .".". $ext; }
sub Journal { my $list = shift; # figure out where to put the journal from the first pair of files my $dir = Dir (abs_path ($list->[0]->[0])) || Dir (abs_path ($list->[0]->[1])); my $undodir = $CONFDIR ."/UNDO". $dir; my $redodir = $CONFDIR ."/REDO". $dir; mkpath ([$undodir, $redodir]); my $journal = $undodir . join (".", gettimeofday) .".patch"; for my $item (@{$list}) { my $old = abs_path ($item->[0]) || '/dev/null'; my $new = abs_path ($item->[1]) || '/dev/null'; `diff -u $old $new >> $journal;`; } system 'sync'; }
sub Undo { my $dir = abs_path (shift); my $undodir = $CONFDIR ."/UNDO". $dir; my $redodir = $CONFDIR ."/REDO". $dir; opendir (DIR, $undodir) or warn "$!"; my @files = sort (readdir (DIR)); @files = grep !/^\./, @files; my $file = pop (@files) || return; my $undo = $undodir ."/". $file; my $redo = $redodir ."/". $file; `cd $dir; patch -p0 --batch --no-backup < $undo; cd -`; rename $undo, $redo; system 'sync'; closedir (DIR); }
sub Redo { my $dir = abs_path (shift); my $undodir = $CONFDIR ."/UNDO". $dir; my $redodir = $CONFDIR ."/REDO". $dir; opendir (DIR, $redodir) or warn "$!"; my @files = sort (readdir (DIR)); @files = grep !/^\./, @files; my $file = shift (@files) || return; my $undo = $undodir ."/". $file; my $redo = $redodir ."/". $file; `cd $dir; patch -p0 --force --no-backup < $redo; cd -`; rename $redo, $undo; system 'sync'; closedir (DIR); } 1;