<commit_before>//
//
//

var $={Dir:{			// Global variable
    Server: 'Dir9',		// Directum server
    DB: 	'Directum'	// Directum database
}};

//goW();
$.doc=newDoc();
startPage();

while(!$.closed && !$.window.welcome) WScript.Sleep(300);

if($.closed) WScript.Quit();

changePage('connect');
$.window.startSpinner();
sysInit();
countDown();

//--[Functions]

//   wscript ( )
function goW()
{
 WScript.Interactive=false;

 if(WScript.FullName.replace(/^.*[\/\\]/, '').match(/^w/i)) return;
 (new ActiveXObject("WScript.Shell")).Run('wscript //B "'+
    WScript.ScriptFullName+'"', 0, false);
 WScript.Quit();
}

//    HTML-
function html(S)
{
 S=''+S;
 var E={'&':'amp', '>':'gt', '<':'lt', '"':'quot'};
 for(var Z in E)
   S=S.split(Z).join('&'+E[Z]+';');
 return S;
}

//  MSIE
function newDoc()
{
 var ie=WScript.CreateObject('InternetExplorer.Application');
 ie.AddressBar=false;
 ie.StatusBar=false;
 ie.ToolBar=false;
 ie.MenuBar=false;
 ie.Visible=true;
 ie.Navigate('about:blank');
 while(ie.Busy) WScript.Sleep(100);
 $.ie=ie;
 return ie.Document;
}

//
function startPage()
{
 $.doc.open();
 $.doc.write(readSnippet('html'));
 $.doc.close();

 $.window=$.doc.parentWindow;
 $.doc.body.onunload=function(){ $.closed=1; }
 $.interior=$.doc.getElementById('Interior');
}

//
function readSnippet(name)
{
 var f=WScript.CreateObject("Scripting.FileSystemObject").
    OpenTextFile(WScript.ScriptFullName, 1);	//ForReading
 var on, R='';
 while(!f.AtEndOfStream)
 {
  var s=f.ReadLine();
  if(!on)
  {
   if(s.match(/^\s*\/\*[-\s]*\[([.\w]+)\][-\s]+$/i) && (RegExp.$1==name)) on=1;
   continue;
  }
  if(s.match(/^[-\s]+\*\/\s*$/)) break;
  R+=s+'\n';
 }
 f.Close();
 return R;
}

//
function countDown()
{
 $.window.countDown($.ie);
 WScript.Quit();
}

//
function doIt(Name, Fun)
{
 if(!$.stepN)$.stepN=1;

 var S=$.window.newStep();
 var t=$.interior.getElementsByTagName('table')[0];
 var r=t.insertRow();
 var c=r.insertCell();
 c.innerHTML=($.stepN++)+'. '+Name;
 c.noWrap=1;
 (S.Time=r.insertCell()).innerHTML='0.0';
 S.Time.align='Right';
 (S.Res=r.insertCell()).innerHTML='
';
 $.window.Step=S;

 function updTime(Txt)
 {
  S.Res.innerHTML=Txt;
  $.window.Step=0;
  S.Time.innerHTML=(((new Date()).getTime()-S.ctime.getTime())/1000).toFixed(3);
 }

 try{
  Fun();
 }catch(e)
 {
  updTime(e.description);
  countDown();
 }
 if($.closed) WScript.Quit();
 updTime('Ok');
}

//
function changePage(N)
{
 $.interior.innerHTML=readSnippet(N);
}

function sqlFetch()
{
 var X=[];
 for(var Rs=$.SQL.Execute(); !Rs.EOF; Rs.MoveNext())
 {
  var r={};
  for(var E=new Enumerator(Rs.Fields); !E.atEnd(); E.moveNext())
   r[E.item().name]=E.item().value;
  X.push(r);
 }
 return X;
}

//      AD
function u2obj(u)
{
 $.AD.cmd.CommandText="<LDAP://"+$.AD.baseDN+
    ">;(&(objectCategory=user)(sAMAccountName="+
    u.replace(/[()*\\]/g, '\\$&')+"));*;subTree";
 var Rs=$.AD.cmd.Execute();
 if(!Rs.EOF) return GetObject(Rs(0).Value);
}

//     AD
function depID(user)
{
 if(!user) return;
 while(user=GetObject(user.Parent))
 {
  if(!user.ou) return;
  var i=user.l;
  if(!i) continue;
  if(!i.match(/^\d+$/)) return;
  return i;
 }
}

//
function findDepts(depId)
{
/*--[Depts.sql]------------------------------------------------------
Select
 Dep.Kod, Dep.NameAn
From
 MBVidAn As Z, MBAnalit As Dep
Where
 Z.Kod='' And Z.Vid=Dep.Vid And Dep.NomPodr=?
Order By 2
-------------------------------------------------------------------*/
 $.SQL.CommandText=readSnippet('Depts.sql');
 $.SQL(0)=depId;
 return fetchRs();
}

//
function sysInit()
{
 var lp, SQL;
 doIt('  Directum', function()
 { lp=new ActiveXObject("SBLogon.LoginPoint"); });

 doIt('   Directum', function()
 {
  $.Dir.App=lp.GetApplication("ServerName="+$.Dir.Server+
    ";DBName="+$.Dir.DB+";IsOSAuth=1");
 });

 doIt('  ', function()
 {
  $.Dir.Photo=!!$.Dir.App.ReferencesFactory..
    GetComponent().FindRequisite('');
 });

 doIt('   MS SQL', function()
 {
  SQL=new ActiveXObject("ADODB.Connection");
  SQL.Provider='SQLOLEDB';
  SQL.Open("Integrated Security=SSPI;Data Source="+$.Dir.Server);
  $.SQL=new ActiveXObject("ADODB.Command");
  $.SQL.ActiveConnection=SQL;
 });

 doIt('   MS SQL', function()
 {
  SQL.DefaultDatabase='['+$.Dir.DB+']';
 });

 doIt('  Active Directory', function()
 {
  $.AD={};
  $.AD.rootDSE=GetObject("LDAP://rootDSE");
  $.AD.baseDN=$.AD.rootDSE.Get('rootDomainNamingContext');

  $.AD.h=new ActiveXObject("ADODB.Connection");
  $.AD.h.Provider = "ADsDSOObject";
  $.AD.h.Open("Active Directory Provider");

  $.AD.cmd=new ActiveXObject("ADODB.Command");
  $.AD.cmd.ActiveConnection=$.AD.h;
  $.AD.cmd.Properties("Page Size")=1000;
  $.AD.cmd.Properties("Searchscope")=2; // ADS_SCOPE_SUBTREE
 });

 doIt('  Directum', function()
 {
/*--[user.sql]-------------------------------------------------------
Select U.Analit, U.Kod, X.UserKod, X.UserLogin, X.UserName
From MBAnalit As U, MBUser As X
Where
 U.Vid=(Select Vid from MBVidAn Where Kod='')
 And U.Dop=X.UserKod
 And X.UserStatus<>'' And X.UserType=''
 And X.UserCategory='' And X.NeedEncode='W'
 And U.Analit not In
    (Select Polzovatel From MBAnalit Where
     Polzovatel is not Null
     And Vid=(Select Vid from MBVidAn Where Kod=''))
-------------------------------------------------------------------*/
  $.SQL.CommandText=readSnippet('user.sql');
  $.u=sqlFetch();
 });

 doIt('   AD', function()
 {
  for(var i in $.u)
  {
   var u=$.u[i];
   u.AD=u2obj(u.UserLogin);
   WScript.Echo(u.UserKod, u.UserName, u.AD? u.AD.displayName:'-');
  }
 });

}

//--[Snippets]

/*--[html]-----------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>  ,   </title>

©  "", 2013

10

  Directum

   "Directum".  , :

        Active Directory

  SQL

<Input Type='Button' Value=' ! >> ' onClick='Welcome(this)' />

     Directum:

  ""

   (Ctrl+N)

  (   )

 -   (    )

,   "Windows-"

,     ""

     ""

!

-------------------------------------------------------------------*/

/*--[connect]--------------------------------------------------------

-------------------------------------------------------------------*/

//--[EOF]------------------------------------------------------------
<commit_msg>Do Depts search<commit_after>//
//
//

var $={Dir:{			// Global variable
    Server: 'Dir9',		// Directum server
    DB: 	'Directum'	// Directum database
}};

//goW();
$.doc=newDoc();
startPage();

while(!$.closed && !$.window.welcome) WScript.Sleep(300);

if($.closed) WScript.Quit();

changePage('connect');
$.window.startSpinner();
sysInit();
countDown();

//--[Functions]

//   wscript ( )
function goW()
{
 WScript.Interactive=false;

 if(WScript.FullName.replace(/^.*[\/\\]/, '').match(/^w/i)) return;
 (new ActiveXObject("WScript.Shell")).Run('wscript //B "'+
    WScript.ScriptFullName+'"', 0, false);
 WScript.Quit();
}

//    HTML-
function html(S)
{
 S=''+S;
 var E={'&':'amp', '>':'gt', '<':'lt', '"':'quot'};
 for(var Z in E)
   S=S.split(Z).join('&'+E[Z]+';');
 return S;
}

//  MSIE
function newDoc()
{
 var ie=WScript.CreateObject('InternetExplorer.Application');
 ie.AddressBar=false;
 ie.StatusBar=false;
 ie.ToolBar=false;
 ie.MenuBar=false;
 ie.Visible=true;
 ie.Navigate('about:blank');
 while(ie.Busy) WScript.Sleep(100);
 $.ie=ie;
 return ie.Document;
}

//
function startPage()
{
 $.doc.open();
 $.doc.write(readSnippet('html'));
 $.doc.close();

 $.window=$.doc.parentWindow;
 $.doc.body.onunload=function(){ $.closed=1; }
 $.interior=$.doc.getElementById('Interior');
}

//
function readSnippet(name)
{
 var f=WScript.CreateObject("Scripting.FileSystemObject").
    OpenTextFile(WScript.ScriptFullName, 1);	//ForReading
 var on, R='';
 while(!f.AtEndOfStream)
 {
  var s=f.ReadLine();
  if(!on)
  {
   if(s.match(/^\s*\/\*[-\s]*\[([.\w]+)\][-\s]+$/i) && (RegExp.$1==name)) on=1;
   continue;
  }
  if(s.match(/^[-\s]+\*\/\s*$/)) break;
  R+=s+'\n';
 }
 f.Close();
 return R;
}

//
function countDown()
{
 $.window.countDown($.ie);
 WScript.Quit();
}

//
function doIt(Name, Fun)
{
 if(!$.stepN)$.stepN=1;

 var S=$.window.newStep();
 var t=$.interior.getElementsByTagName('table')[0];
 var r=t.insertRow();
 var c=r.insertCell();
 c.innerHTML=($.stepN++)+'. '+Name;
 c.noWrap=1;
 (S.Time=r.insertCell()).innerHTML='0.0';
 S.Time.align='Right';
 (S.Res=r.insertCell()).innerHTML='
';
 $.window.Step=S;

 function updTime(Txt)
 {
  S.Res.innerHTML=Txt;
  $.window.Step=0;
  S.Time.innerHTML=(((new Date()).getTime()-S.ctime.getTime())/1000).toFixed(3);
 }

 try{
  Fun();
 }catch(e)
 {
  updTime(e.description);
  countDown();
 }
 if($.closed) WScript.Quit();
 updTime('Ok');
}

