def _getQuerySetChildResult(self, querySet): ''' Determine child results... TODO: uniqueness detection/removal ''' children = self._getAllChildQuerySets(querySet, results=[]) model = modellib.type_map[querySet.resource_type] resources = EmptyQuerySet(model) lookupFn = self._searchMethod(querySet) for qs in children: # this won't use the tags for the child but will re-run # the kids and update transitive tags filtered = self._getQuerySetFilteredResult( qs ).distinct() chosen = self._getQuerySetChosenResult( qs, lookupFn ).distinct() resources = resources | filtered | chosen resources = resources.distinct() # this could be slow if we update on every access, and is complicated by the fact # that chosen ONLY works through tags. So only update transitive tags when # the tags are already stale #if self._areResourceTagsStale(querySet): self._updateTransitiveTags(querySet, resources) return resources
def filterQuerySet(self, querySet): '''Return resources matching specific filter criteria''' model = modellib.type_map[querySet.resource_type] # make sure we've implemented tags for these objects # should be able to remove this code once Edge-p1 is # complete resources = None retval = None if not querySet.filter_entries.all(): resources = EmptyQuerySet(model) else: resources = model.objects.select_related().all() for filt in querySet.filter_entries.select_related().all(): resources = modellib.filterDjangoQuerySet( resources, filt.field, filt.operator, filt.value, queryset=querySet) retval = resources.distinct() self._updateTransitiveTags(querySet, resources) return retval
def unionize_querysets(querysets): """ Combine querysets in a way that results from every queryset in joined together """ result = EmptyQuerySet() for q in querysets: result = result.__or__(q) return result
def needed_ballot_positions(doc, active_positions): '''Returns text answering the question "what does this document need to pass?". The return value is only useful if the document is currently in IESG evaluation.''' yes = [p for p in active_positions if p and p.pos_id == "yes"] noobj = [p for p in active_positions if p and p.pos_id == "noobj"] blocking = [p for p in active_positions if p and p.pos.blocking] recuse = [p for p in active_positions if p and p.pos_id == "recuse"] answer = [] if len(yes) < 1: answer.append("Needs a YES.") if blocking: if len(blocking) == 1: answer.append("Has a %s." % blocking[0].pos.name.upper()) else: if blocking[0].pos.name.upper().endswith('S'): answer.append("Has %d %ses." % (len(blocking), blocking[0].pos.name.upper())) else: answer.append("Has %d %ss." % (len(blocking), blocking[0].pos.name.upper())) needed = 1 if doc.type_id == "draft" and doc.intended_std_level_id in ("bcp", "ps", "ds", "std"): needed = two_thirds_rule(recused=len(recuse)) elif doc.type_id == "statchg": if isinstance(doc,Document): related_set = doc.relateddocument_set elif isinstance(doc,DocHistory): related_set = doc.relateddochistory_set else: related_set = EmptyQuerySet() for rel in related_set.filter(relationship__slug__in=['tops', 'tois', 'tohist', 'toinf', 'tobcp', 'toexp']): if (rel.target.document.std_level.slug in ['bcp','ps','ds','std']) or (rel.relationship.slug in ['tops','tois','tobcp']): needed = two_thirds_rule(recused=len(recuse)) break else: if len(yes) < 1: return " ".join(answer) have = len(yes) + len(noobj) if have < needed: more = needed - have if more == 1: answer.append("Needs one more YES or NO OBJECTION position to pass.") else: answer.append("Needs %d more YES or NO OBJECTION positions to pass." % more) else: if blocking: answer.append("Has enough positions to pass once %s positions are resolved." % blocking[0].pos.name.upper()) else: answer.append("Has enough positions to pass.") return " ".join(answer)
def document_objects_for_keyword_in_range(first_index, keyword): #unescapes and splits the query into keywords keywords = list(set((urllib.unquote_plus(keyword)).split(" "))) query_set = EmptyQuerySet() # Retrieves the set of documents corresponding to each keyword for key in keywords: word = get_or_none(Word, text=key) if word is not None: query_set = query_set | word.document_set.all() # Orders the set, removes duplicates, and returns a list of the resultant documents document_objects = list(query_set.order_by("-pagerank").distinct()[ first_index * RESULTS_PER_PAGE: (first_index + 1) * RESULTS_PER_PAGE]) return document_objects
def document_objects_for_keyword_in_range(first_index, keyword): #unescapes and splits the query into keywords keywords = list(set((urllib.unquote_plus(keyword)).split(" "))) query_set = EmptyQuerySet() # Retrieves the set of documents corresponding to each keyword for key in keywords: word = get_or_none(Word, text=key) if word is not None: query_set = query_set | word.document_set.all() # Orders the set, removes duplicates, and returns a list of the resultant documents document_objects = list( query_set.order_by("-pagerank").distinct() [first_index * RESULTS_PER_PAGE:(first_index + 1) * RESULTS_PER_PAGE]) return document_objects
def search(query, models=None): assert models and len(models) == 1, \ "This search backend only supports searching single models." model = models[0] index = get_indexer(model) table = qn(model._meta.db_table) (conv_query, fields) = convert_new(query, QueryConverter) matches = [] params = [] if conv_query: columns = ["%s.%s" % (table, qn(s)) for s in index.text] matches.append("MATCH(%s) AGAINST (%%s IN BOOLEAN MODE)" \ % ", ".join(columns)) params.append(conv_query) for (field, s) in fields.items(): if field not in index.additional: continue column = "%s.%s" % (table, qn(field)) # these fields should always just be text, so there is # no need for boolean mode matches.append("MATCH(%s) AGAINST(%%s)" % column) params.append(s) if not matches: return EmptyQuerySet(model) return index.get_query_set().extra( # TODO: this isn't an ideal solution for relevance # weighting? select={'_relevance': " + ".join(matches)}, select_params=params, where=matches, params=params, # FIXME: relevance can't be used outside extra() order_by=["-_relevance"])
def __init__(self, *args, **kwargs): super(ProductForm, self).__init__(*args, **kwargs) if self.instance.id: self.fields['main_image'].queryset = (models.ProductImage.objects .filter(product=self.instance)) else: self.fields['main_image'].queryset = EmptyQuerySet(model=models.ProductImage)
def get(self, *args, **kwargs): # TODO fetch the XForm when the manifest is not blank # xform = get_object_or_404( # XForm, # id_string=kwargs.get("id_string"), # username=kwargs.get("username") # ) response = render_to_response( "xformsManifest.xml", { 'host': self.request.build_absolute_uri().replace( self.request.get_full_path(), ''), # TODO do not use an empty query set when we support attachments 'media_files': EmptyQuerySet() }, content_type="text/xml; charset=utf-8") response['X-OpenRosa-Version'] = '1.0' dt = timezone.now().strftime('%a, %d %b %Y %H:%M:%S %Z') response['Date'] = dt return response
def __init__(self, *args, **kwargs): super(CarrierAdminForm, self).__init__(*args, **kwargs) if 'instance' in kwargs: tmp_qs = self.fields['default_zone'].queryset self.fields['default_zone'].queryset = tmp_qs.filter( carrier=kwargs['instance']) else: self.fields['default_zone'].queryset = EmptyQuerySet()
def related_news(self): """ News related to a politician are the union of the news related to allthe politician's current and past institution charges """ news = EmptyQuerySet() for c in self.all_institution_charges: news |= c.related_news return news
def test_no_equivalent_release_for_product(self): """ Should return None for empty querysets """ release = models.Release(version='42.0', channel='Release') release._default_manager = Mock() release._default_manager.filter.return_value.order_by.return_value = ( EmptyQuerySet()) eq_(release.equivalent_release_for_product('Firefox'), None)
def retrieve(self, request, *args, **kwargs): super(SourceRetrieveUpdateDestroyView, self).retrieve(request, *args, **kwargs) self.object = self.get_object() serializer = self.get_serializer(self.object) data = serializer.data source_version = None offset = request.QUERY_PARAMS.get(OFFSET_PARAM, DEFAULT_OFFSET) try: offset = int(offset) except ValueError: offset = DEFAULT_OFFSET limit = settings.REST_FRAMEWORK.get('MAX_PAGINATE_BY', self.paginate_by) include_retired = False include_concepts = request.QUERY_PARAMS.get(INCLUDE_CONCEPTS_PARAM, False) include_mappings = request.QUERY_PARAMS.get(INCLUDE_MAPPINGS_PARAM, False) updated_since = None if include_concepts or include_mappings: source_version = SourceVersion.get_latest_version_of(self.object) paginate_by = self.get_paginate_by(EmptyQuerySet()) if paginate_by: limit = min(limit, paginate_by) include_retired = request.QUERY_PARAMS.get(INCLUDE_RETIRED_PARAM, False) updated_since = parse_updated_since_param(request) if include_concepts: source_version_concepts = source_version.concepts queryset = ConceptVersion.objects.filter(is_active=True) if not include_retired: queryset = queryset.filter(~Q(retired=True)) if updated_since: queryset = queryset.filter(updated_at__gte=updated_since) queryset = queryset.filter(id__in=source_version_concepts) queryset = queryset[offset:offset + limit] serializer = ConceptVersionDetailSerializer(queryset, many=True) data['concepts'] = serializer.data if include_mappings: all_children = source_version.mappings queryset = MappingVersion.objects.filter(is_active=True) if not include_retired: queryset = queryset.filter(~Q(retired=True)) queryset = queryset.filter(id__in=all_children) if updated_since: queryset = queryset.filter(updated_at__gte=updated_since) queryset = queryset[offset:offset + limit] serializer = MappingVersionDetailSerializer(queryset, many=True) data['mappings'] = serializer.data return Response(data)
def get_query_set(self): settings = Settings.objects.order_by("-id") if settings: settings = settings[0] type = settings.stg_directoryservice if type in ('activedirectory', 'ldap', 'nt4', 'nis'): return DirectoryServiceQuerySet(self.model) else: return EmptyQuerySet(self.model)
def tidbits_by_book(request, book): book = book.replace('-',' ') startverse = Verse.objects.filter(book__iexact=book).order_by('id')[:1] if startverse.count() == 0: return HttpResponse(book + " is not valid!") endverse = Verse.objects.filter(book__iexact=book).order_by('-id')[:1] cfs = CrossRef.objects.filter(startverse__gte=startverse, endverse__lte=endverse) from django.db.models.query import EmptyQuerySet tidbits = EmptyQuerySet() for cf in cfs: tidbits |= cf.tidbit_set.all() tidbits = tidbits.distinct() c = { 'filter_criteria': book, 'filter_count': tidbits.count(), 'tidbits': paginate_tidbits(request, tidbits), 'total_count': Tidbit.objects.all().count() } return render_to_response("tidbits_home.html", c, context_instance=RequestContext(request))
def handle(self, *args, **options): today = date.today() to_notify = EmptyQuerySet() # Iterate over sales that are in effect for sale in Sale.objects.filter(start__lte=today, end__gte=today): # Find subscriptions that require the products on sale subscriptions = Subscription.objects.filter( product__in=sale.products.all()) # Remove subscriptions that have been notified subscriptions = subscriptions.exclude(notifications__sale=sale) to_notify |= subscriptions # Collect the subscriptions by user user_subs = defaultdict(list) for sub in to_notify: user_subs[sub.user].append(sub) from_email = getattr(settings, 'DEFAULT_FROM_EMAIL', '*****@*****.**') # Build the emails for user, subs in user_subs.iteritems(): to_email = user.email context = {'user': user, 'subscriptions': subs} subject = render_to_string('notifications/sale_subject.txt', context).replace('\n', '').strip() context['subject'] = subject text_content = render_to_string('notifications/sale_body.txt', context) html_content = render_to_string('notifications/sale_body.html', context) msg = EmailMultiAlternatives(subject, text_content, from_email, [to_email]) msg.attach_alternative(html_content, 'text/html') msg.send() # Will raise exceptions on failure # Mark all active sales for this product as notified for sub in subs: for sale in sub.product.active_sales.all(): notified = Notification() notified.sale = sale notified.subscription = sub notified.save()
def __init__(self, *args, **kwargs): super(ProductForm, self).__init__(*args, **kwargs) if self.instance.pk: self.fields['categories'].initial = [ c.id for c in self.instance.categories.all() ] if self.instance.id: self.fields['main_image'].queryset = ( models.ProductImage.objects.filter(product=self.instance)) else: self.fields['main_image'].queryset = EmptyQuerySet( model=models.ProductImage)
def bookmark_search_page(request): bookmarks = EmptyQuerySet() search_type = '' query = '' show_results = False if request.GET.has_key('search_type') and request.GET.has_key('query'): search_type = request.GET['search_type'] query = request.GET['query'].strip() show_results = True form = BookmarkSearchForm({'search_type':search_type,'query':query}) if search_type and query: if search_type =='tag': bookmarks = Bookmark.objects.filter(tag__name__icontains = query) elif search_type == 'user': bookmarks = Bookmark.objects.filter(user__username__icontains = query) elif search_type == 'bookmark': bookmarks = Bookmark.objects.filter(title__icontains = query) else: pass if request.user.username: bookmarks = bookmarks.filter(Q(user = request.user)|Q(shared = True)) else: bookmarks = bookmarks.filter(shared = True) else: form = BookmarkSearchForm() return render_to_response( 'bookmark_search_page.html', context_instance = RequestContext(request,{ 'search_type':search_type, 'query':query, 'form':form, 'show_user':True, 'bookmark_list':bookmarks, 'paginate_by' : ITEMS_PER_PAGE, 'show_results' : show_results, }) )
def _fetch_all_for_group(self, **kwargs): group = kwargs['group'] albums = Album.remote.fetch(group, all=True) overall_result = EmptyQuerySet(model=Photo) last_result = EmptyQuerySet(model=Photo) overall_count = kwargs.get('count') for album in albums: if overall_count is not None and not kwargs.get('all'): overall_count -= len(last_result) kwargs['count'] = min(self.__class__.fetch_photo_limit, overall_count) if kwargs['count'] <= 0: break else: kwargs['all'] = True kwargs['album'] = album last_result = self._fetch_group_album(**kwargs) overall_result = last_result | overall_result return overall_result
def search(self, keywords, search_type='or'): if type(keywords) in [unicode, str]: keywords = keywords.strip().split() Q_list = [Q(title__icontains=keyword) for keyword in keywords] Q_filters = reduce(lambda x, y: x or y, Q_list) if len(keywords) > 0: qs = Thread.objects.filter(Q_filters) else: qs = EmptyQuerySet() return qs
def get_queryset(self): if not self.parent_resource: # pathological case return EmptyQuerySet() queryset = super(ChildResourceMixin, self).get_queryset() queryset = queryset.filter(parent_id=self.parent_resource.id) if self.include_inverse_mappings: queryset = queryset.filter(Q(from_concept=self.concept) | Q(to_concept=self.concept)) else: queryset = queryset.filter(from_concept=self.concept) if not self.include_retired: queryset = queryset.filter(~Q(retired=True)) return queryset
def related_news(self): """ News related to a location are the union of the news related to all the acts tagged with this location """ news = EmptyQuerySet() tagged_acts = Act.objects.filter(id__in=set( [ta['act_id'] for ta in self.tagged_acts.values('act_id')])) for a in tagged_acts: news |= a.downcast().related_news return news
def render(self, context): try: object = template.resolve_variable(self.object, context) except template.VariableDoesNotExist: return '' # extract all news # if obect is a Person, extract news related to all current and past charges if isinstance(object, Person): news = EmptyQuerySet() for c in object.all_institution_charges: news |= c.related_news elif isinstance(object, basestring): if object == 'politicians_all': news = EmptyQuerySet() for c in InstitutionCharge.objects.all(): news |= c.related_news if object == 'politicians_council': news = EmptyQuerySet() for c in municipality.council.charges: news |= c.related_news if object == 'politicians_gov': news = EmptyQuerySet() for c in municipality.gov.charges: news |= c.related_news else: news = object.related_news # filter only news of a given type (INST or COMM) (if given) if self.news_type: news = news.filter(news_type=self.news_type) # sort news by news_date, descending order # context[self.context_var] = sorted(news, key=lambda n: n.news_date or datetime.date(datetime.MINYEAR,1,1), reverse=True)[0:15] context[self.context_var] = news.order_by("-created")[0:15] return ''
def tidbits_by_book(request, book): book = book.replace('-', ' ') startverse = Verse.objects.filter(book__iexact=book).order_by('id')[:1] if startverse.count() == 0: return HttpResponse(book + " is not valid!") endverse = Verse.objects.filter(book__iexact=book).order_by('-id')[:1] cfs = CrossRef.objects.filter(startverse__gte=startverse, endverse__lte=endverse) from django.db.models.query import EmptyQuerySet tidbits = EmptyQuerySet() for cf in cfs: tidbits |= cf.tidbit_set.all() tidbits = tidbits.distinct() c = { 'filter_criteria': book, 'filter_count': tidbits.count(), 'tidbits': paginate_tidbits(request, tidbits), 'total_count': Tidbit.objects.all().count() } return render_to_response("tidbits_home.html", c, context_instance=RequestContext(request))
def index_queryset(self): # get the correct language and exclude pages that have a redirect base_qs = super(_PageIndex, self).index_queryset() result_qs = EmptyQuerySet() for site_obj in Site.objects.all(): qs = base_qs.published(site=site_obj.id).filter( Q(title_set__language=language_code) & (Q(title_set__redirect__exact='') | Q(title_set__redirect__isnull=True))) if 'publisher' in settings.INSTALLED_APPS: qs = qs.filter(publisher_is_draft=True) qs = qs.distinct() result_qs |= qs return result_qs
def search_haystack(request, species_wid, query): #search if species_wid is None: species_wid = Species.objects.all()[0].wid results = SearchQuerySet().filter(species_wid=species_wid).filter( content=query) #calculate facets facets = results.facet('model_type') tmp = facets.facet_counts()['fields']['model_type'] modelNameFacet = [] objectTypes = getObjectTypes() models = [] for tmp2 in tmp: modelName = objectTypes[objectTypes.index(tmp2[0])] modelNameFacet.append({ 'name': modelName, 'verbose_name': getModel(modelName)._meta.verbose_name, 'count': tmp2[1], }) models.append(getModel(modelName)) modelNameFacet.sort(lambda x, y: cmp(x['verbose_name'], y['verbose_name'])) #narrow search by facets model_type = request.GET.get('model_type', '') if model_type: results = results.models(getModel(model_type)) #order results results = results.order_by('wid') #convert results to query set queryset = EmptyQuerySet() for object in results: tmp = object.model.objects.none() tmp._result_cache.append(object.object) queryset = chain(queryset, tmp) #form response return render_queryset_to_response(species_wid=species_wid, request=request, models=models, queryset=queryset, templateFile='public/search.html', data={ 'query': query, 'engine': 'haystack', 'model_type': model_type, 'modelNameFacet': modelNameFacet, })
def related_news(self): """ News related to a category are the union of the news related to all the acts tagged with ther category and all the tags contained in the category """ news = EmptyQuerySet() # fetch all acts tagget with the category tagged_acts = Act.objects.filter( id__in=set([ta['content_object_id'] for ta in self.tagged_acts.values('content_object_id')]) ) for a in tagged_acts: news |= a.downcast().related_news return news
def __init__(self, *args, **kwargs): self.user = kwargs.pop('user', AnonymousUser) kwargs['queryset'] = EmptyQuerySet() if self.user is not AnonymousUser: if self.user.is_authenticated(): kwargs['queryset'] = InputFile.objects.filter(user__exact = self.user) else: ''' TODO: add AnonymousUser logic here ATM tests suppose that AnonymousUsers don't have any input files. ''' super(InputFileChoiceField, self).__init__(*args, **kwargs)
def _simplify(self, qss=None): ''' Returns QuerySetSequence, QuerySet or EmptyQuerySet depending on the contents of items, i.e. at least two non empty QuerySets, exactly one non empty QuerySet and all empty QuerySets respectively. Does not modify original QuerySetSequence. ''' not_empty_qss = filter(None, qss if qss else self.iables) if not len(not_empty_qss): return EmptyQuerySet() if len(not_empty_qss) == 1: return not_empty_qss[0] return QuerySetSequence(*not_empty_qss)
def render(self, context): try: object = template.resolve_variable(self.object, context) except template.VariableDoesNotExist: return '' # extract all news # if obect is a Person, extract news related to all current and past charges if isinstance(object, Person): news = EmptyQuerySet() for c in object.all_institution_charges: news |= c.related_news elif isinstance(object, basestring): if object == 'politicians_all': news = EmptyQuerySet() for c in InstitutionCharge.objects.all(): news |= c.related_news if object == 'politicians_council': news = EmptyQuerySet() for c in municipality.council.charges: news |= c.related_news if object == 'politicians_gov': news = EmptyQuerySet() for c in municipality.gov.charges: news |= c.related_news else: news = object.related_news # filter only news of a given type (INST or COMM) (if given) if self.news_type: news = news.filter(news_type=self.news_type) # sort news by news_date, descending order context[self.context_var] = sorted(news, key=lambda n: n.news_date, reverse=True)[0:15] return ''
def search(request, keywords=None): if not keywords: keywords = request.GET.get('q', "") if keywords != "": qs = News.objects.get_published().filter( Q(title__contains=keywords) | Q(content__contains=keywords)) else: qs = EmptyQuerySet() return ListView.as_view(request, qs, template_object_name='item', template_name='news/search.html', paginate_by=1, extra_context={"keywords": keywords})
def __init__(self, *args, **kwargs): ''' Build algorithm's arguments form dynamically based on given arguments. This form is shown in browser when user wants to do a new run for certain algorithm. user: User who is currently active in this session. Only this user's files will be shown as possible input files. arguments: 'args' field from instance of Algorithm model. post: request.POST to populate form fields so that is_valid() can be called. Don't use this if you expect user to populate the fields. ''' self.user = kwargs.pop('user', AnonymousUser) post = kwargs.pop('post', None) arguments = kwargs.pop('arguments', None) super(forms.Form, self).__init__(*args, **kwargs) # We need to keep these in mind to check that all of them will be owned # by self.user when form is validated. self.input_files = [] for arg in arguments.all(): key, value, name = arg.key, arg.value, arg.name kwargs = {'label': name, 'validators': field_validators[value]} if value == 'boolean': kwargs['required'] = False if value == 'input_file': kwargs['user'] = self.user field = ftypes[value](**kwargs) #print "%s %s" % (self.user, len(field.queryset)) if field is not EmptyQuerySet(): self.input_files.append(key) self.fields[key] = field else: self.fields[key] = ftypes[value](**kwargs) ''' If there is request, we change form's data to correspond request's key values. ''' if post is not None: for key in post.keys(): self.data[key] = post[key] self.is_bound = True
def fetch_likes(self, **kwargs): kwargs['gid'] = self.owner.pk if not kwargs.get('count'): kwargs['count'] = self.__class__.fetch_like_users_limit kwargs['fields'] = self.__class__.remote.get_request_fields( 'user', prefix=True) response = self.__class__.remote.api_call(method='get_likes', **kwargs) users = response.get('users') if users: users_ids = User.remote.get_or_create_from_resources_list( users).values_list('pk', flat=True) else: users_ids = EmptyQuerySet(model=User) return users_ids, response
def getRows(database, table, q): LOG(q) dbModule = getattr(models, database, None) if dbModule: tableObj = getattr(dbModule, table.capitalize()) tableDigestObj = getattr(dbModule, table.capitalize() + 'Digest') table = 'transition' if table == 'lineprof' else table dsID = 'id_%s_ds' % table exQ = Q( **{ dsID + '__in': tableDigestObj.objects.filter( line_count__gt=settings.LIMIT).values_list(dsID, flat=True) }) return tableObj.objects.select_related().exclude(exQ).filter( makeQ(q, (table, ))) else: return EmptyQuerySet()
def exportData(request, species_wid=None): getDict = request.GET.copy() if getDict.get('format', ''): getDict.__setitem__('species', getDict.get('species', species_wid)) form = ExportDataForm(getDict or None) if not form.is_valid(): return render_queryset_to_response( species_wid=species_wid, request=request, templateFile='public/exportDataForm.html', data={'form': form}) else: species = Species.objects.get(wid=form.cleaned_data['species']) queryset = EmptyQuerySet() models = [] if form.cleaned_data['all_model_types'] == 'True': model_types = getObjectTypes() else: model_types = form.cleaned_data['model_type'] for model_type in model_types: model = getModel(model_type) if issubclass(model, SpeciesComponent): queryset = chain( queryset, model.objects.filter( species__id=species.id).select_related(depth=2).all()) else: queryset = chain( queryset, model.objects.select_related(depth=2).filter( id=species.id)) models.append(getModel(model_type)) return render_queryset_to_response( species_wid=species_wid, request=request, queryset=queryset, templateFile='public/exportDataResult.html', models=models)
def includeConceptsAndMappings(self, request, data, container_version): offset = request.QUERY_PARAMS.get(OFFSET_PARAM, DEFAULT_OFFSET) try: offset = int(offset) except ValueError: offset = DEFAULT_OFFSET limit = settings.REST_FRAMEWORK.get('MAX_PAGINATE_BY', self.paginate_by) include_retired = False include_concepts = request.QUERY_PARAMS.get(INCLUDE_CONCEPTS_PARAM, False) include_mappings = request.QUERY_PARAMS.get(INCLUDE_MAPPINGS_PARAM, False) updated_since = None if include_concepts or include_mappings: paginate_by = self.get_paginate_by(EmptyQuerySet()) if paginate_by: limit = min(limit, paginate_by) include_retired = request.QUERY_PARAMS.get(INCLUDE_RETIRED_PARAM, False) updated_since = parse_updated_since_param(request) if include_concepts: queryset = container_version.get_concepts() queryset = queryset.filter(is_active=True) if not include_retired: queryset = queryset.filter(~Q(retired=True)) if updated_since: queryset = queryset.filter(updated_at__gte=updated_since) queryset = queryset[offset:offset+limit] serializer = ConceptVersionDetailSerializer(queryset, many=True) data['concepts'] = serializer.data if include_mappings: queryset = container_version.get_mappings() queryset = queryset.filter(is_active=True) if not include_retired: queryset = queryset.filter(~Q(retired=True)) if updated_since: queryset = queryset.filter(updated_at__gte=updated_since) queryset = queryset[offset:offset+limit] serializer = MappingVersionDetailSerializer(queryset, many=True) data['mappings'] = serializer.data
def get_queryset_descendants(nodes, include_self=False, add_to_result=None): """ RUS: Запрос к базе данных потомков. Если нет узлов, то возвращается пустой запрос. :param nodes: список узлов дерева, по которым необходимо отыскать потомков :param include_self: признак включения в результ исходного спичка узлов :param add_to_result: список ключей узлов которые необходимо дополнительно включить в результат :return: список узлов (QuerySet), отсортированный в порядке обхода дерева """ if not nodes: # HACK: Emulate MPTTModel.objects.none(), because MPTTModel is abstract return EmptyQuerySet(MPTTModel) filters = [] model_class = nodes[0].__class__ if include_self: for n in nodes: if n.get_descendant_count(): lft, rght = n.lft - 1, n.rght + 1 filters.append(Q(tree_id=n.tree_id, lft__gt=lft, rght__lt=rght)) else: filters.append(Q(pk=n.pk)) else: for n in nodes: if n.get_descendant_count(): lft, rght = n.lft, n.rght filters.append(Q(tree_id=n.tree_id, lft__gt=lft, rght__lt=rght)) if add_to_result: if len(add_to_result) > 1: filters.append(Q(id__in=add_to_result)) else: filters.append(Q(pk=add_to_result[0])) if filters: return model_class.objects.filter(reduce(operator.or_, filters)) else: # HACK: Emulate model_class.objects.none() return model_class.objects.filter(id__isnull=True)
def search(query, models=None): assert models and len(models) == 1, \ "This search backend only supports searching single models." model = models[0] (conv_query, fields) = convert_new(query, QueryConverter) # TODO: fields. if not conv_query: return EmptyQuerySet(model) index = get_indexer(model) if len(index.text) > 1: columns = ["coalesce(%s, '')" % qn(s) for s in index.text] else: columns = index.text # TODO: support different languages tsvector = "to_tsvector('english', %s)" % " || ".join(columns) return index.get_query_set().extra( select={'_relevance': "ts_rank(%s, to_tsquery(%%s), 32)" % tsvector}, select_params=[conv_query], where=["to_tsquery(%%s) @@ %s" % tsvector], params=[conv_query], # FIXME: relevance can't be used outside extra() order_by=["-_relevance"])
def tidbits_by_passage(request, user=None): if request.method == 'GET': passage_ref = request.GET['passage_ref'] try: startverse, endverse = CrossRef.objects.parse_reference(passage_ref) except Exception as e: # TODO: make this neater return HttpResponse(str(e.args[0])) # regex = re.compile("(?P<book>([12]?[A-Za-z ]+[A-Za-z]))( ?(?P<start_chapter>[0-9]+)((:(?P<start_verse>[0-9]+))? ?(- ?(?P<end_chp_or_verse>[0-9]+)(:(?P<end_verse>[0-9]+))?)?)?)?$") # matches = regex.search(passage_ref) # if matches == None: # # TODO: make this neater # return HttpResponse("Invalid passage reference: " + passage_ref) # groups = matches.groupdict() # book = groups['book'] # startchp = groups['start_chapter'] # startvs = groups['start_verse'] # endchporvs = groups['end_chp_or_verse'] # endvs = groups['end_verse'] # cfs = None # if not startchp: # startverse = Verse.objects.filter(book__iexact=book).order_by('id')[:1] # if startverse.count() == 0: # return HttpResponse(book + " is not valid!") # endverse = Verse.objects.filter(book__iexact=book).order_by('-id')[:1] # cfs = CrossRef.objects.filter(startverse__gte=startverse, endverse__lte=endverse) # elif not startvs: # startverse = Verse.objects.filter( # book__iexact=book, # chapter_ref=int(startchp), # verse_ref=1 # ).order_by('id')[:1] # if startverse.count() == 0: # return HttpResponse(book + " " + int(startchp) + " is not valid!") # endverse = Verse.objects.filter( # book__iexact=book, # chapter_ref=int(startchp) # ).order_by('-id')[:1] # cfs = CrossRef.objects.filter(startverse__gte=startverse, endverse__lte=endverse) # elif not endchporvs: # endchp = startchp # endvs = startvs # elif not endvs: # endvs = endchporvs # endchp = startchp # else: # endchp = endchporvs # startverse = Verse.objects.get(book__istartswith=book, # chapter_ref=int(startchp), # verse_ref=int(startvs)) # endverse = Verse.objects.get(book__istartswith=book, # chapter_ref=int(endchp), # verse_ref=int(endvs)) # if startverse.id > endverse.id: # # TODO: handle this # return HttpResponse("Start verse " + startverse + " must come before end verse " + endverse) # get tidbits where a cross ref intersects with a given range (more general) cfs = CrossRef.objects.filter( startverse__gte=startverse, endverse__lte=endverse ) cfs |= CrossRef.objects.filter( startverse__gte=startverse, endverse__gte=endverse, startverse__lte=endverse ) cfs |= CrossRef.objects.filter( startverse__lte=startverse, endverse__lte=endverse, endverse__gte=startverse ) # get tidbits where a cross ref is completely contained in the given range (more precise) cfs = CrossRef.objects.filter( startverse__gte=startverse, endverse__lte=endverse ) # get tidbit entries for each cf from django.db.models.query import EmptyQuerySet tidbits = EmptyQuerySet() for cf in cfs: tidbits |= cf.tidbit_set.all() tidbits = tidbits.distinct() else: return HttpResponseRedirect(reverse('tidbits:home')) c = { 'filter_criteria': passage_ref, 'filter_count': tidbits.count(), 'tidbits': paginate_tidbits(request, tidbits), 'total_count': Tidbit.objects.all().count() } return render_to_response("tidbits_home.html", c, context_instance=RequestContext(request))
def voters_email(request, election, poll=None, voter_uuid=None): user = request.admin TEMPLATES = [("vote", _("Time to Vote")), ("info", _("Additional Info"))] default_template = "vote" if not election.any_poll_feature_can_send_voter_mail: raise PermissionDenied("34") if not election.any_poll_feature_can_send_voter_booth_invitation: TEMPLATES.pop(0) default_template = "info" if election.voting_extended_until and not election.voting_ended_at: TEMPLATES.append(("extension", _("Voting end date extended"))) template = request.REQUEST.get("template", default_template) if not template in [t[0] for t in TEMPLATES]: raise Exception("bad template") polls = [poll] if not poll: polls = election.polls_by_link_id voter = None if voter_uuid: try: if poll: voter = get_object_or_404(Voter, uuid=voter_uuid, poll=poll) else: voter = get_object_or_404(Voter, uuid=voter_uuid, election=election) except Voter.DoesNotExist: raise PermissionDenied("35") if not voter: url = election_reverse(election, "index") return HttpResponseRedirect(url) election_url = election.get_absolute_url() default_subject = render_to_string("email/%s_subject.txt" % template, {"custom_subject": "<SUBJECT>"}) default_body = render_to_string( "email/%s_body.txt" % template, { "election": election, "election_url": election_url, "custom_subject": default_subject, "custom_message": "<BODY>", "voter": { "vote_hash": "<SMART_TRACKER>", "name": "<VOTER_NAME>", "voter_name": "<VOTER_NAME>", "voter_surname": "<VOTER_SURNAME>", "voter_login_id": "<VOTER_LOGIN_ID>", "voter_password": "******", "audit_passwords": "1", "get_audit_passwords": ["pass1", "pass2", "..."], "get_quick_login_url": "<VOTER_LOGIN_URL>", "poll": poll, "election": election, }, }, ) q_param = request.GET.get("q", None) filtered_voters = election.voters.filter() if poll: filtered_voters = poll.voters.filter() if not q_param: filtered_voters = EmptyQuerySet() else: voters_filters = get_filters( q_param, VOTER_TABLE_HEADERS, VOTER_SEARCH_FIELDS, VOTER_BOOL_KEYS_MAP, VOTER_EXTRA_HEADERS ) filtered_voters = filtered_voters.filter(voters_filters) if not filtered_voters.count(): message = _("No voters were found.") messages.error(request, message) url = election_reverse(election, "polls_list") return HttpResponseRedirect(url) if request.method == "GET": email_form = EmailVotersForm() email_form.fields["subject"].initial = dict(TEMPLATES)[template] if voter: email_form.fields["send_to"].widget = email_form.fields["send_to"].hidden_widget() else: email_form = EmailVotersForm(request.POST) if email_form.is_valid(): # the client knows to submit only once with a specific voter_id voter_constraints_include = None voter_constraints_exclude = None update_booth_invitation_date = False if template == "vote": update_booth_invitation_date = True if voter: voter_constraints_include = {"uuid": voter.uuid} # exclude those who have not voted if email_form.cleaned_data["send_to"] == "voted": voter_constraints_exclude = {"vote_hash": None} # include only those who have not voted if email_form.cleaned_data["send_to"] == "not-voted": voter_constraints_include = {"vote_hash": None} for _poll in polls: if not _poll.feature_can_send_voter_mail: continue if template == "vote" and not _poll.feature_can_send_voter_booth_invitation: continue subject_template = "email/%s_subject.txt" % template body_template = "email/%s_body.txt" % template extra_vars = { "custom_subject": email_form.cleaned_data["subject"], "custom_message": email_form.cleaned_data["body"], "election_url": election_url, } task_kwargs = { "subject_template": subject_template, "body_template": body_template, "extra_vars": extra_vars, "voter_constraints_include": voter_constraints_include, "voter_constraints_exclude": voter_constraints_exclude, "update_date": True, "update_booth_invitation_date": update_booth_invitation_date, "q_param": q_param, } log_obj = election if poll: log_obj = poll if voter: log_obj.logger.info( "Notifying single voter %s, [template: %s, filter: %s]", voter.voter_login_id, template, q_param ) else: log_obj.logger.info("Notifying voters, [template: %s, filter: %r]", template, q_param) tasks.voters_email.delay(_poll.pk, **task_kwargs) filters = get_voters_filters_with_constraints(q_param, voter_constraints_include, voter_constraints_exclude) send_to = filtered_voters.filter(filters) if q_param and not send_to.filter(filters).count(): msg = "No voters matched your filters. No emails were sent." messages.error(request, _(msg)) else: messages.info(request, _("Email sending started")) url = election_reverse(election, "polls_list") if poll: url = poll_reverse(poll, "voters") if q_param: url += "?q=%s" % urllib.quote_plus(q_param) return HttpResponseRedirect(url) context = { "email_form": email_form, "election": election, "poll": poll, "voter_o": voter, "default_subject": default_subject, "default_body": default_body, "template": template, "filtered_voters": filtered_voters, "templates": TEMPLATES, } set_menu("voters", context) if not poll: set_menu("polls", context) return render_template(request, "voters_email", context)
def reporting(request): local_timezone = pytz.timezone(TIME_ZONE) # load/set defaults start_date = request.GET.get('start_date') end_date = request.GET.get('end_date') signup_start_date = request.GET.get('signup_start_date') signup_end_date = request.GET.get('signup_end_date') order_start_date = request.GET.get('order_start_date') order_end_date = request.GET.get('order_end_date') # Convert strings to local timezone datetimes start_date, end_date, desc = fix_date_range(start_date, end_date) signup_start_date, signup_end_date, signup_desc = fix_date_range(signup_start_date, signup_end_date) order_start_date, order_end_date, order_desc = fix_date_range(order_start_date, order_end_date) buyers_all = Buyer.objects.all() buyers_active = Buyer.objects.filter( userprofile__site=request.user.userprofile.site, userprofile__approved=True, ) vendors_all = Vendor.objects.all() vendors_active = Vendor.objects.filter( userprofile__site=request.user.userprofile.site, userprofile__approved=True, ) report = request.GET.get('report') # initialize data orders = [] output = [] output_text = '' csv_text = '' table_text = '' filter = [] filter2= [] totals = [] report_header = '' column_headers = [] column_fields = [] data = '' if report in ['buyer_all', 'vendor_all']: if report == 'buyer_all': as_buyer = True else: as_buyer = False # Build report data if as_buyer: query = buyers_all report_header = 'Buyers - All %s' % ', '.join(filter) column_headers = ['Buyer', 'Username', 'Signup Date'] else: query = vendors_all report_header = 'Vendors - All %s' % ', '.join(filter) column_headers = ['Vendor', 'Username', 'Signup Date'] query, filter = apply_report_filters(request, query) data = query # obj = Buyer or Vendor column_fields = ['obj.name', 'obj.userprofile.user.username', 'obj.created.strftime("%m-%d-%Y")'] filter = [] elif report in ['new_buyer_no_purchases', 'buyer_inactive', 'new_vendor_no_sales', 'vendor_inactive']: if report in ['new_buyer_no_purchases', 'buyer_inactive']: as_buyer = True else: as_buyer = False company_orders = [] company_no_orders = [] if as_buyer: query = buyers_all else: query = vendors_all query, filter = apply_report_filters(request, query) for company in query: if as_buyer: try: orders = Order.objects.filter(buyer = company.userprofile.user, state=COMPLETED) except: orders = EmptyQuerySet() else: try: orders = Order.objects.filter(vendor = company, state=COMPLETED) except: orders = EmptyQuerySet() orders, filter2 = apply_order_filters(request, orders) num_orders = len(orders) if num_orders == 0: company_no_orders.append(company) else: company_orders.append(company) if filter2: filter += filter2 if as_buyer: if report in ['new_buyer_no_purchases']: report_header = 'New Buyers - No Purchases - %s' % ', '.join(filter) else: report_header = 'Inactive Buyers - No Purchases - %s' % ', '.join(filter) column_headers = ['Buyer', 'Username', 'Signup Date'] else: if report in ['new_buyer_no_purchases']: report_header = 'New Vendors - No Sales - %s' % ', '.join(filter) else: report_header = 'Inactive Vendors - No Sales- %s' % ', '.join(filter) column_headers = ['Vendor', 'Username', 'Signup Date'] # Build report data data = company_no_orders # obj = Buyer column_fields = ['obj.name', 'obj.userprofile.user.username', 'obj.created.strftime("%m-%d-%Y")'] if report in ['new_buyer_no_purchases', 'new_vendor_no_sales']: filter = ['signup_date'] else: filter = ['signup_date', 'order_date'] elif report in ['buyer_search', 'vendor_search']: if report in ['buyer_search']: as_buyer = True else: as_buyer = False company_no_orders = [] company_orders = [] if as_buyer: query = buyers_all else: query = vendors_all query, filter = apply_report_filters(request, query) # Build report data data = query if as_buyer: report_header = 'Buyer Search - %s' % ', '.join(filter) column_headers = ['Buyer', 'Username', 'Created', 'City', 'State', 'Zip'] else: report_header = 'Vendor Search - %s' % ', '.join(filter) column_headers = ['Vendor', 'Username', 'Created', 'City', 'State', 'Zip'] # obj = Buyer or Vendor column_fields = ['obj.name', 'obj.userprofile.user.username', 'obj.created.strftime("%m-%d-%Y")', 'obj.city', 'obj.state', 'obj.zip'] filter = ['signup_date', 'location', 'username'] elif report in ['order_summary_by_buyer']: if report == 'order_summary_by_buyer': as_buyer = True else: as_buyer = False data = [] if as_buyer: query= buyers_all else: query= vendors_all query, filter = apply_report_filters(request, query) for company in query: min = 9999999 max = 0 count = 0 total = 0 avg = 0 min_date = datetime(3000,1,1).replace(tzinfo=utc) max_date = datetime(2000,1,1).replace(tzinfo=utc) if as_buyer: try: orders = Order.objects.filter(buyer=company.userprofile.user) except: orders = EmptyQuerySet() else: try: orders = Order.objects.filter(vendor=company) except: orders = EmptyQuerySet() orders = orders.filter(state=COMPLETED, date_confirmed__isnull=False) orders, filter2 = apply_order_filters(request, orders) if orders: for o in orders: o_total = o.total # cache so we don't have to keep re-calling this VERY expensive @property count += 1 total += o_total if o_total < min: min = o_total if o_total > max: max = o_total if o.date_confirmed < min_date: min_date = o.date_confirmed if o.date_confirmed > max_date: max_date = o.date_confirmed avg = round(total / count, 2) # Can't do these without an actual order total db field # count = orders.aggregate(Count('order_total'))['order_total__count'] # total = orders.aggregate(Sum('order_total'))['order_total__sum'] # avg = orders.aggregate(Avg('order_total'))['order_total__avg'] # min = orders.aggregate(Min('order_total'))['order_total__min'] # max = orders.aggregate(Max('order_total'))['order_total__max'] # min_date = orders.aggregate(Min('date_confirmed'))['date_confirmed__min'] # max_date = orders.aggregate(Max('date_confirmed'))['date_confirmed__max'] if count: data.append({ 'company' : company, 'total' : total, 'count' : count, 'avg' : avg, 'min' : min, 'max' : max, 'min_date' : min_date, 'max_date' : max_date, }) filter += filter2 # add report and order filter descriptions report_header = 'Order Summary by %s - %s' % ('Buyer' if as_buyer else 'Vendor', ', '.join(filter)) column_headers = [ 'Buyer' if as_buyer else 'Vendor', 'Username', 'Created', 'First Order', 'Last Order' '# Orders', 'Total $', 'Avg $', 'Min $', 'Max $', ] # obj = Vendor column_fields = [ "obj['company'].name", "obj['company'].userprofile.user.username", "obj['company'].created.strftime('%m-%d-%Y')", "obj['min_date'].strftime('%m-%d-%Y')", "obj['max_date'].strftime('%m-%d-%Y')", "obj['count']", "obj['total']", "obj['avg']", "obj['min']", "obj['max']", ] filter = ['order_date', 'buyer', 'location', 'username', 'note_slow'] elif report in ['order_details_by_buyer', 'order_details_by_vendor']: if report == 'order_details_by_buyer': as_buyer = True else: as_buyer = False data = [] if as_buyer: query= buyers_all else: query= vendors_all query, filter = apply_report_filters(request, query) for company in query: min = 9999999 max = 0 count = 0 total = 0 avg = 0 min_date = datetime(3000,1,1).replace(tzinfo=utc) max_date = datetime(2000,1,1).replace(tzinfo=utc) if as_buyer: try: orders = Order.objects.filter(buyer=company.userprofile.user) except: orders = EmptyQuerySet() else: try: orders = Order.objects.filter(vendor=company) except: orders = EmptyQuerySet() orders = orders.filter(state=COMPLETED, date_confirmed__isnull=False) orders, filter2 = apply_order_filters(request, orders) if orders: for o in orders: data.append(o) filter += filter2 # add report and order filter descriptions report_header = 'Order Details by %s - %s' % ('Buyer' if as_buyer else 'Vendor', ', '.join(filter)) column_headers = [ 'Buyer' if as_buyer else 'Vendor', 'Vendor' if as_buyer else 'Buyer', 'Order', 'Subtotal', 'Shipping', 'Total', 'Confirmed', 'Delivery Type', 'Delivery Date', 'Ratings', '# Items', 'Categories/#', ] # obj = Vendor column_fields = [ "obj.buyer.userprofile.buyer.name" if as_buyer else "obj.vendor.name", "obj.vendor.name" if as_buyer else "obj.buyer.userprofile.buyer.name", "obj.uniqueId", "obj.sub_total", "obj.shipping", "obj.total", "obj.date_confirmed.replace(tzinfo=local_timezone).strftime('%m-%d-%Y %H:%M')", "DELIVERY_OPTION_DICT[obj.delivery_option]", "obj.delivery_date.strftime('%m-%d-%Y') if obj.delivery_date else ''", "'%s / %s' % (obj.buyer_rating, obj.vendor_rating)" if as_buyer else "'%s / %s' % (obj.vendor_rating, obj.buyer_rating)", "obj.entry_set.count()", "obj.categories_count", ] filter = ['signup_date', 'order_date', 'buyer', 'vendor', 'location', 'note_slow'] else: # Report not found pass ################################# # Process the report ################################# # process the report if one is specified if data and report: csv_text = data_as_csv(data, report_header, column_headers, column_fields) table_text = data_as_table(data, report_header, column_headers, column_fields) if (request.GET.get('csv')): filename = "%s-%s.csv" % (request.site.name, report) response = HttpResponse( csv_text, mimetype = 'text/csv;', ) response['Content-Disposition'] = 'attachment;filename=%s' % (filename) return response context = { # "start_date" : start_date.astimezone(pytz.timezone('US/Eastern')), # "end_date" : end_date.astimezone(pytz.timezone('US/Eastern')), # "signup_start_date" : signup_start_date.astimezone(pytz.timezone('US/Eastern')), # "signup_end_date" : signup_end_date.astimezone(pytz.timezone('US/Eastern')), # "order_start_date" : order_start_date.astimezone(pytz.timezone('US/Eastern')), # "order_end_date" : order_end_date.astimezone(pytz.timezone('US/Eastern')), # "reports" : reports, "report" : report, "buyers_active" : buyers_active, "vendors_active" : vendors_active, "orders" : orders, "data" : data, "output" : output, "output_text" : table_text, "output_rows" : len(data), "csv_url" : "%s?%s&csv=1" % (request.path, request.META.get('QUERY_STRING')), "filter" : filter, "date_ranges" : DATE_RANGES, # "output_text" : csv_text, } return render_to_response( "reporting.html", context, context_instance = RequestContext(request) )
def voters_email(request, election, poll=None, voter_uuid=None): user = request.admin TEMPLATES = [ ('vote', _('Time to Vote')), ('info', _('Additional Info')), ] default_template = 'vote' if not election.any_poll_feature_can_send_voter_mail: raise PermissionDenied('34') if not election.any_poll_feature_can_send_voter_booth_invitation: TEMPLATES.pop(0) default_template = 'info' if election.voting_extended_until and not election.voting_ended_at: TEMPLATES.append(('extension', _('Voting end date extended'))) template = request.REQUEST.get('template', default_template) if not template in [t[0] for t in TEMPLATES]: raise Exception("bad template") polls = [poll] if not poll: polls = election.polls_by_link_id voter = None if voter_uuid: try: if poll: voter = get_object_or_404(Voter, uuid=voter_uuid, poll=poll) else: voter = get_object_or_404(Voter, uuid=voter_uuid, election=election) except Voter.DoesNotExist: raise PermissionDenied('35') if not voter: url = election_reverse(election, 'index') return HttpResponseRedirect(url) election_url = election.get_absolute_url() default_subject = render_to_string( 'email/%s_subject.txt' % template, { 'custom_subject': "<SUBJECT>" }) default_body = render_to_string( 'email/%s_body.txt' % template, { 'election' : election, 'election_url' : election_url, 'custom_subject' : default_subject, 'custom_message': '<BODY>', 'voter': { 'vote_hash' : '<SMART_TRACKER>', 'name': '<VOTER_NAME>', 'voter_name': '<VOTER_NAME>', 'voter_surname': '<VOTER_SURNAME>', 'voter_login_id': '<VOTER_LOGIN_ID>', 'voter_password': '******', 'audit_passwords': '1', 'get_audit_passwords': ['pass1', 'pass2', '...'], 'get_quick_login_url': '<VOTER_LOGIN_URL>', 'poll': poll, 'election' : election} }) q_param = request.GET.get('q', None) filtered_voters = election.voters.filter() if poll: filtered_voters = poll.voters.filter() if not q_param: filtered_voters = EmptyQuerySet() else: voters_filters = get_filters(q_param, VOTER_TABLE_HEADERS, VOTER_SEARCH_FIELDS, VOTER_BOOL_KEYS_MAP, VOTER_EXTRA_HEADERS) filtered_voters = filtered_voters.filter(voters_filters) if not filtered_voters.count(): message = _("No voters were found.") messages.error(request, message) url = election_reverse(election, 'polls_list') return HttpResponseRedirect(url) if request.method == "GET": email_form = EmailVotersForm() email_form.fields['subject'].initial = dict(TEMPLATES)[template] if voter: email_form.fields['send_to'].widget = \ email_form.fields['send_to'].hidden_widget() else: email_form = EmailVotersForm(request.POST) if email_form.is_valid(): # the client knows to submit only once with a specific voter_id voter_constraints_include = None voter_constraints_exclude = None update_booth_invitation_date = False if template == 'vote': update_booth_invitation_date = True if voter: voter_constraints_include = {'uuid': voter.uuid} # exclude those who have not voted if email_form.cleaned_data['send_to'] == 'voted': voter_constraints_exclude = {'vote_hash' : None} # include only those who have not voted if email_form.cleaned_data['send_to'] == 'not-voted': voter_constraints_include = {'vote_hash': None} for _poll in polls: if not _poll.feature_can_send_voter_mail: continue if template == 'vote' and not \ _poll.feature_can_send_voter_booth_invitation: continue subject_template = 'email/%s_subject.txt' % template body_template = 'email/%s_body.txt' % template extra_vars = { 'custom_subject' : email_form.cleaned_data['subject'], 'custom_message' : email_form.cleaned_data['body'], 'election_url' : election_url, } task_kwargs = { 'subject_template': subject_template, 'body_template': body_template, 'extra_vars': extra_vars, 'voter_constraints_include': voter_constraints_include, 'voter_constraints_exclude': voter_constraints_exclude, 'update_date': True, 'update_booth_invitation_date': update_booth_invitation_date, 'q_param': q_param, } log_obj = election if poll: log_obj = poll if voter: log_obj.logger.info("Notifying single voter %s, [template: %s, filter: %s]", voter.voter_login_id, template, q_param) else: log_obj.logger.info("Notifying voters, [template: %s, filter: %r]", template, q_param) tasks.voters_email.delay(_poll.pk, **task_kwargs) filters = get_voters_filters_with_constraints(q_param, voter_constraints_include, voter_constraints_exclude) send_to = filtered_voters.filter(filters) if q_param and not send_to.filter(filters).count(): msg = "No voters matched your filters. No emails were sent." messages.error(request, _(msg)) else: messages.info(request, _("Email sending started")) url = election_reverse(election, 'polls_list') if poll: url = poll_reverse(poll, 'voters') if q_param: url += '?q=%s' % urllib.quote_plus(q_param) return HttpResponseRedirect(url) context = { 'email_form': email_form, 'election': election, 'poll': poll, 'voter_o': voter, 'default_subject': default_subject, 'default_body': default_body, 'template': template, 'filtered_voters': filtered_voters, 'templates': TEMPLATES } set_menu('voters', context) if not poll: set_menu('polls', context) return render_template(request, "voters_email", context)