def getMenusForScope(self, entity, params): """Returns the featured menu items for one specific entity. A link to the home page of the specified entity is also included. Args: entity: the entity for which the entry should be constructed params: a dict with params for this View. """ filter = { 'prefix': params['document_prefix'], 'scope_path': entity.key().id_or_name(), 'is_featured': True, } entities = self._logic.getForFields(filter) submenus = [] # add a link to the home page submenu = (redirects.getHomeRedirect(entity, params), 'Home', 'allow') submenus.append(submenu) # add a link to all featured documents for entity in entities: #TODO only if a document is readable it might be added submenu = (redirects.getPublicRedirect(entity, self._params), entity.short_name, 'show') submenus.append(submenu) return submenus
def overviewGet(self, request, page_name, params, program_entity, **kwargs): """Handles the GET request for the Program Admins overview page. Args: request: Django HTTPRequest object page_name: Name for this page params: Params for this view program_entity: GSocProgram entity """ page_name = '%s %s' %(page_name, program_entity.name) list_params = params.copy() list_params['admin_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, list_params) } list_params['list_description'] = ugettext( 'An overview of all StudentProjects for %s. Click on an item to view ' 'the project, use the buttons on the list for withdrawing a project.'% (program_entity.name)) if lists.isDataRequest(request): return self.getOverviewData(request, list_params, program_entity) project_list = lists.getListGenerator(request, list_params, idx=0, visibility='admin') # fill contents with the list contents = [project_list] # call the _list method from base to display the list return self._list(request, params, contents, page_name)
def _editContext(self, request, context): """See base.View._editContext(). """ # entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['student_agreement'] = None return program = self._params['group_logic'].getFromKeyName(scope_path) if not (program and program.student_agreement): return agreement = program.student_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['student_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def _editContext(self, request, context): """See base.View._editContext. """ entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['mentor_agreement'] = None return entity = self._params['group_logic'].getFromKeyName(scope_path) if not (entity and entity.scope and entity.scope.mentor_agreement): return agreement = entity.scope.mentor_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['mentor_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def _editContext(self, request, context): """See base.View._editContext(). """ # entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['student_agreement'] = None return program = program_logic.logic.getFromKeyName(scope_path) if not (program and program.student_agreement): return agreement = program.student_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['student_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def listPublic(self, request, access_type, page_name=None, params=None, filter=None, **kwargs): """See base.View.list. """ account = accounts.getCurrentAccount() user = user_logic.logic.getForAccount(account) if account else None try: rights = self._params['rights'] rights.setCurrentUser(account, user) rights.checkIsHost() is_host = True except out_of_band.Error: is_host = False params = params.copy() if is_host: params['public_row_extra'] = lambda entity: { 'link': redirects.getAdminRedirect(entity, params) } else: params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, params) } new_filter = {} new_filter['scope_path'] = kwargs['scope_path'] new_filter['status'] = 'active' filter = dicts.merge(filter, new_filter) return self.list(request, 'allow', page_name=page_name, params=params, filter=filter)
def getMenusForScope(self, entity, params): """Returns the featured menu items for one specific entity. A link to the home page of the specified entity is also included. Args: entity: the entity for which the entry should be constructed params: a dict with params for this View. """ filter = { 'prefix' : params['document_prefix'], 'scope_path': entity.key().id_or_name(), 'is_featured': True, } entities = self._logic.getForFields(filter) submenus = [] # add a link to the home page submenu = (redirects.getHomeRedirect(entity, params), 'Home', 'allow') submenus.append(submenu) # add a link to all featured documents for entity in entities: #TODO only if a document is readable it might be added submenu = (redirects.getPublicRedirect(entity, self._params), entity.short_name, 'show') submenus.append(submenu) return submenus
def _editContext(self, request, context): """See base.View._editContext. """ entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: del form.fields['admin_agreement'] return entity = program_logic.logic.getFromKeyName(scope_path) if not (entity and entity.org_admin_agreement): return agreement = entity.org_admin_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['admin_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def _createReviewFor(self, entity, comment, score=0, is_public=True): """Creates a review for the given proposal and sends out a message to all followers. Args: entity: Student Proposal entity for which the review should be created comment: The textual contents of the review score: The score of the review (only used if the review is not public) is_public: Determines if the review is a public review """ from soc.logic.helper import notifications as notifications_helper from soc.modules.gsoc.logic.models.review import logic as review_logic from soc.modules.gsoc.logic.models.review_follower import logic as \ review_follower_logic # create the fields for the review entity fields = { 'link_id': 't%i' % (int(time.time() * 100)), 'scope': entity, 'scope_path': entity.key().id_or_name(), 'author': user_logic.logic.getForCurrentAccount(), 'content': comment, 'is_public': is_public, } # add the given score if the review is not public if not is_public: fields['score'] = score # create a new Review key_name = review_logic.getKeyNameFromFields(fields) review_entity = review_logic.updateOrCreateFromKeyName( fields, key_name) # get all followers fields = {'scope': entity} if is_public: fields['subscribed_public'] = True else: fields['subscribed_private'] = True followers = review_follower_logic.getForFields(fields) if is_public: # redirect to public page redirect_url = redirects.getPublicRedirect(entity, self._params) else: # redirect to review page redirect_url = redirects.getReviewRedirect(entity, self._params) for follower in followers: # sent to every follower except the reviewer if follower.user.key() != review_entity.author.key(): notifications_helper.sendNewReviewNotification( follower.user, review_entity, entity.title, redirect_url)
def _createReviewFor(self, entity, reviewer, comment, score=0, is_public=True): """Creates a review for the given proposal and sends out a message to all followers. Args: entity: Student Proposal entity for which the review should be created reviewer: A role entity of the reviewer (if possible, else None) comment: The textual contents of the review score: The score of the review (only used if the review is not public) is_public: Determines if the review is a public review """ from soc.logic.helper import notifications as notifications_helper from soc.logic.models.review import logic as review_logic from soc.logic.models.review_follower import logic as review_follower_logic # create the fields for the review entity fields = {'link_id': 't%i' % (int(time.time()*100)), 'scope': entity, 'scope_path': entity.key().id_or_name(), 'author': user_logic.logic.getForCurrentAccount(), 'content': comment, 'is_public': is_public, 'reviewer': reviewer } # add the given score if the review is not public if not is_public: fields['score'] = score # create a new Review key_name = review_logic.getKeyNameFromFields(fields) review_entity = review_logic.updateOrCreateFromKeyName(fields, key_name) # get all followers fields = {'scope': entity} if is_public: fields['subscribed_public'] = True else: fields['subscribed_private'] = True followers = review_follower_logic.getForFields(fields) if is_public: # redirect to public page redirect_url = redirects.getPublicRedirect(entity, self._params) else: # redirect to review page redirect_url = redirects.getReviewRedirect(entity, self._params) for follower in followers: # sent to every follower except the reviewer if follower.user.key() != review_entity.author.key(): notifications_helper.sendNewReviewNotification(follower.user, review_entity, entity.title, redirect_url)
def insertFields(self): """Add the necessary fields to the Form. """ # add common survey fields fields = super(OrgAppSurveyForm, self).insertFields() name = forms.fields.CharField( label='Organization Name', required=True, initial=self.data.get('name')) description = forms.fields.CharField( label='Description', required=True, widget=forms.widgets.Textarea, initial=self.data.get('description')) home_page = forms.fields.URLField( label='Home page', required=True, initial=self.data.get('home_page')) license_field = forms.fields.ChoiceField( choices=[(license,license) for license in licenses.LICENSES], label='Main Organization License', required=True, initial=self.data.get('license')) backup_admin = forms.fields.CharField( label='Backup Admin (Link ID)', required=True, initial=self.data.get('backup_admin')) tos_field = forms.fields.CharField( label='Admin Agreement', required=False, widget=widgets.AgreementField) # set the contents to the current ToS for Org Admins admin_agreement = self.survey.scope.org_admin_agreement if admin_agreement: tos_field.widget.text = admin_agreement.content params = {'url_name': 'document'} tos_field.widget.url = redirects.getPublicRedirect(admin_agreement, params) agreed_to_tos = forms.fields.BooleanField( label='I agree to the Admin Agreement', required=True, initial=self.data.get('agreed_to_tos')) # add fields to the top of the form fields.insert(0, 'name', name) fields.insert(1, 'description', description) fields.insert(2, 'home_page', home_page) fields.insert(3, 'license', license_field) # add fields to the bottom of the form fields['backup_admin'] = backup_admin fields['tos'] = tos_field fields['agreed_to_tos'] = agreed_to_tos return fields
def listTasks(self, request, access_type, page_name=None, params=None, **kwargs): """View where all the tasks can be searched from. """ from soc.modules.gci.views.models.task import view as task_view logic = params['logic'] program_entity = logic.getFromKeyFieldsOr404(kwargs) page_name = '%s %s' % (page_name, program_entity.name) list_params = task_view.getParams().copy() user_account = user_logic.getCurrentUser() user_fields = { 'user': user_account, 'status': 'active' } host_entity = host_logic.getForFields(user_fields, unique=True) tasks_filter = { 'program': program_entity, 'status': ['Open', 'Reopened', 'ClaimRequested'] } if host_entity: list_params['list_description'] = self.DEF_LIST_VALID_TASKS_MSG_FMT % ( program_entity.name) tasks_filter['status'].extend([ 'Claimed', 'ActionNeeded', 'Closed', 'AwaitingRegistration', 'NeedsWork', 'NeedsReview','Unapproved', 'Unpublished']) else: list_params.setdefault('public_field_ignore', []).append('mentors') list_params['list_description'] = self.DEF_LIST_PUBLIC_TASKS_MSG_FMT % ( program_entity.name) list_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getPublicRedirect(entity, list_params) } list_params['public_conf_min_num'] = list_params['public_conf_limit'] = 100 if lists.isDataRequest(request): return self.getListTasksData(request, list_params, tasks_filter) contents = [] order = ['-modified_on'] tasks_list = lists.getListGenerator(request, list_params, order=order, idx=0) contents.append(tasks_list) return self._list(request, list_params, contents, page_name)
def linkToEntity(self, entity): """ link to entity for a feed item """ url_name = CUSTOM_URL_NAMES.get(entity.kind().lower()) if not url_name: url_name = entity.kind().lower() params = {'url_name': url_name} return ('http://%s%s' % ( os.environ['HTTP_HOST'], getPublicRedirect(entity, params) ) )
def listSelf(self, request, access_type, page_name=None, params=None, **kwargs): """Lists all proposals from the current logged-in user for the given student. For params see base.View.public(). """ context = {} list_params = params.copy() list_params['list_description'] = \ 'List of my %(name_plural)s.' % list_params list_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, list_params) } ip_params = list_params.copy() # ineligible proposals description = ugettext('List of my ineligible/withdrawn %s.') % ( ip_params['name_plural']) ip_params['list_description'] = description ip_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, ip_params) } if request.GET.get('fmt') == 'json': scope_path = kwargs['scope_path'] return self.getListSelfData(request, list_params, ip_params, scope_path) valid_list = lists.getListGenerator(request, list_params, idx=0) ip_list = lists.getListGenerator(request, ip_params, idx=1) contents = [valid_list, ip_list] return self._list(request, list_params, contents, page_name, context)
def listStudentTasks(self, request, access_type, page_name=None, params=None, **kwargs): """Displays a list of all tasks for a given student. See base.View.list() for more details. """ # obtain program entity based on request params program = ghop_program_logic.logic.getFromKeyNameOr404( kwargs['scope_path']) user_account = user_logic.logic.getForCurrentAccount() filter = {'user': user_account, 'program': program} tasks = ghop_task_logic.logic.getForFields(filter=filter) tasks_by_orgs = {} for task in tasks: key = task.scope.key().id_or_name() if key in tasks_by_orgs: tasks_by_orgs[key][1].append(task) else: tasks_by_orgs[key] = (task.scope.name, [task]) contents = [] context = {} st_params = ghop_task_view.view.getParams().copy() st_params['list_template'] = 'soc/models/list.html' st_params['list_heading'] = 'modules/ghop/task/list/heading.html' st_params['list_row'] = 'modules/ghop/task/list/row.html' st_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, st_params) } # TODO(LIST) st_org_params = st_params.copy() for k, v in tasks_by_orgs.iteritems(): st_org_params[ 'list_description'] = self.DEF_STUDENT_TASKS_MSG_FMT % v[0] st_org_list = self._listStudentTasks(tasks_by_orgs[k][1], st_org_params) contents.append(st_org_list) return self._list(request, st_params, contents, page_name, context)
def showDetails(self, request, access_type, page_name=None, params=None, **kwargs): """Shows ranking details for the entity specified by **kwargs. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ logic = params['logic'] ranking = logic.getFromKeyFieldsOr404(kwargs) student = ranking.student all_d = gci_task_model.TaskDifficultyTag.all().fetch(100) list_params = params.copy() list_params[ 'list_description'] = self.DETAILS_MSG_FMT % student.user.name list_params['public_field_extra'] = lambda entity: { 'task': entity.title, 'org': entity.scope.name, 'points_difficulty': entity.taskDifficulty(all_d).value } list_params['public_field_keys'] = [ 'task', 'org', 'points_difficulty', 'closed_on' ] list_params['public_field_names'] = [ 'Task', 'Organization', 'Points (Difficulty)', 'Completed on' ] list_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, {'url_name': 'gci/task'}), } if lists.isDataRequest(request): return self.getListRankingDetailsData(request, list_params, student) contents = [] order = ['closed_on'] list = lists.getListGenerator(request, list_params, order=order, idx=0) contents.append(list) return self._list(request, list_params, contents, page_name)
def _getMapData(self, student_project_params, filter=None): """Constructs the JSON object required to generate Google Maps on organization home page. Args: student_project_params: params for student project view filter: a dict for the properties that the entities should have Returns: A JSON object containing map data. """ from soc.logic.models.student_project import logic as student_project_logic people = {} # get all the student_project entities for this organization student_project_entities = student_project_logic.getForFields(filter=filter) # construct a dictionary of mentors. For each mentor construct a # list of 3-tuple containing student, project title and url. This is # mainly done to track and pair all students and mentors who # have allowed to publish their locations. for entity in student_project_entities: if entity.mentor.publish_location and (entity.mentor.key().name() not in people.keys()): # if mentor has allowed to publish his location add it to the # mentors dictionary people[entity.mentor.key().name()] = { 'type': 'mentor', 'name': entity.mentor.name(), 'city': entity.mentor.res_city, 'ccTLD': entity.mentor.ccTld(), 'students': [] } if entity.student.publish_location: if entity.mentor.publish_location: people[entity.mentor.key().name()]['students'].append(entity.student.key().name()) people[entity.student.key().name()] = { 'type': 'student', 'name': entity.student.name(), 'city': entity.student.res_city, 'ccTLD': entity.student.ccTld(), 'summary': entity.title, 'url': redirects.getPublicRedirect(entity, student_project_params), 'mentor': entity.mentor.name() } return simplejson.dumps(people)
def sendNewNotificationMessage(notification_entity): """Sends an email to a user about a new notification. Args: notification_entity: Notification about which the message should be sent """ from soc.logic.models.site import logic as site_logic from soc.views.models.notification import view as notification_view # create the url to show this notification notification_url = 'http://%(host)s%(index)s' % { 'host' : system.getHostname(), 'index': redirects.getPublicRedirect(notification_entity, notification_view.getParams())} sender = mail_dispatcher.getDefaultMailSender() site_entity = site_logic.getSingleton() site_name = site_entity.site_name # get the default mail sender default_sender = mail_dispatcher.getDefaultMailSender() if not default_sender: # no valid sender found, abort logging.error('No default sender') return else: (sender_name, sender) = default_sender to = accounts.denormalizeAccount(notification_entity.scope.account).email() subject = DEF_NEW_NOTIFICATION_MSG_SUBJECT_FMT % notification_entity.subject # create the message contents messageProperties = { 'to_name': notification_entity.scope.name, 'sender_name': sender_name, 'to': to, 'sender': sender, 'site_name': site_name, 'subject': force_unicode(subject), 'notification' : notification_entity, 'notification_url' : notification_url } # send out the message using the default new notification template mail_dispatcher.sendMailFromTemplate('soc/mail/new_notification.html', messageProperties)
def sendNewNotificationMessage(notification_entity): """Sends an email to a user about a new notification. Args: notification_entity: Notification about which the message should be sent """ # pylint: disable-msg=W0612 import soc.views.models.notification # create the url to show this notification notification_url = "http://%(host)s%(index)s" % { 'host' : os.environ['HTTP_HOST'], 'index': redirects.getPublicRedirect(notification_entity, model_view.notification.view.getParams())} sender = mail_dispatcher.getDefaultMailSender() site_entity = model_logic.site.logic.getSingleton() site_name = site_entity.site_name # get the default mail sender default_sender = mail_dispatcher.getDefaultMailSender() if not default_sender: # no valid sender found, abort return else: (sender_name, sender) = default_sender to = accounts.denormalizeAccount(notification_entity.scope.account).email() # create the message contents messageProperties = { 'to_name': notification_entity.scope.name, 'sender_name': sender_name, 'to': to, 'sender': sender, 'site_name': site_name, 'subject': force_unicode(DEF_NEW_NOTIFICATION_MSG), 'notification' : notification_entity, 'notification_url' : notification_url } # send out the message using the default new notification template mail_dispatcher.sendMailFromTemplate('soc/mail/new_notification.html', messageProperties)
def _editContext(self, request, context): """see base.View._editContext. """ entity = context['entity'] if entity: on = entity.scope else: seed = context['seed'] on = seed['commented'] params = {'url_name': self._params['comment_on_url_name']} redirect = redirects.getPublicRedirect(on, params) context['comment_on_url_name'] = self._params['comment_on_url_name'] context['comment_on_name'] = self._params['comment_on_name'] context['work_link'] = redirect
def _editContext(self, request, context): """See base.View._editContext. """ from soc.logic.models.org_app_survey import logic as org_app_logic entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['admin_agreement'] = None return org_entity = self._params['group_logic'].getFromKeyNameOr404( scope_path) org_app = org_app_logic.getForProgramOr404(org_entity.scope) if org_app: user_entity = context['user'] fields = {'main_admin': user_entity, 'survey': org_app} record_logic = org_app_logic.getRecordLogic() org_app_record = record_logic.getForFields(fields, unique=True) if not entity and org_app_record: form.fields['agreed_to_admin_agreement'].initial = True if not (org_entity and org_entity.scope and org_entity.scope.org_admin_agreement): return agreement = org_entity.scope.org_admin_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['admin_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def _editContext(self, request, context): """See base.View._editContext. """ from soc.logic.models.org_app_survey import logic as org_app_logic entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['admin_agreement'] = None return org_entity = self._params['group_logic'].getFromKeyNameOr404(scope_path) org_app = org_app_logic.getForProgramOr404(org_entity.scope) if org_app: user_entity = context['user'] fields = {'main_admin': user_entity, 'survey': org_app} record_logic = org_app_logic.getRecordLogic() org_app_record = record_logic.getForFields(fields, unique=True) if not entity and org_app_record: form.fields['agreed_to_admin_agreement'].initial = True if not (org_entity and org_entity.scope and org_entity.scope.org_admin_agreement): return agreement = org_entity.scope.org_admin_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['admin_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def showDetails(self, request, access_type, page_name=None, params=None, **kwargs): """Shows ranking details for the entity specified by **kwargs. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ logic = params['logic'] ranking = logic.getFromKeyFieldsOr404(kwargs) student = ranking.student all_d = gci_task_model.TaskDifficultyTag.all().fetch(100) list_params = params.copy() list_params['list_description'] = self.DETAILS_MSG_FMT % student.user.name list_params['public_field_extra'] = lambda entity: { 'task': entity.title, 'org': entity.scope.name, 'points_difficulty': entity.taskDifficulty(all_d).value } list_params['public_field_keys'] = [ 'task', 'org', 'points_difficulty', 'closed_on'] list_params['public_field_names'] = [ 'Task', 'Organization', 'Points (Difficulty)', 'Completed on'] list_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, {'url_name': 'gci/task'}), } if lists.isDataRequest(request): return self.getListRankingDetailsData(request, list_params, student) contents = [] order = ['closed_on'] list = lists.getListGenerator(request, list_params, order=order, idx=0) contents.append(list) return self._list(request, list_params, contents, page_name)
def _editContext(self, request, context): """See base.View._editContext. """ entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['admin_agreement'] = None return org_app = org_app_logic.logic.getFromKeyName(scope_path) if not entity and org_app: if org_app.applicant.key() == context['user'].key(): form.fields[ 'agreed_to_admin_agreement'] = forms.fields.BooleanField( widget=widgets.ReadOnlyInput, initial=True, required=True, help_text=self.DEF_ALREADY_AGREED_MSG) entity = org_logic.logic.getFromKeyName(scope_path) if not (entity and entity.scope and entity.scope.org_admin_agreement): return agreement = entity.scope.org_admin_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['admin_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
def acceptedProjects(self, request, access_type, page_name=None, params=None, filter=None, **kwargs): """See base.View.list. """ contents = [] logic = params['logic'] program_entity = logic.getFromKeyFieldsOr404(kwargs) filter = {'status': 'accepted', 'program': program_entity} fmt = {'name': program_entity.name} description = self.DEF_ACCEPTED_PROJECTS_MSG_FMT % fmt from soc.modules.gsoc.views.models import student_project as sp_view ap_params = sp_view.view.getParams().copy() # accepted projects ap_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, ap_params) } ap_params['list_description'] = description ap_params['list_heading'] = 'soc/student_project/list/heading_all.html' ap_params['list_row'] = 'soc/student_project/list/row_all.html' prefetch = ['mentor', 'student', 'scope'] return self.list(request, access_type, page_name=page_name, params=ap_params, filter=filter, prefetch=prefetch)
def overviewGet(self, request, page_name, params, program_entity, **kwargs): """Handles the GET request for the Program Admins overview page. Args: request: Django HTTPRequest object page_name: Name for this page params: Params for this view program_entity: GSocProgram entity """ page_name = '%s %s' % (page_name, program_entity.name) list_params = params.copy() list_params['admin_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, list_params) } list_params['list_description'] = ugettext( 'An overview of all StudentProjects for %s. Click on an item to view ' 'the project, use the buttons on the list for withdrawing a project.' % (program_entity.name)) if lists.isDataRequest(request): return self.getOverviewData(request, list_params, program_entity) project_list = lists.getListGenerator(request, list_params, idx=0, visibility='admin') # fill contents with the list contents = [project_list] # call the _list method from base to display the list return self._list(request, params, contents, page_name)
def _editContext(self, request, context): """See base.View._editContext. """ entity = context['entity'] form = context['form'] if 'scope_path' in form.initial: scope_path = form.initial['scope_path'] elif 'scope_path' in request.POST: scope_path = request.POST['scope_path'] else: form.fields['admin_agreement'] = None return org_app = org_app_logic.logic.getFromKeyName(scope_path) if not entity and org_app: if org_app.applicant.key() == context['user'].key(): form.fields['agreed_to_admin_agreement'] = forms.fields.BooleanField( widget=widgets.ReadOnlyInput, initial=True, required=True, help_text=self.DEF_ALREADY_AGREED_MSG) entity = org_logic.logic.getFromKeyName(scope_path) if not (entity and entity.scope and entity.scope.org_admin_agreement): return agreement = entity.scope.org_admin_agreement content = agreement.content params = {'url_name': 'document'} widget = form.fields['admin_agreement'].widget widget.text = content widget.url = redirects.getPublicRedirect(agreement, params)
For params see base.View().public() """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse( error, request, template=params['error_public']) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name # cancel should go to the public view params['edit_cancel_redirect'] = redirects.getPublicRedirect(entity, params) if request.POST: return self.stEditPost(request, context, params, entity, **kwargs) else: #request.GET return self.stEditGet(request, context, params, entity, **kwargs) def stEditGet(self, request, context, params, entity, **kwargs): """Handles the GET request for the student's edit page. Args: entity: the student project entity rest: see base.View.public() """ # populate form with the existing entity
def createNotificationMail(request, *args, **kwargs): """Appengine task that sends mail to the subscribed users. Expects the following to be present in the POST dict: comment_key: Specifies the comment id for which to send the notifications task_key: Specifies the task key name for which the comment belongs to Args: request: Django Request object """ from soc.modules.gci.logic.helper import notifications as gci_notifications from soc.modules.gci.logic.models import comment as gci_comment_logic from soc.modules.gci.logic.models import task_subscription as \ gci_task_subscription_logic # set default batch size batch_size = 10 post_dict = request.POST comment_key = post_dict.get('comment_key') task_key = post_dict.get('task_key') if not (comment_key and task_key): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid createNotificationMail data: %s' % post_dict) comment_key = long(comment_key) # get the task entity under which the specified comment was made task_entity = gci_task_logic.logic.getFromKeyName(task_key) # get the comment for the given id comment_entity = gci_comment_logic.logic.getFromID(comment_key, task_entity) if not comment_entity: # invalid comment specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid comment specified: %s/%s' % (comment_key, task_key)) # check and retrieve the subscriber_start_key that has been done last idx = post_dict.get('subscriber_start_index', '') subscriber_start_index = int(idx) if idx.isdigit() else 0 # get all subscribers to GCI task fields = { 'task': task_entity, } ts_entity = gci_task_subscription_logic.logic.getForFields(fields, unique=True) subscribers = db.get( ts_entity.subscribers[subscriber_start_index:subscriber_start_index + batch_size]) task_url = "http://%(host)s%(task)s" % { 'host': system.getHostname(), 'task': redirects.getPublicRedirect(task_entity, {'url_name': 'gci/task'}), } # create the data for the mail to be sent message_properties = { 'task_url': task_url, 'redirect_url': "%(task_url)s#c%(cid)d" % { 'task_url': task_url, 'cid': comment_entity.key().id_or_name() }, 'comment_entity': comment_entity, 'task_entity': task_entity, } subject = DEF_TASK_UPDATE_SUBJECT_FMT % { 'program_name': task_entity.program.short_name, 'title': task_entity.title, } for subscriber in subscribers: gci_notifications.sendTaskUpdateMail(subscriber, subject, message_properties) if len(subscribers) == batch_size: # spawn task for sending out notifications to next set of subscribers next_start = subscriber_start_index + batch_size task_params = { 'comment_key': comment_key, 'task_key': task_key, 'subscriber_start_index': next_start } task_url = '/tasks/gci/task/mail/create' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add('mail') # return OK return http.HttpResponse()
def __init__(self, params=None): """Defines the fields and methods required for the base View class to provide the user with list, public, create, edit and delete views. Params: params: a dict with params for this View """ rights = access.Checker(params) rights['edit'] = ['deny'] rights['show'] = [('checkIsMyEntity', [notification_logic, 'scope_path'])] rights['delete'] = [('checkIsMyEntity', [notification_logic, 'scope_path'])] rights['list'] = ['checkIsUser'] # create is developer only for the time being to test functionality rights['create'] = ['checkIsDeveloper'] new_params = {} new_params['logic'] = notification_logic new_params['rights'] = rights new_params['name'] = "Notification" new_params['no_create_with_key_fields'] = True new_params['create_form'] = CreateForm new_params['edit_redirect'] = '/%(url_name)s/list' new_params['public_configuration'] = {"multiselect": True} new_params['public_field_prefetch'] = ['from_user'] new_params['public_field_extra'] = lambda entity: { "from": entity.from_user.name if entity.from_user else site_logic.getSingleton().site_name, "unread": "Not Read" if entity.unread else "Read", } new_params['public_field_props'] = { "unread": { "stype": "select", "editoptions": {"value": ":All;^Read$:Read;^Not Read$:Not Read"} } } new_params['public_conf_extra'] = { "multiselect": True, } new_params['public_field_keys'] = ["unread", "from", "subject", "created_on",] new_params['public_field_names'] = ["Unread", "From", "Subject", "Received on"] new_params['public_button_global'] = [ { 'bounds': [1,'all'], 'id': 'mark_read', 'caption': 'Mark as Read', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1,'all'], 'id': 'mark_unread', 'caption': 'Mark as Unread', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1,'all'], 'id': 'delete', 'caption': 'Delete Notification', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }] params = dicts.merge(params, new_params) params['public_row_extra'] = lambda entity: { "link": redirects.getPublicRedirect(entity, params) } super(View, self).__init__(params=params)
def manageOverview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to see an overview of their Organization's Student Projects. For params see base.View().public() """ from soc.modules.gsoc.logic.models.survey import grading_logic as \ grading_survey_logic from soc.modules.gsoc.logic.models.survey import project_logic as \ project_survey_logic from soc.modules.gsoc.logic.models.survey_record import grading_logic from soc.modules.gsoc.logic.models.survey_record import project_logic # make sure the organization exists org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path']) page_name = '%s %s' % (page_name, org_entity.name) mo_params = params.copy() #list all active projects mo_params['list_description'] = ugettext( 'List of all %s for %s, if you are an Org Admin you can click ' 'a project for more actions. Such as reassigning mentors or viewing ' 'results of the evaluations.' %(params['name_plural'], org_entity.name) ) mo_params['public_field_names'] = params['public_field_names'] + [ 'Mentor evaluation', 'Student Evaluation'] mo_params['public_field_keys'] = params['public_field_keys'] + [ 'mentor_evaluation', 'student_evaluation'] fields = {'scope': org_entity, 'status': ['active', 'inactive']} org_admin = org_admin_logic.getForFields(fields, unique=True) # Org Admins get a link to manage the project, others go to public page if org_admin: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getManageRedirect(entity, mo_params) } else: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getPublicRedirect(entity, mo_params) } mo_params['public_field_prefetch'] = ['student', 'mentor', 'scope'] mo_params['public_field_extra'] = lambda entity, ps, psc, gs, gsc: { 'org': entity.scope.name, 'student': '%s (%s)' % (entity.student.name(), entity.student.email), 'mentor': entity.mentor.name(), 'mentor_evaluation': '%d/%d' % ( grading_logic.getQueryForFields({'project': entity}).count(), gsc), 'student_evaluation': '%d/%d' % ( project_logic.getQueryForFields({'project': entity}).count(), psc), } if lists.isDataRequest(request): return self.getManageOverviewData(request, mo_params, org_entity) mo_list = lists.getListGenerator(request, mo_params, idx=0) contents = [mo_list] # call the _list method from base to display the list return self._list(request, mo_params, contents, page_name)
class View(base.View): """View methods for the Student Project model. """ DEF_NO_RECORD_AVAILABLE_MSG = ugettext('No Record Available') DEF_VIEW_RECORD_MSG = ugettext('View Record') DEF_TAKE_SURVEY_MSG = ugettext('Take Survey') def __init__(self, params=None): """Defines the fields and methods required for the base View class to provide the user with list, public, create, edit and delete views. Params: params: a dict with params for this View """ rights = access.GSoCChecker(params) rights['any_access'] = ['allow'] rights['create'] = ['checkIsDeveloper'] rights['edit'] = ['checkIsDeveloper'] rights['delete'] = ['checkIsDeveloper'] rights['show'] = ['allow'] rights['list'] = ['checkIsDeveloper'] rights['manage'] = [('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkStudentProjectHasStatus', [['accepted', 'failed', 'completed', 'withdrawn']])] rights['manage_overview'] = [('checkHasAny', [[ ('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkHasRoleForScope', [mentor_logic, ['active', 'inactive']]) ]])] # TODO: lack of better name here! rights['st_edit'] = [ 'checkCanEditStudentProjectAsStudent', ('checkStudentProjectHasStatus', [['accepted', 'completed']]) ] rights['overview'] = [('checkIsHostForProgram', [program_logic])] new_params = {} new_params['logic'] = project_logic new_params['rights'] = rights new_params['name'] = 'Student Project' new_params['url_name'] = 'gsoc/student_project' new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['sidebar_grouping'] = 'Students' new_params['scope_view'] = org_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_create_with_key_fields'] = True new_params['extra_dynaexclude'] = [ 'program', 'status', 'link_id', 'mentor', 'additional_mentors', 'student', 'passed_evaluations', 'failed_evaluations' ] new_params['create_extra_dynaproperties'] = { 'scope_path': forms.CharField(widget=forms.HiddenInput, required=True), 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'student_id': forms.CharField(label='Student Link ID', required=True), 'mentor_id': forms.CharField(label='Mentor Link ID', required=True), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_student': cleaning.clean_link_id('student'), 'clean_mentor': cleaning.clean_link_id('mentor'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), 'clean': cleaning.validate_student_project('scope_path', 'mentor_id', 'student_id') } new_params['edit_extra_dynaproperties'] = { 'link_id': forms.CharField(widget=forms.HiddenInput), } patterns = [ (r'^%(url_name)s/(?P<access_type>manage_overview)/%(scope)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage_overview', 'Overview of %(name_plural)s to Manage for'), (r'^%(url_name)s/(?P<access_type>manage)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage', 'Manage %(name)s'), (r'^%(url_name)s/(?P<access_type>st_edit)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.st_edit', 'Edit my %(name)s'), (r'^%(url_name)s/(?P<access_type>overview)/(?P<scope_path>%(ulnp)s)/%(lnp)s$', 'soc.modules.gsoc.views.models.%(module_name)s.overview', 'Overview of all %(name_plural)s for'), ] new_params['extra_django_patterns'] = patterns new_params['edit_template'] = 'soc/student_project/edit.html' new_params['manage_template'] = 'soc/student_project/manage.html' new_params['public_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['public_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'org': entity.scope.name, } new_params['public_field_keys'] = [ 'student', 'title', 'mentor', 'org', 'status' ] new_params['public_field_names'] = [ 'Student', 'Title', 'Mentor', 'Organization', 'Status' ] new_params['org_home_field_prefetch'] = ['mentor', 'student'] new_params['org_home_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': ', '.join(mentor.name() for mentor in [entity.mentor] + db.get( entity.additional_mentors)) } new_params['org_home_field_keys'] = [ 'student', 'title', 'mentor', 'status' ] new_params['org_home_field_names'] = [ 'Student', 'Title', 'Mentor', 'Status' ] # define the list redirect action to show the notification new_params['public_row_extra'] = new_params[ 'org_home_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, new_params) } new_params['org_home_row_action'] = { 'type': 'redirect_custom', 'parameters': dict(new_window=False), } new_params['admin_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['admin_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'student_id': entity.student.link_id } new_params['admin_field_keys'] = [ 'student', 'title', 'mentor', 'status', 'student_id' ] new_params['admin_field_names'] = [ 'Student', 'Title', 'Mentor', 'Status', 'Student Link ID' ] new_params['admin_field_hidden'] = ['student_id'] new_params['admin_conf_extra'] = { 'multiselect': True, } new_params['admin_button_global'] = [{ 'bounds': [1, 'all'], 'id': 'withdraw', 'caption': 'Withdraw Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1, 'all'], 'id': 'accept', 'caption': 'Accept Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }] params = dicts.merge(params, new_params) super(View, self).__init__(params=params) # create the form that students will use to edit their projects dynaproperties = { 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), } student_edit_form = dynaform.newDynaForm( dynabase=self._params['dynabase'], dynamodel=self._params['logic'].getModel(), dynaexclude=self._params['create_dynaexclude'], dynaproperties=dynaproperties, ) self._params['student_edit_form'] = student_edit_form def _editGet(self, request, entity, form): """See base.View._editGet(). """ form.fields['link_id'].initial = entity.link_id form.fields['student_id'].initial = entity.student.link_id form.fields['mentor_id'].initial = entity.mentor.link_id return super(View, self)._editGet(request, entity, form) def _editPost(self, request, entity, fields): """See base.View._editPost(). """ if not entity: fields['link_id'] = 't%i' % (int(time.time() * 100)) else: fields['link_id'] = entity.link_id # fill in the scope via call to super super(View, self)._editPost(request, entity, fields) # editing a project so set the program, student and mentor field if entity: organization = entity.scope else: organization = fields['scope'] fields['program'] = organization.scope filter = {'scope': fields['program'], 'link_id': fields['student_id']} fields['student'] = student_logic.logic.getForFields(filter, unique=True) filter = { 'scope': organization, 'link_id': fields['mentor_id'], 'status': 'active' } fields['mentor'] = mentor_logic.getForFields(filter, unique=True) def _public(self, request, entity, context): """Adds the names of all additional mentors to the context. For params see base.View._public() """ additional_mentors = entity.additional_mentors if not additional_mentors: context['additional_mentors'] = [] else: mentor_names = [] for mentor_key in additional_mentors: additional_mentor = mentor_logic.getFromKeyName( mentor_key.id_or_name()) mentor_names.append(additional_mentor.name()) context['additional_mentors'] = ', '.join(mentor_names) def getOverviewData(self, request, params, program): """Return data for withdraw. """ fields = { 'program': program, } idx = lists.getListIndex(request) if idx != 0: return lists.getErrorResponse(request, "idx not valid") contents = lists.getListData(request, params, fields, visibility='admin') return lists.getResponse(request, contents) @decorators.merge_params @decorators.check_access def overview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Program Admins to see/control all StudentProjects. For args see base.View().public() """ program_entity = program_logic.getFromKeyFieldsOr404(kwargs) if request.POST: return self.overviewPost(request, params, program_entity) else: #request.GET return self.overviewGet(request, page_name, params, program_entity, **kwargs) def overviewPost(self, request, params, program): """Handles the POST request for the Program Admins overview page. Args: request: Django HTTPRequest object params: Params for this view program: GSoCProgram entity """ project_logic = params['logic'] post_dict = request.POST data = simplejson.loads(post_dict.get('data', '[]')) button_id = post_dict.get('button_id', '') if button_id not in ['withdraw', 'accept']: logging.warning('Invalid button ID found %s' % (button_id)) return http.HttpResponse() project_keys = [] for selected in data: project_keys.append(selected['key']) # get all projects and prefetch the program field projects = project_logic.getFromKeyName(project_keys) project_logic.prefetchField('program', projects) # filter out all projects not belonging to the current program projects = [p for p in projects if p.program.key() == program.key()] for p in projects: fields = {} if button_id == 'withdraw': fields['status'] = 'withdrawn' elif button_id == 'accept': fields['status'] = 'accepted' # update the project with the new status project_logic.updateEntityProperties(p, fields) # return a 200 response return http.HttpResponse() def overviewGet(self, request, page_name, params, program_entity, **kwargs): """Handles the GET request for the Program Admins overview page. Args: request: Django HTTPRequest object page_name: Name for this page params: Params for this view program_entity: GSocProgram entity """ page_name = '%s %s' % (page_name, program_entity.name) list_params = params.copy() list_params['admin_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, list_params) } list_params['list_description'] = ugettext( 'An overview of all StudentProjects for %s. Click on an item to view ' 'the project, use the buttons on the list for withdrawing a project.' % (program_entity.name)) if lists.isDataRequest(request): return self.getOverviewData(request, list_params, program_entity) project_list = lists.getListGenerator(request, list_params, idx=0, visibility='admin') # fill contents with the list contents = [project_list] # call the _list method from base to display the list return self._list(request, params, contents, page_name) def _getManageData(self, request, gps_params, ps_params, entity): """Returns the JSONResponse for the Manage page. Args: request: HTTPRequest object gps_params: GradingProjectSurvey list params ps_params: ProjectSurvey list params entity: StudentProject entity """ idx = lists.getListIndex(request) if idx == 0: params = gps_params elif idx == 1: params = ps_params else: return lists.getErrorResponse(request, "idx not valid") fields = {'project': entity} record_logic = params['logic'].getRecordLogic() record_entities = record_logic.getForFields(fields) record_dict = dict( (i.survey.key(), i) for i in record_entities if i.survey) record_getter = lambda entity: record_dict.get(entity.key()) args = [record_getter] fields = {'scope': entity.program, 'prefix': 'gsoc_program'} contents = lists.getListData(request, params, fields, args=args) return lists.getResponse(request, contents) @decorators.merge_params @decorators.check_access def manage(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to manage their Student Projects. For params see base.View().public() """ import soc.logic.lists from soc.modules.gsoc.views.models.grading_project_survey import view as \ grading_survey_view from soc.modules.gsoc.views.models.project_survey import view as \ project_survey_view entity = self._logic.getFromKeyFieldsOr404(kwargs) template = params['manage_template'] # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = "%s '%s' from %s" % (page_name, entity.title, entity.student.name()) context['entity'] = entity if project_logic.canChangeMentors(entity): # only accepted project can have their mentors managed self._enableMentorManagement(entity, params, context) # list all surveys for this Project's Program gps_params = grading_survey_view.getParams().copy() gps_params['list_description'] = \ 'List of all Mentor Evaluations for this Project' gps_params['public_row_extra'] = lambda entity, *args: {} gps_params['public_row_action'] = {} gps_params['public_field_keys'] = [ "title", "taken_by", "taken_on", "record_url", "take_url" ] gps_params['public_field_names'] = [ "Title", "Taken by", "Taken on", "View", "(Re) Take", ] no_record = self.DEF_NO_RECORD_AVAILABLE_MSG # TODO(SRabbelier): use buttons instead project_entity = entity getExtra = lambda params: lambda entity, re: { "taken_by": no_record if not re(entity) else re(entity).user.name, "taken_on": no_record if not re(entity) else str(re(entity).modified), "record_url": no_record if not re(entity) else lists.urlize( redirects.getViewSurveyRecordRedirect(re(entity), params), name=self.DEF_VIEW_RECORD_MSG), "take_url": lists.urlize(redirects.getTakeProjectSurveyRedirect( project_entity, { 'survey': entity, 'params': params }), name=self.DEF_TAKE_SURVEY_MSG), } gps_params['public_field_extra'] = getExtra(gps_params) # get the ProjectSurvey list ps_params = project_survey_view.getParams().copy() ps_params['list_description'] = \ 'List of all Student Evaluations for this Project' ps_params['public_row_extra'] = lambda entity, *args: {} ps_params['public_row_action'] = {} ps_params['public_field_keys'] = gps_params['public_field_keys'] ps_params['public_field_names'] = gps_params['public_field_names'] ps_params['public_field_ignore'] = ["take_url"] ps_params['public_field_extra'] = getExtra(ps_params) if lists.isDataRequest(request): return self._getManageData(request, gps_params, ps_params, entity) gps_list = lists.getListGenerator(request, gps_params, idx=0) ps_list = lists.getListGenerator(request, ps_params, idx=1) # store both lists in the content content = [gps_list, ps_list] context['evaluation_list'] = soc.logic.lists.Lists(content) if request.POST: return self.managePost(request, template, context, params, entity, **kwargs) else: #request.GET return self.manageGet(request, template, context, params, entity, **kwargs) def _enableMentorManagement(self, entity, params, context): """Sets the data required to manage mentors for a StudentProject. Args: entity: StudentProject entity to manage params: params dict for the manage view context: context for the manage view """ context['can_manage_mentors'] = True # get all mentors for this organization fields = {'scope': entity.scope, 'status': 'active'} mentors = mentor_logic.getForFields(fields) choices = [(mentor.link_id, '%s (%s)' % (mentor.name(), mentor.link_id)) for mentor in mentors] # create the form that org admins will use to reassign a mentor dynafields = [ { 'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Primary Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': choices, }, ] dynaproperties = params_helper.getDynaFields(dynafields) mentor_edit_form = dynaform.newDynaForm( dynabase=params['dynabase'], dynaproperties=dynaproperties, ) params['mentor_edit_form'] = mentor_edit_form additional_mentors = entity.additional_mentors # we want to show the names of the additional mentors in the context # therefore they need to be resolved to entities first additional_mentors_context = [] for mentor_key in additional_mentors: mentor_entity = mentor_logic.getFromKeyName( mentor_key.id_or_name()) additional_mentors_context.append(mentor_entity) context['additional_mentors'] = additional_mentors_context # all mentors who are not already an additional mentor or # the primary mentor are allowed to become an additional mentor possible_additional_mentors = [ m for m in mentors if (m.key() not in additional_mentors) and ( m.key() != entity.mentor.key()) ] # create the information to be shown on the additional mentor form additional_mentor_choices = [ (mentor.link_id, '%s (%s)' % (mentor.name(), mentor.link_id)) for mentor in possible_additional_mentors ] dynafields = [ { 'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Co-Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': additional_mentor_choices, }, ] dynaproperties = params_helper.getDynaFields(dynafields) additional_mentor_form = dynaform.newDynaForm( dynabase=params['dynabase'], dynaproperties=dynaproperties, ) params['additional_mentor_form'] = additional_mentor_form def manageGet(self, request, template, context, params, entity, **kwargs): """Handles the GET request for the project's manage page. Args: template: the template used for this view entity: the student project entity rest: see base.View.public() """ get_dict = request.GET if 'remove' in get_dict and entity.status == 'accepted': # get the mentor to remove fields = {'link_id': get_dict['remove'], 'scope': entity.scope} mentor = mentor_logic.getForFields(fields, unique=True) additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor from the additional mentors list additional_mentors.remove(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page without GET arguments redirect = request.path return http.HttpResponseRedirect(redirect) if project_logic.canChangeMentors(entity): # populate forms with the current mentors set initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form']( initial=initial) context['additional_mentor_form'] = params[ 'additional_mentor_form']() return responses.respond(request, template, context) def managePost(self, request, template, context, params, entity, **kwargs): """Handles the POST request for the project's manage page. Args: template: the template used for this view entity: the student project entity rest: see base.View.public() """ post_dict = request.POST if 'set_mentor' in post_dict and project_logic.canChangeMentors( entity): form = params['mentor_edit_form'](post_dict) return self._manageSetMentor(request, template, context, params, entity, form) elif 'add_additional_mentor' in post_dict and \ project_logic.canChangeMentors(entity): form = params['additional_mentor_form'](post_dict) return self._manageAddAdditionalMentor(request, template, context, params, entity, form) else: # unexpected error return the normal page logging.warning('Unexpected POST data found') return self.manageGet(request, template, context, params, entity) def _manageSetMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's mentor. Args: template: the template used for this view entity: the student project entity form: instance of the form used to set the mentor rest: see base.View.public() """ if not form.is_valid(): context['mentor_edit_form'] = form # add an a fresh additional mentors form context['additional_mentor_form'] = params[ 'additional_mentor_form']() return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = { 'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active' } mentor = mentor_logic.getForFields(fields, unique=True) # update the project with the assigned mentor fields = {'mentor': mentor} additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor that is now becoming the primary mentor additional_mentors.remove(mentor.key()) fields['additional_mentors'] = additional_mentors # update the project with the new mentor and possible # new set of additional mentors project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect) def _manageAddAdditionalMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's additional mentors. Args: template: the template used for this view entity: the student project entity form: instance of the form used to add an additional mentor rest: see base.View.public() """ if not form.is_valid(): context['additional_mentor_form'] = form # add a fresh edit mentor form initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form']( initial=initial) return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = { 'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active' } mentor = mentor_logic.getForFields(fields, unique=True) # add this mentor to the additional mentors if not entity.additional_mentors: additional_mentors = [mentor.key()] else: additional_mentors = entity.additional_mentors additional_mentors.append(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect) def getManageOverviewData(self, request, mo_params, org_entity): """Returns the manageOverview data. """ args = [] fields = {} idx = lists.getListIndex(request) if idx == 0: from soc.modules.gsoc.logic.models.survey import grading_logic as \ grading_survey_logic from soc.modules.gsoc.logic.models.survey import project_logic as \ project_survey_logic from soc.modules.gsoc.logic.models.survey_record import grading_logic from soc.modules.gsoc.logic.models.survey_record import project_logic program_entity = org_entity.scope fields = {'scope_path': program_entity.key().id_or_name()} # count the number of have been active ProjectSurveys project_surveys = project_survey_logic.getForFields(fields) project_survey_count = len(project_surveys) for project_survey in project_surveys: if not project_survey_logic.hasRecord(project_survey): project_survey_count = project_survey_count - 1 # count the number of have been active GradingProjectSurveys grading_surveys = grading_survey_logic.getForFields(fields) grading_survey_count = len(grading_surveys) for grading_survey in grading_surveys: if not grading_survey_logic.hasRecord(grading_survey): grading_survey_count = grading_survey_count - 1 fields = {'scope': org_entity} params = mo_params args = [ project_surveys, project_survey_count, grading_surveys, grading_survey_count ] else: return lists.getErrorResponse(request, 'idx not valid') contents = lists.getListData(request, params, fields, args=args) return lists.getResponse(request, contents) @decorators.merge_params @decorators.check_access def manageOverview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to see an overview of their Organization's Student Projects. For params see base.View().public() """ from soc.modules.gsoc.logic.models.survey import grading_logic as \ grading_survey_logic from soc.modules.gsoc.logic.models.survey import project_logic as \ project_survey_logic from soc.modules.gsoc.logic.models.survey_record import grading_logic from soc.modules.gsoc.logic.models.survey_record import project_logic # make sure the organization exists org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path']) page_name = '%s %s' % (page_name, org_entity.name) mo_params = params.copy() #list all active projects mo_params['list_description'] = ugettext( 'List of all %s for %s, if you are an Org Admin you can click ' 'a project for more actions. Such as reassigning mentors or viewing ' 'results of the evaluations.' % (params['name_plural'], org_entity.name)) mo_params['public_field_names'] = params['public_field_names'] + [ 'Mentor evaluation', 'Student Evaluation' ] mo_params['public_field_keys'] = params['public_field_keys'] + [ 'mentor_evaluation', 'student_evaluation' ] fields = {'scope': org_entity, 'status': ['active', 'inactive']} org_admin = org_admin_logic.getForFields(fields, unique=True) # Org Admins get a link to manage the project, others go to public page if org_admin: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getManageRedirect(entity, mo_params) } else: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getPublicRedirect(entity, mo_params) } mo_params['public_field_prefetch'] = ['student', 'mentor', 'scope'] mo_params['public_field_extra'] = lambda entity, ps, psc, gs, gsc: { 'org': entity.scope.name, 'student': '%s (%s)' % (entity.student.name(), entity.student.email), 'mentor': entity.mentor.name(), 'mentor_evaluation': '%d/%d' % (grading_logic.getQueryForFields({ 'project': entity }).count(), gsc), 'student_evaluation': '%d/%d' % (project_logic.getQueryForFields({ 'project': entity }).count(), psc), } if lists.isDataRequest(request): return self.getManageOverviewData(request, mo_params, org_entity) mo_list = lists.getListGenerator(request, mo_params, idx=0) contents = [mo_list] # call the _list method from base to display the list return self._list(request, mo_params, contents, page_name) @decorators.merge_params @decorators.check_access def stEdit(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows students to edit information about their project. For params see base.View().public() """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse(error, request, template=params['error_public']) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name # cancel should go to the public view params['cancel_redirect'] = redirects.getPublicRedirect(entity, params) if request.POST: return self.stEditPost(request, context, params, entity, **kwargs) else: #request.GET return self.stEditGet(request, context, params, entity, **kwargs)
def __init__(self, params=None): """Defines the fields and methods required for the base View class to provide the user with list, public, create, edit and delete views. Params: params: a dict with params for this View """ rights = access.Checker(params) rights['edit'] = ['deny'] rights['show'] = [('checkIsMyEntity', [notification_logic, 'scope_path'])] rights['delete'] = [('checkIsMyEntity', [notification_logic, 'scope_path'])] rights['list'] = ['checkIsUser'] # create is developer only for the time being to test functionality rights['create'] = ['checkIsDeveloper'] new_params = {} new_params['logic'] = notification_logic new_params['rights'] = rights new_params['name'] = "Notification" new_params['no_create_with_key_fields'] = True new_params['create_form'] = CreateForm new_params['edit_redirect'] = '/%(url_name)s/list' new_params['public_configuration'] = {"multiselect": True} new_params['public_field_prefetch'] = ['from_user'] new_params['public_field_extra'] = lambda entity: { "from": entity.from_user.name if entity.from_user else site_logic.getSingleton().site_name, "unread": "Not Read" if entity.unread else "Read", } new_params['public_field_props'] = { "unread": { "stype": "select", "editoptions": { "value": ":All;^Read$:Read;^Not Read$:Not Read" } } } new_params['public_conf_extra'] = { "multiselect": True, } new_params['public_field_keys'] = [ "unread", "from", "subject", "created_on", ] new_params['public_field_names'] = [ "Unread", "From", "Subject", "Received on" ] new_params['public_button_global'] = [{ 'bounds': [1, 'all'], 'id': 'mark_read', 'caption': 'Mark as Read', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1, 'all'], 'id': 'mark_unread', 'caption': 'Mark as Unread', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1, 'all'], 'id': 'delete', 'caption': 'Delete Notification', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }] params = dicts.merge(params, new_params) params['public_row_extra'] = lambda entity: { "link": redirects.getPublicRedirect(entity, params) } super(View, self).__init__(params=params)
def __init__(self, params=None): """Defines the fields and methods required for the task_subscription. Params: params: a dict with params for this View """ rights = gci_access.GCIChecker(params) rights['subscribe'] = ['checkIsUser'] new_params = {} new_params['logic'] = soc.modules.gci.logic.models.task_subscription.logic new_params['rights'] = rights new_params['name'] = "Task Subscription" new_params['module_name'] = "task_subscription" new_params['module_package'] = 'soc.modules.gci.views.models' new_params['url_name'] = 'gci/task_subscription' patterns = [] patterns += [ (r'^%(url_name)s/(?P<access_type>subscribe)$', '%(module_package)s.%(module_name)s.subscribe', 'Subscribe to the %(name)s'), ] new_params['extra_django_patterns'] = patterns new_params['public_field_extra'] = lambda entity, all_d, all_t: { 'title': entity.task.title, 'org': entity.task.scope.name, 'points_difficulty': entity.task.taskDifficultyValue(all_d), 'task_type': entity.task.taskType(all_t), 'arbit_tag': entity.task.taskArbitTag(), 'time_to_complete': entity.task.time_to_complete, 'days_hours': entity.task.taskTimeToComplete(), 'status': entity.task.status, } # TODO(ljvderijk): With multi-level prefetch we should be able to fetch # the org as well. new_params['public_field_prefetch'] = ['task'] new_params['public_field_keys'] = [ 'title', 'org', 'points_difficulty', 'task_type', 'arbit_tag', 'time_to_complete', 'days_hours', 'status', ] new_params['public_field_names'] = [ 'Title', 'Organization', 'Points (Difficulty)', 'Type', 'Tags', 'Total Hours To Complete', 'Time To Complete', 'Status', ] new_params['public_field_props'] = { 'time_to_complete': { 'sorttype': 'integer', }, } new_params['public_row_action'] = { "type": "redirect_custom", "parameters": dict(new_window=True), } new_params['public_row_extra'] = \ lambda entity, *args: { 'link': redirects.getPublicRedirect( entity.task, {'url_name': 'gci/task'}) } params = dicts.merge(params, new_params, sub_merge=True) super(View, self).__init__(params=params)
def _getMapData(self, filter=None): """Constructs the JSON object required to generate Google Maps on organization home page. Args: filter: a dict for the properties that the entities should have Returns: A JSON object containing map data. """ from soc.logic.models.student_project import logic as student_project_logic from soc.views.models import student_project as student_project_view sp_params = student_project_view.view.getParams().copy() people = {} projects = {} # get all the student_project entities for the given filter student_project_entities = student_project_logic.getForFields( filter=filter) # Construct a dictionary of mentors and students. For each mentor construct # a list of 3-tuples containing student name, project title and url. # And for each student a list of 3 tuples containing mentor name, project # title and url. Only students and mentors who have agreed to publish their # locations will be in the dictionary. for entity in student_project_entities: project_key_name = entity.key().id_or_name() project_redirect = redirects.getPublicRedirect(entity, sp_params) student_entity = entity.student student_key_name = student_entity.key().id_or_name() mentor_entity = entity.mentor mentor_key_name = mentor_entity.key().id_or_name() # store the project data in the projects dictionary projects[project_key_name] = {'title': entity.title, 'redirect': project_redirect, 'student_key': student_key_name, 'student_name': student_entity.name(), 'mentor_key': mentor_key_name, 'mentor_name': mentor_entity.name()} if mentor_entity.publish_location: if mentor_key_name not in people: # we have not stored the information of this mentor yet people[mentor_key_name] = { 'type': 'mentor', 'name': mentor_entity.name(), 'lat': mentor_entity.latitude, 'long': mentor_entity.longitude, 'projects': [] } # add this project to the mentor's list people[mentor_key_name]['projects'].append(project_key_name) if student_entity.publish_location: if student_key_name not in people: # new student, store the name and location people[student_key_name] = { 'type': 'student', 'name': student_entity.name(), 'lat': student_entity.latitude, 'long': student_entity.longitude, 'projects': [], } # append the current project to the known student's list of projects people[student_key_name]['projects'].append(project_key_name) # combine the people and projects data into one JSON object data = {} # TODO: to enable map data uncomment the piece of code below #data = {'people': people, # 'projects': projects} return simplejson.dumps(data)
def _getMapData(self, student_project_params, filter=None): """Constructs the JSON object required to generate a Google map on organization home page. Args: student_project_params: params for student project view filter: a dict for the properties that the entities should have Returns: A JSON object containing map data with the following structure. [ { 'type': 'mentor', 'name': MentorName, 'city': CityName, 'ccTLD': ccTLD, 'students': [{'name': Name, 'city': CityName, 'ccTLD': ccTLD, 'summary': Summary, 'url': URL}, {'name': Name, 'city': CityName, 'ccTLD': ccTLD, 'summary': Summary, 'url': URL}, ] }, { 'type': 'none', 'name': MentorName, 'student': {'name': Name, 'city': CityName, 'ccTLD': ccTLD, 'summary': Summary, 'url': URL} } ] """ from soc.logic.models.student_project import logic as student_project_logic map_data = [] mentors = {} student_only = [] # get all the student_project entities for this organization student_project_entities = student_project_logic.getForFields(filter=filter) # construct a dictionary of mentors. For each mentor construct a # list of 3-tuple containing student, project title and url. This is # mainly done to track and pair all students and mentors who # have allowed to publish their locations. for entity in student_project_entities: if entity.mentor.publish_location and entity.mentor not in mentors: # if mentor has allowed to publish his location add it to the # mentors dictionary mentors[entity.mentor] = [] if entity.student.publish_location: # if student has allowed to publish his location, add it to the # corresponding mentor list, otherwise add it to the 'none' list if entity.mentor in mentors: mentors[entity.mentor].append( (entity.student, entity.title, redirects.getPublicRedirect(entity, student_project_params))) else: student_only.append( (entity.student, entity.title, redirects.getPublicRedirect(entity, student_project_params), entity.mentor)) # from the index built in the form of mentors dictionary we now build # the map_data for all the mentors who have allowed to publish their # location for mentor in mentors: mentor_map = { 'type': 'mentor', 'name': mentor.name(), 'city': mentor.res_city, 'ccTLD': mentor.ccTld(), 'students': [] } for student, summary, url in mentors[mentor]: student_map = { 'name': student.name(), 'city': student.res_city, 'ccTLD': student.ccTld(), 'summary': summary, 'url': url } mentor_map['students'].append(student_map) map_data.append(mentor_map) # construct the 'type': 'none' dictionary for those students, whose # mentors haven't allowed to publish location for student, summary, url, mentor in student_only: nomentor_map = { 'type': 'none', 'name': mentor.name(), 'student': { 'name': student.name(), 'city': student.res_city, 'ccTLD': student.ccTld(), 'summary': summary, 'url': url } } map_data.append(nomentor_map) return simplejson.dumps(map_data)
def _public(self, request, entity, context): """See base.View._public(). """ #TODO(LIST) from soc.modules.ghop.views.models import task as ghop_task_view contents = [] ghop_program_entity = entity.scope is_after_student_signup = timeline_helper.isAfterEvent( ghop_program_entity.timeline, 'student_signup_start') is_after_tasks_become_public = timeline_helper.isAfterEvent( ghop_program_entity.timeline, 'tasks_publicly_visible') if is_after_student_signup and is_after_tasks_become_public: # open tasks to_params = ghop_task_view.view.getParams().copy() # define the list redirect action to show the task public page to_params['public_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, to_params) } to_params['list_description'] = self.DEF_OPEN_PROJECTS_MSG_FMT % ( entity.name) to_params['list_heading'] = 'modules/ghop/task/list/heading.html' to_params['list_row'] = 'modules/ghop/task/list/row.html' filter = {'scope': entity, 'status': ['Open', 'Reopened']} to_list = lists.getListContent(request, to_params, filter, idx=0, need_content=True) if to_list: to_list['data'].sort(key=lambda task: task.modified_on) contents.append(to_list) # claimed tasks tc_params = to_params.copy() tc_params[ 'list_description'] = self.DEF_CLAIMED_PROJECTS_MSG_FMT % ( entity.name) filter = { 'scope': entity, 'status': [ 'ClaimRequested', 'Claimed', 'NeedsAction', 'NeedsReview', 'NeedsWork' ] } tc_list = lists.getListContent(request, tc_params, filter, idx=1, need_content=True) if tc_list: tc_list['data'].sort(key=lambda task: task.modified_on) contents.append(tc_list) # closed tasks tcs_params = to_params.copy() tcs_params[ 'list_description'] = self.DEF_CLOSED_PROJECTS_MSG_FMT % ( entity.name) filter = { 'scope': entity, 'status': ['AwaitingRegistration', 'Closed'] } tcs_list = lists.getListContent(request, tcs_params, filter, idx=2, need_content=True) if tcs_list: tcs_list['data'].sort(key=lambda task: task.modified_on) contents.append(tcs_list) # construct the list and put it into the context context['list'] = soc.logic.lists.Lists(contents) return super(View, self)._public(request=request, entity=entity, context=context)
def listTasks(self, request, access_type, page_name=None, params=None, **kwargs): """View where all the tasks can be searched from. """ from soc.modules.gci.views.models.task import view as task_view logic = params['logic'] program_entity = logic.getFromKeyFieldsOr404(kwargs) page_name = '%s %s' % (page_name, program_entity.name) list_params = task_view.getParams().copy() user_account = user_logic.getCurrentUser() user_fields = {'user': user_account, 'status': 'active'} host_entity = host_logic.getForFields(user_fields, unique=True) tasks_filter = { 'program': program_entity, 'status': ['Open', 'Reopened', 'ClaimRequested'] } if host_entity: list_params[ 'list_description'] = self.DEF_LIST_VALID_TASKS_MSG_FMT % ( program_entity.name) tasks_filter['status'].extend([ 'Claimed', 'ActionNeeded', 'Closed', 'AwaitingRegistration', 'NeedsWork', 'NeedsReview', 'Unapproved', 'Unpublished' ]) else: list_params.setdefault('public_field_ignore', []).append('mentors') list_params[ 'list_description'] = self.DEF_LIST_PUBLIC_TASKS_MSG_FMT % ( program_entity.name) list_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getPublicRedirect(entity, list_params) } list_params['public_conf_min_num'] = list_params[ 'public_conf_limit'] = 100 if lists.isDataRequest(request): return self.getListTasksData(request, list_params, tasks_filter) contents = [] order = ['-modified_on'] tasks_list = lists.getListGenerator(request, list_params, order=order, idx=0) contents.append(tasks_list) return self._list(request, list_params, contents, page_name)
For params see base.View().public() """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse( error, request, template=params['error_public']) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name # cancel should go to the public view params['cancel_redirect'] = redirects.getPublicRedirect(entity, params) if request.POST: return self.stEditPost(request, context, params, entity, **kwargs) else: #request.GET return self.stEditGet(request, context, params, entity, **kwargs) def stEditGet(self, request, context, params, entity, **kwargs): """Handles the GET request for the student's edit page. Args: entity: the student project entity rest: see base.View.public() """ # populate form with the existing entity
def __init__(self, params=None): """Defines the fields and methods required for the base View class to provide the user with list, public, create, edit and delete views. Params: params: a dict with params for this View """ rights = access.GSoCChecker(params) rights['any_access'] = ['allow'] rights['create'] = ['checkIsDeveloper'] rights['edit'] = ['checkIsDeveloper'] rights['delete'] = ['checkIsDeveloper'] rights['show'] = ['allow'] rights['list'] = ['checkIsDeveloper'] rights['manage'] = [('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkStudentProjectHasStatus', [['accepted', 'failed', 'completed', 'withdrawn']])] rights['manage_overview'] = [ ('checkHasAny', [ [('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkHasRoleForScope', [mentor_logic, ['active', 'inactive']]) ]])] # TODO: lack of better name here! rights['st_edit'] = [ 'checkCanEditStudentProjectAsStudent', ('checkStudentProjectHasStatus', [['accepted', 'completed']]) ] rights['overview'] = [('checkIsHostForProgram', [program_logic])] new_params = {} new_params['logic'] = project_logic new_params['rights'] = rights new_params['name'] = 'Student Project' new_params['url_name'] = 'gsoc/student_project' new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['sidebar_grouping'] = 'Students' new_params['scope_view'] = org_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_create_with_key_fields'] = True new_params['extra_dynaexclude'] = ['program', 'status', 'link_id', 'mentor', 'additional_mentors', 'student', 'passed_evaluations', 'failed_evaluations'] new_params['create_extra_dynaproperties'] = { 'scope_path': forms.CharField(widget=forms.HiddenInput, required=True), 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), 'student_id': forms.CharField(label='Student Link ID', required=True), 'mentor_id': forms.CharField(label='Mentor Link ID', required=True), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_student': cleaning.clean_link_id('student'), 'clean_mentor': cleaning.clean_link_id('mentor'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), 'clean': cleaning.validate_student_project('scope_path', 'mentor_id', 'student_id') } new_params['edit_extra_dynaproperties'] = { 'link_id': forms.CharField(widget=forms.HiddenInput), } patterns = [ (r'^%(url_name)s/(?P<access_type>manage_overview)/%(scope)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage_overview', 'Overview of %(name_plural)s to Manage for'), (r'^%(url_name)s/(?P<access_type>manage)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage', 'Manage %(name)s'), (r'^%(url_name)s/(?P<access_type>st_edit)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.st_edit', 'Edit my %(name)s'), (r'^%(url_name)s/(?P<access_type>overview)/(?P<scope_path>%(ulnp)s)/%(lnp)s$', 'soc.modules.gsoc.views.models.%(module_name)s.overview', 'Overview of all %(name_plural)s for'), ] new_params['extra_django_patterns'] = patterns new_params['edit_template'] = 'soc/student_project/edit.html' new_params['manage_template'] = 'soc/student_project/manage.html' new_params['public_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['public_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'org': entity.scope.name, } new_params['public_field_keys'] = ['student', 'title', 'mentor', 'org', 'status'] new_params['public_field_names'] = ['Student', 'Title', 'Mentor', 'Organization', 'Status'] new_params['org_home_field_prefetch'] = ['mentor', 'student'] new_params['org_home_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': ', '.join( mentor.name() for mentor in [entity.mentor] + db.get(entity.additional_mentors)) } new_params['org_home_field_keys'] = ['student', 'title', 'mentor', 'status'] new_params['org_home_field_names'] = ['Student', 'Title', 'Mentor', 'Status'] # define the list redirect action to show the notification new_params['public_row_extra'] = new_params[ 'org_home_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, new_params) } new_params['org_home_row_action'] = { 'type': 'redirect_custom', 'parameters': dict(new_window=False), } new_params['admin_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['admin_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'student_id': entity.student.link_id } new_params['admin_field_keys'] = ['student', 'title', 'mentor', 'status', 'student_id'] new_params['admin_field_names'] = ['Student', 'Title', 'Mentor', 'Status', 'Student Link ID'] new_params['admin_field_hidden'] = ['student_id'] new_params['admin_conf_extra'] = { 'multiselect': True, } new_params['admin_button_global'] = [ { 'bounds': [1,'all'], 'id': 'withdraw', 'caption': 'Withdraw Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1,'all'], 'id': 'accept', 'caption': 'Accept Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }] params = dicts.merge(params, new_params) super(View, self).__init__(params=params) # create the form that students will use to edit their projects dynaproperties = { 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), } student_edit_form = dynaform.newDynaForm( dynabase = self._params['dynabase'], dynamodel = self._params['logic'].getModel(), dynaexclude = self._params['create_dynaexclude'], dynaproperties = dynaproperties, ) self._params['student_edit_form'] = student_edit_form
def __init__(self, params=None): """Defines the fields and methods required for the base View class to provide the user with list, public, create, edit and delete views. Params: params: a dict with params for this View """ rights = access.GSoCChecker(params) rights['any_access'] = ['allow'] rights['create'] = ['checkIsDeveloper'] rights['edit'] = ['checkIsDeveloper'] rights['delete'] = ['checkIsDeveloper'] rights['show'] = ['allow'] rights['list'] = ['checkIsDeveloper'] rights['manage'] = [('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkStudentProjectHasStatus', [['accepted', 'failed', 'completed', 'withdrawn']])] rights['manage_overview'] = [('checkHasAny', [[ ('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkHasRoleForScope', [mentor_logic, ['active', 'inactive']]) ]])] # TODO: lack of better name here! rights['st_edit'] = [ 'checkCanEditStudentProjectAsStudent', ('checkStudentProjectHasStatus', [['accepted', 'completed']]) ] rights['overview'] = [('checkIsHostForProgram', [program_logic])] new_params = {} new_params['logic'] = project_logic new_params['rights'] = rights new_params['name'] = 'Student Project' new_params['url_name'] = 'gsoc/student_project' new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['sidebar_grouping'] = 'Students' new_params['scope_view'] = org_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_create_with_key_fields'] = True new_params['extra_dynaexclude'] = [ 'program', 'status', 'link_id', 'mentor', 'additional_mentors', 'student', 'passed_evaluations', 'failed_evaluations' ] new_params['create_extra_dynaproperties'] = { 'scope_path': forms.CharField(widget=forms.HiddenInput, required=True), 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'student_id': forms.CharField(label='Student Link ID', required=True), 'mentor_id': forms.CharField(label='Mentor Link ID', required=True), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_student': cleaning.clean_link_id('student'), 'clean_mentor': cleaning.clean_link_id('mentor'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), 'clean': cleaning.validate_student_project('scope_path', 'mentor_id', 'student_id') } new_params['edit_extra_dynaproperties'] = { 'link_id': forms.CharField(widget=forms.HiddenInput), } patterns = [ (r'^%(url_name)s/(?P<access_type>manage_overview)/%(scope)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage_overview', 'Overview of %(name_plural)s to Manage for'), (r'^%(url_name)s/(?P<access_type>manage)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage', 'Manage %(name)s'), (r'^%(url_name)s/(?P<access_type>st_edit)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.st_edit', 'Edit my %(name)s'), (r'^%(url_name)s/(?P<access_type>overview)/(?P<scope_path>%(ulnp)s)/%(lnp)s$', 'soc.modules.gsoc.views.models.%(module_name)s.overview', 'Overview of all %(name_plural)s for'), ] new_params['extra_django_patterns'] = patterns new_params['edit_template'] = 'soc/student_project/edit.html' new_params['manage_template'] = 'soc/student_project/manage.html' new_params['public_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['public_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'org': entity.scope.name, } new_params['public_field_keys'] = [ 'student', 'title', 'mentor', 'org', 'status' ] new_params['public_field_names'] = [ 'Student', 'Title', 'Mentor', 'Organization', 'Status' ] new_params['org_home_field_prefetch'] = ['mentor', 'student'] new_params['org_home_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': ', '.join(mentor.name() for mentor in [entity.mentor] + db.get( entity.additional_mentors)) } new_params['org_home_field_keys'] = [ 'student', 'title', 'mentor', 'status' ] new_params['org_home_field_names'] = [ 'Student', 'Title', 'Mentor', 'Status' ] # define the list redirect action to show the notification new_params['public_row_extra'] = new_params[ 'org_home_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, new_params) } new_params['org_home_row_action'] = { 'type': 'redirect_custom', 'parameters': dict(new_window=False), } new_params['admin_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['admin_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'student_id': entity.student.link_id } new_params['admin_field_keys'] = [ 'student', 'title', 'mentor', 'status', 'student_id' ] new_params['admin_field_names'] = [ 'Student', 'Title', 'Mentor', 'Status', 'Student Link ID' ] new_params['admin_field_hidden'] = ['student_id'] new_params['admin_conf_extra'] = { 'multiselect': True, } new_params['admin_button_global'] = [{ 'bounds': [1, 'all'], 'id': 'withdraw', 'caption': 'Withdraw Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1, 'all'], 'id': 'accept', 'caption': 'Accept Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }] params = dicts.merge(params, new_params) super(View, self).__init__(params=params) # create the form that students will use to edit their projects dynaproperties = { 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), } student_edit_form = dynaform.newDynaForm( dynabase=self._params['dynabase'], dynamodel=self._params['logic'].getModel(), dynaexclude=self._params['create_dynaexclude'], dynaproperties=dynaproperties, ) self._params['student_edit_form'] = student_edit_form
def manageOverview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to see an overview of their Organization's Student Projects. For params see base.View().public() """ from soc.modules.gsoc.logic.models.survey import grading_logic as \ grading_survey_logic from soc.modules.gsoc.logic.models.survey import project_logic as \ project_survey_logic from soc.modules.gsoc.logic.models.survey_record import grading_logic from soc.modules.gsoc.logic.models.survey_record import project_logic # make sure the organization exists org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path']) page_name = '%s %s' % (page_name, org_entity.name) mo_params = params.copy() #list all active projects mo_params['list_description'] = ugettext( 'List of all %s for %s, if you are an Org Admin you can click ' 'a project for more actions. Such as reassigning mentors or viewing ' 'results of the evaluations.' % (params['name_plural'], org_entity.name)) mo_params['public_field_names'] = params['public_field_names'] + [ 'Mentor evaluation', 'Student Evaluation' ] mo_params['public_field_keys'] = params['public_field_keys'] + [ 'mentor_evaluation', 'student_evaluation' ] fields = {'scope': org_entity, 'status': ['active', 'inactive']} org_admin = org_admin_logic.getForFields(fields, unique=True) # Org Admins get a link to manage the project, others go to public page if org_admin: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getManageRedirect(entity, mo_params) } else: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getPublicRedirect(entity, mo_params) } mo_params['public_field_prefetch'] = ['student', 'mentor', 'scope'] mo_params['public_field_extra'] = lambda entity, ps, psc, gs, gsc: { 'org': entity.scope.name, 'student': '%s (%s)' % (entity.student.name(), entity.student.email), 'mentor': entity.mentor.name(), 'mentor_evaluation': '%d/%d' % (grading_logic.getQueryForFields({ 'project': entity }).count(), gsc), 'student_evaluation': '%d/%d' % (project_logic.getQueryForFields({ 'project': entity }).count(), psc), } if lists.isDataRequest(request): return self.getManageOverviewData(request, mo_params, org_entity) mo_list = lists.getListGenerator(request, mo_params, idx=0) contents = [mo_list] # call the _list method from base to display the list return self._list(request, mo_params, contents, page_name)
def createNotificationMail(request, *args, **kwargs): """Appengine task that sends mail to the subscribed users. Expects the following to be present in the POST dict: comment_key: Specifies the comment id for which to send the notifications task_key: Specifies the task key name for which the comment belongs to Args: request: Django Request object """ from soc.modules.gci.logic.helper import notifications as gci_notifications from soc.modules.gci.logic.models import comment as gci_comment_logic from soc.modules.gci.logic.models import task_subscription as \ gci_task_subscription_logic # set default batch size batch_size = 10 post_dict = request.POST comment_key = post_dict.get('comment_key') task_key = post_dict.get('task_key') if not (comment_key and task_key): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid createNotificationMail data: %s' % post_dict) comment_key = long(comment_key) # get the task entity under which the specified comment was made task_entity = gci_task_logic.logic.getFromKeyName(task_key) # get the comment for the given id comment_entity = gci_comment_logic.logic.getFromID( comment_key, task_entity) if not comment_entity: # invalid comment specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid comment specified: %s/%s' % (comment_key, task_key)) # check and retrieve the subscriber_start_key that has been done last idx = post_dict.get('subscriber_start_index', '') subscriber_start_index = int(idx) if idx.isdigit() else 0 # get all subscribers to GCI task fields = { 'task': task_entity, } ts_entity = gci_task_subscription_logic.logic.getForFields( fields, unique=True) subscribers = db.get(ts_entity.subscribers[ subscriber_start_index:subscriber_start_index+batch_size]) task_url = "http://%(host)s%(task)s" % { 'host': system.getHostname(), 'task': redirects.getPublicRedirect( task_entity, {'url_name': 'gci/task'}), } # create the data for the mail to be sent message_properties = { 'task_url': task_url, 'redirect_url': "%(task_url)s#c%(cid)d" % { 'task_url': task_url, 'cid': comment_entity.key().id_or_name() }, 'comment_entity': comment_entity, 'task_entity': task_entity, } subject = DEF_TASK_UPDATE_SUBJECT_FMT % { 'program_name': task_entity.program.short_name, 'title': task_entity.title, } for subscriber in subscribers: gci_notifications.sendTaskUpdateMail(subscriber, subject, message_properties) if len(subscribers) == batch_size: # spawn task for sending out notifications to next set of subscribers next_start = subscriber_start_index + batch_size task_params = { 'comment_key': comment_key, 'task_key': task_key, 'subscriber_start_index': next_start } task_url = '/tasks/gci/task/mail/create' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add('mail') # return OK return http.HttpResponse()
def _getMapData(self, filter=None): """Constructs the JSON object required to generate Google Maps on organization home page. Args: filter: a dict for the properties that the entities should have Returns: A JSON object containing map data. """ from soc.modules.gsoc.logic.models.student_project import logic as \ student_project_logic from soc.modules.gsoc.views.models import student_project as \ student_project_view sp_params = student_project_view.view.getParams().copy() people = {} projects = {} # get all the student_project entities for the given filter student_project_entities = student_project_logic.getForFields( filter=filter) # Construct a dictionary of mentors and students. For each mentor construct # a list of 3-tuples containing student name, project title and url. # And for each student a list of 3 tuples containing mentor name, project # title and url. Only students and mentors who have agreed to publish their # locations will be in the dictionary. for entity in student_project_entities: project_key_name = entity.key().id_or_name() project_redirect = redirects.getPublicRedirect(entity, sp_params) student_entity = entity.student student_key_name = student_entity.key().id_or_name() mentor_entity = entity.mentor mentor_key_name = mentor_entity.key().id_or_name() # store the project data in the projects dictionary projects[project_key_name] = { 'title': entity.title, 'redirect': project_redirect, 'student_key': student_key_name, 'student_name': student_entity.name(), 'mentor_key': mentor_key_name, 'mentor_name': mentor_entity.name() } if mentor_entity.publish_location: if mentor_key_name not in people: # we have not stored the information of this mentor yet people[mentor_key_name] = { 'type': 'mentor', 'name': mentor_entity.name(), 'lat': mentor_entity.latitude, 'lon': mentor_entity.longitude, 'projects': [] } # add this project to the mentor's list people[mentor_key_name]['projects'].append(project_key_name) if student_entity.publish_location: if student_key_name not in people: # new student, store the name and location people[student_key_name] = { 'type': 'student', 'name': student_entity.name(), 'lat': student_entity.latitude, 'lon': student_entity.longitude, 'projects': [], } # append the current project to the known student's list of projects people[student_key_name]['projects'].append(project_key_name) # combine the people and projects data into one JSON object data = {'people': people, 'projects': projects} return simplejson.dumps(data)
def insertFields(self): """Add the necessary fields to the Form. """ # add common survey fields fields = super(OrgAppSurveyForm, self).insertFields() name = forms.fields.CharField(label='Organization Name', required=True, initial=self.data.get('name')) description = forms.fields.CharField( label='Description', required=True, widget=forms.widgets.Textarea, initial=self.data.get('description')) home_page = forms.fields.URLField(label='Home page', required=True, initial=self.data.get('home_page')) license_field = forms.fields.ChoiceField( choices=[(license, license) for license in licenses.LICENSES], label='Main Organization License', required=True, initial=self.data.get('license')) backup_admin = forms.fields.CharField( label='Backup Admin (Link ID)', required=True, initial=self.data.get('backup_admin')) tos_field = forms.fields.CharField(label='Admin Agreement', required=False, widget=widgets.AgreementField) # set the contents to the current ToS for Org Admins admin_agreement = self.survey.scope.org_admin_agreement if admin_agreement: tos_field.widget.text = admin_agreement.content params = {'url_name': 'document'} tos_field.widget.url = redirects.getPublicRedirect( admin_agreement, params) agreed_to_tos = forms.fields.BooleanField( label='I agree to the Admin Agreement', required=True, initial=self.data.get('agreed_to_tos')) # add fields to the top of the form fields.insert(0, 'name', name) fields.insert(1, 'description', description) fields.insert(2, 'home_page', home_page) fields.insert(3, 'license', license_field) # add fields to the bottom of the form fields['backup_admin'] = backup_admin fields['tos'] = tos_field fields['agreed_to_tos'] = agreed_to_tos return fields