# AUTOGENERATED! DO NOT EDIT! File to edit: notebooks/20_uploading-your-own-deep-zoom-images.ipynb (unless otherwise specified).

__all__ = ['DeepZoomBucket', 'PREFIX', 'ROOTDIR', 'VIEWERSDIR']

# Cell

import pyvips
import b2sdk.v1 as b2
import time
import sys
import os
import re
from IPython.display import HTML
import textwrap


# CONSTANTS
PREFIX = 'dzp_'
ROOTDIR = 'deepzoom'
VIEWERSDIR = 'viewers'

def _dzp_save(fname):
    '''Create local dzp_folder and use pyvips to convert image file *fname* to deepzoom pyramid. '''

    name, ext = os.path.splitext(os.path.basename(fname))
    dzp_folder = os.path.join('.', ROOTDIR, f'{PREFIX}{name}')
    dzi_fname = os.path.join('.', ROOTDIR, f'{PREFIX}{name}', f'{name}.dzi')
    dzi_base = os.path.join('.', ROOTDIR, f'{PREFIX}{name}', f'{name}')

    os.makedirs(dzp_folder, exist_ok=True)

    print('CREATING DEEPZOOM IMAGE TILES...')
    if not os.path.exists(dzi_fname):
        v_img = pyvips.Image.new_from_file(fname)
        v_img.dzsave(dzi_base)
    else:
        print(f'Skipping local deepzoom creation for: {fname}\n(No need to overwrite already existing tiles)')

    return name


def _connect_b2_bucket(application_key_id, application_key, bucket_name):
    '''Creates upload connection to your Backblaze b2 bucket.'''

    info = b2.InMemoryAccountInfo()
    b2_api = b2.B2Api(info)
    b2_api.authorize_account("production", application_key_id, application_key)

    bucket = b2_api.get_bucket_by_name(bucket_name)

    base_url = bucket.get_download_url('')

    return b2_api, base_url



def _upload(b2_api, bucket_name):
    '''Upload newly created files in local directory './deepzoom/' to b2 bucket.'''

    source = os.path.join('.', ROOTDIR)
    destination = f'b2://{bucket_name}/{ROOTDIR}'

    source = b2.parse_sync_folder(source, b2_api)
    destination = b2.parse_sync_folder(destination, b2_api)

    policies_manager = b2.ScanPoliciesManager(exclude_all_symlinks=True)

    synchronizer = b2.Synchronizer(
            max_workers=10,
            policies_manager=policies_manager,
            dry_run=False,
            allow_empty_source=True,
        )

    no_progress = False

    # need to run this to actually synchronize

    print('SYNC LOCAL FOLDER WITH CLOUD BUCKET...')

    with b2.SyncReport(sys.stdout, no_progress) as reporter:
            synchronizer.sync_folders(
                source_folder=source,
                dest_folder=destination,
                now_millis=int(round(time.time() * 1000)),
                reporter=reporter,
            )
    print('')


def _dzp_thumbnail(fname, tn_height=1000):
    '''Creates thumbnail file in dzp_directory'''

    # create directory if needed
    name, ext = os.path.splitext(os.path.basename(fname))
    dzp_fname = os.path.join('.', ROOTDIR, f'{PREFIX}{name}')
    os.makedirs(dzp_fname, exist_ok=True)

    # construct standard thumbnail filename
    thumb_fname = os.path.join('.', ROOTDIR, f'{PREFIX}{name}', f'tn_{name}.png')

    # resize
    v_img = pyvips.Image.new_from_file(fname)
    scale = tn_height / v_img.height
    v_thumb = v_img.resize(scale)

    # write to file
    v_thumb.write_to_file(thumb_fname)


def _list_names(application_key_id, application_key, bucket_name, verbose=True):
    '''List image names and js urls for all uploaded images'''

    # connect
    b2_api, base_url = _connect_b2_bucket(application_key_id, application_key, bucket_name)
    bucket = b2_api.get_bucket_by_name(bucket_name)

    base_url = bucket.get_download_url('')

    # list file names in deepzoom bucket folder
    filenames = [file_info.file_name for file_info, _ in
                 bucket.ls(folder_to_list=ROOTDIR,
                           show_versions=False, recursive=False)]

    # extract image names
    ptrn = f'{ROOTDIR}/{PREFIX}(?P<name>[^/]+).*'

    names = []
    for f in filenames:
        m = re.match(ptrn, f)
        if m:
            names.append(m.groups()[0])

    if verbose:
        print(f'{base_url}{ROOTDIR}/')

    return names


