Example #1
0
    def _open_crispin_connection(self, db_session):
        account = db_session.query(Account).get(self.account_id)
        try:
            conn = account.auth_handler.connect_account(account)
        except (IMAPClient.Error, socket.error, IMAP4.error):
            raise SearchBackendException(('Unable to connect to the IMAP '
                                          'server. Please retry in a '
                                          'couple minutes.'), 503)
        except ValidationError:
            raise SearchBackendException(("This search can't be performed "
                                          "because the account's credentials "
                                          "are out of date. Please "
                                          "reauthenticate and try again."), 403)

        try:
            acct_provider_info = provider_info(account.provider)
        except NotSupportedError:
            self.log.warn('Account provider not supported',
                          provider=account.provider)
            raise

        self.crispin_client = CrispinClient(self.account_id,
                                            acct_provider_info,
                                            account.email_address,
                                            conn,
                                            readonly=True)
Example #2
0
 def _search(self, search_query, limit):
     try:
         token = g_token_manager.get_token_for_email(self.account)
     except OAuthError:
         raise SearchBackendException(
             "This search can't be performed because the account's "
             "credentials are out of date. Please reauthenticate and try "
             "again.", 403)
     ret = requests.get(
         u'https://www.googleapis.com/gmail/v1/users/me/messages',
         params={'q': search_query,
                 'maxResults': limit},
         auth=OAuthRequestsWrapper(token))
     log.info('Gmail API search request completed',
              elapsed=ret.elapsed.total_seconds())
     if ret.status_code != 200:
         log.critical('HTTP error making search request',
                      account_id=self.account.id,
                      url=ret.url,
                      response=ret.content)
         raise SearchBackendException(
             "Error issuing search request", 503, server_error=ret.content)
     data = ret.json()
     if 'messages' not in data:
         return []
     # Note that the Gmail API returns g_msgids in hex format. So for
     # example the IMAP X-GM-MSGID 1438297078380071706 corresponds to
     # 13f5db9286538b1a in the API response we have here.
     return [int(m['id'], 16) for m in data['messages']]
Example #3
0
    def _search(self, search_query, limit):
        results = []

        params = dict(q=search_query, maxResults=limit)

        # Could have used while True: but I don't like infinite loops.
        for i in range(1, 10):
            ret = requests.get(
                u"https://www.googleapis.com/gmail/v1/users/me/messages",
                params=params,
                auth=OAuthRequestsWrapper(self.auth_token),
            )

            log.info(
                "Gmail API search request completed",
                elapsed=ret.elapsed.total_seconds(),
            )

            if ret.status_code != 200:
                log.critical(
                    "HTTP error making search request",
                    account_id=self.account.id,
                    url=ret.url,
                    response=ret.content,
                )
                raise SearchBackendException("Error issuing search request",
                                             503,
                                             server_error=ret.content)

            data = ret.json()

            if "messages" not in data:
                return results

            # Note that the Gmail API returns g_msgids in hex format. So for
            # example the IMAP X-GM-MSGID 1438297078380071706 corresponds to
            # 13f5db9286538b1a in the API response we have here.
            results = results + [int(m["id"], 16) for m in data["messages"]]

            if len(results) >= limit:
                return results[:limit]

            if "nextPageToken" not in data:
                return results
            else:
                # We don't have <limit> results and there's more to fetch ---
                # get them!
                params["pageToken"] = data["nextPageToken"]
                log.info("Getting next page of search results")
                continue

        # If we've been through the loop 10 times, it means we got a request
        # a crazy-high offset --- raise an error.
        log.error("Too many search results", query=search_query, limit=limit)

        raise SearchBackendException("Too many results", 400)
Example #4
0
 def __init__(self, account):
     self.account_id = int(account.id)
     try:
         with session_scope(self.account_id) as db_session:
             self.account = db_session.query(Account).get(self.account_id)
             self.auth_token = g_token_manager.get_token_for_email(
                 self.account)
             db_session.expunge_all()
     except OAuthError:
         raise SearchBackendException(
             "This search can't be performed because the account's "
             "credentials are out of date. Please reauthenticate and try "
             "again.", 403)
Example #5
0
    def _search_folder(self, folder, criteria, charset):
        try:
            self.crispin_client.select_folder(folder.name, uidvalidity_cb)
        except FolderMissingError:
            self.log.warn("Won't search missing IMAP folder", exc_info=True)
            return []
        except UidInvalid:
            self.log.error(("Got Uidvalidity error when searching. "
                            "Skipping."), exc_info=True)
            return []

        try:
            uids = self.crispin_client.conn.search(criteria, charset=charset)
        except IMAP4.error:
            self.log.warn('Search error', exc_info=True)
            raise SearchBackendException(('Unknown IMAP error when '
                                          'performing search.'), 503)

        self.log.debug('Search found messages for folder',
                       folder_name=folder.id, uids=len(uids))
        return uids