//
function changePage(N)
{
 $.interior.innerHTML=readSnippet(N);
}

function sqlFetch()
{
 var X=[];
 for(var Rs=$.SQL.Execute(); !Rs.EOF; Rs.MoveNext())
 {
  var r={};
  for(var E=new Enumerator(Rs.Fields); !E.atEnd(); E.moveNext())
   r[E.item().name]=E.item().value;
  X.push(r);
 }
 return X;
}

//      AD
function u2obj(u)
{
 $.AD.cmd.CommandText="<LDAP://"+$.AD.baseDN+
    ">;(&(objectCategory=user)(sAMAccountName="+
    u.replace(/[()*\\]/g, '\\$&')+"));*;subTree";
 var Rs=$.AD.cmd.Execute();
 if(!Rs.EOF) return GetObject(Rs(0).Value);
}

//     AD
function depID(user)
{
 if(!user) return;
 while(user=GetObject(user.Parent))
 {
  if(!user.ou) return;
  var i=user.l;
  if(!i) continue;
  if(!i.match(/^\d+$/)) return;
  return i;
 }
}

//
function findDepts(depId)
{
/*--[Depts.sql]------------------------------------------------------
Select
 Dep.Kod, Dep.NameAn
From
 MBVidAn As Z, MBAnalit As Dep
Where
 Z.Kod='' And Z.Vid=Dep.Vid And Dep.NomPodr=?
Order By 2
-------------------------------------------------------------------*/
 $.SQL.CommandText=readSnippet('Depts.sql');
 $.SQL(0)=depId;
 return sqlFetch();
}

//
function sysInit()
{
 var lp, SQL;
 doIt('  Directum', function()
 { lp=new ActiveXObject("SBLogon.LoginPoint"); });

 doIt('   Directum', function()
 {
  $.Dir.App=lp.GetApplication("ServerName="+$.Dir.Server+
    ";DBName="+$.Dir.DB+";IsOSAuth=1");
 });

 doIt('  ', function()
 {
  $.Dir.Photo=!!$.Dir.App.ReferencesFactory..
    GetComponent().FindRequisite('');
 });

 doIt('   MS SQL', function()
 {
  SQL=new ActiveXObject("ADODB.Connection");
  SQL.Provider='SQLOLEDB';
  SQL.Open("Integrated Security=SSPI;Data Source="+$.Dir.Server);
  $.SQL=new ActiveXObject("ADODB.Command");
  $.SQL.ActiveConnection=SQL;
 });

 doIt('   MS SQL', function()
 {
  SQL.DefaultDatabase='['+$.Dir.DB+']';
 });

 doIt('  Active Directory', function()
 {
  $.AD={};
  $.AD.rootDSE=GetObject("LDAP://rootDSE");
  $.AD.baseDN=$.AD.rootDSE.Get('rootDomainNamingContext');

  $.AD.h=new ActiveXObject("ADODB.Connection");
  $.AD.h.Provider = "ADsDSOObject";
  $.AD.h.Open("Active Directory Provider");

  $.AD.cmd=new ActiveXObject("ADODB.Command");
  $.AD.cmd.ActiveConnection=$.AD.h;
  $.AD.cmd.Properties("Page Size")=1000;
  $.AD.cmd.Properties("Searchscope")=2; // ADS_SCOPE_SUBTREE
 });

 doIt('  Directum', function()
 {
/*--[user.sql]-------------------------------------------------------
Select U.Analit, U.Kod, X.UserKod, X.UserLogin, X.UserName
From MBAnalit As U, MBUser As X
Where
 U.Vid=(Select Vid from MBVidAn Where Kod='')
 And U.Dop=X.UserKod
 And X.UserStatus<>'' And X.UserType=''
 And X.UserCategory='' And X.NeedEncode='W'
 And U.Analit not In
    (Select Polzovatel From MBAnalit Where
     Polzovatel is not Null
     And Vid=(Select Vid from MBVidAn Where Kod=''))
-------------------------------------------------------------------*/
  $.SQL.CommandText=readSnippet('user.sql');
  $.u=sqlFetch();
 });

 doIt('   AD', function()
 {
  for(var i in $.u)
  {
   var u=$.u[i];
   u.AD=u2obj(u.UserLogin);
  }
 });

 doIt(' ', function()
 {
  for(var i in $.u)
  {
   var u=$.u[i];
   u.Dept=depID(u.AD);
   u.Depts=u.Dept? findDepts(u.Dept) : [];
   WScript.Echo(u.UserKod, u.UserName, u.AD? u.AD.displayName:'-', u.Dept, u.Depts.length);
  }
 });

}

//--[Snippets]

/*--[html]-----------------------------------------------------------
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<title>  ,   </title>

©  "", 2013

10

  Directum

   "Directum".  , :

        Active Directory

  SQL

<Input Type='Button' Value=' ! >> ' onClick='Welcome(this)' />

     Directum:

  ""

   (Ctrl+N)

  (   )

 -   (    )

,   "Windows-"

,     ""

     ""

!

-------------------------------------------------------------------*/

/*--[connect]--------------------------------------------------------

-------------------------------------------------------------------*/

//--[EOF]------------------------------------------------------------
<|endoftext|>


<commit_before>QUnit.test("hello test", function(assert) {
    assert.ok(1 == "1", "Passed!");
});

QUnit.test("example PriorityQueue.MIN_HEAP", function(assert) {
    var p = new PriorityQueue("value", PriorityQueue.MIN_HEAP);

    var object1 = {};
    var object2 = {};
    var object3 = {};
    var object4 = {};

    object1.value = 5;
    object2.value = 10;
    object3.value = 20;
    object4.value = 15;

    p.insert(object1);
    p.insert(object2);
    p.insert(object3);
    p.insert(object4);

    assert.equal(p.peek(), object1);
    assert.equal(p.shiftHighestPriorityElement(), object1);

    assert.equal(p.peek(), object2);
    assert.equal(p.shiftHighestPriorityElement(), object2);

    assert.equal(p.peek(), object4);
    assert.equal(p.shiftHighestPriorityElement(), object4);

    assert.equal(p.peek(), object3);
    assert.equal(p.shiftHighestPriorityElement(), object3);

    assert.equal(p.length, 0);

});

QUnit.test("example 1 PriorityQueue.MIN_HEAP", function(assert) {
    var p = new PriorityQueue("value", PriorityQueue.MIN_HEAP);

    var object1 = {};
    var object2 = {};

    object1.value = 10;
    object2.value = 5;

    p.insert(object1);
    assert.equal(p.peek(), object1);

    p.insert(object2);
    assert.equal(p.peek(), object2);

    assert.equal(p.shiftHighestPriorityElement(), object2);

});

QUnit.test("reverse PriorityQueue.MIN_HEAP", function(assert) {
    var p = new PriorityQueue("value", PriorityQueue.MIN_HEAP);

    var object1 = {};
    var object2 = {};
    var object3 = {};
    // var object4 = {};

    object1.value = 20;
    object2.value = 15;
    object3.value = 10;
    // object4.value = 5;

    p.add(object1);
    assert.equal(p.peek(), object1);
    p.add(object2);
    assert.equal(p.peek(), object2);
    p.add(object3);
    // p.insert(object4);

    // assert.equal(p.peek(), object4);
    // assert.equal(p.shiftHighestPriorityElement(), object4);

    assert.equal(p.peek(), object3);
    assert.equal(p.shiftHighestPriorityElement(), object3);

    assert.equal(p.peek(), object2);
    assert.equal(p.shiftHighestPriorityElement(), object2);

    assert.equal(p.peek(), object1);
    assert.equal(p.shiftHighestPriorityElement(), object1);

    assert.equal(p.length, 0);

});

QUnit.test("PriorityQueue.MIN_HEAP", function(assert) {

    var pq = new PriorityQueue('state', PriorityQueue.MIN_HEAP);
    var zero = {};
    zero.state = 10;

    // console.log(zero);

    var one = {};
    one.state = 20;
    // console.log(one);

    var two = {};
    two.state = 30;

    // console.log(two);

    // console.log('adding first element');
    pq.add(two);
    // console.log(pq);
    assert.equal(pq.peek().state, 30, "make sure 30 is on the top");

    // console.log('adding second element');
    pq.add(one);
    // console.log(pq);
    // console.log(pq.peek());
    assert.equal(pq.peek().state, 20, "make sure 20 is on the top");

    // console.log('adding third element');
    pq.add(zero);
    // console.log(pq);

    assert.equal(pq.peek().state, 10, "make sure 10 is on the top");
});

QUnit.test("deepEqual", function(assert) {
    function State(_node) {
        this.node = _node;
    }
    var one = new State(1);
    var one1 = new State(1);
    assert.deepEqual({
        'node': 1
    }, {
        'node': 1
    }, 'object type the same:object');

    assert.deepEqual(one, one1, 'object type the same:State');
    assert.notDeepEqual(one, {
        'node': 1
    }, 'object type checked');
});

QUnit.test("node equality", function(assert) {
    assert.ok(new Node({
        'state': 1
    }).isEqual(new Node({
        'state': 1
    })), "1==1");
    assert.ok(!new Node({
        'state': 1
    }).isEqual(new Node({
        'state': 2
    })), "1==2");

});

QUnit.test("model validation", function(assert) {
    assert.throws(function() {
        new AStar();
    }, "no model provided", "no model provided");
    assert.throws(function() {
        new AStar({});
    }, /model missing attributes:/, "model missing attributes");
    assert.ok(new AStar({
        'getActions': function() {
            // mock
        },
        'hScore': function() {
            // mock
        },
        'atGoal': function() {
            return false;
        },
        'keepSearching': function() {
            return false;
        },
        'gScore': function() {
            // mock
        },

        'setState': function() {
            // mock
        },
        'getState': function() {
            // mock
            return new Node({});
        }
    }), "mock model");
});

QUnit.test("time constraint", function(assert) {
    var foo = true;
    var mock_model = {
        'start': Date.now(),
        'getActions': function() {
            // mock
            if (foo) {
                foo = false;
                return [{
                    'state': Math.random(),
                    'action': Math.random()
                }, {
                    'state': Math.random(),
                    'action': Math.random()
                }];
            } else {
                return [{
                    'state': Math.random(),
                    'action': Math.random()
                }];
            }
        },
        'hScore': function() {
            // mock
        },
        'atGoal': function() {
            return false;
        },
        'keepSearching': function() {
            console.log(Date.now() - this.start);
            return Date.now() - this.start <= 2000;
        },
        'gScore': function() {
            // mock
        },
        'setState': function() {
            // mock
            return this;
        },
        'getState': function() {
            // mock
            return 0;
        }
    };
    assert.ok(new AStar(mock_model).search(), "time constraint");
});

