Ejemplo n.º 1
0
    def render_leaderboard_complete(self, student_item_dict):
        """
        Render the leaderboard complete state.

        Args:
            student_item_dict (dict): The student item

        Returns:
            template_path (string), tuple of context (dict)
        """

        # Retrieve top scores from the submissions API
        # Since this uses the read-replica and caches the results,
        # there will be some delay in the request latency.
        scores = sub_api.get_top_submissions(student_item_dict['course_id'],
                                             student_item_dict['item_id'],
                                             student_item_dict['item_type'],
                                             self.leaderboard_show)
        for score in scores:
            score['files'] = []
            if 'file_keys' in score['content']:
                for key in score['content']['file_keys']:
                    url = ''
                    try:
                        url = file_upload_api.get_download_url(key)
                    except FileUploadError:
                        pass
                    if url:
                        score['files'].append(url)
            elif 'file_key' in score['content']:
                score['files'].append(
                    file_upload_api.get_download_url(
                        score['content']['file_key']))
            if 'text' in score['content'] or 'parts' in score['content']:
                submission = {'answer': score.pop('content')}
                score['submission'] = create_submission_dict(
                    submission, self.prompts)
            elif isinstance(score['content'], basestring):
                pass
            # Currently, we do not handle non-text submissions.
            else:
                score['submission'] = ""

            score.pop('content', None)

        context = {
            'topscores': scores,
            'allow_latex': self.allow_latex,
            'file_upload_type': self.file_upload_type,
            'xblock_id': self.get_xblock_id()
        }

        return 'openassessmentblock/leaderboard/oa_leaderboard_show.html', context
Ejemplo n.º 2
0
    def test_non_text_submission(self, xblock):
        # Create a mock bucket
        conn = boto.connect_s3()
        conn.create_bucket('mybucket')
        # Create a non-text submission (the submission dict doesn't contain 'text')
        api.get_download_url('s3key')
        self._create_submissions_and_scores(xblock, [('s3key', 1)], submission_key='file_key')

        # Expect that we default to an empty string for content
        self._assert_scores(xblock, [
            {'score': 1, 'files': [], 'submission': ''}
        ])
Ejemplo n.º 3
0
    def test_image_and_text_submission_multiple_files(self, xblock):
        """
        Tests that leaderboard works as expected when multiple files are uploaded
        """
        file_keys = ['foo', 'bar']
        file_descriptions = ['{}-description'.format(file_key) for file_key in file_keys]
        file_names = ['{}-file_name'.format(file_key) for file_key in file_keys]
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        for file_key in file_keys:
            key = Key(bucket, 'submissions_attachments/{}'.format(file_key))
            key.set_contents_from_string("How d'ya do?")
            files_url_and_description = [
                (api.get_download_url(file_key), file_descriptions[idx], file_names[idx], False)
                for idx, file_key in enumerate(file_keys)
            ]

        # Create a image and text submission
        submission = prepare_submission_for_serialization(('test answer 1 part 1', 'test answer 1 part 2'))
        submission[u'file_keys'] = file_keys
        submission[u'files_descriptions'] = file_descriptions
        submission[u'files_name'] = file_names
        self._create_submissions_and_scores(xblock, [
            (submission, 1)
        ])
        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [
            {'score': 1, 'files': files_url_and_description, 'submission': create_submission_dict(
                {'answer': submission},
                xblock.prompts
            )}
        ])
Ejemplo n.º 4
0
    def test_remove_all_uploaded_files(self, xblock):
        """ Test remove all user files """
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket)
        key.key = "submissions_attachments/test_student/test_course/" + xblock.scope_ids.usage_id
        key.set_contents_from_string("How d'ya do?")

        xblock.xmodule_runtime = Mock(
            course_id='test_course',
            anonymous_student_id='test_student',
        )

        download_url = api.get_download_url("test_student/test_course/" + xblock.scope_ids.usage_id)
        resp = self.request(xblock, 'download_url', json.dumps(dict()), response_format='json')
        self.assertTrue(resp['success'])
        self.assertEqual(download_url, resp['url'])

        resp = self.request(xblock, 'remove_all_uploaded_files', json.dumps(dict()), response_format='json')
        self.assertTrue(resp['success'])
        self.assertEqual(resp['removed_num'], 1)

        resp = self.request(xblock, 'download_url', json.dumps(dict()), response_format='json')
        self.assertTrue(resp['success'])
        self.assertEqual(u'', resp['url'])
Ejemplo n.º 5
0
    def _download_file_by_key(cls, key):
        download_url = urljoin(settings.LMS_ROOT_URL, get_download_url(key))

        response = requests.get(download_url)
        response.raise_for_status()

        return response.content
