コード例 #1
0
def CreatePlaceByIP(ip):
    place = Place()
    #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place.max')
    q = Counter.selectBy(name='place.max')
    if (q.count() == 1):
        counter = q[0]
        counter.value = counter.value + 1
    else:
        counter = Counter()
        counter.name = 'place.max'
        counter.value = 1
    #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place.total')
    q2 = Counter.selectBy(name='place.total')
    if (q2.count() == 1):
        counter2 = q2[0]
        counter2.value = counter2.value + 1
    else:
        counter2 = Counter()
        counter2.name = 'place.total'
        counter2.value = 1
    place.num = ip2long(ip)
    place.ip = ip
    place.sync()
    counter.sync()
    counter2.sync()
    store.commit()  #jon add
    return place
コード例 #2
0
 def post(self):
     site = GetSite()
     browser = detect(self.request)
     template_values = {}
     template_values['site'] = site
     template_values['system_version'] = SYSTEM_VERSION
     template_values['page_title'] = site.title + u' › 新建记事'
     member = CheckAuth(self)
     l10n = GetMessages(self, member, site)
     template_values['l10n'] = l10n
     if member:
         template_values['member'] = member
         # Verification: content
         note_content = self.request.arguments['content'][0].strip()
         note_content_length = len(note_content)
         if note_content_length > 0:
             note = Note()
             #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'note.max')
             q = Counter.selectBy(name='note.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'note.max'
                 counter.value = 1
             #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'note.total')
             q2 = Counter.selectBy(name='note.max')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'note.total'
                 counter2.value = 1
             note.num = counter.value
             note.title = note_content.split("\n")[0][0:60].strip()
             note.content = note_content
             note.body = "\n".join(note_content.split("\n")[1:]).strip()
             note.length = len(note_content)
             note.member_num = member.num
             note.member = member
             note.sync()
             counter.sync()
             counter2.sync()
             store.commit()  #jon add
             self.redirect('/notes/' + str(note.num))
         else:
             template_values['note_content'] = note_content
             if browser['ios']:
                 path = os.path.join(os.path.dirname(__file__), 'tpl',
                                     'mobile')
             else:
                 path = os.path.join(os.path.dirname(__file__), 'tpl',
                                     'desktop')
             t = self.get_template(path, 'notes_new.html')
             self.finish(t.render(template_values))
     else:
         self.redirect('/signin')
コード例 #3
0
    def get(self, reply_key):
        reply = Reply.get(reply_key)
        topic = GetKindByNum('Topic', reply.topic_num)
        ms = re.findall('(@[a-zA-Z0-9\_]+\.?)\s?', reply.content)
        unique = []
        for m in ms:
            if m.lower() not in unique:
                unique.append(m.lower())
        keys = []
        if (len(unique) > 0):
            for m in unique:
                m_id = re.findall('@([a-zA-Z0-9\_]+\.?)', m)
                if (len(m_id) > 0):
                    if (m_id[0].endswith('.') != True):
                        member_username = m_id[0]
                        member = GetMemberByUsername(member_username)
                        if member:
                            if (member.id != topic.member.id) and (
                                    member.id != reply.member.id) and (
                                        member.id not in keys):
                                #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'notification.max')
                                q = Counter.selectBy(name='notification.max')
                                if (q.count() == 1):
                                    counter = q[0]
                                    counter.value = counter.value + 1
                                else:
                                    counter = Counter()
                                    counter.name = 'notification.max'
                                    counter.value = 1
                                #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'notification.total')
                                q2 = Counter.selectBy(
                                    name='notification.total')
                                if (q2.count() == 1):
                                    counter2 = q2[0]
                                    counter2.value = counter2.value + 1
                                else:
                                    counter2 = Counter()
                                    counter2.name = 'notification.total'
                                    counter2.value = 1

                                notification = Notification(member=member)
                                notification.num = counter.value
                                notification.type = 'mention_reply'
                                notification.payload = reply.content
                                notification.label1 = topic.title
                                notification.link1 = '/t/' + str(
                                    topic.num) + '#reply' + str(topic.replies)
                                notification.member = reply.member
                                notification.for_member_num = member.num

                                keys.append(str(member.id))

                                counter.sync()
                                counter2.sync()
                                notification.sync()
                                store.commit()  #jon add
        for k in keys:
            taskqueue.add(url='/notifications/check/' + k)
コード例 #4
0
ファイル: notes.py プロジェクト: coderyy/v2ex-tornado-2
 def post(self):
     site = GetSite()
     browser = detect(self.request)
     template_values = {}
     template_values['site'] = site
     template_values['system_version'] = SYSTEM_VERSION
     template_values['page_title'] = site.title + u' › 新建记事'
     member = CheckAuth(self)
     l10n = GetMessages(self, member, site)
     template_values['l10n'] = l10n
     if member:
         template_values['member'] = member
         # Verification: content
         note_content = self.request.arguments['content'][0].strip()
         note_content_length = len(note_content)
         if note_content_length > 0:
             note = Note()
             #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'note.max')
             q = Counter.selectBy(name='note.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'note.max'
                 counter.value = 1
             #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'note.total')
             q2 = Counter.selectBy(name='note.max')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'note.total'
                 counter2.value = 1
             note.num = counter.value
             note.title = note_content.split("\n")[0][0:60].strip()
             note.content = note_content
             note.body = "\n".join(note_content.split("\n")[1:]).strip()
             note.length = len(note_content)
             note.member_num = member.num
             note.member = member
             note.sync()
             counter.sync()
             counter2.sync()
             store.commit()  #jon add
             self.redirect('/notes/' + str(note.num))
         else:
             template_values['note_content'] = note_content
             if browser['ios']:
                 path = os.path.join(os.path.dirname(__file__), 'tpl', 'mobile')
             else:
                 path = os.path.join(os.path.dirname(__file__), 'tpl', 'desktop')
             t=self.get_template(path,'notes_new.html')
             self.finish(t.render(template_values))
     else:
         self.redirect('/signin')
コード例 #5
0
    def post(self, topic_key):
        topic = db.get(db.Key(topic_key))
        combined = topic.title + " " + topic.content
        ms = re.findall('(@[a-zA-Z0-9\_]+\.?)\s?', combined)
        unique = []
        for m in ms:
            if m.lower() not in unique:
                unique.append(m.lower())
        keys = []
        if (len(unique) > 0):
            for m in unique:
                m_id = re.findall('@([a-zA-Z0-9\_]+\.?)', m)
                if (len(m_id) > 0):
                    if (m_id[0].endswith('.') != True):
                        member_username = m_id[0]
                        member = GetMemberByUsername(member_username)
                        if member:
                            if member.key() != topic.member.key(
                            ) and member.key() not in keys:
                                q = db.GqlQuery(
                                    'SELECT * FROM Counter WHERE name = :1',
                                    'notification.max')
                                if (q.count() == 1):
                                    counter = q[0]
                                    counter.value = counter.value + 1
                                else:
                                    counter = Counter()
                                    counter.name = 'notification.max'
                                    counter.value = 1
                                q2 = db.GqlQuery(
                                    'SELECT * FROM Counter WHERE name = :1',
                                    'notification.total')
                                if (q2.count() == 1):
                                    counter2 = q2[0]
                                    counter2.value = counter2.value + 1
                                else:
                                    counter2 = Counter()
                                    counter2.name = 'notification.total'
                                    counter2.value = 1

                                notification = Notification(parent=member)
                                notification.num = counter.value
                                notification.type = 'mention_topic'
                                notification.payload = topic.content
                                notification.label1 = topic.title
                                notification.link1 = '/t/' + str(
                                    topic.num) + '#reply' + str(topic.replies)
                                notification.member = topic.member
                                notification.for_member_num = member.num

                                keys.append(str(member.key()))

                                counter.put()
                                counter2.put()
                                notification.put()
        for k in keys:
            taskqueue.add(url='/notifications/check/' + k)
コード例 #6
0
    def get(self, topic_key):
        topic = Topic.get(topic_key)
        combined = topic.title + " " + topic.content
        ms = re.findall('(@[a-zA-Z0-9\_]+\.?)\s?', combined)
        unique = []
        for m in ms:
            if m.lower() not in unique:
                unique.append(m.lower())
        keys = []
        if (len(unique) > 0):
            for m in unique:
                m_id = re.findall('@([a-zA-Z0-9\_]+\.?)', m)
                if (len(m_id) > 0):
                    if (m_id[0].endswith('.') != True):
                        member_username = m_id[0]
                        member = GetMemberByUsername(member_username)
                        if member:
                            if member.id != topic.member.id and member.id not in keys:
                                #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'notification.max')
                                q = Counter.selectBy(name='notification.max')
                                if (q.count() == 1):
                                    counter = q[0]
                                    counter.value = counter.value + 1
                                else:
                                    counter = Counter()
                                    counter.name = 'notification.max'
                                    counter.value = 1
                                #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'notification.total')
                                q2 = Counter.selectBy(name='notification.total')
                                if (q2.count() == 1):
                                    counter2 = q2[0]
                                    counter2.value = counter2.value + 1
                                else:
                                    counter2 = Counter()
                                    counter2.name = 'notification.total'
                                    counter2.value = 1

                                notification = Notification(member=member)
                                notification.num = counter.value
                                notification.type = 'mention_topic'
                                notification.payload = topic.content
                                notification.label1 = topic.title
                                notification.link1 = '/t/' + str(topic.num) + '#reply' + str(topic.replies)
                                notification.member = topic.member
                                notification.for_member_num = member.num

                                keys.append(str(member.id))

                                counter.sync()
                                counter2.sync()
                                notification.sync()
                                store.commit()  #jon add
        for k in keys:
            taskqueue.add(url='/notifications/check/' + k)
コード例 #7
0
ファイル: notes.py プロジェクト: tgq19901001/igeekco
 def post(self):
     site = GetSite()
     template_values = {}
     template_values['site'] = site
     template_values['system_version'] = SYSTEM_VERSION
     template_values['page_title'] = site.title + u' › 新建记事'
     member = CheckAuth(self)
     l10n = GetMessages(self, member, site)
     template_values['l10n'] = l10n
     if member:
         template_values['member'] = member
         # Verification: content
         note_content = self.request.get('content').strip()
         note_content_length = len(note_content)
         if note_content_length > 0:
             note = Note()
             q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1',
                             'note.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'note.max'
                 counter.value = 1
             q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1',
                              'note.total')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'note.total'
                 counter2.value = 1
             note.num = counter.value
             note.title = note_content.split("\n")[0][0:60].strip()
             note.content = note_content
             note.body = "\n".join(note_content.split("\n")[1:]).strip()
             note.length = len(note_content)
             note.member_num = member.num
             note.member = member
             note.put()
             counter.put()
             counter2.put()
             self.redirect('/notes/' + str(note.num))
         else:
             template_values['note_content'] = note_content
             path = os.path.join(os.path.dirname(__file__), 'tpl',
                                 'desktop', 'notes_new.html')
             output = template.render(path, template_values)
             self.response.out.write(output)
     else:
         self.redirect('/signin')
コード例 #8
0
 def post(self, ip):
     site = GetSite()
     if 'Referer' in self.request.headers:
         go = self.request.headers['Referer']
     else:
         go = '/place'
     member = CheckAuth(self)
     place = GetPlaceByIP(ip)
     say = self.request.arguments['say'][0].strip()
     if len(say) > 0 and len(say) < 280 and member and place:
         if member.ip == ip:
             message = PlaceMessage()
             #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.max')
             q = Counter.selectBy(name='place_message.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'place_message.max'
                 counter.value = 1
             #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.total')
             q2 = Counter.selectBy(name='place_message.total')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'place_message.total'
                 counter2.value = 1
             message.num = counter.value
             message.place = place
             message.place_num = place.num
             message.member = member
             message.content = say
             message.sync()
             counter.sync()
             counter2.sync()
             store.commit()  #jon add
     self.redirect(go)
コード例 #9
0
ファイル: place.py プロジェクト: coderyy/v2ex-tornado-2
 def post(self, ip):
     site = GetSite()
     if 'Referer' in self.request.headers:
         go = self.request.headers['Referer']
     else:
         go = '/place'
     member = CheckAuth(self)
     place = GetPlaceByIP(ip)
     say = self.request.arguments['say'][0].strip()
     if len(say) > 0 and len(say) < 280 and member and place:
         if member.ip == ip:
             message = PlaceMessage()
             #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.max')
             q = Counter.selectBy(name='place_message.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'place_message.max'
                 counter.value = 1
             #q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.total')
             q2 = Counter.selectBy(name='place_message.total')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'place_message.total'
                 counter2.value = 1
             message.num = counter.value
             message.place = place
             message.place_num = place.num
             message.member = member
             message.content = say
             message.sync()
             counter.sync()
             counter2.sync()
             store.commit()  #jon add
     self.redirect(go)
コード例 #10
0
def CreatePlaceByIP(ip):
    place = Place()
    q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place.max')
    if (q.count() == 1):
        counter = q[0]
        counter.value = counter.value + 1
    else:
        counter = Counter()
        counter.name = 'place.max'
        counter.value = 1
    q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place.total')
    if (q2.count() == 1):
        counter2 = q2[0]
        counter2.value = counter2.value + 1
    else:
        counter2 = Counter()
        counter2.name = 'place.total'
        counter2.value = 1
    place.num = ip2long(ip)
    place.ip = ip
    place.put()
    counter.put()
    counter2.put()
    return place
コード例 #11
0
ファイル: place.py プロジェクト: coderyy/v2ex-tornado-2
 def get(self, key):
     if 'Referer' in self.request.headers:
         go = self.request.headers['Referer']
     else:
         go = '/place'
     member = CheckAuth(self)
     if member:
         message = PlaceMessage.get(key)
         if message:
             if message.member.num == member.num:
                 message.delete()
                 #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.total')
                 q = Counter.selectBy(name='place_message.total')
                 if (q.count() == 1):
                     counter = q[0]
                     counter.value = counter.value - 1
                     counter.sync()
                     store.commit()  #jon add
     self.redirect(go)
コード例 #12
0
 def get(self, key):
     if 'Referer' in self.request.headers:
         go = self.request.headers['Referer']
     else:
         go = '/place'
     member = CheckAuth(self)
     if member:
         message = PlaceMessage.get(key)
         if message:
             if message.member.num == member.num:
                 message.delete()
                 #q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'place_message.total')
                 q = Counter.selectBy(name='place_message.total')
                 if (q.count() == 1):
                     counter = q[0]
                     counter.value = counter.value - 1
                     counter.sync()
                     store.commit()  #jon add
     self.redirect(go)
コード例 #13
0
    def post(self):
        site = GetSite()
        member = False
        browser = detect(self.request)
        template_values = {}
        template_values['site'] = site
        template_values['page_title'] = site.title + u' › 注册'
        template_values['system_version'] = SYSTEM_VERSION
        l10n = GetMessages(self, member, site)
        template_values['l10n'] = l10n
        errors = 0
        # Verification: username
        member_username_error = 0
        member_username_error_messages = ['',
            l10n.username_empty,
            l10n.username_too_long,
            l10n.username_invalid,
            l10n.username_taken]
        member_username = self.request.get('username').strip()
        if (len(member_username) == 0):
            errors = errors + 1
            member_username_error = 1
        else:
            if (len(member_username) > 32):
                errors = errors + 1
                member_username_error = 2
            else:
                if (re.search('^[a-zA-Z0-9\_]+$', member_username)):
                    q = db.GqlQuery('SELECT __key__ FROM Member WHERE username_lower = :1', member_username.lower())
                    if (q.count() > 0):
                        errors = errors + 1
                        member_username_error = 4
                else:
                    errors = errors + 1
                    member_username_error = 3
        template_values['member_username'] = member_username
        template_values['member_username_error'] = member_username_error
        template_values['member_username_error_message'] = member_username_error_messages[member_username_error]
        # Verification: password
        member_password_error = 0
        member_password_error_messages = ['',
            u'请输入你的密码',
            u'密码长度不能超过 32 个字符'
        ]
        member_password = self.request.get('password').strip()
        if (len(member_password) == 0):
            errors = errors + 1
            member_password_error = 1
        else:
            if (len(member_password) > 32):
                errors = errors + 1
                member_password_error = 2
        template_values['member_password'] = member_password
        template_values['member_password_error'] = member_password_error
        template_values['member_password_error_message'] = member_password_error_messages[member_password_error]
        # Verification: email
        member_email_error = 0
        member_email_error_messages = ['',
            u'请输入你的电子邮件地址',
            u'电子邮件地址长度不能超过 32 个字符',
            u'你输入的电子邮件地址不符合规则',
            u'抱歉这个电子邮件地址已经有人注册过了']
        member_email = self.request.get('email').strip()
        if (len(member_email) == 0):
            errors = errors + 1
            member_email_error = 1
        else:
            if (len(member_email) > 32):
                errors = errors + 1
                member_email_error = 2
            else:
                p = re.compile(r"(?:^|\s)[-a-z0-9_.]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}(?:\s|$)", re.IGNORECASE)
                if (p.search(member_email)):
                    q = db.GqlQuery('SELECT __key__ FROM Member WHERE email = :1', member_email.lower())
                    if (q.count() > 0):
                        errors = errors + 1
                        member_email_error = 4
                else:
                    errors = errors + 1
                    member_email_error = 3
        template_values['member_email'] = member_email
        template_values['member_email_error'] = member_email_error
        template_values['member_email_error_message'] = member_email_error_messages[member_email_error]
        # Verification: invitation
        invitation = self.request.get('invitation').strip()
        q = db.GqlQuery('SELECT * FROM Invitation WHERE code = :1', invitation)
        if q.count() > 0:
            invi = q[0]
            logging.info('invitation code %s used.' % invitation)
            template_values['invitation_error'] = 0
        else:
            errors = errors + 1
            template_values['invitation_error'] = 1
            template_values['invitation_error_message'] = "无效的邀请码"
        # Verification: reCAPTCHA
        challenge = self.request.get('recaptcha_challenge_field')
        response  = self.request.get('recaptcha_response_field')
        remoteip  = os.environ['REMOTE_ADDR']
        
        cResponse = captcha.submit(
                         challenge,
                         response,
                         config.recaptcha_private_key,
                         remoteip)

        if cResponse.is_valid:
            logging.info('reCAPTCHA verification passed')
            template_values['recaptcha_error'] = 0
        else:
            errors = errors + 1
            error = cResponse.error_code
            chtml = captcha.displayhtml(
                public_key = config.recaptcha_public_key,
                use_ssl = False,
                error = cResponse.error_code)
            template_values['captchahtml'] = chtml
            template_values['recaptcha_error'] = 1
            template_values['recaptcha_error_message'] = '请重新输入 reCAPTCHA 验证码'
        template_values['errors'] = errors
        if (errors == 0):
            member = Member()
            q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'member.max')
            if (q.count() == 1):
                counter = q[0]
                counter.value = counter.value + 1
            else:
                counter = Counter()
                counter.name = 'member.max'
                counter.value = 1
            q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1', 'member.total')
            if (q2.count() == 1):
                counter2 = q2[0]
                counter2.value = counter2.value + 1
            else:
                counter2 = Counter()
                counter2.name = 'member.total'
                counter2.value = 1
            member.num = counter.value
            member.username = member_username
            member.username_lower = member_username.lower()
            member.password = hashlib.sha1(member_password).hexdigest()
            member.email = member_email.lower()
            member.auth = hashlib.sha1(str(member.num) + ':' + member.password).hexdigest()
            member.put()
            counter.put()
            counter2.put()
            invi.used = True
            invi.put()
            self.response.headers['Set-Cookie'] = 'auth=' + member.auth + '; expires=' + (datetime.datetime.now() + datetime.timedelta(days=365)).strftime("%a, %d-%b-%Y %H:%M:%S GMT") + '; path=/'
            self.redirect('/')
        else:
            if browser['ios']:
                path = os.path.join(os.path.dirname(__file__), 'tpl', 'mobile', 'signup.html')
            else:
                path = os.path.join(os.path.dirname(__file__), 'tpl', 'desktop', 'signup.html')
            output = template.render(path, template_values)
            self.response.out.write(output)
コード例 #14
0
 def post(self):
     site = GetSite()
     self.session = Session()
     browser = detect(self.request)
     template_values = {}
     template_values['site'] = site
     template_values['system_version'] = SYSTEM_VERSION
     member = CheckAuth(self)
     l10n = GetMessages(self, member, site)
     template_values['l10n'] = l10n
     if (member):
         dest = '/settings/avatar'
         timestamp = str(int(time.time()))
         try:
             avatar = self.request.get('avatar')
         except:
             return self.redirect(dest)
         if avatar is None:
             return self.redirect(dest)
         avatar_len = len(avatar)
         if avatar_len == 0:
             return self.redirect(dest)
         avatar_73 = images.resize(avatar, 73, 73)
         avatar_48 = images.resize(avatar, 48, 48)
         avatar_24 = images.resize(avatar, 24, 24)
         # Large 73x73
         q1 = db.GqlQuery("SELECT * FROM Avatar WHERE name = :1",
                          'avatar_' + str(member.num) + '_large')
         if (q1.count() == 1):
             avatar_large = q1[0]
             avatar_large.content = db.Blob(avatar_73)
             avatar_large.put()
         else:
             qc1 = db.GqlQuery("SELECT * FROM Counter WHERE name = :1",
                               'avatar.max')
             if (qc1.count() == 1):
                 counter1 = qc1[0]
                 counter1.value = counter1.value + 1
             else:
                 counter1 = Counter()
                 counter1.name = 'avatar.max'
                 counter1.value = 1
             counter1.put()
             avatar_large = Avatar()
             avatar_large.name = 'avatar_' + str(member.num) + '_large'
             avatar_large.content = db.Blob(avatar_73)
             avatar_large.num = counter1.value
             avatar_large.put()
         member.avatar_large_url = '/avatar/' + str(
             member.num) + '/large?r=' + timestamp
         member.put()
         # Normal 48x48
         q2 = db.GqlQuery("SELECT * FROM Avatar WHERE name = :1",
                          'avatar_' + str(member.num) + '_normal')
         if (q2.count() == 1):
             avatar_normal = q2[0]
             avatar_normal.content = db.Blob(avatar_48)
             avatar_normal.put()
         else:
             qc2 = db.GqlQuery("SELECT * FROM Counter WHERE name = :1",
                               'avatar.max')
             if (qc2.count() == 1):
                 counter2 = qc2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'avatar.max'
                 counter2.value = 1
             counter2.put()
             avatar_normal = Avatar()
             avatar_normal.name = 'avatar_' + str(member.num) + '_normal'
             avatar_normal.content = db.Blob(avatar_48)
             avatar_normal.num = counter2.value
             avatar_normal.put()
         member.avatar_normal_url = '/avatar/' + str(
             member.num) + '/normal?r=' + timestamp
         member.put()
         # Mini 24x24
         q3 = db.GqlQuery("SELECT * FROM Avatar WHERE name = :1",
                          'avatar_' + str(member.num) + '_mini')
         if (q3.count() == 1):
             avatar_mini = q3[0]
             avatar_mini.content = db.Blob(avatar_24)
             avatar_mini.put()
         else:
             qc3 = db.GqlQuery("SELECT * FROM Counter WHERE name = :1",
                               'avatar.max')
             if (qc3.count() == 1):
                 counter3 = qc3[0]
                 counter3.value = counter3.value + 1
             else:
                 counter3 = Counter()
                 counter3.name = 'avatar.max'
                 counter3.value = 1
             counter3.put()
             avatar_mini = Avatar()
             avatar_mini.name = 'avatar_' + str(member.num) + '_mini'
             avatar_mini.content = db.Blob(avatar_24)
             avatar_mini.num = counter3.value
             avatar_mini.put()
         member.avatar_mini_url = '/avatar/' + str(
             member.num) + '/mini?r=' + timestamp
         member.put()
         # Upload to MobileMe
         if config.mobileme_enabled:
             headers = {
                 'Authorization':
                 'Basic ' + base64.b64encode(config.mobileme_username +
                                             ':' + config.mobileme_password)
             }
             host = 'idisk.me.com'
             # Sharding
             timestamp = str(int(time.time()))
             shard = member.num % 31
             root = '/' + config.mobileme_username + '/Web/Sites/v2ex/avatars/' + str(
                 shard)
             root_mini = root + '/mini'
             root_normal = root + '/normal'
             root_large = root + '/large'
             h = httplib.HTTPConnection(host)
             # Mini
             h.request('PUT', root_mini + '/' + str(member.num) + '.png',
                       str(avatar_24), headers)
             response = h.getresponse()
             if response.status == 201 or response.status == 204:
                 member.avatar_mini_url = 'http://web.me.com/' + config.mobileme_username + '/v2ex/avatars/' + str(
                     shard) + '/mini/' + str(
                         member.num) + '.png?r=' + timestamp
             # Normal
             h.request('PUT', root_normal + '/' + str(member.num) + '.png',
                       str(avatar_48), headers)
             response = h.getresponse()
             if response.status == 201 or response.status == 204:
                 member.avatar_normal_url = 'http://web.me.com/' + config.mobileme_username + '/v2ex/avatars/' + str(
                     shard) + '/normal/' + str(
                         member.num) + '.png?r=' + timestamp
             # Large
             h.request('PUT', root_large + '/' + str(member.num) + '.png',
                       str(avatar_73), headers)
             response = h.getresponse()
             if response.status == 201 or response.status == 204:
                 member.avatar_large_url = 'http://web.me.com/' + config.mobileme_username + '/v2ex/avatars/' + str(
                     shard) + '/large/' + str(
                         member.num) + '.png?r=' + timestamp
             member.put()
         # Upload to UpYun
         if config.upyun_enabled:
             u = UpYun(config.upyun_bucket, config.upyun_username,
                       config.upyun_password)
             # Mini
             mini = avatar_24
             u.setContentMD5(md5(mini))
             mini_suffix = '/avatars/mini/' + str(member.num) + '.png'
             r = u.writeFile(mini_suffix, mini, True)
             if r == True:
                 member.avatar_mini_url = 'http://' + config.upyun_bucket + '.b0.upaiyun.com' + mini_suffix + '?r=' + timestamp
             # Normal
             normal = avatar_48
             u.setContentMD5(md5(normal))
             normal_suffix = '/avatars/normal/' + str(member.num) + '.png'
             r = u.writeFile(normal_suffix, normal, True)
             if r == True:
                 member.avatar_normal_url = 'http://' + config.upyun_bucket + '.b0.upaiyun.com' + normal_suffix + '?r=' + timestamp
             # Large
             large = avatar_73
             u.setContentMD5(md5(large))
             large_suffix = '/avatars/large/' + str(member.num) + '.png'
             r = u.writeFile(large_suffix, large, True)
             if r == True:
                 member.avatar_large_url = 'http://' + config.upyun_bucket + '.b0.upaiyun.com' + large_suffix + '?r=' + timestamp
             member.put()
         memcache.set('Member_' + str(member.num), member, 86400 * 14)
         memcache.set('Member::' + member.username_lower, member,
                      86400 * 14)
         memcache.delete('Avatar::avatar_' + str(member.num) + '_large')
         memcache.delete('Avatar::avatar_' + str(member.num) + '_normal')
         memcache.delete('Avatar::avatar_' + str(member.num) + '_mini')
         self.session['message'] = '新头像设置成功'
         self.redirect('/settings/avatar')
     else:
         self.redirect('/signin')
コード例 #15
0
 def post(self, topic_num):
     site = GetSite()
     browser = detect(self.request)
     template_values = {}
     template_values['site'] = site
     template_values['system_version'] = SYSTEM_VERSION
     member = CheckAuth(self)
     template_values['member'] = member
     l10n = GetMessages(self, member, site)
     template_values['l10n'] = l10n
     topic_num_str = str(topic_num)
     if len(topic_num_str) > 8:
         if browser['ios']:
             path = os.path.join(os.path.dirname(__file__), 'tpl', 'mobile',
                                 'topic_not_found.html')
         else:
             path = os.path.join(os.path.dirname(__file__), 'tpl',
                                 'desktop', 'topic_not_found.html')
         output = template.render(path, template_values)
         self.response.out.write(output)
         return
     if (member):
         topic = False
         q = db.GqlQuery("SELECT * FROM Topic WHERE num = :1",
                         int(topic_num))
         if (q.count() == 1):
             topic = q[0]
             try:
                 topic.hits = topic.hits + 1
                 topic.put()
             except:
                 topic.hits = topic.hits - 1
         template_values['topic'] = topic
         errors = 0
         # Verification: content
         reply_content_error = 0
         reply_content_error_messages = [
             '', u'请输入回复内容', u'回复内容长度不能超过 2000 个字符'
         ]
         reply_content = self.request.get('content').strip()
         if (len(reply_content) == 0):
             errors = errors + 1
             reply_content_error = 1
         else:
             if (len(reply_content) > 2000):
                 errors = errors + 1
                 reply_content_error = 2
         template_values['reply_content'] = reply_content
         template_values['reply_content_error'] = reply_content_error
         template_values[
             'reply_content_error_message'] = reply_content_error_messages[
                 reply_content_error]
         template_values['errors'] = errors
         if (topic and (errors == 0)):
             reply = Reply(parent=topic)
             q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1',
                             'reply.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'reply.max'
                 counter.value = 1
             q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1',
                              'reply.total')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'reply.total'
                 counter2.value = 1
             node = False
             section = False
             if topic:
                 q3 = db.GqlQuery("SELECT * FROM Node WHERE num = :1",
                                  topic.node_num)
                 node = q3[0]
                 #                    q4 = db.GqlQuery("SELECT * FROM Section WHERE num = :1", node.section_num)
                 q4 = Node.all().filter('name =', q3[0].caterogy)
                 section = q4[0]
             reply.num = counter.value
             reply.content = reply_content
             reply.topic = topic
             reply.topic_num = topic.num
             reply.member = member
             reply.member_num = member.num
             reply.created_by = member.username
             topic.replies = topic.replies + 1
             topic.node_name = node.name
             topic.node_title = node.title
             topic.last_reply_by = member.username
             topic.last_touched = datetime.datetime.now()
             ua = self.request.headers['User-Agent']
             if (re.findall('Mozilla\/5.0 \(iPhone', ua)):
                 reply.source = 'iPhone'
             if (re.findall('Mozilla\/5.0 \(iPod', ua)):
                 reply.source = 'iPod'
             if (re.findall('Mozilla\/5.0 \(iPad', ua)):
                 reply.source = 'iPad'
             if (re.findall('Android', ua)):
                 reply.source = 'Android'
             if (re.findall('Mozilla\/5.0 \(PLAYSTATION 3;', ua)):
                 reply.source = 'PS3'
             reply.put()
             topic.put()
             counter.put()
             counter2.put()
             memcache.set('Topic_' + str(topic.num), topic, 86400)
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_desc_compressed')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_asc_compressed')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_filtered_compressed')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_desc_rendered')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_asc_rendered')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_filtered_rendered')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_desc_rendered_mobile')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_asc_rendered_mobile')
             memcache.delete('topic_' + str(topic.num) +
                             '_replies_filtered_rendered_mobile')
             memcache.delete('member::' + str(member.num) +
                             '::participated')
             memcache.delete('home_rendered')
             memcache.delete('home_rendered_mobile')
             taskqueue.add(url='/index/topic/' + str(topic.num))
             # Twitter Sync
             if member.twitter_oauth == 1 and member.twitter_sync == 1:
                 access_token = OAuthToken.from_string(
                     member.twitter_oauth_string)
                 twitter = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET,
                                    access_token)
                 link = 'http://' + self.request.headers[
                     'Host'] + '/t/' + str(topic.num) + '#r' + str(
                         reply.num)
                 link_length = len(link)
                 reply_content_length = len(reply.content)
                 available = 140 - link_length - 1
                 if available > reply_content_length:
                     status = reply.content + ' ' + link
                 else:
                     status = reply.content[0:(available -
                                               4)] + '... ' + link
                 self.response.out.write('Status: ' + status)
                 logging.error('Status: ' + status)
                 try:
                     twitter.PostUpdate(status.encode('utf-8'))
                 except:
                     logging.error("Failed to sync to Twitter for Reply #" +
                                   str(reply.num))
             self.redirect('/t/' + str(topic.num) + '#reply' +
                           str(topic.replies))
         else:
             node = False
             section = False
             if topic:
                 q2 = db.GqlQuery("SELECT * FROM Node WHERE num = :1",
                                  topic.node_num)
                 node = q2[0]
                 #                    q3 = db.GqlQuery("SELECT * FROM Section WHERE num = :1", node.section_num)
                 q3 = Node.all().filter('name =', q2[0].caterogy)
                 section = q3[0]
             template_values['node'] = node
             template_values['section'] = section
             if browser['ios']:
                 path = os.path.join(os.path.dirname(__file__), 'tpl',
                                     'mobile', 'topic.html')
             else:
                 path = os.path.join(os.path.dirname(__file__), 'tpl',
                                     'desktop', 'topic.html')
             output = template.render(path, template_values)
             self.response.out.write(output)
     else:
         self.redirect('/signin')
