Beispiel #1
0
    def get_members(self, group_id):
        """
        Returns a list of restclients.GroupMember objects for the group
        identified by the passed group ID.
        """
        if not self._is_valid_group_id(group_id):
            raise InvalidGroupID(group_id)

        dao = GWS_DAO()
        url = "/group_sws/v2/group/%s/member" % group_id
        response = dao.getURL(url, self._headers({"Accept": "text/xhtml"}))

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return self._members_from_xhtml(response.data)
Beispiel #2
0
def get_resource(url, subdomain):
    """
    Issue a GET request to IASystem with the given url
    and return a response in Collection+json format.
    :returns: http response with content in json
    """
    headers = {"Accept": "application/vnd.collection+json"}
    timer = Timer()
    response = IASYSTEM_DAO().getURL(url, headers, subdomain)

    log_info(logger, "%s ==status==> %s" % (url, response.status), timer)

    if response.status != 200:
        logger.debug("%s ==data==> %s" % (url, response.data))
        raise DataFailureException(url, response.status, response.data)

    return json.loads(response.data)
Beispiel #3
0
    def put_name_by_netid(self, netid, data):
        """
        Updates display info for a Name object
        """
        if not self.valid_uwnetid(netid):
            raise InvalidNetID(netid)

        pd = self.valid_irws_name_from_json(data)
        dao = IRWS_DAO()
        url = "/%s/v1/name/uwnetid=%s" % (self._service_name, netid.lower())
        response = dao.putURL(url, {"Accept": "application/json"},
                              json.dumps(pd))

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return response.status
Beispiel #4
0
    def import_str(self, csv, params={}):
        """
        Imports a CSV string.

        https://canvas.instructure.com/doc/api/sis_imports.html#method.sis_imports_api.create
        """
        params["import_type"] = SISImportModel.CSV_IMPORT_TYPE
        url = "/api/v1/accounts/%s/sis_imports.json%s" % (
            settings.RESTCLIENTS_CANVAS_ACCOUNT_ID, self._params(params))
        headers = {"Accept": "application/json", "Content-Type": "text/csv"}

        response = Canvas_DAO().postURL(url, headers, csv)

        if not (response.status == 200 or response.status == 204):
            raise DataFailureException(url, response.status, response.data)

        return self._sis_import_from_json(json.loads(response.data))
Beispiel #5
0
    def get_person_by_netid(self, netid):
        """
        Returns a restclients.Person object for the given netid.  If the
        netid isn't found, or if there is an error communicating with the PWS,
        a DataFailureException will be thrown.
        """
        if not self.valid_uwnetid(netid):
            raise InvalidNetID(netid)

        dao = PWS_DAO()
        url = "%s/%s/full.json" % (PERSON_PREFIX, netid.lower())
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return self._person_from_json(response.data)
Beispiel #6
0
    def get_channel_by_surrogate_id(self, channel_type, surrogate_id):
        """
        Get a channel by surrogate id
        """
        key = "%s|%s" % (channel_type, surrogate_id)
        url = "/notification/v1/channel/%s" % (quote(key))

        dao = NWS_DAO()
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        channel = Channel()
        Serializer().deserialize(channel, response.data)

        return channel
