69 lines
2.3 KiB
Python
69 lines
2.3 KiB
Python
import os
|
|
|
|
from b2.api import B2Api
|
|
|
|
from b2mirror.base import Provider, Reciever
|
|
from b2mirror.common import Result, results_ok
|
|
|
|
class B2Provider(Provider):
|
|
"""
|
|
Iterates files in bucket
|
|
"""
|
|
|
|
def __init__(self, accountId, appKey, bucketId, bucketBasePath):
|
|
super(B2Provider, self).__init__()
|
|
raise NotImplemented()
|
|
|
|
|
|
class B2Reciever(Reciever):
|
|
|
|
max_chunk_size = 256*1024
|
|
|
|
def __init__(self, bucket, path, account_id, app_key, workers=10):
|
|
super(B2Reciever, self).__init__()
|
|
self.bucket_name = bucket
|
|
self.path = path
|
|
self.account_id = account_id
|
|
self.app_key = app_key
|
|
|
|
self.api = B2Api(max_upload_workers=workers)
|
|
self.api.authorize_account('production', self.account_id, self.app_key)
|
|
self.bucket = self.api.get_bucket_by_name(self.bucket_name)
|
|
|
|
def put_file(self, file_info, purge_historics=False):
|
|
dest_path = os.path.join(self.path, file_info.rel_path).lstrip('/')
|
|
upload_result = self.bucket.upload_local_file(
|
|
file_info.abs_path,
|
|
dest_path
|
|
)
|
|
|
|
if purge_historics:
|
|
self.delete_by_path(dest_path, skip=1)
|
|
|
|
return Result.ok
|
|
|
|
def purge_file(self, file_path):
|
|
"""
|
|
Remove a file and all historical copies from the bucket
|
|
:param file_path: File path relative to the source tree to delete. This should NOT include self.path
|
|
"""
|
|
dest_path = os.path.join(self.path, file_path).lstrip('/')
|
|
self.delete_by_path(dest_path)
|
|
|
|
def delete_by_path(self, file_path, skip=0, max_entries=100):
|
|
"""
|
|
List all versions of a file and delete some or all of them
|
|
:param file_path: Bucket path to delete
|
|
:param skip: How many files to skip before starting deletion. 5 means keep 5 historical copies. Using a value
|
|
of 0 will delete a file and all it's revisions
|
|
:param max_entries:
|
|
"""
|
|
for f in self.bucket.list_file_versions(start_filename=file_path, max_entries=max_entries)["files"]:
|
|
if f["fileName"] == file_path:
|
|
if skip == 0:
|
|
self.api.delete_file_version(f["fileId"], f["fileName"])
|
|
else:
|
|
skip-=1
|
|
else:
|
|
return
|