コード例 #16
0
 def post(self, node_name):
     site = GetSite()
     browser = detect(self.request)
     template_values = {}
     template_values['site'] = site
     template_values['system_version'] = SYSTEM_VERSION
     member = CheckAuth(self)
     l10n = GetMessages(self, member, site)
     template_values['l10n'] = l10n
     template_values[
         'page_title'] = site.title + u' › ' + l10n.create_new_topic.decode(
             'utf-8')
     if (member):
         template_values['member'] = member
         q = db.GqlQuery("SELECT * FROM Node WHERE name = :1", node_name)
         node = False
         if (q.count() == 1):
             node = q[0]
         template_values['node'] = node
         section = False
         if node:
             #                q2 = db.GqlQuery("SELECT * FROM Section WHERE num = :1", node.section_num)
             q2 = Node.all().filter('name =', node.category)
             if (q2.count() == 1):
                 section = q2[0]
         template_values['section'] = section
         errors = 0
         # Verification: title
         topic_title_error = 0
         topic_title_error_messages = [
             '', u'请输入主题标题', u'主题标题长度不能超过 120 个字符'
         ]
         topic_title = self.request.get('title').strip()
         if (len(topic_title) == 0):
             errors = errors + 1
             topic_title_error = 1
         else:
             if (len(topic_title) > 120):
                 errors = errors + 1
                 topic_title_error = 2
         template_values['topic_title'] = topic_title
         template_values['topic_title_error'] = topic_title_error
         template_values[
             'topic_title_error_message'] = topic_title_error_messages[
                 topic_title_error]
         # Verification: content
         topic_content_error = 0
         topic_content_error_messages = [
             '', u'请输入主题内容', u'主题内容长度不能超过 9999 个字符'
         ]
         topic_content = self.request.get('content').strip()
         if (len(topic_content) == 0):
             errors = errors + 1
             topic_content_error = 1
         else:
             if (len(topic_content) > 9999):
                 errors = errors + 1
                 topic_content_error = 2
         template_values['topic_content'] = topic_content
         template_values['topic_content_error'] = topic_content_error
         template_values[
             'topic_content_error_message'] = topic_content_error_messages[
                 topic_content_error]
         # Verification: type
         if site.use_topic_types:
             types = site.topic_types.split("\n")
             if len(types) > 0:
                 topic_type = self.request.get('type').strip()
                 try:
                     topic_type = int(topic_type)
                     if topic_type < 0:
                         topic_type = 0
                     if topic_type > len(types):
                         topic_type = 0
                     if topic_type > 0:
                         detail = types[topic_type - 1].split(':')
                         topic_type_label = detail[0]
                         topic_type_color = detail[1]
                 except:
                     topic_type = 0
             else:
                 topic_type = 0
             options = '<option value="0">&nbsp;&nbsp;&nbsp;&nbsp;</option>'
             i = 0
             for a_type in types:
                 i = i + 1
                 detail = a_type.split(':')
                 if topic_type == i:
                     options = options + '<option value="' + str(
                         i
                     ) + '" selected="selected">' + detail[0] + '</option>'
                 else:
                     options = options + '<option value="' + str(
                         i) + '">' + detail[0] + '</option>'
             tt = '<div class="sep5"></div><table cellpadding="5" cellspacing="0" border="0" width="100%"><tr><td width="60" align="right">Topic Type</td><td width="auto" align="left"><select name="type">' + options + '</select></td></tr></table>'
             template_values['tt'] = tt
         else:
             template_values['tt'] = ''
         template_values['errors'] = errors
         if (errors == 0):
             topic = Topic(parent=node)
             q = db.GqlQuery('SELECT * FROM Counter WHERE name = :1',
                             'topic.max')
             if (q.count() == 1):
                 counter = q[0]
                 counter.value = counter.value + 1
             else:
                 counter = Counter()
                 counter.name = 'topic.max'
                 counter.value = 1
             q2 = db.GqlQuery('SELECT * FROM Counter WHERE name = :1',
                              'topic.total')
             if (q2.count() == 1):
                 counter2 = q2[0]
                 counter2.value = counter2.value + 1
             else:
                 counter2 = Counter()
                 counter2.name = 'topic.total'
                 counter2.value = 1
             topic.num = counter.value
             topic.title = topic_title
             topic.content = topic_content
             path = os.path.join(os.path.dirname(__file__), 'tpl',
                                 'portion', 'topic_content.html')
             output = template.render(path, {'topic': topic})
             topic.content_rendered = output.decode('utf-8')
             topic.node = node
             topic.node_num = node.num
             topic.node_name = node.name
             topic.node_title = node.title
             topic.created_by = member.username
             topic.member = member
             topic.member_num = member.num
             topic.last_touched = datetime.datetime.now()
             ua = self.request.headers['User-Agent']
             if (re.findall('Mozilla\/5.0 \(iPhone;', ua)):
                 topic.source = 'iPhone'
             if (re.findall('Mozilla\/5.0 \(iPod;', ua)):
                 topic.source = 'iPod'
             if (re.findall('Mozilla\/5.0 \(iPad;', ua)):
                 topic.source = 'iPad'
             if (re.findall('Android', ua)):
                 topic.source = 'Android'
             if (re.findall('Mozilla\/5.0 \(PLAYSTATION 3;', ua)):
                 topic.source = 'PS3'
             if site.use_topic_types:
                 if topic_type > 0:
                     topic.type = topic_type_label
                     topic.type_color = topic_type_color
             node.topics = node.topics + 1
             node.put()
             topic.put()
             counter.put()
             counter2.put()
             memcache.delete('feed_index')
             memcache.delete('Node_' + str(topic.node_num))
             memcache.delete('Node::' + str(node.name))
             memcache.delete('home_rendered')
             memcache.delete('home_rendered_mobile')
             taskqueue.add(url='/index/topic/' + str(topic.num))
             # Twitter Sync
             if member.twitter_oauth == 1 and member.twitter_sync == 1:
                 access_token = OAuthToken.from_string(
                     member.twitter_oauth_string)
                 twitter = OAuthApi(CONSUMER_KEY, CONSUMER_SECRET,
                                    access_token)
                 status = topic.title + ' #' + topic.node.name + ' http://' + self.request.headers[
                     'Host'] + '/t/' + str(topic.num)
                 try:
                     twitter.PostUpdate(status.encode('utf-8'))
                 except:
                     logging.error("Failed to sync to Twitter for Topic #" +
                                   str(topic.num))
             self.redirect('/t/' + str(topic.num) + '#reply0')
         else:
             if browser['ios']:
                 path = os.path.join(os.path.dirname(__file__), 'tpl',
                                     'mobile', 'new_topic.html')
             else:
                 path = os.path.join(os.path.dirname(__file__), 'tpl',
                                     'desktop', 'new_topic.html')
             output = template.render(path, template_values)
             self.response.out.write(output)
     else:
         self.redirect('/signin')
