diff options
20 files changed, 304 insertions, 9 deletions
diff --git a/content/images/screenshots/calf_equalizer.jpg b/content/images/screenshots/calf_equalizer.jpg Binary files differnew file mode 100644 index 0000000..64e1b07 --- /dev/null +++ b/content/images/screenshots/calf_equalizer.jpg diff --git a/content/images/screenshots/calf_monosynth.jpg b/content/images/screenshots/calf_monosynth.jpg Binary files differnew file mode 100644 index 0000000..f137350 --- /dev/null +++ b/content/images/screenshots/calf_monosynth.jpg diff --git a/content/images/screenshots/calf_multiband_compressor.jpg b/content/images/screenshots/calf_multiband_compressor.jpg Binary files differnew file mode 100644 index 0000000..9e3d2a7 --- /dev/null +++ b/content/images/screenshots/calf_multiband_compressor.jpg diff --git a/content/images/screenshots/calf_organ.jpg b/content/images/screenshots/calf_organ.jpg Binary files differnew file mode 100644 index 0000000..e5d492c --- /dev/null +++ b/content/images/screenshots/calf_organ.jpg diff --git a/content/images/screenshots/casynth.png b/content/images/screenshots/casynth.png Binary files differnew file mode 100644 index 0000000..ce25a99 --- /dev/null +++ b/content/images/screenshots/casynth.png diff --git a/content/images/screenshots/distrho_easyssp.png b/content/images/screenshots/distrho_easyssp.png Binary files differnew file mode 100644 index 0000000..3363937 --- /dev/null +++ b/content/images/screenshots/distrho_easyssp.png diff --git a/content/images/screenshots/distrho_obxd.png b/content/images/screenshots/distrho_obxd.png Binary files differnew file mode 100644 index 0000000..b6082bb --- /dev/null +++ b/content/images/screenshots/distrho_obxd.png diff --git a/content/images/screenshots/distrho_tal_noisemaker.png b/content/images/screenshots/distrho_tal_noisemaker.png Binary files differnew file mode 100644 index 0000000..f54198d --- /dev/null +++ b/content/images/screenshots/distrho_tal_noisemaker.png diff --git a/content/images/screenshots/envfollower.png b/content/images/screenshots/envfollower.png Binary files differnew file mode 100644 index 0000000..8182db3 --- /dev/null +++ b/content/images/screenshots/envfollower.png diff --git a/content/images/screenshots/hip2b.png b/content/images/screenshots/hip2b.png Binary files differnew file mode 100644 index 0000000..6c4b5d4 --- /dev/null +++ b/content/images/screenshots/hip2b.png diff --git a/content/images/screenshots/mod.png b/content/images/screenshots/mod.png Binary files differnew file mode 100644 index 0000000..1245e77 --- /dev/null +++ b/content/images/screenshots/mod.png diff --git a/content/images/screenshots/powercut.png b/content/images/screenshots/powercut.png Binary files differnew file mode 100644 index 0000000..d9715e0 --- /dev/null +++ b/content/images/screenshots/powercut.png diff --git a/content/images/screenshots/stuck.png b/content/images/screenshots/stuck.png Binary files differnew file mode 100644 index 0000000..3f0e5df --- /dev/null +++ b/content/images/screenshots/stuck.png diff --git a/content/pages/index.md b/content/pages/index.md index c1adb9f..5968f45 100644 --- a/content/pages/index.md +++ b/content/pages/index.md @@ -1,5 +1,6 @@ Title: save_as: index.html +Gallery: . LV2 is a [free](http://www.gnu.org/philosophy/free-sw.html) standard for audio plugins, used by hundreds of plugins and other projects. At its core, LV2 is a diff --git a/extra_plugins/gallery.py b/extra_plugins/gallery.py new file mode 100644 index 0000000..3c5011d --- /dev/null +++ b/extra_plugins/gallery.py @@ -0,0 +1,184 @@ +import logging, json, os, sys, time, Image +from pelican import signals +from PIL import ImageOps + +""" + +Gallery plugin for Pelican +========================== + +This plugin creates a gallery attribute on content (article.gallery) you want to create. You +will define named presets which can be referenced in your templates. It will attempt to be smart +about regenerating photos once they exist. + +- Resizes images respective of aspect ratio +- Allows for multiple presets e.g. -> article.gallery.photos[0]['thumb'] + +Settings: +--------- + +Example configuration: + +GALLERY_FOLDER = "galleries" +GALLERY_SRC_PATH = "%s%s" % (BASE_PATH, "gallery_src") +GALLERY_OUTPUT_PATH = "%s%s%s" % (BASE_PATH, OUTPUT_PATH, GALLERY_FOLDER) +GALLERY_REGENERATE_EXISTING = False +GALLERY_PRESETS = [ + {"name": "thumb", "actions": [{"type": "fit", "height": 100, "width": 100, "from": (0.5, 0.5) }]}, + {"name": "slider", "actions": [{"type": "fit", "height": 300, "width": 900, "from": (0.5, 0.5) }]}, + {"name": "large", "actions": [{"type": "resize", "height": 640, "width": 850, "from": (0.5, 0.5) }]}, + {"name": "thumb_greyscale", + "actions": [ + {"type": "fit", "height": 100, "width": 100, "from": (0.5, 0.5) }, + {"type": "greyscale"} + ]}, + ] + +# This setting is optional, used for thumbnails in bootstrap +THUMBNAIL_GALLERY_CLASS = "span2" + +Article metadata example: +------------------------- +Gallery: <Relative path from GALLERY_SRC_PATH> + +{% if article.gallery %} + <h3>Gallery</h3> + <ul class="thumbnails"> + {% for photo_set in article.gallery.photos %} + <li class="{{THUMBNAIL_GALLERY_CLASS}}"> + <a href="{{ SITEURL }}/{{ photo_set['large'].src }}" class="thumbnail fancybox-thumbs" rel="article.gallery.galleryName"> + <img src="{{ SITEURL }}/{{ photo_set['thumb'].src }}" alt="{{ photo_set['thumb'].src }}" /> + </a> + </li> + {% endfor %} + </ul> +{% endif %} + +""" + + +class Photo(): + + """ Class to represent a Photo, also handles applying presets to itself""" + def __init__(self, gallery, filename, output_path, preset): + self.gallery = gallery + self.filename = filename + self.input_file = "%s%s%s" % (self.gallery.absolute_src_path, os.sep, self.filename) + self.output_path = output_path + self.output_file = "%s%s%s" % (output_path, os.sep, self.filename) + self.preset = preset + self.image = None + self.width = None + self.height = None + self.image = Image.open(self.input_file) + self.process_image() + self.image = Image.open(self.output_file) + self.width, self.height = self.image.size + self.src = "%s%s%s%s%s%s%s" %(self.gallery.generator.settings["GALLERY_FOLDER"], + os.sep, + self.gallery.gallery_name, + os.sep, + self.preset["name"], + os.sep, + self.filename) + + + def process_image(self): + """Responsible for applying presets to the Image obj""" + if not os.path.isfile(self.output_file) or self.gallery.generator.settings["GALLERY_REGENERATE_EXISTING"]: + + # Actions should be processed in order of appearance in actions array + for i in range(len(self.preset["actions"])): + a = self.preset["actions"][i] + + if a["type"] == "fit": + if not "from" in a: + a["from"] = (0.5, 0.5) # crop from middle by default + + self.image = ImageOps.fit(self.image, (a["width"], a["height"],), method=Image.ANTIALIAS, centering=a["from"]) + + if a["type"] == "greyscale": + self.image = ImageOps.grayscale(self.image) + + if a["type"] == "resize": + self.image.thumbnail((a["width"], a["height"]), Image.NEAREST) + + # TODO: Write other useful transforms here! + + + self.image.save(self.output_file, "JPEG") + + + +class Gallery(): + """Represents a Gallery, iterate of gallery.photos in your Template""" + def __init__(self, generator, metadata): + self.generator = generator + self.gallery_name = None + self.files = [] + self.photos = [] + self.absolute_src_path = None + self.absolute_output_path = None + self.metadata = metadata + self.preset_dir = [] + + if "gallery" in self.metadata: + self.gallery_name = self.metadata["gallery"] + self.absolute_src_path = "%s%s%s" % (self.generator.settings["GALLERY_SRC_PATH"], + os.sep, + self.gallery_name) + + self.absolute_output_path = "%s%s%s" % (self.generator.settings["GALLERY_OUTPUT_PATH"], + os.sep, + self.gallery_name) + + self.create_preset_folders() + self.create_preset_images() + + def create_preset_images(self): + """Creates the image assets for each preset and returns a PhotoSet object""" + for f in self.get_files_from_data(): + photoInstances = {} + for preset in self.generator.settings["GALLERY_PRESETS"]: + preset_dir = "%s%s%s" % (self.absolute_output_path, + os.sep, + preset["name"]) + photoInstances[preset["name"]] = Photo(self, f, preset_dir, preset) + + self.photos.append(photoInstances) + + def create_preset_folders(self): + """Creates the folder structure for a gallery""" + + if not os.path.exists(self.absolute_output_path): + os.makedirs(self.absolute_output_path) + + # Create gallery preset folders for this gallery + if "GALLERY_PRESETS" in self.generator.settings: + for preset in self.generator.settings["GALLERY_PRESETS"]: + preset_dir = "%s%s%s" % (self.absolute_output_path, + os.sep, + preset["name"]) + self.preset_dir.append(preset_dir) + if not os.path.exists(preset_dir): + os.makedirs(preset_dir) + else: + print "You have no presets defined, please add GALLERY_PRESETS array to settings file, with at least one preset defined, see docs." + + def get_files_from_data(self): + print "getting files for %s" % self.absolute_src_path + from os import listdir + from os.path import isfile, join + return [ f for f in listdir(self.absolute_src_path) if isfile(join(self.absolute_src_path,f)) and f != ".DS_Store" ] + + + + +def get_galleries(generator, metadata): + if "gallery" in metadata.keys(): + metadata["gallery"] = Gallery(generator, metadata) + +def register(): + #signals.article_generator_init.connect(init_gallery_plugin) + #signals.article_generator_context.connect(get_galleries) + signals.page_generator_context.connect(get_galleries) diff --git a/pelicanconf.py b/pelicanconf.py index 653afb6..7b4b178 100644 --- a/pelicanconf.py +++ b/pelicanconf.py @@ -7,7 +7,7 @@ SITENAME = u'LV2' SITELOGO = 'images/logo.svg' SITELOGO_WIDTH = '75' SITELOGO_HEIGHT = '48' -SITEURL = '' +SITEURL = 'http://lv2plug.in' PATH = 'content' @@ -54,3 +54,21 @@ DISPLAY_TAGS_ON_SIDEBAR = False DISPLAY_RECENT_POSTS_ON_SIDEBAR = False DISPLAY_SERIES_ON_SIDEBAR = False DISPLAY_CATEGORIES_ON_SIDEBAR = False + +PLUGIN_PATHS = ["extra_plugins"] +PLUGINS = ["gallery"] + +GALLERY_FOLDER = "galleries" +GALLERY_SRC_PATH = "%s%s" % (PATH, "/images/screenshots") +GALLERY_OUTPUT_PATH = "%s%s" % ("output/", GALLERY_FOLDER) +GALLERY_REGENERATE_EXISTING = True +GALLERY_PRESETS = [ + {"name": "thumb", + "actions": [{"type": "fit", "height": 100, "width": 100, "from": (0.5, 0.5)}]}, + {"name": "slider", + "actions" : []}, + {"name": "large", + "actions": [{"type": "resize", "height": 640, "width": 850, "from": (0.5, 0.5)}]}, + {"name": "thumb_greyscale", + "actions": [{"type": "fit", "height": 100, "width": 100, "from": (0.5, 0.5)}, + {"type": "greyscale"} ]}] diff --git a/themes/lv2/static/css/slideshow.css b/themes/lv2/static/css/slideshow.css new file mode 100644 index 0000000..7fe664d --- /dev/null +++ b/themes/lv2/static/css/slideshow.css @@ -0,0 +1,38 @@ +#slideshow { + background-color: #000; + border: 3px solid #000; + border-radius: 6px; + display: inline-block; + height: 20em; + line-height: 20em; + margin: 1em; + margin-left: auto; + margin-right: auto; + position: relative; + text-align: right; + vertical-align: middle; + width: 20em; +} + +#slideshow img { + left: 0; + width: 100%; + height: auto; + max-height: 100%; + opacity: 0; + position: absolute; + text-align: center; + transition-duration: 1s; + transition-property: opacity; + vertical-align: middle; +} + +#slideshow .fadein { + opacity: 1.0; + transform-origin: bottom left; +} + +#slideshow .fadeout { + opacity: 0.0; + transform-origin: bottom left; +} diff --git a/themes/lv2/static/js/slideshow.js b/themes/lv2/static/js/slideshow.js new file mode 100644 index 0000000..d9fb9c5 --- /dev/null +++ b/themes/lv2/static/js/slideshow.js @@ -0,0 +1,40 @@ +function getPreviousNode(n) { + var p = n.previousSibling; + while (p && p.nodeType !== 1) { + p = p.previousSibling; + } + return p; +} + +function startSlideShow() { + var slideshow = document.getElementById("slideshow"), + imgs = slideshow.getElementsByTagName("img"), + n = imgs.length, + m = Math.floor((Math.random() * n)), + pred = getPreviousNode(slideshow); + + // Shrink width of predecessor so gallery fits beside it + if (pred) { + pred.style.width = "50%"; + pred.style.display = "inline-block"; + } + + // Start transition of initial image + imgs[m].className = "fadein"; + m = (m + 1) % n; + + function tick() { + // Fade out the previous image, and fade in the next + var prev = (m + n - 1) % n, + next = (m + 1) % n; + + imgs[prev].className = ""; + imgs[m].className = "fadeout"; + imgs[next].className = "fadein"; + + m = (m + 1) % n; + } + window.setInterval(tick, 4000); +} + +startSlideShow(); diff --git a/themes/lv2/templates/base.html b/themes/lv2/templates/base.html index a3ca785..00f066d 100644 --- a/themes/lv2/templates/base.html +++ b/themes/lv2/templates/base.html @@ -1,13 +1,15 @@ <!DOCTYPE html> <html lang="en"> <head> - <title>{% block title %}{{ SITENAME }}{%endblock%}</title> - <meta charset="utf-8" /> - <link rel="stylesheet" href="{{ SITEURL }}/theme/css/{{ CSS_FILE }}" type="text/css" /> - <link href="{{ SITEURL }}/{{ FEED }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} ATOM Feed" /> - {% if FEED_RSS %} - <link href="{{ SITEURL }}/{{ FEED_RSS }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" /> - {% endif %} + {% block head %} + <title>{% block title %}{{ SITENAME }}{%endblock%}</title> + <meta charset="utf-8" /> + <link rel="stylesheet" href="{{ SITEURL }}/theme/css/{{ CSS_FILE }}" type="text/css" /> + <link href="{{ SITEURL }}/{{ FEED }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} ATOM Feed" /> + {% if FEED_RSS %} + <link href="{{ SITEURL }}/{{ FEED_RSS }}" type="application/atom+xml" rel="alternate" title="{{ SITENAME }} RSS Feed" /> + {% endif %} + {% endblock %} </head> <body> @@ -23,7 +25,7 @@ {% endif %} </a> </li> - + {% for title, link in MENUITEMS %} <li><a href="{{ link }}">{{ title }}</a></li> {% endfor %} diff --git a/themes/lv2/templates/page.html b/themes/lv2/templates/page.html index 33f6aca..762dd27 100644 --- a/themes/lv2/templates/page.html +++ b/themes/lv2/templates/page.html @@ -1,4 +1,8 @@ {% extends "base.html" %} +{% block head %} + {{ super() }} + <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/theme/css/slideshow.css" /> +{% endblock %} {% block title %} {% if page.title %} {{ page.title }} @@ -13,4 +17,12 @@ {% endif %} </header> {{ page.content }} + {% if page.gallery %} + <div id="slideshow"> + {% for photo_set in page.gallery.photos %} + <img src="{{ SITEURL }}/{{ photo_set['slider'].src }}" alt="{{ photo_set['slider'].src }}" /> + {% endfor %} + </div> + <script type="text/javascript" src="{{ SITEURL }}/theme/js/slideshow.js"></script> + {% endif %} {% endblock %} |