July 2020 (#2)
* wip * Forked lektor-thumbnail-generator * Post Co-authored-by: Felipe M <fmartingr@Going-Merry.local>
This commit is contained in:
		
							parent
							
								
									b7799aac92
								
							
						
					
					
						commit
						9709127df1
					
				
					 8 changed files with 258 additions and 1 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -21,5 +21,7 @@ public | ||||||
| # Lektor | # Lektor | ||||||
| .lektor | .lektor | ||||||
| 
 | 
 | ||||||
|  | packages/**/*.egg-info | ||||||
|  | 
 | ||||||
| # macOS | # macOS | ||||||
| .DS_Store | .DS_Store | ||||||
|  | @ -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 | ||||||
|  |  | ||||||
							
								
								
									
										118
									
								
								content/blog/2020-08-02-july/contents.lr
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								content/blog/2020-08-02-july/contents.lr
									
										
									
									
									
										Normal 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. | ||||||
|  | 
 | ||||||
|  | [](./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: | ||||||
							
								
								
									
										
											BIN
										
									
								
								content/blog/2020-08-02-july/image.jpg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								content/blog/2020-08-02-july/image.jpg
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 706 KiB | 
							
								
								
									
										
											BIN
										
									
								
								content/blog/2020-08-02-july/notion-games.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								content/blog/2020-08-02-july/notion-games.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 548 KiB | 
							
								
								
									
										
											BIN
										
									
								
								content/blog/2020-08-02-july/notion-tasks.png
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								content/blog/2020-08-02-july/notion-tasks.png
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 111 KiB | 
|  | @ -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()} | ||||||
							
								
								
									
										17
									
								
								packages/lektor-thumbnail-generator/setup.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								packages/lektor-thumbnail-generator/setup.py
									
										
									
									
									
										Normal 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', | ||||||
|  |         ] | ||||||
|  |     } | ||||||
|  | ) | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue