aboutsummaryrefslogtreecommitdiffstats
path: root/opie.c
Commit message (Expand)AuthorAgeFilesLines
* Align with legacy_6x.Matthias Andree2019-08-251-3/+4
* OPIE: Fix indentation to silence GCC warnings.Matthias Andree2018-04-151-3/+3
* OPIE: Chase to64frombits() API change.Matthias Andree2018-04-151-2/+2
* correct call to gen_send()Sunil Shetye2011-05-041-2/+2
* Further type fixes.Matthias Andree2010-03-181-1/+1
* Fix lots of warnings, most around string literals...Matthias Andree2010-03-181-1/+1
* Further cleanups to compile with C++ compiler.Matthias Andree2006-03-151-0/+6
* Fix more compiler warnings.Matthias Andree2006-03-141-1/+1
* Merge SuSE's fetchmail-6.2.5-random-result.patchMatthias Andree2005-04-251-5/+1
* Fix various warnings.Matthias Andree2004-06-191-3/+3
* Compiler warnings fixes, preprocessor and minor general cleanup.Matthias Andree2004-06-181-1/+1
* Fix for OPIE operation.Eric S. Raymond2001-12-141-9/+18
* Initial revisionEric S. Raymond2001-12-041-0/+74
; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#!/usr/bin/env python3
# Copyright 2017 vg@devys.org
# SPDX-License-Identifier: MIT


'''
Make a html gallery of given directory. Supports image and videos.

Usage: mkgallery.py [options] [--] DIRECTORY
       mkgallery.py -h|--help

Options:
  -h, --help  Display this help message
  -g GALLERY  Where to generate gallery
'''


import os
import urllib
import math


import docopt
import cv2


class Gallery:
    'Gallery generator class'

    def __init__(self, args):
        self.gallery_dir = args.get('GALLERY', 'gallery')
        self.source_dir = args['DIRECTORY']

    def generate_thumbnail(self, original_filename):
        'generate a thumbnail of original_filename in a gallery subdir'
        #sizes = [(120, 120), (720, 720), (1600, 1600)]
        #image = cv2.imread("input.jpg")
        #for size in sizes:
        #    resized_image = cv2.resize(image, size)
        #    cv2.imwrite("thumbnail_%d.jpg" % size[0], resized_image)
        image = cv2.imread(original_filename)
        sizes = [(128, 128)]
        for size in sizes:
            p = os.path
            thumbnail_dir = p.join(self.gallery_dir,
                                   p.dirname(original_filename))
            os.makedirs(thumbnail_dir, exist_ok=True)
            thumbnail_basename = '%s_%dx%d.jpg' % (p.splitext(p.basename(original_filename))[0], size[0], size[1])
            thumbnail_filename = p.join(thumbnail_dir, thumbnail_basename)
            image_height, image_width = image.shape[:2]
            aspect_ratio = image_width / image_height
            area = size[0] * size[1]
            height = math.sqrt(area / aspect_ratio)
            width = height * aspect_ratio
            aspect_ratio_size = (int(width), int(height))
            print('debug thumbnail size:', aspect_ratio_size)
            resized_image = cv2.resize(image, aspect_ratio_size, cv2.INTER_AREA)
            cv2.imwrite(thumbnail_filename, resized_image)
        return thumbnail_filename

    def generate_entry(self, filename):
        'Generate html code for specific image source filename.'

        thumbnail_filename = self.generate_thumbnail(filename)

        return '''\
<p><a href="{encoded_filename}"><img src="{thumbnail_filename}"></a></p>
'''.format(
    encoded_filename=urllib.parse.quote(os.path.abspath(filename)),
    thumbnail_filename=urllib.parse.quote(thumbnail_filename[len(self.gallery_dir):].lstrip('/')),
)

    def content_generator(self):
        'generate <img> entry for each source image'
        for dirpath, _, filenames in os.walk(self.source_dir):
            for filename in filenames:
                yield self.generate_entry(os.path.join(dirpath, filename))

    def generate_html_file(self, output_stream):
        'generate a single html file'
        output_stream.write('''\
<html>
<head>
    <title>Python gallery</title>
</head>
<body>
''')
        for content in self.content_generator():
            output_stream.write(content)
        output_stream.write('''\
</body>
</html>
''')

    def mkgallery(self):
        'global call for generating a gallery'
        os.makedirs(self.gallery_dir, exist_ok=True)
        filename = os.path.join(self.gallery_dir, 'index.html')
        with open(filename, 'w', encoding='utf8') as outstream:
            self.generate_html_file(outstream)


def main():
    'function called only when script invoked directly on command line'
    args = docopt.docopt(__doc__)
    gallery = Gallery(args)
    gallery.mkgallery()


if __name__ == '__main__':
    main()