July 2020 (#2)

* wip

* Forked lektor-thumbnail-generator

* Post

Co-authored-by: Felipe M <fmartingr@Going-Merry.local>
This commit is contained in:
Felipe M 2020-08-02 21:33:34 +02:00 committed by GitHub
parent b7799aac92
commit 9709127df1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 258 additions and 1 deletions

2
.gitignore vendored
View file

@ -21,5 +21,7 @@ public
# Lektor # Lektor
.lektor .lektor
packages/**/*.egg-info
# macOS # macOS
.DS_Store .DS_Store

View file

@ -8,4 +8,4 @@ lektor-markdown-header-anchors = 0.3.1
lektor-atom = 0.3 lektor-atom = 0.3
lektor-htmlmin = 1.0.2 lektor-htmlmin = 1.0.2
lektor-markdown-highlighter = 0.3.1 lektor-markdown-highlighter = 0.3.1
lektor-thumbnail-generator = 0.4.0 # lektor-thumbnail-generator = 0.4.0

View file

@ -0,0 +1,118 @@
title: July 2020
---
pub_date: 2020-08-02
---
_template: blog/post.html
---
body:
Summer is here!
Even without restrictions or quarantine is has been a weird month. Cases here are going up and down,
I don't want to go back to the gym (and I think I won't until next year), some restaurants and cafe
have closed permanently and the ones that are still standing are usually full (which is good). We're
just trying to go back to normal, step by step, and having some friends stay at home a few days
helped a lot.
[![A picture of myself from behind walking through a port](./image-1024.jpg)](./image-1024.jpg)
<!-- readmore -->
This month I have focused on getting more organized. As I said [last month](/blog/2020/06/02/june/)
I badly needed it.
I have managed to move almost everything into my [notion.so](https://notion.so/) workspace.
I had some boards and notes here and there but Notion is so powerful and comfortable to use that I
just went all in. There's some cleanup to do, but my main points of interes are already there. I have
a board with my personal tasks and some metadata about them, and secondary boards for my hobbies
(Games, Books, TVShows, etc), Blog related posts, ... I may go into more detail in the future.
<div class="grid">
<div class="col-1-2">
<a href="./notion-tasks.png">
<img src="./notion-tasks-320.png" />
</a>
</div>
<div class="col-1-2">
<a href="./notion-games.png">
<img src="./notion-games-320.png" />
</a>
</div>
</div>
Related to this I'm also starting to cleanup every last drawer at home. I got a bit tired of not
knowing how much stuff I have so I'm making a full inventory of _everything_. It all started
reviewing how many of my clothers would still fit me after quarantine, and it snapped on me. I
don't know how much I own, and I think it happens to all of us at different levels.
With tech this is gonna be very difficult, I have managed to stash a lot (**a lot**) of cables
during the years. Just imagine how many HDMI and USB cables the average tech guy can get a hold
of... Arduinos, Raspberries... etc.
This will take time, but I'm very happy with the progress I already had and all the things I've
already donated or sold.
## Projects
- My **local infra** is mostly done at this point. I just need to secure everything a bit more
but has been working fine (with some hiccups) for the past months. I may need to check some
networking alternatives and move all SSL negotiation to the main node (avoiding re-encrypting
traffic on a non-controlled node).
- **Butterrobot** got some love this month. I'm _slowly_ setting up an automated CI/CD system to
deploy the application in my local infra, but I need to setup some other details as well. Source
code is already on Github though repository is private while I made last minute changes. I'm
hoping to release it this month.
- I'm also cleaning up my **Home Assistant** node. What that really means that I'm re-deploying a
new instance on a more powerful Raspberry Pi. I have been playing with this software for years
and my current pi is a bit underpowered and messy, so the plan is start from scratch trying to
make the connected devices local trying to avoid third-party clouds as much as possible and
document everything in some blog posts. Let see how that goes.
## TV Shows
I watched something!
- **M.A.R.V.E.L.s Agents of Shield**
Some chapters of the last season. This may be the worst season so far...? (At least the few I saw)
- **The 100**
Up to date with this one, without much focus because some interdimensional time thingy is not very
appealing to me, just want to know how it all ends. If it doesn't end this season, I'm done with it.
- **Sword Art Online (Aincrad saga only)**
Rewatched this one (a friend's fault) as series to have while cooking and doing chores. A bit complex
to read subtitles the same time you do other things, but since this is a re-watch... Now looking for
some other series with the same "protagonist sent to fantasy world" genre.
## Games
- [**Final Fantasy VII: Remake**](https://store.playstation.com/es-es/product/EP0082-CUSA07187_00-FFVIIREMAKE00000)
I have gone through a bit more of the story, trying to enjoy the story till the end. And wait
another five years for the next chapter...?
- [**Reventure**](https://store.steampowered.com/app/900270/Reventure/)
Quick play sessions are quick. Oh my god this game has soooo many endings...
- [**Carrion**](https://www.xbox.com/en-US/games/carrion)
This has been on my radar for quite some time. It's a shame is so short! Finished in a few hours, but that didn't mean
is not great, because it is. Being the monster trapped wanted to go out instead of the _"Hero"_ killing monsters is
a really appreciated change of perspective. The mechanics were amazing and the graphics gorgeous, it was very fun while it
lasted.
- [**Rick and Morty: Virtual Rick-ality**](https://store.steampowered.com/app/469610/Rick_and_Morty_Virtual_Rickality/)
I got time to play some VR, and I had this in the backlog for quite some time. I love Rick and Morty and this was
a short and fun puzzle adventure, just what I expected. I could get on with the optional stuff but I just have too much
on backlog!
## Articles
I forgot to take note of the interesting ones this month. :sweat_smile:

Binary file not shown.

After

Width:  |  Height:  |  Size: 706 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View file

@ -0,0 +1,120 @@
# -*- coding: utf-8 -*-
import shutil
from lektor.build_programs import AttachmentBuildProgram, buildprogram
from lektor.context import get_ctx
from lektor.db import Image
from lektor.imagetools import (computed_height, find_imagemagick,
get_image_info, get_quality)
from lektor.pluginsystem import Plugin
from lektor.reporter import reporter
from lektor.utils import portable_popen
from werkzeug.utils import cached_property
# We override process_image here because Lektor does not support adding extra
# parameters yet, but it will soon, and this can be removed when it does.
def process_image(
ctx,
source_image,
dst_filename,
width=None,
height=None,
mode=None,
quality=None,
extra_params=None,
):
"""Build image from source image, optionally compressing and resizing.
"source_image" is the absolute path of the source in the content directory,
"dst_filename" is the absolute path of the target in the output directory.
"""
if width is None and height is None:
raise ValueError("Must specify at least one of width or height.")
im = find_imagemagick(ctx.build_state.config["IMAGEMAGICK_EXECUTABLE"])
if quality is None:
quality = get_quality(source_image)
resize_key = ""
if width is not None:
resize_key += str(width)
if height is not None:
resize_key += "x" + str(height)
cmdline = [im, source_image, "-auto-orient"]
cmdline += ["-resize", resize_key]
if extra_params:
cmdline.extend(extra_params)
cmdline += ["-quality", str(quality), dst_filename]
reporter.report_debug_info("imagemagick cmd line", cmdline)
portable_popen(cmdline).wait()
@buildprogram(Image)
class ResizedImageBuildProgram(AttachmentBuildProgram):
def build_artifact(self, artifact):
ctx = get_ctx()
plugin = ctx.env.plugins["thumbnail-generator"]
config = plugin.config
artifact.ensure_dir()
AttachmentBuildProgram.build_artifact(self, artifact)
if not config:
return
source_img = artifact.source_obj.attachment_filename
with open(source_img, "rb") as f:
_, w, h = get_image_info(f)
# For every section in the config, we need to generate one image.
for item, conf in config.items():
width = int(conf["max_width"])
height = int(conf.get("max_height", "0"))
quality = int(conf.get("quality", "100"))
if not height:
height = computed_height(source_img, width, w, h)
df = artifact.source_obj.url_path
ext_pos = df.rfind(".")
dst_filename = "%s-%s.%s" % (df[:ext_pos], item, df[ext_pos + 1 :])
def closure(dst_filename, source_img, width, height, resize_image=True):
# We need this closure, otherwise variables get updated and this
# doesn't work at all.
@ctx.sub_artifact(artifact_name=dst_filename, sources=[source_img])
def build_thumbnail_artifact(artifact):
artifact.ensure_dir()
if not resize_image:
shutil.copy2(source_img, artifact.dst_filename)
else:
process_image(
ctx,
source_img,
artifact.dst_filename,
width,
height,
quality=100,
)
# If the image is larger than the max_width, resize it, otherwise
# just copy it.
resize_image = w > width or h > height
closure(dst_filename, source_img, width, height, resize_image)
class ThumbnailGeneratorPlugin(Plugin):
name = u"thumbnail-generator"
description = u"A configurable way to generate thumbnails."
image_exts = ["png", "jpg", "jpeg", "gif"]
@cached_property
def config(self):
conf = self.get_config()
return {section: conf.section_as_dict(section) for section in conf.sections()}

View file

@ -0,0 +1,17 @@
from setuptools import setup
setup(
name='lektor-thumbnail-generator',
version='0.4.0',
author=u'Stavros Korokithakis,,,',
author_email='hi@stavros.io',
url='https://github.com/skorokithakis/lektor-thumbnail-generator/',
description="This plugin automatically generates thumbnails for any images in your Lektor content. The difference between this plugin and the `thumbnail` filter is that this is geared towards content, i.e. you don't need to have any references to the images in your templates at all.",
license='MIT',
py_modules=['lektor_thumbnail_generator'],
entry_points={
'lektor.plugins': [
'thumbnail-generator = lektor_thumbnail_generator:ThumbnailGeneratorPlugin',
]
}
)