def _make_html_snippet(deepzoombucket, image_names):
    '''Create multi image viewer html snippet for list of `image_names`. '''


    # header
    header = textwrap.dedent('''\
    <script src="https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/openseadragon.min.js"
    integrity="<KEY>
    crossorigin="anonymous">
    </script>

    <script type="text/javascript">
    var viewer = OpenSeadragon({
    id: "openseadragon1_dzi",
    prefixUrl: "https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/images/",
    ''')

    filmstrip = textwrap.dedent('''\
    sequenceMode: true,
    preserveViewport: true,
    showReferenceStrip: true,
    showNavigator: true
    ''')

    # construct tilesources section
    base_url = deepzoombucket.base_url
    tilesources_list = [f' \"{base_url}{ROOTDIR}/{PREFIX}{im_name}/{im_name}.dzi\"' for im_name in image_names]

    if len(tilesources_list) == 1:
        tilesources_str = f'tileSources: {tilesources_list[0]},\n'

    else:
        tilesources_str = 'tileSources: [\n' +  ',\n'.join(tilesources_list) + '],\n' + filmstrip

    # footer
    footer = textwrap.dedent('''\
    });
    </script>

    <div id="openseadragon1_dzi" style="width: 800px; height: 500px; background-color: snow"></div>
    ''')


    # combine
    html_snippet = header + tilesources_str + footer

    return html_snippet



# Class

class DeepZoomBucket:
    '''Create DeepZoomBucket object. '''

    def __init__(self, application_key_id, application_key, bucket_name):
        '''Create DeepZoomStore object for your B2 bucket'''

        # create local directory structure in current working directory
        store_dir = os.path.join('.', ROOTDIR)
        os.makedirs(store_dir, exist_ok=True)

        viewers_dir = os.path.join('.', ROOTDIR, VIEWERSDIR)
        os.makedirs(viewers_dir, exist_ok=True)

        # connect to b2 bucket
        self.application_key_id = application_key_id
        self.application_key = application_key
        self.bucket_name = bucket_name

        self.b2_api, self.base_url = _connect_b2_bucket(application_key_id, application_key, bucket_name)

        # initialize image list for this session
        # why again?
        self.images = []


    def upload_as_dzi(self, fname):

        # convert image file to to local deepzoom directory
        name = _dzp_save(fname)
        self.images.append(name)

        # also make thumnail
        _dzp_thumbnail(fname)

        # create viewer pages
        #dzi_to_js(name, self.base_url, self.bucket_name)
        #make_html(name, self.bucket_name)

        # and sync new files to b2 bucket
        _upload(self.b2_api, self.bucket_name)



    def list_names(self, verbose=False):
        '''List all image names in bucket'''

        names = _list_names(self.application_key_id, self.application_key, self.bucket_name, verbose=verbose)

        return names

    def make_html_snippet(self, image_names):

        html_snippet = _make_html_snippet(self, image_names)

        return html_snippet
# AUTOGENERATED! DO NOT EDIT! File to edit: notebooks/20_uploading-your-own-deep-zoom-images.ipynb (unless otherwise specified).

__all__ = ['DeepZoomBucket', 'PREFIX', 'ROOTDIR', 'VIEWERSDIR']

# Cell

import pyvips
import b2sdk.v1 as b2
import time
import sys
import os
import re
from IPython.display import HTML
import textwrap


# CONSTANTS
PREFIX = 'dzp_'
ROOTDIR = 'deepzoom'
VIEWERSDIR = 'viewers'

