def delete_email(request, username, email): # the ID we are to delete auth_id = 'email:%s' % email user = User.get_by_auth_id('twitter:%s' % username) e_user = User.get_by_auth_id(auth_id) if user is None or e_user is None: raise Http404("User not found") if user != request.user or user != e_user: http403 = HttpResponse("This ain't you!") http403.status = 403 return http403 if request.method == "POST": # delete the email from the user user.auth_ids.remove(auth_id) user.unique_model.delete_multi(['User.auth_id:%s' % auth_id]) user.put() return HttpResponseRedirect( reverse('member-profile', kwargs={'username':request.user.username}) ) return render_to_response('people/delete_email.html', {'email': email}, context_instance=RequestContext(request))
def delete_email(request, username, email): # the ID we are to delete auth_id = 'email:%s' % email user = User.get_by_auth_id('own:%s' % username) e_user = User.get_by_auth_id(auth_id) if user is None or e_user is None: raise Http404("User not found") if user != request.user or user != e_user: http403 = HttpResponse("This ain't you!") http403.status = 403 return http403 if request.method == "POST": # delete the email from the user user.auth_ids.remove(auth_id) user.unique_model.delete_multi(['User.auth_id:%s' % auth_id]) user.put() return HttpResponseRedirect( reverse('member-profile', kwargs={'username':request.user.username}) ) return render_to_response('people/delete_email.html', {'email': email}, context_instance=RequestContext(request))
def post(self): """Create a project from the api. Example:: { "url": "http://github.com/defunkt/github", "name": "github", "description": "You're lookin' at it.", "watchers": 5, "forks": 2, "private": 1, "email": "*****@*****.**", "account": "twitter_name", }, """ form = self.parse_form() if not form.is_valid(): return self.respond_json(form.errors, status_code=400) # Lookup the user by email or account email = form.cleaned_data.pop('email', None) account = form.cleaned_data.pop('account', None) user = None if email: user = User.get_by_auth_id('email:%s' % email) elif account: user = User.get_by_auth_id('twitter:%s' % account) created = False project_url = form.cleaned_data['url'] project_key = Project.make_key(project_url) project = project_key.get() if project is None: created = True project = Project(key=project_key, **form.cleaned_data) project.put() @ndb.transactional def txn(): count = getattr(user, 'total', 0) projects = set(getattr(user, 'projects', [])) user.total = count + 10 user.projects = list(projects.add(project_url)) user.put() return user if created and user: txn() self.respond_json({'project': self.serialize(project)}, status_code=201 if created else 200)
def edit_profile(request, username, template_name='people/edit.html'): from forms import EditUserForm user = User.get_by_auth_id('twitter:%s' % username) if user == None: raise Http404("User not found") if user.key != request.user.key: http403 = HttpResponse("This ain't you!") http403.status = 403 return http403 form = EditUserForm(request.POST or None, user=request.user) if form.is_valid(): for key in form.cleaned_data: if key == 'email': continue setattr(user, key, form.cleaned_data.get(key)) slugify(user.location) user.put() return HttpResponseRedirect( reverse('member-profile', kwargs={'username':request.user.username} ) ) return render_to_response(template_name, {'form':form}, context_instance=RequestContext(request))
def test_project_url(self): user = self.make_user('marcus') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/bitbucket', self.POST) user = User.get_by_auth_id('email:[email protected]') self.assertTrue( 'https://some.other.org/marcus/project-x/' in user.projects)
def project_details(request, slug, template_name='projects/details.html'): project_key = ndb.Key('Project', slug) project = project_key.get() if project is None: raise Http404("Project Not Found.") limit = 100 cursor = request.GET.get('cursor') if cursor: cursor = Cursor(urlsafe=cursor) # TODO: pagination user_future = User.query().filter(ndb.GenericProperty('projects') == project.url).fetch_async(100) query = Commit.query().filter(Commit.project_slug == slug).order(-Commit.timestamp) commit_future = query.fetch_page_async(limit, start_cursor=cursor) commits, next_cursor, more = commit_future.get_result() users = user_future.get_result() if next_cursor is not None: next_cursor = next_cursor.urlsafe() return render_to_response(template_name, {'project': project, 'users': users, 'commits': commits, 'next': next_cursor, 'more': more}, context_instance=RequestContext(request))
def edit_address(request, username, template_name='people/edit_address.html'): from forms import EditAddressForm user = User.get_by_auth_id('own:%s' % username) if user == None: raise Http404("User not found") if user.key != request.user.key: http403 = HttpResponse("This ain't you!") http403.status = 403 return http403 form = EditAddressForm(request.POST or None, user=user) if form.is_valid(): for key, value in form.cleaned_data.iteritems(): setattr(user,key,value) user.put() return HttpResponseRedirect( reverse('member-profile', kwargs={'username':request.user.username} ) ) return render_to_response(template_name, {'form':form}, context_instance=RequestContext(request))
def test_testing_mode_off_user_points(self): settings.TESTING = False user = self.make_user('chris') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/github', self.POST) u = User.get_by_auth_id('email:[email protected]') total = getattr(u, 'total', None) self.assertEqual(total, None)
def test_testing_mode_off_user_points(self): settings.TESTING = False user = self.make_user('marcus') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/bitbucket', self.POST) u = User.get_by_auth_id('email:[email protected]') total = getattr(u, 'total', None) self.assertEqual(total, None)
def fix_player_counts(auth_id): """Fix a single user counts.""" user = User.get_by_auth_id(auth_id) ranges = _get_date_ranges() for start, end in ranges: count = Commit.query(ancestor=user.key).filter(Commit.timestamp >= start, Commit.timestamp < end).count(1000) Accumulator.add_count('own:%s' % user.username, start, count, reset=True)
def test_testing_mode_off(self): settings.TESTING = False user = self.make_user('marcus') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/bitbucket', self.POST) u = User.get_by_auth_id('email:[email protected]') p_key = Project.make_key('https://bitbucket.org/marcus/project-x/') # project should not be created self.assertEqual(p_key.get(), None)
def user_profile(request, username): user = User.get_by_auth_id('own:%s' % username) if user == None: raise Http404("User not found") commits = Commit.query(ancestor=user.key).order(-Commit.timestamp).fetch(100) return render_to_response('people/profile.html', {"commits":commits, 'profile':user}, context_instance=RequestContext(request))
def user_profile(request, username): user = User.get_by_auth_id('twitter:%s' % username) if user == None: raise Http404("User not found") commits = Commit.query(ancestor=user.key).order(-Commit.timestamp).fetch(100) return render_to_response('people/profile.html', {"commits":commits, 'profile':user}, context_instance=RequestContext(request))
def fix_team(slug, cursor=None, total=0): # Don't try to lookup slugs that are the empty string. # hint they don't exist! if not slug: return team_slug = slug team = Team.get_or_insert(team_slug) projects = set([]) if cursor: # we are looping Grab the existing project list so we don't # wipe out the earlier runs work team_p = getattr(team, 'projects', []) projects = set(team_p) cursor = Cursor(urlsafe=cursor) people = User.query().filter(ndb.GenericProperty('team_slug') == team_slug) # Go through the users in chucks models, next_cursor, more = people.fetch_page(100, start_cursor=cursor) for model in models: user_projects = getattr(model, 'projects', []) user_total = getattr(model, 'total', 0) # Do a little math to figure out how many commits they have commits = user_total - (len(user_projects) * 10) if commits > 0: logging.info('Adding %s to %s', commits, team_slug) total += commits # Add the users projects to the project set (this filters duplicates) projects.update(user_projects) # Run update in a transaction projects = list(projects) total = total + (len(projects) * 10) @ndb.transactional def txn(): team = Team.get_or_insert(team_slug) team.total = total team.projects = projects team.put() txn() if more: # We have more people to loop through!! return deferred.defer(fix_team, team_slug, cursor=next_cursor.urlsafe(), total=total)
def users_by_location(request, location_slug, template_name='people/people_list.html'): users = User.query(User.location_slug == location_slug) users.order(-ndb.GenericProperty('total')).fetch(1000) location = Location.get_by_id(location_slug) return render_to_response(template_name, {'users':users, 'location': location, 'slug': location_slug}, context_instance=RequestContext(request))
def wrapper(self, *args, **kwargs): if login_required: if self.auth is None: abort(401) if registration_required: # check to see if the user is registered. user = User.get_by_auth_id(self.auth) if not user: abort(403) return func(self, *args, **kwargs)
def project_details(request, slug, template_name='projects/details.html'): project_key = ndb.Key('Project', slug) project = project_key.get() if project is None: raise Http404("Project Not Found.") # TODO: pagination users = User.query().filter(ndb.GenericProperty('projects') == project.url).fetch(1000) return render_to_response(template_name, {'project': project, 'users': users}, context_instance=RequestContext(request))
def fix_player_counts(auth_id): """Fix a single user counts.""" user = User.get_by_auth_id(auth_id) ranges = _get_date_ranges() for start, end in ranges: count = Commit.query(ancestor=user.key).filter( Commit.timestamp >= start, Commit.timestamp < end).count(1000) Accumulator.add_count('own:%s' % user.username, start, count, reset=True)
def leaderboard(request, template_name='people/leaderboard.html'): limit = 100 cursor = request.GET.get('cursor') if cursor: cursor = Cursor(urlsafe=cursor) query = User.query().order(-ndb.GenericProperty('total')) models, next_cursor, more = query.fetch_page(limit, start_cursor=cursor) return render_to_response(template_name, {'next':next_cursor, 'more':more, 'users':models}, context_instance=RequestContext(request))
def people_projects(request, username): user = User.get_by_auth_id('own:%s' % username) if user == None: raise Http404("User not found") if getattr(user, 'projects', None) == None: projects = [] else: projects = user.projects projects = ndb.get_multi([Project.make_key(project) for project in projects]) return render_to_response('people/people_projects.html', {"projects":projects, 'profile':user}, context_instance=RequestContext(request))
def fix_players(cursor=None): """Fix all the players""" if cursor: cursor = Cursor(urlsafe=cursor) query = User.query() models, next_cursor, more = query.fetch_page(15, start_cursor=cursor) for model in models: deferred.defer(fix_player_counts, 'own:%s' % model.username) if more: deferred.defer(fix_players, cursor=next_cursor.urlsafe())
def people_projects(request, username): user = User.get_by_auth_id('twitter:%s' % username) if user == None: raise Http404("User not found") if getattr(user, 'projects', None) == None: projects = [] else: projects = user.projects projects = [Project.get_or_create(url=project)[1] for project in projects] return render_to_response('people/people_projects.html', {"projects":projects, 'profile':user}, context_instance=RequestContext(request))
def edit_profile(request, username, template_name='people/edit.html'): from forms import EditUserForm user = User.get_by_auth_id('own:%s' % username) if user == None: raise Http404("User not found") if user.key != request.user.key: http403 = HttpResponse("This ain't you!") http403.status = 403 return http403 existing_slug = str(user.location_slug) existing_team = str(getattr(user, 'team_slug', '')) form = EditUserForm(request.POST or None, user=request.user) if form.is_valid(): for key, value in form.cleaned_data.iteritems(): if key == 'email': # Don't save the email to the profile continue if key == 'team': # slugify the team to allow easy lookups setattr(user, 'team_slug', slugify(value)) setattr(user, key, value) user.put() if user.location_slug != existing_slug: # Defer a couple tasks to update the locations deferred.defer(fix_location, str(user.location_slug)) deferred.defer(fix_location, existing_slug) if getattr(user, 'team_slug', '') != existing_team: # Defer a couple tasks to update the teams deferred.defer(fix_team, str(user.team_slug)) deferred.defer(fix_team, existing_team) return HttpResponseRedirect( reverse('member-profile', kwargs={'username':request.user.username} ) ) return render_to_response(template_name, {'form':form}, context_instance=RequestContext(request))
def handle_filter(self, query, filter_string): """Allow for filtering by user or project""" if filter_string.startswith('#'): # we're looking for a project strip the hash tag first project_name = filter_string[1:] logging.error('Handle Projects!!! %s', project_name) raise elif filter_string.startswith('@'): username = '******' % filter_string[1:] else: username = filter_string logging.info('looking up commits for user: %s', username) user = User.get_by_auth_id(username) if user is None: abort(404) return self.model.query(ancestor=user.key)
def users_by_location(request, location_slug, template_name='people/people_list.html'): limit = 100 cursor = request.GET.get('cursor') if cursor: cursor = Cursor(urlsafe=cursor) query = User.query(User.location_slug == location_slug) query = query.order(-ndb.GenericProperty('total')) models, next_cursor, more = query.fetch_page(limit, start_cursor=cursor) location = Location.get_by_id(location_slug) return render_to_response(template_name, {'next':next_cursor, 'more':more, 'users':models, 'location': location, 'slug': location_slug}, context_instance=RequestContext(request))
def team_details(request, team_slug, template_name='people/team_details.html'): limit = 100 cursor = request.GET.get('cursor') if cursor: cursor = Cursor(urlsafe=cursor) query = User.query(ndb.GenericProperty('team_slug') == team_slug) query = query.order(-ndb.GenericProperty('total')) models, next_cursor, more = query.fetch_page(limit, start_cursor=cursor) if next_cursor is not None: next_cursor = next_cursor.urlsafe() team = Team.get_by_id(team_slug) return render_to_response(template_name, {'next':next_cursor, 'more':more, 'users':models, 'team': team, 'slug': team_slug}, context_instance=RequestContext(request))
def fix_accounts(cursor=None): """Fix all the accounts in chunks""" if cursor: cursor = Cursor(urlsafe=cursor) query = User.query() models, next_cursor, more = query.fetch_page(15, start_cursor=cursor) for account in models: username = getattr(account, 'username', None) if username is None: logging.error('No user name set for: %s', account) continue added, _ = account.add_auth_id('own:%s' % username) if not added: logging.error("Unable to add username: %s", account.username) if more: deferred.defer(fix_accounts, cursor=next_cursor.urlsafe())
def index(request): """Render the home page""" # For now we are just using hard coded sections #sections = cache.get('front_page') #if sections is None: # sections = Section.all().order('order').fetch(10) # cache.set('front_page', sections, 120) stats = [] total = 0 people = [] locations = [] projects = [] teams = [] messages = [] token = '' # this is only shown on authenticated page loads # to save on the overhead. if True: stats = Accumulator.get_histogram('global') total = sum(stats) location_future = Location.query().order(-Location.total).fetch_async( 15) people_future = User.query().order( -ndb.GenericProperty('total')).fetch_async(10) project_future = Project.query().order(-Project.total).fetch_async(10) team_future = Team.query().order(-Team.total).fetch_async(15) message_future = Message.query().order(-Message.timestamp).fetch_async( 30) # Julython live stuffs #token_key = 'live_token:%s' % request.user.username #token = memcache.get(token_key) #if token is None: #token = channel.create_channel(request.user.username) #memcache.set(token_key, token, time=7000) locations = location_future.get_result() people = people_future.get_result() projects = project_future.get_result() teams = team_future.get_result() message_models = message_future.get_result() m_list = [to_dict(m) for m in message_models] m_list.reverse() messages = json.dumps(m_list) ctx = Context({ 'sections': [], 'people': people, 'projects': projects, 'locations': locations, 'teams': teams, 'stats': json.dumps(stats), 'total': total, 'token': token, 'messages': messages, 'user': request.user, 'MEDIA_URL': settings.MEDIA_URL, 'STATIC_URL': settings.STATIC_URL }) return render_to_response('index.html', context_instance=ctx)
def make_user(self, username, save=True, **kwargs): _, user = User.create_user(auth_id='%s' % username, **kwargs) return user
def test_project_url(self): user = self.make_user('marcus') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/bitbucket', self.POST) user = User.get_by_auth_id('email:[email protected]') self.assertTrue('https://some.other.org/marcus/project-x/' in user.projects)
def make_user(self, username, save=True, **kwargs): kwargs['username'] = username _, user = User.create_user(auth_id=username, **kwargs) return user
def test_post_adds_points_to_user(self): user = self.make_user('chris') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/github', self.POST) u = User.get_by_auth_id('email:[email protected]') self.assertEqual(u.total, 12)
def user(self): """Check the authorization header for a username to lookup""" if self.auth: return User.get_by_auth_id(self.auth) return None
def create_by_auth_id(cls, auth_id, commits, project=None): user = User.get_by_auth_id(auth_id) if user: return cls.create_by_user(user, commits, project=project) return cls.create_orphan(commits, project=project)
def test_post_adds_points_to_user(self): user = self.make_user('marcus') user.add_auth_id('email:[email protected]') self.app.post('/api/v1/bitbucket', self.POST) u = User.get_by_auth_id('email:[email protected]') self.assertEqual(u.total, 11)
def index(request): """Render the home page""" # For now we are just using hard coded sections #sections = cache.get('front_page') #if sections is None: # sections = Section.all().order('order').fetch(10) # cache.set('front_page', sections, 120) stats = [] total = 0 people = [] locations = [] projects = [] teams = [] messages = [] token = '' # this is only shown on authenticated page loads # to save on the overhead. if True: stats = Accumulator.get_histogram('global') total = sum(stats) location_future = Location.query().order(-Location.total).fetch_async(15) people_future = User.query().order(-ndb.GenericProperty('total')).fetch_async(10) project_future = Project.query().order(-Project.total).fetch_async(10) team_future = Team.query().order(-Team.total).fetch_async(15) message_future = Message.query().order(-Message.timestamp).fetch_async(30) # Julython live stuffs #token_key = 'live_token:%s' % request.user.username #token = memcache.get(token_key) #if token is None: #token = channel.create_channel(request.user.username) #memcache.set(token_key, token, time=7000) locations = location_future.get_result() people = people_future.get_result() projects = project_future.get_result() teams = team_future.get_result() message_models = message_future.get_result() m_list = [to_dict(m) for m in message_models] m_list.reverse() messages = json.dumps(m_list) ctx = Context({ 'sections': [], 'people': people, 'projects': projects, 'locations': locations, 'teams': teams, 'stats': json.dumps(stats), 'total': total, 'token': token, 'messages': messages, 'user': request.user, 'MEDIA_URL': settings.MEDIA_URL, 'STATIC_URL': settings.STATIC_URL}) return render_to_response('index.html', context_instance=ctx)