Beispiel #7
0
    def get_entity_by_regid(self, regid):
        """
        Returns a restclients.Entity object for the given regid.  If the
        regid isn't found, or if there is an error communicating with the PWS,
        a DataFailureException will be thrown.
        """
        if not self.valid_uwregid(regid):
            raise InvalidRegID(regid)

        dao = PWS_DAO()
        url = "%s/%s.json" % (ENTITY_PREFIX, regid.upper())
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return self._entity_from_json(response.data)
Beispiel #8
0
    def get_name_by_netid(self, netid):
        """
        Returns a restclients.irws.Name object for the given netid.  If the
        netid isn't found, nothing will be returned.  If there is an error
        communicating with the IRWS, a DataFailureException will be thrown.
        """
        if not self.valid_uwnetid(netid):
            raise InvalidNetID(netid)

        dao = IRWS_DAO()
        url = "/%s/v1/name/uwnetid=%s" % (self._service_name, netid.lower())
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return self._name_from_json(response.data)
Beispiel #9
0
    def get_contact(self, regid):
        """
        Returns data for the given regid.
        """
        if not self.valid_uwregid(regid):
            raise InvalidRegID(regid)

        dao = PWS_DAO()
        url = "%s/%s/full.json" % (PERSON_PREFIX, regid.upper())
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status == 404:
            return

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return json.loads(response.data)
Beispiel #10
0
    def _get_report_file(self, url):
        # Ensure file url matches the hostname in settings,
        # workaround for Canvas bug help.instructure.com/tickets/362386
        url = re.sub(r'^https://[^/]+', settings.RESTCLIENTS_CANVAS_HOST, url)

        timeout = getattr(settings, "RESTCLIENTS_TIMEOUT", 15.0)
        cafile = getattr(settings, "RESTCLIENTS_CA_BUNDLE",
                         "/etc/ssl/certs/ca-bundle.crt")
        pool_manager = PoolManager(cert_reqs="CERT_REQUIRED",
                                   ca_certs=cafile,
                                   timeout=timeout,
                                   retries=5)

        response = pool_manager.request("GET", url)

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return response.data
Beispiel #11
0
    def update_channel(self, channel):
        """
        Update an existing channel

        :param channel:
        is the updated channel that the client wants to update
        """
        #Update the channel
        dao = NWS_DAO()
        url = "/notification/v1/channel/%s" % (channel.channel_id)

        put_response = dao.putURL(url, {"Content-Type": "application/json"}, Serializer().serialize(channel))

        #Http response code 204 No Content:
        #The server has fulfilled the request but does not need to return an entity-body
        if put_response.status != 204:
            raise DataFailureException(url, put_response.status, put_response.data)

        return put_response.status
Beispiel #12
0
    def create_group(self, group):
        """
        Creates a group from the passed restclients.Group object.
        """
        body = self._xhtml_from_group(group)

        dao = GWS_DAO()
        url = "/group_sws/v2/group/%s" % group.name
        response = dao.putURL(
            url,
            self._headers({
                "Accept": "text/xhtml",
                "Content-Type": "text/xhtml"
            }), body)

        if response.status != 201:
            raise DataFailureException(url, response.status, response.data)

        return self._group_from_xhtml(response.data)
Beispiel #13
0
    def create_new_channel(self, channel):
        """
        Create a new channel

        :param channel:
        is the new channel that the client wants to create
        """
        #Create new channel
        dao = NWS_DAO()
        url = "/notification/v1/channel"

        post_response = dao.postURL(url, {"Content-Type": "application/json"}, Serializer().serialize(channel))

        #HTTP Status Code 201 Created: The request has been fulfilled and resulted
        #in a new resource being created
        if post_response.status != 201:
            raise DataFailureException(url, post_response.status, post_response.data)

        return post_response.status
Beispiel #14
0
    def get_channel_by_channel_id(self, channel_id):
        """
        Get a channel by channel id
        """
        #Validate the channel_id
        self._validate_uuid(channel_id)

        url = "/notification/v1/channel/%s" % (channel_id)

        dao = NWS_DAO()
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        channel = Channel()
        Serializer().deserialize(channel, response.data)

        return channel
Beispiel #15
0
    def get_effective_member_count(self, group_id):
        """
        Returns a count of effective members for the group identified by the
        passed group ID.
        """
        if not self._is_valid_group_id(group_id):
            raise InvalidGroupID(group_id)

        dao = GWS_DAO()
        url = "/group_sws/v2/group/%s/effective_member?view=count" % group_id
        response = dao.getURL(url, self._headers({"Accept": "text/xhtml"}))

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        root = etree.fromstring(response.data)
        count = root.find('.//*[@class="member_count"]').get("count")

        return int(count)