Ejemplo n.º 6
0
    def test_image_and_text_submission_multiple_files(self, xblock):
        """
        Tests that leaderboard works as expected when multiple files are uploaded
        """
        file_keys = ['foo', 'bar']
        file_descriptions = ['{}-description'.format(file_key) for file_key in file_keys]

        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        for file_key in file_keys:
            key = Key(bucket, 'submissions_attachments/{}'.format(file_key))
            key.set_contents_from_string("How d'ya do?")
            files_url_and_description = [
                (api.get_download_url(file_key), file_descriptions[idx])
                for idx, file_key in enumerate(file_keys)
                ]

        # Create a image and text submission
        submission = prepare_submission_for_serialization(('test answer 1 part 1', 'test answer 1 part 2'))
        submission[u'file_keys'] = file_keys
        submission[u'files_descriptions'] = file_descriptions

        self._create_submissions_and_scores(xblock, [
            (submission, 1)
        ])

        self.maxDiff = None
        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [
            {'score': 1, 'files': files_url_and_description, 'submission': create_submission_dict(
                {'answer': submission},
                xblock.prompts
            )}
        ])
    def test_image_and_text_submission(self, xblock):
        """
        Tests that text and image submission works as expected
        """
        # Create a file and get the download URL
        conn = boto3.client("s3")
        conn.create_bucket(Bucket='mybucket')
        conn.put_object(
            Bucket="mybucket",
            Key="submissions_attachments/foo",
            Body=b"How d'ya do?",
        )

        file_download_url = [{
            'download_url': api.get_download_url('foo'),
            'description': '',
            'name': '',
            'show_delete_button': False
        }]
        # Create a image and text submission
        submission = prepare_submission_for_serialization(
            ('test answer 1 part 1', 'test answer 1 part 2'))
        submission[u'file_key'] = 'foo'
        self._create_submissions_and_scores(xblock, [(submission, 1)])
        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [{
            'score':
            1,
            'files':
            file_download_url,
            'submission':
            create_submission_dict({'answer': submission}, xblock.prompts)
        }])
Ejemplo n.º 8
0
    def test_image_and_text_submission(self, xblock):
        """
        Tests that text and image submission works as expected
        """
        # Create a file and get the download URL
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket, 'submissions_attachments/foo')
        key.set_contents_from_string("How d'ya do?")

        file_download_url = [(api.get_download_url('foo'), '')]
        # Create a image and text submission
        submission = prepare_submission_for_serialization(
            ('test answer 1 part 1', 'test answer 1 part 2'))
        submission[u'file_key'] = 'foo'
        self._create_submissions_and_scores(xblock, [(submission, 1)])
        self.maxDiff = None
        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [{
            'score':
            1,
            'files':
            file_download_url,
            'submission':
            create_submission_dict({'answer': submission}, xblock.prompts)
        }])
Ejemplo n.º 9
0
    def render_leaderboard_complete(self, student_item_dict):
        """
        Render the leaderboard complete state.

        Args:
            student_item_dict (dict): The student item

        Returns:
            template_path (string), tuple of context (dict)
        """

        # Retrieve top scores from the submissions API
        # Since this uses the read-replica and caches the results,
        # there will be some delay in the request latency.
        scores = sub_api.get_top_submissions(student_item_dict['course_id'],
                                             student_item_dict['item_id'],
                                             student_item_dict['item_type'],
                                             self.leaderboard_show)
        for score in scores:
            if 'file_key' in score['content']:
                score['file'] = file_upload_api.get_download_url(
                    score['content']['file_key'])
            if 'text' in score['content']:
                score['content'] = score['content']['text']
            elif isinstance(score['content'], basestring):
                pass
            # Currently, we do not handle non-text submissions.
            else:
                score['content'] = ""

        context = {'topscores': scores}
        return ('openassessmentblock/leaderboard/oa_leaderboard_show.html',
                context)
Ejemplo n.º 10
0
    def render_leaderboard_complete(self, student_item_dict):
        """
        Render the leaderboard complete state.

        Args:
            student_item_dict (dict): The student item

        Returns:
            template_path (string), tuple of context (dict)
        """

        # Retrieve top scores from the submissions API
        # Since this uses the read-replica and caches the results,
        # there will be some delay in the request latency.
        scores = sub_api.get_top_submissions(
            student_item_dict['course_id'],
            student_item_dict['item_id'],
            student_item_dict['item_type'],
            self.leaderboard_show
        )
        for score in scores:
            if 'file_key' in score['content']:
                score['file'] = file_upload_api.get_download_url(score['content']['file_key'])
            if 'text' in score['content']:
                score['content'] = score['content']['text']
            elif isinstance(score['content'], basestring):
                pass
            # Currently, we do not handle non-text submissions.
            else:
                score['content'] = ""

        context = { 'topscores': scores,
                    'allow_latex': self.allow_latex,
                  }
        return ('openassessmentblock/leaderboard/oa_leaderboard_show.html', context)