コード例 #17
0
ファイル: member.py プロジェクト: coderyy/v2ex-tornado-2
    def post(self):
        site = GetSite()
        self.session = Session()
        browser = detect(self.request)
        template_values = {}
        template_values['site'] = site
        template_values['system_version'] = SYSTEM_VERSION
        member = CheckAuth(self)
        l10n = GetMessages(self, member, site)
        template_values['l10n'] = l10n
        #template_values['xsrf'] = self.xsrf_form_html()
        if (member):
            dest = '/settings/avatar'
            timestamp = str(int(time.time()))
            try:
                avatar = self.request.arguments['avatar'][0]
            except:
                return self.redirect(dest)
            if avatar is None:
                return self.redirect(dest)
            avatar_len = len(avatar)
            if avatar_len == 0:
                return self.redirect(dest)

            s = StringIO.StringIO()
            s.write(avatar)
            images = Image.open(s)
            avatar_73 = images.resize(73, 73)
            avatar_48 = images.resize(48, 48)
            avatar_24 = images.resize(24, 24)
            # Large 73x73
            #q1 = db.GqlQuery("SELECT * FROM Avatar WHERE name = :1", 'avatar_' + str(member.num) + '_large')
            q1 = Avatar.selectBy(name='avatar_' + str(member.num) + '_large')
            if (q1.count() == 1):
                avatar_large = q1[0]
                avatar_large.content = avatar_73
                avatar_large.sync()
                store.commit()  #jon add
            else:
                #qc1 = db.GqlQuery("SELECT * FROM Counter WHERE name = :1", 'avatar.max')
                qc1 =Counter.selectBy(name='avatar.max')
                if (qc1.count() == 1):
                    counter1 = qc1[0]
                    counter1.value = counter1.value + 1
                else:
                    counter1 = Counter()
                    counter1.name = 'avatar.max'
                    counter1.value = 1
                counter1.sync()
                store.commit()  #jon add
                avatar_large = Avatar()
                avatar_large.name = 'avatar_' + str(member.num) + '_large'
                avatar_large.content = avatar_73
                avatar_large.num = counter1.value
                avatar_large.sync()
                store.commit()  #jon add
            member.avatar_large_url = '/avatar/' + str(member.num) + '/large?r=' + timestamp
            member.sync()
            store.commit()  #jon add
            # Normal 48x48
            #q2 = db.GqlQuery("SELECT * FROM Avatar WHERE name = :1", 'avatar_' + str(member.num) + '_normal')
            q2 = Avatar.selectBy(name='avatar_' + str(member.num) + '_normal')
            if (q2.count() == 1):
                avatar_normal = q2[0]
                avatar_normal.content = avatar_48
                avatar_normal.sync()
                store.commit()  #jon add
            else:
                #qc2 = db.GqlQuery("SELECT * FROM Counter WHERE name = :1", 'avatar.max')
                qc2 = Counter.selectBy(name='avatar.max')
                if (qc2.count() == 1):
                    counter2 = qc2[0]
                    counter2.value = counter2.value + 1
                else:
                    counter2 = Counter()
                    counter2.name = 'avatar.max'
                    counter2.value = 1
                counter2.sync()
                avatar_normal = Avatar()
                avatar_normal.name = 'avatar_' + str(member.num) + '_normal'
                avatar_normal.content = avatar_48
                avatar_normal.num = counter2.value
                avatar_normal.sync()
                store.commit()  #jon add
            member.avatar_normal_url = '/avatar/' + str(member.num) + '/normal?r=' + timestamp
            member.sync()
            store.commit()  #jon add
            # Mini 24x24
            #q3 = db.GqlQuery("SELECT * FROM Avatar WHERE name = :1", 'avatar_' + str(member.num) + '_mini')
            q3 = Avatar.selectBy(name='avatar_' + str(member.num) + '_mini')
            if (q3.count() == 1):
                avatar_mini = q3[0]
                avatar_mini.content = avatar_24
                avatar_mini.sync()
            else:
                #qc3 = db.GqlQuery("SELECT * FROM Counter WHERE name = :1", 'avatar.max')
                qc3 = Counter.selectBy(name='avatar.max')
                if (qc3.count() == 1):
                    counter3 = qc3[0]
                    counter3.value = counter3.value + 1
                else:
                    counter3 = Counter()
                    counter3.name = 'avatar.max'
                    counter3.value = 1
                counter3.sync()
                avatar_mini = Avatar()
                avatar_mini.name = 'avatar_' + str(member.num) + '_mini'
                avatar_mini.content = avatar_24
                avatar_mini.num = counter3.value
                avatar_mini.sync()
                store.commit()  #jon add
            member.avatar_mini_url = '/avatar/' + str(member.num) + '/mini?r=' + timestamp
            member.sync()
            store.commit()  #jon add
            # Upload to MobileMe
            if config.mobileme_enabled:
                headers = {'Authorization' : 'Basic ' + base64.b64encode(config.mobileme_username + ':' + config.mobileme_password)}
                host = 'idisk.me.com'
                # Sharding
                timestamp = str(int(time.time()))
                shard = member.num % 31
                root = '/' + config.mobileme_username + '/Web/Sites/v2ex/avatars/' + str(shard)
                root_mini = root + '/mini'
                root_normal = root + '/normal'
                root_large = root + '/large'
                h = httplib.HTTPConnection(host)
                # Mini
                h.request('PUT', root_mini + '/' + str(member.num) + '.png', str(avatar_24), headers)
                response = h.getresponse()
                if response.status == 201 or response.status == 204:
                    member.avatar_mini_url = 'http://web.me.com/' + config.mobileme_username + '/v2ex/avatars/' + str(shard) + '/mini/' + str(member.num) + '.png?r=' + timestamp
                # Normal
                h.request('PUT', root_normal + '/' + str(member.num) + '.png', str(avatar_48), headers)
                response = h.getresponse()
                if response.status == 201 or response.status == 204:
                    member.avatar_normal_url = 'http://web.me.com/' + config.mobileme_username + '/v2ex/avatars/' + str(shard) + '/normal/' + str(member.num) + '.png?r=' + timestamp
                # Large
                h.request('PUT', root_large + '/' + str(member.num) + '.png', str(avatar_73), headers)
                response = h.getresponse()
                if response.status == 201 or response.status == 204:
                    member.avatar_large_url = 'http://web.me.com/' + config.mobileme_username + '/v2ex/avatars/' + str(shard) + '/large/' + str(member.num) + '.png?r=' + timestamp
                member.sync()
                store.commit()  #jon add
            # Upload to UpYun
            if config.upyun_enabled:
                u = UpYun(config.upyun_bucket, config.upyun_username, config.upyun_password)
                # Mini
                mini = avatar_24
                u.setContentMD5(md5(mini))
                mini_suffix = '/avatars/mini/' + str(member.num) + '.png'
                r = u.writeFile(mini_suffix, mini, True)
                if r == True:
                    member.avatar_mini_url = 'http://' + config.upyun_bucket + '.b0.upaiyun.com' + mini_suffix + '?r=' + timestamp
                # Normal
                normal = avatar_48
                u.setContentMD5(md5(normal))
                normal_suffix = '/avatars/normal/' + str(member.num) + '.png'
                r = u.writeFile(normal_suffix, normal, True)
                if r == True:
                    member.avatar_normal_url = 'http://' + config.upyun_bucket + '.b0.upaiyun.com' + normal_suffix + '?r=' + timestamp
                # Large
                large = avatar_73
                u.setContentMD5(md5(large))
                large_suffix = '/avatars/large/' + str(member.num) + '.png'
                r = u.writeFile(large_suffix, large, True)
                if r == True:
                    member.avatar_large_url = 'http://' + config.upyun_bucket + '.b0.upaiyun.com' + large_suffix + '?r=' + timestamp
                member.sync()
                store.commit()  #jon add
            memcache.set('Member_' + str(member.num), member, 86400 * 14)
            memcache.set('Member::' + member.username_lower, member, 86400 * 14)
            memcache.delete('Avatar::avatar_' + str(member.num) + '_large')
            memcache.delete('Avatar::avatar_' + str(member.num) + '_normal')
            memcache.delete('Avatar::avatar_' + str(member.num) + '_mini')
            self.session['message'] = '新头像设置成功'
            self.redirect('/settings/avatar')
        else:
            self.redirect('/signin')