Beispiel #16
0
    def get_endpoints_by_subscriber_id(self, subscriber_id):
        """
        Search for all endpoints by a given subscriber
        """
        #Validate input
        self._validate_subscriber_id(subscriber_id)

        url = "/notification/v1/endpoint?subscriber_id=%s" % (subscriber_id)

        dao = NWS_DAO()
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        endpoint_list = EndpointList()
        Serializer().deserialize(endpoint_list, response.data)

        return endpoint_list.view_models
Beispiel #17
0
    def get_endpoint_by_endpoint_id(self, endpoint_id):
        """
        Get an endpoint by endpoint id
        """
        #Validate the channel_id
        self._validate_uuid(endpoint_id)

        url = "/notification/v1/endpoint/%s" % (endpoint_id)

        dao = NWS_DAO()
        response = dao.getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        endpoint = Endpoint()
        Serializer().deserialize(endpoint, response.data)

        return endpoint
Beispiel #18
0
    def get_verba_link_for_schedule(self, schedule):
        """
        Returns a link to verba.  The link varies by campus and schedule.
        Multiple calls to this with the same schedule may result in
        different urls.
        """
        dao = Book_DAO()

        url = self.get_verba_url(schedule)

        response = dao.getURL(url, {"Accept": "application/json"})
        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        data = json.loads(response.data)

        for key in data:
            if re.match(r'^[A-Z]{2}[0-9]{5}$', key):
                return "%s%s&quarter=%s" % (BOOK_PREFIX, key,
                                            schedule.term.quarter)
Beispiel #19
0
def get_graderoster(section, instructor):
    """
    Returns a restclients.GradeRoster for the passed Section model and
    instructor Person.
    """
    label = GradeRoster(section=section,
                        instructor=instructor).graderoster_label()
    url = "%s/%s" % (graderoster_url, encode_section_label(label))
    headers = {"Accept": "text/xhtml",
               "Connection": "keep-alive",
               "X-UW-Act-as": instructor.uwnetid}

    response = SWS_DAO().getURL(url, headers)

    if response.status != 200:
        root = etree.fromstring(response.data)
        msg = root.find(".//*[@class='status_description']").text.strip()
        raise DataFailureException(url, response.status, msg)

    return graderoster_from_xhtml(response.data, section, instructor)
Beispiel #20
0
    def is_effective_member(self, group_id, netid):
        """
        Returns True if the netid is in the group, False otherwise.
        """
        if not self._is_valid_group_id(group_id):
            raise InvalidGroupID(group_id)

        # GWS doesn't accept EPPNs on effective member checks, for UW users
        netid = re.sub('@washington.edu', '', netid)

        dao = GWS_DAO()
        url = "/group_sws/v2/group/%s/effective_member/%s" % (group_id, netid)
        response = dao.getURL(url, self._headers({"Accept": "text/xhtml"}))

        if response.status == 404:
            return False
        elif response.status == 200:
            return True
        else:
            raise DataFailureException(url, response.status, response.data)
Beispiel #21
0
    def create_new_message(self, dispatch):
        """
        Create a new dispatch

        :param dispatch:
        is the new dispatch that the client wants to create
        """

        #Create new dispatch
        dao = NWS_DAO()
        url = "/notification/v1/dispatch"

        data = Serializer().serialize(dispatch)

        post_response = dao.postURL(url, {"Content-Type": "application/json"}, data)

        if post_response.status != 200:
            raise DataFailureException(url, post_response.status, post_response.data)

        return post_response.status
