[Pkg-mozext-commits] [nostalgy] 155/235: support for predicting target folder given the email addresses (contributed by John Gray)

David Prévot taffit at alioth.debian.org
Tue Oct 8 20:42:10 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository nostalgy.

commit d55513515a0295bed35fe0b5947ef64156251d8c
Author: frisch <frisch at 56b81dcf-5a2f-0410-9db0-014be2e416ff>
Date:   Sat May 30 06:24:17 2009 +0000

    support for predicting target folder given the email addresses (contributed by John Gray)
    
    git-svn-id: http://nostalgy.googlecode.com/svn/trunk@155 56b81dcf-5a2f-0410-9db0-014be2e416ff
---
 CHANGES                        |    4 +
 content/edit_prefs.xul         |    4 +-
 content/folders.js             |   30 ++++-
 content/messageOverlay.xul     |    2 +
 content/nfpredict.js           |  239 ++++++++++++++++++++++++++++++++++++++++
 content/nostalgy.js            |   10 ++
 content/sqlite.js              |   75 +++++++++++++
 content/thunderbirdOverlay.xul |    2 +
 files                          |    2 +
 9 files changed, 365 insertions(+), 3 deletions(-)

diff --git a/CHANGES b/CHANGES
index 0ae8e52..56d20fd 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+Since 0.2.17
+  - integrate support for predicting target folder given the email addresses (contributed by John Gray)
+
+
 0.2.17
   - fix bugs with TB 3
   - allow it to run with TB 3.0b3
diff --git a/content/edit_prefs.xul b/content/edit_prefs.xul
index 58cfc41..216ba47 100644
--- a/content/edit_prefs.xul
+++ b/content/edit_prefs.xul
@@ -80,7 +80,9 @@ shortcuts to move/copy the message to this folder.</label>
    <checkbox label="Tab triggers shell-like completion (otherwise, cycle through suggestions)"
              id="tab_shell_completion" accesskey="T"/>
    <checkbox label="Always include tags"
-             id="always_include_tags"/> 
+             id="always_include_tags"/>
+   <checkbox label="Use Statistical Prediction"
+             id="use_statistical_prediction"/>
  </groupbox>
  </tabpanel>
 
