Changeset 509348 for modules/vI_smartIdentityCollection.js
- Timestamp:
- Nov 3, 2014, 12:35:40 PM (8 years ago)
- Branches:
- ng_0.9
- Children:
- 7204cb
- Parents:
- 3c9c29
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
modules/vI_smartIdentityCollection.js
r3c9c29 r509348 33 33 34 34 function smartIdentityCollection(msgHdr, preseletedID, currentIDisVID, newsgroup, recipients) { 35 36 37 38 39 40 41 42 35 this._IDisVID = currentIDisVID; 36 this._preselectedID = preseletedID; 37 this._msgHdr = msgHdr; 38 this._newsgroup = newsgroup; 39 this._unicodeConverter.charset = "UTF-8"; 40 this._recipients = recipients; 41 this._rdfDatasourceAccess = new rdfDatasourceAccess(); 42 this._allIdentities = new identityCollection(); 43 43 }; 44 44 45 45 smartIdentityCollection.prototype = { 46 messenger : Components.classes["@mozilla.org/messenger;1"].createInstance() 47 .QueryInterface(Components.interfaces.nsIMessenger), 48 _unicodeConverter : Components.classes["@mozilla.org/intl/scriptableunicodeconverter"] 49 .createInstance(Components.interfaces.nsIScriptableUnicodeConverter), 50 _headerParser : Components.classes["@mozilla.org/messenger/headerparser;1"] 51 .getService(Components.interfaces.nsIMsgHeaderParser), 52 53 _msgComposeTypeReference : Components.interfaces.nsIMsgCompType, 54 55 _IDisVID : false, 56 _preselectedID : null, 57 _allIdentities : null, 58 _selectedValue : null, 59 _newsgroup : null, 60 _rdfDatasourceAccess : null, 61 62 // this function adds a timestamp to the current sender 63 __autoTimestamp : function() { 64 Log.debug("__autoTimestamp()"); 65 if (this._IDisVID) { 66 Log.debug("Virtual Identity in use, aborting"); 67 return; 68 } 69 70 var current_email = this._preselectedID.email.split("@"); 71 var localpart = current_email[0]; 72 var domain = current_email[1]; 73 74 Log.debug("current email: " + current_email[0] + "@" + current_email[1]); 75 76 var autoString = vIprefs.get("autoString"); 77 var formatString = vIprefs.get("autoTimeFormat"); 78 79 var dateObj = new Date(); var dateString = ""; 80 if (formatString == "") dateString = parseInt(dateObj.getTime()/1000); 81 else try { // you never know what the formatString will be... 82 dateString = dateObj.toLocaleFormat(formatString).replace(/\s+|[\x00-\x2a]|\x2c|\x2f|[\x3a-\x40]|[\x5b-\x5d]|\x60|\x7c|[\x7f-\xff]/g,"_"); 83 } catch(e) { }; 84 85 var new_email = autoString.replace(/%l/g, localpart).replace(/%d/g, domain).replace(/%t/g,dateString); 86 Log.debug("new email: " + new_email); 87 88 var newIdentity = new identityData(new_email, 89 this._preselectedID.fullName, this._preselectedID.key, this._preselectedID.smtpServerKey, null, null) 90 91 this._allIdentities.addWithoutDuplicates(newIdentity); 92 this._selectedValue = 0; 93 }, 94 95 __ignoreID : function() { 96 Log.debug("checking " + vIprefs.get("idSelection_ignoreIDs") + " against " + this._preselectedID.key ) 97 // check if usage if virtual Identities should be used at all for the currently selected ID 98 if (vIprefs.get("idSelection_ignoreIDs").indexOf(":" + this._preselectedID.key + ":") != -1) { 99 Log.debug("not using virtual Identites for ID " + this._preselectedID.key); 100 return true; 101 } 102 return false 103 }, 104 105 NewMail : function() { 106 Log.debug("NewMail()"); 107 if (this.__ignoreID()) return; 108 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(this._allIdentities, this._recipients); 109 if (this._allIdentities.number == 0 && vIprefs.get("autoTimestamp")) this.__autoTimestamp(); 110 }, 111 112 _foundExistingIdentity : function() { 113 /* compare with existing Identities */ 114 for (var index = 0; index < this._allIdentities.number; index++) { 115 var existingID = this._allIdentities.identityDataCollection[index].isExistingIdentity(false); 116 if (existingID) { 117 this._allIdentities.identityDataCollection[index].id.key = existingID; // set found identity 118 // reorder list of Identities to prefer it on autoselect 119 // has to be done before Identities are added to the Menu 120 Log.debug("found existing Identity, reorder to prefer this one."); 121 var firstIdentity = this._allIdentities.identityDataCollection[index]; 122 for (var i = index; index > 0; index--) { 123 this._allIdentities.identityDataCollection[index] = this._allIdentities.identityDataCollection[index-1]; 124 } 125 this._allIdentities.identityDataCollection[0] = firstIdentity; 126 return { key: index }; 127 } 128 } 129 return null; 130 }, 131 132 ReplyOnSent : function() { 133 Log.debug("ReplyOnSent() (rules like SmartDraft)"); 134 this.__SmartDraftOrReplyOnSent(); 135 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(this._allIdentities, this._recipients); 136 }, 137 138 Draft : function() { 139 Log.debug("Draft()"); 140 141 this.__SmartDraftOrReplyOnSent(); 142 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(this._allIdentities, this._recipients); 143 }, 144 145 __parseHeadersWithArray: function(header, identityCollection) { 146 var emails = {}; var fullNames = {}; var combinedNames = {}; 147 var number = this._headerParser.parseHeadersWithArray(header, emails, fullNames, combinedNames); 148 for (var index = 0; index < number; index++) { 149 var newIdentity = new identityData(emails.value[index], fullNames.value[index], 150 null, NO_SMTP_TAG, null, null); 151 identityCollection.addWithoutDuplicates(newIdentity); 152 } 153 }, 154 155 // this function checks if we have a draft-case and Smart-Draft should replace the Identity 156 __SmartDraftOrReplyOnSent : function() { 157 if (!vIprefs.get("smart_draft")) 158 { Log.debug("SmartDraft deactivated"); return; } 159 160 Log.debug("__SmartDraftOrReplyOnSent()"); 161 162 if (this._msgHdr) { 163 this.__parseHeadersWithArray(this._msgHdr.author, this._allIdentities) 164 Log.debug("sender '" + this._allIdentities.identityDataCollection[0].combinedName + "'"); 165 } 166 else Log.debug("__SmartDraftOrReplyOnSent: No Header found, shouldn't happen"); 167 }, 168 169 __filterAddresses : function() { 170 var returnIdentities = new identityCollection(); 171 172 var filterList = 173 this._unicodeConverter.ConvertToUnicode(vIprefs.get("smart_reply_filter")).split(/\n/) 174 if (filterList.length == 0) filterList[0] == "" 175 176 for (var i = 0; i < filterList.length; i++) { 177 const filterType = { None : 0, RegExp : 1, StrCmp : 2 } 178 var recentfilterType; var skipRegExp = false; 179 if (filterList.length <= 1 && filterList[0] == "") { 180 Log.debug("no filters configured"); 181 recentfilterType = filterType.None; 182 } 183 else if (/^[+-]?\/(.*)\/$/.exec(filterList[i])) { 184 Log.debug("filter emails with RegExp '" + filterList[i].replace(/\\/g,"\\\\") + "'"); 185 recentfilterType = filterType.RegExp; 186 } 187 else { 188 Log.debug("filter emails, compare with '" + filterList[i] + "'"); 189 recentfilterType = filterType.StrCmp; 190 } 191 for (var j = 0; j < this._allIdentities.number; j++) { // check if recent email-address (pre-choosen identity) is found in 192 // copied and adapted from correctIdentity, thank you for the RegExp-idea! 193 var add_addr = false; 194 switch (recentfilterType) { 195 case filterType.None: 196 add_addr = true; break; 197 case filterType.RegExp: 198 if (skipRegExp) break; 199 try { /^[+-]?\/(.*)\/$/.exec(filterList[i]); 200 if ( filterList[i][0] == "-" ) { 201 if (this._allIdentities.identityDataCollection[j].email.match(new RegExp(RegExp.$1,"i"))) 202 this._allIdentities.dropIdentity(j--); 203 } else 204 add_addr = (this._allIdentities.identityDataCollection[j].email.match(new RegExp(RegExp.$1,"i"))); 205 } 206 catch(vErr) { 207 this.stringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"] 208 .getService(Components.interfaces.nsIStringBundleService) 209 .createBundle("chrome://v_identity/locale/v_identity.properties"); 210 SmartReplyNotification.info( 211 this.stringBundle.GetStringFromName("vident.smartIdentity.ignoreRegExp") + 212 +filterList[i].replace(/\\/g,"\\\\") + " ."); 213 skipRegExp = true; } 214 break; 215 case filterType.StrCmp: 216 add_addr = ( this._allIdentities.identityDataCollection[j].email.toLowerCase().indexOf(filterList[i].toLowerCase()) != -1) 217 break; 218 } 219 if (add_addr) returnIdentities.addWithoutDuplicates(this._allIdentities.identityDataCollection[j]) 220 } 221 } 222 this._allIdentities.takeOver(returnIdentities); 223 }, 224 225 __smartReplyCollectAddresses : function() { 226 // add emails from selected headers (stored by vI_getHeader.xul/js) 227 var reply_headers = this._unicodeConverter.ConvertToUnicode(vIprefs.get("smart_reply_headers")).split(/\n/) 228 229 for (var index = 0; index < reply_headers.length; index++) { 230 // ------------- prepare fields to read the stored header ---------------- 231 var replyHeader_splitted = reply_headers[index].split(/:/) 232 // use first part (all before ':') as the header name 233 var replyHeaderName = replyHeader_splitted[0].toLowerCase() 234 // check second or third part for any number 235 var replyHeaderNumber = null; 236 if (replyHeader_splitted.length > 1) parseInt(replyHeader_splitted[1]); 237 if ((!replyHeaderNumber || isNaN(replyHeaderNumber)) && replyHeader_splitted.length > 2) replyHeaderNumber = parseInt(replyHeader_splitted[2]); 238 // check if Fullnames should be erased 239 var replyHeaderEmptyFullNames = ((replyHeader_splitted[1] && replyHeader_splitted[1].match(/@/)) || 240 (replyHeader_splitted[2] && replyHeader_splitted[2].match(/@/))); 241 242 // create header name to find the value 243 var replyHeaderNameToRead = replyHeaderName 244 if (replyHeaderNumber && !isNaN(replyHeaderNumber)) replyHeaderNameToRead += ":" + replyHeaderNumber 245 246 // if mailing-list ignore to-header (usually the mailing list address) 247 if (replyHeaderNameToRead == "to" && this._msgHdr.getStringProperty("vI_list-id")) { 248 Log.debug("header 'list-id' found (mailinglist), skipping header 'to'"); 249 continue; 250 } 251 252 // ------------- read the stored header ------------------------------- 253 var value = this._unicodeConverter.ConvertToUnicode(this._msgHdr.getStringProperty("vI_" + replyHeaderNameToRead)) 254 /* let window3pane = Components.classes['@mozilla.org/appshell/window-mediator;1'] 255 .getService(Components.interfaces.nsIWindowMediator) 256 .getMostRecentWindow("mail:3pane"); 257 258 Log.debug("found stored header '" + 259 replyHeaderNameToRead + "': '" + window3pane.virtualIdentityExtension.storedHeaders["vI_" + replyHeaderNameToRead] + "'");*/ 260 261 Log.debug("reading header '" + 262 replyHeaderNameToRead + "': '" + value + "'"); 263 264 // ------------- parse address-string to get a field of single email-addresses 265 var splitted = new identityCollection(); 266 this.__parseHeadersWithArray(value, splitted); 267 268 // move found addresses step by step to this._allIdentities, and change values if requested 269 for (var i = 0; i < splitted.number; i++) { 270 // if there is no email than it makes no sense to use it as a sender 271 if (!splitted.identityDataCollection[i].email.match(/^.*@.*$/)) { 272 Log.debug(" skipping '" + 273 splitted.identityDataCollection[i].email + "', no email") 274 continue; 275 } 276 277 if (replyHeaderEmptyFullNames) splitted.identityDataCollection[i].fullName = "" 278 279 this._allIdentities.addWithoutDuplicates(splitted.identityDataCollection[i]); 280 281 Log.debug(" found '" + 282 splitted.identityDataCollection[i].combinedName + "'") 283 } 284 } 285 }, 286 287 Reply : function() { 288 Log.debug("Reply()"); 289 290 if (this._msgHdr && !this._newsgroup && !this._msgHdr.getStringProperty("vI_content_base")) { 291 // RFC 2821 (http://www.ietf.org/rfc/rfc2821.txt) says: 292 // "4.4 Trace Information 293 // When an SMTP server receives a message for delivery or further 294 // processing, it MUST insert trace ("time stamp" or "Received") 295 // information at the beginning of the message content, as discussed in 296 // section 4.1.1.4." 297 // so it should be always possible to decide if Reply or Draft based on received headers 298 // hidden option smart_detectByReceivedHeader will act as a switch for not RFC-compliant servers 299 // RFC-compliant 300 if (vIprefs.get("smart_detectByReceivedHeader")) { 301 if (!this._msgHdr.getStringProperty("vI_received")) { // mail was not received 302 Log.debug("reply on non-received (sent?) mail. Using SmartDraft."); 303 this.ReplyOnSent(); 304 return; 305 } 306 } 307 // not RFC-compliant 308 else { 309 const MSG_FOLDER_FLAG_INBOX = 0x1000 310 const MSG_FOLDER_FLAG_SENTMAIL = 0x0200; 311 312 if (this._msgHdr && (this._msgHdr.folder.flags & MSG_FOLDER_FLAG_SENTMAIL)) { 313 if (this._msgHdr.folder.flags & MSG_FOLDER_FLAG_INBOX) 314 Log.debug("reply from Sent folder. Folder is INBOX, assuming Reply-Case."); 315 else { 316 Log.debug("reply from Sent folder. Using SmartDraft."); 317 this.ReplyOnSent(); 318 return; 319 } 320 } 321 } 322 } 323 324 if (this.__ignoreID()) return; 325 326 var storageIdentities = new identityCollection(); 327 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(storageIdentities, this._recipients); 328 329 if (storageIdentities.number == 0 || !vIprefs.get("idSelection_storage_ignore_smart_reply")) 330 this.__SmartReply(); 331 else Log.debug("SmartReply skipped, Identities in Storage found."); 332 333 // merge SmartReply-Identities and Storage-Identites 334 if (vIprefs.get("idSelection_storage_prefer_smart_reply")) 335 { this._allIdentities.mergeWithoutDuplicates(storageIdentities); } 336 else { 337 var smartIdentities = this._allIdentities; 338 this._allIdentities = storageIdentities; 339 this._allIdentities.mergeWithoutDuplicates(smartIdentities); 340 } 341 342 Log.debug("merged SmartReply & Storage, " + this._allIdentities.number + " address(es) left") 343 }, 344 345 // this function checks if we have a reply-case and Smart-Reply should replace the Identity 346 __SmartReply : function() { 347 if (!vIprefs.get("smart_reply")) 348 { Log.debug("SmartReply deactivated"); return; } 349 if (this._newsgroup && !vIprefs.get("smart_reply_for_newsgroups")) { 350 Log.debug("SmartReply, answering to a newsgroup, aborting"); 351 return; 352 } 353 354 Log.debug("__SmartReply()"); 355 Log.debug("----------------------------------------------------------") 356 if (this._msgHdr) { 357 /* first step: collect addresses */ 358 this.__smartReplyCollectAddresses(); 359 Log.debug("" + this._allIdentities.number + " address(es) after parsing, before filtering") 360 361 /* second step: filter (and sort) addresses */ 362 this.__filterAddresses(); 363 364 Log.debug("filtering done, " + this._allIdentities.number + " address(es) left") 365 366 /* set default FullName */ 367 var smart_reply_defaultFullName = this._unicodeConverter.ConvertToUnicode(vIprefs.get("smart_reply_defaultFullName")) 368 if (smart_reply_defaultFullName != "") { 369 for (var index = 0; index < this._allIdentities.number; index++) { 370 if (this._allIdentities.identityDataCollection[index].fullName == "") { 371 this._allIdentities.identityDataCollection[index].fullName = smart_reply_defaultFullName 372 Log.debug("added default FullName '" + 373 smart_reply_defaultFullName + "' to '" + this._allIdentities.identityDataCollection[index].email + "'") 374 } 375 } 376 } 377 378 /* smart_reply_ignoreFullName: compare email with other Identities */ 379 /* if match replace FullName with existing one, keep identity in list by now */ 380 /* will not be added to the menu but probably choosen with __smartIdentitySelection */ 381 if (vIprefs.get("smart_reply_ignoreFullName")) { 382 Log.debug("compare with existing Identities (ignoring FullNames).") 383 384 for (var index = 0; index < this._allIdentities.number; index++) { 385 var idKey = this._allIdentities.identityDataCollection[index].isExistingIdentity(true); 386 if (idKey) { 387 var AccountManager = Components.classes["@mozilla.org/messenger/account-manager;1"] 388 .getService(Components.interfaces.nsIMsgAccountManager); 389 var newFullName = AccountManager.getIdentity(idKey).fullName; 390 this._allIdentities.identityDataCollection[index].fullName = newFullName; 391 Log.debug("replaced Fullname of '" + this._allIdentities.identityDataCollection[index].email + "' with '" + newFullName + "'"); 392 } 393 } 394 } 395 396 /* smart_reply_searchBaseIdentity: compare email with other Identities */ 397 /* to find matching domain. Use first found as base identity (smtp etc) */ 398 if (vIprefs.get("smart_reply_searchBaseIdentity")) { 399 Log.debug("compare domain name with existing accounts.") 400 401 for (var index = 0; index < this._allIdentities.number; index++) { 402 var idKey = this._allIdentities.identityDataCollection[index].hasMatchingDomainIdentity(); 403 if (idKey) { 404 Log.debug("use id with matching domain as base ID"); 405 this._allIdentities.identityDataCollection[index].id.key = idKey; 406 } 407 } 408 } 409 410 } 411 else Log.debug("SmartReply skipped. No Header-information found."); 412 413 Log.debug("----------------------------------------------------------") 414 }, 415 46 messenger: Components.classes["@mozilla.org/messenger;1"].createInstance() 47 .QueryInterface(Components.interfaces.nsIMessenger), 48 _unicodeConverter: Components.classes["@mozilla.org/intl/scriptableunicodeconverter"] 49 .createInstance(Components.interfaces.nsIScriptableUnicodeConverter), 50 _headerParser: Components.classes["@mozilla.org/messenger/headerparser;1"] 51 .getService(Components.interfaces.nsIMsgHeaderParser), 52 53 _msgComposeTypeReference: Components.interfaces.nsIMsgCompType, 54 55 _IDisVID: false, 56 _preselectedID: null, 57 _allIdentities: null, 58 _selectedValue: null, 59 _newsgroup: null, 60 _rdfDatasourceAccess: null, 61 62 // this function adds a timestamp to the current sender 63 __autoTimestamp: function () { 64 Log.debug("__autoTimestamp()"); 65 if (this._IDisVID) { 66 Log.debug("Virtual Identity in use, aborting"); 67 return; 68 } 69 70 var current_email = this._preselectedID.email.split("@"); 71 var localpart = current_email[0]; 72 var domain = current_email[1]; 73 74 Log.debug("current email: " + current_email[0] + "@" + current_email[1]); 75 76 var autoString = vIprefs.get("autoString"); 77 var formatString = vIprefs.get("autoTimeFormat"); 78 79 var dateObj = new Date(); 80 var dateString = ""; 81 if (formatString == "") dateString = parseInt(dateObj.getTime() / 1000); 82 else try { // you never know what the formatString will be... 83 dateString = dateObj.toLocaleFormat(formatString).replace(/\s+|[\x00-\x2a]|\x2c|\x2f|[\x3a-\x40]|[\x5b-\x5d]|\x60|\x7c|[\x7f-\xff]/g, "_"); 84 } catch (e) {}; 85 86 var new_email = autoString.replace(/%l/g, localpart).replace(/%d/g, domain).replace(/%t/g, dateString); 87 Log.debug("new email: " + new_email); 88 89 var newIdentity = new identityData(new_email, 90 this._preselectedID.fullName, this._preselectedID.key, this._preselectedID.smtpServerKey, null, null) 91 92 this._allIdentities.addWithoutDuplicates(newIdentity); 93 this._selectedValue = 0; 94 }, 95 96 __ignoreID: function () { 97 Log.debug("checking " + vIprefs.get("idSelection_ignoreIDs") + " against " + this._preselectedID.key) 98 // check if usage if virtual Identities should be used at all for the currently selected ID 99 if (vIprefs.get("idSelection_ignoreIDs").indexOf(":" + this._preselectedID.key + ":") != -1) { 100 Log.debug("not using virtual Identites for ID " + this._preselectedID.key); 101 return true; 102 } 103 return false 104 }, 105 106 NewMail: function () { 107 Log.debug("NewMail()"); 108 if (this.__ignoreID()) return; 109 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(this._allIdentities, this._recipients); 110 if (this._allIdentities.number == 0 && vIprefs.get("autoTimestamp")) this.__autoTimestamp(); 111 }, 112 113 _foundExistingIdentity: function () { 114 /* compare with existing Identities */ 115 for (var index = 0; index < this._allIdentities.number; index++) { 116 var existingID = this._allIdentities.identityDataCollection[index].isExistingIdentity(false); 117 if (existingID) { 118 this._allIdentities.identityDataCollection[index].id.key = existingID; // set found identity 119 // reorder list of Identities to prefer it on autoselect 120 // has to be done before Identities are added to the Menu 121 Log.debug("found existing Identity, reorder to prefer this one."); 122 var firstIdentity = this._allIdentities.identityDataCollection[index]; 123 for (var i = index; index > 0; index--) { 124 this._allIdentities.identityDataCollection[index] = this._allIdentities.identityDataCollection[index - 1]; 125 } 126 this._allIdentities.identityDataCollection[0] = firstIdentity; 127 return { 128 key: index 129 }; 130 } 131 } 132 return null; 133 }, 134 135 ReplyOnSent: function () { 136 Log.debug("ReplyOnSent() (rules like SmartDraft)"); 137 this.__SmartDraftOrReplyOnSent(); 138 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(this._allIdentities, this._recipients); 139 }, 140 141 Draft: function () { 142 Log.debug("Draft()"); 143 144 this.__SmartDraftOrReplyOnSent(); 145 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(this._allIdentities, this._recipients); 146 }, 147 148 __parseHeadersWithArray: function (header, identityCollection) { 149 var emails = {}; 150 var fullNames = {}; 151 var combinedNames = {}; 152 var number = this._headerParser.parseHeadersWithArray(header, emails, fullNames, combinedNames); 153 for (var index = 0; index < number; index++) { 154 var newIdentity = new identityData(emails.value[index], fullNames.value[index], 155 null, NO_SMTP_TAG, null, null); 156 identityCollection.addWithoutDuplicates(newIdentity); 157 } 158 }, 159 160 // this function checks if we have a draft-case and Smart-Draft should replace the Identity 161 __SmartDraftOrReplyOnSent: function () { 162 if (!vIprefs.get("smart_draft")) { 163 Log.debug("SmartDraft deactivated"); 164 return; 165 } 166 167 Log.debug("__SmartDraftOrReplyOnSent()"); 168 169 if (this._msgHdr) { 170 this.__parseHeadersWithArray(this._msgHdr.author, this._allIdentities) 171 Log.debug("sender '" + this._allIdentities.identityDataCollection[0].combinedName + "'"); 172 } else Log.debug("__SmartDraftOrReplyOnSent: No Header found, shouldn't happen"); 173 }, 174 175 __filterAddresses: function () { 176 var returnIdentities = new identityCollection(); 177 178 var filterList = 179 this._unicodeConverter.ConvertToUnicode(vIprefs.get("smart_reply_filter")).split(/\n/) 180 if (filterList.length == 0) filterList[0] == "" 181 182 for (var i = 0; i < filterList.length; i++) { 183 const filterType = { 184 None: 0, 185 RegExp: 1, 186 StrCmp: 2 187 } 188 var recentfilterType; 189 var skipRegExp = false; 190 if (filterList.length <= 1 && filterList[0] == "") { 191 Log.debug("no filters configured"); 192 recentfilterType = filterType.None; 193 } else if (/^[+-]?\/(.*)\/$/.exec(filterList[i])) { 194 Log.debug("filter emails with RegExp '" + filterList[i].replace(/\\/g, "\\\\") + "'"); 195 recentfilterType = filterType.RegExp; 196 } else { 197 Log.debug("filter emails, compare with '" + filterList[i] + "'"); 198 recentfilterType = filterType.StrCmp; 199 } 200 for (var j = 0; j < this._allIdentities.number; j++) { // check if recent email-address (pre-choosen identity) is found in 201 // copied and adapted from correctIdentity, thank you for the RegExp-idea! 202 var add_addr = false; 203 switch (recentfilterType) { 204 case filterType.None: 205 add_addr = true; 206 break; 207 case filterType.RegExp: 208 if (skipRegExp) break; 209 try { 210 /^[+-]?\/(.*)\/$/.exec(filterList[i]); 211 if (filterList[i][0] == "-") { 212 if (this._allIdentities.identityDataCollection[j].email.match(new RegExp(RegExp.$1, "i"))) 213 this._allIdentities.dropIdentity(j--); 214 } else 215 add_addr = (this._allIdentities.identityDataCollection[j].email.match(new RegExp(RegExp.$1, "i"))); 216 } catch (vErr) { 217 this.stringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"] 218 .getService(Components.interfaces.nsIStringBundleService) 219 .createBundle("chrome://v_identity/locale/v_identity.properties"); 220 SmartReplyNotification.info( 221 this.stringBundle.GetStringFromName("vident.smartIdentity.ignoreRegExp") + 222 +filterList[i].replace(/\\/g, "\\\\") + " ."); 223 skipRegExp = true; 224 } 225 break; 226 case filterType.StrCmp: 227 add_addr = (this._allIdentities.identityDataCollection[j].email.toLowerCase().indexOf(filterList[i].toLowerCase()) != -1) 228 break; 229 } 230 if (add_addr) returnIdentities.addWithoutDuplicates(this._allIdentities.identityDataCollection[j]) 231 } 232 } 233 this._allIdentities.takeOver(returnIdentities); 234 }, 235 236 __smartReplyCollectAddresses: function () { 237 // add emails from selected headers (stored by vI_getHeader.xul/js) 238 var reply_headers = this._unicodeConverter.ConvertToUnicode(vIprefs.get("smart_reply_headers")).split(/\n/) 239 240 for (var index = 0; index < reply_headers.length; index++) { 241 // ------------- prepare fields to read the stored header ---------------- 242 var replyHeader_splitted = reply_headers[index].split(/:/) 243 // use first part (all before ':') as the header name 244 var replyHeaderName = replyHeader_splitted[0].toLowerCase() 245 // check second or third part for any number 246 var replyHeaderNumber = null; 247 if (replyHeader_splitted.length > 1) parseInt(replyHeader_splitted[1]); 248 if ((!replyHeaderNumber || isNaN(replyHeaderNumber)) && replyHeader_splitted.length > 2) replyHeaderNumber = parseInt(replyHeader_splitted[2]); 249 // check if Fullnames should be erased 250 var replyHeaderEmptyFullNames = ((replyHeader_splitted[1] && replyHeader_splitted[1].match(/@/)) || 251 (replyHeader_splitted[2] && replyHeader_splitted[2].match(/@/))); 252 253 // create header name to find the value 254 var replyHeaderNameToRead = replyHeaderName 255 if (replyHeaderNumber && !isNaN(replyHeaderNumber)) replyHeaderNameToRead += ":" + replyHeaderNumber 256 257 // if mailing-list ignore to-header (usually the mailing list address) 258 if (replyHeaderNameToRead == "to" && this._msgHdr.getStringProperty("vI_list-id")) { 259 Log.debug("header 'list-id' found (mailinglist), skipping header 'to'"); 260 continue; 261 } 262 263 // ------------- read the stored header ------------------------------- 264 var value = this._unicodeConverter.ConvertToUnicode(this._msgHdr.getStringProperty("vI_" + replyHeaderNameToRead)) 265 /* let window3pane = Components.classes['@mozilla.org/appshell/window-mediator;1'] 266 .getService(Components.interfaces.nsIWindowMediator) 267 .getMostRecentWindow("mail:3pane"); 268 269 Log.debug("found stored header '" + 270 replyHeaderNameToRead + "': '" + window3pane.virtualIdentityExtension.storedHeaders["vI_" + replyHeaderNameToRead] + "'");*/ 271 272 Log.debug("reading header '" + 273 replyHeaderNameToRead + "': '" + value + "'"); 274 275 // ------------- parse address-string to get a field of single email-addresses 276 var splitted = new identityCollection(); 277 this.__parseHeadersWithArray(value, splitted); 278 279 // move found addresses step by step to this._allIdentities, and change values if requested 280 for (var i = 0; i < splitted.number; i++) { 281 // if there is no email than it makes no sense to use it as a sender 282 if (!splitted.identityDataCollection[i].email.match(/^.*@.*$/)) { 283 Log.debug(" skipping '" + 284 splitted.identityDataCollection[i].email + "', no email") 285 continue; 286 } 287 288 if (replyHeaderEmptyFullNames) splitted.identityDataCollection[i].fullName = "" 289 290 this._allIdentities.addWithoutDuplicates(splitted.identityDataCollection[i]); 291 292 Log.debug(" found '" + 293 splitted.identityDataCollection[i].combinedName + "'") 294 } 295 } 296 }, 297 298 Reply: function () { 299 Log.debug("Reply()"); 300 301 if (this._msgHdr && !this._newsgroup && !this._msgHdr.getStringProperty("vI_content_base")) { 302 // RFC 2821 (http://www.ietf.org/rfc/rfc2821.txt) says: 303 // "4.4 Trace Information 304 // When an SMTP server receives a message for delivery or further 305 // processing, it MUST insert trace ("time stamp" or "Received") 306 // information at the beginning of the message content, as discussed in 307 // section 4.1.1.4." 308 // so it should be always possible to decide if Reply or Draft based on received headers 309 // hidden option smart_detectByReceivedHeader will act as a switch for not RFC-compliant servers 310 // RFC-compliant 311 if (vIprefs.get("smart_detectByReceivedHeader")) { 312 if (!this._msgHdr.getStringProperty("vI_received")) { // mail was not received 313 Log.debug("reply on non-received (sent?) mail. Using SmartDraft."); 314 this.ReplyOnSent(); 315 return; 316 } 317 } 318 // not RFC-compliant 319 else { 320 const MSG_FOLDER_FLAG_INBOX = 0x1000 321 const MSG_FOLDER_FLAG_SENTMAIL = 0x0200; 322 323 if (this._msgHdr && (this._msgHdr.folder.flags & MSG_FOLDER_FLAG_SENTMAIL)) { 324 if (this._msgHdr.folder.flags & MSG_FOLDER_FLAG_INBOX) 325 Log.debug("reply from Sent folder. Folder is INBOX, assuming Reply-Case."); 326 else { 327 Log.debug("reply from Sent folder. Using SmartDraft."); 328 this.ReplyOnSent(); 329 return; 330 } 331 } 332 } 333 } 334 335 if (this.__ignoreID()) return; 336 337 var storageIdentities = new identityCollection(); 338 this._rdfDatasourceAccess.getVIdentityFromAllRecipients(storageIdentities, this._recipients); 339 340 if (storageIdentities.number == 0 || !vIprefs.get("idSelection_storage_ignore_smart_reply")) 341 this.__SmartReply(); 342 else Log.debug("SmartReply skipped, Identities in Storage found."); 343 344 // merge SmartReply-Identities and Storage-Identites 345 if (vIprefs.get("idSelection_storage_prefer_smart_reply")) { 346 this._allIdentities.mergeWithoutDuplicates(storageIdentities); 347 } else { 348 var smartIdentities = this._allIdentities; 349 this._allIdentities = storageIdentities; 350 this._allIdentities.mergeWithoutDuplicates(smartIdentities); 351 } 352 353 Log.debug("merged SmartReply & Storage, " + this._allIdentities.number + " address(es) left") 354 }, 355 356 // this function checks if we have a reply-case and Smart-Reply should replace the Identity 357 __SmartReply: function () { 358 if (!vIprefs.get("smart_reply")) { 359 Log.debug("SmartReply deactivated"); 360 return; 361 } 362 if (this._newsgroup && !vIprefs.get("smart_reply_for_newsgroups")) { 363 Log.debug("SmartReply, answering to a newsgroup, aborting"); 364 return; 365 } 366 367 Log.debug("__SmartReply()"); 368 Log.debug("----------------------------------------------------------") 369 if (this._msgHdr) { 370 /* first step: collect addresses */ 371 this.__smartReplyCollectAddresses(); 372 Log.debug("" + this._allIdentities.number + " address(es) after parsing, before filtering") 373 374 /* second step: filter (and sort) addresses */ 375 this.__filterAddresses(); 376 377 Log.debug("filtering done, " + this._allIdentities.number + " address(es) left") 378 379 /* set default FullName */ 380 var smart_reply_defaultFullName = this._unicodeConverter.ConvertToUnicode(vIprefs.get("smart_reply_defaultFullName")) 381 if (smart_reply_defaultFullName != "") { 382 for (var index = 0; index < this._allIdentities.number; index++) { 383 if (this._allIdentities.identityDataCollection[index].fullName == "") { 384 this._allIdentities.identityDataCollection[index].fullName = smart_reply_defaultFullName 385 Log.debug("added default FullName '" + 386 smart_reply_defaultFullName + "' to '" + this._allIdentities.identityDataCollection[index].email + "'") 387 } 388 } 389 } 390 391 /* smart_reply_ignoreFullName: compare email with other Identities */ 392 /* if match replace FullName with existing one, keep identity in list by now */ 393 /* will not be added to the menu but probably choosen with __smartIdentitySelection */ 394 if (vIprefs.get("smart_reply_ignoreFullName")) { 395 Log.debug("compare with existing Identities (ignoring FullNames).") 396 397 for (var index = 0; index < this._allIdentities.number; index++) { 398 var idKey = this._allIdentities.identityDataCollection[index].isExistingIdentity(true); 399 if (idKey) { 400 var AccountManager = Components.classes["@mozilla.org/messenger/account-manager;1"] 401 .getService(Components.interfaces.nsIMsgAccountManager); 402 var newFullName = AccountManager.getIdentity(idKey).fullName; 403 this._allIdentities.identityDataCollection[index].fullName = newFullName; 404 Log.debug("replaced Fullname of '" + this._allIdentities.identityDataCollection[index].email + "' with '" + newFullName + "'"); 405 } 406 } 407 } 408 409 /* smart_reply_searchBaseIdentity: compare email with other Identities */ 410 /* to find matching domain. Use first found as base identity (smtp etc) */ 411 if (vIprefs.get("smart_reply_searchBaseIdentity")) { 412 Log.debug("compare domain name with existing accounts.") 413 414 for (var index = 0; index < this._allIdentities.number; index++) { 415 var idKey = this._allIdentities.identityDataCollection[index].hasMatchingDomainIdentity(); 416 if (idKey) { 417 Log.debug("use id with matching domain as base ID"); 418 this._allIdentities.identityDataCollection[index].id.key = idKey; 419 } 420 } 421 } 422 423 } else Log.debug("SmartReply skipped. No Header-information found."); 424 425 Log.debug("----------------------------------------------------------") 426 }, 427 416 428 417 429 };
Note: See TracChangeset
for help on using the changeset viewer.