コード例 #1
0
def assign_role(rolename, entity, obj=None):
    """
    Assign a role to a user or a group.

    Args:
        rolename (str): Name of the role to assign.
        entity (django.contrib.auth.User or pulpcore.app.models.Group): Entity to gain the role.
        obj (Optional[pulpcore.app.models.BaseModel]): Object the role permisssions are to be
            asserted on.
    """
    try:
        role = Role.objects.get(name=rolename)
    except Role.DoesNotExist:
        raise BadRequest(_("The role '{}' does not exist.").format(rolename))
    if obj is not None:
        ctype = ContentType.objects.get_for_model(obj,
                                                  for_concrete_model=False)
        if not role.permissions.filter(content_type__pk=ctype.id).exists():
            raise BadRequest(
                _("The role '{}' does not carry any permission for that object."
                  ).format(rolename))
    if isinstance(entity, Group):
        GroupRole.objects.create(role=role, group=entity, content_object=obj)
    else:
        UserRole.objects.create(role=role, user=entity, content_object=obj)
コード例 #2
0
def get_context(request):
    from cvat.apps.organizations.models import Organization, Membership

    IAM_ROLES = {
        role: priority
        for priority, role in enumerate(settings.IAM_ROLES)
    }
    groups = list(request.user.groups.filter(name__in=list(IAM_ROLES.keys())))
    groups.sort(key=lambda group: IAM_ROLES[group.name])

    organization = None
    membership = None
    try:
        org_slug = request.GET.get('org')
        org_id = request.GET.get('org_id')
        org_header = request.headers.get('X-Organization')

        if org_id != None and (org_slug != None or org_header != None):
            raise BadRequest(
                'You cannot specify "org_id" query parameter with ' +
                '"org" query parameter or "X-Organization" HTTP header at the same time.'
            )
        if org_slug != None and org_header != None and org_slug != org_header:
            raise BadRequest(
                'You cannot specify "org" query parameter and ' +
                '"X-Organization" HTTP header with different values.')
        org_slug = org_slug if org_slug != None else org_header

        org_filter = None
        if org_slug:
            organization = Organization.objects.get(slug=org_slug)
            membership = Membership.objects.filter(organization=organization,
                                                   user=request.user).first()
            org_filter = {'organization': organization.id}
        elif org_id:
            organization = Organization.objects.get(id=int(org_id))
            membership = Membership.objects.filter(organization=organization,
                                                   user=request.user).first()
            org_filter = {'organization': organization.id}
        elif org_slug is not None:
            org_filter = {'organization': None}
    except Organization.DoesNotExist:
        raise BadRequest(f'{org_slug or org_id} organization does not exist.')

    if membership and not membership.is_active:
        membership = None

    context = {
        "privilege": groups[0] if groups else None,
        "membership": membership,
        "organization": organization,
        "visibility": org_filter,
    }

    return context
コード例 #3
0
def delete_object(request, pid, ttid):
    object = Objects_Product.objects.get(pk=ttid)
    product = get_object_or_404(Product, id=pid)
    if object.product != product:
        raise BadRequest(
            f'Product {pid} does not fit to product of Object {object.product.id}'
        )

    if request.method == 'POST':
        tform = ObjectSettingsForm(request.POST, instance=object)
        object.delete()
        messages.add_message(request,
                             messages.SUCCESS,
                             'Tracked Product Files Deleted.',
                             extra_tags='alert-success')
        return HttpResponseRedirect(reverse('view_objects', args=(pid, )))
    else:
        tform = DeleteObjectsSettingsForm(instance=object)

    product_tab = Product_Tab(pid,
                              title="Delete Product Tool Configuration",
                              tab="settings")
    return render(request, 'dojo/delete_object.html', {
        'tform': tform,
        'product_tab': product_tab
    })
コード例 #4
0
ファイル: views.py プロジェクト: edx/edx-platform
    def post(self, request, course_id):
        """
        Handles a file upload.
        """
        thread_key = request.POST.get("thread_key", "root")
        unique_file_name = f"{course_id}/{thread_key}/{uuid.uuid4()}"
        try:
            file_storage, stored_file_name = store_uploaded_file(
                request,
                "uploaded_file",
                cc_settings.ALLOWED_UPLOAD_FILE_TYPES,
                unique_file_name,
                max_file_size=cc_settings.MAX_UPLOAD_FILE_SIZE,
            )
        except ValueError as err:
            raise BadRequest("no `uploaded_file` was provided") from err

        file_absolute_url = file_storage.url(stored_file_name)

        # this is a no-op in production, but is required in development,
        # since the filesystem storage returns the path without a base_url
        file_absolute_url = request.build_absolute_uri(file_absolute_url)

        return Response(
            {"location": file_absolute_url},
            content_type="application/json",
        )