def _dzp_save(fname):
    '''Create local dzp_folder and use pyvips to convert image file *fname* to deepzoom pyramid. '''

    name, ext = os.path.splitext(os.path.basename(fname))
    dzp_folder = os.path.join('.', ROOTDIR, f'{PREFIX}{name}')
    dzi_fname = os.path.join('.', ROOTDIR, f'{PREFIX}{name}', f'{name}.dzi')
    dzi_base = os.path.join('.', ROOTDIR, f'{PREFIX}{name}', f'{name}')

    os.makedirs(dzp_folder, exist_ok=True)

    print('CREATING DEEPZOOM IMAGE TILES...')
    if not os.path.exists(dzi_fname):
        v_img = pyvips.Image.new_from_file(fname)
        v_img.dzsave(dzi_base)
    else:
        print(f'Skipping local deepzoom creation for: {fname}\n(No need to overwrite already existing tiles)')

    return name


def _connect_b2_bucket(application_key_id, application_key, bucket_name):
    '''Creates upload connection to your Backblaze b2 bucket.'''

    info = b2.InMemoryAccountInfo()
    b2_api = b2.B2Api(info)
    b2_api.authorize_account("production", application_key_id, application_key)

    bucket = b2_api.get_bucket_by_name(bucket_name)

    base_url = bucket.get_download_url('')

    return b2_api, base_url



def _upload(b2_api, bucket_name):
    '''Upload newly created files in local directory './deepzoom/' to b2 bucket.'''

    source = os.path.join('.', ROOTDIR)
    destination = f'b2://{bucket_name}/{ROOTDIR}'

    source = b2.parse_sync_folder(source, b2_api)
    destination = b2.parse_sync_folder(destination, b2_api)

    policies_manager = b2.ScanPoliciesManager(exclude_all_symlinks=True)

    synchronizer = b2.Synchronizer(
            max_workers=10,
            policies_manager=policies_manager,
            dry_run=False,
            allow_empty_source=True,
        )

    no_progress = False

    # need to run this to actually synchronize

    print('SYNC LOCAL FOLDER WITH CLOUD BUCKET...')

    with b2.SyncReport(sys.stdout, no_progress) as reporter:
            synchronizer.sync_folders(
                source_folder=source,
                dest_folder=destination,
                now_millis=int(round(time.time() * 1000)),
                reporter=reporter,
            )
    print('')


def _dzp_thumbnail(fname, tn_height=1000):
    '''Creates thumbnail file in dzp_directory'''

    # create directory if needed
    name, ext = os.path.splitext(os.path.basename(fname))
    dzp_fname = os.path.join('.', ROOTDIR, f'{PREFIX}{name}')
    os.makedirs(dzp_fname, exist_ok=True)

    # construct standard thumbnail filename
    thumb_fname = os.path.join('.', ROOTDIR, f'{PREFIX}{name}', f'tn_{name}.png')

    # resize
    v_img = pyvips.Image.new_from_file(fname)
    scale = tn_height / v_img.height
    v_thumb = v_img.resize(scale)

    # write to file
    v_thumb.write_to_file(thumb_fname)


def _list_names(application_key_id, application_key, bucket_name, verbose=True):
    '''List image names and js urls for all uploaded images'''

    # connect
    b2_api, base_url = _connect_b2_bucket(application_key_id, application_key, bucket_name)
    bucket = b2_api.get_bucket_by_name(bucket_name)

    base_url = bucket.get_download_url('')

    # list file names in deepzoom bucket folder
    filenames = [file_info.file_name for file_info, _ in
                 bucket.ls(folder_to_list=ROOTDIR,
                           show_versions=False, recursive=False)]

    # extract image names
    ptrn = f'{ROOTDIR}/{PREFIX}(?P<name>[^/]+).*'

    names = []
    for f in filenames:
        m = re.match(ptrn, f)
        if m:
            names.append(m.groups()[0])

    if verbose:
        print(f'{base_url}{ROOTDIR}/')

    return names


