def _msg_addresses(self, msg_info=None, addresses=[], no_from=False, no_to=False, no_cc=False): cids = set() for ai in addresses: eid = self.idx.EMAIL_IDS.get(ai.address.lower()) cids.add(b36(self.idx.add_email(ai.address, name=ai.fn, eid=eid))) if msg_info: if not no_to: to = [t for t in msg_info[MailIndex.MSG_TO].split(',') if t] cids |= set(to) if not no_cc: cc = [t for t in msg_info[MailIndex.MSG_CC].split(',') if t] cids |= set(cc) if not no_from: fe, fn = ExtractEmailAndName(msg_info[MailIndex.MSG_FROM]) if fe: eid = self.idx.EMAIL_IDS.get(fe.lower()) cids.add(b36(self.idx.add_email(fe, name=fn, eid=eid))) return sorted(list(cids))
def _address(self, cid=None, e=None, n=None): if cid and not (e and n): e, n = ExtractEmailAndName(self.idx.EMAILS[int(cid, 36)]) vcard = self.session.config.vcards.get_vcard(e) if vcard and '@' in n: n = vcard.fn return AddressInfo(e, n, vcard=vcard)
def _add_gpg_key(cls, idx, session, addr): fe, fn = ExtractEmailAndName(addr) vcard = session.config.vcards.get_vcard(fe) if vcard: keys = vcard.get_all('KEY') if keys: mime, fp = keys[0].value.split('data:')[1].split(',', 1) return "%s <%s#%s>" % (fn, fe, fp) return "%s <%s>" % (fn, fe)
def _metadata(self, msg_info): msg_mid = msg_info[MailIndex.MSG_MID] if '-' in msg_mid: # Ephemeral... msg_idx = None else: msg_idx = int(msg_mid, 36) cache = self.idx.CACHE.get(msg_idx, {}) if 'metadata' in cache: return cache['metadata'] nz = lambda l: [v for v in l if v] msg_ts = long(msg_info[MailIndex.MSG_DATE], 36) msg_date = datetime.datetime.fromtimestamp(msg_ts) fe, fn = ExtractEmailAndName(msg_info[MailIndex.MSG_FROM]) f_info = self._address(e=fe, n=fn) f_info['aid'] = (self._msg_addresses(msg_info, no_to=True, no_cc=True) or [''])[0] thread_mid = parent_mid = msg_info[MailIndex.MSG_THREAD_MID] if '/' in thread_mid: thread_mid, parent_mid = thread_mid.split('/') expl = { 'mid': msg_mid, 'id': msg_info[MailIndex.MSG_ID], 'timestamp': msg_ts, 'from': f_info, 'to_aids': self._msg_addresses(msg_info, no_from=True, no_cc=True), 'cc_aids': self._msg_addresses(msg_info, no_from=True, no_to=True), 'msg_kb': int(msg_info[MailIndex.MSG_KB], 36), 'tag_tids': sorted(self._msg_tags(msg_info)), 'thread_mid': thread_mid, 'parent_mid': parent_mid, 'subject': msg_info[MailIndex.MSG_SUBJECT], 'body': MailIndex.get_body(msg_info), 'flags': {}, 'crypto': {} } # Ephemeral messages do not have URLs if '-' in msg_info[MailIndex.MSG_MID]: expl['flags'].update({ 'ephemeral': True, 'draft': True, }) else: expl['urls'] = { 'thread': self.urlmap.url_thread(msg_info[MailIndex.MSG_MID]), 'source': self.urlmap.url_source(msg_info[MailIndex.MSG_MID]), } # Support rich snippets if expl['body']['snippet'].startswith('{'): try: expl['body'] = json.loads(expl['body']['snippet']) except ValueError: pass # Misc flags sender_vcard = self.idx.config.vcards.get_vcard(fe.lower()) if sender_vcard: if sender_vcard.kind == 'profile': expl['flags']['from_me'] = True else: expl['flags']['from_contact'] = True tag_types = [self.idx.config.get_tag(t).type for t in expl['tag_tids']] for t in self.TAG_TYPE_FLAG_MAP: if t in tag_types: expl['flags'][self.TAG_TYPE_FLAG_MAP[t]] = True # Check tags for signs of encryption or signatures tag_slugs = [self.idx.config.get_tag(t).slug for t in expl['tag_tids']] for t in tag_slugs: if t.startswith('mp_sig'): expl['crypto']['signature'] = t[7:] elif t.startswith('mp_enc'): expl['crypto']['encryption'] = t[7:] # Extra behavior for editable messages if 'draft' in expl['flags']: if 'ephemeral' in expl['flags']: pass elif self.idx.config.is_editable_message(msg_info): expl['urls']['editing'] = self.urlmap.url_edit(expl['mid']) else: del expl['flags']['draft'] if msg_idx is not None: cache['metadata'] = expl self.idx.CACHE[msg_idx] = cache return expl