コード例 #5
0
def searchView(request):
    search_param = request.GET.get("q", None)
    try:
        tweets = Tweet.objects.filter(
            content__icontains=search_param).prefetch_related(
                Prefetch("comments",
                         queryset=Comment.objects.order_by("-date")),
                "comments__author__profile",
                "author__profile",
            )
        users = (get_user_model().objects.filter(
            Q(username__icontains=search_param)
            | Q(first_name__icontains=search_param)
            | Q(last_name__icontains=search_param)).select_related(
                "profile").annotate(Count(
                    "followers", distinct=True)).order_by("-followers__count"))
        if request.user.is_authenticated:
            like = Like.objects.filter(tweet=OuterRef("pk"), user=request.user)
            tweets = tweets.annotate(like_exists=Exists(like), )
            users = users.exclude(
                Q(id=request.user.id)
                | Q(followers__in=Follow.objects.filter(
                    follower=request.user)))
    except:
        raise BadRequest("Bad request for searching.")
    return render(
        request,
        "tweetApp/search_results.html",
        {
            "tweets": tweets[:6],
            "users": users[:10]
        },
    )
コード例 #6
0
def edit_tool_product(request, pid, ttid):
    product = get_object_or_404(Product, id=pid)
    tool_product = Tool_Product_Settings.objects.get(pk=ttid)
    if tool_product.product != product:
        raise BadRequest(
            f'Product {pid} does not fit to product of Tool_Product {tool_product.product.id}'
        )

    if request.method == 'POST':
        tform = ToolProductSettingsForm(request.POST, instance=tool_product)
        if tform.is_valid():
            tform.save()
            messages.add_message(
                request,
                messages.SUCCESS,
                'Tool Product Configuration Successfully Updated.',
                extra_tags='alert-success')
            return HttpResponseRedirect(
                reverse('all_tool_product', args=(pid, )))
    else:
        tform = ToolProductSettingsForm(instance=tool_product)

    product_tab = Product_Tab(pid,
                              title="Edit Product Tool Configuration",
                              tab="settings")
    return render(request, 'dojo/edit_tool_product.html', {
        'tform': tform,
        'product_tab': product_tab
    })
コード例 #7
0
ファイル: credits.py プロジェクト: Baljan/cafesys
def manual_refill(entered_code, by_user):
    with transaction.atomic():
        try:
            balance_code = BalanceCode.objects.get(
                code__exact=entered_code,
                used_by__isnull=True,
                used_at__isnull=True,
            )
        except BalanceCode.DoesNotExist:
            log.info(f'{by_user} found {entered_code} used or invalid')
            raise BadRequest("Ogiltig kod, missbruk loggas!")
        # log usage
        log.info(f'{by_user} found {entered_code} unused')

        # use code
        profile = by_user.profile
        if (balance_code.currency != profile.balance_currency):
            raise PermissionDenied("Valutorna matchar inte.")
        balance_code.used_by = by_user
        tz = pytz.timezone(settings.TIME_ZONE)
        balance_code.used_at = datetime.now(tz)
        balance_code.save()
        profile.balance += balance_code.value
        profile.save()

        group = balance_code.refill_series.add_to_group
        if group:
            group.user_set.add(by_user)
            log.info(
                f'{by_user} added themselves to group "{group.name}" through a BalanceCode'
            )

        log.info(
            f'{by_user} used {balance_code.id} successfully for {balance_code.valcur()}'
        )