Beispiel #22
0
    def post_hr_person_by_netid(self, netid, data):
        """
        Post to the irws person hr resource.
        We look up the person by netid to get the uri to post to.
        """
        if not self.valid_uwnetid(netid):
            raise InvalidNetID(netid)
        hepps_person = self.valid_hr_person_from_json(data)
        identity = self.get_identity_by_netid(netid)
        if not {'hepps', 'uwhr'} & set(identity.identifiers.keys()):
            raise IRWSPersonNotFound(
                'netid {} not a hepps/uwhr person'.format(netid))
        source = 'uwhr' if 'uwhr' in identity.identifiers.keys() else 'hepps'
        post_url = '/{}/v1{}'.format(self._service_name,
                                     identity.identifiers[source])
        response = IRWS_DAO().postURL(post_url, {'Accept': 'application/json'},
                                      json.dumps(hepps_person))
        if response.status != 200:
            raise DataFailureException(post_url, response.status,
                                       response.data)

        return response.status
Beispiel #23
0
    def update_members(self, group_id, members):
        """
        Updates the membership of the group represented by the passed group id.
        Returns a list of members not found.
        """
        if not self._is_valid_group_id(group_id):
            raise InvalidGroupID(group_id)

        body = self._xhtml_from_members(group_id, members)

        dao = GWS_DAO()
        url = "/group_sws/v2/group/%s/member" % group_id
        response = dao.putURL(
            url, self._headers({
                "Content-Type": "text/xhtml",
                "If-Match": "*"
            }), body)

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        return self._notfoundmembers_from_xhtml(response.data)
Beispiel #24
0
def update_graderoster(graderoster):
    """
    Updates the graderoster resource for the passed restclients.GradeRoster
    model. A new restclients.GradeRoster is returned, representing the
    document returned from the update request.
    """
    label = graderoster.graderoster_label()
    url = "%s/%s" % (graderoster_url, encode_section_label(label))
    headers = {"Content-Type": "application/xhtml+xml",
               "Connection": "keep-alive",
               "X-UW-Act-as": graderoster.instructor.uwnetid}
    body = graderoster.xhtml()

    response = SWS_DAO().putURL(url, headers, body)

    if response.status != 200:
        root = etree.fromstring(response.data)
        msg = root.find(".//*[@class='status_description']").text.strip()
        raise DataFailureException(url, response.status, msg)

    return graderoster_from_xhtml(response.data, graderoster.section,
                                  graderoster.instructor)
Beispiel #25
0
def get_resource(url):
    timer = Timer()
    dao = DigitLib_DAO()
    response = dao.getURL(url, {})

    log_info(logger,
             "%s ==status==> %s" % (url, response.status),
             timer)

    if response.status == 302:
        logger.debug("%s ==headers==> %s" % (url,
                                             response.headers))
        return response.headers

    if response.status == 200 and response.data is not None:
        logger.debug("%s ==data==> %s" % (url,
                                          response.data))
        return json.loads(response.data)

    raise DataFailureException(url,
                               response.status,
                               response.data)
Beispiel #26
0
    def delete_channel(self, channel_id):
        """
        Deleting an existing channel

        :param channel_id:
        is the channel that the client wants to delete
        """

        #Validate the subscription_id
        self._validate_uuid(channel_id)

        #Delete the subscription
        url = "/notification/v1/channel/%s" % (channel_id)
        dao = NWS_DAO()
        delete_response = dao.deleteURL(url, None)

        #Http response code 204 No Content:
        #The server has fulfilled the request but does not need to return an entity-body
        if delete_response.status != 204:
            raise DataFailureException(url, delete_response.status, delete_response.data)

        return delete_response.status