QUnit.test("2 node/one step model search", function(assert) {
    function AI() {
        this._state = 0;
        this.getActions = function() {
            // mock
            if (this._state == 0) {
                return [{
                    'action': 1,
                    'state': 1
                }];
            }
            return [];
        };
        this.hScore = function() {
            // mock
            return 0;
        };

        this.atGoal = function() {
            return this._state === 1;
        };
        this.keepSearching = function() {
            return true;
        };
        this.gScore = function() {
            // mock
            return 0;
        };

        this.setState = function(state) {
            // mock
            this._state = state;
            return this;
        };
        this.getState = function() {
            // mock
            return this._state;
        };

    }

    // console.log([ 0, 1 ]);
    // console.log(new AStar(new AI()).search());
    assert.deepEqual(new AStar(new AI()).search(), [1],
            "2 node/one step model search");
});

QUnit.test("3 node/one step/dead-end model search", function(assert) {
    function AI() {
        this._state = 0;
        this.getActions = function() {
            // mock
            if (this._state == 0) {
                return [{
                    'action': 1,
                    'state': 1
                }, {
                    'action': 2,
                    'state': 2
                }];
            }
            return [];
        };
        this.hScore = function() {
            // mock
        };
        this.atGoal = function() {
            return this._state === 2;
        };
        this.keepSearching = function() {
            return true;
        };
        this.gScore = function() {
            // mock
        };

        this.setState = function(state) {
            // mock
            this._state = state;
            return this;
        };
        this.getState = function() {
            // mock
            return this._state;
        };
    }
    assert.deepEqual(new AStar(new AI()).search(), [2],
            "3 node/one step/dead-end model search");
});

QUnit.test("4 node/2 step/dead-end model search", function(assert) {
    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);

    function AI(_state) {
        // private, use getter and setter methods
        this._state = _state;

        this.getActions = function() {

            // mock
            switch (this._state.node) {
            case 0:
                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];
            case 2:

                return [{
                    'action': three,
                    'state': three
                }];
            }
            return [];
        };
        this.hScore = function() {
            // mock
        };

        this.atGoal = function() {
            return this._state.node === three.node;
        };
        this.keepSearching = function() {
            return true;
        };
        this.gScore = function() {
            // mock
        };
        this.setState = function(state) {
            // mock
            this._state = state;
            return this;
        };
        this.getState = function() {
            return this._state;
        };
    }
    // console.log([ { 'node' : 0 }, { 'node' : 2 }, { 'node' : 3 } ]);

    // console.log(new AStar(new AI(zero)));
    // return;
    assert.deepEqual(new AStar(new AI(zero)).search(), [two, three],
            "4 node/2 step/dead-end model search");
});

QUnit.test("diamond:first path is shorter", function(assert) {

    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);

    // a mock up of thediskgame.AI
    // the AI is responsible for creating new world/game states
    function AI(state) {
        this._state = state;
        // returns an array of objects
        // each object contains 3 attributes: the 'action' to get to the new
        // state, the 'args' for the function in the first argument,
        // and the 'state' resulting from calling the 'action' with the 'args'
        this.getActions = function() {
            // mock
            switch (this._state.node) {
            case 0:

                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];
            case 1:
            case 2:
                return [{
                    'action': three,
                    'state': three
                }];

            default:
                return [];
            }
        };
        // h, heuristic, estimated cost from the node to the goal
        this.hScore = function() {
            switch (this._state.node) {
            case 0:
                return 10;
            case 1:
                return 4;
            case 2:
                return 5;
            }
            // mock
        };
        this.atGoal = function() {
            return this._state.node === three.node;
        };
        this.keepSearching = function() {
            return true;
        };
        // actual cost from start to current node
        this.gScore = function() {
            // mock
        };

        this.setState = function(_state) {
            // mock
            this._state = _state;
            return this;
        };
        this.getState = function() {
            return this._state;
        };
    }
    assert.deepEqual(new AStar(new AI(zero)).search(), [one, three],
            "diamond:first path is shorter");
});

QUnit.test("diamond:second path is shorter", function(assert) {

    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);

    function AI(state) {
        this._state = state;
        this.getActions = function() {
            // mock
            switch (this._state.node) {
            case 0:
                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];

                // both nodes 1 and 2 go to 3
            case 1:
            case 2:
                return [{
                    'action': three,
                    'state': three
                }];
            default:
                return [];
            }
        };
        // h, heuristic, estimated cost from the node to the goal
        this.hScore = function() {
            // console.log(this._state.node);
            switch (this._state.node) {
            case 0:
                return 10;
            case 1:
                return 5;
            case 2:
                return 4;
            }
            // mock
        };
        this.setState = function(_state) {
            // console.log(_state);
            // mock
            this._state = _state;
            // console.log(this._state);
            return this;
        };
        this.getState = function() {
            return this._state;
        };
        this.keepSearching = function() {
            return true;
        };
        this.atGoal = function() {
            return this._state.node === three.node;
        };
        // actual cost from start to current node
        this.gScore = function() {
            // mock
            return 0;
        };

    }

    assert.deepEqual(new AStar(new AI(zero)).search(), [two, three],
            "diamond:second path is shorter");
});

QUnit.test("no path to goal", function(assert) {

    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);
    var four = new State(4);

    function AI(state) {
        this._state = state;
        this.getActions = function() {
            // mock
            switch (this._state.node) {
            case 0:
                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];

                // both nodes 1 and 2 go to 3
            case 1:
            case 2:
                return [{
                    'action': three,
                    'state': three
                }];
            default:
                return [];
            }
        };
        // h, heuristic, estimated cost from the node to the goal
        this.hScore = function() {
            // console.log(this._state.node);
            switch (this._state.node) {
            case 0:
                return 10;
            case 1:
                return 5;
            case 2:
                return 4;
            case 3:
                return 1;
            }
            // mock
        };
        this.setState = function(_state) {
            // console.log(_state);
            // mock
            this._state = _state;
            // console.log(this._state);
            return this;
        };
        this.getState = function() {
            return this._state;
        };
        this.keepSearching = function() {
            return true;
        };
        this.atGoal = function() {
            return this._state.node === four.node;
        };
        // actual cost from start to current node
        this.gScore = function() {
            // mock
            switch (this._state.node) {
            case 0:
                return 0;
            case 1:
                return 5;
            case 2:
                return 4;
            case 3:
                return 1;
            }
        };
    }
    assert.deepEqual(new AStar(new AI(zero)).search(), [two, three],
            "no path to goal");
});
<commit_msg>test cases<commit_after>QUnit.test("hello test", function(assert) {
    assert.ok(1 == "1", "Passed!");
});

QUnit.test("example PriorityQueue.MIN_HEAP", function(assert) {
    var p = new PriorityQueue("value", PriorityQueue.MIN_HEAP);

    var object1 = {};
    var object2 = {};
    var object3 = {};
    var object4 = {};

    object1.value = 5;
    object2.value = 10;
    object3.value = 20;
    object4.value = 15;

    p.insert(object1);
    p.insert(object2);
    p.insert(object3);
    p.insert(object4);

    assert.equal(p.peek(), object1);
    assert.equal(p.shiftHighestPriorityElement(), object1);

    assert.equal(p.peek(), object2);
    assert.equal(p.shiftHighestPriorityElement(), object2);

    assert.equal(p.peek(), object4);
    assert.equal(p.shiftHighestPriorityElement(), object4);

    assert.equal(p.peek(), object3);
    assert.equal(p.shiftHighestPriorityElement(), object3);

    assert.equal(p.length, 0);

});

QUnit.test("example 1 PriorityQueue.MIN_HEAP", function(assert) {
    var p = new PriorityQueue("value", PriorityQueue.MIN_HEAP);

    var object1 = {};
    var object2 = {};

    object1.value = 10;
    object2.value = 5;

    p.insert(object1);
    assert.equal(p.peek(), object1);

    p.insert(object2);
    assert.equal(p.peek(), object2);

    assert.equal(p.shiftHighestPriorityElement(), object2);

});

QUnit.test("reverse PriorityQueue.MIN_HEAP", function(assert) {
    var p = new PriorityQueue("value", PriorityQueue.MIN_HEAP);

    var object1 = {};
    var object2 = {};
    var object3 = {};
    // var object4 = {};

    object1.value = 20;
    object2.value = 15;
    object3.value = 10;
    // object4.value = 5;

    p.add(object1);
    assert.equal(p.peek(), object1);
    p.add(object2);
    assert.equal(p.peek(), object2);
    p.add(object3);
    // p.insert(object4);

    // assert.equal(p.peek(), object4);
    // assert.equal(p.shiftHighestPriorityElement(), object4);

    assert.equal(p.peek(), object3);
    assert.equal(p.shiftHighestPriorityElement(), object3);

    assert.equal(p.peek(), object2);
    assert.equal(p.shiftHighestPriorityElement(), object2);

    assert.equal(p.peek(), object1);
    assert.equal(p.shiftHighestPriorityElement(), object1);

    assert.equal(p.length, 0);

});

QUnit.test("PriorityQueue.MIN_HEAP", function(assert) {

    var pq = new PriorityQueue('state', PriorityQueue.MIN_HEAP);
    var zero = {};
    zero.state = 10;

    // console.log(zero);

    var one = {};
    one.state = 20;
    // console.log(one);

    var two = {};
    two.state = 30;

    // console.log(two);

    // console.log('adding first element');
    pq.add(two);
    // console.log(pq);
    assert.equal(pq.peek().state, 30, "make sure 30 is on the top");

    // console.log('adding second element');
    pq.add(one);
    // console.log(pq);
    // console.log(pq.peek());
    assert.equal(pq.peek().state, 20, "make sure 20 is on the top");

    // console.log('adding third element');
    pq.add(zero);
    // console.log(pq);

    assert.equal(pq.peek().state, 10, "make sure 10 is on the top");
});

QUnit.test("deepEqual", function(assert) {
    function State(_node) {
        this.node = _node;
    }
    var one = new State(1);
    var one1 = new State(1);
    assert.deepEqual({
        'node': 1
    }, {
        'node': 1
    }, 'object type the same:object');

    assert.deepEqual(one, one1, 'object type the same:State');
    assert.notDeepEqual(one, {
        'node': 1
    }, 'object type checked');
});

QUnit.test("node equality", function(assert) {
    assert.ok(new Node({
        'state': 1
    }).isEqual(new Node({
        'state': 1
    })), "1==1");
    assert.ok(!new Node({
        'state': 1
    }).isEqual(new Node({
        'state': 2
    })), "1==2");

});

QUnit.test("multi value sorting", function(assert) {
    var pq = new PriorityQueue('compareTo', PriorityQueue.MIN_HEAP);
    function o(_a, _b) {
        this.a = _a;
        this.b = _b;
        this.compareTo = function(that) {
            if (this.a < that.a) {
                return -1;
            } else if (this.a > that.a) {
                return 1;
            } else {
                if (this.b < that.b) {
                    return -1;
                } else if (this.b > that.b) {
                    return 1;
                }
            }
            return 0;
        };
    }
    var one = new o(1, 1);
    var two = new o(1, 0);

    var three = new o(0, 1);
    pq.add(one);
    assert.equal(pq.peek(), one, 'single node');

    pq.add(two);
    assert.equal(pq.peek(), two, '2 nodes');

    pq.add(three);
    assert.equal(pq.peek(), three, '3 nodes');

});