コード例 #8
0
def remove_role(rolename, entity, obj=None):
    """
    Remove a role from a user or a group.

    Args:
        rolename (str): Name of the role to assign.
        entity (django.contrib.auth.User or pulpcore.app.models.Group): Entity to lose the role.
        obj (Optional[pulpcore.app.models.BaseModel]): Object the role permisssions are to be
            asserted on.
    """
    try:
        role = Role.objects.get(name=rolename)
    except Role.DoesNotExist:
        raise BadRequest(_("The role '{}' does not exist.").format(rolename))
    if isinstance(entity, Group):
        qs = GroupRole.objects.filter(role=role, group=entity)
    else:
        qs = UserRole.objects.filter(role=role, user=entity)
    if obj is None:
        qs = qs.filter(object_id=None)
    else:
        ctype = ContentType.objects.get_for_model(obj,
                                                  for_concrete_model=False)
        qs = qs.filter(content_type__pk=ctype.id, object_id=obj.pk)
    qs.delete()
コード例 #9
0
def detail(request, store_id=1, location=None):
    # Access store_id url parameter with 'store_id' variable
    # Access location url parameter with 'location' variable
    # Extract 'hours', 'lat' or 'lon' values appended to url as
    # e.g. ?hours=sunday&latitude=32.71&longitude=-117.16
    # 'hours' has value 'sunday' or '' if hours not in url
    # 'latitude' has value 32.71 or 0 if latitude not in url
    # 'longitude' has value -117.16 or 0 if longitude not in url
    hours = request.GET.get('hours', '')
    latitude = request.GET.get('latitude', 0)
    longitude = request.GET.get('longitude', 0)
    # Validation for hours variables
    if hours not in [
            '', 'sunday', 'monday', 'tuesday', 'wednesday', 'thursday',
            'friday', 'saturday'
    ]:
        raise Http404
    # Validation for latitude & longitude
    try:
        # latitude and longitude should be cast'able to float if numbers
        float(latitude)
        float(longitude)
    except ValueError:
        raise BadRequest(
            "Provided latitude or longitude can't be converted to float")
    # Validation if latitude in range
    if float(latitude) > 90 or float(latitude) < -90:
        raise Exception("Invalid latitude, min -90 and max 90")
    # Validation if longitude in range
    if float(longitude) > 180 or float(longitude) < -180:
        raise Exception("Invalid longitude, min -180 and max 180")
    # If latitude==90 and longitude==90, redirect to maps.google.com
    if float(latitude) == 90 or float(longitude) == 90:
        return HttpResponsePermanentRedirect("http://maps.google.com/")
    # Create fixed data structures to pass to template
    # data could equally come from database queries
    if store_id == 1:
        store = STORE_LIST[1]
    elif store_id == 2:
        store = STORE_LIST[2]
    elif store_id == 3:
        store = STORE_LIST[3]
    else:
        raise Http404
    store_amenities = ['WiFi', 'A/C']
    store_menu = ((0, ''), (1, 'Drinks'), (2, 'Food'))
    vals_for_template = {
        'store': store,
        'store_amenities': store_amenities,
        'store_menu': store_menu
    }
    return render(request, 'stores/detail.html', vals_for_template)
コード例 #10
0
    def get(self, request):
        product_id = request.GET.get('product_id', None)

        if not product_id:
            raise BadRequest("product_id - param required")

        try:
            product = Product.objects.get(id=product_id)
        except ObjectDoesNotExist as ex:
            raise NotFoundError("No product found with id - {}".format(product_id))

        serializer = self.serializer(product.category)

        return Response(data=serializer.data)
コード例 #11
0
ファイル: frame.py プロジェクト: dzenanz/miqa
    def download(self, request, pk=None, **kwargs):
        frame: Frame = self.get_object()

        if frame.storage_mode == StorageMode.LOCAL_PATH:
            if not frame.path.is_file():
                return HttpResponseServerError('File no longer exists.')

            fd = open(frame.raw_path, 'rb')
            resp = FileResponse(fd, filename=str(frame.frame_number))
            resp['Content-Length'] = frame.size
            return resp
        raise BadRequest(
            'This endpoint is only valid for local files on the server machine.'
        )
コード例 #12
0
 def perform_create(self, serializer):
     canteen_id = self.request.data.get("canteen")
     if not canteen_id:
         logger.error("Canteen ID missing in purchase creation request")
         raise BadRequest("Canteen ID missing in purchase creation request")
     try:
         canteen = Canteen.objects.get(pk=canteen_id)
         if not canteen.managers.filter(pk=self.request.user.pk).exists():
             logger.error(
                 f"User {self.request.user.id} attempted to create a purchase in someone else's canteen: {canteen_id}"
             )
             raise PermissionDenied()
         serializer.save(canteen=canteen)
     except ObjectDoesNotExist as e:
         logger.error(
             f"User {self.request.user.id} attempted to create a purchase in nonexistent canteen {canteen_id}"
         )
         raise NotFound() from e
