def _new(self): # Do we allow account creation? if Config.get('account_creation'): """Create a new person submit. """ # Remove fields not in class results = self.form_result['person'] del results['password_confirm'] c.person = Person(**results) c.person.email_address = c.person.email_address.lower() meta.Session.add(c.person) #for sn in self.form_result['social_network']: # network = SocialNetwork.find_by_name(sn['name']) # if sn['account_name']: # c.person.social_networks[network] = sn['account_name'] meta.Session.commit() if Config.get('confirm_email_address', category='rego') == 'no': redirect_to(controller='person', action='confirm', confirm_hash=c.person.url_hash) else: email(c.person.email_address, render('/person/new_person_email.mako')) # return render('/person/thankyou.mako') return self.finish_login(c.person.email_address) else: return render('/not_allowed.mako')
def _edit(self, id): # We need to recheck auth in here so we can pass in the id if not h.auth.authorized(h.auth.Or(h.auth.is_same_zkpylons_submitter(id), h.auth.has_organiser_role)): # Raise a no_auth error h.auth.no_role() if not h.auth.authorized(h.auth.has_organiser_role): if c.proposal_editing == 'closed' and not h.auth.authorized(h.auth.has_late_submitter_role): return render("proposal/editing_closed.mako") elif c.proposal_editing == 'not_open': return render("proposal/editing_not_open.mako") c.proposal = Proposal.find_by_id(id) for key in self.form_result['proposal']: setattr(c.proposal, key, self.form_result['proposal'][key]) c.proposal.abstract = self.clean_abstract(c.proposal.abstract) c.person = self.form_result['person_to_edit'] if (c.person.id == h.signed_in_person().id or h.auth.authorized(h.auth.has_organiser_role)): for key in self.form_result['person']: setattr(c.person, key, self.form_result['person'][key]) p_edit = "and author" else: p_edit = "(but not author)" meta.Session.commit() if Config.get('proposal_update_email') != '': body = "Subject: %s Proposal Updated\n\nID: %d\nTitle: %s\nType: %s\nURL: %s" % (Config.get('event_name'), c.proposal.id, c.proposal.title, c.proposal.type.name.lower(), "http://" + Config.get('event_host') + h.url_for(action="view")) email(Config.get('proposal_update_email'), body) h.flash("Proposal %s edited!"%p_edit) return redirect_to('/proposal')
def silly_description(): adverb = random.choice(Config.get('silly_description', category='rego')['adverbs']) adjective = random.choice(Config.get('silly_description', category='rego')['adjectives']) noun = random.choice(Config.get('silly_description', category='rego')['nouns']) start = random.choice(Config.get('silly_description', category='rego')['starts']) if start == 'a' and adverb[0] in ['a', 'e', 'i', 'o', 'u']: start = 'an' desc = '%s %s %s %s' % (start, adverb, adjective, noun) descChecksum = silly_description_checksum(desc) return desc, descChecksum
def email(recipients, body): message = email_parser.Parser().parsestr(body.encode('utf-8')) addrs = [] # Get rid of 8-bit chars in the email address fields. for addr_header in email_addr_headers: addrs = message.get_all(addr_header) if not addrs or is_7bit(', '.join(addrs)): continue del message[addr_header] encoded_addrs = ', '.join([encode_addr(a) for a in addrs]) message[addr_header] = encoded_addrs # Get rid of 8-bit chars in the other message headers. for header_name in set(message.keys()): headers = message.get_all(header_name) if is_7bit(''.join(headers)): continue del message[header_name] for utf_header in headers: if is_7bit(''.join(headers)): ascii_header = utf_header else: ascii_header = encode_header(utf_header) message[header_name] = ascii_header # If the body isn't plain ascii, encode it as well. if not message.get_charset(): email_body = message.get_payload() if not is_7bit(email_body): message.set_charset('utf-8') # Default the recipients to the 'To', etc headers in the email. if not recipients: addrs = [] for recipient_header in recipient_addr_headers: addrs.extend(message.get_all(recipient_header, [])) addrs = email_utils.getaddresses(addrs) recipients = [email_utils.formataddr(a) for a in addrs] elif type(recipients) in (str, unicode): recipients = [recipients] # # If bcc_email is set, send it there as well. # if Config.get('bcc_email'): recipients.append(Config.get('bcc_email')) # send the email using smtp try: s = smtplib.SMTP(config['smtp_server']) s.sendmail(Config.get('contact_email'), recipients, message.as_string()) s.quit() except Exception as e: h.flash( 'Unable to send email. ' 'Please contact %s' % Config.get('webmaster_email'), 'error' ) traceback.print_exc()
def sales_tax(amount): """ Calculate the sales tax that for the supplied amount. """ if Config.get('sales_tax_multiplier') != "": sales_tax = int(amount * Config.get('sales_tax_multiplier')) elif Config.get('sales_tax_divisor') != "": sales_tax = int(amount / Config.get('sales_tax_divisor')) else: # wtf? sales_tax = 0 return sales_tax
def _redirect_user_optimally(self): redirect_location = session.get('redirect_to', None) if redirect_location: del session['redirect_to'] session.save() redirect_to(str(redirect_location)) if Config.get('conference_status') == 'open': redirect_to(controller='registration', action='new') elif Config.get('cfp_status') == 'open': redirect_to(controller='proposal') redirect_to('home')
def silly_description(): adverb = random.choice( Config.get('silly_description', category='rego')['adverbs']) adjective = random.choice( Config.get('silly_description', category='rego')['adjectives']) noun = random.choice( Config.get('silly_description', category='rego')['nouns']) start = random.choice( Config.get('silly_description', category='rego')['starts']) if start == 'a' and adverb[0] in ['a', 'e', 'i', 'o', 'u']: start = 'an' desc = '%s %s %s %s' % (start, adverb, adjective, noun) descChecksum = silly_description_checksum(desc) return desc, descChecksum
def filename(self, scale): start_timestamp = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") date_day = start_timestamp + datetime.timedelta(self.day) date_str = date_day.strftime("%Y%m%d") return "%s-%08d-%d-%s-%s" % (date_str, self.person_id, self.entry_id, scale, self.image_name)
def photo(self, filename=None): if not filename: abort(404) if "/" in filename or filename.startswith("."): abort(403) open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") days_open = (datetime.date.today() - open_date.date()).days photo = PhotoCompEntry.from_filename(filename) # # If the entries haven't closed for this day then only the logged in # person or an organiser can see it. # # TODO: A judge can see it too. # id_str = str(photo.person_id) if days_open <= photo.day: if not h.auth.authorized(h.auth.Or(h.auth.is_same_zkpylons_user(photo.person_id), h.auth.has_organiser_role)): abort(403) # # They can have it. # try: handle = open(photo.pathname(tuple(photo.scales)[0]), "rb") except EnvironmentError, e: if e.errno != errno.ENOENT: raise abort(404)
def photo(self, filename=None): if not filename: abort(404) if "/" in filename or filename.startswith("."): abort(403) open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") days_open = (datetime.date.today() - open_date.date()).days photo = PhotoCompEntry.from_filename(filename) # # If the entries haven't closed for this day then only the logged in # person or an organiser can see it. # # TODO: A judge can see it too. # id_str = str(photo.person_id) if days_open <= photo.day: if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_user(photo.person_id), h.auth.has_organiser_role)): abort(403) # # They can have it. # try: handle = open(photo.pathname(tuple(photo.scales)[0]), "rb") except EnvironmentError, e: if e.errno != errno.ENOENT: raise abort(404)
def void(self, id): if not h.auth.authorized(h.auth.Or(h.auth.is_same_zkpylons_attendee(id), h.auth.has_organiser_role)): # Raise a no_auth error h.auth.no_role() c.invoice = Invoice.find_by_id(id, True) if c.invoice.is_void: h.flash("Invoice was already voided.") return redirect_to(action='view', id=c.invoice.id) elif len(c.invoice.payment_received) and h.auth.authorized(h.auth.has_organiser_role): h.flash("Invoice has a payment applied to it, do you want to " + h.link_to('Refund', h.url_for(action='refund')) + " instead?") return redirect_to(action='view', id=c.invoice.id) elif len(c.invoice.payment_received): h.flash("Cannot void a paid invoice.") return redirect_to(action='view', id=c.invoice.id) elif h.auth.authorized(h.auth.has_organiser_role): c.invoice.void = "Administration Change" meta.Session.commit() h.flash("Invoice was voided.") return redirect_to(action='view', id=c.invoice.id) else: c.invoice.void = "User cancellation" c.person = c.invoice.person meta.Session.commit() email(Config.get('contact_email'), render('/invoice/user_voided.mako')) h.flash("Previous invoice was voided.") return redirect_to(controller='registration', action='pay', id=c.person.registration.id)
def void(self, id): if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_attendee(id), h.auth.has_organiser_role)): # Raise a no_auth error h.auth.no_role() c.invoice = Invoice.find_by_id(id, True) if c.invoice.is_void: h.flash("Invoice was already voided.") return redirect_to(action='view', id=c.invoice.id) elif len(c.invoice.payment_received) and h.auth.authorized( h.auth.has_organiser_role): h.flash("Invoice has a payment applied to it, do you want to " + h.link_to('Refund', h.url_for(action='refund')) + " instead?") return redirect_to(action='view', id=c.invoice.id) elif len(c.invoice.payment_received): h.flash("Cannot void a paid invoice.") return redirect_to(action='view', id=c.invoice.id) elif h.auth.authorized(h.auth.has_organiser_role): c.invoice.void = "Administration Change" meta.Session.commit() h.flash("Invoice was voided.") return redirect_to(action='view', id=c.invoice.id) else: c.invoice.void = "User cancellation" c.person = c.invoice.person meta.Session.commit() email(Config.get('contact_email'), render('/invoice/user_voided.mako')) h.flash("Previous invoice was voided.") return redirect_to(controller='registration', action='pay', id=c.person.registration.id)
def validate_python(self, values, state): assertion = values['assertion'] audience = h.url_for(qualified=True, controller='home').strip("/") page = urllib2.urlopen('https://verifier.login.persona.org/verify', urllib.urlencode({ "assertion": assertion, "audience": audience})) data = json.load(page) if data['status'] == 'okay': c.email = data['email'] c.person = Person.find_by_email(c.email) if c.person is None: if not Config.get('account_creation'): error_message = "Your sign-in details are incorrect; try the 'Forgotten your password' link below." message = "Login failed" error_dict = {'email_address': error_message} raise Invalid(message, values, state, error_dict=error_dict) # Create a new account for this email address c.person = Person() c.person.email_address = data['email'] c.person.activated = True meta.Session.add(c.person) meta.Session.commit() if not c.person.activated: # Persona returns verified emails only, so might as well confirm this one... c.person.activated = True meta.Session.commit()
def upload(self, id=None): # # Only an organiser can upload someone elses photos. # if not h.auth.authorized(h.auth.Or(h.auth.is_same_zkpylons_user(id), h.auth.has_organiser_role)): h.auth.no_role() open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") days_open = (datetime.date.today() - open_date.date()).days photo_db = PhotoCompEntry.read_db() if len(VALID_EXTENSIONS) == 1: valid_extensions = VALID_EXTENSIONS[0] else: valid_extensions = ', '.join(VALID_EXTENSIONS[:-1]) + " or " + VALID_EXTENSIONS[-1] # # See what photos he has given us. The an organiser can upload # anything without restrictions. # if h.auth.authorized(h.auth.has_organiser_role): day_range = range(0, DAYS_OPEN) else: day_range = range(max(days_open, 0), DAYS_OPEN) for day in day_range: for entry_id in range(len(ENTRY_NAMES)): old_photo = PhotoCompEntry.get(photo_db, int(id), day, entry_id) photo_field_name = 'photo-%d-%d' % (day, entry_id) delete_field_name = 'delete-%d-%d' % (day, entry_id) if hasattr(request.POST[photo_field_name], 'value'): image_data = request.POST[photo_field_name].value image_name = request.POST[photo_field_name].filename if len(image_data) > MAX_IMAGE_SIZE*1024*1024: h.flash("%s is larger than %dMib" % (image_name, MAX_IMAGE_SIZE)) continue toks = list(os.path.splitext(os.path.basename(image_name))) if toks[0].upper() == toks[0]: toks[0] = toks[0].lower() toks[1] = toks[1].lower() if not toks[1][1:] in VALID_EXTENSIONS: h.flash("%s doesn't end in %s." % (image_name, valid_extensions)) continue image_file = cStringIO.StringIO(image_data) try: image = Image.open(image_file) image.load() except: h.flash("%s doesn't look like a valid image" % image_name) continue if image.format != "JPEG": h.flash("%s isn't a JPEG image" % image_name) continue new_image_name = toks[0] + toks[1] if old_photo: old_photo.delete(photo_db) new_photo = PhotoCompEntry(int(id), day, entry_id, new_image_name) new_photo.write_orig(image_data) new_photo.add(photo_db) elif delete_field_name in request.POST: if old_photo: old_photo.delete(photo_db) redirect_to(action="edit", id=id)
def __before__(self, **kwargs): c.funding_types = FundingType.find_all() c.form_fields = { 'funding.why_attend': 'Why would you like to attend ' + Config.get('event_name'), 'funding.how_contribute': 'How do you contribute to the Open Source community', 'funding.male': 'What is your gender', 'funding.financial_circumstances': 'What are your financial circumstances', }
def initialise_file_paths(): # Should be called after db is initialised if 'enabled_theme' not in file_paths: enabled_theme = Config.get('theme') file_paths['enabled_theme'] = os.path.join(file_paths['theme_root'], enabled_theme) for k in file_paths: file_paths[k] = re.sub('\$enabled_theme', file_paths['enabled_theme'], file_paths[k]) return file_paths
def ical(self): c.schedule_collection = Schedule.find_all() ical = vobject.iCalendar() for schedule in c.schedule_collection: if not schedule.time_slot.heading: event = ical.add('vevent') event.add('uid').value = str(schedule.id) + '@' + Config.get('event_host') # Created tz = timezone(Config.get('time_zone')) event.add('created').value = schedule.creation_timestamp.replace(tzinfo=tz) # Last Modified event.add('dtstamp').value = schedule.last_modification_timestamp.replace(tzinfo=tz) event.add('last-modified').value = schedule.last_modification_timestamp.replace(tzinfo=tz) # Start and End Time event.add('dtstart').value = schedule.time_slot.start_time.replace(tzinfo=tz) event.add('dtend').value = schedule.time_slot.end_time.replace(tzinfo=tz) # Title and Author (need to add Author here) event.add('summary').value = schedule.event.computed_title() + '. ' + h.list_to_string(schedule.event.computed_speakers()) # Abstract, if we have one event.add('description').value = schedule.event.computed_abstract() # Add a URL if schedule.event.proposal: event.add('url').value = h.url_for(qualified=True, controller='schedule', action='view_talk', id=schedule.event.proposal.id) elif not (schedule.event.url is None or schedule.event.url == ''): if schedule.event.url.startswith('https://') or schedule.event.url.startswith('http://'): event.add('url').value = h.url_for(str(schedule.event.url)) else: event.add('url').value = h.url_for(str(schedule.event.url), qualified=True) concurrent_schedules = schedule.event.schedule_by_time_slot(schedule.time_slot) for concurrent_schedule in concurrent_schedules: if concurrent_schedule != schedule: if concurrent_schedule in c.schedule_collection: c.schedule_collection.remove(concurrent_schedule) locations = [concurrent_schedule.location.display_name for concurrent_schedule in concurrent_schedules] event.add('location').value = h.list_to_string(locations) response.charset = 'utf8' response.headers['content-type'] = 'text/calendar; charset=utf8' response.headers.add('content-transfer-encoding', 'binary') response.headers.add('Pragma', 'cache') response.headers.add('Cache-Control', 'max-age=3600,public') return ical.serialize()
def check_for_incomplete_profile(person): if not person.firstname or not person.lastname or not person.i_agree or ( Config.get('personal_info', category='rego')['home_address'] == 'yes' and (not person.address1 or not person.city or not person.postcode)): if not session.get('redirect_to', None): session['redirect_to'] = request.path_info session.save() redirect_to(controller='person', action='finish_signup', id=person.id)
def pdf(self, id): c.fulfilment_group = FulfilmentGroup.find_by_id(id, True) xml_s = render('/fulfilment_group/pdf.mako') xsl_f = app_globals.mako_lookup.get_template('/fulfilment_group/pdf.xsl').filename pdf_data = pdfgen.generate_pdf(xml_s, xsl_f) filename = Config.get('event_shortname') + '_' + str(c.fulfilment_group.id) + '.pdf' return pdfgen.wrap_pdf_response(pdf_data, filename)
def index(self): c.DAYS_OPEN = DAYS_OPEN open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") days_open = (datetime.date.today() - c.open_date.date()).days photo_db = PhotoCompEntry.read_db() photos = [ photo for days in photo_db.values() for entries in days for photo in entries if photo is not None and photo.day < days_open ] c.no_photos = not photos day_filter = request.GET.get('day', 'All') if day_filter and day_filter != 'All': photos = [p for p in photos if str(p.day) == day_filter] person_filter = request.GET.get('person', 'All') if person_filter and person_filter != 'All': photos = [p for p in photos if str(p.person_id) == person_filter] submitted = request.GET.get('s', None) randomise = not submitted or 'randomise' in request.GET if randomise: random.shuffle(photos) else: photos.sort(key=lambda p: (p.day, p.person_id, p.entry_id)) person_map = {} for photo in photos: photo.write_scaled() person_map[photo.person_id] = None c.all_person = [] for person_id in person_map: person = Person.find_by_id(person_id) person_map[person_id] = person c.all_person.append(person) c.all_person.sort(key=lambda person: person.fullname.lower()) c.photos = photos def photo_title(photo): return "%s %s, %s entry %s, %s" % ( person_map[photo.person_id].firstname, person_map[photo.person_id].lastname, (c.open_date + datetime.timedelta(photo.day)).strftime('%A'), ENTRY_NAMES[photo.entry_id], photo.image_name, ) c.photo_title = photo_title field_values = { 'day': day_filter, 'person': person_filter, } if randomise: field_values['randomise'] = '1' if submitted == 'Full Screen' and photos: html = render('/photocomp/index-fullscreen.mako') else: html = render('/photocomp/index.mako') return htmlfill.render(html, field_values)
def from_filename(cls, filename): toks = filename.split("-", 4) open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") photo_date = datetime.datetime(*time.strptime(toks[0], "%Y%m%d")[:3]) day = (photo_date.date() - open_date.date()).days person_id = int(toks[1], 10) entry_id = int(toks[2], 10) image_name = toks[4] photo = cls(person_id, day, entry_id, image_name) photo.scales.add(toks[3]) return photo
def index(self): c.DAYS_OPEN = DAYS_OPEN open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") days_open = (datetime.date.today() - c.open_date.date()).days photo_db = PhotoCompEntry.read_db() photos = [ photo for days in photo_db.values() for entries in days for photo in entries if photo is not None and photo.day < days_open] c.no_photos = not photos day_filter = request.GET.get('day', 'All') if day_filter and day_filter != 'All': photos = [p for p in photos if str(p.day) == day_filter] person_filter = request.GET.get('person', 'All') if person_filter and person_filter != 'All': photos = [p for p in photos if str(p.person_id) == person_filter] submitted = request.GET.get('s', None) randomise = not submitted or 'randomise' in request.GET if randomise: random.shuffle(photos) else: photos.sort(key=lambda p: (p.day, p.person_id, p.entry_id)) person_map = {} for photo in photos: photo.write_scaled() person_map[photo.person_id] = None c.all_person = [] for person_id in person_map: person = Person.find_by_id(person_id) person_map[person_id] = person c.all_person.append(person) c.all_person.sort(key=lambda person: person.fullname.lower()) c.photos = photos def photo_title(photo): return "%s %s, %s entry %s, %s" % ( person_map[photo.person_id].firstname, person_map[photo.person_id].lastname, (c.open_date + datetime.timedelta(photo.day)).strftime('%A'), ENTRY_NAMES[photo.entry_id], photo.image_name,) c.photo_title = photo_title field_values = { 'day': day_filter, 'person': person_filter, } if randomise: field_values['randomise'] = '1' if submitted == 'Full Screen' and photos: html = render('/photocomp/index-fullscreen.mako') else: html = render('/photocomp/index.mako') return htmlfill.render(html, field_values)
def _edit(self, id): # We need to recheck auth in here so we can pass in the id if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_submitter(id), h.auth.has_organiser_role)): # Raise a no_auth error h.auth.no_role() if not h.auth.authorized(h.auth.has_organiser_role): if c.proposal_editing == 'closed' and not h.auth.authorized( h.auth.has_late_submitter_role): return render("proposal/editing_closed.mako") elif c.proposal_editing == 'not_open': return render("proposal/editing_not_open.mako") c.proposal = Proposal.find_by_id(id) for key in self.form_result['proposal']: setattr(c.proposal, key, self.form_result['proposal'][key]) c.proposal.abstract = self.clean_abstract(c.proposal.abstract) c.person = self.form_result['person_to_edit'] if (c.person.id == h.signed_in_person().id or h.auth.authorized(h.auth.has_organiser_role)): for key in self.form_result['person']: setattr(c.person, key, self.form_result['person'][key]) p_edit = "and author" else: p_edit = "(but not author)" meta.Session.commit() if Config.get('proposal_update_email') != '': body = "Subject: %s Proposal Updated\n\nID: %d\nTitle: %s\nType: %s\nURL: %s" % ( Config.get('event_name'), c.proposal.id, c.proposal.title, c.proposal.type.name.lower(), "http://" + Config.get('event_host') + h.url_for(action="view")) email(Config.get('proposal_update_email'), body) h.flash("Proposal %s edited!" % p_edit) return redirect_to('/proposal')
def view_talk(self, id): try: c.day = request.GET['day'] except: c.day = 'all' try: c.talk = Proposal.find_accepted_by_id(id) except: c.talk_id = id c.webmaster_email = Config.get('webmaster_email') return render('/schedule/invalid_talkid.mako') return render('/schedule/table_view.mako')
def pdf(self, id): if not h.auth.authorized(h.auth.Or(h.auth.is_same_zkpylons_attendee(id), h.auth.has_organiser_role, h.auth.has_unique_key())): # Raise a no_auth error h.auth.no_role() c.invoice = Invoice.find_by_id(id, True) xml_s = render('/invoice/pdf.mako') xsl_f = get_path('zk_root') + '/zkpylons/templates/invoice/pdf.xsl' pdf_data = pdfgen.generate_pdf(xml_s, xsl_f) filename = Config.get('event_shortname') + '_' + str(c.invoice.id) + '.pdf' return pdfgen.wrap_pdf_response(pdf_data, filename)
def new(self): # Do we allow account creation? if Config.get('account_creation'): """Create a new person form. """ if h.signed_in_person(): h.flash("You're already logged in") redirect_to('home') defaults = { 'person.country': 'AUSTRALIA', } if Config.get('personal_info', category='rego')['home_address'] == 'no': defaults['person.address1'] = 'not available' defaults['person.city'] = 'not available' defaults['person.postcode'] = 'not available' c.social_networks = SocialNetwork.find_all() form = render('/person/new.mako') return htmlfill.render(form, defaults) else: return render('/not_allowed.mako')
def generate_request(fields): xml_request = "<GenerateRequest>" xml_request += "<PxPayUserId>" + Config.get('paymentgateway_userid') + "</PxPayUserId>" xml_request += "<PxPayKey>" + Config.get('paymentgateway_secretkey') + "</PxPayKey>" xml_request += "<AmountInput>" + fields['amount'] + "</AmountInput>" xml_request += "<CurrencyInput>" + currency + "</CurrencyInput>" xml_request += "<MerchantReference>INV" + str(fields['invoice_id']) + "</MerchantReference>" xml_request += "<EmailAddress></EmailAddress>" xml_request += "<TxnData1>" + fields['client_ip'] + "</TxnData1>" xml_request += "<TxnData2>" + fields['email_address'] + "</TxnData2>" xml_request += "<TxnData3></TxnData3>" xml_request += "<TxnType>Purchase</TxnType>" xml_request += "<TxnId>PAY" + str(fields['payment_id']) + "</TxnId>" xml_request += "<EnableAddBillCard>0</EnableAddBillCard>" xml_request += "<UrlSuccess>" + fields['return_url'] + "</UrlSuccess>" xml_request += "<UrlFail>" + fields['return_url'] + "</UrlFail>" xml_request += "</GenerateRequest>" req = urllib2.Request(pxpay_url, xml_request) xml_response = minidom.parse(urllib2.urlopen(req)) request_node = xml_response.getElementsByTagName("Request")[0] valid = request_node.getAttribute("valid") return valid, get_node_value(request_node, 'URI')
def pdf(self, id): if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_attendee(id), h.auth.has_organiser_role, h.auth.has_unique_key())): # Raise a no_auth error h.auth.no_role() c.invoice = Invoice.find_by_id(id, True) xml_s = render('/invoice/pdf.mako') xsl_f = get_path('zk_root') + '/zkpylons/templates/invoice/pdf.xsl' pdf_data = pdfgen.generate_pdf(xml_s, xsl_f) filename = Config.get('event_shortname') + '_' + str( c.invoice.id) + '.pdf' return pdfgen.wrap_pdf_response(pdf_data, filename)
def edit(self, id=None): # # Helpfully redirect to the correct URL. # if id is None: return redirect_to(h.url_for(id=h.signed_in_person().id)) # # Only an organiser can edit someone elses photos. # if not h.auth.authorized(h.auth.Or(h.auth.is_same_zkpylons_user(id), h.auth.has_organiser_role)): h.auth.no_role() person_id = int(id, 10) c.open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") c.days_open = (datetime.date.today() - c.open_date.date()).days photo_db = PhotoCompEntry.read_db() c.photo = lambda day, entry: PhotoCompEntry.get(photo_db, person_id, day, entry) c.is_organiser = h.auth.authorized(h.auth.has_organiser_role) c.DAYS_OPEN = DAYS_OPEN c.ENTRY_NAMES = ENTRY_NAMES return render('/photocomp/edit.mako')
def edit(self, id=None): # # Helpfully redirect to the correct URL. # if id is None: return redirect_to(h.url_for(id=h.signed_in_person().id)) # # Only an organiser can edit someone elses photos. # if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_user(id), h.auth.has_organiser_role)): h.auth.no_role() person_id = int(id, 10) c.open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") c.days_open = (datetime.date.today() - c.open_date.date()).days photo_db = PhotoCompEntry.read_db() c.photo = lambda day, entry: PhotoCompEntry.get( photo_db, person_id, day, entry) c.is_organiser = h.auth.authorized(h.auth.has_organiser_role) c.DAYS_OPEN = DAYS_OPEN c.ENTRY_NAMES = ENTRY_NAMES return render('/photocomp/edit.mako')
def check_for_incomplete_profile(person): if not person.firstname or not person.lastname or not person.i_agree or (Config.get('personal_info', category='rego')['home_address'] == 'yes' and (not person.address1 or not person.city or not person.postcode)): if not session.get('redirect_to', None): session['redirect_to'] = request.path_info session.save() redirect_to(controller='person', action='finish_signup', id=person.id)
def validate_python(self, value, state): person = Person.find_by_email(value) if person is None: msg = 'Your supplied e-mail does not exist in our database. Please try again or if you continue to have problems, contact %s.' % Config.get('contact_email') raise Invalid(msg, value, state, error_dict={'email_address': msg})
def __init__(self, *args): c.cfp_status = Config.get('cfp_status') c.cfmini_status = Config.get('cfmini_status') c.proposal_editing = Config.get('proposal_editing') c.cfp_hide_assistance_info = Config.get('cfp_hide_assistance_info') c.cfp_hide_scores = Config.get('cfp_hide_scores')
def __init__(self, *args): c.cfp_status = Config.get('cfp_status') c.cfmini_status = Config.get('cfmini_status') c.proposal_editing = Config.get('proposal_editing')
def process_response(fields): if fields['userid'] != Config.get('paymentgateway_userid'): return None, ['Invalid userid in redirect from payment gateway: ' + fields['userid'] ] xml_request = "<ProcessResponse>" xml_request += "<PxPayUserId>" + Config.get('paymentgateway_userid') + "</PxPayUserId>" xml_request += "<PxPayKey>" + Config.get('paymentgateway_secretkey') + "</PxPayKey>" xml_request += "<Response>" + fields['result'] + "</Response>" xml_request += "</ProcessResponse>" req = urllib2.Request(pxpay_url, xml_request) xml_response = minidom.parse(urllib2.urlopen(req)) response_node = xml_response.getElementsByTagName("Response")[0] valid = response_node.getAttribute("valid") if valid != '1': return None, ['Invalid response from payment gateway: ' + get_node_value(response_node, 'ResponseText')] currency_request = get_node_value(response_node, 'CurrencyInput') transaction_type = get_node_value(response_node, 'TxnType') response = { 'approved' : False, 'success_code' : get_node_value(response_node, 'Success'), 'amount_paid' : get_node_value(response_node, 'AmountSettlement'), 'auth_code' : get_node_value(response_node, 'AuthCode'), 'card_name' : get_node_value(response_node, 'CardHolderName'), 'card_type' : get_node_value(response_node, 'CardName'), 'card_number' : get_node_value(response_node, 'CardNumber'), 'card_expiry' : get_node_value(response_node, 'DateExpiry'), 'card_mac' : get_node_value(response_node, 'TxnMac'), 'gateway_ref' : get_node_value(response_node, 'DpsTxnRef'), 'response_text' : get_node_value(response_node, 'ResponseText'), 'currency_used' : get_node_value(response_node, 'CurrencySettlement'), 'invoice_id' : get_node_value(response_node, 'MerchantReference'), 'client_ip_zookeepr' : get_node_value(response_node, 'TxnData1'), 'client_ip_gateway' : get_node_value(response_node, 'ClientInfo'), 'payment_id' : get_node_value(response_node, 'TxnId'), 'email_address' : get_node_value(response_node, 'TxnData2'), } validation_errors = [] # Reformat a few fields for zkpylons if response['amount_paid'] is not None: response['amount_paid'] = int(float(response['amount_paid']) * 100) if response['payment_id'] is not None: if 'PAY' == response['payment_id'][0:3]: response['payment_id'] = int(response['payment_id'][3:]) else: validation_errors.append('Wrong format in the payment ID field: ' + response['payment_id']) if response['invoice_id'] is not None: if 'INV' == response['invoice_id'][0:3]: response['invoice_id'] = int(response['invoice_id'][3:]) else: validation_errors.append('Wrong format in the invoice ID field: ' + response['invoice_id']) # Indicate whether or not the payment gateway has approved this transaction if response['success_code'] != '0': response['approved'] = True else: validation_errors.append('Transaction declined or unsuccessful (success_code=' + response['success_code'] + ')') # Validate the fields specific to the payment gateway (which we do not store) if transaction_type != 'Purchase': validation_errors.append('Invalid transaction type: ' + response['transaction_type']) if currency_request != currency: validation_errors.append('An invalid currency type was requested: ' + response['currency_request']) return response, validation_errors
def badge_pdf(self, id): pdf_data = self._badge(id) filename = Config.get('event_shortname') + '_' + str( c.fulfilment.id) + '.pdf' return pdfgen.wrap_pdf_response(pdf_data, filename)
class PaymentController(BaseController): """This controller receives payment advice from the payment gateway. the url /payment/new receives the advice """ @authorize(h.auth.has_organiser_role) def index(self): c.payment_collection = Payment.find_all() return render('/payment/list.mako') @authorize(h.auth.is_valid_user) def view(self, id): payment = Payment.find_by_id(id, abort_404=True) c.person = payment.invoice.person if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_user(c.person.id), h.auth.has_organiser_role)): # Raise a no_auth error h.auth.no_role() c.is_organiser = False if h.auth.authorized(h.auth.has_organiser_role): c.is_organiser = True c.payment = PaymentReceived.find_by_payment(payment.id) c.validation_errors = [] if c.payment is not None and c.payment.validation_errors is not None and len( c.payment.validation_errors) > 0: c.validation_errors = c.payment.validation_errors.split(';') same_invoice = PaymentReceived.find_by_invoice(payment.invoice.id) same_email = PaymentReceived.find_by_email(c.person.email_address) if c.payment is not None: same_invoice = same_invoice.filter("payment_id <> " + str(payment.id)) same_email = same_email.filter("payment_id <> " + str(payment.id)) c.related_payments = same_invoice.union(same_email) return render('/payment/view.mako') # No authentication because it's called directly by the payment gateway def new(self): schema = SecurePayPingSchema() try: form_result = schema.to_python(request.params) except validators.Invalid, error: return 'Invalid: %s' % error payment = None c.person = None fields = form_result c.response = { 'payment_id': fields['payment_id'], 'invoice_id': fields['invoice_id'], 'success_code': fields['summary_code'], 'amount_paid': fields['response_amount'], 'currency_used': fields['currency'], 'card_name': fields['card_name'], 'card_type': fields['card_type'], 'card_number': fields['card_number'], 'card_expiry': fields['card_number'], 'card_mac': fields['card_mac'], 'auth_code': fields['response_code'], 'gateway_ref': fields['bank_reference'], 'response_text': fields['response_text'], 'client_ip_gateway': fields['remote_ip'], 'client_ip_zookeepr': request.environ.get('REMOTE_ADDR'), 'email_address': fields['receipt_address'] } if 'Approved' in c.response[ 'response_text'] or 'success' in c.response['response_text']: c.response['approved'] = True else: c.response['approved'] = False validation_errors = [] if c.response is None: abort(500, ''.join(validation_errors)) else: # Make sure the same browser created the zkpylons payment object and paid by credit card #if c.response['client_ip_gateway'] != c.response['client_ip_zookeepr']: #validation_errors.append('Mismatch in IP addresses: zkpylons=' + c.response['client_ip_zookeepr'] + ' gateway=' + c.response['client_ip_gateway']) # Get the payment object associated with this transaction payment = Payment.find_by_id(c.response['payment_id']) if payment is None: validation_errors.append( 'Invalid payment ID from the payment gateway') else: c.person = payment.invoice.person # Check whether a payment has already been received for this payment object received = PaymentReceived.find_by_payment(payment.id) if received is not None: # Ignore repeat payment return redirect_to(action='view', id=payment.id) # Extra validation if c.response['amount_paid'] != payment.amount: validation_errors.append( 'Mismatch between amounts paid and invoiced') if c.response['invoice_id'] != payment.invoice.id: validation_errors.append( 'Mismatch between returned invoice ID and payment object') #if c.response['email_address'] != pxpay.munge_email(payment.invoice.person.email_address): # validation_errors.append('Mismatch between returned email address and invoice object') if not c.person.is_from_common_country(): if c.person.country: validation_errors.append('Uncommon country: ' + c.person.country) else: validation_errors.append('Unknown country') c.pr = PaymentReceived(**c.response) c.pr.validation_errors = ';'.join(validation_errors) meta.Session.add(c.pr) meta.Session.commit() if len(validation_errors) > 0 and c.response['approved']: # Suspiciously approved transaction which needs to be checked manually email(Config.get('contact_email'), render('/payment/suspicious_payment.mako')) if c.person is not None: email(c.person.email_address, render('/payment/response.mako')) # OK we now have a valid transaction, we redirect the user to the view page # so they can see if their transaction was accepted or declined return redirect_to(action='view', id=payment.id)
def full_url_for(*args, **kwargs): return os.path.join(Config.get('event_permalink'), url_for(*args, **kwargs))
def __init__(self, *args): c.funding_status = Config.get('funding_status') c.funding_editing = Config.get('funding_editing')
def badge_pdf(self, id): pdf_data = self._badge(id) filename = Config.get("event_shortname") + "_" + str(c.fulfilment.id) + ".pdf" return pdfgen.wrap_pdf_response(pdf_data, filename)
def process_response(fields): if fields['userid'] != Config.get('paymentgateway_userid'): return None, [ 'Invalid userid in redirect from payment gateway: ' + fields['userid'] ] xml_request = "<ProcessResponse>" xml_request += "<PxPayUserId>" + Config.get( 'paymentgateway_userid') + "</PxPayUserId>" xml_request += "<PxPayKey>" + Config.get( 'paymentgateway_secretkey') + "</PxPayKey>" xml_request += "<Response>" + fields['result'] + "</Response>" xml_request += "</ProcessResponse>" req = urllib2.Request(pxpay_url, xml_request) xml_response = minidom.parse(urllib2.urlopen(req)) response_node = xml_response.getElementsByTagName("Response")[0] valid = response_node.getAttribute("valid") if valid != '1': return None, [ 'Invalid response from payment gateway: ' + get_node_value(response_node, 'ResponseText') ] currency_request = get_node_value(response_node, 'CurrencyInput') transaction_type = get_node_value(response_node, 'TxnType') response = { 'approved': False, 'success_code': get_node_value(response_node, 'Success'), 'amount_paid': get_node_value(response_node, 'AmountSettlement'), 'auth_code': get_node_value(response_node, 'AuthCode'), 'card_name': get_node_value(response_node, 'CardHolderName'), 'card_type': get_node_value(response_node, 'CardName'), 'card_number': get_node_value(response_node, 'CardNumber'), 'card_expiry': get_node_value(response_node, 'DateExpiry'), 'card_mac': get_node_value(response_node, 'TxnMac'), 'gateway_ref': get_node_value(response_node, 'DpsTxnRef'), 'response_text': get_node_value(response_node, 'ResponseText'), 'currency_used': get_node_value(response_node, 'CurrencySettlement'), 'invoice_id': get_node_value(response_node, 'MerchantReference'), 'client_ip_zookeepr': get_node_value(response_node, 'TxnData1'), 'client_ip_gateway': get_node_value(response_node, 'ClientInfo'), 'payment_id': get_node_value(response_node, 'TxnId'), 'email_address': get_node_value(response_node, 'TxnData2'), } validation_errors = [] # Reformat a few fields for zkpylons if response['amount_paid'] is not None: response['amount_paid'] = int(float(response['amount_paid']) * 100) if response['payment_id'] is not None: if 'PAY' == response['payment_id'][0:3]: response['payment_id'] = int(response['payment_id'][3:]) else: validation_errors.append('Wrong format in the payment ID field: ' + response['payment_id']) if response['invoice_id'] is not None: if 'INV' == response['invoice_id'][0:3]: response['invoice_id'] = int(response['invoice_id'][3:]) else: validation_errors.append('Wrong format in the invoice ID field: ' + response['invoice_id']) # Indicate whether or not the payment gateway has approved this transaction if response['success_code'] != '0': response['approved'] = True else: validation_errors.append( 'Transaction declined or unsuccessful (success_code=' + response['success_code'] + ')') # Validate the fields specific to the payment gateway (which we do not store) if transaction_type != 'Purchase': validation_errors.append('Invalid transaction type: ' + response['transaction_type']) if currency_request != currency: validation_errors.append('An invalid currency type was requested: ' + response['currency_request']) return response, validation_errors
def upload(self, id=None): # # Only an organiser can upload someone elses photos. # if not h.auth.authorized( h.auth.Or(h.auth.is_same_zkpylons_user(id), h.auth.has_organiser_role)): h.auth.no_role() open_date = datetime.strptime(Config.get("date"), "%Y-%m-%dT%H:%M:%S") days_open = (datetime.date.today() - open_date.date()).days photo_db = PhotoCompEntry.read_db() if len(VALID_EXTENSIONS) == 1: valid_extensions = VALID_EXTENSIONS[0] else: valid_extensions = ', '.join( VALID_EXTENSIONS[:-1]) + " or " + VALID_EXTENSIONS[-1] # # See what photos he has given us. The an organiser can upload # anything without restrictions. # if h.auth.authorized(h.auth.has_organiser_role): day_range = range(0, DAYS_OPEN) else: day_range = range(max(days_open, 0), DAYS_OPEN) for day in day_range: for entry_id in range(len(ENTRY_NAMES)): old_photo = PhotoCompEntry.get(photo_db, int(id), day, entry_id) photo_field_name = 'photo-%d-%d' % (day, entry_id) delete_field_name = 'delete-%d-%d' % (day, entry_id) if hasattr(request.POST[photo_field_name], 'value'): image_data = request.POST[photo_field_name].value image_name = request.POST[photo_field_name].filename if len(image_data) > MAX_IMAGE_SIZE * 1024 * 1024: h.flash("%s is larger than %dMib" % (image_name, MAX_IMAGE_SIZE)) continue toks = list(os.path.splitext(os.path.basename(image_name))) if toks[0].upper() == toks[0]: toks[0] = toks[0].lower() toks[1] = toks[1].lower() if not toks[1][1:] in VALID_EXTENSIONS: h.flash("%s doesn't end in %s." % (image_name, valid_extensions)) continue image_file = cStringIO.StringIO(image_data) try: image = Image.open(image_file) image.load() except: h.flash("%s doesn't look like a valid image" % image_name) continue if image.format != "JPEG": h.flash("%s isn't a JPEG image" % image_name) continue new_image_name = toks[0] + toks[1] if old_photo: old_photo.delete(photo_db) new_photo = PhotoCompEntry(int(id), day, entry_id, new_image_name) new_photo.write_orig(image_data) new_photo.add(photo_db) elif delete_field_name in request.POST: if old_photo: old_photo.delete(photo_db) redirect_to(action="edit", id=id)
def badge_pdf(self, id): pdf_data = self._badge(id) filename = Config.get('event_shortname') + '_' + str(c.fulfilment.id) + '.pdf' return pdfgen.wrap_pdf_response(pdf_data, filename)