QUnit.test("model validation", function(assert) {
    assert.throws(function() {
        new AStar();
    }, "no model provided", "no model provided");
    assert.throws(function() {
        new AStar({});
    }, /model missing attributes:/, "model missing attributes");
    assert.ok(new AStar({
        'getActions': function() {
            // mock
        },
        'hScore': function() {
            // mock
        },
        'atGoal': function() {
            return false;
        },
        'keepSearching': function() {
            return false;
        },
        'gScore': function() {
            // mock
        },

        'setState': function() {
            // mock
        },
        'getState': function() {
            // mock
            return new Node({});
        }
    }), "mock model");
});

QUnit.test("time constraint", function(assert) {
    var foo = true;
    var mock_model = {
        'start': Date.now(),
        'getActions': function() {
            // mock
            if (foo) {
                foo = false;
                return [{
                    'state': Math.random(),
                    'action': Math.random()
                }, {
                    'state': Math.random(),
                    'action': Math.random()
                }];
            } else {
                return [{
                    'state': Math.random(),
                    'action': Math.random()
                }];
            }
        },
        'hScore': function() {
            // mock
        },
        'atGoal': function() {
            return false;
        },
        'keepSearching': function() {
            console.log(Date.now() - this.start);
            return Date.now() - this.start <= 2000;
        },
        'gScore': function() {
            // mock
        },
        'setState': function() {
            // mock
            return this;
        },
        'getState': function() {
            // mock
            return 0;
        }
    };
    assert.ok(new AStar(mock_model).search(), "time constraint");
});

QUnit.test("2 node/one step model search", function(assert) {
    function AI() {
        this._state = 0;
        this.getActions = function() {
            // mock
            if (this._state == 0) {
                return [{
                    'action': 1,
                    'state': 1
                }];
            }
            return [];
        };
        this.hScore = function() {
            // mock
            return 0;
        };

        this.atGoal = function() {
            return this._state === 1;
        };
        this.keepSearching = function() {
            return true;
        };
        this.gScore = function() {
            // mock
            return 0;
        };

        this.setState = function(state) {
            // mock
            this._state = state;
            return this;
        };
        this.getState = function() {
            // mock
            return this._state;
        };

    }

    // console.log([ 0, 1 ]);
    // console.log(new AStar(new AI()).search());
    assert.deepEqual(new AStar(new AI()).search(), [1],
            "2 node/one step model search");
});

QUnit.test("3 node/one step/dead-end model search", function(assert) {
    function AI() {
        this._state = 0;
        this.getActions = function() {
            // mock
            if (this._state == 0) {
                return [{
                    'action': 1,
                    'state': 1
                }, {
                    'action': 2,
                    'state': 2
                }];
            }
            return [];
        };
        this.hScore = function() {
            // mock
        };
        this.atGoal = function() {
            return this._state === 2;
        };
        this.keepSearching = function() {
            return true;
        };
        this.gScore = function() {
            // mock
        };

        this.setState = function(state) {
            // mock
            this._state = state;
            return this;
        };
        this.getState = function() {
            // mock
            return this._state;
        };
    }
    assert.deepEqual(new AStar(new AI()).search(), [2],
            "3 node/one step/dead-end model search");
});

QUnit.test("4 node/2 step/dead-end model search", function(assert) {
    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);

    function AI(_state) {
        // private, use getter and setter methods
        this._state = _state;

        this.getActions = function() {

            // mock
            switch (this._state.node) {
            case 0:
                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];
            case 2:

                return [{
                    'action': three,
                    'state': three
                }];
            }
            return [];
        };
        this.hScore = function() {
            // mock
        };

        this.atGoal = function() {
            return this._state.node === three.node;
        };
        this.keepSearching = function() {
            return true;
        };
        this.gScore = function() {
            // mock
        };
        this.setState = function(state) {
            // mock
            this._state = state;
            return this;
        };
        this.getState = function() {
            return this._state;
        };
    }
    // console.log([ { 'node' : 0 }, { 'node' : 2 }, { 'node' : 3 } ]);

    // console.log(new AStar(new AI(zero)));
    // return;
    assert.deepEqual(new AStar(new AI(zero)).search(), [two, three],
            "4 node/2 step/dead-end model search");
});

QUnit.test("diamond:first path is shorter", function(assert) {

    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);

    // a mock up of thediskgame.AI
    // the AI is responsible for creating new world/game states
    function AI(state) {
        this._state = state;
        // returns an array of objects
        // each object contains 3 attributes: the 'action' to get to the new
        // state, the 'args' for the function in the first argument,
        // and the 'state' resulting from calling the 'action' with the 'args'
        this.getActions = function() {
            // mock
            switch (this._state.node) {
            case 0:

                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];
            case 1:
            case 2:
                return [{
                    'action': three,
                    'state': three
                }];

            default:
                return [];
            }
        };
        // h, heuristic, estimated cost from the node to the goal
        this.hScore = function() {
            switch (this._state.node) {
            case 0:
                return 10;
            case 1:
                return 4;
            case 2:
                return 5;
            }
            // mock
        };
        this.atGoal = function() {
            return this._state.node === three.node;
        };
        this.keepSearching = function() {
            return true;
        };
        // actual cost from start to current node
        this.gScore = function() {
            // mock
        };

        this.setState = function(_state) {
            // mock
            this._state = _state;
            return this;
        };
        this.getState = function() {
            return this._state;
        };
    }
    assert.deepEqual(new AStar(new AI(zero)).search(), [one, three],
            "diamond:first path is shorter");
});

QUnit.test("diamond:second path is shorter", function(assert) {

    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);

    function AI(state) {
        this._state = state;
        this.getActions = function() {
            // mock
            switch (this._state.node) {
            case 0:
                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];

                // both nodes 1 and 2 go to 3
            case 1:
            case 2:
                return [{
                    'action': three,
                    'state': three
                }];
            default:
                return [];
            }
        };
        // h, heuristic, estimated cost from the node to the goal
        this.hScore = function() {
            // console.log(this._state.node);
            switch (this._state.node) {
            case 0:
                return 10;
            case 1:
                return 5;
            case 2:
                return 4;
            }
            // mock
        };
        this.setState = function(_state) {
            // console.log(_state);
            // mock
            this._state = _state;
            // console.log(this._state);
            return this;
        };
        this.getState = function() {
            return this._state;
        };
        this.keepSearching = function() {
            return true;
        };
        this.atGoal = function() {
            return this._state.node === three.node;
        };
        // actual cost from start to current node
        this.gScore = function() {
            // mock
            return 0;
        };

    }

    assert.deepEqual(new AStar(new AI(zero)).search(), [two, three],
            "diamond:second path is shorter");
});

QUnit.test("no path to goal", function(assert) {

    function State(_node) {
        this.node = _node;
    }
    var zero = new State(0);
    var one = new State(1);
    var two = new State(2);
    var three = new State(3);
    var four = new State(4);

    function AI(state) {
        this._state = state;
        this.getActions = function() {
            // mock
            switch (this._state.node) {
            case 0:
                return [{
                    'action': one,
                    'state': one
                }, {
                    'action': two,
                    'state': two
                }];

                // both nodes 1 and 2 go to 3
            case 1:
            case 2:
                return [{
                    'action': three,
                    'state': three
                }];
            default:
                return [];
            }
        };
        // h, heuristic, estimated cost from the node to the goal
        this.hScore = function() {
            // console.log(this._state.node);
            switch (this._state.node) {
            case 0:
                return 10;
            case 1:
                return 5;
            case 2:
                return 4;
            case 3:
                return 1;
            }
            // mock
        };
        this.setState = function(_state) {
            // console.log(_state);
            // mock
            this._state = _state;
            // console.log(this._state);
            return this;
        };
        this.getState = function() {
            return this._state;
        };
        this.keepSearching = function() {
            return true;
        };
        this.atGoal = function() {
            return this._state.node === four.node;
        };
        // actual cost from start to current node
        this.gScore = function() {
            // mock
            switch (this._state.node) {
            case 0:
                return 0;
            case 1:
                return 5;
            case 2:
                return 4;
            case 3:
                return 1;
            }
        };
    }
    assert.deepEqual(new AStar(new AI(zero)).search(), [two, three],
            "no path to goal");
});
<|endoftext|>


