diff --git a/api/tests.py b/api/tests.py index 2920acc9..7d04ee89 100755 --- a/api/tests.py +++ b/api/tests.py @@ -1,5 +1,5 @@ import json -import datetime +from regluit.utils.localdatetime import now from decimal import Decimal from django.test import TestCase @@ -19,7 +19,7 @@ class ApiTests(TestCase): name=edition.work.title, work=edition.work, description='Test Campaign', - deadline=datetime.datetime.now(), + deadline=now(), target=Decimal('1000.00'), ) self.user = User.objects.create_user('test', 'test@example.com', 'testpass') diff --git a/core/bookloader.py b/core/bookloader.py index 898d592d..49595223 100755 --- a/core/bookloader.py +++ b/core/bookloader.py @@ -1,21 +1,26 @@ import json import logging -import datetime import requests from xml.etree import ElementTree from itertools import izip, islice +from datetime import timedelta + from django.db.models import Q from django.conf import settings from django.db import IntegrityError from django.contrib.comments.models import Comment + import regluit from regluit.core import models +from regluit.utils.localdatetime import now import regluit.core.isbn + + logger = logging.getLogger(__name__) @@ -444,9 +449,9 @@ def merge_works(w1, w2, user=None): def add_openlibrary(work): if work.openlibrary_lookup is not None: # don't hit OL if we've visited in the past month or so - if datetime.datetime.now()- work.openlibrary_lookup < datetime.timedelta(days=30): + if now()- work.openlibrary_lookup < timedelta(days=30): return - work.openlibrary_lookup = datetime.datetime.now() + work.openlibrary_lookup = now() work.save() # find the first ISBN match in OpenLibrary diff --git a/core/management/commands/random_campaigns.py b/core/management/commands/random_campaigns.py index 01271142..c8ff26f2 100644 --- a/core/management/commands/random_campaigns.py +++ b/core/management/commands/random_campaigns.py @@ -1,6 +1,7 @@ from decimal import Decimal from random import randint, randrange -from datetime import datetime, timedelta +from datetime import timedelta +from regluit.utils.localdatetime import now from decimal import Decimal as D from django.core.management.base import BaseCommand @@ -27,7 +28,7 @@ class Command(BaseCommand): campaign.paypal_receiver = settings.PAYPAL_TEST_RH_EMAIL # random deadline between 5 days from now and 180 days from now - now = datetime.now() + now = now() campaign.deadline = random_date(now + timedelta(days=5), now + timedelta(days=180)) diff --git a/core/models.py b/core/models.py index 91c8f0e9..92bce81c 100755 --- a/core/models.py +++ b/core/models.py @@ -1,6 +1,7 @@ import re import random -import datetime +from regluit.utils.localdatetime import now, date_today +from datetime import timedelta from decimal import Decimal from django.db import models @@ -16,7 +17,7 @@ class UnglueitError(RuntimeError): pass class CeleryTask(models.Model): - created = models.DateTimeField(auto_now_add=True, default=datetime.datetime.now()) + created = models.DateTimeField(auto_now_add=True, default=now()) task_id = models.CharField(max_length=255) user = models.ForeignKey(User, related_name="tasks", null=True) description = models.CharField(max_length=2048, null=True) # a description of what the task is @@ -114,10 +115,10 @@ class Campaign(models.Model): if self.target < Decimal(settings.UNGLUEIT_MINIMUM_TARGET): self.problems.append(_('A campaign may not be launched with a target less than $%s' % settings.UNGLUEIT_MINIMUM_TARGET)) may_launch = False - if self.deadline.date()-datetime.date.today() > datetime.timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE)): + if self.deadline.date()- date_today() > timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE)): self.problems.append(_('The chosen closing date is more than %s days from now' % settings.UNGLUEIT_LONGEST_DEADLINE)) may_launch = False - elif self.deadline.date()-datetime.date.today() < datetime.timedelta(days=int(settings.UNGLUEIT_SHORTEST_DEADLINE)): + elif self.deadline.date()- date_today() < timedelta(days=int(settings.UNGLUEIT_SHORTEST_DEADLINE)): self.problems.append(_('The chosen closing date is less than %s days from now' % settings.UNGLUEIT_SHORTEST_DEADLINE)) may_launch = False return may_launch @@ -126,10 +127,9 @@ class Campaign(models.Model): def update_success(self): """ updates the campaign's status. returns true if updated """ - now = datetime.datetime.utcnow() if not self.status=='ACTIVE': return False - elif self.deadline < now: + elif self.deadline < now(): if self.current_total >= self.target: self.status = 'SUCCESSFUL' action = CampaignAction(campaign=self, type='succeeded', comment = self.current_total) diff --git a/frontend/tests.py b/frontend/tests.py index ac86ff1b..2a5692e5 100755 --- a/frontend/tests.py +++ b/frontend/tests.py @@ -7,7 +7,8 @@ from django.core.urlresolvers import reverse from regluit.core.models import Work, Campaign from decimal import Decimal as D -import datetime +from regluit.utils.localdatetime import now +from datetime import timedelta class WishlistTests(TestCase): @@ -86,7 +87,7 @@ class CampaignUiTests(TestCase): # load a Work and a Campaign to create a Pledge page self.work = Work(title="test Work") self.work.save() - self.campaign = Campaign(target=D('1000.00'), deadline=datetime.datetime.utcnow() + datetime.timedelta(days=180), + self.campaign = Campaign(target=D('1000.00'), deadline=now() + timedelta(days=180), work=self.work) self.campaign.save() self.campaign.activate() diff --git a/frontend/views.py b/frontend/views.py index 00bd7912..899d290f 100755 --- a/frontend/views.py +++ b/frontend/views.py @@ -2,7 +2,9 @@ import re import sys import json import logging -import datetime +from datetime import timedelta +from regluit.utils.localdatetime import now, date_today + from random import randint from re import sub from itertools import islice @@ -359,7 +361,7 @@ class PledgeView(FormView): # the recipients of this authorization is not specified here but rather by the PaymentManager. # set the expiry date based on the campaign deadline - expiry = campaign.deadline + datetime.timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN ) + expiry = campaign.deadline + timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN ) t, url = p.authorize('USD', TARGET_TYPE_CAMPAIGN, preapproval_amount, expiry=expiry, campaign=campaign, list=None, user=user, return_url=return_url, cancel_url=cancel_url, anonymous=anonymous) else: # embedded view -- which we're not actively using right now. @@ -595,7 +597,7 @@ def rh_tools(request): claim.campaign_form = OpenCampaignForm(request.POST) if claim.campaign_form.is_valid(): new_campaign = claim.campaign_form.save(commit=False) - new_campaign.deadline = datetime.date.today() + datetime.timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE)) + new_campaign.deadline = date_today() + timedelta(days=int(settings.UNGLUEIT_LONGEST_DEADLINE)) new_campaign.target = D(settings.UNGLUEIT_MINIMUM_TARGET) new_campaign.save() claim.campaign_form.save_m2m() @@ -962,7 +964,7 @@ class CampaignFormView(FormView): work_id = campaign.work.id # set the expiry date based on the campaign deadline - expiry = campaign.deadline + datetime.timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN ) + expiry = campaign.deadline + timedelta( days=settings.PREAPPROVAL_PERIOD_AFTER_CAMPAIGN ) if not self.embedded: @@ -998,15 +1000,15 @@ class InfoPageView(TemplateView): def get_context_data(self, **kwargs): users = User.objects - users.today = users.filter(date_joined__range = (datetime.date.today(), datetime.datetime.now())) - users.days7 = users.filter(date_joined__range = (datetime.date.today()-datetime.timedelta(days=7), datetime.datetime.now())) - users.year = users.filter(date_joined__year = datetime.date.today().year) - users.month = users.year.filter(date_joined__month = datetime.date.today().month) + users.today = users.filter(date_joined__range = (date_today(), now())) + users.days7 = users.filter(date_joined__range = (date_today()-timedelta(days=7), now())) + users.year = users.filter(date_joined__year = date_today().year) + users.month = users.year.filter(date_joined__month = date_today().month) works = models.Work.objects - works.today = works.filter(created__range = (datetime.date.today(), datetime.datetime.now())) - works.days7 = works.filter(created__range = (datetime.date.today()-datetime.timedelta(days=7), datetime.datetime.now())) - works.year = works.filter(created__year = datetime.date.today().year) - works.month = works.year.filter(created__month = datetime.date.today().month) + works.today = works.filter(created__range = (date_today(), now())) + works.days7 = works.filter(created__range = (date_today()-timedelta(days=7), now())) + works.year = works.filter(created__year = date_today().year) + works.month = works.year.filter(created__month = date_today().month) works.wishedby2 = works.filter(num_wishes__gte = 2) works.wishedby20 = works.filter(num_wishes__gte = 20) works.wishedby5 = works.filter(num_wishes__gte = 5) @@ -1014,15 +1016,15 @@ class InfoPageView(TemplateView): works.wishedby10 = works.filter(num_wishes__gte = 10) works.wishedby100 = works.filter(num_wishes__gte = 100) ebooks = models.Ebook.objects - ebooks.today = ebooks.filter(created__range = (datetime.date.today(), datetime.datetime.now())) - ebooks.days7 = ebooks.filter(created__range = (datetime.date.today()-datetime.timedelta(days=7), datetime.datetime.now())) - ebooks.year = ebooks.filter(created__year = datetime.date.today().year) - ebooks.month = ebooks.year.filter(created__month = datetime.date.today().month) + ebooks.today = ebooks.filter(created__range = (date_today(), now())) + ebooks.days7 = ebooks.filter(created__range = (date_today()-timedelta(days=7), now())) + ebooks.year = ebooks.filter(created__year = date_today().year) + ebooks.month = ebooks.year.filter(created__month = date_today().month) wishlists= models.Wishlist.objects.exclude(wishes__isnull=True) - wishlists.today = wishlists.filter(created__range = (datetime.date.today(), datetime.datetime.now())) - wishlists.days7 = wishlists.filter(created__range = (datetime.date.today()-datetime.timedelta(days=7), datetime.datetime.now())) - wishlists.year = wishlists.filter(created__year = datetime.date.today().year) - wishlists.month = wishlists.year.filter(created__month = datetime.date.today().month) + wishlists.today = wishlists.filter(created__range = (date_today(), now())) + wishlists.days7 = wishlists.filter(created__range = (date_today()-timedelta(days=7), now())) + wishlists.year = wishlists.filter(created__year = date_today().year) + wishlists.month = wishlists.year.filter(created__month = date_today().month) return { 'users': users, 'works': works, diff --git a/payment/manager.py b/payment/manager.py index d1cb0313..f8e2c373 100644 --- a/payment/manager.py +++ b/payment/manager.py @@ -9,7 +9,7 @@ from regluit.payment.paypal import Preapproval, IPN_PAY_STATUS_COMPLETED, Cancel from regluit.payment.paypal import RefundPayment import uuid import traceback -from datetime import datetime +from regluit.utils.localdatetime import now from dateutil.relativedelta import relativedelta import logging from decimal import Decimal as D @@ -154,10 +154,10 @@ class PaymentManager( object ): past_days = DEFAULT_DAYS_TO_CHECK try: - ref_date = datetime.utcnow() - relativedelta(days=int(past_days)) + ref_date = now() - relativedelta(days=int(past_days)) payment_transactions = Transaction.objects.filter(date_payment__gte=ref_date) except: - ref_date = datetime.utcnow() + ref_date = now() payment_transactions = Transaction.objects.filter(date_payment__isnull=False) logger.info(payment_transactions) @@ -486,7 +486,7 @@ class PaymentManager( object ): return False # mark this transaction as executed - transaction.date_executed = datetime.utcnow() + transaction.date_executed = now() transaction.save() p = Execute(transaction) @@ -540,7 +540,7 @@ class PaymentManager( object ): transaction.create_receivers(receiver_list) # Mark as payment attempted so we will poll this periodically for status changes - transaction.date_payment = datetime.utcnow() + transaction.date_payment = now() transaction.save() p = Pay(transaction) @@ -833,7 +833,7 @@ class PaymentManager( object ): campaign=campaign, list=list, user=user, - date_payment=datetime.utcnow(), + date_payment=now(), anonymous=anonymous ) diff --git a/payment/tests.py b/payment/tests.py index 6ea46fd5..f1ea3785 100644 --- a/payment/tests.py +++ b/payment/tests.py @@ -22,7 +22,7 @@ from selenium.webdriver.support.ui import WebDriverWait import logging import os from decimal import Decimal as D -import datetime +from regluit.utils.localdatetime import now def setup_selenium(): # Set the display window for our xvfb @@ -278,7 +278,7 @@ class TransactionTest(TestCase): w = Work() w.save() - c = Campaign(target=D('1000.00'),deadline=datetime.datetime.utcnow() + datetime.timedelta(days=180),work=w) + c = Campaign(target=D('1000.00'),deadline=now() + datetime.timedelta(days=180),work=w) c.save() t = Transaction() diff --git a/requirements.pip b/requirements.pip index 91d2b115..c27e282f 100644 --- a/requirements.pip +++ b/requirements.pip @@ -1,4 +1,5 @@ -django +Django==1.3.1 +MySQL-python==1.2.3 south django-extensions https://github.com/toastdriven/django-tastypie/tarball/master diff --git a/settings/common.py b/settings/common.py index 6309ba57..137553b3 100644 --- a/settings/common.py +++ b/settings/common.py @@ -107,6 +107,7 @@ INSTALLED_APPS = ( 'regluit.api', 'regluit.core', 'regluit.payment', + 'regluit.utils', 'registration', 'social_auth', 'tastypie', diff --git a/utils/__init__.py b/utils/__init__.py new file mode 100644 index 00000000..aa53091f --- /dev/null +++ b/utils/__init__.py @@ -0,0 +1 @@ +import localdatetime diff --git a/utils/localdatetime.py b/utils/localdatetime.py new file mode 100644 index 00000000..c6a7e045 --- /dev/null +++ b/utils/localdatetime.py @@ -0,0 +1,42 @@ +""" +Utility to return datetime.datetime.utcnow() by default but allows for a custom utcnow() (e.g., for testing) + +>>> import regluit +>>> from regluit.utils.localdatetime import now +>>> now() +datetime.datetime(2012, 3, 8, 14, 0, 35, 409270) +>>> now() +datetime.datetime(2012, 3, 8, 14, 0, 36, 985271) +>>> n = now() +>>> n +datetime.datetime(2012, 3, 8, 14, 1, 54, 650679) +>>> regluit.utils.localdatetime._now = lambda: n +>>> now() +datetime.datetime(2012, 3, 8, 14, 1, 54, 650679) +>>> now() +datetime.datetime(2012, 3, 8, 14, 1, 54, 650679) +>>> now() + + +""" + +import datetime +import django + +# for Django 1.3.x, return a timestamp naive now() +# for Django 1.4 should switch to django.utils.timezone.now() +# see https://code.djangoproject.com/browser/django/trunk/django/utils/timezone.py?rev=17642#L232 + +try: + _now = django.utils.timezone.now +except AttributeError, e: + _now = datetime.datetime.now + +now = lambda: _now() + +# provide a replacement for datetime.date.today() +# this will be timezone naive -- is that what we really want? + +date_today = lambda: _now().date() + +