Ejemplo n.º 1
0
    def verify(self, content):
        from derp import t
        old_result = self.result or ""
        old_result = latin1_to_ascii(old_result)
        content = latin1_to_ascii(content)
        if config.STABLE:
            verb = "SAME" if self.result == content else (
                "UPDATED %s>%s" % (len(self.result), len(content)))
            if not old_result:
                verb = "WROTE"
            self.result = content
            self.save()
            t("%s %s" % (verb, self))
            return True
        if not self.result:
            raise ValueError("Stable result not recorded for %s" % self)

        if old_result != content:  # last minute reconcilation for big integers that are off by small amounts
            old_lines = old_result.split("\n")
            new_lines = content.split("\n")
            for i, old_line in enumerate(old_lines):
                if len(new_lines) <= i:
                    break
                new_line = new_lines[i]
                if old_line == new_line:
                    continue
                old_number = int((re.findall(": (\d+)", old_line) or ['0'])[0])
                new_number = int((re.findall(": (\d+)", new_line) or ['0'])[0])
                if not (old_number and new_number) or old_number == new_number:
                    continue
                if abs(old_number - new_number) / float(old_number) < 0.001:
                    new_lines[i] = new_line.replace(str(new_number),
                                                    str(old_number))
            content = "\n".join(new_lines)
        if old_result == content:
            t("PASS: %s" % self)
            return True
        if old_result and old_result != content:
            # maybe this should be on t?
            import os, difflib
            name = str(self).replace(" ", "/").replace("#", "")
            diff_dir = "/".join(name.split("/")[:-1])
            fname = name.split("/")[-1]
            diff_dir = t.mkdir(diff_dir, prefix=".diff")
            diff_path = os.path.join(diff_dir, "%s.diff" % fname)
            d = "\n".join(
                difflib.unified_diff(old_result.split("\n"),
                                     content.split("\n")))
            headers = ["#%s" % self
                       ] + ["#%s: %s" % i for i in self.parameters.items()]
            d = "\n".join(headers) + "\n\n" + d
            t.write_file(diff_path, d, group="DIFF")
            t("CHANGED: %s %s" % (self.id, self))
Ejemplo n.º 2
0
 def _data(self,obj):
   fields = [{k: latin1_to_ascii(v) for k,v in f.items()} for f in fields]
   try:
     rows = "".join(["<tr><th>{name}</th><td>{value}</td></tr>".format(**f) for f in fields])
     return "<table class='table'>%s</table>"%rows
   except:
     return "unicode error"
Ejemplo n.º 3
0
 def query_list(self, obj):
     try:
         params = QueryDict(latin1_to_ascii(obj.query))
     except:
         return "Bad query"
     return "<table>%s</table>" % (''.join([
         "<tr><td>%s</td><td>%s</td></tr>" % i
         for i in sorted(params.items())
     ]))
Ejemplo n.º 4
0
 def _data(self,obj):
   if not obj.data:
     return
   fields = obj.get_fields()
   for field in fields:
     field['value'] = latin1_to_ascii(field['value'])
   try:
     rows = "".join(["<tr><th>{name}</th><td>{value}</td></tr>".format(**f) for f in fields])
     return "<table class='table'>%s</table>"%rows
   except:
     return "unicode error"
Ejemplo n.º 5
0
 def _data(self, obj):
     if not obj.data:
         return
     fields = obj.get_fields()
     for field in fields:
         field['value'] = latin1_to_ascii(field['value'])
     try:
         rows = "".join([
             "<tr><th>{name}</th><td>{value}</td></tr>".format(**f)
             for f in fields
         ])
         return "<table class='table'>%s</table>" % rows
     except:
         return "unicode error"
