File: bucket.py

package info (click to toggle)
python-b2sdk 2.8.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,020 kB
  • sloc: python: 30,902; sh: 13; makefile: 8
file content (170 lines) | stat: -rw-r--r-- 6,290 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
######################################################################
#
# File: b2sdk/v2/bucket.py
#
# Copyright 2021 Backblaze Inc. All Rights Reserved.
#
# License https://www.backblaze.com/using_b2_code.html
#
######################################################################
from __future__ import annotations

import typing

from b2sdk import _v3 as v3
from b2sdk._v3.exception import BucketIdNotFound as v3BucketIdNotFound
from b2sdk.v2._compat import _file_infos_rename
from b2sdk._internal.http_constants import LIST_FILE_NAMES_MAX_LIMIT
from .exception import BucketIdNotFound
from .file_version import FileVersionFactory

if typing.TYPE_CHECKING:
    from b2sdk._internal.utils import Sha1HexDigest
    from b2sdk._internal.filter import Filter
    from .file_version import FileVersion


# Overridden to raise old style BucketIdNotFound exception
class Bucket(v3.Bucket):
    FILE_VERSION_FACTORY_CLASS = staticmethod(FileVersionFactory)

    def get_fresh_state(self) -> Bucket:
        try:
            return super().get_fresh_state()
        except v3BucketIdNotFound as e:
            raise BucketIdNotFound(e.bucket_id)

    @_file_infos_rename
    def upload_bytes(
        self,
        data_bytes,
        file_name,
        content_type=None,
        file_info: dict | None = None,
        progress_listener=None,
        encryption: v3.EncryptionSetting | None = None,
        file_retention: v3.FileRetentionSetting | None = None,
        legal_hold: v3.LegalHold | None = None,
        large_file_sha1: Sha1HexDigest | None = None,
        custom_upload_timestamp: int | None = None,
        cache_control: str | None = None,
        *args,
        **kwargs,
    ):
        return super().upload_bytes(
            data_bytes,
            file_name,
            content_type,
            file_info,
            progress_listener,
            encryption,
            file_retention,
            legal_hold,
            large_file_sha1,
            custom_upload_timestamp,
            cache_control,
            *args,
            **kwargs,
        )

    @_file_infos_rename
    def upload_local_file(
        self,
        local_file,
        file_name,
        content_type=None,
        file_info: dict | None = None,
        sha1_sum=None,
        min_part_size=None,
        progress_listener=None,
        encryption: v3.EncryptionSetting | None = None,
        file_retention: v3.FileRetentionSetting | None = None,
        legal_hold: v3.LegalHold | None = None,
        upload_mode: v3.UploadMode = v3.UploadMode.FULL,
        custom_upload_timestamp: int | None = None,
        cache_control: str | None = None,
        *args,
        **kwargs,
    ):
        return super().upload_local_file(
            local_file,
            file_name,
            content_type,
            file_info,
            sha1_sum,
            min_part_size,
            progress_listener,
            encryption,
            file_retention,
            legal_hold,
            upload_mode,
            custom_upload_timestamp,
            cache_control,
            *args,
            **kwargs,
        )

    def ls(
        self,
        folder_to_list: str = '',
        latest_only: bool = True,
        recursive: bool = False,
        fetch_count: int | None = LIST_FILE_NAMES_MAX_LIMIT,
        with_wildcard: bool = False,
        filters: typing.Sequence[Filter] = (),
        folder_to_list_can_be_a_file: bool = False,
        **kwargs,
    ) -> typing.Iterable[tuple[FileVersion, str]]:
        """
        Pretend that folders exist and yields the information about the files in a folder.

        B2 has a flat namespace for the files in a bucket, but there is a convention
        of using "/" as if there were folders.  This method searches through the
        flat namespace to find the files and "folders" that live within a given
        folder.

        When the `recursive` flag is set, lists all of the files in the given
        folder, and all of its sub-folders.

        :param folder_to_list: the name of the folder to list; must not start with "/".
                               Empty string means top-level folder
        :param latest_only: when ``False`` returns info about all versions of a file,
                            when ``True``, just returns info about the most recent versions
        :param recursive: if ``True``, list folders recursively
        :param fetch_count: how many entries to list per API call or ``None`` to use the default. Acceptable values: 1 - 10000
        :param with_wildcard: Accepts "*", "?", "[]" and "[!]" in folder_to_list, similarly to what shell does.
                              As of 1.19.0 it can only be enabled when recursive is also enabled.
                              Also, in this mode, folder_to_list is considered to be a filename or a pattern.
        :param filters: list of filters to apply to the files returned by the server.
        :param folder_to_list_can_be_a_file: if ``True``, folder_to_list can be a file, not just a folder
                                             This enabled default behavior of b2sdk.v3.Bucket.ls, in which for all
                                             paths that do not end with '/', first we try to check if file with this
                                             exact name exists, and only if it does not then we try to list files with
                                             this prefix.
        :rtype: generator[tuple[b2sdk.v2.FileVersion, str]]
        :returns: generator of (file_version, folder_name) tuples

        .. note::
            In case of `recursive=True`, folder_name is not returned.
        """
        if (
            not folder_to_list_can_be_a_file
            and folder_to_list
            and not folder_to_list.endswith('/')
            and not with_wildcard
        ):
            folder_to_list += '/'
        yield from super().ls(
            path=folder_to_list,
            latest_only=latest_only,
            recursive=recursive,
            fetch_count=fetch_count,
            with_wildcard=with_wildcard,
            filters=filters,
            **kwargs,
        )


# Overridden to use old style Bucket
class BucketFactory(v3.BucketFactory):
    BUCKET_CLASS = staticmethod(Bucket)