Ejemplo n.º 11
0
    def test_image_and_text_submission(self, xblock):
        """
        Tests that text and image submission works as expected
        """
        # Create a file and get the download URL
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket, 'submissions_attachments/foo')
        key.set_contents_from_string("How d'ya do?")

        file_download_url = [(api.get_download_url('foo'), '')]
        # Create a image and text submission
        submission = prepare_submission_for_serialization(('test answer 1 part 1', 'test answer 1 part 2'))
        submission[u'file_key'] = 'foo'
        self._create_submissions_and_scores(xblock, [
            (submission, 1)
        ])
        self.maxDiff = None
        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [
            {'score': 1, 'files': file_download_url, 'submission': create_submission_dict(
                {'answer': submission},
                xblock.prompts
            )}
        ])
Ejemplo n.º 12
0
    def test_remove_all_uploaded_files(self, xblock):
        """ Test remove all user files """
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket)
        key.key = "submissions_attachments/test_student/test_course/" + xblock.scope_ids.usage_id
        key.set_contents_from_string("How d'ya do?")

        xblock.xmodule_runtime = Mock(
            course_id='test_course',
            anonymous_student_id='test_student',
        )
        download_url = api.get_download_url("test_student/test_course/" +
                                            xblock.scope_ids.usage_id)
        resp = self.request(xblock,
                            'download_url',
                            json.dumps(dict()),
                            response_format='json')
        self.assertTrue(resp['success'])
        self.assertTrue(resp['url'].startswith(download_url))

        resp = self.request(xblock,
                            'remove_all_uploaded_files',
                            json.dumps(dict()),
                            response_format='json')
        self.assertTrue(resp['success'])
        self.assertEqual(resp['removed_num'], 1)

        resp = self.request(xblock,
                            'download_url',
                            json.dumps(dict()),
                            response_format='json')
        self.assertTrue(resp['success'])
        self.assertEqual(u'', resp['url'])
Ejemplo n.º 13
0
 def test_get_download_url(self):
     conn = boto.connect_s3()
     bucket = conn.create_bucket('mybucket')
     key = Key(bucket)
     key.key = "submissions_attachments/foo"
     key.set_contents_from_string("How d'ya do?")
     downloadUrl = api.get_download_url("foo")
     self.assertIn("https://mybucket.s3.amazonaws.com/submissions_attachments/foo", downloadUrl)
Ejemplo n.º 14
0
 def test_get_download_url(self):
     conn = boto3.client("s3")
     conn.create_bucket(Bucket="mybucket")
     conn.put_object(Bucket="mybucket",
                     Key="submissions_attachments/foo",
                     Body=b"How d'ya do?")
     downloadUrl = api.get_download_url("foo")
     self.assertIn("/submissions_attachments/foo", downloadUrl)
Ejemplo n.º 15
0
 def test_get_download_url(self):
     conn = boto.connect_s3()
     bucket = conn.create_bucket('mybucket')
     key = Key(bucket)
     key.key = "submissions_attachments/foo"
     key.set_contents_from_string("How d'ya do?")
     downloadUrl = api.get_download_url("foo")
     self.assertIn("/submissions_attachments/foo", downloadUrl)
Ejemplo n.º 16
0
    def create_submission(self,
                          student_item_dict,
                          student_sub_data,
                          files_descriptions=None):
        # Import is placed here to avoid model import at project startup.
        from submissions import api

        # Store the student's response text in a JSON-encodable dict
        # so that later we can add additional response fields.
        files_descriptions = files_descriptions if files_descriptions else []
        student_sub_dict = prepare_submission_for_serialization(
            student_sub_data)

        if self.file_upload_type:
            student_sub_dict['file_keys'] = []
            student_sub_dict['files_descriptions'] = []
            for i in range(self.MAX_FILES_COUNT):
                key_to_save = ''
                file_description = ''
                item_key = self._get_student_item_key(i)
                try:
                    url = file_upload_api.get_download_url(item_key)
                    if url:
                        key_to_save = item_key
                        try:
                            file_description = files_descriptions[i]
                        except IndexError:
                            pass
                except FileUploadError:
                    logger.exception(
                        u"FileUploadError for student_item: {student_item_dict}"
                        u" and submission data: {student_sub_data} with file"
                        "descriptions {files_descriptions}".format(
                            student_item_dict=student_item_dict,
                            student_sub_data=student_sub_data,
                            files_descriptions=files_descriptions))
                if key_to_save:
                    student_sub_dict['file_keys'].append(key_to_save)
                    student_sub_dict['files_descriptions'].append(
                        file_description)
                else:
                    break

        submission = api.create_submission(student_item_dict, student_sub_dict)
        self.create_workflow(submission["uuid"])
        self.submission_uuid = submission["uuid"]

        # Emit analytics event...
        self.runtime.publish(
            self, "openassessmentblock.create_submission", {
                "submission_uuid": submission["uuid"],
                "attempt_number": submission["attempt_number"],
                "created_at": submission["created_at"],
                "submitted_at": submission["submitted_at"],
                "answer": submission["answer"],
            })

        return submission
