This is just some static backup of the original site, don't expect every link to work!

Ignore:
Timestamp:
Nov 3, 2014, 12:35:40 PM (8 years ago)
Author:
rene <rene@…>
Branches:
ng_0.9
Children:
7204cb
Parents:
3c9c29
Message:

code formatting (no code changes)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • modules/vI_smartIdentityCollection.js

    r3c9c29 r509348  
    3333
    3434function smartIdentityCollection(msgHdr, preseletedID, currentIDisVID, newsgroup, recipients) {
    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();
     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();
    4343};
    4444
    4545smartIdentityCollection.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
    416428
    417429};
Note: See TracChangeset for help on using the changeset viewer.