Explorar o código

initial release

Markus Spring hai 1 ano
pai
achega
1f9c872c30
Modificáronse 3 ficheiros con 471 adicións e 0 borrados
  1. 46 0
      all_galleries.py
  2. 247 0
      create_gallery_index.py
  3. 178 0
      create_gallery_search.py

+ 46 - 0
all_galleries.py

@@ -0,0 +1,46 @@
+#!/usr/bin/python3
+
+
+import os
+import re
+from pathlib import Path
+
+script='/home/springm/projekte/python/create_lightgallery/create_lightgallery.py'
+#script='create_lightgallery.py'
+
+def title(x):
+    x = str(x)
+    x = re.sub('^\d\d\d_', '', x)
+    x = re.sub('_', ' ', x)
+    return x
+
+def make_forward(dirs, x):
+    try:
+        s = '-f "../' + str(dirs[x+1]) + ' ' + title(dirs[x+1]) + '"'
+        return(s)
+    except:
+        return('')
+
+def make_backward(dirs, x):
+    if x == 0:
+        return('')
+    try:
+        s = '-b "../' + str(dirs[x-1]) + ' ' + title(dirs[x-1]) + '"'
+        return(s)
+    except:
+        return('')
+
+startdir = os.getcwd()
+os.chdir("/media/thinc_webserver_data/vaters_dias")
+
+dirs = []
+for d in Path(".").glob("[a-zA-Z0-9]*"):
+    dirs.append(d)
+dirs.sort()
+for x in range(len(dirs)):
+    forward = make_forward(dirs, x)
+    backward = make_backward(dirs, x)
+#    print(' '.join([ str(dirs[x]), '--', script, '-t', '"' + title(dirs[x]) + '"', forward, backward ]))
+    print(' '.join([ script, '-t',  '"' + title(dirs[x]) + '"', forward, backward, '-u..', str(dirs[x]) ]))
+
+os.chdir(startdir)

+ 247 - 0
create_gallery_index.py