Ejemplo n.º 6
0
def handle_successful_store_payment(sender, user):
  from drop.models import Product, Order, OrderPayment, Cart
  params = QueryDict(latin1_to_ascii(sender.query))
  try:
    order = Order.objects.get(pk=params['invoice'])
  except Order.DoesNotExist:
    mail_admins("missing invoice for %s"%sender.txn_id,"")
    return
  if order.status == Order.PAID:
    #order has already been paid, transaction was repeated. PayPal does this a lot
    return
  total = 0
  if not "num_cart_items" in params:
    mail_admins("No cart items found for %s"%sender.txn_id,"")
    return
  item_count = int(params['num_cart_items'])
  products = []
  for i in range(1,item_count+1):
    total += int(float(params['mc_gross_%d'%i]))
    quantity = int(params['quantity%s'%i])
    try:
      product = Product.objects.get(pk=params['item_number%d'%i] or 0)
    except Product.DoesNotExist:
      mail_admins("Product fail for %s"%sender.txn_id,"")
      continue
    if hasattr(product,"purchase"):
      product.purchase(order.user or user,quantity)
    products.append(product)
  order.status = Order.PAID
  order.user = order.user or user
  order.save()
  payment = OrderPayment.objects.create(
    order=order,
    amount=total,
    payment_method='PayPal',
    transaction_id=sender.txn_id
  )
  [p.save() for p in products] #save decreased stock last, incase of error
  try:
    Cart.objects.get(pk=order.cart_pk).delete()
  except Cart.DoesNotExist:
    pass
Ejemplo n.º 7
0
def handle_successful_store_payment(sender, user):
    from drop.models import Product, Order, OrderPayment, Cart
    try:
        params = QueryDict(sender.query)
    except UnicodeEncodeError:
        params = QueryDict(latin1_to_ascii(sender.query))
    try:
        order = Order.objects.get(pk=params['invoice'])
    except Order.DoesNotExist:
        mail_admins("repeat transaction for %s" % sender.txn_id, "")
        return
    if order.status == Order.COMPLETED:
        return
    total = 0
    if not "num_cart_items" in params:
        mail_admins("No cart items found for %s" % sender.txn_id, "")
        return
    item_count = int(params['num_cart_items'])
    products = []
    for i in range(1, item_count + 1):
        total += int(float(params['mc_gross_%d' % i]))
        quantity = int(params['quantity%s' % i])
        try:
            product = Product.objects.get(pk=params['item_number%d' % i] or 0)
        except Product.DoesNotExist:
            mail_admins("Product fail for %s" % sender.txn_id, "")
            continue
        products.append(product)
        product.decrease_stock(quantity)
    order.status = Order.COMPLETED
    order.user = order.user or user
    order.save()
    payment = OrderPayment.objects.create(order=order,
                                          amount=total,
                                          payment_method='PayPal',
                                          transaction_id=sender.txn_id)
    [p.save() for p in products]  #save decreased stock last, incase of error
    try:
        Cart.objects.get(pk=order.cart_pk).delete()
    except Cart.DoesNotExist:
        pass
