<commit_before>"use strict";

var EXPORTED_SYMBOLS = ["tbSync"];

//global objects (not exported, not available outside this module)
const Cc = Components.classes;
const Ci = Components.interfaces;

Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/osfile.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
Components.utils.import("resource://gre/modules/AddonManager.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource:///modules/mailServices.js")
Components.utils.importGlobalProperties(["XMLHttpRequest"]);


//Date has a toISOString method, which returns the Date obj as extended ISO 8601,
//however EAS MS-ASCAL uses compact/basic ISO 8601,
//extending Date obj by toBasicISOString method to return compact/basic ISO 8601.
if (!Date.prototype.toBasicISOString) {
  (function() {

    function pad(number) {
      if (number < 10) {
        return '0' + number;
      }
      return number.toString();
    }

    Date.prototype.toBasicISOString = function() {
      return pad(this.getUTCFullYear()) +
        pad(this.getUTCMonth() + 1) +
        pad(this.getUTCDate()) +
        'T' + 
        pad(this.getUTCHours()) +
        pad(this.getUTCMinutes()) +
        pad(this.getUTCSeconds()) +
        'Z';
    };

  }());
}





var tbSync = {

    enabled: false,
    window: null,
    versionInfo: {installed: "0.0.0", mozilla : {number: "0.0.0", url: ""}, stable : {number: "0.0.0", url: ""}, beta : {number: "0.0.0.0", url: ""}},
    lastVersionCheck: 0,
        
    lightningInitDone: false,
    cachedTimezoneData: null,
    defaultTimezoneInfo: null,
    windowsTimezoneMap: {},

    bundle: Services.strings.createBundle("chrome://tbsync/locale/tbSync.strings"),

    prefWindowObj: null,
    decoder : new TextDecoder(),
    encoder : new TextEncoder(),

    prefSettings: Services.prefs.getBranch("extensions.tbsync."),
    syncProviderPref: Services.prefs.getBranch("extensions.tbsync.provider."),
    syncProviderList: Services.prefs.getBranch("extensions.tbsync.provider.").getChildList("", {}),


    storageDirectory : OS.Path.join(OS.Constants.Path.profileDir, "TbSync"),





    // GLOBAL INIT
    init: Task.async (function* (window)  { 

        tbSync.dump("TbSync init","Start");
        tbSync.window = window;

        Services.obs.addObserver(tbSync.openManagerObserver, "tbsync.openManager", false);
        Services.obs.addObserver(tbSync.initSyncObserver, "tbsync.initSync", false);
        Services.obs.addObserver(tbSync.syncstateObserver, "tbsync.changedSyncstate", false);
        
        //Inject UI - statusbar
        let statuspanel = tbSync.window.document.createElement('statusbarpanel');
        statuspanel.setAttribute("label","TbSync");
        statuspanel.setAttribute("id","tbsync.status");
        statuspanel.onclick = function (event) {if (event.button == 0) Services.obs.notifyObservers(null, 'tbsync.openManager', null);};
        tbSync.window.document.getElementById("status-bar").appendChild(statuspanel);

        //Inject UI - menuitem - if possible above "menu_accountmgr", wherever that is, if not found, fall back to taskPopup as container
        let menuitem = tbSync.window.document.createElement('menuitem');
        menuitem.setAttribute("label", tbSync.getLocalizedMessage("menu.settingslabel"));
        menuitem.setAttribute("id","tbsync.menuitem");
        menuitem.onclick = function (event) {Services.obs.notifyObservers(null, 'tbsync.openManager', null);};

        let accountManagerMenuItem = tbSync.window.document.getElementById("menu_accountmgr");
        let taskPopup = tbSync.window.document.getElementById("taskPopup");
        
        if (accountManagerMenuItem && accountManagerMenuItem.parentNode) {
          accountManagerMenuItem.parentNode.insertBefore(menuitem, accountManagerMenuItem);
        } else if (taskPopup) {
          tbSync.window.document.getElementById("taskPopup").appendChild(menuitem);	
        }
        
        //print information about Thunderbird version and OS
        tbSync.dump(Services.appinfo.name, Services.appinfo.platformVersion + " on " + OS.Constants.Sys.Name);
        
        // load common subscripts into tbSync (each subscript will be able to access functions/members of other subscripts, loading order does not matter)
        tbSync.includeJS("chrome://tbsync/content/db.js");

        //init DB
        yield tbSync.db.init();

        //convert database when migrating from connect state to enable state (keep this in 0.7 branch)
        let accounts = tbSync.db.getAccounts();
        for (let i = 0; i < accounts.IDs.length; i++) {
            if (accounts.data[accounts.IDs[i]].state == "connected") accounts.data[accounts.IDs[i]].state = "enabled";
        }

        //load provider subscripts into tbSync 
        for (let i=0;i<tbSync.syncProviderList.length;i++) {
            tbSync.dump("PROVIDER", tbSync.syncProviderList[i] + "::" + tbSync.syncProviderPref.getCharPref(tbSync.syncProviderList[i]));
            tbSync.includeJS("chrome://tbsync/content/provider/"+tbSync.syncProviderList[i]+"/" + tbSync.syncProviderList[i] +".js");
        }
        
        //init provider 
        for (let i=0;i<tbSync.syncProviderList.length;i++) {
            yield tbSync[tbSync.syncProviderList[i]].init();
        }

        //init stuff for address book
        tbSync.addressbookListener.add();
        tbSync.scanPrefIdsOfAddressBooks();
        
        //init stuff for lightning (and dump any other installed AddOn)
        //TODO: If lightning is converted to restartless, use AddonManager.addAddonListener() to get notification of enable/disable
        AddonManager.getAllAddons(Task.async (function* (addons) {
          for (let a=0; a < addons.length; a++) {
            if (addons[a].isActive) {
                tbSync.dump("Active AddOn", addons[a].name + " (" + addons[a].version + ", " + addons[a].id + ")");
                if (addons[a].id.toString() == "{e2fda1a4-762b-4020-b5ad-a41df1933103}") tbSync.onLightningLoad.start()
                if (addons[a].id.toString() == "<EMAIL>") {
                    tbSync.versionInfo.installed = addons[a].version.toString();
                    //check for updates
                    yield tbSync.check4updates();

                    //init stuff for sync process
                    tbSync.resetSync();
                    
                    //enable TbSync
                    tbSync.enabled = true;
                    
                    //activate sync timer
                    tbSync.syncTimer.start();

                    tbSync.dump("TbSync init","Done");
                }
            }
          }
        }));
                
    }),
    
    onLightningLoad: {
        timer: Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer),

        start: function () {
            this.timer.cancel();
            this.timer.initWithCallback(this.event, 2000, 0); //run timer in 2s
        },

        cancel: function () {
            this.timer.cancel();
        },

        event: {
            notify: Task.async (function* (timer) {
                tbSync.dump("Check4Lightning","Start");<commit_msg>check4updates() should not hold up init sequence<commit_after>"use strict";

var EXPORTED_SYMBOLS = ["tbSync"];

//global objects (not exported, not available outside this module)
const Cc = Components.classes;
const Ci = Components.interfaces;

Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/osfile.jsm");
Components.utils.import("resource://gre/modules/Task.jsm");
Components.utils.import("resource://gre/modules/AddonManager.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource:///modules/mailServices.js")
Components.utils.importGlobalProperties(["XMLHttpRequest"]);


//Date has a toISOString method, which returns the Date obj as extended ISO 8601,
//however EAS MS-ASCAL uses compact/basic ISO 8601,
//extending Date obj by toBasicISOString method to return compact/basic ISO 8601.
if (!Date.prototype.toBasicISOString) {
  (function() {

    function pad(number) {
      if (number < 10) {
        return '0' + number;
      }
      return number.toString();
    }

    Date.prototype.toBasicISOString = function() {
      return pad(this.getUTCFullYear()) +
        pad(this.getUTCMonth() + 1) +
        pad(this.getUTCDate()) +
        'T' + 
        pad(this.getUTCHours()) +
        pad(this.getUTCMinutes()) +
        pad(this.getUTCSeconds()) +
        'Z';
    };

  }());
}





var tbSync = {

    enabled: false,
    window: null,
    versionInfo: {installed: "0.0.0", mozilla : {number: "0.0.0", url: ""}, stable : {number: "0.0.0", url: ""}, beta : {number: "0.0.0.0", url: ""}},
    lastVersionCheck: 0,
        
    lightningInitDone: false,
    cachedTimezoneData: null,
    defaultTimezoneInfo: null,
    windowsTimezoneMap: {},

    bundle: Services.strings.createBundle("chrome://tbsync/locale/tbSync.strings"),

    prefWindowObj: null,
    decoder : new TextDecoder(),
    encoder : new TextEncoder(),

    prefSettings: Services.prefs.getBranch("extensions.tbsync."),
    syncProviderPref: Services.prefs.getBranch("extensions.tbsync.provider."),
    syncProviderList: Services.prefs.getBranch("extensions.tbsync.provider.").getChildList("", {}),


    storageDirectory : OS.Path.join(OS.Constants.Path.profileDir, "TbSync"),





    // GLOBAL INIT
    init: Task.async (function* (window)  { 

        tbSync.dump("TbSync init","Start");
        tbSync.window = window;

        Services.obs.addObserver(tbSync.openManagerObserver, "tbsync.openManager", false);
        Services.obs.addObserver(tbSync.initSyncObserver, "tbsync.initSync", false);
        Services.obs.addObserver(tbSync.syncstateObserver, "tbsync.changedSyncstate", false);
        
        //Inject UI - statusbar
        let statuspanel = tbSync.window.document.createElement('statusbarpanel');
        statuspanel.setAttribute("label","TbSync");
        statuspanel.setAttribute("id","tbsync.status");
        statuspanel.onclick = function (event) {if (event.button == 0) Services.obs.notifyObservers(null, 'tbsync.openManager', null);};
        tbSync.window.document.getElementById("status-bar").appendChild(statuspanel);

        //Inject UI - menuitem - if possible above "menu_accountmgr", wherever that is, if not found, fall back to taskPopup as container
        let menuitem = tbSync.window.document.createElement('menuitem');
        menuitem.setAttribute("label", tbSync.getLocalizedMessage("menu.settingslabel"));
        menuitem.setAttribute("id","tbsync.menuitem");
        menuitem.onclick = function (event) {Services.obs.notifyObservers(null, 'tbsync.openManager', null);};

        let accountManagerMenuItem = tbSync.window.document.getElementById("menu_accountmgr");
        let taskPopup = tbSync.window.document.getElementById("taskPopup");
        
        if (accountManagerMenuItem && accountManagerMenuItem.parentNode) {
          accountManagerMenuItem.parentNode.insertBefore(menuitem, accountManagerMenuItem);
        } else if (taskPopup) {
          tbSync.window.document.getElementById("taskPopup").appendChild(menuitem);	
        }
        
        //print information about Thunderbird version and OS
        tbSync.dump(Services.appinfo.name, Services.appinfo.platformVersion + " on " + OS.Constants.Sys.Name);
        
        // load common subscripts into tbSync (each subscript will be able to access functions/members of other subscripts, loading order does not matter)
        tbSync.includeJS("chrome://tbsync/content/db.js");

        //init DB
        yield tbSync.db.init();

        //convert database when migrating from connect state to enable state (keep this in 0.7 branch)
        let accounts = tbSync.db.getAccounts();
        for (let i = 0; i < accounts.IDs.length; i++) {
            if (accounts.data[accounts.IDs[i]].state == "connected") accounts.data[accounts.IDs[i]].state = "enabled";
        }

        //load provider subscripts into tbSync 
        for (let i=0;i<tbSync.syncProviderList.length;i++) {
            tbSync.dump("PROVIDER", tbSync.syncProviderList[i] + "::" + tbSync.syncProviderPref.getCharPref(tbSync.syncProviderList[i]));
            tbSync.includeJS("chrome://tbsync/content/provider/"+tbSync.syncProviderList[i]+"/" + tbSync.syncProviderList[i] +".js");
        }
        
        //init provider 
        for (let i=0;i<tbSync.syncProviderList.length;i++) {
            yield tbSync[tbSync.syncProviderList[i]].init();
        }

        //init stuff for address book
        tbSync.addressbookListener.add();
        tbSync.scanPrefIdsOfAddressBooks();
        
        //init stuff for lightning (and dump any other installed AddOn)
        //TODO: If lightning is converted to restartless, use AddonManager.addAddonListener() to get notification of enable/disable
        AddonManager.getAllAddons(Task.async (function* (addons) {
          for (let a=0; a < addons.length; a++) {
            if (addons[a].isActive) {
                tbSync.dump("Active AddOn", addons[a].name + " (" + addons[a].version + ", " + addons[a].id + ")");
                if (addons[a].id.toString() == "{e2fda1a4-762b-4020-b5ad-a41df1933103}") tbSync.onLightningLoad.start()
                if (addons[a].id.toString() == "<EMAIL>") {
                    tbSync.versionInfo.installed = addons[a].version.toString();

                    //init stuff for sync process
                    tbSync.resetSync();
                    
                    //enable TbSync
                    tbSync.enabled = true;
                    
                    //activate sync timer
                    tbSync.syncTimer.start();

                    tbSync.dump("TbSync init","Done");

                    //check for updates
                    yield tbSync.check4updates();
                }
            }
          }
        }));
                
    }),
    
    onLightningLoad: {
        timer: Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer),

        start: function () {
            this.timer.cancel();
            this.timer.initWithCallback(this.event, 2000, 0); //run timer in 2s
        },

        cancel: function () {
            this.timer.cancel();
        },

        event: {
            notify: Task.async (function* (timer) {
                tbSync.dump("Check4Lightning","Start");
{'fraction_non_alphanumeric': 0.13556791966345502, 'fraction_numerical': 0.009024290948568327, 'mean_word_length': 2.657320099255583, 'pattern_counts': {'":': 2, '<': 15, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '611467', 'n_tokens_mistral': 4332, 'n_tokens_neox': 4214, 'n_words': 813}