def project(request):
    user = get_user(request)
    session = DBSession()
    project = request.context
        
    updates = session.query(ProjectUpdate)\
        .filter(ProjectUpdate.project_id==project.id)\
        .filter(ProjectUpdate.when >= utcnow() - timedelta(days=10))\
        .order_by(ProjectUpdate.when.desc()).limit(10).all()
    
    # Update user access time:
    if user:
        part = session.query(Participation).filter(Participation.user_email==user.email).filter(Participation.project_id==project.id).first()
        if not part or not part.access_time:
            note.new_participant(request, request.context, user)  
        part.access_time = utcnow()
        session.flush()
              
    return template_permissions(request, {
        'project_id' : project.id,
        'project' : project, 
        'creator' : user_dict(request, project.creator),
        'updates' : updates,
        'ideas': project.ideas.all(), 
        'user' : user_dict(request, user), 
        'can_update' : user == project.creator,
        'ideas_count': project.ideas.count(), 
        'people_count': 1
    })
def display_project_people(request):
    cur_user = get_user(request)
    session = DBSession()
        
    project = request.context
    
    participants = session.query(Participation, User).outerjoin(User).filter(Participation.project == project).all()
    people_data = []
    email_data = []
    for participant, user in participants:
        person_data = {}
        if user:
            person_data['first_name'] = user.first_name
            person_data['last_name'] = user.last_name
            person_data['profile_url'] = request.root.user_url(user)
            person_data['invite_accepted'] = participant.access_time is not None
            person_data['profile_picture'] = user.profile_picture
            people_data += [person_data]
        else:
            email_data += [participant.user_email]
    
    # Sort by first last name
    people_data.sort(key=lambda user: user['first_name'] + u' ' + user['last_name'])
    
    
    return template_permissions(request, {
        'people' : people_data,
        'invited_emails' : email_data,
        'project_id' : project.id,
        'project' : project, 
        'creator' : user_dict(request, project.creator),
        'user' : user_dict(request, cur_user), 
        'ideas_count': project.ideas.count(), 
        'people_count': len(active_users(project)),
    })
def ideas(request):
    # Optional parameters: sort="user" | "rating" | "date"
    user = get_user(request)
    session = DBSession()
    project = request.context
    # Create list of ideas with User's rating added:
    if user:
        idea_query = session.query(Idea, AggregateRating, UserRating)\
            .outerjoin(AggregateRating, (AggregateRating.idea_id==Idea.id))\
            .outerjoin(UserRating, (Idea.id==UserRating.idea_id) & (UserRating.user_id==user.id))\
            .join(User, (Idea.author_id==User.id))\
            .filter(Idea.project_id == project.id)
    else:
         # Just fill third column with Nones.
        idea_query = session.query(Idea, AggregateRating, UserRating)\
            .outerjoin(AggregateRating, (AggregateRating.idea_id==Idea.id))\
            .outerjoin(UserRating, (UserRating.idea_id==0))\
            .join(User, (Idea.author_id==User.id))\
            .filter(Idea.project_id == project.id)
            
    
    sort = request.params.get('sort', 'rating') 
    if sort == 'user':
        # Use Python to sort, so we sort Anonymous posts properly.
        pass
    elif sort == 'rating':
        # Use Python to sort, so we can use our total_rating algorithm..
        pass
    elif sort == 'date':
        idea_query = idea_query.order_by(Idea.creation_time.desc()) # Most recent first
    else:
        logging.warn('Unrecognized sort: ' + str(sort))
    
    idea_data = idea_query.all()
    # Do python sorting.
    if sort == 'user':
        idea_data.sort(key=lambda el:el[0].author.first_name + ' ' + el[0].author.last_name if not el[0].anonymous else 'Anonymous')
    elif sort == 'rating':
        if project.rating_type == 'like/love':
            idea_data.sort(key=lambda el: el[0].aggregate_rating.total_rating if el[0].aggregate_rating else 0, reverse=True)
        else:
            idea_data.sort(key=lambda el: el[0].aggregate_rating.average_stars if el[0].aggregate_rating else 0, reverse=True)
    
    # Turn it all into dicts for our templating engine.
    for i in range(len(idea_data)):
        idea, aggregate_rating, rating = idea_data[i]
        idea_data[i] = idea_dict(request, idea, rating, aggregate_rating, include_comments=True)
        
    
    # Idea.user_rating will be used to determine the initial state of the Like/Love/Stars
    return template_permissions(request, {
        'project' : project, 
        'creator' : user_dict(request, project.creator),
        'project_id' : project.id,
        'idea_data': idea_data, 
        'user' : user_dict(request, user), 
        'ideas_count': len(idea_data), 
        'people_count': 1,
        'sort' : sort
    })
