package com::oclib::perl::util::FSHash; use com::oclib::perl::lang::Root; our @ISA = "com::oclib::perl::lang::Root"; use strict; use warnings; use utf8; my $string_utf = "Нормализатор utf ©"; use File::Compare; use File::Copy; use File::stat; use FindBin; use com::oclib::perl::util::Date; my $date = new com::oclib::perl::util::Date(); use com::oclib::perl::util::String; my $string = new com::oclib::perl::util::String(); sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = { classCreated => "20051103", classCreator => "http://www.oclib.com/", classEditors => "http://www.oclib.com/,http://www.krassotkin.ru/", classHistory => "20070604, 20070212,20060718,20060617,20050927,20051012,20051103", classIndexLocation => "http://www.oclib.com/library/com/oclib/perl/util/date/", classLocation => "http://www.oclib.com/library/com/oclib/perl/util/Date.pm", className => "FSHash", classNamespace => "com::oclib::perl::util::FSHash", classVersion => "20070604", classVersionIndexLocation => "http://www.oclib.com/library/com/oclib/perl/util/date/20070604/", classVersionLocation => "http://www.oclib.com/library/com/oclib/perl/util/fshash/20070604/FSHash.pm", debugging => 0, tracing => 0, root => "", defaultFileName => "", count => 0, error => 0, recursion => 0, warning => 0, WARNING_NOT_EXIST => 0.1, WARNING_IS_EXIST => 0.2, ERROR_DONT_CREATED => -1, ERROR_CAN_NOT_CREATE_FILE => -2, ERROR_CAN_NOT_CREATE_DIR => -3, ERROR_CAN_NOT_REMOVE => -4, ERROR_NOT_EXIST => -5, ERROR_IS_EXIST => -6, ERROR_FILE_NAME_IS_NOT_DEFINED => -7, @_}; bless($self, $class); return $self; } sub appendData { my $self = shift; return $self->appendDataSimple($self->{root}.$string->trim(shift)); } sub appendDataSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::setDataSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; my $content = shift; if($f =~ m/\/$/ || $f eq "") { if($self->{defaultFileName} ne "") { $f .= $self->{defaultFileName}; } else { $self->{error} = $self->{ERROR_FILE_NAME_IS_NOT_DEFINED}; return $self->{error}; }; }; $f =~ m/(.+)\/.+$/; my $dirToSave = $1; if(!(-e $dirToSave)) { if(!$self->createDirsSimple($dirToSave)) { return $self->{error}; }; }; if(!$self->isExistSimple($f)) { if(!$self->createFileSimple($f)) { return $self->{error}; }; }; open(tmpFile, ">>", $f); print tmpFile $content; close(tmpFile); return 1; } sub copyFromTo { my $self = shift; return $self->copyFromToSimple($self->{root}.$string->trim(shift), $self->{root}.$string->trim(shift)); } sub copyFromToSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::copyFromToSimple\n";}; return copy($string->trim(shift), $string->trim(shift)); } sub createFile { my $self = shift; return createFileSimple($self->{root}.$string->trim(shift)); } sub createFileSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::createFileSimple\n";}; my $f = $string->trim(shift); if($self->{debugging}) {print "FSHash::createFileSimple:(~130):\$f=".$f."\n";}; $f =~ s/\/\//\//g; open(tmpFile, ">", $f); close(tmpFile); if($self->isExistSimple($f) < 0) { if($self->{debugging}) {print "FSHash::createFileSimple:(~137): ERROR_CAN_NOT_CREATE_FILE\n";}; $self->{error} = $self->{ERROR_CAN_NOT_CREATE_FILE}; return $self->{error}; } ; return 1; } # Concluding "/" sub createDirs { my $self = shift; return $self->createDirsSimple($self->{root}.$string->trim(shift)); } # Concluding "/" sub createDirsSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::createDirsSimple\n";}; my $path = $string->trim(shift); if($self->{debugging}) {print "FSHash::createDirsSimple:(~160):\$path=".$path."\n";} $path =~ s/\/\//\//g; my $parent = $self->getParentSimple($path); if($self->{debugging}) {print "FSHash::createDirsSimple:(~162):\$parent=".$parent."\n";}; if(!(-e $parent)) {$self->createDirsSimple($parent);}; if($self->{debugging}) {print "FSHash::createDirsSimple:(~164):\$path=".$path."\n";}; if($self->mkdirSimple($path)) { if($self->{debugging}) {print "FSHash::createDirsSimple:(~166): DIR IS CREATED: ".$path."\n";}; return 1; } else { if($self->{debugging}) {print "FSHash::createDirsSimple:(~167): DIR CAN NOT BE CREATED\n";}; return -1; }; } sub delete { my $self = shift; return $self->remove(shift); } sub deleteSimple { my $self = shift; return $self->removeSimple(shift); } sub getBin { my $self = shift; return $FindBin::Bin || ""; } sub getData { my $self = shift; return $self->getDataSimple($self->{root}.$string->trim(shift)); } sub getDataSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::getDataSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; if($self->isExistSimple($f) < 0) { $self->{error} = $self->{ERROR_NOT_EXIST}; if($self->{debugging}) {print "FSHash::isFileSimple Error: ERROR_NOT_EXIST (".$f.")\n";}; return $self->{error}; } if($f =~ m/\/$/ || $f eq "") { if($self->{defaultFileName} ne "") { $f .= $self->{defaultFileName}; } else { if($self->{debugging}) {print "FSHash::setDataSimple:(~614): ERROR_FILE_NAME_IS_NOT_DEFINED\n";}; $self->{error} = $self->{ERROR_FILE_NAME_IS_NOT_DEFINED}; return $self->{error}; }; }; my $content = ""; open(tmpFile, "<", $f); while() {$content .= $_;}; close(tmpFile); return $content; } sub getHome { #tested my $self = shift; return $ENV{HOME} || $ENV{LOGDIR} || (getpwuid($>))[7] || ""; } sub getParent { my $self = shift; return $self->getParentSimple($self->{root}.$string->trim(shift)); } sub getParentSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::getParentSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; $f =~ m/(.+)\/.+$/; return $1; } # my $inode = FSHash->getStat("/bla/bla/bla"); # $inode->dev - номер устройства в системе # $inode->ino - номер индексного узла # $inode->mode - режим файла (тип и права доступа) # $inode->nlink - количество прямых ссылок на файл # $inode->uid - числовой идентификатор пользователя файла # $inode->gid - числовой идентификатор группы владельца файла # $inode->rdev - идентификатор устройства (только для специальных файлов) # $inode->size - общий размер файла в байтах # $inode->atime - время последнего обращения (в секундах с начала эпохи) # $inode->mtime - время последней последней модификации (в секундах с начала эпохи) # $inode->ctime - время изменения индексного узла (в секундах с начала эпохи) # $inode->blksize - предпочтительный размер блока для операций ввода/вывода в файловой системе # $inode->block - фактическое количество выделенных блоков sub getStat { my $self = shift; return $self->getStatSimple($self->{root}.$string->trim(shift)); } sub getStatSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::getStatSimple\n";}; return stat($string->trim(shift)); } sub getATimeNormalized { my $self = shift; return $self->getATimeNormalizedSimple($self->{root}.$string->trim(shift)); } sub getATimeNormalizedSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::getATimeNormalizedSimple\n";}; my $f = $string->trim(shift); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$f=".$f."\n";}; $f =~ s/\/\//\//g; if($self->isExistSimple($f) < 0) { $self->{error} = $self->{ERROR_NOT_EXIST}; if($self->{debugging}) {print "FSHash::isFileSimple Error: ERROR_NOT_EXIST (".$f.")\n";}; return $self->{error}; } my $inode = stat($f); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$inode=".$inode."\n";}; my $atime = $inode->atime; if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$atime=".$atime."\n";}; my $natime = Date->normalize($atime); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$natime=".$natime."\n";}; return $natime; } sub getCTimeNormalized { my $self = shift; return $self->getCTimeNormalizedSimple($self->{root}.$string->trim(shift)); } sub getCTimeNormalizedSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::getATimeNormalizedSimple\n";}; my $f = $string->trim(shift); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$f=".$f."\n";}; $f =~ s/\/\//\//g; if($self->isExistSimple($f) < 0) { $self->{error} = $self->{ERROR_NOT_EXIST}; if($self->{debugging}) {print "FSHash::isFileSimple Error: ERROR_NOT_EXIST (".$f.")\n";}; return $self->{error}; } my $inode = stat($f); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$inode=".$inode."\n";}; my $ctime = $inode->ctime; if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$atime=".$ctime."\n";}; my $nctime = Date->normalize($ctime); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$natime=".$nctime."\n";}; return $nctime; } sub getMTimeNormalized { my $self = shift; return $self->getMTimeNormalizedSimple($self->{root}.$string->trim(shift)); } sub getMTimeNormalizedSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::getATimeNormalizedSimple\n";}; my $f = $string->trim(shift); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$f=".$f."\n";}; $f =~ s/\/\//\//g; if($self->isExistSimple($f) < 0) { $self->{error} = $self->{ERROR_NOT_EXIST}; if($self->{debugging}) {print "FSHash::isFileSimple Error: ERROR_NOT_EXIST (".$f.")\n";}; return $self->{error}; } my $inode = stat($f); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$inode=".$inode."\n";}; my $mtime = $inode->mtime; if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$atime=".$mtime."\n";}; my $nmtime = Date->normalize($mtime); if($self->{debugging}) {print "FSHash::getATimeNormalizedSimple::(~276) \$natime=".$nmtime."\n";}; return $nmtime; } sub isDir { #tested my $self = shift; return $self->isDirSimple($self->{root}.$string->trim(shift)); } sub isDirSimple { #tested my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::isDirSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; if(!$self->isExistSimple($f)) { $self->{error} = $self->{ERROR_NOT_EXIST}; return $self->{error}; } if(-d $f) { return 1; } else { return -1; }; } sub isEqual { my $self = shift; return $self->isEqualSimple($self->{root}.$string->trim(shift), $self->{root}.$string->trim(shift)); } sub isEqualSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::isEqual\n";}; my $f1 = $string->trim(shift); my $f2 = $string->trim(shift); if(compare($f1, $f2) == 0) { # 0, if equal return 1; } else { return -1; }; } sub isExist {#tested my $self = shift; return $self->isExistSimple($self->{root}.$string->trim(shift)); } sub isExistSimple {#tested my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::isExistSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; if(-e $f) { return 1; } else { return -1; }; } sub isFile { my $self = shift; return $self->isFileSimple($self->{root}.$string->trim(shift)); } sub isFileSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::isFileSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; if($self->isExistSimple($f) < 0) { $self->{error} = $self->{ERROR_NOT_EXIST}; if($self->{debugging}) {print "FSHash::isFileSimple Error: ERROR_NOT_EXIST (".$f.")\n";}; return $self->{error}; } if($self->{debugging}) { my $result = -f $f; if($self->{debugging}) {print "FSHash::isFileSimple -f \$f: ".$result."\n";}; }; if(-f $f) { return 1; } else { return -1; }; } sub isLink { my $self = shift; return $self->isLinkSimple($self->{root}.$string->trim(shift)); } sub isLinkSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::isLinkSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; if(-l $f) { return 1; } else { return -1; }; } sub moveFromTo { my $self = shift; return $self->moveFromToSimple($self->{root}.$string->trim(shift), $self->{root}.$string->trim(shift)); } sub moveFromToSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::moveFromToSimple\n";}; my $from = $string->trim(shift); $from =~ s/\/\//\//g; my $to = $string->trim(shift); $to =~ s/\/\//\//g; if(move($from, $to)) { return 1; } else { return -1; }; } sub mkdir {#tested my $self = shift; return $self->mkdirSimple($self->{root}.$string->trim(shift)); } sub mkdirSimple {#tested my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::mkdirSimple\n";}; my $d = $string->trim(shift); if($self->{debugging}) {print "FSHash::mkdirSimple:(~265):\$d=".$d."\n";}; $d =~ s/\/\//\//g; if($self->isExistSimple($d) > 0) { $self->{warning} = $self->{WARNING_IS_EXIST}; return $self->{warning}; } else { CORE::mkdir($d); if($self->isExistSimple($d) > 0) { return 1; } else { $self->{error} = $self->{ERROR_CAN_NOT_CREATE_DIR}; return $self->{error}; }; }; return 1; } sub remove { my $self = shift; return $self->removeSimple($self->{root}.$string->trim(shift)); } sub removeSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::removeSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; if($self->isExistSimple($f) < 0) { $self->{warning} = $self->{WARNING_NOT_EXIST}; return $self->{warning}; } if($self->isFileSimple($f) > 0) { if($self->{debugging}) {print "FSHash::removeSimple:isFile: ".$f."\n";}; unlink($f); } else { if($self->{debugging}) {print "FSHash::removeSimple:isDir: ".$f."\n";}; rmdir($f); }; if($self->isExistSimple($f) > 0) { $self->{error} = $self->{ERROR_CAN_NOT_REMOVE}; if($self->{debugging}) {print "FSHash::isFileSimple Error: ERROR_CAN_NOT_REMOVE (".$f.")\n";}; return $self->{error}; } else { return 1; }; return 1; } sub removeData { my $self = shift; return $self->removeDataSimple($self->{root}.$string->trim(shift)); } sub removeDataSimple { my $self = shift; return $self->setDataSimple($string->trim(shift), ""); } sub removeUp { my $self = shift; return $self->removeUpSimple($self->{root}.$string->trim(shift)); } sub removeUpSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::removeUpSimple\n";}; my $f = $string->trim(shift); $f =~ s/\/\//\//g; my $recursion = shift || 0; if($self->{debugging}) {print "FSHash::removeUpSimple::(~490) \$recursion=".$recursion."; \$f=".$f.";\n";}; if($self->removeSimple($f) < 0) { if($recursion == 0) { if($self->{debugging}) {print "FSHash::removeUpSimple::(~490) ERROR_CAN_NOT_REMOVE (".$f.")\n";}; $self->{error} = $self->{ERROR_CAN_NOT_REMOVE}; return $self->{error}; } else { $self->{error} = 0; return $self->{count}; }; }; $self->{count} = $self->{count} + 1; return $self->removeUpSimple($self->getParentSimple($f), ++$recursion); } sub renameFromTo { my $self = shift; return $self->renameFromToSimple($self->{root}.$string->trim(shift), $self->{root}.$string->trim(shift)); } sub renameFromToSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::renameFromToSimple\n";}; my $oldName = $self->{root}.$string->trim(shift); $oldName =~ s/\/\//\//g; my $newName = $self->{root}.$string->trim(shift); $newName =~ s/\/\//\//g; return rename($oldName, $newName); } sub setData { my $self = shift; return $self->setDataSimple($self->{root}.$string->trim(shift), shift); } sub setDataSimple { my $self = shift; $self->{error} = 0; $self->{warning} = 0; if($self->{tracing}) {print "FSHash::setDataSimple\n";}; my $f = $string->trim(shift); if($self->{debugging}) {print "FSHash::setDataSimple:(~604):\$f=".$f."\n";}; $f =~ s/\/\//\//g; my $content = shift; if($self->{debugging}) {print "FSHash::setDataSimple:(~607):\$content=".$content."\n";}; if($f =~ m/\/$/ || $f eq "") { if($self->{defaultFileName} ne "") { $f .= $self->{defaultFileName}; } else { if($self->{debugging}) {print "FSHash::setDataSimple:(~614): ERROR_FILE_NAME_IS_NOT_DEFINED\n";}; $self->{error} = $self->{ERROR_FILE_NAME_IS_NOT_DEFINED}; return $self->{error}; }; }; my $dirToSave = $self->getParentSimple($f); if($self->{debugging}) {print "FSHash::setDataSimple:(~621):\$dirToSave=".$dirToSave."\n";}; if($self->isExistSimple($dirToSave) < 0) { if($self->createDirsSimple($dirToSave) < 0) { if($self->{debugging}) {print "FSHash::setDataSimple:(~625): DIR CAN NOT BE CREATED\n";}; return $self->{error}; }; }; if($self->isExistSimple($f) < 0) { if($self->createFileSimple($f) < 0) { if($self->{debugging}) {print "FSHash::setDataSimple:(~607): FILE CAN NOT BE CREATED\n";}; return $self->{error}; }; }; open(tmpFile, ">", $f); print tmpFile $content; close(tmpFile); return 1; } 1;