/src/main.py
Python | 2964 lines | 2898 code | 46 blank | 20 comment | 45 complexity | 61aabd1f337c08fece12c14dd462cceb MD5 | raw file
Possible License(s): AGPL-3.0
Large files files are truncated, but you can click here to view the full file
- #! coding: utf-8
- # pylint: disable-msg=W0311, W0611, E1103, E1101
- #@PydevCodeAnalysisIgnore
- from raven.contrib.flask import Sentry
-
- from flask import (Flask, request,
- render_template, render_template_string,
- redirect, abort,
- url_for, session, g, flash,
- make_response, Response)
- from flask_sslify import SSLify
- from flask.ext.oauth import OAuth
- from flask.ext.seasurf import SeaSurf
- from flask.ext.assets import Bundle, Environment as WebAssets
- from werkzeug.wrappers import BaseRequest
- from werkzeug.utils import cached_property
- from werkzeug.contrib.securecookie import SecureCookie
- from werkzeug.contrib.profiler import ProfilerMiddleware, MergeStream
- from datetime import timedelta
- from commands import getoutput
- from mimetypes import guess_type
- from simplejson import dumps, loads
- from time import mktime, strptime, sleep
- from urlparse import urlparse, urlunparse
- from jinja2 import Environment
- from werkzeug.contrib.cache import MemcachedCache
- from lib import cache
- from lib.img_utils import zoom
- from lib.json_util import default as BSON
- from helpers import extensions
- from helpers.decorators import *
- from helpers.converters import *
- import os
- import sys
- import logging
- import requests
- import traceback
- import werkzeug.serving
- import flask_debugtoolbar
- from flask_debugtoolbar_lineprofilerpanel.profile import line_profile
- import api
- import filters
- import settings
- from app import CURRENT_APP, render
- # switch from the default ASCII to UTF-8 encoding
- reload(sys)
- sys.setdefaultencoding("utf-8") #@UndefinedVariable
- requests.adapters.DEFAULT_RETRIES = 3
- app = CURRENT_APP
-
- assets = WebAssets(app)
- if settings.SENTRY_DSN:
- sentry = Sentry(app, dsn=settings.SENTRY_DSN, logging=False)
- csrf = SeaSurf(app)
- oauth = OAuth()
- @line_profile
- def render_homepage(session_id, title, **kwargs):
- """ Render homepage for signed in user """
- if session_id:
- user_id = api.get_user_id(session_id)
- if user_id:
- owner = api.get_user_info(user_id)
- else:
- owner = None
- else:
- owner = None
-
- if owner:
- friends_online = [i for i in owner.contacts \
- if i.status in ['online', 'away']]
- friends_online.sort(key=lambda k: k.last_online, reverse=True)
- if not kwargs.has_key('groups'):
- groups = api.get_groups(session_id, limit=3)
- else:
- groups = kwargs.pop('groups')
-
- for group in groups[:3]:
- group.unread_posts = api.get_unread_posts_count(session_id, group.id)
-
- unread_messages = api.get_unread_messages(session_id)
- unread_messages_count = sum([i.get('unread_count') for i in unread_messages])
- unread_notification_count = api.get_unread_notifications_count(session_id)\
- + unread_messages_count
-
- else:
- friends_online = []
- groups = []
- unread_messages = []
- unread_messages_count = 0
- unread_notification_count = 0
-
- if kwargs.has_key('stats'):
- stats = kwargs.pop('stats')
- else:
- stats = {}
-
-
- hostname = request.headers.get('Host')
- logo_text = 'Jupo'
- if hostname != settings.PRIMARY_DOMAIN:
- network_info = api.get_network_info(hostname.replace('.', '_'))
- if network_info and network_info.has_key('name'):
- logo_text = network_info['name']
- resp = Response(render_template('home.html',
- owner=owner,
- title=title,
- groups=groups,
- friends_online=friends_online,
- unread_messages=unread_messages,
- unread_messages_count=unread_messages_count,
- unread_notification_count=unread_notification_count,
- stats=stats,
- debug=settings.DEBUG,
- logo_text=logo_text,
- domain=hostname,
- **kwargs))
- if owner:
- resp.set_cookie('channel_id', api.get_channel_id(session_id))
- else:
- resp.delete_cookie('channel_id')
-
- # disallows rendering of the document when inside an iframe
- # http://javascript.info/tutorial/clickjacking
- resp.headers['X-Frame-Options'] = 'DENY'
- return resp
- def event_stream(channel):
- pubsub = api.PUBSUB.pubsub()
- pubsub.subscribe(channel)
- for message in pubsub.listen():
- yield 'retry: 100\ndata: %s\n\n' % message['data']
-
- #===============================================================================
- # URL routing and handlers
- #===============================================================================
- @app.route('/ping')
- def ping():
- session_id = session.get('session_id')
- if session_id:
- api.update_pingpong_timestamp(session_id)
- return 'pong'
- @app.route('/stream')
- def stream():
- session_id = session.get('session_id')
- if not session_id:
- abort(400)
-
- channel_id = request.cookies.get('channel_id')
- resp = Response(event_stream(channel_id),
- mimetype="text/event-stream")
- resp.headers['X-Accel-Buffering'] = 'no'
- return resp
- @csrf.exempt
- @app.route("/autocomplete")
- @line_profile
- def autocomplete():
- session_id = session.get("session_id")
- query = request.args.get('query')
- type = request.args.get('type')
-
- if not query: # preload all groups & coworkers
- owners = api.get_contacts(session_id)
- user_ids = [i.id for i in owners]
- for user in api.get_all_users():
- if user.id not in user_ids:
- user_ids.append(user.id)
- owners.append(user)
-
- if type != 'user':
- groups = api.get_groups(session_id)
- group_ids = [i.id for i in groups]
- owners.extend(groups)
-
- items = [{'id': 'public',
- 'name': 'Public',
- 'avatar': '/public/images/public-group.png',
- 'type': 'group'}]
-
- for group in api.get_all_groups():
- if group.id not in group_ids:
- group_ids.append(group.id)
- owners.append(group)
-
- else:
- items = []
-
- for i in owners:
- if i.is_group():
- info = {'name': i.name,
- 'id': str(i.id),
- 'avatar': '/public/images/group-icon2.png',
- 'type': 'group'}
- items.append(info)
- else:
- names = [i.name]
- for name in names:
- info = {'name': name,
- 'id': str(i.id),
- 'avatar': i.avatar,
- 'type': 'user'}
-
- items.append(info)
-
- else:
-
- if type == 'user': # mentions
- _items = api.autocomplete(session_id, query)
- items = []
- for item in _items:
- if not api.is_group(item.get('id')): # only show user, not group
- info = api.get_user_info(item.get('id'))
- avatar = info.avatar
- type = 'user'
-
- items.append({'id': str(item.get('id')),
- 'name': item.get('name', item.get('email')),
- 'avatar': avatar,
- 'type': type})
- else:
- _items = api.autocomplete(session_id, query)
- items = []
- for item in _items:
- info = api.get_owner_info_from_uuid(item.get('id'))
- avatar = '/public/images/group.png' if info.is_group() else info.avatar
-
- items.append({'id': str(item.get('id')),
- 'name': item.get('name', item.get('email')),
- 'avatar': avatar,
- 'type': item.get('type')})
-
- # emoticons = [{'id': 'happy',
- # 'type': 'emoticon',
- # 'name': 'happy',
- # 'avatar': 'https://5works.s3.amazonaws.com/emoticons/1.gif'},
- # {'id': 'sad',
- # 'type': 'emoticon',
- # 'name': 'sad',
- # 'avatar': 'https://5works.s3.amazonaws.com/emoticons/2.gif'},
- # ]
- # items.extend(emoticons)
- return dumps(items)
- @app.route("/search", methods=['GET', 'OPTIONS', 'POST'])
- @login_required
- @line_profile
- def search():
- t0 = api.utctime()
- session_id = session.get("session_id")
- query = request.form.get('query', request.args.get('query', '')).strip()
- item_type = request.args.get('type')
- page = int(request.args.get('page', 1))
- ref_user_id = request.args.get('user')
-
- ref = request.args.get('ref')
- if ref and 'group-' in ref:
- group_id = ref.split('-')[1]
- group = api.get_group_info(session_id, group_id)
- if item_type == 'people':
- title = 'Add people to group'
- else:
- title = 'Invite your friends'
- elif ref == 'everyone':
- title = 'Invite your friends'
- group_id = group = None
- else:
- group_id = group = None
- title = 'Add Contacts'
-
- user_id = api.get_user_id(session_id)
- owner = api.get_user_info(user_id)
-
-
- if item_type in ['people', 'email']:
-
- if request.method == 'OPTIONS':
- if query:
- if item_type == 'people':
- users = api.people_search(query, group_id)
- if users:
- users = [i for i in users \
- if i.id not in owner.contact_ids and i.id != owner.id]
- else:
- users = [i for i in api.get_coworkers(session_id) \
- if i.id not in group.member_ids and i.id != owner.id]
- else:
- users = [i for i in owner.google_contacts \
- if api.get_user_id_from_email_address(i.email) not in group.member_ids]
-
- elif group_id:
- if item_type == 'email':
- users = [i for i in owner.google_contacts \
- if api.get_user_id_from_email_address(i.email) not in group.member_ids]
- else:
- users = [i for i in api.get_coworkers(session_id) \
- if i.id not in group.member_ids and i.id != owner.id]
- else:
- if item_type == 'email':
- users = [i for i in owner.google_contacts]
- else:
- users = [i for i in api.get_coworkers(session_id) \
- if i.id not in owner.contact_ids and i.id != owner.id]
-
- return dumps({'title': title,
- 'body': render_template('people_search.html',
- title=title,
- mode='search',
- type=item_type,
- group_id=group_id,
- group=group,
- users=users,
- query=query,
- owner=owner)})
- else:
- if item_type == 'people':
- users = api.people_search(query)
- else:
- q = query.lower()
- users = [i for i in owner.google_contacts \
- if i.email and i.email.lower().startswith(q)]
-
-
- if group_id:
- out = [i for i in users if i.email and i.id not in group.member_ids and i.id != owner.id]
- out.extend([i for i in users if i.email and i.id != owner.id and i.id in group.member_ids])
- users = out
- else:
- users = [i for i in users if i.email]
-
-
- if users:
- return ''.join(render_template('user.html',
- mode='search',
- user=user,
- group_id=group_id,
- group=group,
- type=item_type,
- query=query,
- owner=owner,
- title=title) \
- for user in users if user.email)
- else:
- if item_type == 'email':
- return "<li>Type your friend's email address</li>"
- else:
- return "<li>0 results found</li>"
-
- # search posts
- results = api.search(session_id, query, item_type,
- ref_user_id=ref_user_id, page=page)
- if results and results.has_key('counters'):
- hits = results.get('hits', 0)
- total = sum([i['count'] for i in results.get('counters')])
- counters = results['counters']
- else:
- hits = 0
- total = 0
- counters = {}
-
- due = api.utctime() - t0
- owner = api.get_owner_info(session_id)
- coworkers = api.get_coworkers(session_id)
-
- if request.method == 'GET':
- return render_homepage(session_id, 'Results for "%s"' % query,
- query=query,
- type=item_type,
- due='%.3f' % due,
- total=total,
- hits=hits,
- coworkers=coworkers,
- user=user,
- view='results',
- page=page,
- counters=counters)
-
- if page == 1:
- body = render_template('results.html', owner=owner,
- query=query,
- type=item_type,
- due='%.3f' % due,
- total=total,
- hits=hits,
- coworkers=coworkers,
- user=user,
- view='results',
- page=page,
- counters=counters)
- else:
- posts = [render(hits, "feed", owner, 'results')]
-
- if len(hits) == 0:
- posts.append(render_template('more.html', more_url=None))
- else:
- more_url = '/search?query=%s&page=%s' % (query, page+1)
- if item_type:
- more_url += '&type=%s' % item_type
- if user:
- more_url += '&user=%s' % user
-
- posts.append(render_template('more.html', more_url=more_url))
- return ''.join(posts)
-
- # TODO: render 1 lần thôi :(
- if body.split('<ul id="stream">')[-1].split('<script>')[0].split('right-sidebar')[0].count(query) < 2:
- spelling_suggestion = api.get_spelling_suggestion(query)
- app.logger.debug('spelling suggestion: %s' % spelling_suggestion)
- body = render_template('results.html', owner=owner,
- spelling_suggestion=spelling_suggestion,
- query=query,
- type=item_type,
- due='%.3f' % due,
- total=total,
- hits=hits,
- coworkers=coworkers,
- user=user,
- view='results',
- counters=counters)
-
- json = dumps({'title': '%s - Jupo Search' % query,
- 'body': body})
- return Response(json, content_type='application/json')
- #@app.route("/", methods=["GET", "OPTIONS"])
- @app.route('/<any(discover, starred, hot, incoming, shared_by_me):name>', methods=['GET', 'OPTIONS'])
- @app.route('/<any(discover, starred, hot, incoming, shared_by_me):name>/page<int:page>', methods=['OPTIONS'])
- def discover(name='discover', page=1):
- code = request.args.get('code')
- user_id = api.get_user_id(code)
- if user_id:
- session['session_id'] = code
- return render_homepage(code, 'Complete Profile',
- code=code, user_id=user_id)
-
- session_id = session.get("session_id")
-
-
- app.logger.debug('session_id: %s' % session_id)
-
- user_id = api.get_user_id(session_id)
-
- if user_id:
- owner = api.get_user_info(user_id)
- if name == 'starred':
- category = name
- feeds = api.get_starred_posts(session_id, page=page)
- elif name == 'hot':
- category = name
- feeds = api.get_hot_posts(page=page)
- elif name == 'shared_by_me':
- category = name
- feeds = api.get_shared_by_me_posts(session_id, page=page)
- elif request.path in ['/', '/incoming', '/discover']:
- # feeds = api.get_incoming_posts(session_id, page=page)
- feeds = api.get_discover_posts(session_id, page=page)
- # feeds = api.get_public_posts(session_id=session_id, page=page)
- category = None
- else:
- feeds = api.get_public_posts(session_id=session_id, page=page)
- category = None
- else:
- feeds = api.get_public_posts(session_id=session_id, page=page)
- owner = category = None
- if session.has_key('session_id'):
- session.pop('session_id')
-
- public_groups = api.get_open_groups(limit=10)
- if request.method == 'OPTIONS':
- if page == 1:
- menu = render_template('menu.html',
- owner=owner,
- category=category,
- view='discover')
-
- body = render_template('discover.html',
- view='discover',
- category=category,
- public_groups=public_groups,
- owner=owner,
- title='Discover',
- feeds=feeds)
-
-
- json = dumps({"body": body,
- "menu": menu,
- "title": 'Discover'})
-
- resp = Response(json, mimetype='application/json')
- return resp
- else:
- posts = []
- for feed in feeds:
- posts.append(render(feed, "feed", owner, 'discover'))
- if len(feeds) == 0:
- posts.append(render_template('more.html', more_url=None))
- else:
- posts.append(render_template('more.html',
- more_url='/%s/page%d' \
- % (request.path.split('/')[1], page+1)))
-
- return ''.join(posts)
- else:
- if not user_id:
- # return render_homepage(session_id, 'Get work done. Faster. | Jupo',
- # view='intro')
- return render_template('landing_page.html')
- else:
- return render_homepage(session_id, 'Discover',
- view='discover',
- feeds=feeds)
- @app.route('/invite', methods=['GET', 'POST'])
- def invite():
- email = request.form.get('email', request.args.get('email'))
- group_id = request.form.get('group_id', request.args.get('group_id'))
- session_id = session.get("session_id")
- api.invite(session_id, email, group_id)
- return ' ✔ Done '
- @app.route('/welcome', methods=['GET', 'OPTIONS'])
- def welcome():
- if request.method == 'GET':
- session_id = session.get("session_id")
- return render_homepage(session_id, 'Getting Started', view='welcome')
- else:
- body = render_template('welcome.html', view='welcome')
- return dumps({'body': body,
- 'title': 'Welcome to Jupo'})
-
- @app.route('/privacy')
- def privacy():
- return redirect('https://www.jupo.com/note/340925645733232641')
- @app.route('/terms')
- def terms():
- return redirect('https://www.jupo.com/note/340921286333038593')
- @app.route('/about')
- def about():
- return render_template('about.html')
-
-
- @app.route('/notify_me', methods=['POST'])
- def notify_me():
- email = request.form.get('email')
- if not email:
- abort(400, 'Missing email')
- state = api.notify_me(email)
- return 'Thank you!'
- @app.route('/jobs')
- def jobs():
- return render_template('jobs_v2.html', title='Jupo - Jobs')
-
- @app.route("/<any(sign_in, sign_up, sign_out, forgot_password, reset_password):action>", methods=["GET", "OPTIONS", "POST"])
- def authentication(action=None):
- hostname = request.headers.get('Host')
-
- db_name = hostname.replace('.', '_')
-
- primary_domain = '.'.join(settings.PRIMARY_DOMAIN.rsplit('.', 2)[-2:])
- if hostname != settings.PRIMARY_DOMAIN:
- network_info = api.get_network_info(db_name)
- else:
- network_info = {'name': 'Jupo'}
-
- if request.path.endswith('sign_in'):
-
-
- if request.method == 'OPTIONS':
- data = dumps({'title': 'Sign in to Jupo',
- 'body': render_template('sign_in.html',
- domain=hostname,
- PRIMARY_DOMAIN=settings.PRIMARY_DOMAIN)})
- resp = Response(data, mimetype='application/json')
- return resp
-
- elif request.method == "GET":
- resp = Response(render_template('sign_in.html',
- domain=hostname,
- PRIMARY_DOMAIN=settings.PRIMARY_DOMAIN,
- network_info=network_info))
- return resp
-
-
- email = request.form.get("email")
- password = request.form.get("password")
- back_to = request.form.get('back_to', request.args.get('back_to'))
- user_agent = request.environ.get('HTTP_USER_AGENT')
- app.logger.debug(user_agent)
- remote_addr = request.environ.get('REMOTE_ADDR')
- session_id = api.sign_in(email, password,
- user_agent=user_agent, remote_addr=remote_addr)
- app.logger.debug(session_id)
- if session_id:
-
- # Sign in for all networks
- if db_name:
- db_names = api.get_db_names(email)
- if db_name not in db_names:
- api.add_db_name(email, db_name)
-
- for db in db_names:
- if db != db_name:
- api.update_session_id(email, session_id, db)
-
- session.permanent = True
- session['session_id'] = session_id
- if back_to:
- resp = redirect(back_to)
- resp.set_cookie('channel_id', api.get_channel_id(session_id))
- else:
- resp = redirect('/news_feed')
- resp.set_cookie('channel_id', api.get_channel_id(session_id))
- return resp
- else:
- message = 'Wrong email address and password combination.'
- resp = redirect('/?email=%s&message=%s' % (email, message))
- resp.set_cookie('new_user', '0')
- return resp
-
- elif request.path.endswith('sign_up'):
- if request.method == 'GET':
- welcome = request.args.get('welcome')
- resp = Response(render_template('sign_up.html',
- welcome=welcome,
- domain=hostname,
- PRIMARY_DOMAIN=settings.PRIMARY_DOMAIN,
- network_info=network_info))
- return resp
-
- email = request.form.get('email').strip()
- name = request.form.get('name')
- password = request.form.get('password', '')
-
- alerts = {}
- if email and api.is_exists(email):
- alerts['email'] = '"%s" is already in use.' % email
- if len(password) < 6:
- alerts['password'] = 'Your password must be at least 6 characters long.'
-
-
- if alerts.keys():
- data = dumps(alerts)
- return Response(data, mimetype='application/json')
-
- else:
- session_id = api.sign_up(email, password, name)
- if session_id:
-
- # Sign in for all networks
- if db_name:
- db_names = api.get_db_names(email)
- if db_name not in db_names:
- api.add_db_name(email, db_name)
-
- for db in db_names:
- if db != db_name:
- api.update_session_id(email, session_id, db)
-
- session['session_id'] = session_id
- return redirect('/reminders')
- else:
- return redirect('/')
-
- elif request.path.endswith('sign_out'):
- session_id = session.get('session_id')
- if session_id:
- user_id = api.get_user_id(session_id)
- email = api.get_user_info(user_id).email
-
- app.logger.debug('sign out: %s' % session_id)
- api.set_status(session_id, 'offline')
- api.sign_out(session_id)
- session.pop('session_id')
-
-
- # Sign out all networks
- if db_name:
- db_names = api.get_db_names(email)
- if db_name not in db_names:
- api.add_db_name(email, db_name)
-
- for db in db_names:
- if db != db_name:
- api.sign_out(session_id, db_name=db)
-
- return redirect('/')
-
- elif request.path.endswith('forgot_password'):
- if request.method == 'GET':
- return render_template('reset_password.html')
- if request.method == 'OPTIONS':
- data = dumps({'title': 'Jupo - Forgot your password?',
- 'body': render_template('forgot_password.html')})
- return Response(data, mimetype='application/json')
- else:
- email = request.form.get('email')
- if not email:
- abort(400)
- api.forgot_password(email)
- return redirect("/?message=Please check your inbox and follow the instructions in the email")
-
- elif request.path.endswith('reset_password'):
- if request.method == 'GET':
- code = request.args.get('code')
- if not code:
- return redirect('/news_feed')
- email = api.FORGOT_PASSWORD.get(code)
- if email:
- resp = {'title': 'Reset your password',
- 'body': render_template('reset_password.html',
- email=email, code=code)}
- return render_homepage(None, 'Reset your password',
- view='reset_password', email=email, code=code)
- return redirect('/?message=Link expired')
-
- else:
- code = request.form.get('code')
- new_password = request.form.get('password')
- if not code or not new_password:
- abort(400)
- email = api.FORGOT_PASSWORD.get(code)
- if not email:
- abort(410)
- user_id = api.get_user_id_from_email_address(email)
- if not user_id:
- abort(400)
- else:
- api.reset_password(user_id, new_password)
- session_id = api.sign_in(email, new_password)
- session['session_id'] = session_id
- return redirect('/news_feed')
-
-
- @app.route('/oauth/google')
- def google_login():
- domain = request.args.get('domain', settings.PRIMARY_DOMAIN)
-
- return redirect('https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https://www.googleapis.com/auth/userinfo.email+https://www.googleapis.com/auth/userinfo.profile+https://www.google.com/m8/feeds/&redirect_uri=%s&approval_prompt=auto&state=%s&client_id=%s&hl=en&from_login=1&as=-773fbbe34097e4fd&pli=1&authuser=0' \
- % (settings.GOOGLE_REDIRECT_URI, domain, settings.GOOGLE_CLIENT_ID))
- @app.route('/oauth/google/authorized')
- def google_authorized():
- code = request.args.get('code')
- domain = request.args.get('state', settings.PRIMARY_DOMAIN)
-
- # get access_token
- url = 'https://accounts.google.com/o/oauth2/token'
- resp = requests.post(url, data={'code': code,
- 'client_id': settings.GOOGLE_CLIENT_ID,
- 'client_secret': settings.GOOGLE_CLIENT_SECRET,
- 'redirect_uri': settings.GOOGLE_REDIRECT_URI,
- 'grant_type': 'authorization_code'})
- data = loads(resp.text)
-
- # app.logger.debug(data)
-
- # fetch user info
- url = 'https://www.googleapis.com/oauth2/v1/userinfo'
- resp = requests.get(url, headers={'Authorization': '%s %s' \
- % (data.get('token_type'),
- data.get('access_token'))})
- user = loads(resp.text)
-
-
- url = 'https://www.google.com/m8/feeds/contacts/default/full/?max-results=5000'
- resp = requests.get(url, headers={'Authorization': '%s %s' \
- % (data.get('token_type'),
- data.get('access_token'))})
- contacts = api.re.findall("address='(.*?)'", resp.text)
- if contacts:
- contacts = list(set(contacts))
-
- db_name = domain.lower().strip().replace('.', '_')
- session_id = api.sign_in_with_google(email=user.get('email'),
- name=user.get('name'),
- gender=user.get('gender'),
- avatar=user.get('picture'),
- link=user.get('link'),
- locale=user.get('locale'),
- verified=user.get('verified_email'),
- google_contacts=contacts,
- db_name=db_name)
-
- if db_name:
- email = user.get('email')
- if email:
- db_names = api.get_db_names(email)
- if db_name not in db_names:
- api.add_db_name(email, db_name)
-
- for db in db_names:
- if db != db_name:
- api.update_session_id(email, session_id, db)
-
- if domain == settings.PRIMARY_DOMAIN:
- session['session_id'] = session_id
- return redirect('/')
- else:
- url = 'http://%s/?session_id=%s' % (domain, session_id)
- resp = redirect(url)
- return resp
-
-
-
-
-
-
- if settings.FACEBOOK_APP_ID and settings.FACEBOOK_APP_SECRET:
- facebook = oauth.remote_app('facebook',
- base_url='https://graph.facebook.com/',
- request_token_url=None,
- access_token_url='/oauth/access_token',
- authorize_url='https://www.facebook.com/dialog/oauth',
- consumer_key=settings.FACEBOOK_APP_ID,
- consumer_secret=settings.FACEBOOK_APP_SECRET,
- request_token_params={'scope': 'email'}
- )
-
- @app.route('/oauth/facebook')
- def facebook_login():
- if not facebook:
- abort(501)
- # return facebook.authorize(callback='http://play.jupo.com/oauth/facebook/authorized')
- callback_url = url_for('facebook_authorized',
- domain=request.args.get('domain', settings.PRIMARY_DOMAIN),
- _external=True)
- app.logger.debug(callback_url)
- return facebook.authorize(callback=callback_url)
-
-
-
- @app.route('/oauth/facebook/authorized')
- @facebook.authorized_handler
- def facebook_authorized(resp):
- domain = request.args.get('domain', settings.PRIMARY_DOMAIN)
-
- if resp is None:
- return 'Access denied: reason=%s error=%s' % (request.args['error_reason'],
- request.args['error_description'])
- session['facebook_access_token'] = (resp['access_token'], '')
-
- if request.args.get('fb_source') == 'notification':
- return redirect('/')
-
- retry_count = 0
- while retry_count < 3:
- try:
- me = facebook.get('/me')
- break
- except:
- retry_count += 1
- sleep(1)
-
- retry_count = 0
- while retry_count < 3:
- try:
- friends = facebook.get('/me/friends?limit=5000')
- break
- except:
- retry_count += 1
- sleep(1)
-
- facebook_id = me.data['id']
- friend_ids = [i['id'] for i in friends.data['data'] if isinstance(i, dict)]
-
- db_name = domain.lower().strip().replace('.', '_')
- session_id = api.sign_in_with_facebook(email=me.data.get('email'),
- name=me.data.get('name'),
- gender=me.data.get('gender'),
- avatar='https://graph.facebook.com/%s/picture' % facebook_id,
- link=me.data.get('link'),
- locale=me.data.get('locale'),
- timezone=me.data.get('timezone'),
- verified=me.data.get('verified'),
- facebook_id=facebook_id,
- facebook_friend_ids=friend_ids,
- db_name=db_name)
-
- if db_name:
- email = me.data.get('email')
- if email:
- db_names = api.get_db_names(email)
- if db_name not in db_names:
- api.add_db_name(email, db_name)
-
- for db in db_names:
- if db != db_name:
- api.update_session_id(email, session_id, db)
-
- if domain == settings.PRIMARY_DOMAIN:
- session['session_id'] = session_id
- return redirect('/')
- else:
- url = 'http://%s/?session_id=%s' % (domain, session_id)
- resp = redirect(url)
- return resp
-
-
- @facebook.tokengetter
- def get_facebook_token():
- return session.get('facebook_access_token')
-
-
- @app.route('/reminders', methods=['GET', 'OPTIONS', 'POST'])
- @app.route('/reminder/new', methods=["POST"])
- @app.route('/reminder/<int:reminder_id>/check', methods=["POST"])
- @app.route('/reminder/<int:reminder_id>/uncheck', methods=["POST"])
- @login_required
- @line_profile
- def reminders(reminder_id=None):
- session_id = session.get("session_id")
- message = request.form.get('message')
- if request.path.endswith('/new'):
- id = api.new_reminder(session_id, message)
- return str(id)
- elif request.path.endswith('/check'):
- api.check(session_id, reminder_id)
- return 'Done'
- elif request.path.endswith('/uncheck'):
- api.uncheck(session_id, reminder_id)
- return 'Done'
- else:
- reminders_list = api.get_reminders(session_id)
- if request.method == 'GET':
- return render_homepage(session_id, 'Reminders',
- view='reminders',
- reminders=reminders_list)
- else:
- body = render_template('reminders.html',
- view='reminders',
- reminders=reminders_list)
-
- json = dumps({"body": body,
- "title": 'Reminders'})
- return Response(json, mimetype='application/json')
-
-
- @app.route("/notes", methods=['GET', 'OPTIONS'])
- @app.route("/notes/page<int:page>", methods=['OPTIONS'])
- @login_required
- @line_profile
- def notes(page=1):
- view = 'notes'
- session_id = session.get("session_id")
- user_id = api.get_user_id(session_id)
- owner = api.get_user_info(user_id)
-
- title = "Notes"
- notes = api.get_notes(session_id, page=page)
-
- if page == 1:
- reference_notes = api.get_reference_notes(session_id, 10)
- else:
- reference_notes = []
-
- app.logger.debug(notes)
-
-
- if request.method == "OPTIONS":
- if page > 1:
- stream = ''
- posts = []
- for note in notes:
- posts.append(render(note, "note", owner, view, request=request))
- if len(notes) == 0:
- posts.append(render_template('more.html', more_url=None))
- else:
- posts.append(render_template('more.html',
- more_url='/notes/page%d' % (page+1)))
- return ''.join(posts)
- else:
- menu = render_template('menu.html',
- view=view)
- body = render_template('notes.html',
- view=view,
- title=title,
- owner=owner,
- request=request,
- reference_notes=reference_notes,
- notes=notes)
-
-
- json = dumps({"body": body,
- "menu": menu,
- "title": title})
- return Response(json, mimetype='application/json')
- else:
- return render_homepage(session_id, title,
- view=view,
- request=request,
- reference_notes=reference_notes,
- notes=notes)
-
- @app.route("/note/new", methods=["GET", "OPTIONS", "POST"])
- @app.route("/note/<int:note_id>", methods=["GET", "OPTIONS"])
- @app.route("/note/<int:note_id>/edit", methods=["OPTIONS"])
- @app.route("/note/<int:note_id>/v<int:version>", methods=["OPTIONS", "POST"])
- @app.route("/note/<int:note_id>/<action>", methods=["GET", "OPTIONS", "POST"])
- @login_required
- def note(note_id=None, action=None, version=None):
- session_id = session.get("session_id")
- owner = api.get_owner_info(session_id)
- content = info = None
- if request.path == '/note/new':
- if request.method == 'GET':
- note = {}
- title = 'New Note'
- mode = 'edit'
- view = 'notes'
- return render_homepage(session_id, title,
- view=view,
- note=note, mode=mode)
- elif request.method == 'OPTIONS':
- title = 'New Note'
- mode = 'edit'
- note = {}
- else:
- title = request.form.get('title', 'Untitled Note')
- content = request.form.get('content')
- note_id = request.form.get('note_id')
-
- viewers = request.form.get('viewers')
- if viewers:
- viewers = viewers.split(',')
- else:
- viewers = []
-
- attachments = request.form.get('attachments')
- if attachments:
- attachments = attachments.rstrip(',').split(',')
- else:
- attachments = []
- note_id = api.new_note(session_id, title, content, attachments, viewers)
-
- return dumps({'redirect': '/note/%s' % note_id})
- elif action and action == 'last_changes':
- note = api.compare_with_previous_version(session_id, note_id, revision=0)
- mode = 'view'
- action = 'compare'
- title = 'Notes - Track changes'
-
- elif version is not None:
- app.logger.debug(version)
- note = api.get_note(session_id, note_id, version)
- mode = 'view'
- title = '%s v%s | Jupo Notes' % (note.title, version)
-
- elif request.path.endswith('/edit'):
- note = api.get_note(session_id, note_id)
- title = 'Notes - EditMode - %s' % note.title
- mode = 'edit'
-
- elif action == 'update':
- title = request.form.get('title', 'Untitled Note')
- content = request.form.get('content')
- viewers = request.form.get('viewers')
- if viewers:
- viewers = viewers.split(',')
- else:
- viewers = []
-
- attachments = request.form.get('attachments')
- app.logger.debug(attachments)
- if attachments:
- attachments = attachments.rstrip(',').split(',')
- else:
- attachments = []
-
- if note_id:
- api.update_note(session_id, note_id, title, content, attachments, viewers)
- else:
- note_id = api.new_note(session_id, title, content, attachments, viewers)
-
- return dumps({'redirect': '/note/%s' % note_id})
-
- elif action == 'remove':
- session_id = session.get("session_id")
- id = api.remove_note(session_id, note_id)
- return id
-
- elif action == 'mark_official':
- api.mark_official(session_id, note_id)
- return 'Done'
-
- elif action == 'mark_unofficial':
- api.mark_unofficial(session_id, note_id)
- return 'Done'
-
- elif action == 'mark_as_read':
- api.mark_as_read(session_id, note_id)
- return ':)'
-
- # elif action and action.startswith('restore_from_'):
- # revision = action.lstrip('restore_from_')
- # if revision.isdigit():
- # api.restore_note(session_id, note_id, int(revision))
- # note = api.get_note(session_id, note_id)
- # title = 'Notes - %s' % info.title
- # mode = 'view'
- # else:
- # pass #TODO: return an error page with code = 405
-
- elif action == 'comment':
- message = request.form.get('message')
- comment = api.new_comment(session_id, message, note_id)
- return render_template('comment.html',
- comment=comment,
- owner=owner,
- prefix='note')
-
- else:
- note = api.get_note(session_id, note_id)
-
- if not session_id and note is False:
- return redirect('/?back_to=%s' % request.path)
-
- if not note.id:
- abort(404)
- mode = 'view'
-
- recents = api.get_notes(session_id, limit=5)
- view = 'notes'
- if version is None and info:
- version = len(note.to_dict()['version'])
- group_id = request.args.get('group_id')
- if group_id:
- group = api.get_group_info(session_id, group_id)
- else:
- group = None
-
- if request.method in ["POST", "OPTIONS"]:
- body = render_template('notes.html',
- view='notes',
- mode=mode,
- action=action,
- version=version,
- recents=recents,
- note=note,
- group=group,
- owner=owner,
- content=content)
- info = {'body': body}
- if note:
- info['title'] = note.title
- else:
- info['title'] = 'Untitle Note'
- return Response(dumps(info), mimetype='application/json')
- else:
- return render_homepage(session_id, note.title,
- version=version,
- group=group, note=note, view='notes', mode='view')
- @app.route('/u<key>')
- @app.route('/u/<int:note_id>')
- def share_to_anyone_with_the_link(note_id=None, key=None):
- session_id = session.get("session_id")
- if key:
- doc = api.get_doc_by_key(key)
- return render_homepage(session_id, 'Note',
- view='discover', mode='view', doc=doc)
-
- else:
- key = api.get_key(session_id, note_id)
- if not key:
- abort(404)
- return redirect('/u' + key)
-
- #===============================================================================
- # Files
- #===============================================================================
- @app.route("/public/<path:filename>")
- def public_files(filename):
- filedata = cache.get('file:%s' % os.path.basename(filename)) \
- if not settings.DEBUG else None
-
- if not filedata:
- path = os.path.join(os.path.dirname(__file__), 'public', filename)
- if not os.path.exists(path):
- abort(404, 'File not found')
- filedata = open(path).read()
-
- response = make_response(filedata)
- response.headers['Content-Length'] = len(filedata)
- response.headers['Content-Type'] = guess_type(filename)[0]
- response.headers['Cache-Control'] = 'public'
- response.headers['Expires'] = '31 December 2037 23:59:59 GMT'
- return response
- @app.route("/favicon.ico")
- def favicon():
- path = 'public/favicon.ico'
- filedata = open(path).read()
- response = make_response(filedata)
- response.headers['Content-Length'] = len(filedata)
- response.headers['Content-Type'] = 'image/x-icon'
- return response
- @app.route('/update_profile_picture', methods=['POST'])
- @app.route('/user/<int:user_id>', methods=['GET', 'OPTIONS'])
- @app.route('/user/<int:user_id>/page<int:page>', methods=['GET', 'OPTIONS'])
- @app.route('/user/<int:user_id>/update', methods=['POST'])
- @app.route('/user/<int:user_id>/complete_profile', methods=['POST'])
- @app.route('/user/<int:user_id>/follow', methods=['POST'])
- @app.route('/user/<int:user_id>/unfollow', methods=['POST'])
- @app.route('/user/<int:user_id>/<view>', methods=['GET', 'OPTIONS'])
- @login_required
- @line_profile
- def user(user_id=None, page=1, view=None):
- session_id = session.get("session_id")
-
- if request.path == '/update_profile_picture':
- fid = request.args.get('fid')
- api.update_user_info(session_id, {'avatar': long(fid)})
- return 'OK'
-
- owner = api.get_owner_info(session_id)
- user = api.get_user_info(user_id)
- if not user.id:
- abort(404)
-
- if view in ['edit', 'update_profile']:
- resp = {'title': 'Update Profile',
- 'body': render_template('user.html',
- mode='edit',
- view='update_profile',
- owner=owner)}
- return Response(dumps(resp), mimetype='application/json')
- elif view == 'change_password':
- resp = {'title': 'Change Password',
- 'body': render_template('user.html',
- mode='change_password',
- owner=user)}
- return Response(dumps(resp), mimetype='application/json')
-
- elif request.path.endswith('/complete_profile'):
- name = request.form.get('name')
- gender = request.form.get('gender')
-
- password = request.form.get('password')
- avatar = request.files.get('file')
-
- fid = api.new_attachment(session_id, avatar.filename, avatar.stream.read())
- new_session_id = api.complete_profile(session_id,
- name, password, gender, fid)
-
- resp = redirect('/news_feed')
- if new_session_id:
- session['session_id'] = new_session_id
- return resp
-
- elif request.path.endswith('/update'):
- old_password = request.form.get('current_password')
- new_password = request.form.get('new_password')
- confirm_new_password = request.form.get('confirm_new_password')
-
- if old_password:
- if new_password != confirm_new_password:
- return redirect('/?message=New password does not match')
- else:
- ok = api.change_password(session_id, old_password, new_password)
-
- api.set_status(session_id, 'offline')
- api.sign_out(session_id)
- session.pop('session_id')
-
- return redirect('/?message=Password updated successfully.')
-
- if not old_password and new_password and new_password == confirm_new_password:
- if owner.has_password():
- return redirect('/?message=Please enter your current password.')
- else:
- user_id = api.get_user_id(session_id)
- api.reset_password(user_id, new_password)
- return redirect('/?message=New password updated successfully.')
-
-
- name = request.form.get('name')
- gender = request.form.get('gender')
-
-
- intro = request.form.get('intro')
- location = request.form.get('location')
-
- if location:
- info = {'name': name,
- 'gender': gender,
- 'location': location,
- 'introduction': intro}
- else:
- info = {'name': name,
- 'gender': gender,
- 'introduction': intro}
-
-
- disabled_notifications = []
- if not request.form.get('comments'):
- disabled_notifications.append('comments')
- if not request.form.get('share_posts'):
- disabled_notifications.append('share_posts')
- if not request.form.get('mentions'):
- disabled_notifications.append('mentions')
-
- info['disabled_notifications'] = disabled_notifications
-
- birthday_day = request.form.get('birthday-day')
- birthday_month = request.form.get('birthday-month')
- birthday_year = request.form.get('birthday-year')
- if birthday_day.isdigit() and birthday_month.isdigit() and birthday_year.isdigit():
- info['birthday'] = '%s/%s/%s' % (birthday_day, birthday_month, birthday_year)
-
-
- phone = request.form.get('phone')
- if phone.replace('+', '').replace(' ', '').isdigit():
- info['phone'] = phone
-
- fid = request.form.get('fid')
- if fid:
- info['avatar'] = long(fid)
- api.update_user_info(session_id, info)
- return redirect('/news_feed')
-
- elif request.path.endswith('/follow'):
- api.add_to_contacts(session_id, user_id)
- # api.follow(session_id, user_id)
- return 'Done'
-
- elif request.path.endswith('/unfollow'):
- api.remove_from_contacts(session_id, user_id)
- # api.unfollow(session_id, user_id)
- return 'Done'
-
- elif view == 'groups':
- return dumps({'body': render_template('groups.html',
- user=user,
- owner=owner,
- groups=user.groups)})
- elif view == 'followers':
- users = [api.get_user_info(user_id) for user_id in user.followers]
- return dumps({'body': render_template('users.html',
- title='Followers',
- users=users)})
-
- elif view == 'following':
- users = [api.get_user_info(user_id) for user_id in user.following_users]
- return dumps({'body': render_template('users.html',
- title='Following',
- users=users)})
-
- elif view == 'starred':
- posts = api.get_starred_posts(api.get_session_id(user_id))
- body = render_template('user.html',
- title='Starred',
- category = 'starred',
- view='user',
- user=user,
- owner=owner,
- feeds=posts)
- json = dumps({'body': body, 'title': 'Intelliview'})
- return Response(json, mimetype='application/json')
-
- else:
-
- view = 'user'
- title = user.name
-
-
- if not session_id or owner.id == user.id:
- feeds = api.get_public_posts(user_id=user.id, page=page)
- else:
- feeds = api.get_user_posts(session_id, user_id, page=page)
- user.recent_files = api.get_user_files(session_id, user_id=user.id, limit=3)
- user.recent_notes = api.get_user_notes(session_id, user_id=user.id, limit=3)
-
- coworkers = [user]
- if request.method == "OPTIONS":
-
- if page == 1:
- body = render_template('user.html',
- view=view,
- user=user,
- owner=owner,
- title=title,
- coworkers=coworkers,
- feeds=feeds)
-
- json = dumps({"body": body,
- "title": title})
- return Response(json, mimetype='application/json')
- else:
- posts = [render(feeds, 'feed', owner, 'user')]
-
- if len(feeds) == 0:
- posts.append(render_template('more.html', more_url=None))
- else:
- posts.append(render_template('more.html',
- more_url='/user/%s/page%d' \
- % (user_id, page+1)))
- return ''.jo…
Large files files are truncated, but you can click here to view the full file