Ejemplo n.º 17
0
    def _get_download_url(self):
        """
        Internal function for retrieving the download url.

        """
        try:
            return file_upload_api.get_download_url(self._get_student_item_key())
        except FileUploadError:
            logger.exception("Error retrieving download URL.")
            return ''
Ejemplo n.º 18
0
    def _get_url_by_file_key(self, key):
        """
        Return download url for some particular file key.

        """
        url = ''
        try:
            if key:
                url = file_upload_api.get_download_url(key)
        except FileUploadError:
            logger.exception("Unable to generate download url for file key {}".format(key))
        return url
    def _get_url_by_file_key(self, key):
        """
        Return download url for some particular file key.

        """
        url = ''
        try:
            if key:
                url = file_upload_api.get_download_url(key)
        except FileUploadError:
            logger.exception("Unable to generate download url for file key {}".format(key))
        return url
Ejemplo n.º 20
0
    def test_non_text_submission(self, xblock):
        # Create a mock bucket
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        # Create a non-text submission (the submission dict doesn't contain 'text')
        file_download_url = api.get_download_url('s3key')
        self._create_submissions_and_scores(xblock, [('s3key', 1)], submission_key='file_key')

        # Expect that we default to an empty string for content
        self._assert_scores(xblock, [
            {'score': 1, 'files': [], 'submission': ''}
        ])
Ejemplo n.º 21
0
    def _get_download_url(self, file_num=0):
        """
        Internal function for retrieving the download url.

        """
        try:
            return file_upload_api.get_download_url(
                self._get_student_item_key(file_num))
        except FileUploadError as exc:
            logger.exception(
                u"FileUploadError: Download URL retrieval for filenum {num} failed with {error}"
                .format(error=exc, num=file_num))
            return ''
Ejemplo n.º 22
0
    def create_submission(self, student_item_dict, student_sub_data, files_descriptions=None):
        # Import is placed here to avoid model import at project startup.
        from submissions import api

        # Store the student's response text in a JSON-encodable dict
        # so that later we can add additional response fields.
        files_descriptions = files_descriptions if files_descriptions else []
        student_sub_dict = prepare_submission_for_serialization(student_sub_data)

        if self.file_upload_type:
            student_sub_dict['file_keys'] = []
            student_sub_dict['files_descriptions'] = []
            for i in range(self.MAX_FILES_COUNT):
                key_to_save = ''
                file_description = ''
                item_key = self._get_student_item_key(i)
                try:
                    url = file_upload_api.get_download_url(item_key)
                    if url:
                        key_to_save = item_key
                        try:
                            file_description = files_descriptions[i]
                        except IndexError:
                            pass
                except FileUploadError:
                    pass
                if key_to_save:
                    student_sub_dict['file_keys'].append(key_to_save)
                    student_sub_dict['files_descriptions'].append(file_description)
                else:
                    break

        submission = api.create_submission(student_item_dict, student_sub_dict)
        self.create_workflow(submission["uuid"])
        self.submission_uuid = submission["uuid"]

        # Emit analytics event...
        self.runtime.publish(
            self,
            "openassessmentblock.create_submission",
            {
                "submission_uuid": submission["uuid"],
                "attempt_number": submission["attempt_number"],
                "created_at": submission["created_at"],
                "submitted_at": submission["submitted_at"],
                "answer": submission["answer"],
            }
        )

        return submission
Ejemplo n.º 23
0
    def _get_url_by_file_key(self, key):
        """
        Return download url for some particular file key.

        """
        url = ''
        try:
            if key:
                url = file_upload_api.get_download_url(key)
        except FileUploadError as exc:
            logger.exception(
                u"FileUploadError: Download url for file key {key} failed with error {error}"
                .format(key=key, error=exc))
        return url
Ejemplo n.º 24
0
    def test_image_and_text_submission(self, xblock):
        # Create a file and get the download URL
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket)
        key.key = "submissions_attachments/foo"
        key.set_contents_from_string("How d'ya do?")
        downloadUrl = api.get_download_url("foo")
        # Create a image and text submission
        self._create_submissions_and_scores(xblock, [({"text": "test answer", "file_key": "foo"}, 1)], submission_key=None)

        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [
            {"content": "test answer", "score": 1, "file": downloadUrl}
        ])
Ejemplo n.º 25
0
    def _get_file_download_url(self, file_key):
        """
        Internal function for retrieving the download url at which the file that corresponds
        to the file_key can be downloaded.

        Arguments:
            file_key (string): Corresponding file key.
        Returns:
            file_download_url (string) or empty string in case of error.
        """
        try:
            file_download_url = file_upload_api.get_download_url(file_key)
        except FileUploadError:
            file_download_url = ''
        return file_download_url
Ejemplo n.º 26
0
    def _get_file_download_url(self, file_key):
        """
        Internal function for retrieving the download url at which the file that corresponds
        to the file_key can be downloaded.

        Arguments:
            file_key (string): Corresponding file key.
        Returns:
            file_download_url (string) or empty string in case of error.
        """
        try:
            file_download_url = file_upload_api.get_download_url(file_key)
        except FileUploadError:
            file_download_url = ''
        return file_download_url
Ejemplo n.º 27
0
    def test_image_and_text_submission_multiple_files(self, xblock):
        """
        Tests that leaderboard works as expected when multiple files are uploaded
        """
        file_keys = ['foo', 'bar']
        file_descriptions = [
            '{}-description'.format(file_key) for file_key in file_keys
        ]
        files_names = [
            '{}-file_name'.format(file_key) for file_key in file_keys
        ]
        conn = boto3.client("s3")
        conn.create_bucket(Bucket="mybucket")
        for file_key in file_keys:
            conn.put_object(
                Bucket="mybucket",
                Key="submissions_attachments/{}".format(file_key),
                Body=b"How d'ya do?",
            )
            files_url_and_description = [{
                'download_url':
                api.get_download_url(file_key),
                'description':
                file_descriptions[idx],
                'name':
                files_names[idx],
                'show_delete_button':
                False
            } for idx, file_key in enumerate(file_keys)]

        # Create a image and text submission
        submission = prepare_submission_for_serialization(
            ('test answer 1 part 1', 'test answer 1 part 2'))
        submission['file_keys'] = file_keys
        submission['files_descriptions'] = file_descriptions
        submission['files_names'] = files_names
        submission['files_sizes'] = []
        self._create_submissions_and_scores(xblock, [(submission, 1)])
        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [{
            'score':
            1,
            'files':
            files_url_and_description,
            'submission':
            create_submission_dict({'answer': submission}, xblock.prompts)
        }])
Ejemplo n.º 28
0
    def _get_url_by_file_key(cls, key):
        """
        Return download url for some particular file key.

        """
        url = ''
        try:
            if key:
                url = file_upload_api.get_download_url(key)
        except FileUploadError as exc:
            logger.exception(
                "FileUploadError: Download url for file key %s failed with error %s",
                key,
                exc,
                exc_info=True)

        return url
Ejemplo n.º 29
0
    def get_all_upload_urls_for_user(self, username_or_email):
        """
        For a particular ORA block, get the download URLs for all the files uploaded and still present.

        Used for an extreme edge case, where the stored files indices are out of sync with
        the uploaded files, this is a last resort to get the download URLs of all the files
        that have been uploaded by a learner in an ORA block(and haven't been deleted from the storage).
        Starting from 0 index to maximum file upload count possible, this checks if a file exists against
        every index. If present, add the info, else repeat it for the next indices.

        Arguments:
            username_or_email(str): username or email of the learner whose files' information is to be obtained.
        Returns:
            List of 3-valued tuples, with first value being file URL and other two values as empty string.
            The other 2 values have to be appended to work properly in the template.
        """
        file_uploads = []
        student_item_dict = self.get_student_item_dict_from_username_or_email(username_or_email)
        for index in range(self.MAX_FILES_COUNT):
            file_key = file_upload_api.get_student_file_key(student_item_dict, index)
            download_url = ''
            try:
                download_url = file_upload_api.get_download_url(file_key)
            except FileUploadError:
                pass

            if download_url:
                logger.info(
                    "Download URL exists for key %s in block %s for user %s",
                    file_key,
                    username_or_email,
                    str(self.location)
                )
                file_uploads.append(
                    file_upload_api.FileDescriptor(
                        download_url=download_url,
                        description='',
                        name='',
                        show_delete_button=False
                    )._asdict()
                )
            else:
                continue

        return file_uploads
Ejemplo n.º 30
0
    def test_download_url(self, xblock):
        """ Test generate correct download URL with existing file. should create a file and get the download URL """
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket)
        key.key = "submissions_attachments/test_student/test_course/" + xblock.scope_ids.usage_id
        key.set_contents_from_string("How d'ya do?")
        download_url = api.get_download_url("test_student/test_course/" + xblock.scope_ids.usage_id)

        xblock.xmodule_runtime = Mock(
            course_id='test_course',
            anonymous_student_id='test_student',
        )

        resp = self.request(xblock, 'download_url', json.dumps(dict()), response_format='json')

        self.assertTrue(resp['success'])
        self.assertEqual(download_url, resp['url'])
Ejemplo n.º 31
0
    def test_download_url(self, xblock):
        """ Test generate correct download URL with existing file. should create a file and get the download URL """
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket)
        key.key = "submissions_attachments/test_student/test_course/" + xblock.scope_ids.usage_id
        key.set_contents_from_string("How d'ya do?")
        download_url = api.get_download_url("test_student/test_course/" + xblock.scope_ids.usage_id)

        xblock.xmodule_runtime = Mock(
            course_id='test_course',
            anonymous_student_id='test_student',
        )

        resp = self.request(xblock, 'download_url', json.dumps(dict()), response_format='json')

        self.assertTrue(resp['success'])
        self.assertEqual(download_url, resp['url'])
Ejemplo n.º 32
0
    def _get_file_download_url(self, file_key):
        """
        Internal function for retrieving the download url at which the file that corresponds
        to the file_key can be downloaded.

        Arguments:
            file_key (string): Corresponding file key.
        Returns:
            file_download_url (string) or empty string in case of error.
        """
        try:
            file_download_url = file_upload_api.get_download_url(file_key)
        except FileUploadError as exc:
            logger.exception(
                u'FileUploadError: URL retrieval failed for key {file_key} with error {error}'
                .format(file_key=file_key, error=exc))
            file_download_url = ''
        return file_download_url
Ejemplo n.º 33
0
    def test_image_and_text_submission(self, xblock):
        # Create a file and get the download URL
        conn = boto.connect_s3()
        bucket = conn.create_bucket('mybucket')
        key = Key(bucket)
        key.key = "submissions_attachments/foo"
        key.set_contents_from_string("How d'ya do?")
        downloadUrl = api.get_download_url("foo")
        # Create a image and text submission
        self._create_submissions_and_scores(xblock, [({
            "text": "test answer",
            "file_key": "foo"
        }, 1)],
                                            submission_key=None)

        # Expect that we retrieve both the text and the download URL for the file
        self._assert_scores(xblock, [{
            "content": "test answer",
            "score": 1,
            "file": downloadUrl
        }])
Ejemplo n.º 34
0
 def test_image_and_text_submission(self, xblock):
     # Create a file and get the download URL
     conn = boto.connect_s3()
     bucket = conn.create_bucket('mybucket')
     key = Key(bucket)
     key.key = "submissions_attachments/foo"
     key.set_contents_from_string("How d'ya do?")
     downloadUrl = api.get_download_url("foo")
     # Create a image and text submission
     submission = prepare_submission_for_serialization(("test answer 1 part 1", "test answer 1 part 2"))
     submission[u"file_key"] = "foo"
     self._create_submissions_and_scores(xblock, [
         (submission, 1)
     ])
     self.maxDiff = None
     # Expect that we retrieve both the text and the download URL for the file
     self._assert_scores(xblock, [
         {"file": downloadUrl, "score": 1, "submission": create_submission_dict(
             {"answer": submission},
             xblock.prompts
         )}
     ])
Ejemplo n.º 35
0
    def get_download_url_from_submission(self, submission):
        """
        Returns a download URL for retrieving content within a submission.

        Args:
            submission (dict): Dictionary containing an answer and a file_key.
                The file_key is used to try and retrieve a download url
                with related content

        Returns:
            A URL to related content. If there is no content related to this
            key, or if there is no key for the submission, returns an empty
            string.

        """
        url = ""
        key = submission['answer'].get('file_key', '')
        try:
            if key:
                url = file_upload_api.get_download_url(key)
        except FileUploadError:
            logger.exception("Unable to generate download url for file key {}".format(key))
        return url
Ejemplo n.º 36
0
    def render_leaderboard_complete(self, student_item_dict):
        """
        Render the leaderboard complete state.

        Args:
            student_item_dict (dict): The student item

        Returns:
            template_path (string), tuple of context (dict)
        """

        # Retrieve top scores from the submissions API
        # Since this uses the read-replica and caches the results,
        # there will be some delay in the request latency.
        scores = sub_api.get_top_submissions(
            student_item_dict["course_id"],
            student_item_dict["item_id"],
            student_item_dict["item_type"],
            self.leaderboard_show,
        )
        for score in scores:
            if "file_key" in score["content"]:
                score["file"] = file_upload_api.get_download_url(score["content"]["file_key"])
            if "text" in score["content"] or "parts" in score["content"]:
                submission = {"answer": score.pop("content")}
                score["submission"] = create_submission_dict(submission, self.prompts)
            elif isinstance(score["content"], basestring):
                pass
            # Currently, we do not handle non-text submissions.
            else:
                score["submission"] = ""

            score.pop("content", None)

        context = {"topscores": scores, "allow_latex": self.allow_latex}

        return "openassessmentblock/leaderboard/oa_leaderboard_show.html", context
Ejemplo n.º 37
0
    def get_student_info_path_and_context(self, student_username):
        """
        Get the proper path and context for rendering the the student info
        section of the staff debug panel.

        Args:
            student_username (unicode): The username of the student to report.

        """
        submission_uuid = None
        submission = None
        assessment_steps = self.assessment_steps
        anonymous_user_id = None
        submissions = None
        student_item = None

        if student_username:
            anonymous_user_id = self.get_anonymous_user_id(student_username, self.course_id)
            student_item = self.get_student_item_dict(anonymous_user_id=anonymous_user_id)

        if anonymous_user_id:
            # If there is a submission available for the requested student, present
            # it. If not, there will be no other information to collect.
            submissions = submission_api.get_submissions(student_item, 1)

        if submissions:
            submission_uuid = submissions[0]['uuid']
            submission = submissions[0]

            if 'file_key' in submission.get('answer', {}):
                file_key = submission['answer']['file_key']

                try:
                    submission['image_url'] = file_api.get_download_url(file_key)
                except file_api.FileUploadError:
                    # Log the error, but do not prevent the rest of the student info
                    # from being displayed.
                    msg = (
                        u"Could not retrieve image URL for staff debug page.  "
                        u"The student username is '{student_username}', and the file key is {file_key}"
                    ).format(student_username=student_username, file_key=file_key)
                    logger.exception(msg)

        example_based_assessment = None
        self_assessment = None
        peer_assessments = []
        submitted_assessments = []

        if "peer-assessment" in assessment_steps:
            peer_assessments = peer_api.get_assessments(submission_uuid)
            submitted_assessments = peer_api.get_submitted_assessments(submission_uuid, scored_only=False)

        if "self-assessment" in assessment_steps:
            self_assessment = self_api.get_assessment(submission_uuid)

        if "example-based-assessment" in assessment_steps:
            example_based_assessment = ai_api.get_latest_assessment(submission_uuid)

        workflow_cancellation = workflow_api.get_assessment_workflow_cancellation(submission_uuid)
        if workflow_cancellation:
            workflow_cancellation['cancelled_by'] = self.get_username(workflow_cancellation['cancelled_by_id'])

        context = {
            'submission': submission,
            'workflow_cancellation': workflow_cancellation,
            'peer_assessments': peer_assessments,
            'submitted_assessments': submitted_assessments,
            'self_assessment': self_assessment,
            'example_based_assessment': example_based_assessment,
            'rubric_criteria': copy.deepcopy(self.rubric_criteria_with_labels),
        }

        if peer_assessments or self_assessment or example_based_assessment:
            max_scores = peer_api.get_rubric_max_scores(submission_uuid)
            for criterion in context["rubric_criteria"]:
                criterion["total_value"] = max_scores[criterion["name"]]

        path = 'openassessmentblock/staff_debug/student_info.html'
        return path, context
Ejemplo n.º 38
0
 def test_get_download_url_error(self, mock_s3):
     with raises(exceptions.FileUploadInternalError):
         mock_s3.side_effect = Exception("Oh noes")
         api.get_download_url("foo")
Ejemplo n.º 39
0
 def test_get_download_url_error(self, mock_s3):
     mock_s3.side_effect = Exception("Oh noes")
     api.get_download_url("foo")
