Ejemplo n.º 1
0
 def _validate_entity_fields(self, entity_type, fields):
     self._validate_entity_type(entity_type)
     if fields is not None:
         valid_fields = set(self._schema[entity_type].keys())
         for field in fields:
             try:
                 field2, entity_type2, field3 = field.split(".", 2)
                 self._validate_entity_fields(entity_type2, [field3])
             except ValueError:
                 if field not in valid_fields and field not in ("type",
                                                                "id"):
                     raise ShotgunError(
                         "%s is not a valid field for entity %s" %
                         (field, entity_type))
Ejemplo n.º 2
0
 def _row_matches_filter(self, entity_type, row, filter):
     try:
         field, operator, rval = filter
     except ValueError:
         raise ShotgunError(
             "Filters must be in the form [lval, operator, rval]")
     lval = self._get_field_from_row(entity_type, row, field)
     field_type = self._get_field_type(entity_type, field)
     # if we're operating on an entity, we'll need to grab the name from the lval's row
     if field_type == "entity":
         lval_row = self._db[lval["type"]][lval["id"]]
         if "name" in lval_row:
             lval["name"] = lval_row["name"]
         elif "code" in lval_row:
             lval["name"] = lval_row["code"]
     return self._compare(field_type, lval, operator, rval)
Ejemplo n.º 3
0
 def batch(self, requests):
     results = []
     for request in requests:
         if request["request_type"] == "create":
             results.append(
                 self.create(request["entity_type"], request["data"]))
         elif request["request_type"] == "update":
             # note: Shotgun.update returns a list of a single item
             results.append(
                 self.update(request["entity_type"], request["entity_id"],
                             request["data"])[0])
         elif request["request_type"] == "delete":
             results.append(
                 self.delete(request["entity_type"], request["entity_id"]))
         else:
             raise ShotgunError("Invalid request type %s in request %s" %
                                (request["request_type"], request))
     return results
Ejemplo n.º 4
0
 def _row_matches_filters(self, entity_type, row, filters, filter_operator,
                          retired_only):
     if retired_only and not row["__retired"] or not retired_only and row[
             "__retired"]:
         # ignore retired rows unless the retired_only flag is set
         # ignore live rows if the retired_only flag is set
         return False
     elif filter_operator in ("all", None):
         return all(
             self._row_matches_filter(entity_type, row, filter)
             for filter in filters)
     elif filter_operator == "any":
         return any(
             self._row_matches_filter(entity_type, row, filter)
             for filter in filters)
     else:
         raise ShotgunError("%s is not a valid filter operator" %
                            filter_operator)
Ejemplo n.º 5
0
    def _validate_entity_data(self, entity_type, data):
        if "id" in data or "type" in data:
            raise ShotgunError("Can't set id or type on create or update")

        self._validate_entity_fields(entity_type, data.keys())

        for field, item in data.items():
            field_info = self._schema[entity_type][field]

            if field_info["data_type"]["value"] == "multi_entity":
                if not isinstance(item, list):
                    raise ShotgunError(
                        "%s.%s is of type multi_entity, but data %s is not a list"
                        % (entity_type, field, item))
                elif item and any(not isinstance(sub_item, dict)
                                  for sub_item in item):
                    raise ShotgunError(
                        "%s.%s is of type multi_entity, but data %s contains a non-dictionary"
                        % (entity_type, field, item))
                elif item and any(
                        "id" not in sub_item or "type" not in sub_item
                        for sub_item in item):
                    raise ShotgunError(
                        "%s.%s is of type multi-entity, but an item in data %s does not contain 'type' and 'id'"
                        % (entity_type, field, item))
                elif item and any(
                        sub_item["type"] not in field_info["properties"]
                    ["valid_types"]["value"] for sub_item in item):
                    raise ShotgunError(
                        "%s.%s is of multi-type entity, but an item in data %s has an invalid type (expected one of %s)"
                        % (entity_type, field, item,
                           field_info["properties"]["valid_types"]["value"]))

            elif field_info["data_type"]["value"] == "entity":
                if not isinstance(item, dict):
                    raise ShotgunError(
                        "%s.%s is of type entity, but data %s is not a dictionary"
                        % (entity_type, field, item))
                elif "id" not in item or "type" not in item:
                    raise ShotgunError(
                        "%s.%s is of type entity, but data %s does not contain 'type' and 'id'"
                        % (entity_type, field, item))
                elif item["type"] not in field_info["properties"][
                        "valid_types"]["value"]:
                    raise ShotgunError(
                        "%s.%s is of type entity, but data %s has an invalid type (expected one of %s)"
                        % (entity_type, field, item,
                           field_info["properties"]["valid_types"]["value"]))

            else:
                try:
                    sg_type = field_info["data_type"]["value"]
                    python_type = {
                        "number": int,
                        "float": float,
                        "checkbox": bool,
                        "text": basestring,
                        "date": datetime.date,
                        "date_time": datetime.datetime,
                        "url": dict
                    }[sg_type]
                except KeyError:
                    raise ShotgunError(
                        "Handling for Shotgun type %s is not implemented" %
                        sg_type)

                if not isinstance(item, python_type):
                    raise ShotgunError(
                        "%s.%s is of type %s, but data %s is not of type %s" %
                        (entity_type, field, type(item), sg_type, python_type))