Ejemplo n.º 8
0
class Session(UserModel, PhotosMixin, models.Model):
    def __init__(self, *args, **kwargs):
        super(Session, self).__init__(*args, **kwargs)
        if self.pk:
            # this sets self.first_date to the first ClassTime.start if they aren't equal
            # also sets self.last_date to the last ClassTime.end
            # handled in the admin by /static/js/course_admin.js
            _a = self.all_occurrences
            if not _a:
                return
            if not _a[0].start == self.first_date:
                self.first_date = _a[0].start
                self.save()
            if not _a[-1].end == self.last_date:
                self.last_date = _a[-1].end
                self.save()

    get_ics_url = lambda self: reverse_ics(self)
    course = models.ForeignKey(Course)
    cancelled = models.BooleanField(default=False)
    active = models.BooleanField(default=True)
    _ht = "This session will not appear as overbooked if it is less than X seats overbooked."
    overbook = models.IntegerField(default=0, help_text=_ht)
    _ht = "Private classes cannot be signed up for and do not appear on the session page unless " \
          "the user is manually enrolled. It will appear on calendar but it will be marked in red."
    private = models.BooleanField(default=False, help_text=_ht)
    notified = models.DateTimeField(null=True, blank=True)
    publish_dt = models.DateTimeField(null=True, blank=True)
    _ht = "This will be automatically updated when you save the model. Do not change"
    first_date = models.DateTimeField(default=datetime.datetime.now,
                                      help_text=_ht)  # for filtering
    last_date = models.DateTimeField(default=datetime.datetime.now,
                                     help_text=_ht)  # for filtering
    created = models.DateTimeField(
        auto_now_add=True)  # for emailing new classes
    # depracated?
    branding = models.ForeignKey(Branding, null=True, blank=True)

    _ht = "Date the instructor marked students in the class as completed"
    instructor_completed = models.DateField(null=True, blank=True)
    needed = models.TextField("What is needed?", blank=True, default="")
    needed_completed = models.DateField(null=True, blank=True)

    __unicode__ = lambda self: latin1_to_ascii("%s (%s - %s)" %
                                               (self.course, self.user,
                                                self.first_date.date()))
    title = property(lambda self: "%s (%s)" %
                     (self.course.name, self.first_date.date()))

    in_progress = property(lambda self: self.first_date < datetime.datetime.
                           now() < self.last_date)
    past = property(lambda self: datetime.datetime.now() > self.last_date)
    closed = property(lambda self: self.cancelled or
                      (self.past and not self.in_progress))

    @property
    def as_json(self):
        short_dates = self.get_short_dates()
        enrolled_status = "Enrolled: %s" % short_dates
        if datetime.datetime.now() > self.last_date:
            d = self.last_date
            enrolled_status = "Completed: %s/%s/%s" % (d.month, d.day, d.year)
        closed_status = self.closed_string if (self.closed
                                               or self.full) else None
        if self.private:
            closed_status = 'private'
        return {
            'id': self.pk,
            'name': "<b>%s</b> %s" % (self.course, short_dates),
            'course_name': self.course.name,
            'closed_status': closed_status,
            'short_dates': short_dates,
            'instructor_name': self.get_instructor_name(),
            'instructor_pk': self.user_id,
            'course_id': self.course_id,
            'enrolled_status': enrolled_status,
            'classtimes': [c.as_json for c in self.classtime_set.all()],
            'product_id': self.sessionproduct.id,
            'private': True,
        }

    json = property(lambda self: dumps(self.as_json))
    get_room = lambda self: self.course.room

    total_students = property(
        lambda self: sum([e.quantity for e in self.enrollment_set.all()]))
    evaluated_students = property(lambda self: self.get_evaluations().count())
    completed_students = property(lambda self: self.enrollment_set.filter(
        completed__isnull=False).count())
    full = property(
        lambda self: self.total_students >= self.course.max_students)
    list_users = property(lambda self: [self.user])

    #! mucch of this if deprecated after course remodel
    description = property(lambda self: self.course.description)

    @cached_property
    def first_photo(self):
        return (self.get_photos() or [super(Session, self).first_photo])[0]

    @cached_method
    def get_photos(self):
        return self._get_photos() or self.course.get_photos()

    #calendar crap
    name = property(lambda self: self.course.name)
    all_occurrences = cached_property(
        lambda self: list(self.classtime_set.all()), name='all_occurrences')
    get_ics_url = lambda self: reverse_ics(self)

    @cached_method
    def get_week(self):
        sunday = self.first_date.date() - datetime.timedelta(
            self.first_date.weekday())
        return (sunday, sunday + datetime.timedelta(6))

    subjects = cached_property(
        lambda self: self.course.subjects.filter(parent__isnull=True),
        name="subjects")
    all_subjects = cached_property(lambda self: self.course.subjects.all(),
                                   name="all_subjects")

    @cached_property
    def related_sessions(self):
        sessions = Session.objects.filter(
            first_date__gte=datetime.datetime.now(), active=True)
        sessions = sessions.exclude(course=self.course)
        sub_subjects = self.course.subjects.filter(parent__isnull=False)
        sub_sessions = list(
            sessions.filter(course__subjects__in=sub_subjects).distinct())
        if len(sub_sessions) >= 5:
            return sub_sessions
        sessions = sessions.filter(course__subjects__in=self.subjects.all())
        sessions = list(sessions.exclude(course__subjects__in=sub_subjects))
        return sub_sessions + sessions

    @property
    def closed_string(self):  #! may be depracated
        if self.cancelled:
            return "cancelled"
        if self.past:
            return "past"
        return "full"

    def save(self, *args, **kwargs):
        #this may be depracated, basically the site fails hard if instructors don't have membership profiles
        from membership.models import UserMembership
        if not self.pk and self.course:
            c = self.course
            c.active = True
            c.save()
        if self.active and not self.publish_dt:
            publish_dt = datetime.datetime.now()
        profile, _ = UserMembership.objects.get_or_create(user=self.user)
        super(Session, self).save(*args, **kwargs)
        SessionProduct.objects.get_or_create(session=self)[0].update()

    @cached_method
    def get_absolute_url(self):
        return self.course.get_absolute_url()

    get_admin_url = lambda self: "/admin/course/session/%s/" % self.id
    get_rsvp_url = cached_method(
        lambda self: reverse('course:rsvp', args=[self.id]),
        name="get_rsvp_url")

    def get_instructor_name(self):
        if self.user.first_name and self.user.last_name:
            return "%s %s." % (self.user.first_name, self.user.last_name[0])
        return self.user.username

    def get_short_dates(self):
        dates = [ct.start for ct in self.all_occurrences]
        month = None
        out = []
        for d in dates:
            if month != d.month:
                month = d.month
                out.append(d.strftime("%b %e"))
            else:
                out.append(d.strftime("%e"))
        return ', '.join(out)

    def get_evaluations(self):
        return Evaluation.objects.filter(enrollment__session=self)

    def has_completed_permission(self, user):
        return user.is_superuser or user.is_toolmaster or user.id == self.user_id

    class Meta:
        ordering = ('first_date', )