@@ -0,0 +1,247 @@
+#!/usr/bin/python3
+
+import logging
+import os
+from os import listdir
+from os.path import isdir, isfile, join
+import re
+from string import Template
+import sys
+import traceback
+#import Image
+
+from configparser import ConfigParser
+from optparse import OptionParser
+
+__all__ = []
+__version__ = 0.1
+__date__ = '2021-12-27'
+__updated__ = '2021-12-27'
+
+DEBUG = 1
+TESTRUN = 0
+PROFILE = 0
+
+html = Template("""<html>
+    <head>
+        <script src="/res/js/jquery.min.js"></script>
+        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
+        <link type="text/css" rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightgallery@2.0.0-beta.3/css/lightgallery-bundle.css" />
+        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
+        <link type="text/css" rel="stylesheet" href="/res/user.css" />
+        <link type="text/css" rel="stylesheet" href="/res/galleryindex.css" />
+    </head>
+    <body class="index">
+        <div id="header" class="index">
+            <h1>$title</h1>
+            <div class="searchcontainer">
+	        <form role="form">
+                    <div class="form-group">
+                        <input type="input" class="form-control input-lg" id="txt-search" placeholder="Suchbegriff eingeben">
+                    </div>
+	        </form>
+            </div>
+        </div><!-- end header -->
+        <div id="outer_lightgallery">
+            <ul class="nav nav-tabs" id="myTab" role="tablist">
+                <li class="nav-item">
+                    <a class="nav-link active" id="lightgallery-tab" data-toggle="tab" href="#lightgallery" role="tab" aria-controls="lightgallery" aria-selected="true">Alle Galerien</a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" id="filters-tab" data-toggle="tab" href="#filters" role="tab" aria-controls="filters" aria-selected="false">Filter</a>
+                </li>
+                <li class="nav-item">
+                    <a class="nav-link" id="results-tab" data-toggle="tab" href="#results" role="tab" aria-controls="results" aria-selected="false">Filter-Ergebnisse</a>
+                </li>
+            </ul>
+            <div class="tab-content" id="myTabContent">
+                <div class="tab-pane fade active index" id="lightgallery" role="tabpanel" aria-labelledby="lightgallery-tab">
+                $dirlist
+                </div>
+                <div class="tab-pane fade" id="filters" role="tabpanel" aria-labelledby="filters-tab"><div style="padding:5em;">Zum Filtern bitte einen Suchbegriff in das Suchfeld eingeben.</div></div>
+                <div class="tab-pane fade" id="results" role="tabpanel" aria-labelledby="results-tab"><div style="padding:5em;">Es gibt noch keine Filter-Ergebnisse</div></div>
+            </div>
+        </div>
+        <script src="headerimages.js"></script>
+        <script>
+         function choosePic() {
+             var randomNum = Math.floor(Math.random() * myPix.length);
+             document.getElementById("header").style.backgroundImage = "url('" + myPix[randomNum] + "')";
+         }
+         function gallery_startup() {
+             choosePic();
+             $$('#myTab li:first-child a').tab('show')
+         }
+         window.onload = gallery_startup();
+        </script>
+        <script src="/res/js/lightgallery.min.js"></script> 
+        <script src="/res/plugins/relativeCaption/lg-relative-caption.min.js"></script> 
+        <script src="/res/plugins/fullscreen/lg-fullscreen.min.js"></script> 
+        <script src="/res/plugins/autoplay/lg-autoplay.min.js"></script> 
+        <script src="/res/plugins/thumbnail/lg-thumbnail.min.js"></script> 
+        <script src="/res/plugins/zoom/lg-zoom.min.js"></script> 
+        <script src="searchdata.js"></script>
+        <script src="/res/lightgallery_search.js"></script>
+    </body>
+</html>""")
+
+def maketitle(x):
+    x = str(x)
+    x = re.sub('^\d\d\d_', '', x)
+    x = re.sub('_', ' ', x)
+    return x
+
+def remove_prefix(text, prefix):
+    return text[text.startswith(prefix) and len(prefix):]
+
+def getthumb(gallerydir, webrootdir):
+    thumb = ''
+    try:
+        for f in listdir(join(gallerydir, '_thumbnails')):
+            # print(f)
+            thumbfile = join(gallerydir, '_thumbnails', f)
+            if isfile(thumbfile):
+                if str(f).lower().endswith('jpg'):
+                    thumb = remove_prefix(join(gallerydir, '_thumbnails', f), webrootdir)
+                    break                    
+    except:
+        pass
+    return(thumb)
+
+def get_headerimage(gallerydir, webrootdir):
+    print(gallerydir)
+    return(remove_prefix(join(gallerydir, 'header/header.jpg'), webrootdir))
+
+def get_directories_in_gallerydir(gallerydir):
+    onlydirs = []
+    for f in listdir(gallerydir):
+        if isdir(join(gallerydir, f)):
+            if str(f) != '_thumbnails':
+                onlydirs.append(f)
+    onlydirs.sort()
+    return(onlydirs)
+
+def read_config(opts):
+    try:
+        config_object = ConfigParser()
+        config_object.read( "." + os.path.splitext(os.path.basename(__file__))[0] )
+        ini = dict(config_object.items('default'))
+        for key in ini:
+            if not opts.__dict__[key]:
+                opts.__dict__[key] = ini[key]
+    except:
+        pass
+
+def write_config(opts):
+    ini = {}
+    for key in opts.__dict__:
+        value = opts.__dict__[key]
+        if value is None:
+            pass
+        elif key == 'verbose':
+            pass
+        else:
+            ini[key] = str(value)
+    
+    config_object = ConfigParser()
+    config_object.read_dict({'default' : ini})
+    with open("." + os.path.splitext(os.path.basename(__file__))[0], 'w') as conf:
+        config_object.write(conf)
+        
+def create_index_html(gallerydir, opts):
+    read_config(opts)
+    logging.info(f"Creating index in {gallerydir}")
+    dirs = get_directories_in_gallerydir(gallerydir)
+    logging.info(dirs)
+    dirlist = ''
+    headerimages = ''
+    for d in dirs:
+        headerimages = headerimages + '","' + get_headerimage(join(gallerydir,d), opts.webrootdir)
+        thumb = getthumb(join(gallerydir,d), opts.webrootdir)
+        print(thumb)
+#        dirlist = dirlist + f"<div class='direntry'><a href='{d}'><img src='{thumb}'>&nbsp;" + maketitle(d) + "</a></div>\n"
+        dirlist = dirlist + f"<div class='img-wrapper'><img src='{thumb}'><div class='p'><a href='{d}'>" + maketitle(d) + "</a></div></div>\n"
+    #print(dirlist)
+    headerimages = re.sub('^",', '', headerimages)
+    with open(join(gallerydir, 'headerimages.js'), 'w') as e:
+        e.write('var myPix = new Array(' + headerimages + '");')
+    title = opts.title or os.path.basename(os.path.normpath(os.getcwd()))
+    with open(join(gallerydir, 'index.html'), 'w') as f:
+        dirlist2 = dirlist
+        f.write(html.substitute( dirlist=dirlist2, title=title ))
+    write_config(opts)
+
+def main(argv=None):
+    '''Command line options.'''
+
+    program_name = os.path.basename(sys.argv[0])
+    program_version = "v0.1"
+    program_build_date = "%s" % __updated__
+
+    program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
+    #program_usage = '''usage: spam two eggs''' # optional - will be autogenerated by optparse
+    program_longdesc = '''create index for directory of lightgallery galleries''' # optional - give further explanation about what the program does
+    program_license = "Copyright 2021 Markus Spring (markus-spring.info).                                      \
+    Licensed under the Apache License 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0"
+
+    if argv is None:
+        argv = sys.argv[1:]
+    try:
+        # setup option parser
+        parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
+        # parser.add_option("-i", "--in", dest="infile", help="set input path [default: %default]", metavar="FILE")
+        # parser.add_option("-o", "--out", dest="outfile", help="set output path [default: %default]", metavar="FILE")
+        parser.add_option("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %default]")
+        parser.add_option("-t", "--title", action="store", dest="title", help="set index title [default: %default]")
+        parser.add_option("-w", "--webrootdir", action="store", dest="webrootdir", help="webserver root dir [default: %default]")
+
+        parser.set_defaults( verbose=0)
+
+        (opts, args) = parser.parse_args(argv)
+
+        if opts.verbose > 0:
+            print(("verbosity level = %d" % opts.verbose))
+        if opts.title:
+            print(("title = %s" % opts.title))
+
+        if len(args) < 1:
+            parser.error("directory argument missing")
+            
+        # MAIN BODY #
+        logging.basicConfig(filename=os.path.basename(sys.argv[0]) + '.log', level=logging.INFO)
+        create_index_html(args[0], opts)
+
+    except BaseException as ex:
+        ex_type, ex_value, ex_traceback = sys.exc_info()         # Get current system exception
+        trace_back = traceback.extract_tb(ex_traceback)          # Extract unformatter stack traces as tuples
+        stack_trace = list()                                     # Format stacktrace
+
+        for trace in trace_back:
+            stack_trace.append("File : %s , Line : %d, Func.Name : %s, Message : %s" % (trace[0], trace[1], trace[2], trace[3]))
+        print("Exception type : %s " % ex_type.__name__)
+        print("Exception message : %s" %ex_value)
+        print("Stack trace : %s" %stack_trace)
+
+
+if __name__ == "__main__":
+    if DEBUG:
+        sys.argv.append("-v")
+    if TESTRUN:
+        import doctest
+        doctest.testmod()
+    if PROFILE:
+        import cProfile
+        import pstats
+        profile_filename = 'config_reader.config_reader_profile.txt'
+        cProfile.run('main()', profile_filename)
+        statsfile = open("profile_stats.txt", "wb")
+        p = pstats.Stats(profile_filename, stream=statsfile)
+        stats = p.strip_dirs().sort_stats('cumulative')
+        stats.print_stats()
+        statsfile.close()
+        sys.exit(0)
+    sys.exit(main())
+
+#Local Variables:
+#compile-command: "./create_gallery_index.py -t 'Dias Ed Spring 1958-1998' /media/thinc_webserver_data/vaters_dias/"
+#End:

+ 178 - 0
create_gallery_search.py

@@ -0,0 +1,178 @@
+#!/usr/bin/python3
+#coding: utf-8
+
+import json
+import logging
+import os
+from os import listdir
+from os.path import isdir, isfile, join
+import re
+from string import Template
+import sys
+import traceback
+from optparse import OptionParser
+
+__all__ = []
+__version__ = '0.1'
+__date__ = '2021-12-27'
+__updated__ = '2021-12-27'
+
+DEBUG = 1
+TESTRUN = 0
+PROFILE = 0
+
+def collect_tagged_images(searchindex, d, tagnr, image_metadata):
+    title = ''
+    with open(join(d, 'index.html'), mode="r") as file:
+        logging.info(join(d, 'index.html'))
+        for line in file:
+            titlematch = re.search("h1>(.+?)<", line)
+            if titlematch:
+                title = titlematch.group(1)
+                # print(title)
+                y = re.search("\d\d\d\d\s+(\D.*)", title)
+                if y:
+                    title = y.group(1)
+                    #print(title)
+                found = next((i for i, item in enumerate(searchindex) if
+                          (item["name"] == title) and item["type"] == 'gallery'), None)
+                if found:
+                    pass
+                else:
+                    searchindex.append({'id':tagnr, 'name':title, 'type':'gallery', 'dir':d})
+                    tagnr = tagnr + 1
+            z = re.search('href=[\'"](.*?)["\'].*data_index=["\'](.+?)["\']>', line)
+            alltags = ''
+            if z:
+                img, data = z.groups()
+                data = data.replace("'","")
+                tags = data.split(',')
+                if len(tags) == 0:
+                    tags = data
+                for t in tags:
+                    [typus,val] = t.split('|')
+                    alltags = alltags + ', ' + val
+                    found = next((i for i, item in enumerate(searchindex) if
+                                  (item["name"] == val) and item["type"] == typus), None)
+                    if found:
+                        searchindex[found]['images'].append(d + '/' + img)
+                    else:
+                        searchindex.append({'id':tagnr,'name':val,'type':typus,'images':[d + '/' + img]})
+                        tagnr = tagnr + 1
+                image_metadata[d + '/' + img] = remove_prefix(alltags, ', ')
+    return(searchindex, tagnr, image_metadata)
+#    return ['','']
+
+def remove_prefix(text, prefix):
+    return text[text.startswith(prefix) and len(prefix):]
+
+def get_directories_in_gallerydir(gallerydir):
+    onlydirs = []
+    for f in listdir(gallerydir):
+        if isdir(join(gallerydir, f)):
+            if str(f) != '_thumbnails':
+                onlydirs.append(f)
+    onlydirs.sort()
+    return(onlydirs)
+                
+def create_search_index(gallerydir, opts):
+    startdir = os.getcwd()
+    os.chdir(gallerydir)
+    print('> ' + gallerydir)
+    logging.info(f"Creating search index in {gallerydir}")
+    dirs = get_directories_in_gallerydir(gallerydir)
+    logging.info(dirs)
+    searchindex = []
+    image_metadata = {}
+    i = 0
+    tagnr = 0
+    for d in dirs:
+        print('>> ' + d)
+        print('>>> ' + join(d, 'index.html'))
+        if not os.path.isfile(join(d, 'index.html')):
+            continue;
+        print('>>>> ' + d)
+        searchindex, tagnr, image_metadata = collect_tagged_images(searchindex, d, tagnr, image_metadata)
+        if i == int(opts.limit) - 1:
+            print('limit reached')
+            break
+        i = i + 1
+        pass
+    # print(json.dumps(searchindex, ensure_ascii=False))
+    with open(join(gallerydir, 'searchdata.js'), 'w') as f:
+         f.write("var data = '" + json.dumps(searchindex, ensure_ascii=False) + "';\n")
+         f.write("var metadata = '" + json.dumps(image_metadata, ensure_ascii=False) + "';\n")
+    os.chdir(startdir)
+
+def main(argv=None):
+    '''Command line options.'''
+
+    program_name = os.path.basename(sys.argv[0])
+    program_version = "v0.1"
+    program_build_date = "%s" % __updated__
+
+    program_version_string = '%%prog %s (%s)' % (program_version, program_build_date)
+    #program_usage = '''usage: spam two eggs''' # optional - will be autogenerated by optparse
+    program_longdesc = '''create index for directory of lightgallery galleries''' # optional - give further explanation about what the program does
+    program_license = "Copyright 2021 Markus Spring (markus-spring.info).                                      \
+    Licensed under the Apache License 2.0\nhttp://www.apache.org/licenses/LICENSE-2.0"
+
+    if argv is None:
+        argv = sys.argv[1:]
+    try:
+        # setup option parser
+        parser = OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license)
+        # parser.add_option("-i", "--in", dest="infile", help="set input path [default: %default]", metavar="FILE")
+        # parser.add_option("-o", "--out", dest="outfile", help="set output path [default: %default]", metavar="FILE")
+        parser.add_option("-l", "--limit", dest="limit", action="store", help="limit number of searched dirs [default: %default]")
+        parser.add_option("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %default]")
+        parser.add_option("-t", "--title", action="store", dest="title", help="set index title [default: %default]")
+        parser.add_option("-w", "--webrootdir", action="store", dest="webrootdir", help="webserver root dir [default: %default]")
+
+        parser.set_defaults( verbose=0, title='sowosamma', webrootdir='/media/thinc_webserver_data', limit=9999)
+
+        (opts, args) = parser.parse_args(argv)
+
+        if len(args) < 1:
+            parser.error("directory argument missing")
+            
+        # MAIN BODY #
+        logging.basicConfig(filename=os.path.basename(sys.argv[0]) + '.log', level=logging.INFO)
+        create_search_index(args[0], opts)
+
+    except BaseException as ex:
+        ex_type, ex_value, ex_traceback = sys.exc_info()         # Get current system exception
+        trace_back = traceback.extract_tb(ex_traceback)          # Extract unformatter stack traces as tuples
+        stack_trace = list()                                     # Format stacktrace
+
+        for trace in trace_back:
+            stack_trace.append("File : %s , Line : %d, Func.Name : %s, Message : %s" % (trace[0], trace[1], trace[2], trace[3]))
+        print("Exception type : %s " % ex_type.__name__)
+        print("Exception message : %s" %ex_value)
+        print("Stack trace : %s" %stack_trace)
+
+
+if __name__ == "__main__":
+    if DEBUG:
+        sys.argv.append("-v")
+    if TESTRUN:
+        import doctest
+        doctest.testmod()
+    if PROFILE:
+        import cProfile
+        import pstats
+        profile_filename = 'config_reader.config_reader_profile.txt'
+        cProfile.run('main()', profile_filename)
+        statsfile = open("profile_stats.txt", "wb")
+        p = pstats.Stats(profile_filename, stream=statsfile)
+        stats = p.strip_dirs().sort_stats('cumulative')
+        stats.print_stats()
+        statsfile.close()
+        sys.exit(0)
+    sys.exit(main())
+
+
+#Local Variables:
+#compile-command: "./create_gallery_search.py -l 5 /media/thinc_webserver_data/vaters_dias/"
+#End:
+