Ejemplo n.º 6
0
 def _validate_entity_type(self, entity_type):
     if entity_type not in self._schema:
         raise ShotgunError("%s is not a valid entity" % entity_type)
Ejemplo n.º 7
0
 def _validate_entity_exists(self, entity_type, entity_id):
     if entity_id not in self._db[entity_type]:
         raise ShotgunError("No entity of type %s exists with id %s" %
                            (entity_type, entity_id))
Ejemplo n.º 8
0
    def _compare(self, field_type, lval, operator, rval):
        if field_type == "checkbox":
            if operator == "is":
                return lval == rval
            elif operator == "is_not":
                return lval != rval
        elif field_type in ("float", "number", "date", "date_time"):
            if operator == "is":
                return lval == rval
            elif operator == "is_not":
                return lval != rval
            elif operator == "less_than":
                return lval < rval
            elif operator == "greater_than":
                return lval > rval
            elif operator == "between":
                return lval >= rval[0] and lval <= rval[1]
            elif operator == "not_between":
                return lval < rval[0] or lval > rval[1]
            elif operator == "in":
                return lval in rval
        elif field_type == "text":
            if operator == "is":
                return lval == rval
            elif operator == "is_not":
                return lval != rval
            elif operator == "contains":
                return lval in rval
            elif operator == "not_contains":
                return lval not in rval
            elif operator == "starts_with":
                return lval.startswith(rval)
            elif operator == "ends_with":
                return lval.endswith(rval)
        elif field_type == "entity":
            if operator == "is":
                return lval["type"] == rval["type"] and lval["id"] == rval["id"]
            elif operator == "is_not":
                return lval["type"] != rval["type"] or lval["id"] != rval["id"]
            elif operator == "in":
                return all((lval["type"] == sub_rval["type"]
                            and lval["id"] == sub_rval["id"])
                           for sub_rval in rval)
            elif operator == "type_is":
                return lval["type"] == rval
            elif operator == "type_is_not":
                return lval["type"] != rval
            elif operator == "name_contains":
                return rval in lval["name"]
            elif operator == "name_not_contains":
                return rval not in lval["name"]
            elif operator == "name_starts_with":
                return lval["name"].startswith(rval)
            elif operator == "name_ends_with":
                return lval["name"].endswith(rval)
        elif field_type == "multi_entity":
            if operator == "is":
                return rval["id"] in (sub_lval["id"] for sub_lval in lval)
            elif operator == "is_not":
                return rval["id"] not in (sub_lval["id"] for sub_lval in lval)

        raise ShotgunError("The %s operator is not supported on the %s type" %
                           (operator, field_type))