Beispiel #27
0
    def update_person(self, person):
        """
        Update an existing person

        :param person:
        is the updated person that the client wants to update
        """
        #Validate
        self._validate_regid(person.person_id)
        self._validate_subscriber_id(person.surrogate_id)

        attributes = person.get_attributes()
        person.attributes = None

        for attribute in attributes:
            if attribute.name in MANAGED_ATTRIBUTES:
                continue

            person.add_attribute(attribute.name, attribute.value, None, None)
        #    ATTRIBUTE_TYPE_EMAIL_DISPATCHED_COUNT = 'DispatchedEmailCount'
        #    ATTRIBUTE_TYPE_SMS_DISPATCHED_COUNT = 'DispatchedTextMessageCount'
        #        ATTRIBUTE_TYPE_SMS_SENT_COUNT = 'SentTextMessageCount'
        #            ATTRIBUTE_TYPE_SUBSCRIPTION_COUNT = 'SubscriptionCount'

        dao = NWS_DAO()
        url = "/notification/v1/person/%s" % (person.person_id)
        headers = {"Content-Type": "application/json"}
        if self.override_user is not None:
            headers['X_UW_ACT_AS'] = self.override_user

        put_response = dao.putURL(url, headers, Serializer().serialize(person))

        #Http response code 204 No Content:
        #The server has fulfilled the request but does not need to return an entity-body
        if put_response.status != 204:
            raise DataFailureException(url, put_response.status, put_response.data)

        return put_response.status
Beispiel #28
0
    def _get_resource_url(self, url, auto_page, data_key):
        """
        Canvas GET method on a full url. Return representation of the requested resource,
        chasing pagination links to coalesce resources if indicated.
        """
        response = Canvas_DAO().getURL(url, {"Accept": "application/json"})

        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        data = json.loads(response.data)

        self.next_page_url = self._next_page(response)
        if auto_page and self.next_page_url:
            if isinstance(data, list):
                data.extend(
                    self._get_resource_url(self.next_page_url, True, data_key))
            elif isinstance(data, dict) and data_key is not None:
                data[data_key].extend(
                    self._get_resource_url(self.next_page_url, True,
                                           data_key)[data_key])

        return data
Beispiel #29
0
    def get_books_by_quarter_sln(self, quarter, sln):
        dao = Book_DAO()
        sln_string = self._get_sln_string(sln)
        url = "/myuw/myuw_mobile_beta.ubs?quarter=%s&%s" % (
            quarter,
            sln_string,
        )
        response = dao.getURL(url, {"Accept": "application/json"})
        if response.status != 200:
            raise DataFailureException(url, response.status, response.data)

        data = json.loads(response.data)

        books = []

        sln_data = data[str(sln)]

        if len(sln_data) > 0:
            for book_data in sln_data:
                book = Book()
                book.isbn = book_data["isbn"]
                book.title = book_data["title"]
                book.price = book_data["price"]
                book.used_price = book_data["used_price"]
                book.is_required = book_data["required"]
                book.notes = book_data["notes"]
                book.cover_image_url = book_data["cover_image"]
                book.authors = []

                for author_data in book_data["authors"]:
                    author = BookAuthor()
                    author.name = author_data["name"]
                    book.authors.append(author)

                books.append(book)
        return books
Beispiel #30
0
    def create_new_subscription(self, subscription):
        """
        Create a new subscription

        :param subscription:
        is the new subscription that the client wants to create
        """
        #Validate input
        if subscription.get_subscription_id() is not None:
            self._validate_uuid(subscription.get_subscription_id())

        if subscription.get_endpoint() is not None:
            if subscription.get_endpoint().user:
                self._validate_subscriber_id(subscription.endpoint.user)

            if subscription.get_endpoint().get_endpoint_id() is not None:
                self._validate_uuid(subscription.endpoint.get_endpoint_id())

        if subscription.get_channel() is not None:
            self._validate_uuid(subscription.channel.get_channel_id())

        #Create new subscription
        dao = NWS_DAO()
        url = "/notification/v1/subscription"
        headers = {"Content-Type": "application/json"}
        if self.override_user is not None:
            headers['X_UW_ACT_AS'] = self.override_user

        post_response = dao.postURL(url, headers, Serializer().serialize(subscription))

        #HTTP Status Code 201 Created: The request has been fulfilled and resulted
        #in a new resource being created
        if post_response.status != 201:
            raise DataFailureException(url, post_response.status, post_response.data)

        return post_response.status