jsharmony-cms 1.9.4 → 1.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/jsHarmonyCMSSFTPServer.js +148 -130
- package/models/Publish_Add_Branch.json +1 -1
- package/models/Publish_Add_Branch.onroute.js +16 -0
- package/models/Publish_Add_Release.json +1 -1
- package/models/Publish_Add_Release.onroute.js +16 -0
- package/models/Publish_Log.js +1 -6
- package/models/Publish_Redeploy.json +2 -2
- package/models/Publish_Redeploy.onroute.js +21 -0
- package/package.json +1 -1
|
@@ -797,154 +797,172 @@ jsHarmonyCMSSFTPServer.prototype.Run = function(run_cb){
|
|
|
797
797
|
|
|
798
798
|
|
|
799
799
|
}).on('READDIR', function(reqid, handle) {
|
|
800
|
-
_this.DebugLog(clientDesc + 'READDIR');
|
|
800
|
+
_this.DebugLog(clientDesc + 'READDIR '+reqid);
|
|
801
801
|
//.name(reqid, names) names = array of { filename, longname, attrs }
|
|
802
802
|
//.status(reqid, statusCode, [message])
|
|
803
803
|
|
|
804
804
|
var handleInfo = getHandleInfo(handle);
|
|
805
805
|
if(!handleInfo) return sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.FAILURE, 'Handle not found');
|
|
806
806
|
|
|
807
|
-
handleInfo
|
|
807
|
+
waitForLock(handleInfo, function(){
|
|
808
|
+
handleInfo.lock = true;
|
|
808
809
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
if(handleInfo.
|
|
812
|
-
|
|
813
|
-
|
|
810
|
+
handleInfo.page++;
|
|
811
|
+
|
|
812
|
+
if(!handleInfo.syspath){
|
|
813
|
+
//Root folder
|
|
814
|
+
if(handleInfo.page > 1){
|
|
815
|
+
handleInfo.lock = false;
|
|
816
|
+
sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.EOF);
|
|
817
|
+
closeHandle(handle);
|
|
818
|
+
}
|
|
819
|
+
else {
|
|
820
|
+
var filename = 'sites';
|
|
821
|
+
handleInfo.lock = false;
|
|
822
|
+
sftpStream.name(reqid, [{
|
|
823
|
+
filename: filename,
|
|
824
|
+
longname: 'drwxrwxrwx 1 sys sys 4096 '+moment().format('MMM D YYYY')+' ' + filename,
|
|
825
|
+
attrs: {
|
|
826
|
+
mode: 0777 + fs.constants.S_IFDIR, // eslint-disable-line no-octal
|
|
827
|
+
uid: 0,
|
|
828
|
+
gid: 0,
|
|
829
|
+
size: 4096,
|
|
830
|
+
atime: moment().unix(),
|
|
831
|
+
mtime: moment().unix(),
|
|
832
|
+
}
|
|
833
|
+
}]);
|
|
834
|
+
}
|
|
814
835
|
}
|
|
815
836
|
else {
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
attrs: {
|
|
821
|
-
mode: 0777 + fs.constants.S_IFDIR, // eslint-disable-line no-octal
|
|
822
|
-
uid: 0,
|
|
823
|
-
gid: 0,
|
|
824
|
-
size: 4096,
|
|
825
|
-
atime: moment().unix(),
|
|
826
|
-
mtime: moment().unix(),
|
|
837
|
+
fs.exists(handleInfo.syspath, function(exists){
|
|
838
|
+
if(!exists){
|
|
839
|
+
handleInfo.lock = false;
|
|
840
|
+
return sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.NO_SUCH_FILE);
|
|
827
841
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
842
|
+
fs.readdir(handleInfo.syspath, function(err, files){
|
|
843
|
+
if(err){
|
|
844
|
+
handleInfo.lock = false;
|
|
845
|
+
return sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.FAILURE, 'Error retrieving directory listing');
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
Helper.execif((handleInfo.path=='/sites'),
|
|
849
|
+
function(f){
|
|
850
|
+
files = [];
|
|
851
|
+
jsh.AppSrv.ExecRecordset(req._DBContext, cms.funcs.replaceSchema("select site_id,site_name from {schema}.v_my_site where site_sts='ACTIVE' order by site_id"), [], { }, function (err, rslt) {
|
|
852
|
+
if (err) {
|
|
853
|
+
jsh.Log.error(err);
|
|
854
|
+
handleInfo.lock = false;
|
|
855
|
+
return sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.FAILURE, 'Error retrieving site listing');
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
if(rslt && rslt[0]) _.each(rslt[0], function(site){
|
|
859
|
+
var filename_short = HelperFS.cleanFileName(site.site_id);
|
|
860
|
+
var filename_long = HelperFS.cleanFileName(site.site_id+'_'+site.site_name);
|
|
861
|
+
files.push({
|
|
862
|
+
filename: filename_short,
|
|
863
|
+
longname: 'drwxrwxrwx 0 sys sys 4096 '+moment().format('MMM D YYYY')+' ' + filename_short,
|
|
864
|
+
attrs: {
|
|
865
|
+
mode: 0777, // eslint-disable-line no-octal
|
|
866
|
+
uid: 0,
|
|
867
|
+
gid: 0,
|
|
868
|
+
size: 4096,
|
|
869
|
+
atime: moment().unix(),
|
|
870
|
+
mtime: moment().unix(),
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
files.push({
|
|
874
|
+
filename: filename_long,
|
|
875
|
+
longname: 'lrwxrwxrwx 1 sys sys 4096 '+moment().format('MMM D YYYY')+' ' + filename_long,
|
|
876
|
+
attrs: {
|
|
877
|
+
mode: 0777 + fs.constants.S_IFDIR, // eslint-disable-line no-octal
|
|
878
|
+
uid: 0,
|
|
879
|
+
gid: 0,
|
|
880
|
+
size: 4096,
|
|
881
|
+
atime: moment().unix(),
|
|
882
|
+
mtime: moment().unix(),
|
|
883
|
+
}
|
|
884
|
+
});
|
|
869
885
|
});
|
|
886
|
+
|
|
887
|
+
return f();
|
|
870
888
|
});
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.EOF);
|
|
881
|
-
closeHandle(handle);
|
|
882
|
-
}
|
|
883
|
-
else{
|
|
884
|
-
for(var i=filesPerPage*(handleInfo.page-1);i<filesPerPage*handleInfo.page&&i<files.length;i++){
|
|
885
|
-
var file = files[i];
|
|
886
|
-
if(_.isString(file)){
|
|
887
|
-
pageFiles.push(file);
|
|
888
|
-
dirPage.push({
|
|
889
|
-
filename: file,
|
|
890
|
-
longname: file,
|
|
891
|
-
attrs: {}
|
|
892
|
-
});
|
|
893
|
-
}
|
|
894
|
-
else {
|
|
895
|
-
pageFiles.push('');
|
|
896
|
-
dirPage.push(file);
|
|
897
|
-
}
|
|
889
|
+
},
|
|
890
|
+
function(){
|
|
891
|
+
var filesPerPage = 1000;
|
|
892
|
+
var pageFiles = [];
|
|
893
|
+
var dirPage = [];
|
|
894
|
+
if((handleInfo.page-1)*filesPerPage >= files.length){
|
|
895
|
+
handleInfo.lock = false;
|
|
896
|
+
sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.EOF);
|
|
897
|
+
closeHandle(handle);
|
|
898
898
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
if(
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
dirPage[idx] = undefined;
|
|
910
|
-
return file_cb();
|
|
899
|
+
else{
|
|
900
|
+
for(var i=filesPerPage*(handleInfo.page-1);i<filesPerPage*handleInfo.page&&i<files.length;i++){
|
|
901
|
+
var file = files[i];
|
|
902
|
+
if(_.isString(file)){
|
|
903
|
+
pageFiles.push(file);
|
|
904
|
+
dirPage.push({
|
|
905
|
+
filename: file,
|
|
906
|
+
longname: file,
|
|
907
|
+
attrs: {}
|
|
908
|
+
});
|
|
911
909
|
}
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
dirPage[idx].attrs = {
|
|
917
|
-
mode: 0777 + (longname[0]=='d' ? fs.constants.S_IFDIR : longname[0]=='l' ? fs.constants.S_IFLNK : fs.constants.S_IFREG), // eslint-disable-line no-octal
|
|
918
|
-
uid: 0,
|
|
919
|
-
gid: 0,
|
|
920
|
-
size: (longname=='-' ? fstat.size : 4096),
|
|
921
|
-
atime: Math.floor(fstat.atime/1000),
|
|
922
|
-
mtime: Math.floor(fstat.mtime/1000),
|
|
923
|
-
};
|
|
924
|
-
|
|
925
|
-
return file_cb();
|
|
926
|
-
});
|
|
927
|
-
}, function(err){
|
|
928
|
-
if(err){
|
|
929
|
-
jsh.Log.error(err);
|
|
930
|
-
return sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.FAILURE, 'Error retrieving directory listing');
|
|
931
|
-
}
|
|
932
|
-
//Remove undefined entries from dirPage
|
|
933
|
-
for(var i=0;i<dirPage.length;i++){
|
|
934
|
-
if(typeof dirPage[i]=='undefined'){
|
|
935
|
-
dirPage.splice(i, 1);
|
|
936
|
-
i--;
|
|
910
|
+
else {
|
|
911
|
+
pageFiles.push('');
|
|
912
|
+
dirPage.push(file);
|
|
937
913
|
}
|
|
938
914
|
}
|
|
939
|
-
|
|
940
|
-
|
|
915
|
+
async.eachOfLimit(pageFiles, 50, function(pageFile, idx, file_cb){
|
|
916
|
+
if(!pageFile) return file_cb();
|
|
917
|
+
fs.stat(fspath.join(handleInfo.syspath, pageFile), function(err, fstat){
|
|
918
|
+
if(err) return file_cb();
|
|
919
|
+
|
|
920
|
+
var longname = '';
|
|
921
|
+
if(fstat.isDirectory()) longname += 'd';
|
|
922
|
+
//else if(fstat.isSymbolicLink()) longname += 'l';
|
|
923
|
+
else if(fstat.isFile()) longname += '-';
|
|
924
|
+
else{
|
|
925
|
+
dirPage[idx] = undefined;
|
|
926
|
+
return file_cb();
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
longname += 'rwxrwxrwx 0 sys sys '+(longname=='-' ? fstat.size : 4096)+' '+moment(fstat.mtime).format('MMM D YYYY')+' '+pageFile;
|
|
930
|
+
dirPage[idx].longname = longname;
|
|
931
|
+
|
|
932
|
+
dirPage[idx].attrs = {
|
|
933
|
+
mode: 0777 + (longname[0]=='d' ? fs.constants.S_IFDIR : longname[0]=='l' ? fs.constants.S_IFLNK : fs.constants.S_IFREG), // eslint-disable-line no-octal
|
|
934
|
+
uid: 0,
|
|
935
|
+
gid: 0,
|
|
936
|
+
size: (longname=='-' ? fstat.size : 4096),
|
|
937
|
+
atime: Math.floor(fstat.atime/1000),
|
|
938
|
+
mtime: Math.floor(fstat.mtime/1000),
|
|
939
|
+
};
|
|
940
|
+
|
|
941
|
+
return file_cb();
|
|
942
|
+
});
|
|
943
|
+
}, function(err){
|
|
944
|
+
if(err){
|
|
945
|
+
jsh.Log.error(err);
|
|
946
|
+
handleInfo.lock = false;
|
|
947
|
+
return sftpStream.status(reqid, ssh2.SFTP_STATUS_CODE.FAILURE, 'Error retrieving directory listing');
|
|
948
|
+
}
|
|
949
|
+
//Remove undefined entries from dirPage
|
|
950
|
+
for(var i=0;i<dirPage.length;i++){
|
|
951
|
+
if(typeof dirPage[i]=='undefined'){
|
|
952
|
+
dirPage.splice(i, 1);
|
|
953
|
+
i--;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
handleInfo.lock = false;
|
|
957
|
+
sftpStream.name(reqid, dirPage);
|
|
958
|
+
});
|
|
959
|
+
}
|
|
941
960
|
}
|
|
942
|
-
|
|
943
|
-
);
|
|
961
|
+
);
|
|
962
|
+
});
|
|
944
963
|
});
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
|
|
964
|
+
}
|
|
965
|
+
});
|
|
948
966
|
|
|
949
967
|
}).on('LSTAT', function(reqid, fpath) {
|
|
950
968
|
_this.DebugLog(clientDesc + 'LSTAT '+fpath);
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"<% } %>",
|
|
24
24
|
]},
|
|
25
25
|
{"name":"branch_desc","control":"label","caption":"Revision","sqlselect":"(select branch_desc from {schema}.v_my_branch_desc where {schema}.v_my_branch_desc.branch_id = {schema}.branch.branch_id)"},
|
|
26
|
-
{"name":"deployment_date","control":"textbox","caption":"Publish Date", "validate":["Required","IsDate:'YYYY-MM-DD hh:mm A'"],"default":"
|
|
26
|
+
{"name":"deployment_date","control":"textbox","caption":"Publish Date", "validate":["Required","IsDate:'YYYY-MM-DD hh:mm A'"],"default":"","controlstyle":"width:160px;","unbound":true},
|
|
27
27
|
{"name":"deployment_tag","control":"textbox_L","caption":"Tag", "validate":["Required","MaxLength:256"],"unbound":true},
|
|
28
28
|
{"control":"button","value":"Schedule Deployment","controlstyle": "padding:3px 8px;margin-top:6px;","onclick": "_this.publish();"}
|
|
29
29
|
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//(routetype, req, res, callback, require, jsh, modelid, params)
|
|
2
|
+
|
|
3
|
+
var Helper = require('../Helper.js');
|
|
4
|
+
var moment = require('moment');
|
|
5
|
+
|
|
6
|
+
if(routetype == 'model'){
|
|
7
|
+
var model = jsh.getModel(req, modelid);
|
|
8
|
+
if (!Helper.hasModelAction(req, model, 'B')) { Helper.GenError(req, res, -11, 'Invalid Model Access'); return; }
|
|
9
|
+
|
|
10
|
+
var resModel = jsh.getModelClone(req, modelid);
|
|
11
|
+
var deployment_date = jsh.AppSrvClass.prototype.getFieldByName(resModel.fields, 'deployment_date');
|
|
12
|
+
deployment_date.default = 'js:' + JSON.stringify(moment().format('YYYY-MM-DD hh:mm A'));
|
|
13
|
+
req.jshlocal.Models[modelid] = resModel;
|
|
14
|
+
return callback();
|
|
15
|
+
}
|
|
16
|
+
else return callback();
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
]},
|
|
30
30
|
{"name":"branch_id","control":"dropdown","caption":"Release","validate":["Required"],"onchange":"_this.branch_id_onchange(obj, newval, undoChange);",
|
|
31
31
|
"lov":{"parent":"site_id" ,"sql2":"select site_id code_parent, branch_id code_val, branch_desc code_txt from {schema}.v_my_branch_desc where branch_type='PUBLIC' and branch_sts='ACTIVE' and site_id={schema}.my_current_site_id() order by site_id,branch_desc"}},
|
|
32
|
-
{"name":"deployment_date","control":"textbox","caption":"Publish Date", "validate":["Required","IsDate:'YYYY-MM-DD hh:mm A'"],"default":"
|
|
32
|
+
{"name":"deployment_date","control":"textbox","caption":"Publish Date", "validate":["Required","IsDate:'YYYY-MM-DD hh:mm A'"],"default":"","controlstyle":"width:160px;"},
|
|
33
33
|
{"name":"deployment_tag","control":"textbox_L","caption":"Tag", "validate":["Required","MaxLength:256"]},
|
|
34
34
|
{"control":"button","value":"Schedule Deployment","controlstyle": "padding:3px 8px;margin-top:6px;","onclick": "_this.publish();"}
|
|
35
35
|
]
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
//(routetype, req, res, callback, require, jsh, modelid, params)
|
|
2
|
+
|
|
3
|
+
var Helper = require('../Helper.js');
|
|
4
|
+
var moment = require('moment');
|
|
5
|
+
|
|
6
|
+
if(routetype == 'model'){
|
|
7
|
+
var model = jsh.getModel(req, modelid);
|
|
8
|
+
if (!Helper.hasModelAction(req, model, 'B')) { Helper.GenError(req, res, -11, 'Invalid Model Access'); return; }
|
|
9
|
+
|
|
10
|
+
var resModel = jsh.getModelClone(req, modelid);
|
|
11
|
+
var deployment_date = jsh.AppSrvClass.prototype.getFieldByName(resModel.fields, 'deployment_date');
|
|
12
|
+
deployment_date.default = 'js:' + JSON.stringify(moment().format('YYYY-MM-DD hh:mm A'));
|
|
13
|
+
req.jshlocal.Models[modelid] = resModel;
|
|
14
|
+
return callback();
|
|
15
|
+
}
|
|
16
|
+
else return callback();
|
package/models/Publish_Log.js
CHANGED
|
@@ -52,12 +52,7 @@ jsh.App[modelid] = new (function(){
|
|
|
52
52
|
|
|
53
53
|
var isRunning = false;
|
|
54
54
|
if(deployment_sts=='RUNNING') isRunning = true;
|
|
55
|
-
else if(deployment_sts=='PENDING')
|
|
56
|
-
var deployment_date = jsh.moment(rslt.deployment.deployment_date);
|
|
57
|
-
if(deployment_date.isValid()){
|
|
58
|
-
if(deployment_date.toDate() <= (new Date())) isRunning = true;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
55
|
+
else if(deployment_sts=='PENDING') isRunning = true;
|
|
61
56
|
|
|
62
57
|
//Render Log
|
|
63
58
|
$('#'+xmodel.class+'_deployment_log').html(XExt.escapeHTMLBR(rslt.log));
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
{"name":"branch_desc","control":"label","caption":"Revision","sqlselect":"(select branch_desc from {schema}.v_my_branch_desc where branch_id={schema}.v_my_deployment.branch_id)"},
|
|
17
17
|
{"name":"deployment_target_id","control":"dropdown","caption":"Deployment Target","validate":["Required"],"unbound":true,
|
|
18
18
|
"lov":{"sql":"select deployment_target_id code_val, deployment_target_name code_txt from {schema}.v_my_deployment_target where deployment_target_can_publish = 1 and deployment_target_sts='ACTIVE' and site_id in (select site_id from {schema}.deployment inner join {schema}.branch on branch.branch_id = deployment.branch_id where deployment_id=@deployment_id) order by deployment_target_name"}},
|
|
19
|
-
{"name":"deployment_date","control":"textbox","caption":"Schedule Redeployment", "validate":["Required","IsDate:'YYYY-MM-DD hh:mm A'"],"default":"
|
|
20
|
-
{"name":"deployment_tag","control":"textbox_L","caption":"Tag", "validate":["Required","MaxLength:256"],"unbound":true,"default":"
|
|
19
|
+
{"name":"deployment_date","control":"textbox","caption":"Schedule Redeployment", "validate":["Required","IsDate:'YYYY-MM-DD hh:mm A'"],"default":"","controlstyle":"width:160px;","unbound":true},
|
|
20
|
+
{"name":"deployment_tag","control":"textbox_L","caption":"Tag", "validate":["Required","MaxLength:256"],"unbound":true,"default":""},
|
|
21
21
|
{"control":"button","value":"Schedule Redeployment","controlstyle": "padding:3px 8px;margin-top:6px;","onclick": "_this.publish();"}
|
|
22
22
|
]
|
|
23
23
|
},
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//(routetype, req, res, callback, require, jsh, modelid, params)
|
|
2
|
+
|
|
3
|
+
var Helper = require('../Helper.js');
|
|
4
|
+
var moment = require('moment');
|
|
5
|
+
|
|
6
|
+
if(routetype == 'model'){
|
|
7
|
+
var model = jsh.getModel(req, modelid);
|
|
8
|
+
if (!Helper.hasModelAction(req, model, 'B')) { Helper.GenError(req, res, -11, 'Invalid Model Access'); return; }
|
|
9
|
+
|
|
10
|
+
var resModel = jsh.getModelClone(req, modelid);
|
|
11
|
+
|
|
12
|
+
var deployment_date = jsh.AppSrvClass.prototype.getFieldByName(resModel.fields, 'deployment_date');
|
|
13
|
+
deployment_date.default = 'js:' + JSON.stringify(moment().format('YYYY-MM-DD hh:mm A'));
|
|
14
|
+
|
|
15
|
+
var deployment_tag = jsh.AppSrvClass.prototype.getFieldByName(resModel.fields, 'deployment_tag');
|
|
16
|
+
deployment_tag.default = 'js:' + JSON.stringify(moment().format('YYYY-MM-DD hh:mm A')+' Redeployment');
|
|
17
|
+
|
|
18
|
+
req.jshlocal.Models[modelid] = resModel;
|
|
19
|
+
return callback();
|
|
20
|
+
}
|
|
21
|
+
else return callback();
|