<commit_before>ide.editor = (function() {
  var Editor = function(aceId, settings) {
    this.editor = createAceEditor(aceId, settings);
    this.settings = settings;

    this.addKeyboardShortcut('save', 'Ctrl-S', function() {
      this.saveFile(this.tabs.selectedTab());
    }.bind(this));
    this.addKeyboardShortcut('save-all', 'Ctrl-Shift-S', function() {
      this.tabs.tabs().forEach(this.saveFile.bind(this));
    }.bind(this));

    this.sessions = {};
    this.asts = {};
    this.tabs = new ide.tabs.TabsViewModel()
      .on('all_tabs_closed', function() {
        this.visible(false);
      }.bind(this))
      .on('tab_select', this.selectFile.bind(this))
      .on('tab_save', this.saveFile.bind(this));

    this.editor.on('change', function () {
      this.tabs.selectedTab().dirty(true);
    }.bind(this));

    this.editor.on('click', function(e) {
      this.editor.getSelection().toSingleRange();
      if (!e.getAccelKey()) {
        return;
      }
      if (!this.hasAst()) {
        ide.utils.flashError('There are parse errors.');
        return;
      }
      var token = this.getTokenFromMouseEvent(e);
      if (this.isFunctionCall(token)) {
        this.trigger('function_call_clicked', token);
      }
    }.bind(this));

    this.visible = ko.observable(false);
  };

  var createAceEditor = function(el, settings) {
    var editor = ace.edit(el);
    editor.setTheme('ace/theme/' + settings.theme);
    editor.setFontSize(14);
    editor.setShowPrintMargin(false);
    if (settings.keybindings === 'vim') {
      editor.setKeyboardHandler('ace/keyboard/vim');
    } else if (settings.keybindings === 'emacs') {
      editor.setKeyboardHandler('ace/keyboard/emacs');
    }

    editor.resize();
    editor.focus();
    return editor;
  };

  var createEditSession = function(text, settings) {
    var session = ace.createEditSession(text, 'ace/mode/matlab');
    session.setUseSoftTabs(settings.expand_tabs);
    session.setTabSize(settings.tab_width);
    return session;
  };

  Editor.prototype.selectLine = function(line) {
    var Range = ace.require('ace/range').Range;
    var selection = this.editor.selection;
    selection.setSelectionRange(new Range(line - 1, 0, line - 1, 0));
    selection.selectLineStart();
    selection.selectLineEnd();
  }

  Editor.prototype.createSession = function(path, text) {
    this.sessions[path] = createEditSession(text, this.settings);
  };

  Editor.prototype.addKeyboardShortcut = function(name, key, action) {
    var bindKey = key;
    if (bindKey.indexOf('Ctrl') !== -1) {
      bindKey = {win: key, mac: key.replace('Ctrl', 'Command')};
    }
    this.editor.commands.addCommand({
      name: name,
      bindKey: bindKey,
      exec: action,
    });
  };

  Editor.prototype.openFile = function(path, callback) {
    if (_(this.sessions).has(path)) {
      this.tabs.openTab(path);
      if (callback) {
        callback();
      }
      return;
    }
    ide.ajax.readFile(path, function (contents) {
      this.createSession(path, contents);
      this.tabs.openTab(path);
      this.tryParse();
      if (callback) {
        callback();
      }
    }.bind(this));
  };

  Editor.prototype.selectFile = function(tab) {
    var path = tab.name();
    if (!_(this.sessions).has(path)) {
      this.createSession(path, '');
    }
    this.editor.setSession(this.sessions[path]);
    this.visible(true);
  };

  Editor.prototype.saveFile = function(tab) {
    var path = tab.name();
    ide.ajax.writeFile(path, this.sessions[path].getValue());
    tab.dirty(false);
  }

  var renameKey = function(object, oldKey, newKey) {
    if (_(object).has(oldKey)) {
      object[newKey] = object[oldKey];
      delete object[oldKey];
    }
  };

  var removeKey = function(object, key) {
    if (_(object).has(key)) {
      delete object[key];
    }
  };

  Editor.prototype.hasDirtyTab = function(path) {
    var tab = this.tabs.findByName(path);
    return tab && tab.dirty();
  };

  Editor.prototype.renameFile = function(oldPath, newPath) {
    var tab = this.tabs.findByName(oldPath);
    if (tab) {
      tab.name(newPath);
    }
    renameKey(this.sessions, oldPath, newPath);
    renameKey(this.asts, oldPath, newPath);
  };

  Editor.prototype.deleteFile = function(path) {
    var tab = this.tabs.findByName(path);
    if (tab) {
      this.tabs.forceCloseTab(tab);
    }
    removeKey(this.sessions, path);
    removeKey(this.asts, path);
  };

  Editor.prototype.jumpTo = function(token) {
    this.openFile(token.file, function () {
     this.editor.getSelection().moveTo(token.line - 1, token.col - 1);
    }.bind(this));
  };

  Editor.prototype.getTokenFromMouseEvent = function(e) {
    var MouseEvent = ace.require('ace/mouse/mouse_event').MouseEvent;
    if (!(e instanceof MouseEvent)) {
      e = new MouseEvent(e, this.editor);
    }
    var position = e.getDocumentPosition();
    var token = this.editor.getSession().getTokenAt(position.row, position.column);
    return {
      identifier: token.value,
      file: this.tabs.selectedTab().name(),
      line: position.row + 1,
      col: token.start + 1
    };
  };

  Editor.prototype.getSelectionRange = function() {
    var range = this.editor.getSelection().getRange();
    return {
      startLine: range.start.row + 1,
      startColumn: range.start.column + 1,
      endLine: range.end.row + 1,
      endColumn: range.end.column + 1,
    };
  };

  Editor.prototype.isFunctionCall = function(token) {
    return this.getAst()
      .findAtPosition('NameExpr', token)
      .isFunctionCall();
  };

  Editor.prototype.hasAst = function() {
    return _(this.asts).has(this.tabs.selectedTab().name());
  };

  Editor.prototype.getAst = function() {
    return this.asts[this.tabs.selectedTab().name()];
  };

  Editor.prototype.clearErrors = function() {
    this.overlayErrors([]);
  };

  Editor.prototype.overlayErrors = function(errors) {
    this.editor.getSession().setAnnotations(
      errors.map(function (err) {
        return {
          row: err.line - 1,
          column: err.col - 1,
          text: err.message,
          type: 'error'
        };
      })
    );
  };

  Editor.prototype.tryParse = function() {
    ide.ast.parse(this.editor.getValue(),
      function (ast) {
        this.clearErrors();
        this.asts[this.tabs.selectedTab().name()] = ast;
      }.bind(this),
      function (errors) {
        this.overlayErrors(errors);
        delete this.asts[this.tabs.selectedTab().name()];
      }.bind(this));
  };

  Editor.prototype.startSyntaxChecker = function() {
    var typingTimer = null;
    var doneTypingInterval = 1000;

    var doneTyping = function() {
      this.tryParse();
      typingTimer = null;
    }.bind(this);

    this.editor.on('change', function() {
      if (typingTimer !== null) {
        clearTimeout(typingTimer);
        typingTimer = null;
      }
      typingTimer = setTimeout(doneTyping, doneTypingInterval);
    });
  };

  _.extend(Editor.prototype, ide.utils.EventsMixin);

  return {
    Editor: Editor
  };
})();
<commit_msg>Use _.debounce to simplify syntax checking.<commit_after>ide.editor = (function() {
  var Editor = function(aceId, settings) {
    this.editor = createAceEditor(aceId, settings);
    this.settings = settings;

    this.addKeyboardShortcut('save', 'Ctrl-S', function() {
      this.saveFile(this.tabs.selectedTab());
    }.bind(this));
    this.addKeyboardShortcut('save-all', 'Ctrl-Shift-S', function() {
      this.tabs.tabs().forEach(this.saveFile.bind(this));
    }.bind(this));

    this.sessions = {};
    this.asts = {};
    this.tabs = new ide.tabs.TabsViewModel()
      .on('all_tabs_closed', function() {
        this.visible(false);
      }.bind(this))
      .on('tab_select', this.selectFile.bind(this))
      .on('tab_save', this.saveFile.bind(this));

    this.editor.on('change', function () {
      this.tabs.selectedTab().dirty(true);
    }.bind(this));

    this.editor.on('click', function(e) {
      this.editor.getSelection().toSingleRange();
      if (!e.getAccelKey()) {
        return;
      }
      if (!this.hasAst()) {
        ide.utils.flashError('There are parse errors.');
        return;
      }
      var token = this.getTokenFromMouseEvent(e);
      if (this.isFunctionCall(token)) {
        this.trigger('function_call_clicked', token);
      }
    }.bind(this));

    this.visible = ko.observable(false);
  };

  var createAceEditor = function(el, settings) {
    var editor = ace.edit(el);
    editor.setTheme('ace/theme/' + settings.theme);
    editor.setFontSize(14);
    editor.setShowPrintMargin(false);
    if (settings.keybindings === 'vim') {
      editor.setKeyboardHandler('ace/keyboard/vim');
    } else if (settings.keybindings === 'emacs') {
      editor.setKeyboardHandler('ace/keyboard/emacs');
    }

    editor.resize();
    editor.focus();
    return editor;
  };

  var createEditSession = function(text, settings) {
    var session = ace.createEditSession(text, 'ace/mode/matlab');
    session.setUseSoftTabs(settings.expand_tabs);
    session.setTabSize(settings.tab_width);
    return session;
  };

  Editor.prototype.selectLine = function(line) {
    var Range = ace.require('ace/range').Range;
    var selection = this.editor.selection;
    selection.setSelectionRange(new Range(line - 1, 0, line - 1, 0));
    selection.selectLineStart();
    selection.selectLineEnd();
  }

  Editor.prototype.createSession = function(path, text) {
    this.sessions[path] = createEditSession(text, this.settings);
  };

  Editor.prototype.addKeyboardShortcut = function(name, key, action) {
    var bindKey = key;
    if (bindKey.indexOf('Ctrl') !== -1) {
      bindKey = {win: key, mac: key.replace('Ctrl', 'Command')};
    }
    this.editor.commands.addCommand({
      name: name,
      bindKey: bindKey,
      exec: action,
    });
  };

  Editor.prototype.openFile = function(path, callback) {
    if (_(this.sessions).has(path)) {
      this.tabs.openTab(path);
      if (callback) {
        callback();
      }
      return;
    }
    ide.ajax.readFile(path, function (contents) {
      this.createSession(path, contents);
      this.tabs.openTab(path);
      this.tryParse();
      if (callback) {
        callback();
      }
    }.bind(this));
  };

  Editor.prototype.selectFile = function(tab) {
    var path = tab.name();
    if (!_(this.sessions).has(path)) {
      this.createSession(path, '');
    }
    this.editor.setSession(this.sessions[path]);
    this.visible(true);
  };

  Editor.prototype.saveFile = function(tab) {
    var path = tab.name();
    ide.ajax.writeFile(path, this.sessions[path].getValue());
    tab.dirty(false);
  }

  var renameKey = function(object, oldKey, newKey) {
    if (_(object).has(oldKey)) {
      object[newKey] = object[oldKey];
      delete object[oldKey];
    }
  };

  var removeKey = function(object, key) {
    if (_(object).has(key)) {
      delete object[key];
    }
  };

  Editor.prototype.hasDirtyTab = function(path) {
    var tab = this.tabs.findByName(path);
    return tab && tab.dirty();
  };

  Editor.prototype.renameFile = function(oldPath, newPath) {
    var tab = this.tabs.findByName(oldPath);
    if (tab) {
      tab.name(newPath);
    }
    renameKey(this.sessions, oldPath, newPath);
    renameKey(this.asts, oldPath, newPath);
  };

  Editor.prototype.deleteFile = function(path) {
    var tab = this.tabs.findByName(path);
    if (tab) {
      this.tabs.forceCloseTab(tab);
    }
    removeKey(this.sessions, path);
    removeKey(this.asts, path);
  };

  Editor.prototype.jumpTo = function(token) {
    this.openFile(token.file, function () {
     this.editor.getSelection().moveTo(token.line - 1, token.col - 1);
    }.bind(this));
  };

  Editor.prototype.getTokenFromMouseEvent = function(e) {
    var MouseEvent = ace.require('ace/mouse/mouse_event').MouseEvent;
    if (!(e instanceof MouseEvent)) {
      e = new MouseEvent(e, this.editor);
    }
    var position = e.getDocumentPosition();
    var token = this.editor.getSession().getTokenAt(position.row, position.column);
    return {
      identifier: token.value,
      file: this.tabs.selectedTab().name(),
      line: position.row + 1,
      col: token.start + 1
    };
  };

  Editor.prototype.getSelectionRange = function() {
    var range = this.editor.getSelection().getRange();
    return {
      startLine: range.start.row + 1,
      startColumn: range.start.column + 1,
      endLine: range.end.row + 1,
      endColumn: range.end.column + 1,
    };
  };

  Editor.prototype.isFunctionCall = function(token) {
    return this.getAst()
      .findAtPosition('NameExpr', token)
      .isFunctionCall();
  };

  Editor.prototype.hasAst = function() {
    return _(this.asts).has(this.tabs.selectedTab().name());
  };

  Editor.prototype.getAst = function() {
    return this.asts[this.tabs.selectedTab().name()];
  };

  Editor.prototype.clearErrors = function() {
    this.overlayErrors([]);
  };

  Editor.prototype.overlayErrors = function(errors) {
    this.editor.getSession().setAnnotations(
      errors.map(function (err) {
        return {
          row: err.line - 1,
          column: err.col - 1,
          text: err.message,
          type: 'error'
        };
      })
    );
  };

  Editor.prototype.tryParse = function() {
    ide.ast.parse(this.editor.getValue(),
      function (ast) {
        this.clearErrors();
        this.asts[this.tabs.selectedTab().name()] = ast;
      }.bind(this),
      function (errors) {
        this.overlayErrors(errors);
        delete this.asts[this.tabs.selectedTab().name()];
      }.bind(this));
  };

  Editor.prototype.startSyntaxChecker = function() {
    this.editor.on('change', _.debounce(this.tryParse.bind(this), 1000));
  };

  _.extend(Editor.prototype, ide.utils.EventsMixin);

  return {
    Editor: Editor
  };
})();
<|endoftext|>


