Commit bef79b00 authored by Frank Bergmann's avatar Frank Bergmann

- Last - more or less - working version before

  starting to work with versions
parent 6d0e0dc7
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
* *
************************************************************/ ************************************************************/
Ext.define('POSync.controller.Connection', { Ext.define('POSync.controller.Connection', {
extend: 'Ext.app.Controller', extend: 'Ext.app.Controller',
id: 'Connection', id: 'Connection',
...@@ -45,6 +46,14 @@ Ext.define('POSync.controller.Connection', { ...@@ -45,6 +46,14 @@ Ext.define('POSync.controller.Connection', {
}); });
}, },
/**
* Convert a time to a PostgreSQL ISO date string
*/
timeToIso: function(time) {
var date = new Date(time);
return date.toISOString().replace("T", " ").replace("Z", "");
},
/* FIXME: no easy way to know if login is successful */ /* FIXME: no easy way to know if login is successful */
login: function (request_options) { login: function (request_options) {
var me = this; var me = this;
...@@ -177,14 +186,22 @@ Ext.define('POSync.controller.Connection', { ...@@ -177,14 +186,22 @@ Ext.define('POSync.controller.Connection', {
// Get the contents // Get the contents
var dirTree = require ('directory-tree'); var dirTree = require ('directory-tree');
var tree = dirTree(path,{attributes:['mode', 'mtime', 'mtimeMs']}); var tree = dirTree(path,{attributes:['mode', 'mtime', 'mtimeMs']});
this.fixLocalTree(tree); this.fixLocalTree(tree, projectId);
this.localDirStore.loadTree (tree); this.localDirStore.loadTree (tree);
this.localDirStore.isLoaded = projectId; this.localDirStore.isLoaded = projectId;
}, },
/* Fix a tree before loading it */ /**
fixLocalTree: function (tree) { * Fix a tree before loading it
*/
fixLocalTree: function (tree, projectId) {
var me = this;
// Get the project path
var fs = require('fs');
var sha1File = require('sha1-file');
if (tree) { if (tree) {
if (tree.type == 'directory') { if (tree.type == 'directory') {
tree.type = 'folder'; tree.type = 'folder';
...@@ -194,14 +211,11 @@ Ext.define('POSync.controller.Connection', { ...@@ -194,14 +211,11 @@ Ext.define('POSync.controller.Connection', {
tree.leaf = false; tree.leaf = false;
tree.mime_type = ''; tree.mime_type = '';
} else { } else {
// const cp = require('child_process'); var stats = fs.statSync(tree.path);
// tree.type = cp.execFileSync('/usr/bin/file', ['--brief', '--mime-type', tree.path]).toString(); tree.sha1 = sha1File(tree.path);
// tree.sha1 = cp.execFileSync('/usr/bin/sha1sum', [tree.path]).toString().substr(0,40); tree.modification_date = me.timeToIso(stats.mtimeMs);
// tree.date = cp.execFileSync('/usr/bin/stat', ['-c', '%y', tree.path]).toString(); tree.creation_date = me.timeToIso(stats.birthtimeMs);
tree.size = stats.size;
tree.sha1 = '<sha1>';
tree.date = '<date>';
tree.expandable = false; tree.expandable = false;
tree.expanded = false; tree.expanded = false;
tree.leaf = true; tree.leaf = true;
...@@ -247,39 +261,42 @@ Ext.define('POSync.controller.Connection', { ...@@ -247,39 +261,42 @@ Ext.define('POSync.controller.Connection', {
// ******************************************************************** // ********************************************************************
// Go through the list of remote files and check that a local file exists. // Go through the list of remote files and check that a local file exists.
var root = me.filesStore.getRootNode(); var root = me.filesStore.getRootNode();
root.cascadeBy(function(file) { root.cascadeBy(function(remoteFile) {
if ("root" == file.get('id')) return; // Exclude folders and the root if ("root" == remoteFile.get('id')) return; // Exclude folders and the root
var pathArray = file.getPathArray(); var pathArray = remoteFile.getPathArray();
var purePathArray = pathArray.slice(0); var purePathArray = pathArray.slice(0);
var fileName = file.get('name'); var fileName = remoteFile.get('name');
pathArray.push(fileName); pathArray.push(fileName);
console.log('Connection.sync remote: path='+pathArray); console.log('Connection.sync remote: path='+pathArray);
var type = file.get('type'); var type = remoteFile.get('type');
switch (type) { switch (type) {
case 'file': case 'file':
var localFileFound = me.localDirStore.searchUsingPathArray(pathArray); var localFile = me.localDirStore.searchUsingPathArray(pathArray);
if (!localFileFound) { if (!localFile) {
var operation = Ext.create('POSync.model.Operation', { var operation = Ext.create('POSync.model.Operation', {
id: 'op_'+file.get('id'), id: 'download_'+pathArray.join('_'),
file_id: file.get('id'), file_id: remoteFile.get('id'),
file_path: purePathArray.join('/'), file_path: purePathArray.join('/'),
file_name: file.get('name'), file_name: remoteFile.get('name'),
mime_type: file.get('mime_type'), mime_type: remoteFile.get('mime_type'),
file_sha1: null, file_sha1: null,
local_file: localFile,
remote_file: remoteFile,
op: 'download' op: 'download'
}); });
me.operationsStore.add(operation); me.operationsStore.add(operation);
} else {
// Compare local with remote file based on meta information
me.syncFileLocalRemote(projectId, localFile, remoteFile);
} }
break; break;
case 'folder': case 'folder':
var localFileFound = me.localDirStore.searchUsingPathArray(purePathArray); var localFile = me.localDirStore.searchUsingPathArray(purePathArray);
if (!localFileFound) { if (!localFile) {
// Create a new local folder // Create a new local folder
var fs = require('fs'); var fs = require('fs');
// Get the project path
var project = me.projectsStore.getById(''+projectId); var project = me.projectsStore.getById(''+projectId);
var projectPath = configData.topdir+'/'+project.get('project_path'); var projectPath = configData.topdir+'/'+project.get('project_path');
var path = projectPath+'/'+purePathArray.join('/'); var path = projectPath+'/'+purePathArray.join('/');
...@@ -293,43 +310,52 @@ Ext.define('POSync.controller.Connection', { ...@@ -293,43 +310,52 @@ Ext.define('POSync.controller.Connection', {
// ******************************************************************** // ********************************************************************
// Go through the list of local files and check that a remote file exists // Go through the list of local files and check that a remote file exists
var root = me.localDirStore.getRootNode(); var root = me.localDirStore.getRootNode();
root.cascadeBy(function(file) { root.cascadeBy(function(localFile) {
if ("root" == file.get('id')) return; // Exclude root if ("root" == localFile.get('id')) return; // Exclude root
var pathArray = file.getPathArray(); var pathArray = localFile.getPathArray();
var purePathArray = pathArray.slice(0); var purePathArray = pathArray.slice(0);
var fileName = file.get('name'); var fileName = localFile.get('name');
pathArray.push(fileName); pathArray.push(fileName);
console.log('Connection.sync local: path='+pathArray); console.log('Connection.sync local: path='+pathArray);
var type = file.get('type'); var type = localFile.get('type');
switch (type) { switch (type) {
case 'file': case 'file':
var remoteFileFound = me.filesStore.searchUsingPathArray(pathArray); var remoteFile = me.filesStore.searchUsingPathArray(pathArray);
if (!remoteFileFound) { if (!remoteFile) {
var operation = Ext.create('POSync.model.Operation', { var operation = Ext.create('POSync.model.Operation', {
id: 'op_'+file.get('id'), id: 'upload_'+pathArray.join('_'),
file_id: file.get('id'), file_id: localFile.get('id'),
file_path: purePathArray.join('/'), file_path: purePathArray.join('/'),
file_name: file.get('name'), file_name: localFile.get('name'),
mime_type: file.get('mime_type'), mime_type: localFile.get('mime_type'),
file_sha1: null, file_sha1: null,
local_file: localFile,
remote_file: remoteFile,
op: 'upload' op: 'upload'
}); });
me.operationsStore.add(operation); me.operationsStore.add(operation);
console.log('Connection.sync local: upload: localFile='+pathArray.join('/'));
} else {
// We already call syncFileLocalRemote with remote files above
// me.syncFileLocalRemote(localFile, remoteFile);
} }
break; break;
case 'folder': case 'folder':
var remoteFileFound = me.filesStore.searchUsingPathArray(purePathArray); var remoteFile = me.filesStore.searchUsingPathArray(purePathArray);
if (!remoteFileFound) { if (!remoteFile) {
var operation = Ext.create('POSync.model.Operation', { var operation = Ext.create('POSync.model.Operation', {
id: 'op_'+file.get('id'), id: 'mkdir_'+pathArray.join('_'),
file_id: file.get('id'), file_id: file.get('id'),
file_path: purePathArray.join('/'), file_path: purePathArray.join('/'),
file_name: file.get('name'), file_name: file.get('name'),
local_file: localFile,
remote_file: remoteFile,
op: 'mkdir' op: 'mkdir'
}); });
me.operationsStore.add(operation); me.operationsStore.add(operation);
console.log('Connection.sync local: mkdir: path='+purePathArray.join('/'));
} }
break; break;
default: alert('sync: invalid type for local file: '+type); default: alert('sync: invalid type for local file: '+type);
...@@ -339,6 +365,46 @@ Ext.define('POSync.controller.Connection', { ...@@ -339,6 +365,46 @@ Ext.define('POSync.controller.Connection', {
me.syncExecOperations(projectId); me.syncExecOperations(projectId);
}, },
/**
* Handles the case that a file is available both locally
* and remotely.
* Checks for creation_date, file_length and compares them
* against the version history of the file on the server.
*/
syncFileLocalRemote: function(projectId, localFile, remoteFile) {
var me = this;
console.log('Connection.syncFileLocalRemote: local='+localFile.get('name')+', '+remoteFile.get('name'));
var configData = this.guiController.configData;
var project = me.projectsStore.getById(''+projectId);
var projectPath = configData.topdir+'/'+project.get('project_path');
var localPathArray = localFile.getPathArray();
var fileName = localFile.get('name');
localPathArray.push(fileName);
var localFullPath = projectPath+'/'+localPathArray.join('/');
// Check that meta information is available with the local file
var fs = require('fs');
var local_creation_date = localFile.get('creation_date');
if ("" === local_creation_date) {
var stats = fs.statSync(localFullPath);
localFile.set('creation_date', me.timeToIso(stats.birthtimeMs));
localFile.set('modification_date', me.timeToIso(stats.mtimeMs));
localFile.set('content_length', stats.size);
}
var sha1File = require('sha1-file');
var sha1 = sha1File(localFullPath);
localFile.set('sha1', sha1);
console.log('Connection.syncFileLocalRemote: finished');
},
syncFileLocalRemoteStats: function(projectId,localFile,remoteFile) {
alert(localFile);
},
/** /**
* Takes a store with sync "Operations" and executes them. * Takes a store with sync "Operations" and executes them.
...@@ -349,10 +415,8 @@ Ext.define('POSync.controller.Connection', { ...@@ -349,10 +415,8 @@ Ext.define('POSync.controller.Connection', {
console.log('Connection.syncExecOperations'); console.log('Connection.syncExecOperations');
me.operationsStore.each(function(op) { me.operationsStore.each(function(op) {
console.log('Connection.syncExecOperations: op');
console.log(op);
var operation = op.get('op'); var operation = op.get('op');
console.log('Connection.syncExecOperations: op='+operation+', id='+op.get('id'));
switch (operation) { switch (operation) {
case 'download': case 'download':
me.syncDownload(projectId, op); me.syncDownload(projectId, op);
...@@ -379,13 +443,13 @@ Ext.define('POSync.controller.Connection', { ...@@ -379,13 +443,13 @@ Ext.define('POSync.controller.Connection', {
*/ */
syncDownload: function(projectId, op) { syncDownload: function(projectId, op) {
var me = this; var me = this;
console.log('Connection.syncDownload');
var configData = this.guiController.configData; var configData = this.guiController.configData;
var fileId = op.get('file_id'); var fileId = op.get('file_id');
var filePath = op.get('file_path'); var filePath = op.get('file_path');
var fileName = op.get('file_name'); var fileName = op.get('file_name');
var mimeType = op.get('mime_type'); var mimeType = op.get('mime_type');
console.log('Connection.syncDownload: path='+filePath+', name='+fileName);
// Get the project path // Get the project path
var project = this.projectsStore.getById(''+projectId); var project = this.projectsStore.getById(''+projectId);
...@@ -428,12 +492,13 @@ Ext.define('POSync.controller.Connection', { ...@@ -428,12 +492,13 @@ Ext.define('POSync.controller.Connection', {
*/ */
syncUpload: function(projectId, op) { syncUpload: function(projectId, op) {
var me = this; var me = this;
console.log('Connection.syncUpload');
var configData = this.guiController.configData; var configData = this.guiController.configData;
var filePath = op.get('file_path'); var filePath = op.get('file_path');
var fileName = op.get('file_name'); var fileName = op.get('file_name');
var mimeType = op.get('mime_type'); var mimeType = op.get('mime_type');
var localFile = op.get('local_file');
console.log('Connection.syncUpload: path='+filePath+', name='+fileName);
// Get the project path // Get the project path
var project = this.projectsStore.getById(''+projectId); var project = this.projectsStore.getById(''+projectId);
...@@ -452,6 +517,9 @@ Ext.define('POSync.controller.Connection', { ...@@ -452,6 +517,9 @@ Ext.define('POSync.controller.Connection', {
var formData = new FormData(); var formData = new FormData();
formData.append('project_id', projectId); formData.append('project_id', projectId);
formData.append('path', filePath); formData.append('path', filePath);
formData.append('creation_date', localFile.get('creation_date'));
formData.append('modification_date', localFile.get('modification_date'));
formData.append('sha1', localFile.get('sha1'));
// formData.append('upload_file', fileContent); // formData.append('upload_file', fileContent);
var blob = new Blob([fileContent], { type: mimeType}); var blob = new Blob([fileContent], { type: mimeType});
...@@ -481,11 +549,12 @@ Ext.define('POSync.controller.Connection', { ...@@ -481,11 +549,12 @@ Ext.define('POSync.controller.Connection', {
*/ */
syncMkdir: function(projectId, op) { syncMkdir: function(projectId, op) {
var me = this; var me = this;
console.log('Connection.syncMkdir');
// POST the file to the mkdir page // POST the file to the mkdir page
var configData = this.guiController.configData; var configData = this.guiController.configData;
var filePath = op.get('file_path'); var filePath = op.get('file_path');
console.log('Connection.syncMkdir: path='+filePath);
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
var url = configData.url + '/intranet-rest-fs-openacs/mkdir'; var url = configData.url + '/intranet-rest-fs-openacs/mkdir';
var formData = new FormData(); var formData = new FormData();
......
...@@ -23,7 +23,6 @@ Ext.define('POSync.model.File', { ...@@ -23,7 +23,6 @@ Ext.define('POSync.model.File', {
'content_length', // File length in bytes (empty string for folders) 'content_length', // File length in bytes (empty string for folders)
'creation_date', // Date of first creation 'creation_date', // Date of first creation
'publish_date',
'modification_date', // Date of last modification 'modification_date', // Date of last modification
'sha1', // sha-1 hash of the content (empty string for folders) 'sha1', // sha-1 hash of the content (empty string for folders)
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
/* /*
* What should we do during sync? * What should we do during sync?
*/ */
Ext.define('POSync.model.Operation', { Ext.define('POSync.model.Operation', {
extend: 'Ext.data.Model', extend: 'Ext.data.Model',
idProperty: 'id', idProperty: 'id',
...@@ -14,6 +12,8 @@ Ext.define('POSync.model.Operation', { ...@@ -14,6 +12,8 @@ Ext.define('POSync.model.Operation', {
'file_name', 'file_name',
'mime_type', 'mime_type',
'file_sha1', 'file_sha1',
'op' 'op',
'local_file',
'remote_file'
] ]
}); });
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment