def handle(self, *args, **options):
        self._canvas = Canvas()
        self._tools = ExternalTools()
        self._accounts = Accounts()
        self._courses = Courses()
        self._options = options

        csv.register_dialect("unix_newline", lineterminator="\n")
        self._writer = csv.writer(sys.stdout, dialect="unix_newline")

        self._headers = [
            'tool_name', 'tool_id', 'tool_type', 'account_name', 'account_id'
        ]

        if self._options['courses']:
            self._headers.append('course_name')
            self._headers.append('course_id')
            self._headers.append('term')

        if options['sessionless']:
            self._headers.append('sessionless url')

        if re.match(r'^\d+$', options['account_id']):
            account = self._accounts.get_account(options['account_id'])
        else:
            account = self._accounts.get_account_by_sis_id(
                options['account_id'])

        try:
            self.report_external_tools(account)

        except DataFailureException as err:
            if err.status == 404:
                print('Unknown Sub-Account \"%s\"' % (options['account_id']),
                      file=sys.stderr)
    def update_discovery_url(self, discovery_url):
        account_id = settings.RESTCLIENTS_CANVAS_ACCOUNT_ID

        LiveDAO.pools = {}
        auth = Accounts().get_auth_settings(account_id)

        if auth.auth_discovery_url != discovery_url:
            auth.auth_discovery_url = discovery_url
            Accounts().update_auth_settings(account_id, auth)
    def test_account(self):
        canvas = Canvas()

        account = canvas.get_account_by_sis_id('uwcourse:seattle:cse:cse')
        self.assertEquals(account.account_id, 696969)
        self.assertEquals(account.name, "Computer Science & Engineering",
                          "Has proper name")
        self.assertEquals(account.sis_account_id, 'uwcourse:seattle:cse:cse')
        self.assertEquals(account.parent_account_id, 987654)
    def test_sub_account(self):
        canvas = Canvas()

        accounts = canvas.get_sub_accounts_by_sis_id('uwcourse:seattle:cse')

        account = accounts[1]

        self.assertEquals(len(accounts), 3, "Too few accounts")
        self.assertEquals(account.name,
                          "Comp Sci & Engr Accelerated Masters Prg",
                          "Has proper name")
        self.assertEquals(account.sis_account_id, 'uwcourse:seattle:cse:csem')
        self.assertEquals(account.parent_account_id, 54321)
    def test_update_account(self, mock_update):
        mock_update.return_value = None
        canvas = Canvas()

        accounts = canvas.get_all_sub_accounts_by_sis_id(
            'uwcourse:seattle:cse')
        account = accounts[0]
        account.name = "New Name"

        canvas.update_account(account)
        mock_update.assert_called_with('/api/v1/accounts/88888',
                                       {'account': {
                                           'name': 'New Name'
                                       }})
    def test_update_sis_id(self, mock_update):
        mock_update.return_value = None
        canvas = Canvas()

        canvas.update_sis_id(54321, 'NEW_SIS_ID')
        mock_update.assert_called_with(
            '/api/v1/accounts/54321',
            {'account': {
                'sis_account_id': 'NEW_SIS_ID'
            }})

        # Cannot update sis id for root account
        self.assertRaises(Exception, canvas.update_sis_id,
                          getattr(settings, 'RESTCLIENTS_CANVAS_ACCOUNT_ID'),
                          'NEW_SIS_ID')
    def test_update_auth_settings(self, mock_update):
        mock_update.return_value = None
        canvas = Canvas()

        auth_settings = CanvasSSOSettings(
            unknown_user_url='https://test.edu/unknown')

        canvas.update_auth_settings(
            getattr(settings, 'RESTCLIENTS_CANVAS_ACCOUNT_ID'), auth_settings)
        mock_update.assert_called_with(
            '/api/v1/accounts/12345/sso_settings', {
                'sso_settings': {
                    'login_handle_name': None,
                    'change_password_url': None,
                    'auth_discovery_url': None,
                    'unknown_user_url': 'https://test.edu/unknown'
                }
            })