<commit_before>/* bender-tags: editor,unit */
/* bender-ckeditor-plugins: contextmenu,detabler */

(function () {
	'use strict';
	bender.editor = {
		config: {
			enterMode: CKEDITOR.ENTER_P
		}
	};
	bender.test({
		setUp: function () {
			this.command = this.editorBot.editor.getCommand('detable');
		},
		contextMenuItemIsPresent: function (editor) {
			// open and close the context menu, and return true if the detable option was present.

			editor.contextMenu.open(editor.editable());

			var itemExists = false;
			for (var i = 0; i < editor.contextMenu.items.length; ++i) {
				if (editor.contextMenu.items[i].command == 'detable') {
					itemExists = true;
					break;
				}
			}

			editor.contextMenu.hide();

			return itemExists;
		},
		'context menu item is not present outside of tables': function () {
			var editor = this.editorBot.editor,
				startHtml;

			startHtml = '
foobar^
' +
				'
baz
' +
				'
' +
					'
' +
						'
leave me alone
' +
					'
' +
				'
';

			this.editorBot.setHtmlWithSelection(
				startHtml
			);
			// setHtmlWithSelection doesn't appear to refresh command state, so we must manually do it
			this.command.refresh(editor, editor.elementPath());

			assert.areEqual(false, this.contextMenuItemIsPresent(editor));

		},
		'context menu item is present inside of tables': function () {
			var editor = this.editorBot.editor,
				startHtml;

			startHtml = '
foo
' +
				'
' +
					'
' +
						'
^foo	bar
' +
					'
' +
				'
';

			this.editorBot.setHtmlWithSelection(
				startHtml
			);
			// setHtmlWithSelection doesn't appear to refresh command state, so we must manually do it
			this.command.refresh(editor, editor.elementPath());

			assert.areEqual(true, this.contextMenuItemIsPresent(editor));
		}
	});
})();
<commit_msg>more one-lining<commit_after>/* bender-tags: editor,unit */
/* bender-ckeditor-plugins: contextmenu,detabler */

(function () {
	'use strict';
	bender.editor = {
		config: {
			enterMode: CKEDITOR.ENTER_P
		}
	};
	bender.test({
		setUp: function () {
			this.command = this.editorBot.editor.getCommand('detable');
		},
		contextMenuItemIsPresent: function (editor) {
			// open and close the context menu, and return true if the detable option was present.

			editor.contextMenu.open(editor.editable());

			var itemExists = false;
			for (var i = 0; i < editor.contextMenu.items.length; ++i) {
				if (editor.contextMenu.items[i].command == 'detable') {
					itemExists = true;
					break;
				}
			}

			editor.contextMenu.hide();

			return itemExists;
		},
		'context menu item is not present outside of tables': function () {
			var editor = this.editorBot.editor,
				startHtml;

			startHtml = '
foobar^
' +
				'
baz
' +
				'
' +
					'
' +
						'
leave me alone
' +
					'
' +
				'
';

			this.editorBot.setHtmlWithSelection(startHtml);
			// setHtmlWithSelection doesn't appear to refresh command state, so we must manually do it
			this.command.refresh(editor, editor.elementPath());

			assert.areEqual(false, this.contextMenuItemIsPresent(editor));

		},
		'context menu item is present inside of tables': function () {
			var editor = this.editorBot.editor,
				startHtml;

			startHtml = '
foo
' +
				'
' +
					'
' +
						'
^foo	bar
' +
					'
' +
				'
';

			this.editorBot.setHtmlWithSelection(startHtml);
			// setHtmlWithSelection doesn't appear to refresh command state, so we must manually do it
			this.command.refresh(editor, editor.elementPath());

			assert.areEqual(true, this.contextMenuItemIsPresent(editor));
		}
	});
})();
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import { checkA11y } from 'storybook-addon-a11y';
import { withInfo } from '@storybook/addon-info';
import { LoadingMolecule } from '../components';
import styles from '@sambego/storybook-styles';
import { baseStyles, centerStyles } from '../.storybook/styles';

const basePath = window.location.pathname + window.location.search;

storiesOf('Loading molecules', module)
  .addDecorator((story, context) => withInfo('common info')(story)(context))
  .addDecorator(checkA11y)
  .addDecorator(styles({ ...baseStyles, ...centerStyles }))
  .add('color', () => (

      <LoadingMolecule basePath={basePath} startColor="#00ACA9" stopColor="#1F7F79" />

  ))
  .add('grayscale', () => (

      <LoadingMolecule basePath={basePath} startColor="#BABABA" stopColor="#DADADA" />

  ))
  .add('small', () => (

      <LoadingMolecule basePath={basePath} startColor="#00ACA9" stopColor="#1F7F79" type="small" />

  ))
  .add('large', () => (

      <LoadingMolecule basePath={basePath} startColor="#00ACA9" stopColor="#1F7F79" type="large" />

  ));
<commit_msg>Fix loading molecule<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import { checkA11y } from 'storybook-addon-a11y';
import { withInfo } from '@storybook/addon-info';
import { LoadingMolecule } from '../components';
import styles from '@sambego/storybook-styles';
import { baseStyles } from '../.storybook/styles';

const basePath = window.location.pathname + window.location.search;

storiesOf('Loading molecules', module)
  .addDecorator((story, context) => withInfo('common info')(story)(context))
  .addDecorator(checkA11y)
  .addDecorator(styles(baseStyles))
  .add('color', () => (

      <LoadingMolecule basePath={basePath} startColor="#00ACA9" stopColor="#1F7F79" />

  ))
  .add('grayscale', () => (

      <LoadingMolecule basePath={basePath} startColor="#BABABA" stopColor="#DADADA" />

  ))
  .add('small', () => (

      <LoadingMolecule basePath={basePath} startColor="#00ACA9" stopColor="#1F7F79" type="small" />

  ))
  .add('large', () => (

      <LoadingMolecule basePath={basePath} startColor="#00ACA9" stopColor="#1F7F79" type="large" />

  ));
<|endoftext|>


<commit_before>let q = require('q')
let fs = require('fs')
let unzip = require('unzip')
let { exec } = require('child_process');
const path = require('path');
const searchsdk = require('../../searchsdk');

const { config } = require('../config');

let checkIfDeviceIsUSB = (string) => {
  let defer = q.defer();
  let uuidBegin = string.indexOf("UUID") + 5;
  let uuidEnd = string.indexOf('"', uuidBegin + 1);
  if (uuidEnd - uuidBegin == 10) {
    defer.resolve(string);
  } else {
    defer.reject(string);
  }
  return defer.promise;
}

let verifyIfBlockDevice = (mountPoint) => {
  let defer = q.defer();
  exec('blkid', (err, stdout, stderr) => {
    if (err) {
      return defer.reject(err);
    } else {
      let blkLines = stdout.split('\n');
      for (let i in blkLines) {
        if (blkLines[i].indexOf('/dev/' + mountPoint) >= 0) {
          return defer.resolve(blkLines[i]);
        }
      }
    }
  })
  return defer.promise;
}

let extractUSBDeviceFromList = (output, dir) => {
  let defer = q.defer();
  let outputLines = output.split('\n');
  for (let i in outputLines) {
    let line = outputLines[i];
    let index = line.indexOf('/media/');
    let usbDeviceFound = false;
    if (index >= 0) {
      let mediaDirectory = line.slice(index);
      let mountPointRegExp = /sd[a-zA-Z][\d]+/;
      let mediaMountPoint = '';
      try {
        mediaMountPoint = line.match(mountPointRegExp)[0];
      } catch (err) {
        continue;
      }
      verifyIfBlockDevice(mediaMountPoint).then(resolve => {
        return checkIfDeviceIsUSB(resolve);
      }, reject => {
      }).then(resolve => {
        let directoryToRead = line.slice(index) + '/' + dir;
        fs.readdir(directoryToRead, (err, files) => {
          if (err) {
            console.log("err: " + err);
            return defer.reject(err);
          } else {
            usbDeviceFound = true;
            return defer.resolve({ dir: directoryToRead, files });
          }
        })
      }, reject => {
        return defer.reject(reject);
      });
      if (usbDeviceFound) {
        break;
      }
    }
  }
  return defer.promise;
}

let getConnectedDevice = (dir) => {
  let defer = q.defer();
  exec('lsblk', (err, stdout, stderr) => {
    if (err) {
      return defer.reject(err);
    } else {
      extractUSBDeviceFromList(stdout, dir).then(resolve => {
        return defer.resolve(resolve);
      }, reject => {
        return defer.reject(reject);
      });
    }
  })
  return defer.promise;
}

let getUSB = (req, res) => {
  let dir = decodeURIComponent(req.query.dir);
  getConnectedDevice(dir).then(resolve => {
    return res.status(200).json(resolve);
  }, reject => {
    return res.status(500).json({ 'msg': reject });
  })

}

let getEcarNameForId = (id, db) => {
  let defer = q.defer();

  searchsdk.getDocument({
    indexName: db,
    documentID: id
  }).then(results => {
    const metaData = JSON.parse(results.body);
    const ecarName = metaData.fields["archive.items.name"];

    defer.resolve(ecarName);
  }).catch(err => {
    // defer.reject(err);
    defer.resolve(name = '');
  });
  return defer.promise;
}

// make following configurable
const isEcarDir = dir => {
	let ecarDirList = [
		'/home/admin/sunbird/ecar_files',
    '/home/admin/ekStep/ecar_files',
    '/home/admin/diksha/ecar_files'
	];

	dir = path.resolve(dir);
	ecarDirList = ecarDirList.map(dir => path.resolve(dir));

	if (ecarDirList.indexOf(dir) !== -1 ) {
		return true;
	}

	return false;
}

// make following configurable
const getEcarDb = dir => {
  let db;
  const contentFolder = path.basename(path.dirname(dir));

  switch (contentFolder) {
    case 'ekStep':
      db = 'es.db';
      break;

    case 'sunbird':
      db = 'sb.db';
      break;

    case 'diksha':
      db = 'dk.db';
      break;

    default:
      db = null;
      break;
  }

  return db;
}

