def post(self): """Save references to reports, and perhaps the report file itself. Has two modes: accept a file, in which case the file is saved to GCS, or a dataset id. In both cases a Report is inserted referencing the file/dataset. Either `team_id` or `classroom_id` must be provided. If team_id, then the report's classroom_id is empty (these are "team-level" reports). If classroom_id, the corresponding team_id is looked up (these are "classroom-level" reports). """ # Allow RServe to call this endpoint, then fall back on regular auth. user, error = self.authenticate_rserve() if not user: user = self.get_current_user() error = '' # Replaces function of `requires_auth = True`. if user.user_type == 'public': return self.http_unauthorized() if not user.super_admin: return self.http_forbidden() org_id = self.get_param('organization_id', str, None) team_id = self.get_param('team_id', str, None) classroom_id = self.get_param('classroom_id', str, None) params = self.get_params({ 'dataset_id': str, 'filename': unicode, 'issue_date': str, 'notes': unicode, 'preview': bool, 'template': str, }) # Lookup related objects. classroom = None if classroom_id: classroom = Classroom.get_by_id(classroom_id) if not classroom: return self.http_bad_request( "Classroom not found: {}".format(classroom_id)) team_id = classroom.team_id team = None if team_id: # May be set for team reports, or via lookup for class reports. team = Team.get_by_id(team_id) if not team: return self.http_bad_request( "Team not found: {}".format(team_id)) org = None if org_id: org = Organization.get_by_id(org_id) if not org: return self.http_bad_request( "Organization not found: {}".format(org_id)) content_type = self.request.headers['Content-Type'] is_form = 'multipart/form-data' in content_type is_json = 'application/json' in content_type if is_form: report = self.save_file( params['filename'], self.request.POST['file'], org_id, team_id, classroom_id, ) elif is_json: kwargs = { 'classroom_id': classroom_id, 'dataset_id': params['dataset_id'], 'filename': params['filename'], 'issue_date': params.get('issue_date', None), 'notes': params.get('notes', None), 'organization_id': org_id, 'team_id': team_id, 'template': params['template'], } # Some params we may want to avoid including at all, so that if # they're absent they'll take the default value defined in the db. if params.get('preview', None) is not None: kwargs['preview'] = params['preview'] report = Report.create(**kwargs) else: return self.http_bad_request( "Only supported content types are 1) multipart/form-data for " "uploading files and 2) application/json for datasets. Got {}". format(self.request.headers['Content-Type'])) saved_report = Report.put_for_index(report, 'parent-file') self.write(saved_report)