def mine(self, request): email_account_list = get_shared_email_accounts(request.user) email_account_list = email_account_list.prefetch_related( 'labels', 'sharedemailconfig_set', 'owner', ) serializer = self.get_serializer(email_account_list, many=True) return Response(serializer.data)
def initial(self, request, *args, **kwargs): """ Anything that should happen after permission checks and before dispatching. """ super(EmailDraftAttachmentViewSet, self).initial(request, *args, **kwargs) # Store the email accounts on the class so we only have to fetch them once. self.available_accounts = get_shared_email_accounts(self.request.user) try: self.draft = EmailDraft.objects.get( pk=kwargs['draft_id'], send_from__in=self.available_accounts) except EmailDraft.DoesNotExist: raise NotFound()
def initial(self, request, *args, **kwargs): """ Anything that should happen after permission checks and before dispatching. """ super(EmailDraftAttachmentViewSet, self).initial(request, *args, **kwargs) # Store the email accounts on the class so we only have to fetch them once. self.available_accounts = get_shared_email_accounts(self.request.user) try: self.draft = EmailDraft.objects.get( pk=kwargs['draft_id'], send_from__in=self.available_accounts ) except EmailDraft.DoesNotExist: raise NotFound()
def user_email_related(self, user): """ Search emails that the user is allowed to see. Args: user (User): The user to use with the search """ email_account_list = get_shared_email_accounts(user) email_account_list = email_account_list.exclude(is_active=False) if not email_account_list: # Disable results if no email at all for account. self.raw_filters.append({'limit': {'value': 0}}) return email_accounts = set( ['%s' % email.email_address for email in email_account_list]) join = ' OR '.join(email_accounts) filterquery = 'account.email:(%s)' % join self.filter_query(filterquery)
def user_email_related(self, user): """ Search emails that the user is allowed to see. Args: user (User): The user to use with the search """ email_account_list = get_shared_email_accounts(user) email_account_list = email_account_list.exclude(is_active=False) if not email_account_list: # Disable results if no email at all for account. self.raw_filters.append({ 'limit': { 'value': 0 } }) return email_accounts = set(['%s' % email.email_address for email in email_account_list]) join = ' OR '.join(email_accounts) filterquery = 'account.email:(%s)' % join self.filter_query(filterquery)
def get(self, request, format=None): with tracer.trace('SearchView.get: parameter setup'): user = request.user # Search query. q = request.query_params.get('q', '').strip() # Paging parameters. page = request.query_params.get('page', '0') page = int(page) + 1 size = int(request.query_params.get('size', '20')) sort = request.query_params.get('sort', '-sent_date') # Mail labeling parameters. label_id = request.query_params.get('label', None) account_ids = request.query_params.get('account', None) # None means search in all owned email accounts. with tracer.trace('SearchView.get: email_accounts setup'): # Get a list of all email accounts added by the user or publicly shared with the user as a group inbox. email_accounts = get_shared_email_accounts(user, True) if account_ids: # Only search within the email accounts indicated by the account_ids parameter. account_ids = account_ids.split(',') email_accounts = email_accounts.filter(pk__in=account_ids) email_accounts = email_accounts.exclude( Q(is_active=False) | Q(is_deleted=True) | Q(is_authorized=False) ) message_list = EmailMessage.objects if q: # System Gmail labels visible in Lily, where the user can search in. gmail_labels = [ settings.GMAIL_LABEL_INBOX, settings.GMAIL_LABEL_SPAM, settings.GMAIL_LABEL_TRASH, settings.GMAIL_LABEL_SENT, settings.GMAIL_LABEL_DRAFT ] if label_id and label_id not in gmail_labels: # Also retrieve related user set labels because later the label name will be queried. email_accounts = email_accounts.prefetch_related('labels') # Prevent too much calls on the search api, so restrict number of search results per email account. max_results = 3 * size messages_ids = [] with tracer.trace('SearchView.get: for all accounts'): for email_account in email_accounts: if label_id: with tracer.trace('SearchView.get: building q with label lookup'): # Retrieve the label corresponding to the label_id, otherwise Gmail defaults to all mail. label_name = label_id if label_id not in gmail_labels: # Retrieve the label name if label_id will differ from the user set label name. try: label_name = email_account.labels.get(label_id=label_id).name except EmailLabel.DoesNotExist: logger.error( "Incorrect label id {0} with search request for account {1}.".format( label_id, email_account ) ) # Failing label lookup within one account should not halt the complete search. continue q = u"{0} {1}:{2}".format(q, 'label', label_name) with tracer.trace('SearchView.get: retrieving message_ids by Gmail API'): try: connector = GmailConnector(email_account) messages = connector.search(query=q, size=max_results) messages_ids.extend([message['id'] for message in messages]) except (InvalidCredentialsError, NotFoundError, HttpAccessTokenRefreshError, FailedServiceCallException) as e: logger.error( "Failed to search within account {0} with error: {1}.".format(email_account, e) ) # Failing search within one account should not halt the complete search. continue # Retrieve messages from the database. message_list = message_list.filter( message_id__in=messages_ids, account__in=email_accounts ) with tracer.trace('SearchView.get: retrieving messages from db'): message_list = message_list.order_by(sort) # Exclude fields that aren't serialized and potential large. message_list = message_list.defer("body_html", "body_text", "snippet") # The serializer will query for account, sender and star label, so instead of the extra separate queries, # retrieve them now. message_list = message_list.select_related('account', 'sender') message_list = message_list.prefetch_related('labels', 'received_by') # It's possible Google search returns message_id's that aren't in the database (due to 'sync from now'). actual_number_of_results = len(message_list) with tracer.trace('SearchView.get: serializing messages'): # Construct paginator. limit = size * page offset = limit - size message_list = message_list[offset:limit] serializer = EmailMessageListSerializer(message_list, many=True) result = { 'hits': serializer.data, 'total': actual_number_of_results, } return Response(result)
def initial(self, request, *args, **kwargs): """ Anything that should happen after permission checks and before dispatching. """ super(EmailDraftViewSet, self).initial(request, *args, **kwargs) # Store the email accounts on the class so we only have to fetch them once. self.available_accounts = get_shared_email_accounts(self.request.user)
def color(self, request): email_account_list = get_shared_email_accounts(request.user) serializer = SimpleEmailAccountSerializer(email_account_list, many=True) return Response(serializer.data)
def get(self, request, format=None): user = request.user # Search query. q = request.query_params.get('q', '').strip() # Paging parameters. page = request.query_params.get('page', '0') page = int(page) + 1 size = int(request.query_params.get('size', '20')) sort = request.query_params.get('sort', '-sent_date') # Mail labeling parameters. label_id = request.query_params.get('label', None) account_ids = request.query_params.get( 'account', None) # None means search in all owned email accounts. # Get a list of all email accounts added by the user or publicly shared with the user as a group inbox. email_accounts = get_shared_email_accounts(user, True) if account_ids: # Only search within the email accounts indicated by the account_ids parameter. account_ids = account_ids.split(',') email_accounts = email_accounts.filter(pk__in=account_ids) email_accounts = email_accounts.exclude( Q(is_active=False) | Q(is_deleted=True) | Q(is_authorized=False)) message_list = EmailMessage.objects if q: # System Gmail labels visible in Lily, where the user can search in. gmail_labels = [ settings.GMAIL_LABEL_INBOX, settings.GMAIL_LABEL_SPAM, settings.GMAIL_LABEL_TRASH, settings.GMAIL_LABEL_SENT, settings.GMAIL_LABEL_DRAFT ] if label_id and label_id not in gmail_labels: # Also retrieve related user set labels because later the label name will be queried. email_accounts = email_accounts.prefetch_related('labels') # Prevent too much calls on the search api, so restrict number of search results per email account. max_results = 3 * size messages_ids = [] for email_account in email_accounts: if label_id: # Retrieve the label corresponding to the label_id, otherwise Gmail defaults to all mail. label_name = label_id if label_id not in gmail_labels: # Retrieve the label name if label_id will differ from the user set label name. try: label_name = email_account.labels.get( label_id=label_id).name except EmailLabel.DoesNotExist: logger.error( "Incorrect label id {0} with search request for account {1}." .format(label_id, email_account)) # Failing label lookup within one account should not halt the complete search. continue q = u"{0} {1}:{2}".format(q, 'label', label_name) try: connector = GmailConnector(email_account) messages = connector.search(query=q, size=max_results) messages_ids.extend( [message['id'] for message in messages]) except (InvalidCredentialsError, NotFoundError, HttpAccessTokenRefreshError, FailedServiceCallException) as e: logger.error( "Failed to search within account {0} with error: {1}.". format(email_account, e)) # Failing search within one account should not halt the complete search. continue # Retrieve messages from the database. message_list = message_list.filter(message_id__in=messages_ids, account__in=email_accounts) message_list = message_list.order_by(sort) # Exclude fields that aren't serialized and potential large. message_list = message_list.defer("body_html", "body_text", "snippet") # The serializer will query for account, sender and star label, so instead of the extra separate queries, # retrieve them now. message_list = message_list.select_related('account', 'sender') message_list = message_list.prefetch_related('labels', 'received_by') # It's possible Google search returns message_id's that aren't in the database (due to 'sync from now'). actual_number_of_results = len(message_list) # Construct paginator. limit = size * page offset = limit - size message_list = message_list[offset:limit] serializer = EmailMessageListSerializer(message_list, many=True) result = { 'hits': serializer.data, 'total': actual_number_of_results, } return Response(result)
def mine(self, request): email_account_list = get_shared_email_accounts(request.user) serializer = self.get_serializer(email_account_list, many=True) return Response(serializer.data)