diff --git a/content/folders.js b/content/folders.js
index 81cf081..8569a9e 100644
--- a/content/folders.js
+++ b/content/folders.js
@@ -6,6 +6,7 @@ var nostalgy_completion_options = {
   match_case_sensitive : false,
   tab_shell_completion : false,
   always_include_tags  : false,
+  use_statistical_prediction: false,
 
   /* not related to completion: should move to somewhere else */
   always_show_search_mode : false
@@ -162,8 +163,33 @@ function(text, results, listener) {
  var f = function (folder) { add_folder(folder_name(folder)); };
  
  if (text == "") {
-   for (var j = 0; j < nostalgy_recent_folders.length; j++)
-     add_folder(nostalgy_recent_folders[j]);
+	 var added_count=0;
+	if ( nostalgy_completion_options.use_statistical_prediction )
+	{
+		var predictedFolders = null;
+		try { predictedFolders = NostalgyPredict.predict_folder(nostalgy_recent_folders_max_size); }
+		catch (ex) { }
+		if( predictedFolders != null && predictedFolders.length > 0 )
+			for( var j = 0; j < predictedFolders.length; j++ )
+				if ( added_count < nostalgy_recent_folders_max_size )
+				{
+					f(predictedFolders[j]);
+					added_count++;
+				}
+	}
+	for ( j = 0; j < nostalgy_recent_folders.length; j++)
+	{
+		var found=0;
+		if ( nostalgy_completion_options.use_statistical_prediction && predictedFolders != null && predictedFolders.length > 0)
+			for( var i=0; i < predictedFolders.length; i++ )
+				if (folder_name(predictedFolders[i]) == nostalgy_recent_folders[j] )
+					found=1;
+		if ( found==0 && added_count < nostalgy_recent_folders_max_size )
+		{
+			add_folder(nostalgy_recent_folders[j]);
+			added_count++;
+		}
+	}
  } else {
    nostalgy_search_folder_options.do_tags =
      nostalgy_completion_options.always_include_tags ||
diff --git a/content/messageOverlay.xul b/content/messageOverlay.xul
index 4752b2a..eace518 100644
--- a/content/messageOverlay.xul
+++ b/content/messageOverlay.xul
@@ -6,6 +6,8 @@
  <script src="misc.js"/>
  <script src="folders.js"/>
  <script src="nostalgy_keys.js"/>
+ <script src="sqlite.js"/>
+ <script src="nfpredict.js"/>
  <script src="nostalgy.js"/>
 
  <commandset id="tasksCommands">
diff --git a/content/nfpredict.js b/content/nfpredict.js
new file mode 100644
index 0000000..4d078e9
--- /dev/null
+++ b/content/nfpredict.js
@@ -0,0 +1,239 @@
+//some variables :
+//assuming db file is in user's profile directory:
+var myDBFile = 'nfpredict.sqlite';
+
+var myCreateTablesQuery1 = 'CREATE TABLE IF NOT EXISTS addresses (id INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT, count INTEGER)';
+var myCreateTablesQuery2 = 'CREATE TABLE IF NOT EXISTS folders (id INTEGER PRIMARY KEY AUTOINCREMENT, folder TEXT)';
+var myCreateTablesQuery3 = 'CREATE TABLE IF NOT EXISTS probabilities (id INTEGER PRIMARY KEY AUTOINCREMENT, address_id INTEGER, folder_id INTEGER, probability REAL, count INTEGER)';
+
+var myPredictQueryA = 'SELECT avg(probabilities.count*100/addresses.count) as prob,folder FROM addresses,folders,probabilities '+
+    'WHERE probabilities.address_id=addresses.id AND  probabilities.folder_id=folders.id AND addresses.address in (';
+var myPredictQueryB = ') group by folder order by prob desc limit ';
+
+var myFolderQuery = 'SELECT * FROM folders where folder = ?1';
+var myFolderInsert = 'INSERT INTO folders(folder) VALUES(?1);';
+
+var myAddressQuery = 'SELECT * FROM addresses where address = ?1';
+var myAddressInsert = 'INSERT INTO addresses(address,count) VALUES(?1,0);';
+var myGetAddressCount = 'SELECT count FROM addresses where id = ?1';
+var myUpdateAddressCount = 'UPDATE addresses SET count=?2 WHERE id=?1;';
+
+var myProbabilityInsert = 'INSERT INTO probabilities(address_id , folder_id , probability , count) VALUES(?1,?2,?3,?4);';
+var myUpdateProbabilityCount = 'UPDATE probabilities SET count=?2, probability=?3 WHERE id=?1;';
+
+var myCountsQuery = 'SELECT distinct addresses.id as address_id, addresses.count as address_count, probabilities.id as probability_id, probabilities.count as probability_count '+
+    'FROM addresses, folders, probabilities WHERE addresses.id=probabilities.address_id AND probabilities.folder_id=?1 AND addresses.address=?2;';
+
+var myCountsQueryAll = 'SELECT distinct addresses.id as address_id, addresses.count as address_count, probabilities.id as probability_id, probabilities.count as probability_count FROM addresses, folders, probabilities WHERE addresses.id=probabilities.address_id;';
+
+var myGetMaintValues = 'select probabilities.*,addresses.count as addr_count from probabilities, addresses where probabilities.address_id=addresses.id;';
+
+// For anything other than SELECT statement, use $sqlite.cmd() :
+
+var NostalgyPredict =
+{
+    inited: false,
+
+    emails: {},
+
+    init: function() {
+        this.inited = true;
+
+        var prefs = (Components.classes["@mozilla.org/preferences-service;1"].
+                     getService(Components.interfaces.nsIPrefService));
+
+        for (var i = 1; i <= 20; i++) {
+            try {
+                this.emails[prefs.getCharPref("mail.identity.id" + i + ".useremail")] = 1;
+            } catch (ex) { }
+        }
+
+        this.createDB(); // Its safe to ask to create the db even if its already set up
+
+        //this.update_probabilites();
+    },
+
+    getDBFile: function() {
+        return myDBFile;
+    },
+
+    createDB: function() {
+    // creating a DB:
+        $sqlite.cmd(this.getDBFile(),myCreateTablesQuery1);
+        $sqlite.cmd(this.getDBFile(),myCreateTablesQuery2);
+        $sqlite.cmd(this.getDBFile(),myCreateTablesQuery3);
+    },
+
+    dbExists: function() {
+        // get profile directory
+        var file = (Components.classes["@mozilla.org/file/directory_service;1"].
+                    getService(Components.interfaces.nsIProperties).
+                    get("ProfD", Components.interfaces.nsIFile));
+        file.append(myDBFile);
+
+        return file.exists();
+    },
+
+    keep_email: function(s) {
+        if (this.emails[s]) return false; else return true;
+    },
+
+    predict_folder: function (numPredictions) {
+        try {
+            if ( this.inited==false )
+                this.init();
+
+            if (gDBView!=null) {
+                var hdr = gDBView.hdrForFirstSelectedMessage;
+                var addresses = (hdr.author + ", " + hdr.recipients + ", " + hdr.ccList).toLowerCase();
+
+                var addrs = "";
+
+                email_re = /(([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+)/;
+                var aAdresses = addresses.split(email_re);
+                for (var i=0; i < aAdresses.length; i++) {
+                    if (aAdresses[i].match(email_re) && this.keep_email(aAdresses[i]) ) {
+                        if ( addrs.length != 0 )
+                            addrs = addrs + ", ";
+                        addrs = addrs + "\'" + aAdresses[i] +  "\'";
+                    }
+                }
+                NostalgyDebug("addrs = " + addrs);
+                try {
+                    /*
+                    var myArray1 = $sqlite.select(this.getDBFile(),myCountsQueryAll);
+                    NostalgyDebug("length: "+myArray1.length);
+                    for(var i = 0; i < myArray1.length; i++ ) {
+                        NostalgyDebug("i = " + i);
+                        for (var k in myArray1[i]) {
+                            NostalgyDebug("row[" + k + "] = " + myArray1[i][k]);
+                        }
+                    }
+                    */
+
+                    var myArray1 = $sqlite.select(this.getDBFile(),myPredictQueryA+addrs+myPredictQueryB+numPredictions+';');
+                    NostalgyDebug(myPredictQueryA+addrs+myPredictQueryB);
+                    NostalgyDebug("myArray1.length: "+myArray1.length);
+                    if ( myArray1.length > 0 ) {
+                        //NostalgyDebug(myArray1[0]['folder'] +": "+myArray1[0]['prob']);
+                        for( i = 0; i < myArray1.length; i++ ) {
+                            NostalgyDebug(myArray1[i]['folder'] +": "+myArray1[i]['prob']);
+                            if ( parseFloat(myArray1[i]['prob']) > 0.5 ) {
+                                var uri = myArray1[i]['folder'];
+
+                                var ret = null;
+                                var save_req = nostalgy_search_folder_options.require_file;
+                                nostalgy_search_folder_options.require_file = false;
+                                try {
+                                    IterateFoldersAllServers(function (folder) {
+                                            //NostalgyDebug(folder.URI);
+                                            if (folder.URI == uri) { ret = folder; throw(0); }
+                                        });
+                                } catch (ex) { }
+                                nostalgy_search_folder_options.require_file = save_req;
+                                myArray1[i] = ret;
+                            }
+                            else
+                                myArray1[i] = null;
+                        }
+
+                        if( numPredictions == 1 ) return myArray1[0];
+                        else return myArray1;
+                    }
+                }
+                catch(ex) {
+                    NostalgyDebug( ex.toString() );
+                }
+            }
+            else { }
+        }
+        catch (ex) {
+            // gDBView.hdrForFirstSelectedMessage was called without a select message
+            //NostalgyDebug( ex.toString() );
+        }
+        return null;
+    },
+
+    find_generic_id: function (value,insertQ,selectQ) {
+        while ( true ) {
+            var myArray1 = $sqlite.select(this.getDBFile(),selectQ,value);
+            if ( myArray1.length >= 1 )
+                return myArray1[0]['id'];
+            else
+                $sqlite.cmd(this.getDBFile(),insertQ,value);
+        }
+    },
+
+    find_folder_id: function find_folder_id(folder) {
+        return this.find_generic_id(folder,myFolderInsert,myFolderQuery);
+    },
+
+    find_address_id: function (address) {
+        return this.find_generic_id(address,myAddressInsert,myAddressQuery);
+    },
+
+    update_probabilites : function() {
+        var myArray1 = $sqlite.select(this.getDBFile(),myCountsQueryAll);
+        for(var j=0;j<myArray1.length;j++) {
+            var addr_count = parseInt(myArray1[j]["address_count"]);
+            var prob_count = parseInt(myArray1[j]["probability_count"]);
+            var prob = parseFloat(prob_count)/parseFloat(addr_count);
+
+            //NostalgyDebug(myUpdateProbabilityCount+" "+myArray1[j]["probability_id"]+" "+prob_count+" "+prob);
+            $sqlite.cmd(this.getDBFile(),myUpdateProbabilityCount,myArray1[j]["probability_id"],prob_count,prob);
+        }
+    },
+
+    update_folder: function (nsiFolder) {
+        if ( this.inited==false )
+            this.init();
+
+        var folder = nsiFolder.URI;
+
+        var hdr = gDBView.hdrForFirstSelectedMessage;
+        var addresses = (hdr.author + " " + hdr.recipients + " " + hdr.ccList).toLowerCase();
+
+
+        var folder_id=this.find_folder_id(folder);
+
+        email_re = /(([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+)/;
+        var aAdresses = addresses.split(email_re);
+        for (var i=0; i < aAdresses.length; i++) {
+            //NostalgyDebug(aAdresses[i]);
+            if (aAdresses[i].match(email_re) && this.keep_email(aAdresses[i]) ) {
+                //NostalgyDebug(myCountsQuery+" "+folder_id+" "+aAdresses[i]);
+                var myArray1 = $sqlite.select(this.getDBFile(),myCountsQuery,folder_id,aAdresses[i]);
+                if (myArray1.length==0) {
+                    // Add address if necessary
+                    address_id=this.find_address_id(aAdresses[i]);
+
+                    var myArray2 = $sqlite.select(this.getDBFile(),myGetAddressCount,address_id);
+                    if (myArray2.length!=0) { // This should never fail
+                        var addr_count = 1+parseInt(myArray2[0]["count"]);
+                        var prob_count = 1;
+                        var prob = parseFloat(prob_count)/parseFloat(addr_count);
+
+                        //NostalgyDebug(myUpdateAddressCount+" "+address_id+" "+addr_count);
+                        $sqlite.cmd(this.getDBFile(),myUpdateAddressCount,address_id,addr_count);
+
+                        $sqlite.cmd(this.getDBFile(),myProbabilityInsert,address_id,folder_id,prob,prob_count);
+                    }
+                }
+                else {
+                    //NostalgyDebug(myArray1.length);
+                    for(var j=0;j<myArray1.length;j++) {
+                        var addr_count = 1+parseInt(myArray1[j]["address_count"]);
+                        var prob_count = 1+parseInt(myArray1[j]["probability_count"]);
+                        var prob = parseFloat(prob_count)/parseFloat(addr_count);
+
+                        //NostalgyDebug(myUpdateAddressCount+" "+myArray1[j]["address_id"]+" "+addr_count);
+                        $sqlite.cmd(this.getDBFile(),myUpdateAddressCount,myArray1[j]["address_id"],addr_count);
+
+                        //NostalgyDebug(myUpdateProbabilityCount,myArray1[j]["probability_id"]+" "+prob_count+" "+prob);
+                        $sqlite.cmd(this.getDBFile(),myUpdateProbabilityCount,myArray1[j]["probability_id"],prob_count,prob);
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/content/nostalgy.js b/content/nostalgy.js
index c50e641..03dad21 100644
--- a/content/nostalgy.js
+++ b/content/nostalgy.js
@@ -543,6 +543,13 @@ function NostalgySuggest() {
   if (r) { return(r); }
  } catch (ex) { NostalgyDebug("ex:" + ex);  }
 
+if ( nostalgy_completion_options.use_statistical_prediction )
+{
+ try {
+  r = NostalgyPredict.predict_folder(1);
+  if (r) { return(r); }
+ } catch (ex) { NostalgyDebug("ex:" + ex);  }
+}
 // r = last_folder_author[MailAuthor()];
 // if (r) { return(r); }
 
@@ -680,6 +687,7 @@ function NostalgyToggleMessageTag(tag) {
 
 function NostalgyMoveToFolder(folder) {
  register_folder(folder);
+ NostalgyPredict.update_folder(folder);
  SetNextMessageAfterDelete();
  if (folder.tag) NostalgyToggleMessageTag(folder);
  else gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages,folder);
@@ -688,6 +696,7 @@ function NostalgyMoveToFolder(folder) {
 
 function NostalgyMoveToFolderAndGo(folder) {
  register_folder(folder);
+ NostalgyPredict.update_folder(folder);
  var sel = NostalgySaveSelection();
  if (folder.tag) NostalgyToggleMessageTag(folder);
  else gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages,folder);
@@ -702,6 +711,7 @@ function NostalgyMoveToFolderAndGo(folder) {
 
 function NostalgyCopyToFolder(folder) {
  register_folder(folder);
+ NostalgyPredict.update_folder(folder);
  if (folder.tag) NostalgyToggleMessageTag(folder);
  else gDBView.doCommandWithFolder(nsMsgViewCommandType.copyMessages,folder);
  return true;
diff --git a/content/sqlite.js b/content/sqlite.js
new file mode 100644
index 0000000..2a8f73e
--- /dev/null
+++ b/content/sqlite.js
@@ -0,0 +1,75 @@
+var $sqlite = {
+	storageService: [],
+	mDBConn: [],
+	
+	_initService : function(file){
+		var db = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
+		db.append(file);
+		this.storageService[file] = Components.classes["@mozilla.org/storage/service;1"].getService(Components.interfaces.mozIStorageService);
+		this.mDBConn[file] = (this.storageService[file]).openDatabase(db);
+			
+	},
+	
+	select : function(file,sql,param){
+		if (this.storageService[file]== undefined){
+                    this._initService(file);
+		}
+		var ourTransaction = false;
+		if ((this.mDBConn[file]).transactionInProgress){
+			ourTransaction = true;
+			(this.mDBConn[file]).beginTransactionAs((this.mDBConn[file]).TRANSACTION_DEFERRED);
+		}
+		var statement = (this.mDBConn[file]).createStatement(sql);
+                if (param){
+			for (var m=2, arg=null; arg=arguments[m]; m++) {
+				statement.bindUTF8StringParameter(m-2, arg);
+			}
+		}
+		try{
+			var dataset = [];
+			while (statement.executeStep()){
+				var row = [];
+				for(var i=0,k=statement.columnCount; i<k; i++){
+					row[statement.getColumnName(i)] = statement.getUTF8String(i);
+				}
+				dataset.push(row);
+			}
+			// return dataset;	
+		}
+		finally {
+			statement.reset();
+		}
+		if (ourTransaction){
+			(this.mDBConn[file]).commitTransaction();
+		}
+        return dataset;	
+	},
+	
+	
+	cmd : function(file,sql,param){
+		if (this.storageService[file] == undefined){
+	                    this._initService(file);
+		}
+		var ourTransaction = false;
+		if ((this.mDBConn[file]).transactionInProgress){
+			ourTransaction = true;
+			(this.mDBConn[file]).beginTransactionAs((this.mDBConn[file]).TRANSACTION_DEFERRED);
+		}
+		var statement = (this.mDBConn[file]).createStatement(sql);
+		if (param){
+			for (var m=2, arg=null; arg=arguments[m]; m++) {
+				statement.bindUTF8StringParameter(m-2, arg);
+			}
+		}
+		try{
+			statement.execute();
+		}
+		finally {
+			statement.reset();
+		}
+		if (ourTransaction){
+			(this.mDBConn[file]).commitTransaction();
+		}
+	}	
+
+}
diff --git a/content/thunderbirdOverlay.xul b/content/thunderbirdOverlay.xul
index 527f6d0..080e635 100644
--- a/content/thunderbirdOverlay.xul
+++ b/content/thunderbirdOverlay.xul
@@ -6,6 +6,8 @@
  <script src="misc.js"/>
  <script src="folders.js"/>
  <script src="nostalgy_keys.js"/>
+ <script src="sqlite.js"/>
+ <script src="nfpredict.js"/>
  <script src="nostalgy.js"/>
 
  <commandset id="tasksCommands">
diff --git a/files b/files
index 8d41090..1f4d563 100644
--- a/files
+++ b/files
@@ -12,9 +12,11 @@ content/edit_rule.xul
 content/folders.js
 content/messageOverlay.xul
 content/misc.js
+content/nfpredict.js
 content/nostalgy.js
 content/nostalgy.js.orig
 content/nostalgy_keys.js
+content/sqlite.js
 content/thunderbirdOverlay.xul
 locale/en-US/nostalgy.dtd
 locale/en-US/nostalgy.properties

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/nostalgy.git



More information about the Pkg-mozext-commits mailing list