コード例 #13
0
    def get(self, request, *args, **kwargs):
        canteen_id = kwargs.get("canteen_pk")
        year = request.query_params.get("year")
        if not year:
            raise BadRequest("Missing year in request's query parameters")

        canteen = self._get_canteen(canteen_id, request)
        purchases = Purchase.objects.filter(canteen=canteen, date__year=year)

        data = {}
        data["total"] = purchases.aggregate(total=Sum("price_ht"))["total"]
        bio_purchases = purchases.filter(
            Q(characteristics__contains=[Purchase.Characteristic.BIO])
            | Q(characteristics__contains=[
                Purchase.Characteristic.CONVERSION_BIO
            ])).distinct()
        data["bio"] = bio_purchases.aggregate(total=Sum("price_ht"))["total"]
        # the remaining stats should ignore any bio products
        purchases = purchases.exclude(
            Q(characteristics__contains=[Purchase.Characteristic.BIO])
            | Q(characteristics__contains=[
                Purchase.Characteristic.CONVERSION_BIO
            ]))
        sustainable_purchases = purchases.annotate(characteristics_len=Func(
            F("characteristics"), function="CARDINALITY"))
        sustainable_purchases = sustainable_purchases.filter(
            characteristics_len__gt=0)
        data["sustainable"] = sustainable_purchases.aggregate(
            total=Sum("price_ht"))["total"]
        hve_purchases = purchases.filter(
            characteristics__contains=[Purchase.Characteristic.HVE])
        data["hve"] = hve_purchases.aggregate(total=Sum("price_ht"))["total"]
        aoc_aop_igp_purchases = purchases.filter(
            Q(characteristics__contains=[Purchase.Characteristic.AOCAOP])
            | Q(characteristics__contains=[Purchase.Characteristic.IGP])
        ).distinct()
        data["aoc_aop_igp"] = aoc_aop_igp_purchases.aggregate(
            total=Sum("price_ht"))["total"]
        rouge_purchases = purchases.filter(
            characteristics__contains=[Purchase.Characteristic.LABEL_ROUGE])
        data["rouge"] = rouge_purchases.aggregate(
            total=Sum("price_ht"))["total"]

        return Response(PurchaseSummarySerializer(data).data)
コード例 #14
0
 def save(self, *args, **kwargs):
     """Save recipe's data."""
     user = kwargs.get('user')
     try:
         with transaction.atomic():
             recipe = super().save(commit=False)
             if recipe.author_id is None:
                 recipe.author = user
             slug = slugify(self.cleaned_data['title'])
             if Recipe.objects.filter(slug=slug).exists():
                 slug = uuid4()
             recipe.slug = slug
             recipe.save()
             self.delete_compositions(recipe)
             self.create_compositions(recipe)
             self.save_m2m()
     except IntegrityError as save_error:
         raise BadRequest('Error while saving') from save_error
     return recipe
コード例 #15
0
ファイル: filters.py プロジェクト: pennlabs/penn-courses
def attribute_filter(queryset, attr_query):
    """
    :param queryset: initial Course object queryset
    :param attr_query: the attribute query string; see the description
        of the attributes query param below for an explanation of the
        syntax/semantics of this filter
    :return: filtered queryset
    """
    if not attr_query:
        return queryset

    expr = None
    try:
        expr = attribute_query_parser.parse(attr_query)
    except UnexpectedInput as e:
        raise BadRequest(e)

    def lift_demorgan(t):
        """
        Optimization: Given a Lark parse tree t, tries to
        convert `*` to leaf-level `|` operators as much as possible,
        using DeMorgan's laws (for query performance).
        """
        if t.data == "attribute":
            return t
        t.children = [lift_demorgan(c) for c in t.children]
        if t.data == "conjunction":
            c1, c2 = t.children
            if c1.data == "negation" and c2.data == "negation":
                (c1c, ) = c1.children
                (c2c, ) = c2.children
                return Tree(
                    data="negation",
                    children=[Tree(data="disjunction", children=[c1c, c2c])],
                )
        return t

    expr = lift_demorgan(expr)

    _, query = AttributeQueryTreeToCourseQ().transform(expr)

    return queryset.filter(query).distinct()
