def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if self.has_changed(): if hasattr(self, "changed_by_user") and getattr( self, "changed_by_user", None): self.edited_by = self.changed_by_user self.edited_ts = django_now() if self.created_by is None: self.created_by = self.changed_by_user last_version = self.versions.order_by( "-version_number").first() version_number = 1 if last_version is not None: version_number = last_version.version_number + 1 new_version = Version.objects.create( version_number=version_number, edited_by=self.changed_by_user, edited_ts=django_now()) for field in self.versioned_fields: orig = '__original_%s' % field old_value = getattr(self, orig, None) new_value = getattr(self, field, None) if old_value != new_value: VersionChange.objects.create( version=new_version, fieldname=field, old_value=str(old_value)[:4000], new_value=str(new_value)[:4000]) super(VersionedModel, self).save()
def set_config(key, value): conf = Config.objects.filter(key=key) if conf.count() == 0: Config.objects.create(key=key, value=dumps(value), last_access=django_now()) else: conf = conf[0] if not value is None: conf.value = dumps(value) conf.last_access = django_now() conf.save() else: conf.delete()
def test_finalize_uploaded_assignment( self, finalized_setting, model_change_expected, upload_allowed, get_student_item_dict ): """ Tests that finalize_uploaded_assignment sets a submission to be finalized """ block = self.make_xblock() get_student_item_dict.return_value = { "student_id": 1, "course_id": block.block_course_id, "item_id": block.block_id, "item_type": 'sga', } upload_allowed.return_value = True existing_submitted_at_value = django_now() fake_submission_data = fake_get_submission(**finalized_setting) fake_submission_object = mock.Mock( submitted_at=existing_submitted_at_value, answer=fake_submission_data['answer'] ) with mock.patch( 'edx_sga.sga.Submission.objects.get', return_value=fake_submission_object ), mock.patch( 'edx_sga.sga.StaffGradedAssignmentXBlock.get_submission', return_value=fake_submission_data ), mock.patch( 'edx_sga.sga.StaffGradedAssignmentXBlock.student_state', return_value={} ): block.finalize_uploaded_assignment(mock.Mock()) assert fake_submission_object.answer['finalized'] is True assert (existing_submitted_at_value != fake_submission_object.submitted_at) is model_change_expected assert fake_submission_object.save.called is model_change_expected
def _assertVisionSyncLogFundamentals(self, total_records, total_processed, details='', exception_message='', successful=True): '''Assert common properties of the VisionSyncLog record that should have been created during a test. Populate the method parameters with what you expect to see in the VisionSyncLog record. ''' sync_logs = VisionSyncLog.objects.all() self.assertEqual(len(sync_logs), 1) sync_log = sync_logs[0] self.assertEqual(sync_log.country.pk, self.test_country.pk) self.assertEqual(sync_log.handler_name, '_MySynchronizer') self.assertEqual(sync_log.total_records, total_records) self.assertEqual(sync_log.total_processed, total_processed) self.assertEqual(sync_log.successful, successful) if details: self.assertEqual(sync_log.details, details) else: self.assertIn(sync_log.details, ('', None)) if exception_message: self.assertEqual(sync_log.exception_message, exception_message) else: self.assertIn(sync_log.exception_message, ('', None)) # date_processed is a datetime; there's no way to know the exact microsecond it should contain. As long as # it's within a few seconds of now, that's good enough. delta = django_now() - sync_log.date_processed self.assertLess(delta.seconds, 5)
def get_elections_with_polling_reports_enabled(self, as_of=None): """ The polling reporting period is from the time polling starts until 16 hours after polling ends, for in person elections only. """ as_of = as_of or django_now() return self.filter(polling_start_time__lte=as_of, work_end_time__gt=as_of)
def get_previous_election(self, as_of=None): """ Return the most recently completed election, or None. """ as_of = as_of or django_now() return (self.filter( polling_end_time__lte=as_of).order_by('-polling_end_time').first())
def get_next_election(self, as_of=None): """ Return the nearest election that's not over, or None. """ as_of = as_of or django_now() return (self.filter( polling_end_time__gt=as_of).order_by('polling_end_time').first())
def timestamp_first_triage(self): # use only on code triggered by # human interaction if self.first_triaged is None: self.first_triaged = django_now() self.summary.timestamp_first_triage().save() return self
def test_enforce_membership_should_execute_and_return_view(self, now): # setup view = mock.Mock(return_value=mock.MagicMock()) wrapped_view = enforce_membership(view) now.return_value = django_now() end_date = datetime.datetime(year=now().year + 1, month=now().month, day=now().day, hour=now().hour, minute=now().minute, second=now().second, microsecond=now().microsecond, tzinfo=utc) request = mock.Mock() request.user.membership.end_date = end_date # action returned_value = wrapped_view(request, *self.args, **self.kwargs) # assert self.assertTupleEqual(( (request, ) + self.args, self.kwargs, ), view.call_args) self.assertEqual(id(view.return_value), id(returned_value)) self.assertTupleEqual(( 'CURRENT', True, ), returned_value.__setitem__.call_args[0])
def _execute_transition(*, transition, user, object_id, object_state_id, automatic=False, last_transition=None, recursion_count=0): if recursion_count > 10: raise RecursionError("too many chained automatic transitions") if transition.is_available(user=user, object_id=object_id, object_state_id=object_state_id, automatic=automatic, last_transition=last_transition): # #print("transition {} available on {}".format(transition, object_id)) # first execute all sync callbacks within then update the log and state tables all within a transaction object_state = _atomic_execution(object_id, object_state_id, transition, user) # now trigger all async callbacks for c in transition.callback_set.filter(execute_async=True): params = {p.name: p.value for p in c.callback_parameter_set.all()} thr = threading.Thread(target=c.function, args=(transition.initial_state.workflow, user, object_id), kwargs=params) thr.start() # finally look for the first automatic transaction that applies and start it if any _execute_atomatic_transitions(transition.final_state, object_id, object_state_id, last_transition=django_now()) return object_state
def get_job_name(username): """Given a username (e.g. 'mtwain'), returns a guaranteed unique directory name""" # Autogenerate a directory name that includes a timestamp and the name of the current # user. The timestamp is microsecond-granular which guarantees directory name # uniqueness even if the user is 'unknown'. For example -- # 2014-05-19.15-44-36-401151-mtwain return '{}-{}'.format(django_now().strftime('%Y-%m-%d.%H-%M-%S-%f'), username)
def test_sum_saved_hours(self): u'''sum_saved_hoursの確認''' user_profile = self._create_user_profile() now = django_now() def _create_lock(before, saved_hours): return Lock.objects.create( user_profile=user_profile, locked_file_name='dummy', original_file_name='dummy', original_file_size=1, password='******', locked_at=before, unlockable_at=before + datetime.timedelta(days=1), saved_hours=saved_hours ) # 行無し self.assertEqual(Lock.objects.sum_saved_hours(), 0) # 1日間未満のものを追加 before = now - datetime.timedelta(days=1, seconds=-1) _create_lock(before, 1) _create_lock(before, 2) self.assertEqual(Lock.objects.sum_saved_hours(), 3) self.assertEqual(Lock.objects.sum_saved_hours(period=1), 3) # 加えて、2日間のものを追加 before = now - datetime.timedelta(days=2) _create_lock(before, 3) self.assertEqual(Lock.objects.sum_saved_hours(), 6) self.assertEqual(Lock.objects.sum_saved_hours(period=1), 3) # 二日前のものは含まれない
def enter_grade(self, request, suffix=''): # pylint: disable=unused-argument """ Persist a score for a student given by staff. """ require(self.is_course_staff()) score = request.params.get('grade', None) module = self.get_student_module(request.params['module_id']) state = json.loads(module.state) try: score = int(score) except: score = 0 if self.is_instructor(): uuid = request.params['submission_id'] submissions_api.set_score(uuid, score, self.max_score()) else: state['staff_score'] = score state['comment'] = request.params.get('comment', '') state['fresh'] = False state['date_fin'] = force_text(django_now()) module.state = json.dumps(state) module.save() log.info("enter_grade for course:%s module:%s student:%s", module.course_id, module.module_state_key, module.student.username) return Response(json_body=self.staff_grading_data())
def show_upcoming_events(count, centre_code, display_all): if count is not None: count = min(max(1, int(count)), 10) now = django_now() try: centre = Centre.objects.get(code=centre_code) title = 'Kommende aktiviteter på {}'.format(centre.title) events = centre.events.filter(end__gte=now).order_by('start') except Centre.DoesNotExist: centre = None title = 'Kommende aktiviteter' events = Event.objects.filter(end__gte=now).order_by('start') grouped = OrderedDict() for event in events: key = event.start.strftime('%B') try: grouped[key].append(event) except KeyError: grouped[key] = [] grouped[key].append(event) return { 'events': events[:count], 'count': len(events), 'title': title, 'full': grouped, 'display_all': display_all }
def create_by_user(self, user, uploaded_file, period, saved_hours): locked_at = django_now() unlockable_at = locked_at + datetime.timedelta(days=period) max_saved_hours = period * 24 if saved_hours > max_saved_hours: saved_hours = max_saved_hours password = get_random_string(8, allowed_chars='0123456789') fl = FileLocker() fl.lock(uploaded_file, password) locked_file = File( open(fl.get_locked_file_path(), 'r'), name=fl.get_locked_file_name() ) obj = self.create( user_profile=user.get_profile(), locked_file=locked_file, locked_file_name=fl.get_locked_file_name(), original_file_name=uploaded_file.name, original_file_size=uploaded_file.size, password=password, locked_at=locked_at, unlockable_at=unlockable_at, saved_hours=saved_hours ) locked_file.close() fl.clean() return obj
def ttt_get(request): if 'secret' not in request.GET: return json_failure('You must supply a secret.') clean_secret = request.GET['secret'].replace(' ','') try: secret = Secret.objects.filter(secret__exact=clean_secret).get() except Secret.DoesNotExist: return json_failure('Invalid secret.') user = secret.user num_points = int(request.GET.get('n', DEFAULT_NUM_POINTS)) lq = Location.objects.filter(user__exact=user) if 'last' in request.GET: lq = lq.filter(id__gt=request.GET['last']) if 'oldness' in request.GET: oldness = int(request.GET['oldness']) if oldness > 0 and oldness <= 2592000: lq = lq.filter(date__gt= django_now() - datetime.timedelta(0, oldness, 0) ) locations = lq.order_by('-date')[:num_points] location_dicts = [{ 'latitude': l.latitude, 'longitude': l.longitude, 'accuracy': l.accuracy, 'speed': l.speed, 'date': str(l.date), 'id': l.id, } for l in locations] return json_success('Succcess!', data={'locations': location_dicts})
def _atomic_execution(object_id, object_state_id, transition, user): # we first change status for consistency, exceptions in callbacks could break the process # #print("executing transition {} on object id {}".format(transition.name, object_id)) object_state = None if transition.initial_state is not None: if object_state_id: object_state = CurrentObjectState.objects.get( id=object_state_id, state__workflow=transition.workflow) else: object_state = CurrentObjectState.objects.filter( object_id=object_id, state__workflow=transition.workflow).order_by('-id').first() if object_state: object_state.updated_ts = django_now() object_state.state = transition.final_state object_state.save() else: object_state = CurrentObjectState.objects.create( object_id=object_id, state=transition.final_state) for c in transition.callback_set.filter(execute_async=False): # #print("executing {}.{}".format(c.function_module, c.function_name)) params = {p.name: p.value for p in c.parameters.all()} print("test") c.function(workflow=transition.final_state.workflow, user=user, object_id=object_id, object_state=object_state, **params) TransitionLog.objects.create(workflow=object_state.workflow, current_object_state=object_state, user_id=user.id if user else None, transition=transition, success=True) return object_state
def test_is_unlockable(self): u'''Lock.is_unlocableが正しいか タイムゾーン処理が慣れていないので特にテスト ''' user_profile = self._create_user_profile() now = django_now() after = now + datetime.timedelta(seconds=1) lock_obj = Lock.objects.create( user_profile=user_profile, locked_file_name='dummy', original_file_name='dummy', original_file_size=1, password='******', locked_at=now, unlockable_at=after, saved_hours=1 ) # 解除可能日時が現在時刻以上 self.assertFalse(lock_obj.is_unlockable()) # 解除可能日時が現在時刻未満 pre = now - datetime.timedelta(seconds=1) lock_obj.unlockable_at = pre lock_obj.save() self.assertTrue(lock_obj.is_unlockable())
def get_election_in_progress(self, as_of=None): """ If there's an election with polling allowed right now, return the Election object. Else return None. """ as_of = as_of or django_now() return self.filter(polling_start_time__lte=as_of, polling_end_time__gt=as_of).first()
def get_elections_with_phone_activation_enabled(self, as_of=None): """ People can activate phones to centers between midnight, two days before polling starts, and the end of polling, for in-person elections only. """ as_of = as_of or django_now() return self.filter(work_start_time__lte=as_of, polling_end_time__gt=as_of)
def now_plus_delta(**kwargs): """ Returns an aware or naive datetime.datetime, depending on settings.USE_TZ with delta. """ now = django_now() if kwargs: return now + timedelta(**kwargs) return now
def _locked_file_upload_to(instance, filename): now = django_now() return '%s/%04d/%02d/%s/%s' % ( settings.LOCKED_FILES_DIR_NAME, now.year, now.month, get_random_string(32), filename, )
def get_current_election(self, as_of=None): """Returns the election currently in progress (somewhere between the first and last things that are scheduled for it), or None if there is no such election. """ as_of = as_of or django_now() return self.filter( start_time__lte=as_of, end_time__gt=as_of, ).order_by('start_time').first()
def get_elections_with_polling_reports_enabled(self, as_of=None): """ The polling reporting period is from the time polling starts until 16 hours after polling ends, for in person elections only. """ as_of = as_of or django_now() return self.filter( polling_start_time__lte=as_of, work_end_time__gt=as_of, )
def sum_saved_hours(self, period=None): u'''period is number of days from now to the past for including aggregation''' qs = self.all() if period is not None: now = django_now() in_period = now - datetime.timedelta(days=period) qs = qs.filter(locked_at__gt=in_period) result = qs.aggregate(models.Sum('saved_hours')) return result['saved_hours__sum'] or 0
def put_data_in_es(index_name, file_path, read_chunk_size, parallel_jobs_count, index_chunk_size, delimeter): current_file = UploadedFiles.objects.get(pk=index_name) time_creation = time.time() wait_time = 4 es = Elasticsearch() columns = { 'col_' + str(item): { "type": "string", "index": "not_analyzed" } for item in range(current_file.upload_into_es_cols_count) } columns['row_num'] = {"type": "long"} mapping = { 'properties': { 'col_' + str(item): { 'type': 'string', 'index': 'not_analyzed' } for item in range(current_file.upload_into_es_cols_count) } } mapping['properties']['row_num'] = {'type': 'long'} es.indices.create(index=index_name) es.indices.put_mapping(index=index_name, doc_type=index_name, body=mapping) t0 = time.time() while not es.indices.exists_type( index=index_name, doc_type=index_name) and time.time() - t0 < wait_time: time.sleep(0.01) pass time_indexing = time.time() upload_file_into_es(file_path=file_path, index_name=index_name, read_chunk_size=read_chunk_size, parallel_jobs_count=parallel_jobs_count, index_chunk_size=index_chunk_size, delimeter=delimeter) stop_time = time.time() current_file.upload_into_es_settings_rcs = read_chunk_size current_file.upload_into_es_settings_pp = parallel_jobs_count current_file.upload_into_es_settings_ics = index_chunk_size current_file.upload_into_es_ttm = stop_time - time_creation current_file.upload_into_es_itm = stop_time - time_indexing current_file.upload_into_es_indexing_done = django_now() current_file.save()
def get_election_in_progress(self, as_of=None): """ If there's an election with polling allowed right now, return the Election object. Else return None. """ as_of = as_of or django_now() return self.filter( polling_start_time__lte=as_of, polling_end_time__gt=as_of, ).first()
def get_elections_with_phone_activation_enabled(self, as_of=None): """ People can activate phones to centers between midnight, two days before polling starts, and the end of polling, for in-person elections only. """ as_of = as_of or django_now() return self.filter( work_start_time__lte=as_of, polling_end_time__gt=as_of, )
def polling_csv_view(request): """Deliver the polling CSV file for the current election""" csv = generate_polling_metadata_csv() client_filename = 'metadata_polling_{}.csv'.format(django_now().strftime('%Y_%m_%d')) # Proper MIME type is text/csv. ref: http://tools.ietf.org/html/rfc4180 response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="{}"'.format(client_filename) response.write(csv) return response
def test_age_with_time_zones(self): """Haystack should use django.utils.timezone.now on Django 1.4+""" from django.utils.timezone import now as django_now from haystack.management.commands.update_index import now as haystack_now self.assertIs(haystack_now, django_now, msg="update_index should use django.utils.timezone.now") with patch("haystack.management.commands.update_index.now") as m: m.return_value = django_now() self.test_age() assert m.called
def test_is_outdated_is_synced_with_related_summary( self, test_perf_alert_summary): backfill_record = BackfillReport.objects.create( summary=test_perf_alert_summary) assert backfill_record.is_outdated is False # now change summary, so it's more recent that its report test_perf_alert_summary.last_updated = django_now() test_perf_alert_summary.save() assert backfill_record.is_outdated is True
def test_age_with_time_zones(self): """Haystack should use django.utils.timezone.now""" from django.utils.timezone import now as django_now from haystack.management.commands.update_index import now as haystack_now self.assertIs(haystack_now, django_now, msg="update_index should use django.utils.timezone.now") with patch("haystack.management.commands.update_index.now") as m: m.return_value = django_now() self.test_age() assert m.called
def get_device_status(request, slug): try: dev = DeviceEntry.objects.get(slug=slug) except DeviceEntry.DoesNotExist: res = None else: res = utils.exec_upri_config("check_device", dev.ip) if bool(res): # update last_seen date dev.last_seen = django_now() dev.save() return JsonResponse({slug: bool(res)})
def test_serve_metadata_csv(self): """Generate an view for the metadata CSV and test the response, including headers""" response = self.client.get(reverse('rollgen:polling_csv')) expected_filename = 'metadata_polling_{}.csv'.format(django_now().strftime('%Y_%m_%d')) self.assertResponseOK(response) self.assertEqual('text/csv', response['Content-Type']) self.assertEqual('attachment; filename="{}"'.format(expected_filename), response['Content-Disposition']) self.assertEqual('Centre #,', response.content[:9]) self.assertGreaterEqual(500, len(response.content)) self.assertLessEqual(100, len(response.content))
def polling_csv_view(request): """Deliver the polling CSV file for the current election""" csv = generate_polling_metadata_csv() client_filename = 'metadata_polling_{}.csv'.format( django_now().strftime('%Y_%m_%d')) # Proper MIME type is text/csv. ref: http://tools.ietf.org/html/rfc4180 response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="{}"'.format( client_filename) response.write(csv) return response
def test_serve_metadata_csv(self): """Generate an view for the metadata CSV and test the response, including headers""" response = self.client.get(reverse('rollgen:polling_csv')) expected_filename = 'metadata_polling_{}.csv'.format( django_now().strftime('%Y_%m_%d')) self.assertResponseOK(response) self.assertEqual('text/csv', response['Content-Type']) self.assertEqual('attachment; filename="{}"'.format(expected_filename), response['Content-Disposition']) self.assertEqual('Centre #,', response.content[:9]) self.assertGreaterEqual(500, len(response.content)) self.assertLessEqual(100, len(response.content))
def show_event_instances(count, event_page): if count is not None: count = min(max(1, int(count)), 10) now = django_now() events = event_page.event_instances.filter( end__gte=now ).order_by('start')[:count] return { 'events': events, 'centre': event_page.calendar.centre, 'title': 'Kommende aktiviteter' }
def finalize_uploaded_assignment(self, request, suffix=''): # pylint: disable=unused-argument """ Finalize a student's uploaded submission. This prevents further uploads for the given block, and makes the submission available to instructors for grading """ submission_data = self.get_submission() require(self.upload_allowed(submission_data=submission_data)) # Editing the Submission record directly since the API doesn't support it submission = Submission.objects.get(uuid=submission_data['uuid']) if not submission.answer.get('finalized'): submission.answer['finalized'] = True submission.submitted_at = django_now() submission.save() return Response(json_body=self.student_state())
def comment_page(request, page_id): page = get_object_or_404(Page, id=page_id) if request.method == 'POST': content = request.POST.getlist('content') try: comment = PageComment(user=request.user, content=content) except Exception, e: LOG.exception(e) messages.error(request, _(u'输入错误,请重新输入')) else: for c in comments: c.save() order.comment_time = django_now() order.save() messages.success(request, _(u'评论完成,已经添加到产品详细页面中。')) return redirect('/order/%s/' % order_id)
def post(self, request, **kwargs): file_name = 'tds-' + str(datetime.now()).replace(' ', '-').replace( ':', '-').replace('.', '-') context = super(main, self).get_context_data(**kwargs) if 'submit-upload-files' in request.POST and request.FILES[ 'file'].name.split('.')[-1] == 'csv': delimeter = '\t' form = DocumentForm(request.POST, request.FILES) absolut_file_path, num_rows, num_cols = uploaded_file( request.FILES['file'], new_file_name=file_name, delimeter=delimeter) context['form'] = form context['res_list'] = self.res_list context['file_type'] = self.file_type context['file_size'] = request.POST['file_size'] user_file = UploadedFiles( unique_file_name=file_name, absolut_file_path=absolut_file_path, original_file_name=request.FILES['file'].name, upload_into_es_file_size=request.POST['file_size'], upload_into_es_rows_count=num_rows, upload_into_es_cols_count=num_cols, file_upload_date_time=django_now()) user_file.save() put_file_into_es = tasks.put_data_in_es.delay( index_name=file_name, file_path=absolut_file_path, read_chunk_size=50000, parallel_jobs_count=12, index_chunk_size=50000, delimeter=delimeter) self.json_response['task_id'] = put_file_into_es.task_id self.json_response['index_name'] = file_name user_file.upload_into_es_task_id = put_file_into_es.task_id user_file.save() elif 'submit-upload-files' in request.POST and request.FILES[ 'file'].name.split('.')[-1] != 'csv': self.file_type = False context['file_type'] = self.file_type return JsonResponse(self.json_response)
def _is_transition_available(transition, user, object_id, object_state_id=None, automatic=False, last_transition=None): # #print("checking if {} available on obj id {}".format(transition.name, object_id)) if transition.is_initial: return transition.workflow.is_initial_transition_available( user=user, object_id=object_id, object_state_id=object_state_id, automatic=automatic) object_state = None if object_state_id is not None: object_state = CurrentObjectState.objects.get(id=object_state_id) else: q = CurrentObjectState.objects.filter(object_id=object_id, workflow=transition.workflow) if q.exists(): object_state = q.first() if object_state is not None: if last_transition is None: last_transition = object_state.updated_ts if automatic != transition.automatic: # print("not executing because of automatic setting") return False if automatic \ and transition.automatic_delay is not None \ and last_transition is not None \ and django_now() - last_transition < timedelta(days=transition.automatic_delay): # print("not executing because of delay") return False root_condition = transition.condition_set.filter( parent_condition__isnull=True) condition_checks = True if root_condition.exists(): condition_checks = root_condition.first().check_condition( user=user, object_id=object_id, object_state=object_state, transition=transition) # print("condition_checks: {}".format(condition_checks)) return condition_checks else: return False
def full_event_overview(event_page): overview = OrderedDict() now = django_now() events = event_page.event_instances.filter(end__gte=now).order_by('start') if events.count() <= 3: return {} for event in events: month = event.start.strftime('%B') try: overview[month].append(event) except KeyError: overview[month] = [event] return {'result': overview}
def test_enforce_membership_should_redirect_to_membership_home_when_users_membership_plan_has_expired( self, now, redirect): # setup view = mock.Mock() wrapped_view = enforce_membership(view) now.return_value = django_now() end_date = datetime.datetime(year=now().year - 3, month=now().month, day=now().day, hour=now().hour, minute=now().minute, second=now().second, microsecond=now().microsecond, tzinfo=utc) request = mock.Mock() request.user.membership.end_date = end_date # action returned_value = wrapped_view(request) # assert self.assertTupleEqual(('membership:home',), redirect.call_args[0]) self.assertEqual(0, view.call_count) self.assertEqual(id(redirect.return_value), id(returned_value))
def test_enforce_membership_should_execute_and_return_view(self, now): # setup view = mock.Mock(return_value=mock.MagicMock()) wrapped_view = enforce_membership(view) now.return_value = django_now() end_date = datetime.datetime(year=now().year + 1, month=now().month, day=now().day, hour=now().hour, minute=now().minute, second=now().second, microsecond=now().microsecond, tzinfo=utc) request = mock.Mock() request.user.membership.end_date = end_date # action returned_value = wrapped_view(request, *self.args, **self.kwargs) # assert self.assertTupleEqual(((request,) + self.args, self.kwargs,), view.call_args) self.assertEqual(id(view.return_value), id(returned_value)) self.assertTupleEqual(('CURRENT', True,), returned_value.__setitem__.call_args[0])
def setUp(self): super(TestPollingCSVs, self).setUp() # Jam a comma in one of the fields that appears in the CSV to exercise the code's # ability to escape the delimiter correctly. self.center.name = ',' + self.center.name self.center.save() job = Job('polling', [self.center], self.input_arguments, self.user.username, self.output_path) job.generate_rolls() # Create a station related to an older election in a (hopefully unsuccessful) attempt to # confuse the code that creates the polling metadata CSV. start = django_now() start = start.replace(year=start.year - 1) end = start.replace(year=start.year - 1) + datetime.timedelta(days=1) old_election = ElectionFactory(polling_start_time=start, polling_end_time=end) old_center = RegistrationCenterFactory() Station(election=old_election, center=old_center, number=1, gender=FEMALE, n_registrants=42, first_voter_name='first', first_voter_number=1, last_voter_name='last', last_voter_number=42)
def smartdate(value): if isinstance(value, datetime.datetime): now = django_now() else: now = datetime.date.today() timedelta = value - now format = _(u"%(delta)s %(unit)s") delta = abs(timedelta.days) if delta > 30: delta = int(delta / 30) unit = _(u"mois") else: unit = _(u"jours") ctx = { 'delta': delta, 'unit': unit, } return format % ctx
def is_unlockable(self): return django_now() > self.unlockable_at
def generate_rolls(self): """Build PDFs for this job. This is where all the action happens. May raise NoVotersError, NoOfficeError and OutOfDiskSpaceError. """ self.begin = django_now() if not self.input_arguments['forgive_no_office']: # We are not going to be forgiving if we find any office-less centers. has_office = lambda center: center.office.id != NO_NAMEDTHING problem_centers = [center.center_id for center in self.centers if not has_office(center)] if problem_centers: msg = "The following centers have no associated office: {}." raise NoOfficeError(msg.format(problem_centers)) if not self.input_arguments['forgive_no_voters']: # Test each center to make sure it has at least one registration. This is a lot of # DB churn and can take a while. It has to be done in two parts. # Find non-copy centers with no registrations problem_center_ids = \ RegistrationCenter.objects.filter(id__in=[center.id for center in self.centers], registration__isnull=True, copy_of_id__isnull=True).values_list('id', flat=True) problem_centers = [center for center in self.centers if center.id in problem_center_ids] # Find copy centers with no registrations. This runs one query per center which is # the expensive way to do it, but it's the only way to figure out exactly which copy # centers (if any) have parents with no registrations without dropping to raw SQL. for center in self.centers: copied = center.copy_of if copied: if not Registration.objects.filter(registration_center=copied).exists(): problem_centers.append(center) if problem_centers: problem_centers = [center.center_id for center in problem_centers] msg = "The following centers have no registrants: {}." raise NoVotersError(msg.format(problem_centers)) for i_center, center in enumerate(self.centers): # Fetch the voters for this center from the DB. voter_roll = get_voter_roll(center) office_id = center.office.id if office_id not in self.offices: self.offices[office_id] = center.office out_path = os.path.join(self.output_path, str(office_id)) if not os.path.exists(out_path): with out_of_disk_space_handler_context(): os.makedirs(out_path) filename_params = {'center_id': center.center_id, } # Generate different PDFs based on phase if self.phase == 'in-person': # election center books only for gender in (FEMALE, MALE): filename_params['gender'] = GENDER_ABBRS[gender] filename = self.get_filename(out_path, filename_params) n_pages = generate_pdf(filename, center, voter_roll, gender, center_book=True) self.add(filename, n_pages) elif self.phase == 'exhibitions': # election center list only for gender in (FEMALE, MALE): filename_params['gender'] = GENDER_ABBRS[gender] filename = self.get_filename(out_path, filename_params) n_pages = generate_pdf(filename, center, voter_roll, gender) self.add(filename, n_pages) elif self.phase == 'polling': # distribute registrations into stations for this center stations = station_distributor(voter_roll) # Stash the list of which voters registered at this center/station for later. election = Election.objects.get_most_current_election() if not election: raise NoElectionError('There is no current in-person election.') for station in stations: station.election = election station.center = center for voter in station.roll: voter_station = VoterStation(national_id=voter.national_id, center_id=center.center_id, station_number=station.number) self.voter_stations.append(voter_station) # count stations by gender for center list station_counts_by_gender = Counter(station.gender for station in stations) for gender in station_counts_by_gender: filename_params['gender'] = GENDER_ABBRS[gender] filename = self.get_filename(out_path, filename_params, 'list') n_pages = generate_pdf_center_list(filename, stations, gender) self.add(filename, n_pages) logger.info('center list {}'.format(filename)) # Create a separate book and sign for each station for station in stations: filename_params['station_number'] = station.number # polling station books filename = self.get_filename(out_path, filename_params, 'book') n_pages = generate_pdf_station_book(filename, station) self.add(filename, n_pages) logger.info('station book {}'.format(filename)) # polling station sign filename = self.get_filename(out_path, filename_params, 'sign') n_pages = generate_pdf_station_sign(filename, station) self.add(filename, n_pages) logger.info('station book {}'.format(filename)) with transaction.atomic(): # Delete any existing Stations for this center and replace them with new. Station.objects.filter(election=election, center=center).delete() for station in stations: station.save() # Emit status logger.info('saved PDFs for center %s' % center.center_id) params = (i_center + 1, len(self.centers), (i_center + 1) / len(self.centers)) logger.info("Completed {} of {} (~{:.2%})".format(*params)) self.end = django_now() # Now that rolls are generated, write voter station CSVs (if appropriate) and job JSON # metadata. Last but not least, zip output. if self.voter_stations: # Write voter station data twice to CSV files. First sorted by national id and again # sorted by (center id, station number). header = [('national_id', 'center_id', 'station_number')] # sort by national id self.voter_stations.sort() filename = os.path.join(self.output_path, 'voters_by_national_id.csv') with out_of_disk_space_handler_context(): csv_writer = UnicodeWriter(open(filename, 'w')) csv_writer.writerows(header) csv_writer.writerows(self.voter_stations) # sort by center, station number self.voter_stations.sort(key=lambda voter_station: voter_station[1:]) filename = os.path.join(self.output_path, 'voters_by_center_and_station.csv') with out_of_disk_space_handler_context(): csv_writer = UnicodeWriter(open(filename, 'w')) csv_writer.writerows(header) csv_writer.writerows(self.voter_stations) # Write the JSON metadata file metadata_filename = os.path.join(self.output_path, METADATA_FILENAME) with out_of_disk_space_handler_context(): with open(metadata_filename, 'w') as f: json.dump(self.metadata, f, indent=2) # Write a hash of the metadata file sha = hashlib.sha256(open(metadata_filename).read()).hexdigest() with out_of_disk_space_handler_context(): open(metadata_filename + '.sha256', 'w').write(sha) logger.info('zipping output') for office_id in sorted(self.offices.keys()): office_dir = os.path.join(self.output_path, str(office_id)) with out_of_disk_space_handler_context(): zip_filename = office_dir + '.zip' with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as office_zip: logger.info('zipping %s' % office_dir) for office_base, dirs, files in os.walk(office_dir): for pdf in files: fn = os.path.join(office_base, pdf) office_zip.write(fn, pdf) logger.info('done')
def reg_is_open(self): return django_now() < self.reg_close
def timestamp_first_triage(self): # called for summary specific updates (e.g. notes, bug linking) if self.first_triaged is None: self.first_triaged = django_now() return self
def get_previous_election(self, as_of=None): """ Return the most recently completed election, or None. """ as_of = as_of or django_now() return self.filter(polling_end_time__lte=as_of).order_by("-polling_end_time").first()
def now(fmt=None): return helpers.datetime(django_now(), fmt)
def get_next_election(self, as_of=None): """ Return the nearest election that's not over, or None. """ as_of = as_of or django_now() return self.filter(polling_end_time__gt=as_of).order_by("polling_end_time").first()
def unlock_locked_file(self): self.unlocked_at = django_now() self.save()
def get_age(self): """ 通过身份证号获取年龄 """ if isinstance(self.get_birthday(), datetime): age = django_now().year - self.get_birthday().year return age