def create(self): """Handles the POST data for creating a group. Form Variables: name: the name of the new group public: true if the group should be joinable by the public """ if auth.logged_in(): name = self.request.get('name') public = self.request.get('public') == 'public' owner = auth.current_user() if Group.exists(name): Messages.add('A group with that name already exists') return self.redirect('/groups/signup') Group(name=name, public=public, owner=owner, members=[owner]).put() return self.redirect('/groups') else: Messages.add('You must be logged in to create a group') return self.redirect('/groups/signup')
def delete(self, key): if auth.user_is_admin(): Group.get(key).delete() else: Messages.add('Only an administrator may delete groups. This ' + 'incident has been logged.') return self.redirect('/groups')
def delete(self, key): if auth.user_is_admin(): Project.get(key).delete() else: Messages.add('Only and administrator may delete projects. This ' + 'incident has been logged.') return self.redirect('/projects')
def signup(self): user = auth.User(auth.current_user()) if user.in_group(): Messages.add('You are already in a group') return self.redirect('/groups') else: return self.render('groups_signup')
def delete(self, key): if auth.user_is_admin(): Idea.get(key).delete() else: Messages.add('Only and administrator may delete submitted ideas. ' + 'This incident has been logged.') return self.redirect('/ideas')
def delete(self, key): """Deletes a project.""" if auth.user_is_admin(): Project.get(key).delete() else: Messages.add('Only and administrator may delete projects. This ' + 'incident has been logged.') return self.redirect('/projects')
def signup(self): """Displays the group sign up form.""" user = auth.User(auth.current_user()) if user.in_group(): Messages.add('You are already in a group') return self.redirect('/groups') else: return self.render('groups_signup')
def delete(self, key): """Deletes a group.""" if auth.user_is_admin(): Group.get(key).delete() else: Messages.add('Only an administrator may delete groups. This ' + 'incident has been logged.') return self.redirect('/groups')
def delete(self, key): """Deletes a project idea.""" if auth.user_is_admin(): Idea.get(key).delete() else: Messages.add('Only and administrator may delete submitted ' + 'ideas. This incident has been logged.') return self.redirect('/ideas')
def update_group(self, key): if not auth.logged_in(): return self.redirect('/groups') user = auth.current_user() group = Group.get(key) if group.owner.user_id() != user.user_id() and not auth.user_is_admin(): Messages.add('Only the owner of the group owner may modify it') return self.redirect('/groups') name = self.request.get('name') public = self.request.get('public') == 'public' abandon = self.request.get('abandon-project') sub_text = self.request.get('submission-text') sub_url = self.request.get('submission-url') remove_submission = self.request.get_all('remove-submission') remove = self.request.get_all('remove') owner = self.request.get('owner') delete = self.request.get('delete') if delete: group.delete() return self.redirect('/groups') group.name = name group.public = public if abandon: group.project = None if sub_text and sub_url: Submission(text=sub_text, url=sub_url, group=group).put() for sub in Submission.get(remove_submission): sub.delete() pending = list(group.pending_users) for user in pending: approve = self.request.get("approve-%s" % user) if approve == "approve": group.members.append(user) group.pending_users.remove(user) elif approve == "refuse": group.pending_users.remove(user) group.owner = auth.user_from_email(owner) for user in remove: if auth.user_from_email(user) == group.owner: Messages.add('Cannot remove the group owner') return self.redirect('/groups/%s/edit' % key) else: group.members.remove(auth.user_from_email(user)) group.put() return self.redirect('/groups/%s' % key)
def edit(self, key): if not auth.logged_in(): return self.redirect('/groups') user = auth.current_user() group = Group.get(key) if group.owner.user_id() == user.user_id() or auth.user_is_admin(): return self.render('groups_edit', { 'group': group }) else: Messages.add('Only the owner of this group may edit it') return self.redirect('/groups/%s' % key)
def leave(self, key): group = Group.get(key) user = auth.User(auth.current_user()) if user.group != group: Messages.add('You cannot leave a group you are not in') return self.redirect('/groups/%s' % key) group.members.remove(user.gae_user) group.put() return self.redirect('/groups')
def edit(self, key): """Displays the group moderation form.""" if not auth.logged_in(): return self.redirect('/groups') user = auth.current_user() group = Group.get(key) if group.owner.user_id() == user.user_id() or auth.user_is_admin(): return self.render('groups_edit', {'group': group}) else: Messages.add('Only the owner of this group may edit it') return self.redirect('/groups/%s' % key)
def claim(self, key): user = auth.User(auth.current_user()) group = user.group if group.owner.user_id() == auth.current_user().user_id(): project = Project.get(key) group.project = project group.put() return self.redirect('/groups/%s' % group.key()) else: Messages.add('You are not the owner of your group. Only the ' + 'owner of the group may select a project.') return self.redirect('/projects')
def leave(self, key): """Removes the current user from the group's roster.""" group = Group.get(key) user = auth.User(auth.current_user()) if user.group != group: Messages.add('You cannot leave a group you are not in') return self.redirect('/groups/%s' % key) group.members.remove(user.gae_user) group.put() return self.redirect('/groups')
def claim(self, key): """Claims a project for a group.""" user = auth.User(auth.current_user()) group = user.group if group.owner.user_id() == auth.current_user().user_id(): project = Project.get(key) group.project = project group.put() return self.redirect('/groups/%s' % group.key()) else: Messages.add('You are not the owner of your group. Only the ' + 'owner of the group may select a project.') return self.redirect('/projects')
def approve(self, key): if auth.user_is_admin(): idea = Idea.get(key) Project(name=idea.name, description=idea.description, author=idea.author, post_time=idea.post_time).put() idea.delete() return self.redirect('/projects') else: Messages.add('Only and administrator may approve submitted ' + 'ideas. This incident has been logged.') return self.redirect('/ideas')
def approve(self, key): """Promotes a project idea to an accepted project.""" if auth.user_is_admin(): idea = Idea.get(key) Project(name=idea.name, description=idea.description, author=idea.author, post_time=idea.post_time).put() idea.delete() return self.redirect('/projects') else: Messages.add('Only and administrator may approve submitted ' + 'ideas. This incident has been logged.') return self.redirect('/ideas')
def getMessages(): messages = Messages() if request.method == 'POST': if request.data: # Content-Type: application/json # ie. - { "foo": "bar", "baz": "moe" } data = json.loads(request.data) else: # Content-Type: x-www-form-urlencoded # ie. - foo=bar&baz=moe data = dict((k, request.values[k]) for k in request.values.keys()) return jsonify(messages.add(data)) else: return jsonify(messages.getMessages())
def join(self, key): group = Group.get(key) user = auth.User(auth.current_user()) if user.in_group(): Messages.add('You are already in a group') return self.redirect('/groups/%s' % key) if user.pending_join(): Messages.add('You have already applied to join a group') return self.redirect('/groups/%s' % key) if group.public: group.members.append(auth.current_user()) Messages.add('You have joined the group') else: group.pending_users.append(auth.current_user()) Messages.add('You have requested to join the group') group.put() return self.redirect('/groups/%s' % key)
def join(self, key): """Adds the current user to the group's roster.""" group = Group.get(key) user = auth.User(auth.current_user()) if user.in_group(): Messages.add('You are already in a group') return self.redirect('/groups/%s' % key) if user.pending_join(): Messages.add('You have already applied to join a group') return self.redirect('/groups/%s' % key) if group.public: group.members.append(auth.current_user()) Messages.add('You have joined the group') else: group.pending_users.append(auth.current_user()) Messages.add('You have requested to join the group') group.put() return self.redirect('/groups/%s' % key)
def update_group(self, key): """Updates a group with information from the moderation form. Form Variables: name: the name of the group public: true if the group should be joinable by the public abandon-project: true if the group moderator wants to abandon the current project submission-text: the text to be displayed for the new submission submission-url: the URL of the new submission remove-submission: a list of submissions to be removed remove: a list of users to be removed from the group owner: the owner of the group delete: true if the group moderator wants to disband the group """ if not auth.logged_in(): return self.redirect('/groups') user = auth.current_user() group = Group.get(key) if (group.owner.user_id() != user.user_id() and not auth.user_is_admin()): Messages.add('Only the owner of the group owner may modify it') return self.redirect('/groups') name = self.request.get('name') public = self.request.get('public') == 'public' abandon = self.request.get('abandon-project') sub_text = self.request.get('submission-text') sub_url = self.request.get('submission-url') remove_submission = self.request.get_all('remove-submission') remove = self.request.get_all('remove') owner = self.request.get('owner') delete = self.request.get('delete') if delete: group.delete() return self.redirect('/groups') group.name = name group.public = public if abandon: group.project = None if sub_text and sub_url: Submission(text=sub_text, url=sub_url, group=group).put() for sub in Submission.get(remove_submission): sub.delete() pending = list(group.pending_users) for user in pending: approve = self.request.get("approve-%s" % user) if approve == "approve": group.members.append(user) group.pending_users.remove(user) elif approve == "refuse": group.pending_users.remove(user) group.owner = auth.user_from_email(owner) for user in remove: if auth.user_from_email(user) == group.owner: Messages.add('Cannot remove the group owner') return self.redirect('/groups/%s/edit' % key) else: group.members.remove(auth.user_from_email(user)) group.put() return self.redirect('/groups/%s' % key)
class Window(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, title=title) # Splitters and Panels self.controls_map_splitter = wx.SplitterWindow(self) self.controls_map_splitter.SetMinimumPaneSize(300) controls_panel = wx.Panel(self.controls_map_splitter) map_panel = wx.Panel(self.controls_map_splitter) self.graphs_messages_splitter = wx.SplitterWindow(controls_panel) self.graphs_messages_splitter.SetMinimumPaneSize(50) graphs_panel = wx.Panel(self.graphs_messages_splitter) messages_panel = wx.Panel(self.graphs_messages_splitter) # World graphic self._graphics = worldmap.WorldMap(map_panel) self.graphics_sizer = wx.BoxSizer(wx.VERTICAL) self.graphics_sizer.Add(self._graphics, 1, wx.EXPAND) map_panel.SetSizerAndFit(self.graphics_sizer) # Controls panel self.controls = Controls(controls_panel, (300, 250), self) # Info panel self.info = Info(controls_panel, (300, 250)) # Graph canvas self.graphs = graphs.Graphs(graphs_panel, (300, 300)) # Messages panel self.messages = Messages(messages_panel, (600, 200)) self.interface_sizer = wx.BoxSizer(wx.VERTICAL) self.controls_info_sizer = wx.BoxSizer(wx.HORIZONTAL) self.controls_info_sizer.Add(self.info, 0, wx.EXPAND) self.controls_info_sizer.Add((20, -1), proportion=0) # Padding self.controls_info_sizer.Add(self.controls, 1, wx.EXPAND) self.messages_sizer = wx.BoxSizer(wx.VERTICAL) self.messages_sizer.Add(self.messages, 1, wx.EXPAND) messages_panel.SetSizerAndFit(self.messages_sizer) self.graphs_sizer = wx.BoxSizer(wx.VERTICAL) self.graphs_sizer.Add(self.graphs, 1, wx.EXPAND) graphs_panel.SetSizerAndFit(self.graphs_sizer) self.interface_sizer.Add(self.controls_info_sizer, 0, wx.EXPAND) self.interface_sizer.Add(self.graphs_messages_splitter, 1, wx.EXPAND) controls_panel.SetSizerAndFit(self.interface_sizer) self.graphs_messages_splitter.SplitHorizontally( messages_panel, graphs_panel ) self.controls_map_splitter.SplitVertically(controls_panel, map_panel) # Set up event handler for any worker thread results EVT_RESULT(self, self.OnResult) EVT_STOP(self, self.OnStop) # Set up close event so timer is properly stopped wx.EVT_CLOSE(self, self.OnClose) self.reset_gui() self.Show() def reset_gui(self): self.controls.reset_buttons() self.messages.clear() self.graphs.reset_data() # Event Methods def OnStart(self, event): self.controls.set_buttons_ready() self._simulation = simulation.Simulation() self._simulation.setup_config(self.controls.get_config_filename()) self.simulation_info = self._simulation.initialize() if not self.simulation_info.interface_config.print_messages: self.messages.deactivate() self._graphics.num_max_complaints = \ self.simulation_info.num_max_complaints self.rounds = 0 self.steps = 0 self.next_phase = "COASTPLAN" self.prev_phase = None self.worker = None def run(self, rounds, steps): assert rounds >= 0, "Rounds has to be a positive integer." assert steps >= 0, "Steps has to be a positive integer." assert steps > 0 or rounds > 0, "Rounds or steps needs to be positive." self.controls.set_status(rounds, steps) self.controls.set_buttons_processing() self.rounds = rounds self.steps = steps if self.worker is None: self.prev_phase = self.next_phase self.info.set_current_phase(self.next_phase) self.worker = WorkerThread(self._simulation, self) def OnResult(self, event): if not event.source is self.worker: # ongoing simulation was aborted return self.worker = None self.simulation_info.map.grid = util.update_map( self.simulation_info.map.grid, event.result.map.grid ) self.next_phase = event.result.next_phase handle_statistics(self.graphs, event.result.round, event.result.data) self._graphics.set_map(self.simulation_info.map) if event.result.phase == "HEARING": self._graphics.add_votes(event.result.complaints) self._graphics.update() for m in event.result.messages: self.messages.add(str(m)) newr = self.prev_phase == "LEARNING" and self.next_phase == "COASTPLAN" if newr: self._graphics.reset_votes() if newr and self.rounds > 0: self.rounds -= 1 elif self.rounds == 0: self.steps -= 1 if self.rounds > 0 or self.steps > 0: self.run(self.rounds, self.steps) else: self.controls.set_buttons_ready() def OnStop(self, event): self.reset_gui() self._simulation = None self.worker = None self.simulation_info = None def OnClose(self, event): # TODO: Fix self.Destroy()
class Feed(object): def __init__(self, page): self.page = page self.conf = conf.getInstance() messageLikes_addHeaders(page) messageComments_addHeaders(page) self.messages = Messages() self.scroll_pos = 0 self.num_messages = None self.url_preview_html = unicode(open('url_preview.html').read()) def process(self): # add new messages if 'new_message' in self.page.form: data = { 'user_id': self.page.session.user.id, 'text': self.page.form['new_message'].value } id = self.messages.add(data) # add like if 'like' in self.page.form: message_id = int(self.page.form['like'].value) if message_id: message = Message(message_id) MessageLikes(message).toggle(self.page.session.user.id) # add comment for field in self.page.form.keys(): if field.startswith('new_comment_'): reference_id = field.split('_')[2] if reference_id: data = { 'user_id': self.page.session.user.id, 'reference_id': reference_id, 'text': self.page.form[field].value } id = self.messages.add(data) break # remember scroll if 'scroll_pos' in self.page.form: p = self.page.form['scroll_pos'].value self.scroll_pos = int(round(float(p), 0)) def getMessages(self, user_id=None, search=None, school_id=None): # TO DO: rename getMyMessages to something like getThisUsersMessages if search: messages = self.messages.getSearchMessages(search)['messages'] elif school_id: messages = self.messages.getSchoolSearchMessages(school_id)\ ['messages'] else: if not user_id: user_id = self.page.session.user.id if self.page.name == 'profile': messages = self.messages.getMyMessages(user_id)['messages'] else: messages = self.messages.getUserMessages(user_id)['messages'] self.num_messages = len(messages) hidden_fields = \ input(name='like', type='hidden') + \ input(name='scroll_pos', type='hidden') + \ input(name='prev_scroll_pos', type='hidden', value=self.scroll_pos) o = '' o += hidden_fields for m in messages: o += self._getMessageCard(m, search=search) return form(div(o, id='messageArea'), name='messages-form') def getNewMessageCard(self): return form(open('new-message2.html', 'r').read(), name='new-card-form') def _getMessageCard(self, message, search=None): message = odict(message) image = getUserImage(message.user_id) user_icon = div(img(src=image, width='70px', class_='img-thumbnail'), class_='userIcon') username = div(message.author, class_='messageAuthor') reason = div(message.reason, class_='messageReason') date = div(message.created, class_='messageDate') name_link = a(username, href='//%s/profile.py?u=%s' % (self.conf.baseurl, encrypt_int(message.user_id))) username_and_date = div(name_link + reason + date, class_='usernameAndDate') text = urlize(message.text, trim_url_limit=50, nofollow=True, target='_blank') text = self._highlightKeyTerms(text, search) messageLikes = MessageLikes(message) messageComments = MessageComments(message) footer = \ messageLikes.html_widget(self.page.session.user) + \ messageComments.html_widget() # hack need to instantiate m for each mesage: url_previews = '' for preview in Message(message.id).url_previews: preview2 = copy(preview) preview2['thumbnail_width'] = min(preview2['thumbnail_width'], 500) if not preview2['thumbnail_url']: preview2['thumbnail_url'] = '' url_previews += self.url_preview_html.format(**preview2) o = '' o += user_icon + username_and_date o += div(text, class_='messageText') o += url_previews o += div(footer, class_='messageFooter') o += messageLikes.html_likersSection() o += messageComments.html_commentsSection(self.page.session.user, search=search) return div(o, class_='messageCard', id='message_card_%s' % message.id) def _highlightKeyTerms(self, text, search=None): if not search: return text text2 = text for term in search.split(' '): term2 = r'(%s)(?!=)' % term text2 = re.sub(term2, r'<span class="search-term">\1</span>', text2, flags=re.IGNORECASE) return text2
class Window(wx.Frame): def __init__(self, parent, title): wx.Frame.__init__(self, parent, title=title) # Splitters and Panels self.controls_map_splitter = wx.SplitterWindow(self) self.controls_map_splitter.SetMinimumPaneSize(300) controls_panel = wx.Panel(self.controls_map_splitter) map_panel = wx.Panel(self.controls_map_splitter) self.graphs_messages_splitter = wx.SplitterWindow(controls_panel) self.graphs_messages_splitter.SetMinimumPaneSize(50) graphs_panel = wx.Panel(self.graphs_messages_splitter) messages_panel = wx.Panel(self.graphs_messages_splitter) # World graphic self._graphics = worldmap.WorldMap(map_panel) self.graphics_sizer = wx.BoxSizer(wx.VERTICAL) self.graphics_sizer.Add(self._graphics, 1, wx.EXPAND) map_panel.SetSizerAndFit(self.graphics_sizer) # Controls panel self.controls = Controls(controls_panel, (300, 250), self) # Info panel self.info = Info(controls_panel, (300, 250)) # Graph canvas self.graphs = graphs.Graphs(graphs_panel, (300, 300)) # Messages panel self.messages = Messages(messages_panel, (600, 200)) self.interface_sizer = wx.BoxSizer(wx.VERTICAL) self.controls_info_sizer = wx.BoxSizer(wx.HORIZONTAL) self.controls_info_sizer.Add(self.info, 0, wx.EXPAND) self.controls_info_sizer.Add((20, -1), proportion=0) # Padding self.controls_info_sizer.Add(self.controls, 1, wx.EXPAND) self.messages_sizer = wx.BoxSizer(wx.VERTICAL) self.messages_sizer.Add(self.messages, 1, wx.EXPAND) messages_panel.SetSizerAndFit(self.messages_sizer) self.graphs_sizer = wx.BoxSizer(wx.VERTICAL) self.graphs_sizer.Add(self.graphs, 1, wx.EXPAND) graphs_panel.SetSizerAndFit(self.graphs_sizer) self.interface_sizer.Add(self.controls_info_sizer, 0, wx.EXPAND) self.interface_sizer.Add(self.graphs_messages_splitter, 1, wx.EXPAND) controls_panel.SetSizerAndFit(self.interface_sizer) self.graphs_messages_splitter.SplitHorizontally( messages_panel, graphs_panel) self.controls_map_splitter.SplitVertically(controls_panel, map_panel) # Set up event handler for any worker thread results EVT_RESULT(self, self.OnResult) EVT_STOP(self, self.OnStop) # Set up close event so timer is properly stopped wx.EVT_CLOSE(self, self.OnClose) self.reset_gui() self.Show() def reset_gui(self): self.controls.reset_buttons() self.messages.clear() self.graphs.reset_data() # Event Methods def OnStart(self, event): self.controls.set_buttons_ready() self._simulation = simulation.Simulation() self._simulation.setup_config(self.controls.get_config_filename()) self.simulation_info = self._simulation.initialize() if not self.simulation_info.interface_config.print_messages: self.messages.deactivate() self._graphics.num_max_complaints = \ self.simulation_info.num_max_complaints self.rounds = 0 self.steps = 0 self.next_phase = "COASTPLAN" self.prev_phase = None self.worker = None def run(self, rounds, steps): assert rounds >= 0, "Rounds has to be a positive integer." assert steps >= 0, "Steps has to be a positive integer." assert steps > 0 or rounds > 0, "Rounds or steps needs to be positive." self.controls.set_status(rounds, steps) self.controls.set_buttons_processing() self.rounds = rounds self.steps = steps if self.worker is None: self.prev_phase = self.next_phase self.info.set_current_phase(self.next_phase) self.worker = WorkerThread(self._simulation, self) def OnResult(self, event): if not event.source is self.worker: # ongoing simulation was aborted return self.worker = None self.simulation_info.map.grid = util.update_map( self.simulation_info.map.grid, event.result.map.grid) self.next_phase = event.result.next_phase handle_statistics(self.graphs, event.result.round, event.result.data) self._graphics.set_map(self.simulation_info.map) if event.result.phase == "HEARING": self._graphics.add_votes(event.result.complaints) self._graphics.update() for m in event.result.messages: self.messages.add(str(m)) newr = self.prev_phase == "LEARNING" and self.next_phase == "COASTPLAN" if newr: self._graphics.reset_votes() if newr and self.rounds > 0: self.rounds -= 1 elif self.rounds == 0: self.steps -= 1 if self.rounds > 0 or self.steps > 0: self.run(self.rounds, self.steps) else: self.controls.set_buttons_ready() def OnStop(self, event): self.reset_gui() self._simulation = None self.worker = None self.simulation_info = None def OnClose(self, event): # TODO: Fix self.Destroy()