Ejemplo n.º 40
0
    def get_student_info_path_and_context(self, student_id):
        """
        Get the proper path and context for rendering the the student info
        section of the staff debug panel.

        Args:
            student_id (unicode): The ID of the student to report.

        """
        submission_uuid = None
        submission = None
        assessment_steps = self.assessment_steps
        student_item = self.get_student_item_dict()
        scores = {}
        problem_closed = None

        if student_id:
            student_item['student_id'] = student_id

            # If there is a submission available for the requested student, present
            # it. If not, there will be no other information to collect.
            submissions = submission_api.get_submissions(student_item, 1)

            if submissions:
                submission_uuid = submissions[0]['uuid']
                submission = submissions[0]

                if 'file_key' in submission.get('answer', {}):
                    file_key = submission['answer']['file_key']

                    try:
                        submission['image_url'] = file_api.get_download_url(file_key)
                    except file_api.FileUploadError:
                        # Log the error, but do not prevent the rest of the student info
                        # from being displayed.
                        msg = (
                            u"Could not retrieve image URL for staff debug page.  "
                            u"The student ID is '{student_id}', and the file key is {file_key}"
                        ).format(student_id=student_id, file_key=file_key)
                        logger.exception(msg)

        example_based_assessment = None
        self_assessment = None
        peer_assessments = []
        submitted_assessments = []

        if "peer-assessment" in assessment_steps:
            peer_assessments = peer_api.get_assessments(submission_uuid)
            submitted_assessments = peer_api.get_submitted_assessments(submission_uuid, scored_only=False)

            # Get the data we need for instructor override of the student's score
            rubric_dict = create_rubric_dict(self.prompt, self.rubric_criteria_with_labels)
            scores = peer_api.get_data_for_override_score(
                submission_uuid,
                student_item,
                rubric_dict,
            )
            problem_closed, dummy0, dummy1, dummy2 = self.is_closed(step='peer-assessment', course_staff=False)

        if "self-assessment" in assessment_steps:
            self_assessment = self_api.get_assessment(submission_uuid)

        if "example-based-assessment" in assessment_steps:
            example_based_assessment = ai_api.get_latest_assessment(submission_uuid)

        context = {
            'submission': submission,
            'peer_assessments': peer_assessments,
            'submitted_assessments': submitted_assessments,
            'self_assessment': self_assessment,
            'example_based_assessment': example_based_assessment,
            'rubric_criteria': copy.deepcopy(self.rubric_criteria_with_labels),
            'scores': scores,
            'problem_closed': problem_closed,
        }

        if peer_assessments or self_assessment or example_based_assessment:
            max_scores = peer_api.get_rubric_max_scores(submission_uuid)
            for criterion in context["rubric_criteria"]:
                criterion["total_value"] = max_scores[criterion["name"]]

        path = 'openassessmentblock/staff_debug/student_info.html'
        return path, context
Ejemplo n.º 41
0
def get_file_url(answer):
    if answer.get('file_key'):
        return ora_file_upload_api.get_download_url(answer['file_key'])
    return None
Ejemplo n.º 42
0
    def get_student_info_path_and_context(self, student_id):
        """
        Get the proper path and context for rendering the the student info
        section of the staff debug panel.

        Args:
            student_id (unicode): The ID of the student to report.

        """
        submission_uuid = None
        submission = None
        assessment_steps = self.assessment_steps

        if student_id:
            student_item = self.get_student_item_dict()
            student_item['student_id'] = student_id

            # If there is a submission available for the requested student, present
            # it. If not, there will be no other information to collect.
            submissions = submission_api.get_submissions(student_item, 1)

            if submissions:
                submission_uuid = submissions[0]['uuid']
                submission = submissions[0]

                if 'file_key' in submission.get('answer', {}):
                    file_key = submission['answer']['file_key']

                    try:
                        submission['image_url'] = file_api.get_download_url(
                            file_key)
                    except file_api.FileUploadError:
                        # Log the error, but do not prevent the rest of the student info
                        # from being displayed.
                        msg = (
                            u"Could not retrieve image URL for staff debug page.  "
                            u"The student ID is '{student_id}', and the file key is {file_key}"
                        ).format(student_id=student_id, file_key=file_key)
                        logger.exception(msg)

        example_based_assessment = None
        self_assessment = None
        peer_assessments = []
        submitted_assessments = []

        if "peer-assessment" in assessment_steps:
            peer_assessments = peer_api.get_assessments(submission_uuid)
            submitted_assessments = peer_api.get_submitted_assessments(
                submission_uuid, scored_only=False)

        if "self-assessment" in assessment_steps:
            self_assessment = self_api.get_assessment(submission_uuid)

        if "example-based-assessment" in assessment_steps:
            example_based_assessment = ai_api.get_latest_assessment(
                submission_uuid)

        context = {
            'submission': submission,
            'peer_assessments': peer_assessments,
            'submitted_assessments': submitted_assessments,
            'self_assessment': self_assessment,
            'example_based_assessment': example_based_assessment,
            'rubric_criteria': copy.deepcopy(self.rubric_criteria_with_labels),
        }

        if peer_assessments or self_assessment or example_based_assessment:
            max_scores = peer_api.get_rubric_max_scores(submission_uuid)
            for criterion in context["rubric_criteria"]:
                criterion["total_value"] = max_scores[criterion["name"]]

        path = 'openassessmentblock/staff_debug/student_info.html'
        return path, context
Ejemplo n.º 43
0
 def test_get_download_url_error(self, mock_s3):
     mock_s3.side_effect = Exception("Oh noes")
     api.get_download_url("foo")