def create(request):
    user = get_user(request)
    
    if 'project_key' in request.params:
        # User submitted a project.
        # TODO: Validation.
        try: 
            new_project = request.context.newProject(
                title=request.params['project_title'],
                key=request.params['project_key'],
                description=request.params['project_description'],
                url_name=request.params['project_url'],
                creator_id=user.id)
                
            participation = Participation(user=user, project=new_project)
            session = DBSession()
            session.add(participation)
            session.flush()
            note.new_project(request, new_project, user)
        except IntegrityError:
            # url_name collision.
            raise HTTPBadRequest(explanation="Sorry! That URL has already been taken!")
        return HTTPFound(location=request.root.project_url(new_project)+'/invite')
    else:
        return {'user' : user_dict(request, user)}
def invite(request):
    project = request.context
    session = DBSession()
    user = get_user(request)
    redirect_uri = request.resource_url(project)
    
    iframe_url = 'https://www.facebook.com/dialog/apprequests?access_token=%(access_token)s&api_key=%(api_key)s&app_id=%(app_id)s&display=iframe&frictionless=false&locale=en_US&message=%(message)s&next=%(next)s' % {
        'access_token' : request.session['access_token'] if 'access_token' in request.session else None,
        'api_key' : request.registry.settings['facebook.app_id'],
        'app_id' : request.registry.settings['facebook.app_id'],
        'message' : "WEE ARE THE CHAMPIONS",
        'next' : redirect_uri
    }
    
    # Parse the request params:
    emails = []
    message = None
    response_params = {}
    if 'email_0' in request.params:
        i = 0
        while 'email_' + str(i) in request.params:
            email = request.params['email_'+str(i)]
            if email:
                emails += [email]
            i += 1
        message = request.params['message']
        try: 
            logging.info('Sending invite message for project ' + str(project.id))
            send_email(user.email, emails, "You've been invited!", message)
            response_params['invited'] = True
            response_params['invitee_count'] = len(emails)
        except socket.error:
            pass
    else:
        if request.referrer == request.resource_url(project, 'new'):
            response_params['created'] = True
    
    if emails:
        # Add the emails to the participants list for that project.
        existing = session.query(Participation).filter(Participation.user_email.in_(emails)).filter(Participation.project==project).all()
        existing = [participation.user_email for participation in existing]
        for email in emails:
            if email in existing:
                continue
            session.add(Participation(project_id=project.id, user_email=email))
    
    
    # Get friends list from serverside facebook api.
    friends = ''
    if 'access_token' in request.session:
        logging.info('Invite: access_token present in session, populating friends list')
        graph = fb.GraphAPI(request.session['access_token'])
        friends = graph.get_connections("me", "friends", fields='id,name')
        friends = json.dumps(friends)
    else:
        logging.info('Invite: no access_token in session, not facebook?')
    
    
    response_params.update({'user' : user_dict(request, user), 
    'project' : {'key':project.key,'title':project.title, 'url': request.resource_url(project)},
    'creator' : user_dict(request, project.creator),
    'fb_app_id' : request.registry.settings['facebook.app_id'],
    'iframe_url' : iframe_url,
    'fb_access_token' : request.session['access_token'] if 'access_token' in request.session else None,
    'friend_data' : friends,
    'fb_login_url' : fb_login_url(request)
    })
    return template_permissions(request, response_params)