Ejemplo n.º 9
0
 def query_list(self,obj):
   try:
     params = QueryDict(latin1_to_ascii(obj.query))
   except:
     return "Bad query"
   return "<table>%s</table>"%(''.join(["<tr><td>%s</td><td>%s</td></tr>"%i for i in sorted(params.items())]))
Ejemplo n.º 10
0
def paypal_signal(sender, **kwargs):
    params = QueryDict(latin1_to_ascii(sender.query).replace("%FC", "u"))
    if sender.txn_type == "web_accept" and params[
            "custom"] == "support page donation":
        address = ""
        if params.get("address_street", None):
            address = "\n".join([
                params['address_name'], params['address_street'],
                "%s, %s" % (params['address_city'], params['address_state']),
                params['address_zip']
            ])
        send_template_email("email/donation_thank_you",
                            [params["payer_email"]],
                            context={
                                'params': params,
                                'address': address
                            })
        return
    if sender.txn_type in ["web_accept", "send_money"]:
        return  # payment from front page
    subscr_id = params.get('subscr_id', None) or params.get(
        'recurring_payment_id', None)
    if sender.txn_type in ['', 'cart', 'subscr_signup']:
        return  # refunds and classes and signups
    if sender.txn_id and Status.objects.filter(transaction_id=sender.txn_id):
        return  # This has already been processed
    subscription = get_subscription(params, sender)
    kwargs['subscription'] = subscription
    user, new_user = get_or_create_student(params)
    urls = "https://txrxlabs.org/admin/ipn/paypalipn/%s/" % sender.pk
    urls += "\n\n%s http://txrxlabs.org/admin/user/user/%s/" % (new_user,
                                                                user.pk)
    if subscription:
        urls += "\n\nhttps://txrxlabs.org/admin/membership/subscription/%s/" % subscription.pk

    if sender.txn_type in ['subscr_cancel']:
        subscription.force_canceled()
        paypal_flag(sender, **kwargs)
        mail_admins("Flagged %s and canceled" % sender.txn_type, urls)
        return

    elif sender.txn_type != "subscr_payment":
        return  # rest of function handles successful membership payment

    if not 'mc_gross' in params:
        mail_admins("Bad IPN", "no mc_gross in txn %s" % sender.txn_id)
        return
    amt = float(params['mc_gross'])
    if not subscription and params.get("item_number", None):
        try:
            subscription = Subscription.objects.get(pk=params['item_number'],
                                                    amount=amt)
        except Subscription.DoesNotExist:
            b = "Could not find subscription #%s for $%s and txn %s" % (
                params['item_number'], amt, sender.txn_id)
            mail_admins("Bad IPN: no subscription", b)
            return
    if not subscription:
        try:
            level = Level.objects.get(name=params.get('option_name1', ''))
        except Level.DoesNotExist:
            b = "Could not find level \"%s\" for txn %s" % (params.get(
                'option_name1', ''), sender.txn_id)
            mail_admins("Bad IPN: no level", b)
            return
        try:
            product = Product.objects.get(unit_price=amt, level=level)
        except Product.DoesNotExist:
            b = "Could not find level product \"%s\" (cost $%s) for txn %s"
            mail_admins("Bad IPN: no product", b % (level, amt, sender.txn_id))
            return
        subscription = Subscription.objects.create(user=user,
                                                   subscr_id=subscr_id,
                                                   level=product.level,
                                                   months=product.months,
                                                   amount=amt)
        Flag.objects.filter(
            subscription__user=subscription.user,
            status__in=Flag.PAYMENT_ACTIONS).update(status="paid")
        if not user.usercriterion_set.filter(
                criterion_id=settings.ORIENTATION_CRITERION_ID):
            # user has never been oriented, send welcome email and create fake safety
            user.send_welcome_email()

    status = Status.objects.create(
        transaction_id=sender.txn_id,
        subscription=subscription,
        paypalipn=sender,
        payment_method='paypal',
        amount=amt,
    )
    if not subscription.subscr_id:
        subscription.subscr_id = subscr_id
        subscription.save()
    # need to get subscription again because status forced it to recalculate
    subscription = status.subscription
    # clear out any subscription flags
    if subscription.owed <= 0:
        Flag.objects.filter(
            subscription=subscription,
            status__in=Flag.PAYMENT_ACTIONS).update(status="paid")
