implemented snapshot diff; started work on admin settings
This commit is contained in:
parent
4c67bf71c4
commit
8b22d56e32
7 changed files with 423 additions and 8 deletions
208
lib/Manager/DiffManager.php
Normal file
208
lib/Manager/DiffManager.php
Normal file
|
@ -0,0 +1,208 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\GroupfolderFilesystemSnapshots\Manager;
|
||||
|
||||
class DiffManager {
|
||||
|
||||
public function __construct(){
|
||||
}
|
||||
|
||||
private function seperateFilesFromFolders($parentDir, $items) {
|
||||
$files = [];
|
||||
$folders = [];
|
||||
|
||||
foreach($items as $item) {
|
||||
if(is_dir($parentDir . DIRECTORY_SEPARATOR . $item)) {
|
||||
$folders[] = $item;
|
||||
} else {
|
||||
$files[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return array($files, $folders);
|
||||
}
|
||||
|
||||
private function getFilesAndFolders($dir) {
|
||||
$scan = array_diff(scandir($dir), array('..', '.'));
|
||||
|
||||
return $this->seperateFilesFromFolders($dir, $scan);
|
||||
}
|
||||
|
||||
private function getFilesizesOfFiles($prefix, array $files) {
|
||||
$result = array();
|
||||
foreach($files as $index=>$file) {
|
||||
$result[$index] = filesize($prefix . DIRECTORY_SEPARATOR . $file);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function diffDirectories($dir1, $dir2, $prefix = "") {
|
||||
$diff = [];
|
||||
|
||||
$scan1files = [];
|
||||
$scan1folders = [];
|
||||
if(file_exists($dir1) && is_dir($dir1)) {
|
||||
list($scan1files, $scan1folders) = $this->getFilesAndFolders($dir1);
|
||||
}
|
||||
|
||||
$scan2files = [];
|
||||
$scan2folders = [];
|
||||
if(file_exists($dir2) && is_dir($dir2)) {
|
||||
list($scan2files, $scan2folders) = $this->getFilesAndFolders($dir2);
|
||||
}
|
||||
|
||||
$fileCreations = array_diff($scan2files, $scan1files);
|
||||
$fileCreationsFilesizes = $this->getFilesizesOfFiles($dir2, $fileCreations);
|
||||
|
||||
$fileDeletions = array_diff($scan1files, $scan2files);
|
||||
$fileDeletionsFilesizes = $this->getFilesizesOfFiles($dir1, $fileDeletions);
|
||||
|
||||
$filePossibleEdits = array_intersect($scan1files, $scan2files);
|
||||
|
||||
$allSubfolders = array_unique(array_merge($scan1folders, $scan2folders));
|
||||
|
||||
/*$diff[] = [
|
||||
"type" => "DEBUG",
|
||||
"prefix" => $prefix,
|
||||
"fileCreations" => $fileCreations,
|
||||
"fileCreationsFilesizes" => $fileCreationsFilesizes,
|
||||
"fileDeletions" => $fileDeletions,
|
||||
"fileDeletionsFilesizes" => $fileDeletionsFilesizes,
|
||||
//"folderCreations" => $folderCreations,
|
||||
//"folderDeletions" => $folderDeletions,
|
||||
"allSubfolders" => $allSubfolders,
|
||||
];*/
|
||||
|
||||
// search for creations and deletions, that are actually renames
|
||||
foreach($fileCreations as $creationIndex=>$creation) {
|
||||
$creationPath = $dir2 . DIRECTORY_SEPARATOR . $creation;
|
||||
$creationSize = $fileCreationsFilesizes[$creationIndex];
|
||||
|
||||
$renameContenders = array_keys($fileDeletionsFilesizes, $creationSize);
|
||||
|
||||
if(sizeof($renameContenders) != 0) {
|
||||
/*$diff[] = [
|
||||
"type" => "DEBUG",
|
||||
"comparing" => [
|
||||
"creation" => $creationIndex,
|
||||
"deletions" => $renameContenders,
|
||||
],
|
||||
];*/
|
||||
|
||||
$creationSHA = sha1_file($creationPath);
|
||||
foreach($renameContenders as $contender) {
|
||||
$deletion = $fileDeletions[$contender];
|
||||
$deletionPath = $dir1 . DIRECTORY_SEPARATOR . $deletion;
|
||||
$deletionSHA = sha1_file($deletionPath);
|
||||
|
||||
if($deletionSHA == $creationSHA) {
|
||||
$diff[] = [
|
||||
"type" => "RENAME",
|
||||
"before" => [
|
||||
"exists" => True,
|
||||
"path" => $prefix . DIRECTORY_SEPARATOR . $deletion,
|
||||
"size" => $creationSize,
|
||||
],
|
||||
"afterwards" => [
|
||||
"exists" => True,
|
||||
"path" => $prefix . DIRECTORY_SEPARATOR . $creation,
|
||||
"size" => $creationSize,
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
unset($fileCreations[$creationIndex]);
|
||||
unset($fileDeletions[$contender]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach($fileCreations as $index=>$creation) {
|
||||
$diff[] = [
|
||||
"type" => "CREATION",
|
||||
"before" => [
|
||||
"exists" => False,
|
||||
],
|
||||
"afterwards" => [
|
||||
"exists" => True,
|
||||
"path" => $prefix . DIRECTORY_SEPARATOR . $creation,
|
||||
"size" => $fileCreationsFilesizes[$index],
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
foreach($fileDeletions as $index=>$deletion) {
|
||||
$diff[] = [
|
||||
"type" => "DELETION",
|
||||
"before" => [
|
||||
"exists" => True,
|
||||
"path" => $prefix . DIRECTORY_SEPARATOR . $deletion,
|
||||
"size" => $fileDeletionsFilesizes[$index],
|
||||
],
|
||||
"afterwards" => [
|
||||
"exists" => False,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
foreach($filePossibleEdits as $possibleEdit) {
|
||||
$file1 = $dir1 . DIRECTORY_SEPARATOR . $possibleEdit;
|
||||
$file2 = $dir2 . DIRECTORY_SEPARATOR . $possibleEdit;
|
||||
$file1Size = filesize($file1);
|
||||
$file2Size = filesize($file2);
|
||||
|
||||
if(filemtime($file1) == filemtime($file2)) {
|
||||
//not different because same mtime
|
||||
continue;
|
||||
} else {
|
||||
// mtime different, but could just have gotten touched without modifications
|
||||
if($file1Size == $file2Size) {
|
||||
// if filesize is the same check for binary differences
|
||||
$handle1 = fopen($file1, 'rb');
|
||||
$handle2 = fopen($file2, 'rb');
|
||||
|
||||
$filesdifferent = false;
|
||||
|
||||
while(!feof($handle1)) {
|
||||
if(fread($handle1, 8192) != fread($handle2, 8192)) {
|
||||
// files are different
|
||||
$filesdifferent = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose($handle1);
|
||||
fclose($handle2);
|
||||
|
||||
if(!$filesdifferent) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$diff[] = [
|
||||
"type" => "EDIT",
|
||||
"before" => [
|
||||
"path" => $prefix . DIRECTORY_SEPARATOR . $possibleEdit,
|
||||
"size" => $file1Size,
|
||||
],
|
||||
"afterwards" => [
|
||||
"path" => $prefix . DIRECTORY_SEPARATOR . $possibleEdit,
|
||||
"size" => $file2Size,
|
||||
]
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
foreach($allSubfolders as $folder) {
|
||||
array_push($diff, ...($this->diffDirectories($dir1 . DIRECTORY_SEPARATOR . $folder, $dir2 . DIRECTORY_SEPARATOR . $folder, $prefix . DIRECTORY_SEPARATOR . $folder)));
|
||||
}
|
||||
|
||||
return $diff;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue