def get_global_tag_based_subscribers(self, tag_mark_reason=None, subscription_records=None): """returns a list of users who either follow or "do not ignore" the given set of tags, depending on the tag_mark_reason ``subscription_records`` - query set of ``~askbot.models.EmailFeedSetting`` this argument is used to reduce number of database queries """ if tag_mark_reason == 'good': email_tag_filter_strategy = const.INCLUDE_INTERESTING user_set_getter = User.objects.filter elif tag_mark_reason == 'bad': email_tag_filter_strategy = const.EXCLUDE_IGNORED user_set_getter = User.objects.exclude else: raise ValueError('Uknown value of tag mark reason %s' % tag_mark_reason) #part 1 - find users who follow or not ignore the set of tags tag_names = self.get_tag_names() tag_selections = MarkedTag.objects.filter(tag__name__in=tag_names, reason=tag_mark_reason) subscribers = set( user_set_getter(tag_selections__in=tag_selections).filter( notification_subscriptions__in=subscription_records).filter( email_tag_filter_strategy=email_tag_filter_strategy)) #part 2 - find users who follow or not ignore tags via wildcard selections #inside there is a potentially time consuming loop if askbot_settings.USE_WILDCARD_TAGS: #todo: fix this #this branch will not scale well #because we have to loop through the list of users #in python if tag_mark_reason == 'good': empty_wildcard_filter = {'interesting_tags__exact': ''} wildcard_tags_attribute = 'interesting_tags' update_subscribers = lambda the_set, item: the_set.add(item) elif tag_mark_reason == 'bad': empty_wildcard_filter = {'ignored_tags__exact': ''} wildcard_tags_attribute = 'ignored_tags' update_subscribers = lambda the_set, item: the_set.discard(item ) potential_wildcard_subscribers = User.objects.filter( notification_subscriptions__in=subscription_records).filter( email_tag_filter_strategy=email_tag_filter_strategy ).exclude( ** empty_wildcard_filter #need this to limit size of the loop ) for potential_subscriber in potential_wildcard_subscribers: wildcard_tags = getattr(potential_subscriber, wildcard_tags_attribute).split(' ') if tags_match_some_wildcard(tag_names, wildcard_tags): update_subscribers(subscribers, potential_subscriber) return subscribers
def get_global_tag_based_subscribers( self, tag_mark_reason = None, subscription_records = None ): """returns a list of users who either follow or "do not ignore" the given set of tags, depending on the tag_mark_reason ``subscription_records`` - query set of ``~askbot.models.EmailFeedSetting`` this argument is used to reduce number of database queries """ if tag_mark_reason == 'good': email_tag_filter_strategy = const.INCLUDE_INTERESTING user_set_getter = User.objects.filter elif tag_mark_reason == 'bad': email_tag_filter_strategy = const.EXCLUDE_IGNORED user_set_getter = User.objects.exclude else: raise ValueError('Uknown value of tag mark reason %s' % tag_mark_reason) #part 1 - find users who follow or not ignore the set of tags tag_names = self.get_tag_names() tag_selections = MarkedTag.objects.filter( tag__name__in = tag_names, reason = tag_mark_reason ) subscribers = set( user_set_getter( tag_selections__in = tag_selections ).filter( notification_subscriptions__in = subscription_records ).filter( email_tag_filter_strategy = email_tag_filter_strategy ) ) #part 2 - find users who follow or not ignore tags via wildcard selections #inside there is a potentially time consuming loop if askbot_settings.USE_WILDCARD_TAGS: #todo: fix this #this branch will not scale well #because we have to loop through the list of users #in python if tag_mark_reason == 'good': empty_wildcard_filter = {'interesting_tags__exact': ''} wildcard_tags_attribute = 'interesting_tags' update_subscribers = lambda the_set, item: the_set.add(item) elif tag_mark_reason == 'bad': empty_wildcard_filter = {'ignored_tags__exact': ''} wildcard_tags_attribute = 'ignored_tags' update_subscribers = lambda the_set, item: the_set.discard(item) potential_wildcard_subscribers = User.objects.filter( notification_subscriptions__in = subscription_records ).filter( email_tag_filter_strategy = email_tag_filter_strategy ).exclude( **empty_wildcard_filter #need this to limit size of the loop ) for potential_subscriber in potential_wildcard_subscribers: wildcard_tags = getattr( potential_subscriber, wildcard_tags_attribute ).split(' ') if tags_match_some_wildcard(tag_names, wildcard_tags): update_subscribers(subscribers, potential_subscriber) return subscribers
def get_global_tag_based_subscribers( self, tag_mark_reason = None, subscription_records = None ): """returns a list of users who either follow or "do not ignore" the given set of tags, depending on the tag_mark_reason ``subscription_records`` - query set of ``~askbot.models.EmailFeedSetting`` this argument is used to reduce number of database queries """ debug_str = "\n " if tag_mark_reason == 'S': email_tag_filter_strategy = const.INCLUDE_INTERESTING user_set_getter = User.objects.filter debug_str += "Subscribed Tags" elif tag_mark_reason == 'I': email_tag_filter_strategy = const.EXCLUDE_IGNORED user_set_getter = User.objects.exclude debug_str += "Not Ignored Tags" else: raise ValueError('Uknown value of tag mark reason %s' % tag_mark_reason) #part 1 - find users who follow or not ignore the set of tags tag_names = self.get_tag_names() debug_str += " (%s)\n" % tag_names tag_selections = MarkedTag.objects.filter( tag__name__in = tag_names, reason__contains = tag_mark_reason ) subscribers = set( user_set_getter( tag_selections__in = tag_selections ).filter( notification_subscriptions__in = subscription_records ).filter( email_tag_filter_strategy = email_tag_filter_strategy ) ) debug_str += " Match%s\n" % self.get_user_id_string(subscribers) #part 2 - find users who follow or not ignore tags via wildcard selections #inside there is a potentially time consuming loop if askbot_settings.USE_WILDCARD_TAGS: #todo: fix this #this branch will not scale well #because we have to loop through the list of users #in python if tag_mark_reason == 'S': empty_wildcard_filter = {'subscribed_tags__exact': ''} wildcard_tags_attribute = 'subscribed_tags' update_subscribers = lambda the_set, item: the_set.add(item) exclude_wildcards = lambda sub_set, wild_set: wild_set.difference_update(sub_set) elif tag_mark_reason == 'I': empty_wildcard_filter = {'ignored_tags__exact': ''} wildcard_tags_attribute = 'ignored_tags' update_subscribers = lambda the_set, item: the_set.discard(item) exclude_wildcards = lambda sub_set, wild_set: wild_set.intersection_update(sub_set) potential_wildcard_subscribers = set(User.objects.filter( notification_subscriptions__in = subscription_records ).filter( email_tag_filter_strategy = email_tag_filter_strategy ).exclude( **empty_wildcard_filter #need this to limit size of the loop )) debug_str += " Total Wildcard Cnt %d" % (len(potential_wildcard_subscribers)) exclude_wildcards(subscribers, potential_wildcard_subscribers) debug_str += " Filtered Wildcard Cnt %d\n" % len(potential_wildcard_subscribers) wild_users = [] for potential_subscriber in potential_wildcard_subscribers: wildcard_tags = getattr( potential_subscriber, wildcard_tags_attribute ).split(' ') if tags_match_some_wildcard(tag_names, wildcard_tags): update_subscribers(subscribers, potential_subscriber) wild_users.append(potential_subscriber) debug_str += " Wildcard%s\n" % self.get_user_id_string(wild_users) #logging.info(debug_str) return subscribers