let classify = (dir, file) => {
  let defer = q.defer();

  fs.stat(dir + file, (err, stats) => {
    if (err) {
      console.log(err);
      return defer.reject(err);
    } else if (stats.isDirectory()) {
      return defer.resolve({ 'name': file, 'type': 'dir', 'ext': null, 'size': stats.size })
    } else if (stats.isFile()) {
      const ext = path.extname(file);
      const name = path.basename(file).replace(ext, '');

      let response = { 'name': file, 'type': 'file', 'ext': 'other', 'size': stats.size };

      if (ext === '.ecar' && isEcarDir(dir)) {
        const db = getEcarDb(dir);

        getEcarNameForId(file, db)
          .then(ecarName => {
            const id = name.substring(0, name.lastIndexOf('_'));

            response.name = ecarName + ext;
            response.ext = ext;
            response.id = id;

            defer.resolve(response);
          }).catch(err => {
            defer.reject(err);
          });
      } else {
        defer.resolve(response);
      }
    }
  });
  return defer.promise;
}

let getFilesFromFolder = (dir) => {
  let defer = q.defer();
  fs.readdir(dir, (err, files) => {
    if (err) {
      console.log(err);
      return defer.reject(err);
    } else {
      files = files.filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
      return defer.resolve(files);
    }
  })
  return defer.promise;
}

let checkIfIsFolder = (dir) => {
  let defer = q.defer();
  fs.stat(dir, (err, stats) => {
    if (err || !(stats.isDirectory())) {
      console.log(err);
      return defer.reject({ success: false });
    } else {
      return defer.resolve({ success: true });
    }
  });
  return defer.promise;
}

let openDirectory = (req, res) => {
  let currentPath = decodeURIComponent(req.query.path);
  let responseStructure = {
    success: false,
    msg: '',
    fileList: [],
    folderList: []
  };
  checkIfIsFolder(currentPath).then(response => {
    if (response.success) {
      return getFilesFromFolder(currentPath);
    } else {
      return res.status(200).json(responseStructure);
    }
  }).then(response => {
    let taskArray = [];
    for (let i in response) {
      taskArray.push(classify(currentPath, response[i]));
    }
    return q.allSettled(taskArray);
  }).then(response => {
    let responseStructure = {
      children: []
    }
    for (let i = 0; i < response.length; i++) {
      responseStructure.children.push({
        'name': response[i].value.name,
        'type': response[i].value.type,
        'ext': response[i].value.ext,
        'size': response[i].value.size,
        'id': response[i].value.id
      });
    }
    return res.status(200).json(responseStructure);
  }).catch(e => {
    console.log(e);
    responseStructure.msg = 'Server side error';
    return res.status(500).json(responseStructure);
  })
}

