def news_sale_title_find(): #图书促销 global sale_list_link_new home = "http://www.queshu.com/sale/" try: response = urllib2.urlopen(urllib2.Request(home)) soup = BeautifulSoup(response, "html.parser") for news_sale_detail in soup.find_all(class_="news_sale_detail"): promotionCompany = news_sale_detail.contents[0].contents[0] #电商名字 promotionDeadline = news_sale_detail.contents[1].string #活动结束时间 for news_sale_title in news_sale_detail.find_all(class_="news_sale_title"): #活动链接 promotionName = news_sale_title.contents[0].contents[0] #活动名称 promotionLink = news_sale_title.contents[0]["href"] if promotionLink[1:5] == "link": promotionLink = home[:-5] + promotionLink if promotionDeadline: #可能为空 promotionDeadline = promotionDeadline.encode('utf-8') promotionID=promotionLink[-5:] result = Promotion( promotionID = promotionID.encode('utf-8'), promotionCompany = promotionCompany.encode('utf-8'), promotionName = promotionName.encode('utf-8'), promotionDeadline = promotionDeadline, promotionLink = promotionLink.encode('utf-8')) result.save() font_13_bold = news_sale_detail.find(href=re.compile("sale_list")) #参加活动图书列表 if font_13_bold: sale_list_link_new[promotionID] = home[:-6] + font_13_bold["href"] except urllib2.URLError, e: print e.reason
def news_sale_title_find(): #活动列表 global sale_list_link_new home = "http://www.queshu.com/sale/" try: response = urllib2.urlopen(urllib2.Request(home)) soup = BeautifulSoup(response, "html.parser") for news_sale_detail in soup.find_all(class_="news_sale_detail"): promotionCompany = news_sale_detail.contents[0].contents[0] #电商名字 promotionDeadline = news_sale_detail.contents[1].string #活动结束时间 for news_sale_title in news_sale_detail.find_all(class_="news_sale_title"): #活动链接 promotionName = news_sale_title.contents[0].contents[0] #活动名称 promotionLink = news_sale_title.contents[0]["href"] if promotionLink[1:5] == "link": promotionLink = home[:-5] + promotionLink if promotionDeadline: #活动结束时间可能为空 promotionDeadline = promotionDeadline.encode('utf-8') promotionID=promotionLink[-5:] promotionSearchLink = "" font_13_bold = news_sale_detail.find(href=re.compile("sale_list")) #参加活动图书列表 if font_13_bold: promotionSearchLink = home[:-6] + font_13_bold["href"] sale_list_link_new[promotionID] = promotionSearchLink result = Promotion( promotionID = promotionID.encode('utf-8'), promotionCompany = promotionCompany.encode('utf-8'), promotionName = promotionName.encode('utf-8'), promotionDeadline = promotionDeadline, promotionLink = promotionLink.encode('utf-8'), promotionSearchLink = promotionSearchLink) result.save() except urllib2.URLError, e: print e.reason
def _parse_promotion(self, json_obj): item = Promotion(**json_obj) if self.is_logged_in and self.user.favorites: if item.type == 'ALBUM': item._isFavorite = self.user.favorites.isFavoriteAlbum(item.id) elif item.type == 'PLAYLIST': item._isFavorite = self.user.favorites.isFavoritePlaylist( item.id) elif item.type == 'VIDEO': item._isFavorite = self.user.favorites.isFavoriteVideo(item.id) return item
def get(self): """ Logged in users not allowed here. """ if self.get_current_user(): return self.redirect("/") if options.disable_signups: return self.write("Sorry! Signups Are Closed.") # voucher key key_value = self.get_argument('key', '') promotions = Promotion.active() # Amazon's ELB will set this header to inform us what scheme is in use # Fallback to checking Tornado's protocol if it is absent using_https = self.request.headers.get( "X-Forwarded-Proto", self.request.protocol) == "https" #recaptcha hot fix captcha_string = captcha.displayhtml(options.recaptcha_public_key, use_ssl=using_https) return self.render("account/create.html", name="", email="", key=key_value, promotions=promotions, recaptcha=captcha_string)
def get(self): """ Logged in users not allowed here. """ if self.get_current_user(): return self.redirect("/") if options.disable_signups: return self.write("Sorry! Signups Are Closed.") # voucher key key_value = self.get_argument('key', '') promotions = Promotion.active() # If we're using mltshp-cdn.com, we know that we can use # https; if something else is configured, check the # X-Forwarded-Proto header and fallback to the protocol # of the request using_https = options.cdn_ssl_host == "mltshp-cdn.com" or \ self.request.headers.get("X-Forwarded-Proto", self.request.protocol) == "https" #recaptcha hot fix if options.recaptcha_public_key: captcha_string = captcha.displayhtml(options.recaptcha_public_key, use_ssl=using_https) else: captcha_string = "" return self.render("account/create.html", name="", email="", key=key_value, promotions=promotions, recaptcha=captcha_string)
def get(self): current_user = self.get_current_user_object() if current_user.is_paid: return self.redirect("/account/settings") promotions = Promotion.active() return self.render('account/subscribe.html', promotions=promotions)
def list_promotions(): """ Returns all of the Promotions """ promotions = [] category = request.args.get('category') name = request.args.get('name') availability = request.args.get('availability') if category: promotions = Promotion.find_by_category(category) elif name: promotions = Promotion.find_by_promo_name(name) elif availability: promotions = Promotion.find_by_availability(availability) else: promotions = Promotion.all() results = [promotion.serialize() for promotion in promotions] return make_response(jsonify(results), status.HTTP_200_OK)
def __init__(self, sub, promotion_type): self.promotion = Promotion.Promotion(promotion_type) self.sub = sub if sub.sub_level == "starter": self.__sub_price = 2.99-2.99 * self.promotion.percent if sub.sub_level == "plus": self.__sub_price = 5.99-5.99 * self.promotion.percent if sub.sub_level == "premium": self.__sub_price = 9.99-9.99 * self.promotion.percent
def delete_promotion(promotion_id): """ Delete a Promotion This endpoint will delete a Promotion based the id specified in the path """ promotion = Promotion.find(promotion_id) if promotion: promotion.delete() return make_response('', status.HTTP_204_NO_CONTENT)
def get(self): """ Returns all of the Promotions""" app.logger.info("Request to list promotions") promotions = [] category = request.args.get('category') name = request.args.get('promo_name') availability = request.args.get('availability') if category: promotions = Promotion.find_by_category(category) elif name: promotions = Promotion.find_by_promo_name(name) elif availability: availability = str_to_bool(availability) promotions = Promotion.find_by_availability(availability) else: promotions = Promotion.all() results = [promotion.serialize() for promotion in promotions] return results, status.HTTP_200_OK
def delete(self): """ Delete all unavailable Promotions This endpoint will delete all unavailable Promotions """ promotions = Promotion.find_by_availability(False) if promotions: for promotion in promotions: promotion.delete() return '', status.HTTP_204_NO_CONTENT
def delete_unavailable_promotion(): """ Delete all unavailable Promotions """ """ This endpoint will delete all unavailable Promotions """ promotions = Promotion.find_by_availability(False) if promotions: for promotion in promotions: promotion.delete() return make_response('', status.HTTP_204_NO_CONTENT)
def get_promotion(promotion_id): """ Retrieve a single Promotion This endpoint will return a Promotion based on it's id """ promotion = Promotion.find(promotion_id) if not promotion: raise NotFound("Promotion with id '{}' was not found.".format(promotion_id)) return make_response(jsonify(promotion.serialize()), status.HTTP_200_OK)
def delete(self, promotion_id): """ Delete a Promotion This endpoint will delete a Promotion based the id specified in the path """ app.logger.info('Request to Delete a promotion with id [%s]', promotion_id) promotion = Promotion.find(promotion_id) if promotion: promotion.delete() return '', status.HTTP_204_NO_CONTENT
def update_promotion(promotion_id): """ Update a Promotion This endpoint will update a Promotion based the body that is posted """ check_content_type('application/json') promotion = Promotion.find(promotion_id) if not promotion: raise NotFound("Promotion with id '{}' was not found.".format(promotion_id)) promotion.deserialize(request.get_json()) promotion.id = promotion_id promotion.save() return make_response(jsonify(promotion.serialize()), status.HTTP_200_OK)
def setUp(self): super(VoucherTests, self).setUp() self.admin = test.factories.user() self.sign_in("admin", "password") self.shake = Shake(user_id=self.admin.id, name='promotion-shake', title='Promotion Shake', type='group') self.shake.save() self.expired_promotion = Promotion(name="Expired Promotion", membership_months=60, expires_at=datetime.utcnow() - timedelta(seconds=50), promotion_shake_id=0) self.expired_promotion.save() self.promotion = Promotion(name="Unit Test Sale", membership_months=60, promotion_shake_id=self.shake.id, expires_at=datetime.utcnow() + timedelta(seconds=60 * 60 * 24 * 365)) self.promotion.save() self.used_voucher = Voucher(offered_by_user_id=0, promotion_id=self.promotion.id, voucher_key="abc123") # apply_to_user saves the voucher object (because it touches the # claimed_by_user_id and dates) and also the user object (by # updating the is_paid status) self.used_voucher.apply_to_user(self.admin) self.unused_voucher = Voucher(offered_by_user_id=0, claimed_by_user_id=0, promotion_id=self.promotion.id, voucher_key="unclaimed") self.unused_voucher.save() tornado.httpclient.HTTPClient()
def create_promotion(): """ Create a new promotion This endpoint will create a promotion based on the data in the request body and save it into the db """ check_content_type('application/json') promotion = Promotion() promotion.deserialize(request.get_json()) promotion.save() saved_info = promotion.serialize() location_url = url_for('get_promotion', promotion_id = promotion.id, _external=True) return make_response(jsonify(saved_info), status.HTTP_201_CREATED, { 'Location': location_url })
def get(self, promotion_id): """ Retrieve a single Promotion This endpoint will return a Promotion based on it's id """ app.logger.info("Request to Retrieve a promotion with id [%s]", promotion_id) promotion = Promotion.find(promotion_id) if not promotion: app.logger.error('Promotion with id %d was not found.', promotion_id) raise NotFound( "Promotion with id '{}' was not found.".format(promotion_id)) return promotion.serialize(), status.HTTP_200_OK
def get(self): user = self.get_current_user_object() payments = [] if user.is_paid: payments = PaymentLog.last_payments(count=3, user_id=user.id) already_requested = self.get_secure_cookie("image_request") promotions = Promotion.active() return self.render("account/settings.html", user=user, payments=payments, already_requested=already_requested, promotions=promotions)
def get(self): vid = self.get_argument('vid', None) shake = None promotion = None voucher = None user = self.get_current_user_object() if vid is not None: voucher = Voucher.get("id=%s", vid) if voucher is not None and voucher.claimed_by_user_id == user.id: if voucher.promotion_id: promotion = Promotion.get("id=%s", voucher.promotion_id) if promotion is not None: shake = promotion.shake() return self.render( "account/confirm.html", promotion=promotion, promotion_shake=shake, voucher=voucher, current_user_obj=user)
def post(self): key_value = self.get_argument('key', '') voucher = is_valid_voucher_key(key_value) user = self.get_current_user_object() if voucher is not None: if not voucher.claimed_by_user_id: voucher.apply_to_user(user) return self.redirect("/account/settings") promotions = Promotion.active() self.add_error('key', 'Invalid discount code') return self.render("account/redeem.html", key=key_value, promotions=promotions)
def post(self): user = self.get_current_user_object() email = self.get_argument('email', None) disable_notifications = self.get_argument('disable_notifications', 0) show_naked_people = self.get_argument('show_naked_people', 0) show_stats = self.get_argument('show_stats', 0) disable_autoplay = self.get_argument('disable_autoplay', 0) if email != user.email and email != None: user.update_email(email) user.invalidate_email() if disable_notifications: user.disable_notifications = 1 else: user.disable_notifications = 0 if show_naked_people: user.show_naked_people = 1 else: user.show_naked_people = 0 if show_stats: user.show_stats = 1 else: user.show_stats = 0 if disable_autoplay: user.disable_autoplay = 1 else: user.disable_autoplay = 0 if user.save(): return self.redirect("/account/settings") promotions = Promotion.active() self.add_errors(user.errors) return self.render("account/settings.html", user=user, errors=self._errors, promotions=promotions)
def post(self): """ Create a new promotion This endpoint will create a promotion based on the data in the request body and save it into the db """ app.logger.info('Request to Create a Promotion') check_content_type('application/json') promotion = Promotion() app.logger.info('Payload = %s', api.payload) promotion.deserialize(api.payload) promotion.save() app.logger.info('Promotion with new id [%s] saved!', promotion.id) location_url = api.url_for(PromotionResource, promotion_id=promotion.id, _external=True) return promotion.serialize(), status.HTTP_201_CREATED, { 'Location': location_url }
def get(self): """ Logged out users not allowed here. """ # voucher key key_value = self.get_argument('key', '') user = self.get_current_user_object() if user is None: if key_value != '': query = "?" + urlencode({"key": key_value}) return self.redirect("/create-account%s" % query) if user.is_paid: # pro users can't redeem return self.redirect("/account/settings") promotions = Promotion.active() return self.render("account/redeem.html", key=key_value, promotions=promotions)
def create_model(self, form): try: assert form.promotion_type is not None and form.promotion_type.data in PromotionType.__members__ assert isinstance(form.bonus_amount.data, int) and form.bonus_amount.data > 0 assert isinstance(form.betting_volume_threshold.data, int) and form.bonus_amount.data > 0 assert isinstance(form.user_balance_minimum.data, int) and form.bonus_amount.data > 0 model = Promotion( promotion_type=PromotionType[form.promotion_type.data], bonus_amount=form.bonus_amount.data, betting_volume_threshold=form.betting_volume_threshold.data, user_balance_minimum=form.user_balance_minimum.data ) self.session.add(model) self.session.commit() logger.info(f'Promotion created by admin {auth_get_current_username()}: {model.to_json()}') except Exception as ex: self.session.rollback() flash(f'Failed to create promotion. {str(ex)}', 'error') logger.exception(f'Promotion create by admin {auth_get_current_username()} raised exception') return False return True
def put(self, promotion_id): """ Update a Promotion This endpoint will update a Promotion based the body that is posted """ app.logger.info('Request to Update a promotion with id [%s]', promotion_id) check_content_type('application/json') promotion = Promotion.find(promotion_id) if not promotion: app.logger.error('Promotion with id %d was not found.', promotion_id) raise NotFound( "Promotion with id '{}' was not found.".format(promotion_id)) data = api.payload app.logger.info(data) promotion.deserialize(data) promotion.id = promotion_id promotion.save() return promotion.serialize(), status.HTTP_200_OK
def add_promotions(): promotions_file = request.files.get('promotions') if not promotions_file or not promotions_file.filename: raise HttpError('Missing field', 400, { 'errors': { 'discounts': 'this field is required', }, }) promotions_parsed = parse(promotions_file) # for production, create_products should probably be 'false'. I set it # as a facility to automatically create missing products promotions = Promotion.from_file(promotions_parsed, request.user, create_products=True) promotions_dict = list(map(serialize_promotion, promotions)) response = jsonify(promotions_dict) response.status_code = 201 return response
def get(self): user = self.get_current_user_object() payments = [] if user.is_paid: payments = PaymentLog.last_payments(count=3, user_id=user.id) already_requested = self.get_secure_cookie("image_request") cancel_flag = "canceled" in (user.stripe_plan_id or "") migrated_flag = self.get_argument('migrated', 0) promotions = Promotion.active() has_data_to_migrate = not MigrationState.has_migrated(user.id) return self.render("account/settings.html", user=user, payments=payments, already_requested=already_requested, promotions=promotions, plan_name=plan_name(user.stripe_plan_id), has_data_to_migrate=has_data_to_migrate, migrated_flag=migrated_flag, cancel_flag=cancel_flag)
def post(self): if options.disable_signups: return name_value = self.get_argument('name', '') email_value = self.get_argument('email', '') key_value = self.get_argument('key', '') has_errors = False voucher = None if key_value != '': voucher = is_valid_voucher_key(key_value) if voucher is None: has_errors = True self.add_error('key', 'Invalid discount code') new_user = User(name=name_value, email=email_value, email_confirmed=0) new_user.set_and_confirm_password( self.get_argument('password', ""), self.get_argument('password_again', "")) skip_recaptcha = self.get_argument('_skip_recaptcha_test_only', False) if not options.recaptcha_private_key: skip_recaptcha = True #recaptcha hotfix if not skip_recaptcha: response = captcha.submit( self.get_argument('recaptcha_challenge_field'), self.get_argument('recaptcha_response_field'), options.recaptcha_private_key, self.request.remote_ip) if not response.is_valid: has_errors = True self.add_error('recaptcha', 'Invalid captcha') if not has_errors: try: # create form asserts the user agress to terms of use new_user.tou_agreed = 1 if new_user.save(): if options.postmark_api_key: # i'd like to NOT invalidate_email in the # case of using a voucher, but the person # may use a different email for MLTSHP than # they used for receiving their voucher, so... new_user.invalidate_email() else: # we have no way to send a verification # email, so we're gonna trust 'em new_user.email_confirmed = 1 new_user.save() query_str = '' if voucher is not None: voucher.apply_to_user(new_user) query_str = '?vid=%s' % str(voucher.id) self.log_user_in(new_user) if new_user.email_confirmed: return self.redirect('/') else: return self.redirect('/confirm-account%s' % query_str) except torndb.IntegrityError: #This is a rare edge case, so we handle it lazily -- IK. pass has_errors = True self.add_errors(new_user.errors) #recaptcha hot fix captcha_string = captcha.displayhtml(options.recaptcha_public_key) promotions = Promotion.active() return self.render("account/create.html", name=name_value, email=email_value, key=key_value, recaptcha=captcha_string, promotions=promotions)
def post(self): if options.disable_signups: return name_value = self.get_argument('name', '') email_value = self.get_argument('email', '') key_value = self.get_argument('key', '') has_errors = False voucher = None if key_value != '': voucher = is_valid_voucher_key(key_value) if voucher is None: has_errors = True self.add_error('key', 'Invalid discount code') new_user = User(name=name_value, email=email_value, email_confirmed=0) new_user.set_and_confirm_password( self.get_argument('password', ""), self.get_argument('password_again', "")) skip_recaptcha = self.get_argument('_skip_recaptcha_test_only', False) if not options.recaptcha_secret_key: skip_recaptcha = True # recaptcha validation, when configured if not skip_recaptcha: response = requests.post( "https://www.google.com/recaptcha/api/siteverify", params={ "secret": options.recaptcha_secret_key, "response": self.get_argument("recaptcha_token"), }) try: result = response.json() if not result["success"] or result["score"] < 0.5: has_errors = True self.add_error("recaptcha", "Invalid captcha") except ValueError: has_errors = True self.add_error("recaptcha", "Invalid captcha") if not has_errors: try: # create form asserts the user agress to terms of use new_user.tou_agreed = 1 if new_user.save(): if options.postmark_api_key: # i'd like to NOT invalidate_email in the # case of using a voucher, but the person # may use a different email for MLTSHP than # they used for receiving their voucher, so... new_user.invalidate_email() else: # we have no way to send a verification # email, so we're gonna trust 'em new_user.email_confirmed = 1 new_user.save() query_str = '' if voucher is not None: voucher.apply_to_user(new_user) query_str = '?vid=%s' % str(voucher.id) self.log_user_in(new_user) if new_user.email_confirmed: return self.redirect('/') else: return self.redirect('/confirm-account%s' % query_str) except torndb.IntegrityError: #This is a rare edge case, so we handle it lazily -- IK. pass has_errors = True self.add_errors(new_user.errors) promotions = Promotion.active() return self.render("account/create.html", name=name_value, email=email_value, key=key_value, recaptcha_site_key=options.recaptcha_site_key, promotions=promotions)
def get(self): user = self.get_current_user_object() payments = [] if user.is_paid: payments = [] if user.stripe_customer_id: customer_id = user.stripe_customer_id charges = stripe.Charge.list(limit=5, customer=customer_id) for charge in charges.data: payments.append({ "transaction_amount": "USD %0.2f" % (charge.amount / 100.0, ), "refund_amount": charge.refunded and "USD %0.2f" % (charge.amount_refunded / 100.0, ) or "", "created_at": datetime.datetime.fromtimestamp(charge.created), "status": "charged", "is_pending": charge.status == "pending", "is_failed": charge.status == "failed", "is_success": charge.status == "succeeded", "is_refund": charge.refunded, }) else: log = PaymentLog.last_payments(count=5, user_id=user.id) for payment in log: payments.append({ "transaction_amount": payment.transaction_amount, "refund_amount": "", "created_at": payment.created_at, "status": payment.status, "is_pending": False, "is_success": True, "is_failed": False, "is_refund": False, }) already_requested = self.get_secure_cookie("image_request") cancel_flag = "canceled" in (user.stripe_plan_id or "") updated_flag = self.get_argument("update", "") == "1" migrated_flag = self.get_argument("migrated", 0) past_due = False source_card_type = None source_last_4 = None source_expiration = None promotions = Promotion.active() has_data_to_migrate = not MigrationState.has_migrated(user.id) if user.stripe_customer_id: customer = None try: customer = stripe.Customer.retrieve(user.stripe_customer_id) except stripe.error.InvalidRequestError: pass if customer and not hasattr(customer, 'deleted'): if customer.subscriptions.total_count >= 1: subscriptions = [ sub for sub in customer.subscriptions.data if sub.plan.id == user.stripe_plan_id ] if subscriptions: subscription = subscriptions[0] past_due = subscription.status == "past_due" if customer.sources.total_count > 0: if customer.sources.data[0].object == "card": card = customer.sources.data[0] elif customer.sources.data[0].object == "source": card = customer.sources.data[0].card source_card_type = card.brand source_last_4 = card.last4 source_expiration = "%d/%d" % (card.exp_month, card.exp_year) return self.render("account/settings.html", user=user, payments=payments, already_requested=already_requested, promotions=promotions, plan_name=plan_name(user.stripe_plan_id), past_due=past_due, stripe_public_key=options.stripe_public_key, source_card_type=source_card_type, source_last_4=source_last_4, source_expiration=source_expiration, has_data_to_migrate=has_data_to_migrate, updated_flag=updated_flag, migrated_flag=migrated_flag, cancel_flag=cancel_flag)