def login(): if env.user.id: return Response().redirect('%s://%s.%s/' % \ (env.request.protocol, env.user.login, settings.domain)) referer = get_referer() if env.request.method == 'GET': return render('/auth/login.html', referer=referer, fields=ULOGIN_FIELDS) try: login = env.request.args('login') password = env.request.args('password') if not login or not password: raise NotAuthorized env.user.authenticate(login, password) if env.request.is_xhr: return Response(json.dumps({'ok': True}), mimetype='application/json') else: return Response(redirect=referer) except (KeyError, NotAuthorized): if env.request.is_xhr: return Response(json.dumps({'error': 'credentials'}), mimetype='application/json') else: return render('/auth/login.html', errors=['credentials'], referer=referer, fields=ULOGIN_FIELDS) return Response(redirect=referer)
def reset_password(code): if env.request.method != 'POST': if env.request.args('changed'): return render('/auth/new-password-changed.html') if env.request.args('fail'): return render('/auth/new-password-fail.html') return render('/auth/new-password.html') errors = [] password = env.request.args('password') confirm = env.request.args('confirm') if not password: errors.append('password') if password != confirm: errors.append('confirm') if errors: return render('/auth/new-password.html', errors=errors) if env.user.id: env.user.logout() try: user = users.reset_password(code, password) except UserNotFound: return Response(redirect='%s://%s/remember/%s?fail=1' % \ (env.request.protocol, settings.domain, code)) WebUser(user.id).authenticate() return Response(redirect='%s://%s/remember/%s?changed=1' % \ (env.request.protocol, settings.domain, code))
def unsubscribe(id): posts.unsubscribe(id) if env.request.is_xhr: return Response(json.dumps({'ok': True}), mimetype='application/json') return Response(redirect=env.request.referer)
def login(): if env.user.id: if env.request.is_xhr: raise AlreadyAuthorized return Response( redirect='%s://%s%s' % (env.request.protocol, settings.domain, userlink(env.user))) ref = referer() try: login = env.request.args('login') password = env.request.args('password') if not login or not password: raise NotAuthorized env.user.authenticate(login, password) if env.request.is_xhr: return Response(ok=True) else: return Response(redirect=ref) except (KeyError, NotAuthorized): return Response(template='/auth/login.html', code=NotAuthorized.code, message=NotAuthorized.message, errors={'password': '******'}, referer=ref, fields=ULOGIN_FIELDS)
def comments(page=1, unread=False): if not env.owner or env.owner.id != env.user.id: return Response(redirect='%s://%s.%s%s' % \ (env.request.protocol, env.user.login.lower(), settings.domain, env.request.path)) try: page = int(page) except (TypeError, ValueError): page = 1 if not page: page = 1 offset = (page - 1) * settings.page_limit plist = posts.recent_commented_posts(unread=unread, offset=offset, limit=settings.page_limit + 1) if env.request.is_xhr: for p in plist: p['created'] = timestamp(p['created']) return Response(json.dumps(plist), mimetype='application/json') return render('/comments.html', section='comments', unread=unread, posts=plist, page=page)
def messages_new(page=1): try: page = int(page) except (TypeError, ValueError): page = 1 if not page: page = 1 offset = (page - 1) * settings.page_limit plist = posts.private_unread(offset=offset, limit=settings.page_limit + 1) if not plist and page == 1: return Response(redirect='%s://%s/messages/incoming' % \ (env.request.protocol, settings.domain)) if env.request.is_xhr: for p in plist: p['created'] = timestamp(p['created']) return Response(json.dumps(plist), mimetype='application/json') return render('/messages/index.html', section='messages', posts=plist, page=page)
def unsubscribe(): if not env.owner or not env.owner.id: raise NotFound users.unsubscribe(env.owner) if env.request.is_xhr: return Response(json.dumps({'ok': True}), mimetype='application/json') return Response(redirect=env.request.referer)
def subscribe(id): try: posts.subscribe(id) except AlreadySubscribed: raise Forbidden if env.request.is_xhr: return Response(json.dumps({'ok': True}), mimetype='application/json') return Response(redirect=env.request.referer)
def unread_messages(page=1): plist, page, has_next = get_posts(posts.private_unread, page) if not plist and page == 1: return Response(redirect='%s://%s/messages/incoming' % \ (env.request.protocol, settings.domain)) return Response(template='/pages/messages/unread.html', menu='messages', owner=env.owner, posts=plist, page=page, has_next=has_next)
def del_from_blacklist(): if not env.owner or not env.owner.id: raise NotFound try: res = users.del_from_blacklist(env.owner) except SubscribeError: raise Forbidden if env.request.is_xhr: return Response(json.dumps({'ok': bool(res)}), mimetype='application/json') return Response(redirect=env.request.referer)
def add_feed(): url = env.request.args('url', '').strip() try: if url.index(settings.domain): return Response(redirect=url) except ValueError: pass if env.request.method == 'GET': return render('/feeds/add.html', section='feeds', feeds=feeds.subscriptions(), url=url) errors = env.request.args('errors') if not errors: errors = [] elif not isinstance(errors, (list, tuple)): errors = [errors] try: feed = feeds.get_feed(url) except InvalidFeedUrl: errors.append('url') except InvalidFeedType: errors.append('type') except FeedFetchError: errors.append('fetch') if errors: return render('/feeds/add.html', section='feeds', feeds=feeds.subscriptions(), url=url, errors=errors) if feed.id and feed.check_subscriber(env.user): return Response(redirect="%s://%s.%s/" % \ (env.request.protocol, feed.login.lower(), settings.domain)) try: feed.fetch() except FeedFetchError: errors.append('fetch') return render('/feeds/subscribe.html', section='feeds', feeds=feeds.subscriptions(), feed=feed, url=url)
def subscribe(): url = env.request.args('url', '').strip() if not url: return Response(redirect="%s://%s.%s/feeds/add" % \ (env.request.protocol, env.user.login.lower(), settings.domain)) try: if url.index(settings.domain): return Response(redirect=url) except ValueError: pass errors = [] try: feed = feeds.get_feed(url) feed.fetch() except InvalidFeedUrl: errors.append('url') except InvalidFeedType: errors.append('type') except FeedFetchError: errors.append('fetch') if errors: return Response(redirect="%s://%s.%s/feeds/add?url=%s&%s" % \ (env.request.protocol, env.user.login.lower(), settings.domain, urlencode(url), '&'.join(["errors=%s" % e for e in errors]))) if not feed.id: feed.save() try: env.user.subscribe(feed) except AlreadySubscribed: pass return Response(redirect="%s://%s.%s/" % \ (env.request.protocol, feed.login.lower(), settings.domain)) if env.request.method == 'GET': return render('/feeds/subscribe.html', feeds=feeds.subscriptions(), feed=feed)
def handle(environ, start_response): tm = time() env.request = Request(environ) process_request(env.request) code = None message = None try: response = resolve(env.request) except GewebError, e: code = e.code message = e.message try: response = Response(code=code, message=message, template=[ '/errors/%s.html' % e.__class__.__name__, '/%d.html' % code, '/50x.html', 'geweb/50x.html' ], error=e) except TemplateNotFound, e: response = 'No error template found'
def bookmarks(page=1): if not env.owner or env.owner.id != env.user.id: return Response(redirect='%s://%s.%s/%s' % \ (env.request.protocol, env.user.login.lower(), settings.domain, env.request.path)) try: page = int(page) except (TypeError, ValueError): page = 1 if not page: page = 1 offset = (page - 1) * settings.page_limit plist = posts.bookmarks(settings.page_limit + 1, offset) #if env.request.is_xhr: # for p in plist: # p['created'] = timestamp(p['created']) # p['text'] = html(None, p['text'], True) # return Response(json.dumps(plist), mimetype='application/json') section = 'bookmarks' return render('/bookmarks.html', section=section, posts=plist, page=page)
def ulogin(): if env.request.method == 'GET': raise Forbidden url = "http://ulogin.ru/token.php?token=%s&host=%s" % \ (env.request.args('token'), settings.domain) try: resp = urllib2.urlopen(url) data = json.loads(resp.read()) resp.close() except urllib2.URLError: return render('/profile/accounts.html', errors=['ulogin-fail']) if 'error' in data: raise Forbidden try: env.user.bind_ulogin( data['network'], data['uid'], nickname=data['nickname'], name=('%s %s' % (data['first_name'], data['last_name'])).strip(), profile=data['profile']) except (KeyError, UserExists): pass return Response(redirect='%s://%s.%s/profile/accounts?saved=1' % \ (env.request.protocol, env.user.login, settings.domain))
def unpin(id): post = Post(id) if env.user.id == post.author.id: post.set_pinned(False) return Response(redirect=env.request.referer) else: raise Forbidden
def add_post(): text = env.request.args('text', '').strip() tags = env.request.args('tags', '').strip(' \t*,;') if isinstance(tags, str): tags = tags.decode('utf-8') tags = [t.replace(u"\xa0", " ") for t in re.split(r'\s*[,;*]\s*', tags)] private = bool(env.request.args('private')) m = re.search(r'^\s*(?P<to>(?:@[a-z0-9_-]+[,\s]*)+)', text) to = parse_logins(m.group('to')) if m else [] files = _files([]) try: id = posts.add_post(text, tags=tags, to=to, private=private, files=files) except PostTextError: return render('/post-error.html') return Response(redirect='%s://%s.%s/%s' % \ (env.request.protocol, env.user.login, settings.domain, id))
def info(login): try: user = User('login', login) except UserNotFound: raise NotFound try: data = users.info(user) except SubscribeError: raise Forbidden data['login'] = login try: data['created'] = timestamp(data['created']) except (KeyError, AttributeError): pass try: data['birthdate'] = timestamp(data['birthdate']) except (KeyError, AttributeError): pass if env.user.id: data['subscribed'] = user.check_subscriber(env.user) data['rec_sub'] = user.check_rec_subscriber(env.user) if not data['subscribed']: data['bl'] = env.user.check_blacklist(user) if not data['bl']: data['wl'] = env.user.check_blacklist(user) return Response(json.dumps(data), mimetype='application/json')
def usercss(login): try: u = User('login', login) except UserNotFound: raise NotFound css = u.get_profile('www.usercss') return Response(css, mimetype='text/css')
def subscribe_rec(): if not env.owner or not env.owner.id: raise NotFound try: res = users.subscribe_rec(env.owner) except SubscribeError: raise Forbidden except (AlreadySubscribed, AlreadyRequested): res = False if env.request.is_xhr: return Response(json.dumps({'ok': bool(res)}), mimetype='application/json') return Response(redirect=env.request.referer)
def all_posts_rss(): plist = posts.select_posts(private=False, author_private=False, deny_anonymous=False, blacklist=True, limit=settings.page_limit * 4) feed = PyRSS2Gen.RSS2(title="Point.im", link='http://%s/' % (settings.domain), description="Point.im") for p in plist: if 'comment_id' in p and p['comment_id']: title = '#%s/%s' % (p['post'].id, p['comment_id']) link = 'http://%s/%s#%s' % \ (settings.domain, p['post'].id, p['comment_id']) else: title = '#%s' % p['post'].id link = 'http://%s/%s' % (settings.domain, p['post'].id) feed.items.append( PyRSS2Gen.RSSItem(author=env.owner.login, title=title, link=link, guid=link, pubDate=p['post'].created, categories=p['post'].tags, description=render_string('/rss-text.html', p=p))) return Response(feed.to_xml(), mimetype='application/rss+xml')
def blog_rss(): if not env.owner or not env.owner.id: raise UserNotFound if env.owner.type == 'feed': raise Forbidden plist = posts.recent_blog_posts(env.owner, settings.page_limit, 0) feed = PyRSS2Gen.RSS2(title="%s@point" % env.owner.login, link='http://%s.%s/' % (env.owner.login, settings.domain), description="Point.im user's blog") for p in plist: if 'comment_id' in p and p['comment_id']: title = '#%s/%s' % (p['post'].id, p['comment_id']) link = 'http://%s/%s#%s' % \ (settings.domain, p['post'].id, p['comment_id']) else: title = '#%s' % p['post'].id link = 'http://%s/%s' % (settings.domain, p['post'].id) feed.items.append( PyRSS2Gen.RSSItem(author=env.owner.login, title=title, link=link, guid=link, pubDate=p['post'].created, categories=p['post'].tags, description=render_string('/rss-text.html', p=p))) return Response(feed.to_xml(), mimetype='application/rss+xml')
def show_post(id): post = posts.show_post(id) if env.request.method == 'POST': return add_comment(post.id) if not env.owner or env.owner.id != post.author.id: return Response(redirect='%s://%s.%s/%s' % \ (env.request.protocol, post.author.login.lower(), settings.domain, id)) comments = post.comments(cuser=env.user) if env.user.is_authorized(): posts.clear_unread_posts(id) if comments: posts.clear_unread_comments(id) errors = [] if env.request.args('expired'): errors.append('expired') if env.request.args('commented'): errors.append('commented') sess = Session() tree = env.request.args('tree') if tree: if tree.lower() in ('0', 'false', 'f'): tree = False else: tree = True sess['ctree'] = tree sess.save() elif sess['ctree'] is not None: tree = sess['ctree'] else: env.user.get_profile('tree') comments_count = len(comments) if tree: cout = {} for c in comments: cout[c.id] = c if c.to_comment_id and c.to_comment_id in cout: cout[c.to_comment_id].comments.append(c) else: c.to_comment_id = None comments = filter(lambda c: not c.to_comment_id, cout.itervalues()) section = 'messages' if post.private else '' return render('/post.html', post=post, comments=comments, comments_count=comments_count, tree=tree, errors=errors, section=section)
def thumbnail(hash): url = env.request.args('u') if not url: raise NotFound if hash != md5(url).hexdigest(): raise NotFound make_thumbnail(url) return Response(redirect=url)
def userinfo(login): env.owner = User('login', login) if env.user.is_authorized() and env.user == env.owner: menu = 'blog' else: menu = '' return Response(template='/pages/userinfo.html', menu=menu, owner=env.owner)
def edit_post(id): try: post = posts.show_post(id) except PostAuthorError: raise SubscribeError if env.request.method == 'GET': return render('/post-edit.html', post=post) files = _files(post.files) @csrf def save(post): text = env.request.args('text', '').strip() tags = env.request.args('tags', '').strip(' \t*,;') if isinstance(tags, str): tags = tags.decode('utf-8') tags = [ t.replace(u"\xa0", " ") for t in re.split(r'\s*[,;*]\s*', tags) ] private = bool(env.request.args('private')) posts.edit_post(post, text=text, tags=tags, private=private, files=files) return Response(redirect='%s://%s.%s/%s' % \ (env.request.protocol, env.user.login, settings.domain, post.id)) try: return save(post) except PostUpdateError: return Response(redirect='%s://%s.%s/%s?expired=1' % \ (env.request.protocol, env.user.login, settings.domain, post.id)) except PostCommentedError: return Response(redirect='%s://%s.%s/%s?commented=1' % \ (env.request.protocol, env.user.login, settings.domain, post.id)) except PostDiffError: return render('/post-edit.html', post=post, errors=['diff'])
def unrecommend(id): comment_id = env.request.args('comment_id') try: posts.unrecommend(id, comment_id) except RecommendationNotFound: pass return Response(redirect=env.request.referer)
def remember(): if env.request.method != 'POST': if env.request.args('sent'): return render('/auth/remember-sent.html') if env.request.args('fail'): return render('/auth/remember-fail.html') return render('/auth/remember.html') errors = [] if env.user.id: user = env.user else: login = env.request.args('login') if not login: errors.append('login') else: try: user = User('login', login) except UserNotFound: errors.append('login') if not errors: try: text = env.request.args('recaptcha_response_field') challenge = env.request.args('recaptcha_challenge_field') resp = captcha.submit(challenge, text, settings.recaptcha_private_key, env.request.remote_host) if resp.is_valid: users.request_password(user) return Response(redirect='%s://%s/remember?sent=1' % \ (env.request.protocol, settings.domain)) errors.append('captcha') except urllib2.URLError: errors.append('recaptcha-fail') except AddressNotFound: return Response(redirect='%s://%s/remember?fail=1' % \ (env.request.protocol, settings.domain)) return render('/auth/remember.html', errors=errors)
def incoming_messages(page=1): plist, page, has_next = get_posts(posts.private_outgoing, page) return Response(template='/pages/messages/outgoing.html', menu='messages', owner=env.owner, posts=plist, page=page, has_next=has_next)
def tag_add_to_blacklist(): tag = env.request.args('tag', '').strip() if not tag: raise Forbidden try: tags.add_to_blacklist(tag, env.owner.login) except SubscribeError: raise Forbidden return Response(redirect=env.request.referer)
trace = trace.decode('utf-8') log.error("%s: %s" % (code, trace)) subject = 'Error at %s: %s' % (settings.domain, e.__class__.__name__) body = render('geweb/report.html', code=code, message=message, protocol=env.request.protocol, host=env.request.host, uri=env.request.uri, method=env.request.method, params=env.request.args().iteritems(), headers=env.request.headers(), globals=tb.f_globals.iteritems(), locals=tb.f_locals.iteritems(), exception=e, trace=trace) if settings.debug: response = Response(body, code=code, message=message) else: response = render('/50x.html', code=code, message=message) mail(settings.report_mail, subject=subject, body=body, html=True) if isinstance(response, (str, unicode)): response = Response(response) elif response is None: response = Response('') if not code or not message: code = response.code message = response.message process_response(response) status, headers = response.render_headers() body = response.render()