Ejemplo n.º 11
0
from django.http import QueryDict

from course.models import Enrollment
from drop.models import Order, OrderPayment
from lablackey.utils import latin1_to_ascii 
from paypal.standard.ipn.models import PayPalIPN

from decimal import Decimal
Order.objects.filter(pk__gt=3000).delete()
for enrollment in Enrollment.objects.exclude(transaction_ids__isnull=True):
  for txn_id in enrollment.transaction_ids.split("|"):
    if not txn_id:
      continue
    ipn = PayPalIPN.objects.filter(txn_id=txn_id)[0]
    order_payments = OrderPayment.objects.filter(transaction_id=txn_id)
    params = QueryDict(latin1_to_ascii(ipn.query))
    if order_payments:
      order = order_payments[0].order
    else:
      order = Order.objects.create(
        order_total=params['mc_gross'],
        order_subtotal=params['mc_gross'],
        user=enrollment.user,
      )
      order.created=enrollment.datetime
      order.updated=enrollment.datetime
      order.status = order.PAID
      order.save()
      order_payments = [OrderPayment.objects.create(
        order=order,
        transaction_id=txn_id,
Ejemplo n.º 12
0
def paypal_signal(sender,**kwargs):
  params = QueryDict(latin1_to_ascii(sender.query).replace("%FC","u"))
  if sender.txn_type == "web_accept" and params["custom"] == "support page donation":
    address = ""
    if params.get("address_street",None):
      address = "\n".join([
        params['address_name'],
        params['address_street'],
        "%s, %s"%(params['address_city'],params['address_state']),
        params['address_zip']
      ])
    send_template_email("email/donation_thank_you",[params["payer_email"]],context={'params': params,'address': address})
    return
  if sender.txn_type in ["web_accept","send_money"]:
    return # payment from front page
  subscr_id = params.get('subscr_id',None) or params.get('recurring_payment_id',None)
  if sender.txn_type in ['','cart','subscr_signup']:
    return # refunds and classes and signups
  if sender.txn_id and Status.objects.filter(transaction_id=sender.txn_id):
    return # This has already been processed
  subscription = get_subscription(params,sender)
  kwargs['subscription'] = subscription
  user,new_user = get_or_create_student(params)
  urls = "https://txrxlabs.org/admin/ipn/paypalipn/%s/"%sender.pk
  urls += "\n\n%s http://txrxlabs.org/admin/user/user/%s/"%(new_user,user.pk)
  if subscription:
    urls += "\n\nhttps://txrxlabs.org/admin/membership/subscription/%s/"%subscription.pk

  if sender.txn_type in ['subscr_cancel']:
    subscription.force_canceled()
    paypal_flag(sender,**kwargs)
    mail_admins("Flagged %s and canceled"%sender.txn_type,urls)
    return

  elif sender.txn_type != "subscr_payment":
    return # rest of function handles successful membership payment

  if not 'mc_gross' in params:
    mail_admins("Bad IPN","no mc_gross in txn %s"%sender.txn_id)
    return
  amt = float(params['mc_gross'])
  if not subscription and params.get("item_number",None):
    try:
      subscription = Subscription.objects.get(pk=params['item_number'],amount=amt)
    except Subscription.DoesNotExist:
      b = "Could not find subscription #%s for $%s and txn %s"%(params['item_number'],amt,sender.txn_id)
      mail_admins("Bad IPN: no subscription",b)
      return
  if not subscription:
    try:
      level = Level.objects.get(name=params.get('option_name1',''))
    except Level.DoesNotExist:
      b = "Could not find level \"%s\" for txn %s"%(params.get('option_name1',''),sender.txn_id)
      mail_admins("Bad IPN: no level",b)
      return
    try:
      product = Product.objects.get(unit_price=amt,level=level)
    except Product.DoesNotExist:
      b = "Could not find level product \"%s\" (cost $%s) for txn %s"
      mail_admins("Bad IPN: no product",b%(level,amt,sender.txn_id))
      return
    subscription = Subscription.objects.create(
      user=user,
      subscr_id=subscr_id,
      level=product.level,
      months=product.months,
      amount=amt
    )
    Flag.objects.filter(
      subscription__user=subscription.user,
      status__in=Flag.PAYMENT_ACTIONS
    ).update(status="paid")
    if not user.usercriterion_set.filter(criterion_id=settings.ORIENTATION_CRITERION_ID):
      # user has never been oriented, send welcome email and create fake safety
      user.send_welcome_email()

  status = Status.objects.create(
    transaction_id=sender.txn_id,
    subscription=subscription,
    paypalipn=sender,
    payment_method='paypal',
    amount=amt,
  )
  if not subscription.subscr_id:
    subscription.subscr_id = subscr_id
    subscription.save()
  # need to get subscription again because status forced it to recalculate
  subscription = status.subscription
  # clear out any subscription flags
  if subscription.owed <= 0:
    Flag.objects.filter(
      subscription=subscription,
      status__in=Flag.PAYMENT_ACTIONS
    ).update(status="paid")
Ejemplo n.º 13
0
from django.http import QueryDict

from course.models import Enrollment
from drop.models import Order, OrderPayment
from lablackey.utils import latin1_to_ascii
from paypal.standard.ipn.models import PayPalIPN

from decimal import Decimal
Order.objects.filter(pk__gt=3000).delete()
for enrollment in Enrollment.objects.exclude(transaction_ids__isnull=True):
    for txn_id in enrollment.transaction_ids.split("|"):
        if not txn_id:
            continue
        ipn = PayPalIPN.objects.filter(txn_id=txn_id)[0]
        order_payments = OrderPayment.objects.filter(transaction_id=txn_id)
        params = QueryDict(latin1_to_ascii(ipn.query))
        if order_payments:
            order = order_payments[0].order
        else:
            order = Order.objects.create(
                order_total=params['mc_gross'],
                order_subtotal=params['mc_gross'],
                user=enrollment.user,
            )
            order.created = enrollment.datetime
            order.updated = enrollment.datetime
            order.status = order.PAID
            order.save()
            order_payments = [
                OrderPayment.objects.create(
                    order=order,