def mail_reply(user, reply): """ Sends an e-mail representing the supplied reply to a review. """ review = reply.base_reply_to review_request = review.review_request if not review_request.public: return extra_context = { 'user': user, 'review': review, 'reply': reply, } has_error, extra_context['comment_entries'] = \ build_diff_comment_fragments( reply.comments.order_by('filediff', 'first_line'), extra_context, "notifications/email_diff_comment_fragment.html") reply.email_message_id = \ send_review_mail(user, review_request, u"Re: Review Request %d: %s" % (review_request.id, review_request.summary), review.email_message_id, review.participants, 'notifications/reply_email.txt', 'notifications/reply_email.html', extra_context) reply.time_emailed = get_tz_aware_utcnow() reply.save()
def create(self, file_attachment, review_request): comment = FileAttachmentComment(text=self.cleaned_data["review"], file_attachment=file_attachment) comment.timestamp = get_tz_aware_utcnow() comment.save(save=True) draft = ReviewRequestDraft.create(review_request) draft.file_attachment_comments.add(comment) draft.save() return comment
def pre_save(self, model, add): if not add or getattr(model, self.attname) is None: value = datetime.now() if is_aware(value): value = get_tz_aware_utcnow() setattr(model, self.attname, value) return value return super(ModificationTimestampField, self).pre_save(model, add)
def pre_save(self, model, add): if not add or getattr(model, self.attname) is None: if settings.USE_TZ: value = get_tz_aware_utcnow() else: value = datetime.now() setattr(model, self.attname, value) return value return super(ModificationTimestampField, self).pre_save(model, add)
def ageid(timestamp): """Return an ID based on the difference between now and a timestamp. This can be used to help show the age of an item in days. It will generate an ID in the form of :samp:`age{num}` ranging from ``age1`` (today) through ``age5`` (4+ days old). This is a specialty function, and is not expected to be useful in many cases. Args: timestamp (datetime.datetime): The timestamp to compare to. Returns: unicode: The ID. One of ``age1``, ``age2``, ``age3``, ``age4``, or ``age5``. Example: .. code-block:: html+django <div class="{% ageid obj.timestamp %}"> {{obj.timestamp}} </div> """ if timestamp is None: return "" # Convert datetime.date into datetime.datetime if timestamp.__class__ is not datetime.datetime: timestamp = datetime.datetime(timestamp.year, timestamp.month, timestamp.day) now = datetime.datetime.utcnow() if is_aware(timestamp): now = get_tz_aware_utcnow() delta = now - (timestamp - datetime.timedelta(0, 0, timestamp.microsecond)) if delta.days == 0: return "age1" elif delta.days == 1: return "age2" elif delta.days == 2: return "age3" elif delta.days == 3: return "age4" else: return "age5"
def test_check_for_updates(self): """Testing the check for updates functionality""" r = ReviewRequest.objects.filter(public=True, status='P', submitter=self.user)[0] self.selenium.open(r.get_absolute_url()) # Simulate an update. r.last_updated = get_tz_aware_utcnow() r.save() transaction.commit() self.selenium.get_eval('this.browserbot.getCurrentWindow().' 'gReviewRequest._checkForUpdates()') self.wait_for_element_present('updates-bubble') self.wait_for_visible('updates-bubble')
def ageid(timestamp): """ Returns an ID based on the difference between a timestamp and the current time. The ID is returned based on the following differences in days: ========== ==== Difference ID ========== ==== 0 age1 1 age2 2 age3 3 age4 4 or more age5 ========== ==== """ if timestamp is None: return "" # Convert datetime.date into datetime.datetime if timestamp.__class__ is not datetime.datetime: timestamp = datetime.datetime(timestamp.year, timestamp.month, timestamp.day) now = datetime.datetime.utcnow() if is_aware(timestamp): now = get_tz_aware_utcnow() delta = now - (timestamp - datetime.timedelta(0, 0, timestamp.microsecond)) if delta.days == 0: return "age1" elif delta.days == 1: return "age2" elif delta.days == 2: return "age3" elif delta.days == 3: return "age4" else: return "age5"
def testDateTimeSinceColumn(self): """Testing DateTimeSinceColumn""" class DummyObj: time = None column = DateTimeSinceColumn("Test", field_name='time') if settings.USE_TZ: now = get_tz_aware_utcnow() else: now = datetime.now() obj = DummyObj() obj.time = now self.assertEqual(column.render_data(obj), "0\xa0minutes ago") obj.time = now - timedelta(days=5) self.assertEqual(column.render_data(obj), "5\xa0days ago") obj.time = now - timedelta(days=7) self.assertEqual(column.render_data(obj), "1\xa0week ago")
def testDateTimeSinceColumn(self): """Testing DateTimeSinceColumn""" class DummyObj: time = None column = DateTimeSinceColumn("Test", field_name='time') if settings.USE_TZ: now = get_tz_aware_utcnow() else: now = datetime.now() obj = DummyObj() obj.time = now self.assertEqual(column.render_data(obj), "0 minutes ago") obj.time = now - timedelta(days=5) self.assertEqual(column.render_data(obj), "5 days ago") obj.time = now - timedelta(days=7) self.assertEqual(column.render_data(obj), "1 week ago")
def mail_review_request(user, review_request, changedesc=None): """ Send an e-mail representing the supplied review request. The "changedesc" argument is an optional ChangeDescription showing what changed in a review request, possibly with explanatory text from the submitter. This is created when saving a draft on a public review request, and will be None when publishing initially. This is used by the template to add contextual (updated) flags to inform people what changed. """ # If the review request is not yet public or has been discarded, don't send # any mail. if not review_request.public or review_request.status == 'D': return subject = u"Review Request %d: %s" % (review_request.id, review_request.summary) reply_message_id = None if review_request.email_message_id: # Fancy quoted "replies" subject = "Re: " + subject reply_message_id = review_request.email_message_id extra_recipients = review_request.participants else: extra_recipients = None extra_context = {} if changedesc: extra_context['change_text'] = changedesc.text extra_context['changes'] = changedesc.fields_changed review_request.time_emailed = get_tz_aware_utcnow() review_request.email_message_id = \ send_review_mail(user, review_request, subject, reply_message_id, extra_recipients, 'notifications/review_request_email.txt', 'notifications/review_request_email.html', extra_context) review_request.save()
def test_render_data(self): """Testing DateTimeSinceColumn.render_data""" class DummyObj: time = None column = DateTimeSinceColumn('Test', field_name='time') state = StatefulColumn(None, column) if settings.USE_TZ: now = get_tz_aware_utcnow() else: now = datetime.now() obj = DummyObj() obj.time = now self.assertEqual(column.render_data(state, obj), '0\xa0minutes ago') obj.time = now - timedelta(days=5) self.assertEqual(column.render_data(state, obj), '5\xa0days ago') obj.time = now - timedelta(days=7) self.assertEqual(column.render_data(state, obj), '1\xa0week ago')
def internal_login(request, username, password): try: user = auth.authenticate(username=username, password=password) except: user = None if not user: return "Incorrect username or password." elif not user.is_active: return "This account is inactive." elif not request.session.test_cookie_worked(): return "Cookies must be enabled." auth.login(request, user) if request.session.test_cookie_worked(): request.session.delete_test_cookie() if settings.USE_TZ: user.last_login = get_tz_aware_utcnow() else: user.last_login = datetime.now() user.save()
def test_date_time_is_in_utc(self): """Testing get_tz_aware_utcnow returns UTC time.""" utc_time = dates.get_tz_aware_utcnow() self.assertEqual(utc_time.tzinfo, pytz.utc)
def test_date_time_is_in_utc(self): """Testing get_tz_aware_utcnow returns UTC time.""" utc_time = get_tz_aware_utcnow() self.assertEqual(utc_time.tzinfo, pytz.utc)
def review_detail(request, review_request_id, local_site_name=None, template_name="reviews/review_detail.html"): """ Main view for review requests. This covers the review request information and all the reviews on it. """ # If there's a local_site passed in the URL, we want to look up the review # request based on the local_id instead of the pk. This allows each # local_site configured to have its own review request ID namespace # starting from 1. review_request, response = \ _find_review_request(request, review_request_id, local_site_name) if not review_request: return response reviews = review_request.get_public_reviews() review = review_request.get_pending_review(request.user) review_timestamp = 0 last_visited = 0 starred = False if request.user.is_authenticated(): # If the review request is public and pending review and if the user # is logged in, mark that they've visited this review request. if review_request.public and review_request.status == "P": visited, visited_is_new = ReviewRequestVisit.objects.get_or_create( user=request.user, review_request=review_request) last_visited = visited.timestamp.replace(tzinfo=utc) visited.timestamp = get_tz_aware_utcnow() visited.save() profile, profile_is_new = \ Profile.objects.get_or_create(user=request.user) starred = review_request in profile.starred_review_requests.all() # Unlike review above, this covers replies as well. try: last_draft_review = Review.objects.filter( review_request=review_request, user=request.user, public=False).latest() review_timestamp = last_draft_review.timestamp except Review.DoesNotExist: pass draft = review_request.get_draft(request.user) # Find out if we can bail early. Generate an ETag for this. last_activity_time, updated_object = review_request.get_last_activity() if draft: draft_timestamp = draft.last_updated else: draft_timestamp = "" etag = "%s:%s:%s:%s:%s:%s" % (request.user, last_activity_time, draft_timestamp, review_timestamp, int(starred), settings.AJAX_SERIAL) if etag_if_none_match(request, etag): return HttpResponseNotModified() changedescs = review_request.changedescs.filter(public=True) latest_changedesc = None try: latest_changedesc = changedescs.latest() latest_timestamp = latest_changedesc.timestamp except ChangeDescription.DoesNotExist: latest_timestamp = None entries = [] for temp_review in reviews: temp_review.ordered_comments = \ temp_review.comments.order_by('filediff', 'first_line') state = '' # Mark as collapsed if the review is older than the latest change if latest_timestamp and temp_review.timestamp < latest_timestamp: state = 'collapsed' try: latest_reply = \ temp_review.public_replies().latest('timestamp').timestamp except Review.DoesNotExist: latest_reply = None # Mark as expanded if there is a reply newer than last_visited if latest_reply and last_visited and last_visited < latest_reply: state = '' entries.append({ 'review': temp_review, 'timestamp': temp_review.timestamp, 'class': state, }) for changedesc in changedescs: fields_changed = [] for name, info in changedesc.fields_changed.items(): multiline = False if 'added' in info or 'removed' in info: change_type = 'add_remove' # We don't hard-code URLs in the bug info, since the # tracker may move, but we can do it here. if (name == "bugs_closed" and review_request.repository and review_request.repository.bug_tracker): bug_url = review_request.repository.bug_tracker for field in info: for i, buginfo in enumerate(info[field]): try: full_bug_url = bug_url % buginfo[0] info[field][i] = (buginfo[0], full_bug_url) except TypeError: logging.warning("Invalid bugtracker url format") elif 'old' in info or 'new' in info: change_type = 'changed' multiline = (name == "description" or name == "testing_done") # Branch text is allowed to have entities, so mark it safe. if name == "branch": if 'old' in info: info['old'][0] = mark_safe(info['old'][0]) if 'new' in info: info['new'][0] = mark_safe(info['new'][0]) # Make status human readable. if name == 'status': if 'old' in info: info['old'][0] = status_to_string(info['old'][0]) if 'new' in info: info['new'][0] = status_to_string(info['new'][0]) elif name == "screenshot_captions": change_type = 'screenshot_captions' elif name == "file_captions": change_type = 'file_captions' else: # No clue what this is. Bail. continue fields_changed.append({ 'title': fields_changed_name_map.get(name, name), 'multiline': multiline, 'info': info, 'type': change_type, }) # Expand the latest review change state = '' # Mark as collapsed if the change is older than a newer change if latest_timestamp and changedesc.timestamp < latest_timestamp: state = 'collapsed' entries.append({ 'changeinfo': fields_changed, 'changedesc': changedesc, 'timestamp': changedesc.timestamp, 'class': state, }) entries.sort(key=lambda item: item['timestamp']) close_description = '' if latest_changedesc and 'status' in latest_changedesc.fields_changed: status = latest_changedesc.fields_changed['status']['new'][0] if status in (ReviewRequest.DISCARDED, ReviewRequest.SUBMITTED): close_description = latest_changedesc.text issues = { 'total': 0, 'open': 0, 'resolved': 0, 'dropped': 0 } for entry in entries: if 'review' in entry: for comment in entry['review'].get_all_comments(issue_opened=True): issues['total'] += 1 issues[BaseComment.issue_status_to_string( comment.issue_status)] += 1 response = render_to_response( template_name, RequestContext(request, _make_review_request_context(review_request, { 'draft': draft, 'detail_hooks': ReviewRequestDetailHook.hooks, 'review_request_details': draft or review_request, 'entries': entries, 'last_activity_time': last_activity_time, 'review': review, 'request': request, 'latest_changedesc': latest_changedesc, 'close_description': close_description, 'PRE_CREATION': PRE_CREATION, 'issues': issues, }))) set_etag(response, etag) return response