def _make_html_snippet(deepzoombucket, image_names):
    '''Create multi image viewer html snippet for list of `image_names`. '''


    # header
    header = textwrap.dedent('''\
    <script src="https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/openseadragon.min.js"
    integrity="<KEY>
    crossorigin="anonymous">
    </script>

    <script type="text/javascript">
    var viewer = OpenSeadragon({
    id: "openseadragon1_dzi",
    prefixUrl: "https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/images/",
    ''')

    filmstrip = textwrap.dedent('''\
    sequenceMode: true,
    preserveViewport: true,
    showReferenceStrip: true,
    showNavigator: true
    ''')

    # construct tilesources section
    base_url = deepzoombucket.base_url
    tilesources_list = [f' \"{base_url}{ROOTDIR}/{PREFIX}{im_name}/{im_name}.dzi\"' for im_name in image_names]

    if len(tilesources_list) == 1:
        tilesources_str = f'tileSources: {tilesources_list[0]},\n'

    else:
        tilesources_str = 'tileSources: [\n' +  ',\n'.join(tilesources_list) + '],\n' + filmstrip

    # footer
    footer = textwrap.dedent('''\
    });
    </script>

    <div id="openseadragon1_dzi" style="width: 800px; height: 500px; background-color: snow"></div>
    ''')


    # combine
    html_snippet = header + tilesources_str + footer

    return html_snippet



# Class

class DeepZoomBucket:
    '''Create DeepZoomBucket object. '''

    def __init__(self, application_key_id, application_key, bucket_name):
        '''Create DeepZoomStore object for your B2 bucket'''

        # create local directory structure in current working directory
        store_dir = os.path.join('.', ROOTDIR)
        os.makedirs(store_dir, exist_ok=True)

        viewers_dir = os.path.join('.', ROOTDIR, VIEWERSDIR)
        os.makedirs(viewers_dir, exist_ok=True)

        # connect to b2 bucket
        self.application_key_id = application_key_id
        self.application_key = application_key
        self.bucket_name = bucket_name

        self.b2_api, self.base_url = _connect_b2_bucket(application_key_id, application_key, bucket_name)

        # initialize image list for this session
        # why again?
        self.images = []


    def upload_as_dzi(self, fname):

        # convert image file to to local deepzoom directory
        name = _dzp_save(fname)
        self.images.append(name)

        # also make thumnail
        _dzp_thumbnail(fname)

        # create viewer pages
        #dzi_to_js(name, self.base_url, self.bucket_name)
        #make_html(name, self.bucket_name)

        # and sync new files to b2 bucket
        _upload(self.b2_api, self.bucket_name)



    def list_names(self, verbose=False):
        '''List all image names in bucket'''

        names = _list_names(self.application_key_id, self.application_key, self.bucket_name, verbose=verbose)

        return names

    def make_html_snippet(self, image_names):

        html_snippet = _make_html_snippet(self, image_names)

        return html_snippet
# AUTOGENERATED! DO NOT EDIT! File to edit: notebooks/20_uploading-your-own-deep-zoom-images.ipynb (unless otherwise specified). # Cell # CONSTANTS Create local dzp_folder and use pyvips to convert image file *fname* to deepzoom pyramid. Creates upload connection to your Backblaze b2 bucket. Upload newly created files in local directory './deepzoom/' to b2 bucket. # need to run this to actually synchronize Creates thumbnail file in dzp_directory # create directory if needed # construct standard thumbnail filename # resize # write to file List image names and js urls for all uploaded images # connect # list file names in deepzoom bucket folder # extract image names Create multi image viewer html snippet for list of `image_names`. # header \     <script src="https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/openseadragon.min.js"     integrity="<KEY>     crossorigin="anonymous">     </script>      <script type="text/javascript">     var viewer = OpenSeadragon({     id: "openseadragon1_dzi",     prefixUrl: "https://cdnjs.cloudflare.com/ajax/libs/openseadragon/2.4.2/images/", \     sequenceMode: true,     preserveViewport: true,     showReferenceStrip: true,     showNavigator: true # construct tilesources section # footer \     });     </script>      <div id="openseadragon1_dzi" style="width: 800px; height: 500px; background-color: snow"></div> # combine # Class Create DeepZoomBucket object. Create DeepZoomStore object for your B2 bucket # create local directory structure in current working directory # connect to b2 bucket # initialize image list for this session # why again? # convert image file to to local deepzoom directory # also make thumnail # create viewer pages #dzi_to_js(name, self.base_url, self.bucket_name) #make_html(name, self.bucket_name) # and sync new files to b2 bucket List all image names in bucket