コード例 #16
0
    def post(self, request, playlist_id, format=None):
        playlist = get_object_or_404(DynamicPlaylist, id=playlist_id)

        if request.data["trackToPersist"]:
            playlist.persist_track(request.data["trackToPersist"])

        for i in range(5):
            next_user_track: UserTrack = playlist.find_next_track()
            if not next_user_track:
                raise BadRequest('No active user in playlist')

            next_track_url = UriParser(next_user_track.track_uri.uri).url
            if response_content := fetch_media(next_track_url):
                response_content["id"] = next_user_track.id
                return Response(response_content)
            else:
                next_user_track.track_uri.unavailable = True
                next_user_track.track_uri.save()
                logger.warning("Tagged TrackUri '%s' as unavailable because it couldn't be fetched",
                               next_user_track.track_uri.uri)
コード例 #17
0
ファイル: views.py プロジェクト: hds2g/RememberME
def remember_ok(request):
    user = request.user
    # get remember.

    if request.method == "POST" and request.is_ajax:
        id = request.POST.get("id")
        print(id)
        remember = Remember.objects.get(pk=id)
    # post_id = request.GET.get("data")
    # print("data")
    # print(post_id)

    if user == remember.user:

        for s in Remember.REMEMBER_STAGE:  #
            if remember.stage == s[0]:
                print(remember.stage, s[0], type(s))
                update_idx = Remember.REMEMBER_STAGE.index(s) + 1

                # if already max stage, just let it be
                if update_idx >= len(Remember.REMEMBER_STAGE):
                    break

                remember.stage = Remember.REMEMBER_STAGE[update_idx][0]
                # print(remember.stage)

                break
        # Update showing_date
        for s in Remember.REMEMBER_STAGE:
            if remember.stage == s[0]:
                print(f"updated showing date : {remember.stage}")
                remember.showing_date = datetime.today() + timedelta(
                    days=int(remember.stage))

        remember.save()
        print("remember_ok: ok")
        return HttpResponse("ok :)")

    else:
        # bad request
        return BadRequest("Invalid request.")
コード例 #18
0
    def post(self, request, username=None):
        """only works as POST request"""
        # first check if this server is on our shitlist
        raise_is_blocked_user_agent(request)

        # make sure the user's inbox even exists
        if username:
            get_object_or_404(models.User, localname=username, is_active=True)

        # is it valid json? does it at least vaguely resemble an activity?
        try:
            activity_json = json.loads(request.body)
        except json.decoder.JSONDecodeError:
            raise BadRequest()

        # let's be extra sure we didn't block this domain
        raise_is_blocked_activity(activity_json)

        if (
            not "object" in activity_json
            or not "type" in activity_json
            or not activity_json["type"] in activitypub.activity_objects
        ):
            raise Http404()

        # verify the signature
        if not has_valid_signature(request, activity_json):
            if activity_json["type"] == "Delete":
                # Pretend that unauth'd deletes succeed. Auth may be failing
                # because the resource or owner of the resource might have
                # been deleted.
                return HttpResponse()
            return HttpResponse(status=401)

        activity_task.delay(activity_json)
        return HttpResponse()
コード例 #19
0
ファイル: cron.py プロジェクト: wagnerand/addons-server
def update_blog_posts():
    """Update the blog post cache."""
    response = requests.get(settings.DEVELOPER_BLOG_URL, timeout=10)
    try:
        items = response.json()
    except requests.exceptions.JSONDecodeError:
        items = None
    if not (response.status_code == 200 and items and len(items) > 1):
        raise BadRequest('Developer blog JSON import failed.')

    latest_five = items[:5]
    latest_five_ids = [item['id'] for item in latest_five]
    BlogPost.objects.exclude(post_id__in=latest_five_ids).delete()
    existing_blogposts = {
        post.post_id: post
        for post in BlogPost.objects.all()
    }

    for item in latest_five:
        existing = existing_blogposts.get(item['id'])
        data = {
            'title':
            item['title']['rendered'],
            'date_posted':
            datetime.strptime(item['date'], '%Y-%m-%dT%H:%M:%S'),
            'date_modified':
            datetime.strptime(item['modified'], '%Y-%m-%dT%H:%M:%S'),
            'permalink':
            item['link'],
        }
        if not existing:
            BlogPost.objects.create(post_id=item['id'], **data)
        elif existing.date_modified != data['date_modified']:
            existing.update(**data)

    log.info(f'Adding {len(latest_five)} blog posts.')
