def fmt_timesince(d): """ Formatter for time since. :param d: :return: str """ now = timezone.now() diff = now - d secs = diff.total_seconds() if secs < 60: return 'moments ago' elif secs >= 60 and secs < 3600: mins = math.floor(secs / 60) return '{} minute{} ago'.format(mins, '' if mins == 1 else 's') elif secs >= 3600 and secs < 3600 * 3: hours = math.floor(secs / 3600) return '{} hour{} ago'.format(hours, '' if hours == 1 else 's') elif now.date() == d.date(): return 'Today, {}'.format(filter_date(d, 'H:i')) elif now.date() - relativedelta(days=1) == d.date(): return 'Yesterday, {}'.format(filter_date(d, 'H:i')) else: return filter_date(d, 'N j, Y H:i')
def last_seen(value, autoescape=None): """Formats a datetime as an HTML string representing a short digest of the time since that date, contained by a <span>, with a title (tooltip) of the full date.""" # if autoescaping is on, then we will # need to pass outgoing strings through # cond_esc, or django will escape the HTML if autoescape: esc = conditional_escape else: esc = lambda x: x try: if value: # looks like we have a valid date - return # a span containing the long and short version ts = timesince(value) mag = magnitude_ago(value) long = "on %s at %s" % (filter_date(value), filter_time(value)) out = '<span class="last-seen %s" title="%s">%s ago</span>' % (esc(mag), esc(long), esc(ts)) # abort if there is no date (it's # probably just a null model field) else: out = '<span class="last-seen n/a">Never</span>' # something went wrong! don't blow up # the entire template, just flag it except (ValueError, TypeError): out = '<span class="last-seen error">Error</span>' return mark_safe(out)
def expiry(export): if export.isoneoff: return 'One off' elif export.expiration: return filter_date(export.expiration, 'd F, Y H:i') else: return 'Never'
def ajax_users(request): """ User list ajax. """ #TODO make less db queries. #TODO stats sortable too. search = request.GET.get("search") sort = request.GET.get("sort", "id") order_type = request.GET.get("order", "desc") limit = request.GET.get("limit") offset = request.GET.get("offset") page = (int(offset) / int(limit)) + 1 users = User.objects.filter(is_active=True) users_count = users.count() if search: users = users.filter(username=search) if order_type == 'asc': users = users.order_by(sort) else: users = users.order_by('-' + sort) paginator = Paginator(users, limit) try: users = paginator.page(page) except PageNotAnInteger: users = paginator.page(1) except EmptyPage: users = paginator.page(paginator.num_pages) rows = [ { "id": user.id, "username": user.username, "firstname": user.first_name, "lastname": user.last_name, "email": user.email, "profiles": FacebookProfileUrl.objects.filter(user=user, is_deleted=False).count(), "sent": Stats.objects.filter(user=user)[0].total_messages, "created_on": filter_date(user.date_joined, "d/m/Y") } for user in users ] data = { "total": users_count, "rows": rows } return JsonResponse(data)
def test_expiry(self): export = Export(isoneoff=True) self.assertEqual(export_tags.expiry(export), 'One off') export = Export(expiration=datetime.now()) self.assertEqual( export_tags.expiry(export), filter_date(export.expiration, 'd F, Y H:i') ) export = Export(isoneoff=False) self.assertEqual(export_tags.expiry(export), 'Never')
def ajax_collector_history(request): """ Ajax view for collectiong history. """ search = request.GET.get("search") sort = request.GET.get("sort", "id") order_type = request.GET.get("order", "desc") limit = request.GET.get("limit") offset = request.GET.get("offset") page = (int(offset) / int(limit)) + 1 collector = CollectProgress.objects.filter(user=request.user) collector_count = collector.count() if search: collector = collector.filter(Q(name__icontains=search) | Q(url__icontains=search)) if order_type == 'asc': collector = collector.order_by(sort) else: collector = collector.order_by('-' + sort) paginator = Paginator(collector, limit) try: collector = paginator.page(page) except PageNotAnInteger: collector = paginator.page(1) except EmptyPage: collector = paginator.page(paginator.num_pages) rows = [ { "id": collected.id, "name": collected.name, "url": collected.url, "collected": collected.collected, "done": collected.done, "created_on": filter_date(collected.created_on, "d/m/Y") } for collected in collector ] data = { "total": collector_count, "rows": rows } return JsonResponse(data)
def ajax_profile(request): search = request.GET.get("search") sort = request.GET.get("sort", "id") order_type = request.GET.get("order", "desc") limit = request.GET.get("limit") offset = request.GET.get("offset") page = (int(offset) / int(limit)) + 1 profiles = FacebookProfileUrl.objects.filter(user=request.user, is_deleted=False) profile_count = profiles.count() if search: profiles = profiles.filter(Q(url__icontains=search) | Q(tag__icontains=search) | Q(full_name__icontains=search)) if order_type == 'asc': profiles = profiles.order_by(sort) else: profiles = profiles.order_by('-' + sort) paginator = Paginator(profiles, limit) try: profiles = paginator.page(page) except PageNotAnInteger: profiles = paginator.page(1) except EmptyPage: profiles = paginator.page(paginator.num_pages) rows = [ { "id": profile.id, "tag": profile.tag, "image_path": profile.image_path, "desc": profile.desc, "date_to_be_added": profile.date_to_be_added, "full_name": profile.full_name, "url": profile.url, "is_messaged": profile.is_messaged, "created_on": filter_date(profile.created_on, "d/m/Y") } for profile in profiles ] data = { "total": profile_count, "rows": rows } return JsonResponse(data)
def ajax_messenger_history(request): search = request.GET.get("search") sort = request.GET.get("sort", "id") order_type = request.GET.get("order", "desc") limit = request.GET.get("limit") offset = request.GET.get("offset") page = (int(offset) / int(limit)) + 1 profiles = TaskProgress.objects.filter(user=request.user) profile_count = profiles.count() if search: profiles = profiles.filter(name__icontains=search) if order_type == 'asc': profiles = profiles.order_by(sort) else: profiles = profiles.order_by('-' + sort) paginator = Paginator(profiles, limit) try: profiles = paginator.page(page) except PageNotAnInteger: profiles = paginator.page(1) except EmptyPage: profiles = paginator.page(paginator.num_pages) rows = [ { "id": profile.id, "in_pause": TaskStatus.objects.filter(task_id=profile.id, task_type="m")[0].in_pause, "name": profile.name, "sent": profile.sent, "total": profile.total, "done": profile.done, "created_on": filter_date(profile.created_on, "d/m/Y") } for profile in profiles ] data = { "total": profile_count, "rows": rows } return JsonResponse(data)
def submit_measurement(self, request, data, instance): user = request.user project = request.data.get('project', None) properties = data.get('properties', None) if project is not None and properties is not None: finished = data.get('finished', None) results = properties.get('results', None) if finished is not None and results is not None: try: project = Project.objects.get(pk=project, status='active') aq_project = AirQualityProject.objects.get( status='active', project=project ) category_types = dict(AirQualityCategory.TYPES) field_types = dict(AirQualityField.TYPES) results = float(results) if results < 40: category = category_types['1'] elif results >= 40 and results < 60: category = category_types['2'] elif results >= 60 and results < 80: category = category_types['3'] elif results >= 80 and results < 100: category = category_types['4'] else: category = category_types['5'] aq_category = AirQualityCategory.objects.get( type=category, project=aq_project ) properties = {} for key, value in field_types.iteritems(): aq_field = AirQualityField.objects.get( type=value, category=aq_category ) instance_properties = instance.location.properties value = None if key == 'results': value = results elif key == 'date_out': value = filter_date(instance.started, 'd/m/Y') elif key == 'time_out': value = filter_date(instance.started, 'H:i') elif key == 'date_collected': value = filter_date(instance.finished, 'd/m/Y') elif key == 'time_collected': value = filter_date(instance.finished, 'H:i') elif key == 'exposure_min': value = instance.finished - instance.started value = int(value.total_seconds() / 60) elif key == 'distance_from_road': value = '%sm' % instance_properties.get( 'distance' ) elif key == 'height': value = '%sm' % instance_properties.get( 'height' ) elif key == 'site_characteristics': value = instance_properties.get( 'characteristics' ) elif key == 'additional_details': value = instance.properties.get( 'additional_details' ) elif key == 'made_by_students': value = instance.properties.get( 'made_by_students' ) if value: value = 'Yes' else: value = 'No' try: value = aq_field.field.lookupvalues.get( name=value).id except Field.DoesNotExist: return False if value is not None: properties[aq_field.field.key] = str(value) except: return False if project.can_contribute(user): data = { 'type': 'Feature', 'meta': { 'status': 'active', 'category': aq_category.category.id }, 'location': { 'geometry': instance.location.geometry.geojson }, 'properties': properties } serializer = ContributionSerializer( data=data, context={'user': user, 'project': project} ) if serializer.is_valid(raise_exception=True): serializer.save() instance.delete() return True return False
def get(self, request, file, *args, **kwargs): """ GET method for the view. Export all measurements to a CSV file. Parameters ---------- request : django.http.HttpRequest Represents the request. file : str Identifies the file name. Returns ------- django.http.HttpResponse CSV file. """ if not request.user.is_superuser: return HttpResponse(status=403) out = HttpResponse(content_type='text/csv') out['Content-Disposition'] = 'attachment; filename="%s - %s.csv"' % ( 'Measurements', dateformat.format(timezone.now(), 'l, jS \\o\\f F, Y') ) fieldnames = [ 'Barcode', 'Location', 'Site characteristics', 'Height from ground (m)', 'Distance from the road (m)', 'Additional details', 'Date out', 'Date in', 'Time out', 'Time in', 'Exposure time (min)', 'Exposure time (hr)', 'Diffusion tube made by students', 'Added by' ] writer = csv.DictWriter(out, fieldnames=fieldnames) writer.writeheader() for measurement in AirQualityMeasurement.objects.all(): location = measurement.location if measurement.finished: exposure = measurement.finished - measurement.started exposure_min = int(exposure.total_seconds() / 60) exposure_hr = int(exposure.total_seconds() / 3600) date_in = filter_date(measurement.finished, 'd/m/Y') time_in = filter_date(measurement.finished, 'H:i') else: exposure_min = None exposure_hr = None date_in = None time_in = None row = { 'Barcode': measurement.barcode, 'Location': location.name, 'Site characteristics': location.properties.get( 'characteristics'), 'Height from ground (m)': location.properties.get( 'height'), 'Distance from the road (m)': location.properties.get( 'distance'), 'Additional details': measurement.properties.get( 'additional_details'), 'Date out': filter_date(measurement.started, 'd/m/Y'), 'Date in': date_in, 'Time out': filter_date(measurement.started, 'H:i'), 'Time in': time_in, 'Exposure time (min)': exposure_min, 'Exposure time (hr)': exposure_hr, 'Diffusion tube made by students': measurement.properties.get( 'made_by_students'), 'Added by': measurement.creator.display_name } writer.writerow({key: str(value).encode('utf-8') if value else None for key, value in row.iteritems()}) return out
def get(self, request): """ Sends a sheet of finished measurements started by the user. Parameters ---------- request : rest_framework.request.Request Represents the request. Returns ------- rest_framework.response.Response Contains empty response indicating successful send of an email or an error message. """ user = request.user if user.is_anonymous(): return Response( {'error': 'You have no rights to retrieve a sheet.'}, status=status.HTTP_403_FORBIDDEN ) out = StringIO.StringIO() fieldnames = [ 'Barcode', 'Location', 'Site characteristics', 'Height from ground (m)', 'Distance from the road (m)', 'Additional details', 'Date out', 'Date in', 'Time out', 'Time in', 'Exposure time (min)', 'Exposure time (hr)', 'Diffusion tube made by students', ] writer = csv.DictWriter(out, fieldnames=fieldnames) writer.writeheader() for measurement in AirQualityMeasurement.objects.filter( creator=user ).exclude(finished=None).distinct(): location = measurement.location exposure = measurement.finished - measurement.started row = { 'Barcode': measurement.barcode, 'Location': location.name, 'Site characteristics': location.properties.get( 'characteristics'), 'Height from ground (m)': location.properties.get( 'height'), 'Distance from the road (m)': location.properties.get( 'distance'), 'Additional details': measurement.properties.get( 'additional_details'), 'Date out': filter_date(measurement.started, 'd/m/Y'), 'Date in': filter_date(measurement.finished, 'd/m/Y'), 'Time out': filter_date(measurement.started, 'H:i'), 'Time in': filter_date(measurement.finished, 'H:i'), 'Exposure time (min)': int(exposure.total_seconds() / 60), 'Exposure time (hr)': int(exposure.total_seconds() / 3600), 'Diffusion tube made by students': measurement.properties.get( 'made_by_students') } writer.writerow({key: str(value).encode('utf-8') if value else None for key, value in row.iteritems()}) message = mail.EmailMessage( 'Air Quality: Sheet of finished measurements', 'Please find the attached CSV in this email.', settings.DEFAULT_FROM_EMAIL, [user.email] ) message.attach('sheet.csv', out.getvalue(), 'text/csv') connection = mail.get_connection() connection.open() connection.send_messages([message]) connection.close() return Response(status=status.HTTP_204_NO_CONTENT)