Exemplo n.º 8
0
    def find_grading_standard_for_account(self, account_id,
                                          grading_standard_id):
        """
        Get a single grading standard in account context, searching ancestor
        accounts if necessary.
        """
        if not self._canvas_account_id:
            raise MissingAccountID()

        acc = Accounts()
        while account_id is not None:
            try:
                return self.get_grading_standard_for_account(
                    account_id, grading_standard_id)
            except DataFailureException as ex:
                if ex.status == 404 and account_id != self._canvas_account_id:
                    account_id = acc.get_account(account_id).parent_account_id
                    continue
                raise
Exemplo n.º 9
0
def update_account_sis_id(account_id, sis_account_id):
    return Accounts().update_sis_id(account_id, sis_account_id)
Exemplo n.º 10
0
def get_all_sub_accounts(account_id):
    return Accounts(per_page=100).get_all_sub_accounts(account_id)
Exemplo n.º 11
0
def get_account_by_sis_id(sis_account_id):
    return Accounts().get_account_by_sis_id(sis_account_id)
Exemplo n.º 12
0
def get_account_by_id(account_id):
    return Accounts().get_account(account_id)
class Command(BaseCommand):
    help = "Report externals tools in account"

    def add_arguments(self, parser):
        parser.add_argument(
            '-a',
            '--account',
            action='store',
            dest='account_id',
            default=default_account,
            help=('show external tools in account by id or '
                  'sis_id (default: {})').format(default_account))
        parser.add_argument('-r',
                            '--recurse',
                            action='store_true',
                            dest='recurse',
                            default=False,
                            help='recurse through subaccounts')
        parser.add_argument('-c',
                            '--courses',
                            action='store_true',
                            dest='courses',
                            default=False,
                            help='include account courses in report')
        parser.add_argument('-t',
                            '--term',
                            action='store',
                            dest='term',
                            default='',
                            help='include only courses in given term')
        parser.add_argument(
            '-s',
            '--sessionless-url',
            action='store_true',
            dest='sessionless',
            default=False,
            help='show sessionless url with each external tool')

    def handle(self, *args, **options):
        self._canvas = Canvas()
        self._tools = ExternalTools()
        self._accounts = Accounts()
        self._courses = Courses()
        self._options = options

        csv.register_dialect("unix_newline", lineterminator="\n")
        self._writer = csv.writer(sys.stdout, dialect="unix_newline")

        self._headers = [
            'tool_name', 'tool_id', 'tool_type', 'account_name', 'account_id'
        ]

        if self._options['courses']:
            self._headers.append('course_name')
            self._headers.append('course_id')
            self._headers.append('term')

        if options['sessionless']:
            self._headers.append('sessionless url')

        if re.match(r'^\d+$', options['account_id']):
            account = self._accounts.get_account(options['account_id'])
        else:
            account = self._accounts.get_account_by_sis_id(
                options['account_id'])

        try:
            self.report_external_tools(account)

        except DataFailureException as err:
            if err.status == 404:
                print('Unknown Sub-Account \"%s\"' % (options['account_id']),
                      file=sys.stderr)

    def report_external_tools(self, account):
        tools = self._tools.get_external_tools_in_account(account.account_id)
        self._print_tools(tools, account)

        if self._options['courses']:
            params = {
                "by_subaccounts": [account.account_id],
                "include": ["term"]
            }

            if self._options['term']:
                params['enrollment_term_id'] = self._canvas.get_term_by_sis_id(
                    self._options['term']).term_id

            courses = self._courses.get_published_courses_in_account(
                account.account_id, params=params)
            for course in courses:
                tools = self._tools.get_external_tools_in_course(
                    course.course_id)
                self._print_tools(tools, account, course)

        if self._options['recurse']:
            subaccounts = self._accounts.get_sub_accounts(account.account_id)
            for account in subaccounts:
                self.report_external_tools(account)

    def _print_tools(self, tools, account, course=None):
        if len(tools):
            if self._headers:
                self._writer.writerow(self._headers)
                self._headers = None

            for tool in tools:
                tool_types = []
                for tt in ['account', 'course', 'user']:
                    if tool.get("{}_navigation".format(tt)):
                        tool_types.append(tt)

                tool_type = ' & '.join(tool_types)
                line = [
                    tool['name'], tool['id'], tool_type, account.name,
                    account.account_id
                ]

                if self._options['courses']:
                    if course:
                        line.extend([
                            course.name, course.course_id,
                            course.term.name if course.term else ''
                        ])
                    else:
                        line.extend(['', '', ''])

                if self._options['sessionless']:
                    try:
                        tools = self._tools
                        url = tools.get_sessionless_launch_url_from_account(
                            tool['id'], account.account_id)
                        line.append(url['url'])
                    except DataFailureException as ex:
                        line.append('')

                self._writer.writerow(line)
    def handle(self, *args, **options):
        subaccount_id = options.get('subaccount_id')
        sis_term_id = options.get('term_id')

        accounts = Accounts()
        reports = Reports()
        pws = PWS()

        outpath = "{}/{}-{}-{}.csv".format(
            dirname(__file__), "active-instructors", subaccount_id,
            sis_term_id)
        outfile = open(outpath, "w")
        csv.register_dialect('unix_newline', lineterminator='\n')
        writer = csv.writer(outfile, dialect='unix_newline')
        writer.writerow(['email', 'first_name', 'last_name'])

        account = accounts.get_account(subaccount_id)
        term = reports.get_term_by_sis_id(sis_term_id)

        enrollment_report = reports.create_enrollments_provisioning_report(
            account.account_id, term.term_id)
        enrollment_data = reports.get_report_data(enrollment_report)

        all_instructors = {}

        enrollment_csv_data = csv.reader(enrollment_data)
        header = next(enrollment_csv_data)
        course_id_idx = header.index("course_id")
        sis_user_id_idx = header.index("user_id")
        role_idx = header.index("role")
        status_idx = header.index("status")

        for row in enrollment_csv_data:
            if not len(row):
                continue

            course_id = row[course_id_idx]
            sis_user_id = row[sis_user_id_idx]
            role = row[role_idx]
            status = row[status_idx]

            if (sis_user_id != "" and role.lower() == "teacher" and
                    status.lower() == "active"):
                if course_id not in all_instructors:
                    all_instructors[course_id] = []

                all_instructors[course_id].append(sis_user_id)

        course_report = reports.create_course_provisioning_report(
            account.account_id, term.term_id)
        course_data = reports.get_report_data(course_report)

        course_csv_data = csv.reader(course_data)
        header = next(course_csv_data)
        course_id_idx = header.index("course_id")
        sis_account_id_idx = header.index("account_id")
        status_idx = header.index("status")

        active_instructors = {}
        for row in course_csv_data:
            if not len(row):
                continue

            course_id = row[course_id_idx]
            sis_account_id = row[sis_account_id_idx]
            status = row[status_idx]

            if (sis_account_id != "" and status.lower() == "active" and
                    course_id in all_instructors):
                for sis_user_id in all_instructors[course_id]:
                    if sis_user_id in active_instructors:
                        continue

                    try:
                        person = pws.get_person_by_regid(sis_user_id)
                        active_instructors[sis_user_id] = [
                            person.uwnetid + "@uw.edu",
                            person.preferred_first_name or person.first_name,
                            person.preferred_surname or person.surname]
                    except InvalidRegID:
                        continue
                    except DataFailureException as err:
                        if err.status == 404:
                            continue
                        else:
                            raise

        for csv_data in active_instructors.values():
            writer.writerow(csv_data)
        outfile.close()

        reports.delete_report(enrollment_report)
        reports.delete_report(course_report)

        print(outpath)