let deleteFileFromDisk = (req, res) => {
  let fileToDelete = decodeURIComponent(req.query.path);
  let responseStructure = {
    success: false,
    msg: ''
  }
  let cmd;

  const ext = path.extname(fileToDelete);
  const name = path.basename(fileToDelete).replace(ext, '');
  const dir = path.dirname(fileToDelete);
  const file = path.resolve(dir, name);
  const json_dir = path.resolve(dir, '..', 'json_dir', name);
  const xcontent = path.resolve(dir, '..', 'xcontent', name);

  if (ext === '.ecar') {
    cmd = `rm -rf ${file}* ${json_dir}* ${xcontent}*`;
  } else {
    if((dir.startsWith('/home/admin')) && (!(dir.startsWith('/home/admin/diksha')))){
      fileToDelete = fileToDelete.replace(/\W/g,"\\$&");
      cmd = `rm -rf ${fileToDelete}`;
    }else {
      responseStructure.msg = "Cannot Delete this file!";
      return res.status(200).json(responseStructure);
    }
  }

  exec(cmd, (err, stdout, stderr) => {
    if (err) {
      console.log(err);
      responseStructure.msg = "Cannot delete this file!";
      return res.status(500).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let createNewFolder = (req, res) => {
  let newFolder = decodeURIComponent(req.body.path);
  let responseStructure = {
    success: false,
    msg: ''
  }
  fs.mkdir(newFolder, (err) => {
    if (err) {
      console.log(err);
      responseStructure.msg = err;
      return res.status(200).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let copyFile = (req, res) => {
  let oldFile = decodeURIComponent(req.body.old);
  let newFile = decodeURIComponent(req.body.new);
  let responseStructure = {
    success: false,
    msg: ''
  }
  exec('cp -r "' + oldFile + '" "' + newFile + '"', (err, stdout, stderr) => {
    if (err) {
      console.log(err);
      responseStructure.msg = "Cannot copy file!";
      return res.status(500).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let moveFile = (req, res) => {
  let oldFile = req.body.old;
  let newFile = req.body.new;
  let responseStructure = {
    success: false,
    msg: ''
  }
  fs.rename(oldFile, newFile, (err) => {
    if (err) {
      console.log(err);
      responseStructure.msg = `Moving failed`;
      return res.status(500).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let writeFileToDisk = (req, res) => {
  let temporaryPath = req.files.file.path
  let actualPathPrefix = req.body.prefix;
  let actualFileName = req.files.file.originalFilename;

  let filePathArr = actualFileName.split('/');
  let mkdirPathPrefix = path.join(config.FS_ROOT, 'tmp');
  if (filePathArr.length > 1) {
    console.log(filePathArr);
    // console.log(filePathArr.splice(0, filePathArr.length - 1).join('/'));
    let temp = filePathArr.splice(0, filePathArr.length - 1).join('/');
    console.log(temp);
    actualPathPrefix = actualPathPrefix + "" + temp
    mkdirPathPrefix = '"' + actualPathPrefix+ '"';
    console.log(actualPathPrefix);
    actualFileName = "/" + filePathArr.splice(-1,1)[0];
  }

  console.log(`mkdir -p ${mkdirPathPrefix}`)
  exec(`mkdir -p ${mkdirPathPrefix}`, (err, stdout, stderr) => {
    if (err) {
      console.log(err);
      console.log("error");
    } else {
      console.log(stdout);
      fs.copyFile(temporaryPath, actualPathPrefix + actualFileName, (err) => {
        if (err) {
          console.log(err);
          res.status(500).json({ success: false });
        } else {
          return res.status(200).json({ success: true });
        }
      });
    }
  });
  let actualFileType = actualFileName.slice(actualFileName.lastIndexOf('.') + 1);
  // fs.copyFile(temporaryPath, actualPathPrefix + actualFileName, (err) => {
  //   if (err) {
  //     console.log(err);
  //     res.status(500).json({ success: false });
  //   } else {
  //     return res.status(200).json({ success: true });
  //   }
  // });
}

const applyChangesToPlugins = (req, res) => {
    let response = {
        success : false,
        message : null
    }

    const cmd = 'service appserver restart';

    exec(cmd, (err, stdout, stderr) => {
        if (err || stderr) {
            console.log(err);

            response = {
                ...response,
                message : 'Could not apply changes to the plugins.'
            }

            res.status(500).json(response);
        } else {
            response = {
                ...response,
                success : true,
                message : 'Changes applied successfully.'
            }

            res.status(200).json(response);
        }
    })

}

/*
* Code to write content refresh time to a `.meta` file
*/

const formatTimestamp = timestamp => {
    const options = {
        hour: 'numeric',
        minute: 'numeric',
        hour12: true,
        weekday: 'short',
        year: 'numeric',
        month: 'short',
        day: 'numeric'
    };

    return timestamp.toLocaleString('en-IN', options);
}

let storeTimestamp = (req, res, next) => {
    const timestamp = new Date(parseInt(req.body.timestamp || req.query.timestamp));

    fs.writeFile(path.join(config.FS_ROOT, '.meta'), formatTimestamp(timestamp), function (err) {
        if (err) {
            return console.log(err);
        }

        next();
        console.log("Timestamp stored.");
    });
}

module.exports = {
  openDirectory,
  deleteFileFromDisk,
  createNewFolder,
  copyFile,
  moveFile,
  writeFileToDisk,
  getUSB,
  storeTimestamp,
  applyChangesToPlugins
}
<commit_msg>Deletion of files outside "/home/admin" would cause sever damage to the device.The entire OS would get deleted. Deletion of files/folders inside "home/admin/diksha" would damage the ecar file structure.Deletion of xcontent folder and json dir would damage the content of the ecar files. Hence Deletion operation is restricted outside the "/home/admin" dir and inside the "/home/admin/diksha" dir.<commit_after>let q = require('q')
let fs = require('fs')
let unzip = require('unzip')
let { exec } = require('child_process');
const path = require('path');
const searchsdk = require('../../searchsdk');

const { config } = require('../config');

let checkIfDeviceIsUSB = (string) => {
  let defer = q.defer();
  let uuidBegin = string.indexOf("UUID") + 5;
  let uuidEnd = string.indexOf('"', uuidBegin + 1);
  if (uuidEnd - uuidBegin == 10) {
    defer.resolve(string);
  } else {
    defer.reject(string);
  }
  return defer.promise;
}

let verifyIfBlockDevice = (mountPoint) => {
  let defer = q.defer();
  exec('blkid', (err, stdout, stderr) => {
    if (err) {
      return defer.reject(err);
    } else {
      let blkLines = stdout.split('\n');
      for (let i in blkLines) {
        if (blkLines[i].indexOf('/dev/' + mountPoint) >= 0) {
          return defer.resolve(blkLines[i]);
        }
      }
    }
  })
  return defer.promise;
}

let extractUSBDeviceFromList = (output, dir) => {
  let defer = q.defer();
  let outputLines = output.split('\n');
  for (let i in outputLines) {
    let line = outputLines[i];
    let index = line.indexOf('/media/');
    let usbDeviceFound = false;
    if (index >= 0) {
      let mediaDirectory = line.slice(index);
      let mountPointRegExp = /sd[a-zA-Z][\d]+/;
      let mediaMountPoint = '';
      try {
        mediaMountPoint = line.match(mountPointRegExp)[0];
      } catch (err) {
        continue;
      }
      verifyIfBlockDevice(mediaMountPoint).then(resolve => {
        return checkIfDeviceIsUSB(resolve);
      }, reject => {
      }).then(resolve => {
        let directoryToRead = line.slice(index) + '/' + dir;
        fs.readdir(directoryToRead, (err, files) => {
          if (err) {
            console.log("err: " + err);
            return defer.reject(err);
          } else {
            usbDeviceFound = true;
            return defer.resolve({ dir: directoryToRead, files });
          }
        })
      }, reject => {
        return defer.reject(reject);
      });
      if (usbDeviceFound) {
        break;
      }
    }
  }
  return defer.promise;
}

let getConnectedDevice = (dir) => {
  let defer = q.defer();
  exec('lsblk', (err, stdout, stderr) => {
    if (err) {
      return defer.reject(err);
    } else {
      extractUSBDeviceFromList(stdout, dir).then(resolve => {
        return defer.resolve(resolve);
      }, reject => {
        return defer.reject(reject);
      });
    }
  })
  return defer.promise;
}

let getUSB = (req, res) => {
  let dir = decodeURIComponent(req.query.dir);
  getConnectedDevice(dir).then(resolve => {
    return res.status(200).json(resolve);
  }, reject => {
    return res.status(500).json({ 'msg': reject });
  })

}

let getEcarNameForId = (id, db) => {
  let defer = q.defer();

  searchsdk.getDocument({
    indexName: db,
    documentID: id
  }).then(results => {
    const metaData = JSON.parse(results.body);
    const ecarName = metaData.fields["archive.items.name"];

    defer.resolve(ecarName);
  }).catch(err => {
    // defer.reject(err);
    defer.resolve(name = '');
  });
  return defer.promise;
}

// make following configurable
const isEcarDir = dir => {
	let ecarDirList = [
		'/home/admin/sunbird/ecar_files',
    '/home/admin/ekStep/ecar_files',
    '/home/admin/diksha/ecar_files'
	];

	dir = path.resolve(dir);
	ecarDirList = ecarDirList.map(dir => path.resolve(dir));

	if (ecarDirList.indexOf(dir) !== -1 ) {
		return true;
	}

	return false;
}

// make following configurable
const getEcarDb = dir => {
  let db;
  const contentFolder = path.basename(path.dirname(dir));

  switch (contentFolder) {
    case 'ekStep':
      db = 'es.db';
      break;

    case 'sunbird':
      db = 'sb.db';
      break;

    case 'diksha':
      db = 'dk.db';
      break;

    default:
      db = null;
      break;
  }

  return db;
}

let classify = (dir, file) => {
  let defer = q.defer();

  fs.stat(dir + file, (err, stats) => {
    if (err) {
      console.log(err);
      return defer.reject(err);
    } else if (stats.isDirectory()) {
      return defer.resolve({ 'name': file, 'type': 'dir', 'ext': null, 'size': stats.size })
    } else if (stats.isFile()) {
      const ext = path.extname(file);
      const name = path.basename(file).replace(ext, '');

      let response = { 'name': file, 'type': 'file', 'ext': 'other', 'size': stats.size };

      if (ext === '.ecar' && isEcarDir(dir)) {
        const db = getEcarDb(dir);

        getEcarNameForId(file, db)
          .then(ecarName => {
            const id = name.substring(0, name.lastIndexOf('_'));

            response.name = ecarName + ext;
            response.ext = ext;
            response.id = id;

            defer.resolve(response);
          }).catch(err => {
            defer.reject(err);
          });
      } else {
        defer.resolve(response);
      }
    }
  });
  return defer.promise;
}

let getFilesFromFolder = (dir) => {
  let defer = q.defer();
  fs.readdir(dir, (err, files) => {
    if (err) {
      console.log(err);
      return defer.reject(err);
    } else {
      files = files.filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
      return defer.resolve(files);
    }
  })
  return defer.promise;
}

let checkIfIsFolder = (dir) => {
  let defer = q.defer();
  fs.stat(dir, (err, stats) => {
    if (err || !(stats.isDirectory())) {
      console.log(err);
      return defer.reject({ success: false });
    } else {
      return defer.resolve({ success: true });
    }
  });
  return defer.promise;
}

let openDirectory = (req, res) => {
  let currentPath = decodeURIComponent(req.query.path);
  let responseStructure = {
    success: false,
    msg: '',
    fileList: [],
    folderList: []
  };
  checkIfIsFolder(currentPath).then(response => {
    if (response.success) {
      return getFilesFromFolder(currentPath);
    } else {
      return res.status(200).json(responseStructure);
    }
  }).then(response => {
    let taskArray = [];
    for (let i in response) {
      taskArray.push(classify(currentPath, response[i]));
    }
    return q.allSettled(taskArray);
  }).then(response => {
    let responseStructure = {
      children: []
    }
    for (let i = 0; i < response.length; i++) {
      responseStructure.children.push({
        'name': response[i].value.name,
        'type': response[i].value.type,
        'ext': response[i].value.ext,
        'size': response[i].value.size,
        'id': response[i].value.id
      });
    }
    return res.status(200).json(responseStructure);
  }).catch(e => {
    console.log(e);
    responseStructure.msg = 'Server side error';
    return res.status(500).json(responseStructure);
  })
}

let deleteFileFromDisk = (req, res) => {
  let fileToDelete = decodeURIComponent(req.query.path);
  let responseStructure = {
    success: false,
    msg: ''
  }
  let cmd;

  const ext = path.extname(fileToDelete);
  const name = path.basename(fileToDelete).replace(ext, '');
  const dir = path.dirname(fileToDelete);
  const file = path.resolve(dir, name);
  const json_dir = path.resolve(dir, '..', 'json_dir', name);
  const xcontent = path.resolve(dir, '..', 'xcontent', name);

  if (ext === '.ecar') {
    cmd = `rm -rf ${file}* ${json_dir}* ${xcontent}*`;
  } else {
    // deletion of files outside the "/home/admin" dir and inside the "/home/admin/diksha" dir has been restricted.
    if((dir.startsWith('/home/admin')) && (!(dir.startsWith('/home/admin/diksha')))){
      fileToDelete = fileToDelete.replace(/\W/g,"\\$&");
      cmd = `rm -rf ${fileToDelete}`;
    }else {
      responseStructure.msg = "Cannot Delete this file!";
      return res.status(200).json(responseStructure);
    }
  }

  exec(cmd, (err, stdout, stderr) => {
    if (err) {
      console.log(err);
      responseStructure.msg = "Cannot delete this file!";
      return res.status(500).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let createNewFolder = (req, res) => {
  let newFolder = decodeURIComponent(req.body.path);
  let responseStructure = {
    success: false,
    msg: ''
  }
  fs.mkdir(newFolder, (err) => {
    if (err) {
      console.log(err);
      responseStructure.msg = err;
      return res.status(200).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let copyFile = (req, res) => {
  let oldFile = decodeURIComponent(req.body.old);
  let newFile = decodeURIComponent(req.body.new);
  let responseStructure = {
    success: false,
    msg: ''
  }
  exec('cp -r "' + oldFile + '" "' + newFile + '"', (err, stdout, stderr) => {
    if (err) {
      console.log(err);
      responseStructure.msg = "Cannot copy file!";
      return res.status(500).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let moveFile = (req, res) => {
  let oldFile = req.body.old;
  let newFile = req.body.new;
  let responseStructure = {
    success: false,
    msg: ''
  }
  fs.rename(oldFile, newFile, (err) => {
    if (err) {
      console.log(err);
      responseStructure.msg = `Moving failed`;
      return res.status(500).json(responseStructure);
    } else {
      responseStructure.success = true;
      return res.status(200).json(responseStructure);
    }
  })
}

let writeFileToDisk = (req, res) => {
  let temporaryPath = req.files.file.path
  let actualPathPrefix = req.body.prefix;
  let actualFileName = req.files.file.originalFilename;

  let filePathArr = actualFileName.split('/');
  let mkdirPathPrefix = path.join(config.FS_ROOT, 'tmp');
  if (filePathArr.length > 1) {
    console.log(filePathArr);
    // console.log(filePathArr.splice(0, filePathArr.length - 1).join('/'));
    let temp = filePathArr.splice(0, filePathArr.length - 1).join('/');
    console.log(temp);
    actualPathPrefix = actualPathPrefix + "" + temp
    mkdirPathPrefix = '"' + actualPathPrefix+ '"';
    console.log(actualPathPrefix);
    actualFileName = "/" + filePathArr.splice(-1,1)[0];
  }

  console.log(`mkdir -p ${mkdirPathPrefix}`)
  exec(`mkdir -p ${mkdirPathPrefix}`, (err, stdout, stderr) => {
    if (err) {
      console.log(err);
      console.log("error");
    } else {
      console.log(stdout);
      fs.copyFile(temporaryPath, actualPathPrefix + actualFileName, (err) => {
        if (err) {
          console.log(err);
          res.status(500).json({ success: false });
        } else {
          return res.status(200).json({ success: true });
        }
      });
    }
  });
  let actualFileType = actualFileName.slice(actualFileName.lastIndexOf('.') + 1);
  // fs.copyFile(temporaryPath, actualPathPrefix + actualFileName, (err) => {
  //   if (err) {
  //     console.log(err);
  //     res.status(500).json({ success: false });
  //   } else {
  //     return res.status(200).json({ success: true });
  //   }
  // });
}

const applyChangesToPlugins = (req, res) => {
    let response = {
        success : false,
        message : null
    }

    const cmd = 'service appserver restart';

    exec(cmd, (err, stdout, stderr) => {
        if (err || stderr) {
            console.log(err);

            response = {
                ...response,
                message : 'Could not apply changes to the plugins.'
            }

            res.status(500).json(response);
        } else {
            response = {
                ...response,
                success : true,
                message : 'Changes applied successfully.'
            }

            res.status(200).json(response);
        }
    })

}

/*
* Code to write content refresh time to a `.meta` file
*/

const formatTimestamp = timestamp => {
    const options = {
        hour: 'numeric',
        minute: 'numeric',
        hour12: true,
        weekday: 'short',
        year: 'numeric',
        month: 'short',
        day: 'numeric'
    };

    return timestamp.toLocaleString('en-IN', options);
}

let storeTimestamp = (req, res, next) => {
    const timestamp = new Date(parseInt(req.body.timestamp || req.query.timestamp));

    fs.writeFile(path.join(config.FS_ROOT, '.meta'), formatTimestamp(timestamp), function (err) {
        if (err) {
            return console.log(err);
        }

        next();
        console.log("Timestamp stored.");
    });
}

module.exports = {
  openDirectory,
  deleteFileFromDisk,
  createNewFolder,
  copyFile,
  moveFile,
  writeFileToDisk,
  getUSB,
  storeTimestamp,
  applyChangesToPlugins
}
<|endoftext|>


<commit_before>import AWS from 'aws-sdk';
import multer from 'multer';
import multerS3 from 'multer-s3';
import config from './config';

const myConfig = new AWS.Config({
  accessKeyId: config.s3_key,
  secretAccessKey: config.s3_secret,
  region: 'us-west-2'
});
const s3 = new AWS.S3(myConfig);

const upload = multer({
  storage: multerS3({
    s3,
    bucket: 'some-bucket',
    metadata: (req, file, cb) => {
      cb(null, { fieldName: file.fieldname });
    },
    key: (req, file, cb) => {
      cb(null, Date.now().toString());
    }
  })
});

export default upload;
<commit_msg>add filter to aws function<commit_after>import AWS from 'aws-sdk';
import multer from 'multer';
import multerS3 from 'multer-s3';
import config from './config';

const myConfig = new AWS.Config({
  accessKeyId: config.s3_key,
  secretAccessKey: config.s3_secret,
  region: 'us-west-2'
});
const s3 = new AWS.S3(myConfig);

const upload = multer({
  storage: multerS3({
    s3,
    bucket: 'some-bucket',
    metadata: (req, file, cb) => {
      cb(null, { fieldName: file.fieldname });
    },
    key: (req, file, cb) => {
      cb(null, Date.now().toString());
    }
  }),
  fileFilter(req, file, next) {
    const isPhoto = file.mimetype.startsWith('image/');
    if (isPhoto) {
      next(null, true);
    } else {
      next({ message: 'That file type is not supported' }, false);
    }
  }
});

export default upload;
<|endoftext|>