コード例 #20
0
ファイル: views.py プロジェクト: hds2g/RememberME
def remember_ng(request):
    user = request.user

    if request.method == "POST" and request.is_ajax:
        id = request.POST.get("id")
        print(id)
        remember = Remember.objects.get(pk=id)
    # post_id = request.GET.get("data")
    # print("data")
    # print(post_id)
    # get remember.
    remember = Remember.objects.get(pk=id)

    if user == remember.user:
        remember.stage = Remember.STAGE_1WEEK
        remember.showing_date = datetime.today() + timedelta(days=7)

        remember.save()

        return HttpResponse("ok :)")

    else:
        # bad request
        return BadRequest("Invalid request.")
コード例 #21
0
ファイル: views.py プロジェクト: uktrade/data-workspace
 def dispatch(self, request, *args, **kwargs):
     if "file" not in self.request.GET:
         raise BadRequest("Expected a `file` parameter")
     return super().dispatch(request, *args, **kwargs)
コード例 #22
0
def bad_request(request):
    raise BadRequest()
コード例 #23
0
def _validate_limit(integer_string: str, max_value: int):
    """ ensures the requested number of results doesn't exceed the maximal number allowed """
    num = int(integer_string)
    if num <= 0 or num > max_value:
        raise BadRequest(f'limit must be between 1 and {max_value}')
    return num
コード例 #24
0
ファイル: views.py プロジェクト: mastermind711/DJANGO
def raises400_bad_request(request):
    raise BadRequest('Malformed request syntax')
コード例 #25
0
ファイル: views.py プロジェクト: uktrade/data-workspace
 def dispatch(self, request, *args, **kwargs):
     for param in self.required_parameters:
         if param not in self.request.GET:
             raise BadRequest(f"Expected a `{param}` parameter")
     return super().dispatch(request, *args, **kwargs)
コード例 #26
0
    def get_base_ranges(self, header):
        """
        Parses a range header into a list of two-tuples (start, stop) where
        `start` is the starting byte of the range (inclusive) and
        `stop` is the ending byte position of the range (exclusive).

        Args:
            header (str): The HTTP_RANGE request header.

        Returns:
            (start, stop) tuple or (None, None) if the value of the header is not syntatically valid.
        
        Specs https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range
        Syntax
            Range: <unit>=<range-start>-
            Range: <unit>=<range-start>-<range-end>
            Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>
            Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
            Range: <unit>=-<suffix-length>

        Directives
            <unit>
            The unit in which ranges are specified. This is usually bytes.

            <range-start>
            An integer in the given unit indicating the beginning of the request range.

            <range-end>
            An integer in the given unit indicating the end of the requested range. This value is optional and, if omitted, the end of the document is taken as the end of the range.

            <suffix-length>
            An integer in the given unit indicating the number of units at the end of the file to return.
        """

        if not header or '=' not in header:
            return None, None

        start = None
        stop = None
        units, range_ = header.split('=', 1)
        units = units.strip().lower()

        if units != 'bytes':
            raise BadRequest('Only bytes ranges are supported')

        # We don't handle multipart byteranges, just the first one
        val = range_.split(',')[0].strip()
        if '-' not in val:
            raise BadRequest(
                f'HTTP_RANGE header is bad defined (missing "-"): {header}')

        start, stop = val.split('-', 1)
        if start != '' and not start.isnumeric():
            raise BadRequest(
                f'HTTP_RANGE header is bad defined (start is not numeric): {header}'
            )
        if stop != '' and not stop.isnumeric():
            raise BadRequest(
                f'HTTP_RANGE header is bad defined (stop is not numeric): {header}'
            )

        stop = 0 if stop == '' else int(stop)
        if start == '' and stop > 0:  # corner case
            # start must be (FILE_SIZE - stop) but we don't know the file size
            # stop must be -> FILE_SIZE but we don't know the file size
            # Define start as negative as a flag
            start = -int(stop)
            stop = 0
        else:
            start = 0 if start == '' else int(start)

        return start, stop