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))
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"
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()) ]))
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"
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"
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
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
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', )
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())]))
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")
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,
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")
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,