[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