From f8dc7e71a4d9e279ba4f5b606f7f56ccdfae0448 Mon Sep 17 00:00:00 2001 From: Lukas Date: Sun, 24 Mar 2024 15:45:15 -0400 Subject: [PATCH] first commitm --- Jenkinsfile | 25 ++ config.toml | 81 ++++ content/_index.md | 8 + content/about.md | 16 + content/contact.md | 12 + content/posts/2023/06/_index.md | 9 + .../posts/2023/06/resolved-email-delivery.md | 20 + content/posts/2023/07/_index.md | 9 + .../posts/2023/07/encryption-flashcards.md | 8 + content/posts/2023/07/prompt-engineering.md | 8 + content/posts/2023/07/security-models.md | 8 + content/posts/2023/07/youtube-music.md | 9 + content/posts/2023/08/_index.md | 9 + content/posts/2023/08/cissp.md | 59 +++ content/posts/2023/09/19.md | 10 + content/posts/2023/09/_index.md | 9 + content/posts/2023/09/defaults.md | 19 + content/posts/2023/10/02.md | 16 + content/posts/2023/10/_index.md | 9 + content/posts/2023/10/backups.md | 12 + content/posts/2023/10/bash-reverse-search.md | 11 + .../2023/10/resolved-libvirt-isolated.md | 20 + content/posts/2023/10/surreal-blog.md | 11 + content/posts/2023/10/wordpress-gripes.md | 12 + content/posts/2023/11/_index.md | 9 + content/posts/2023/11/google.md | 18 + content/posts/2023/_index.md | 9 + content/posts/_index.md | 9 + content/posts/typography.md | 9 + content/search.md | 6 + index.html | 7 + sass/base.scss | 142 +++++++ sass/blog.scss | 126 +++++++ sass/custom.scss | 1 + sass/footer.scss | 9 + sass/gallery.scss | 50 +++ sass/header.scss | 89 +++++ sass/normalize.scss | 351 ++++++++++++++++++ sass/search.scss | 58 +++ sass/tags.scss | 9 + sass/typography.scss | 89 +++++ sass/utilities.scss | 19 + sass/variables.scss | 17 + static/inky.png | Bin 0 -> 5294 bytes static/js/search.js | 180 +++++++++ .../inky.14c2be2bf4556dcc.png | Bin 0 -> 9968 bytes .../inky.509a176c30944214.png | Bin 0 -> 2848 bytes .../inky.7c7bddb9fe90360e.png | Bin 0 -> 5673 bytes templates/base.html | 143 +++++++ templates/blog-page.html | 9 + templates/blog.html | 13 + templates/gallery.html | 24 ++ templates/index.html | 6 + templates/index.md | 8 + templates/macros/head.html | 11 + templates/macros/hooks.html | 10 + templates/macros/images.html | 52 +++ templates/macros/opengraph.html | 53 +++ templates/page.html | 12 + templates/post.html | 33 ++ templates/posts.html | 29 ++ templates/search.html | 22 ++ templates/shortcodes/image.html | 3 + templates/shortcodes/image_original.html | 3 + templates/shortcodes/spotify.html | 5 + templates/shortcodes/thumbnail.html | 22 ++ templates/shortcodes/youtube.html | 7 + templates/taxonomy_list.html | 14 + templates/taxonomy_single.html | 29 ++ 69 files changed, 2125 insertions(+) create mode 100644 Jenkinsfile create mode 100644 config.toml create mode 100644 content/_index.md create mode 100644 content/about.md create mode 100644 content/contact.md create mode 100644 content/posts/2023/06/_index.md create mode 100644 content/posts/2023/06/resolved-email-delivery.md create mode 100644 content/posts/2023/07/_index.md create mode 100644 content/posts/2023/07/encryption-flashcards.md create mode 100644 content/posts/2023/07/prompt-engineering.md create mode 100644 content/posts/2023/07/security-models.md create mode 100644 content/posts/2023/07/youtube-music.md create mode 100644 content/posts/2023/08/_index.md create mode 100644 content/posts/2023/08/cissp.md create mode 100644 content/posts/2023/09/19.md create mode 100644 content/posts/2023/09/_index.md create mode 100644 content/posts/2023/09/defaults.md create mode 100644 content/posts/2023/10/02.md create mode 100644 content/posts/2023/10/_index.md create mode 100644 content/posts/2023/10/backups.md create mode 100644 content/posts/2023/10/bash-reverse-search.md create mode 100644 content/posts/2023/10/resolved-libvirt-isolated.md create mode 100644 content/posts/2023/10/surreal-blog.md create mode 100644 content/posts/2023/10/wordpress-gripes.md create mode 100644 content/posts/2023/11/_index.md create mode 100644 content/posts/2023/11/google.md create mode 100644 content/posts/2023/_index.md create mode 100644 content/posts/_index.md create mode 100644 content/posts/typography.md create mode 100644 content/search.md create mode 100644 index.html create mode 100644 sass/base.scss create mode 100644 sass/blog.scss create mode 100644 sass/custom.scss create mode 100644 sass/footer.scss create mode 100644 sass/gallery.scss create mode 100644 sass/header.scss create mode 100644 sass/normalize.scss create mode 100644 sass/search.scss create mode 100644 sass/tags.scss create mode 100644 sass/typography.scss create mode 100644 sass/utilities.scss create mode 100644 sass/variables.scss create mode 100644 static/inky.png create mode 100644 static/js/search.js create mode 100644 static/processed_images/inky.14c2be2bf4556dcc.png create mode 100644 static/processed_images/inky.509a176c30944214.png create mode 100644 static/processed_images/inky.7c7bddb9fe90360e.png create mode 100644 templates/base.html create mode 100644 templates/blog-page.html create mode 100644 templates/blog.html create mode 100644 templates/gallery.html create mode 100644 templates/index.html create mode 100644 templates/index.md create mode 100644 templates/macros/head.html create mode 100644 templates/macros/hooks.html create mode 100644 templates/macros/images.html create mode 100644 templates/macros/opengraph.html create mode 100644 templates/page.html create mode 100644 templates/post.html create mode 100644 templates/posts.html create mode 100644 templates/search.html create mode 100644 templates/shortcodes/image.html create mode 100644 templates/shortcodes/image_original.html create mode 100644 templates/shortcodes/spotify.html create mode 100644 templates/shortcodes/thumbnail.html create mode 100644 templates/shortcodes/youtube.html create mode 100644 templates/taxonomy_list.html create mode 100644 templates/taxonomy_single.html diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..322406e --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,25 @@ +pipeline { + agent any + + stages { + stage('Build') { + steps { + echo 'run zola build' + sh 'zola build' + } + } + stage('Deploy') { + steps { + echo 'Hello World' + sh 'ls public' + sshagent(credentials: ['d82f9436-4c96-44c2-9ed3-b21481e7b742']) { + sh ''' + [ -d ~/.ssh ] || mkdir ~/.ssh && chmod 0700 ~/.ssh + ssh-keyscan -t rsa,dsa lvacula.com >> ~/.ssh/known_hosts + rsync -avz -e "ssh -o StrictHostKeyChecking=no" public/. greywolver@lvacula.com:lvacula.com-docker/volumes/blog + ''' + } + } + } + } +} \ No newline at end of file diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..51cdeba --- /dev/null +++ b/config.toml @@ -0,0 +1,81 @@ +title = "Temporary Permanence" +description = "Lukas Vacula's personal website and blog." + +# The URL the site will be built for +base_url = "https://lvacula.com" + +# Whether to automatically compile all Sass files in the sass directory +compile_sass = true + +# Whether to build a search index to be used later on by a JavaScript library +build_search_index = true +default_language = "en" + +generate_feed = true +author = "Lukas Vacula" +feed_filename = "atom.xml" + +# The taxonomies to be rendered for the site and their configuration of the default languages +# Example: +# taxonomies = [ +# {name = "tags", feed = true}, # each tag will have its own feed +# {name = "tags"}, # you can have taxonomies with the same name in multiple languages +# {name = "categories", paginate_by = 5}, # 5 items per page for a term +# {name = "authors"}, # Basic definition: no feed or pagination +# ] +# +taxonomies = [{ name = "tags", lang = "en", rss = true }] + +[markdown] +# Whether to do syntax highlighting +# Theme can be customised by setting the `highlight_theme` variable to a theme supported by Zola +highlight_code = true + + +[slugify] +paths = "on" +taxonomies = "on" +anchors = "on" + +[extra] + +# Place your avatar in your /static folder +avatar = "/inky.png" + +# Your Google Analytics measurement id ("G-XXXXXXXXXX") +# google_analytics_tag_id = ""; + +#keywords = "zola, theme, ink, hugo-ink" +keywords = "tech, security" + +search_enabled = false + + +image_resizing_disabled = false +image_format = "auto" # "auto", "jpg", "png", "webp" + +# responsive image shortcode +# example: {{ image(src="foo.jpeg", alt="some image") }} +image_quality = 80 +images_default_size = 1024 +images_sizes = [512, 1024, 2048] + +thumbnail_quality = 70 +thumbnail_default_size = 256 +thumbnail_sizes = [128, 256] + + +#link_github_username = "jimmyff/zola-inky" +# link_twitter_username = "" +# link_mastodon_url = "" +# link_medium_username = "" +# link_instagram_username = "" + +menu_links = [ + { url = "$BASE_URL/", name = "About" }, + { url = "$BASE_URL/posts/", name = "Posts" }, + { url = "$BASE_URL/tags/", name = "Tags" }, + # { url = "https://github.com/jimmyff/zola-inky", name = "Github" }, + { url = "$BASE_URL/contact/", name = "Contact" }, + { url = "$BASE_URL/search/", name = "Search" }, +] diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 0000000..73dbfe6 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,8 @@ ++++ +title = "Home" +images = [] +template = "index.html" +in_search_index = true ++++ + +Hi there! I'm Lukas. This is the website where I host notes about programming, homelabbing, and other topics that interest me. Not all topics are technical. diff --git a/content/about.md b/content/about.md new file mode 100644 index 0000000..3cc455f --- /dev/null +++ b/content/about.md @@ -0,0 +1,16 @@ ++++ +title = "About" +images = [] +template = "page.html" +in_search_index = true ++++ + +## The Person + +Heya, I'm a guy who likes tech. My background is mostly in computer security with a focus on the IT/networks side of things rather than the programming side. However, I do a lot of automation and hobby projects with Python. + +## The Site + +There's a proverb in tech: "nothing is more permanent than a temporary solution". Sometimes it’s your “temporary fix” cron job to clear out caches instead of adding more storage. Sometimes it’s the quick setup server that you put in place to hotfix one that crashed. Either way, you end up seeing it years later and go “*that’s* still being used?”. + +I couldn’t think of a blog name and nearly named it “temp”. Then I realized that I was falling right into that trap. May as well own it. diff --git a/content/contact.md b/content/contact.md new file mode 100644 index 0000000..e3c14ab --- /dev/null +++ b/content/contact.md @@ -0,0 +1,12 @@ ++++ +title = "Contact" +images = [] +template = "page.html" +in_search_index = true ++++ + +The best way to contact me is by email - "lukas" @ this domain. I am not explicitly writing it due to spam, but I'm sure you can figure it out. ;) + +## Other Ways to Find Me +I don't have a very large or public internet presence. Here are some other sites where you can find me: +- [github.com/ldv8434](github.com/ldv8434) diff --git a/content/posts/2023/06/_index.md b/content/posts/2023/06/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/06/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/2023/06/resolved-email-delivery.md b/content/posts/2023/06/resolved-email-delivery.md new file mode 100644 index 0000000..f8e73b4 --- /dev/null +++ b/content/posts/2023/06/resolved-email-delivery.md @@ -0,0 +1,20 @@ ++++ +title = "Resolved: Email Delivery Issues with Google Domains Email Aliases" +date = 2023-06-15 +[taxonomies] +tags= ["resolved"] ++++ + +This post is a combination announcement and “hey, this is how you fix this” post. + +I’ve used Google Domains as my DNS registrar for several years now, and I’ve used the email address hinted at [on my Contact page](/contact) as a personal address for just about as long. Unfortunately, it wasn’t until recently that I learned that some senders *can’t* or *won’t* send to it because it is set up as an alias instead of a proper address. + +The solution provided by Google is to use a Google Workspace email instead. I guess I’ll just have to add another address to Thunderbird. + +--- + +For anyone who’s curious, here’s what Google has to say about the matter [on their help page](https://support.google.com/domains/answer/3251241?hl=en#zippy=%2Cemail-forwarding-delivery-issues-from-sender): + +> You may not get the email forwarded to you by senders with specific email authentication settings. Regardless of your mail settings in Google Domains, some email senders have rules that prevent their mail from being delivered with email forwarding systems. +> +> **Tip:** To avoid delivery issues, use a custom email with Google Workspace instead of email forwarding. diff --git a/content/posts/2023/07/_index.md b/content/posts/2023/07/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/07/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/2023/07/encryption-flashcards.md b/content/posts/2023/07/encryption-flashcards.md new file mode 100644 index 0000000..962c842 --- /dev/null +++ b/content/posts/2023/07/encryption-flashcards.md @@ -0,0 +1,8 @@ ++++ +title = "Encryption Flashcards" +date = 2023-07-19 +[taxonomies] +tags= ["shortnotes"] ++++ + +I think I added an extra 80 or so cards today just for encryption algorithms’ key lengths, block sizes, etc… I don’t expect they will be used in a lot of CISSP questions, but I’ll ace whatever questions involve them. diff --git a/content/posts/2023/07/prompt-engineering.md b/content/posts/2023/07/prompt-engineering.md new file mode 100644 index 0000000..893ff6d --- /dev/null +++ b/content/posts/2023/07/prompt-engineering.md @@ -0,0 +1,8 @@ ++++ +title = "\"Prompt Engineering\"" +date = 2023-07-28 +[taxonomies] +tags= ["shortnotes"] ++++ + +A small realization just came to me: there’s a certain irony to “prompt engineering” being something that people try to teach as if it’s a programming discipline. Wasn’t the goal of the natural language models to make it so that people can speak normally and get the output they want? Shouldn’t that mean that “prompt engineering” should be the same as a communications or writing class? diff --git a/content/posts/2023/07/security-models.md b/content/posts/2023/07/security-models.md new file mode 100644 index 0000000..a38d2d6 --- /dev/null +++ b/content/posts/2023/07/security-models.md @@ -0,0 +1,8 @@ ++++ +title = "Security Models" +date = 2023-07-14 +[taxonomies] +tags= ["shortnotes"] ++++ + +I’m reviewing security models in preparation for taking the CISSP exam. It’s something I haven’t had a lot of reason to think about since I took a class on it in college. Bell-LaPadula, Biba, Clark-Wilson, etc…. I’m glad I know what Anki is now. diff --git a/content/posts/2023/07/youtube-music.md b/content/posts/2023/07/youtube-music.md new file mode 100644 index 0000000..d369703 --- /dev/null +++ b/content/posts/2023/07/youtube-music.md @@ -0,0 +1,9 @@ ++++ +title = "YouTube Music" +date = 2023-07-24 +[taxonomies] +tags= ["shortnotes"] ++++ + +A funny thing I’ve noticed about YouTube Music: it doesn’t seem to take your recently-listened-to music into account when showing quick recommendations if you have YouTube history turned off. I can listen to as much blues or j-rock as I want, but it doesn’t start showing those as quick recommends until I hit the like button on a track. Unfortunately, this also means that things I liked a while ago don’t appear anymore. + diff --git a/content/posts/2023/08/_index.md b/content/posts/2023/08/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/08/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/2023/08/cissp.md b/content/posts/2023/08/cissp.md new file mode 100644 index 0000000..8f4fdfb --- /dev/null +++ b/content/posts/2023/08/cissp.md @@ -0,0 +1,59 @@ ++++ +title = "My Experience Studying For and Taking the CISSP Exam" +date = 2023-08-15 +[taxonomies] +tags= ["security","certification"] ++++ + +This post is about studying for and taking the (ISC)2 CISSP exam. I’ll talk about my experiences, what I thought was useful, what I thought wasn’t useful, and some high-level information about the test. I will not go into specifics about the questions on the test. + +## Studying + +I primarily used five sources for the exam: + +- Sybex CISSP Official Study Guide +- Sybex CISSP Official Practice Tests +- LearnZApp CISSP official practice test app +- Anki +- r/cissp subreddit (for meta-information) + +I had access to the first two resources through O’Reilly’s online learning subscription – which I had for free through my alma mater’s library. Both were good resources, but had multiple clear errors in the answer key (as in, mentioning something not even referenced in the question or having same answer associated with a different letter). + +I took the first practice test before starting on the Official Study Guide (OSG) book. I scored a 60%. I completed the chapter questions after reading each chapter of the OSG, then did another two practice tests. By the end, I was scoring ~80%. + +I cannot really recommend paying for the official practice test app if you have the practice test book. A good number of the questions in the app were identical to the ones in the book. Also, the “readiness score” isn’t helpful – I had a 55% when I took my exam. + +## Anki + +Anki, for those unfamiliar, is a [spaced-repetition software](https://en.wikipedia.org/wiki/Spaced_repetition) for flashcards. I’ve used it for Japanese, trivia, grep flags, tmux keybinds, and more. It is one of the most useful pieces of software I’ve ever used. + +I used two Anki decks: one of my own creation, and [lfionxkshine](https://www.reddit.com/user/lfionxkshine/)‘s CISSP 10k deck. While lfionxkshine‘s deck is very impressive for it’s size, I didn’t continue using it for a few reasons: + +- There are a very large number of cards that are things I’d already committed to long-term memory. It makes no sense to spend such a large amount of time sorting through to find the useful cards instead of making them myself. +- Some of the cards were contained incomplete or incorrect information. + - One question was “What layer of the ring protection scheme is not normally implemented?” +This question is both in the Anki deck as an open-ended question, and in the official practice test app as a multiple-choice question with the options 0, 1, 3, and 4. Both formats list “Layer 1” as the correct answer – but the practice test app goes on to tell that the full answer is layers 1 and 2. +It’s better to not study the card at all than to memorize the wrong thing. + +It’s worth noting that I’d made over 700 cards while studying but only reviewed about half of them by the time I took the exam (see below in the Taking section to see why). + +## r/CISSP Subreddit + +I spent a good amount of time before the exam browsing the r/cissp subreddit to see what others’ thoughts were on exam prep materials and the format of the exam. + +## College Degree and Hands-On Experience + +I have a four-year degree in computer security, and just under 2 years’ experience doing penetration testing. I think that had a significant impact on how much less I had to study compared to others. + +--- + +## Taking + +The days leading up to my test were, in short, a mess. The clothes dryer broke. The AC broke and it would get into the 90s some days. I was doing prep for a job offer I had just accepted. I’d already bought the exam voucher and wanted to use it before things got even more hectic. I was prepared to fail the exam, but come out with better knowledge of what the questions would be like and where I would need to study more. + +The sign-in process for the exam was uneventful. The only difference between it and any other certification test I’ve taken (Sec+, CC, etc…) is that I had to get my palms scanned a bunch. + +Again, I will not discuss details of questions. All I will say is that the questions were generally less technical than I expected, and slightly easier than some of the practice questions. + +I would often see comments on the subreddit about the exam drilling you on whatever it thinks is what you struggle with the most as you get further in the exam. I don’t think that I experienced that. I’d have a difficult question from a random domain, followed by a really easy question from a different one. I was fairly certain that I was going to fail with how easy some of the questions near the end were. Then I hit submit on Q125 and was told my test was over. I passed. + diff --git a/content/posts/2023/09/19.md b/content/posts/2023/09/19.md new file mode 100644 index 0000000..04ead6a --- /dev/null +++ b/content/posts/2023/09/19.md @@ -0,0 +1,10 @@ ++++ +title = "Using Vi[m]" +date = 2023-09-19 +[taxonomies] +tags= ["shortnotes"] ++++ + +I'm finally giving Vi[m] a try. It's hard to get used to it after using `nano` for so long. Surprisingly, it's not the `:wq` or insert mode stuff that is catching me, but the fact taht I can't go to the previous/next ling by pressing left/right at the line ends. + +(Yes, I realize I can modify this in the .vimrc file but I'm attempting to keep it as close to default as possible since I work on so many different systems.) diff --git a/content/posts/2023/09/_index.md b/content/posts/2023/09/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/09/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/2023/09/defaults.md b/content/posts/2023/09/defaults.md new file mode 100644 index 0000000..abe0665 --- /dev/null +++ b/content/posts/2023/09/defaults.md @@ -0,0 +1,19 @@ ++++ +title = "When do you change the default settings (on tools/apps?)" +description = "Musing on defaults" +date = 2023-09-28 +[taxonomies] +tags= ["uncategorized"] ++++ + +That question is rhetorical. I already have a good system in place for myself. + +I will *always* review privacy settings. It’s rare that privacy settings will default to the more private options unless you’re using certain open source software such as KDE. Perhaps ironically, I’ll usually enable the anonymous usage statistics in those cases. The reason for that is a story for another post, though. + +Things like keybinds and such are another story. Sometimes I’ll change the settings to whatever gets me the most use, and sometimes I’ll avoid changing the defaults as much as possible. + +On one hand, if I have something like Joplin or Firefox, I’ll obsess over each setting and get it configured *just so*. These are tools that I’ll likely only use from devices I own, and only from a small percentage of them at that. I’ll only need to do that setup once every few months. + +However, take something like `Vim` or `tmux`: I use these very often (more often than Joplin for sure), but I use them on almost every system I work on. This includes systems that aren’t owned by me or systems that I’ll only *use* once every few months. If someone else uses the system, they should be able to expect how these tools will behave. + +It’s for this reason that I haven’t configured tmux, Vim, or similar tools on my own systems. I use the system default settings for tmux. I think I have small vanity options configured for Vim (syntax highlighting, hard tabs), but nothing more. diff --git a/content/posts/2023/10/02.md b/content/posts/2023/10/02.md new file mode 100644 index 0000000..a9698af --- /dev/null +++ b/content/posts/2023/10/02.md @@ -0,0 +1,16 @@ ++++ +title = "python `or [default]`" +date = 2023-10-02 +[taxonomies] +tags= ["shortnotes"] ++++ + +Did you know that you can use the “or” keyword in python to set a “default” for a variable? + +```py +variable_name = value_or_none() or "default value!" +``` + +Over five years since I started using Python, and I’m only learning this now. I wish I knew about it sooner. + + diff --git a/content/posts/2023/10/_index.md b/content/posts/2023/10/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/10/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/2023/10/backups.md b/content/posts/2023/10/backups.md new file mode 100644 index 0000000..57c8181 --- /dev/null +++ b/content/posts/2023/10/backups.md @@ -0,0 +1,12 @@ ++++ +title = "Backups and YAML" +date = 2023-10-29 +[taxonomies] +tags= ["shortnotes"] ++++ + +Finally doing something that I should have done a long time ago – adding a second (and in some places, first) backup to my systems. BorgBase won over rsync.net for price, and over Backblaze B2 for ease of use with Borg. Bonus points for also making my GUI of choice – Vorta. + +Additionally, I’m automating as much as possible with Ansible. I still loathe YAML for configuring anything, but Ansible nearly makes that worth it. ;p + + diff --git a/content/posts/2023/10/bash-reverse-search.md b/content/posts/2023/10/bash-reverse-search.md new file mode 100644 index 0000000..42d0827 --- /dev/null +++ b/content/posts/2023/10/bash-reverse-search.md @@ -0,0 +1,11 @@ ++++ +title = "Bash history search" +date = 2023-10-05 +[taxonomies] +tags= ["shortnotes"] ++++ + +Another useful tip for Linux users and admins: you can search your command history in bash with `Ctrl+r`. Typing something and hitting it again will search backward through commands that match that pattern. It saves a lot of time compared to pressing up repeatedly. + + + diff --git a/content/posts/2023/10/resolved-libvirt-isolated.md b/content/posts/2023/10/resolved-libvirt-isolated.md new file mode 100644 index 0000000..f847a13 --- /dev/null +++ b/content/posts/2023/10/resolved-libvirt-isolated.md @@ -0,0 +1,20 @@ ++++ +title = "Resolved: Connection Issues on a libvirt Isolated Network to Router" +date = 2023-10-07 +[taxonomies] +tags= ["resolved"] ++++ + +Quick answer: The isolated network auto-allocates the first address to a virtual interface for the hypervisor host. Check that your router’s IP isn’t set to the same thing. + +--- + +I was having issues the other night with my homelab setup. Specifically, devices would randomly be unable to communicate with the router. Pinging worked, but accessing OPNsense’s web interface wasn’t. It wasn’t firewall issues either. + +After running `tcpdump` on the opnsense box, I realized that my traffic wasn’t even reaching it. I double checked that they were on the same vnet (they were), then checked the ARP table on the client I was using. Sure enough, the MAC of the supposed gateway wasn’t the same as the OPNsense interface. + +I took down all other VMs except the router and client to isolate the issue in case it was a misconfiguration, but the issue persisted. This meant it had to be something involving libvirt. + +Sure enough, a quick Google search revealed that libvirt will still allocate an address for the host on isolated subnets – even if you disable services such as DHCP. It defaults to the first IP address in the subnet. + +I changed the OPNsense LAN IP from .1 to .254 and the issue was resolved. diff --git a/content/posts/2023/10/surreal-blog.md b/content/posts/2023/10/surreal-blog.md new file mode 100644 index 0000000..5b450fc --- /dev/null +++ b/content/posts/2023/10/surreal-blog.md @@ -0,0 +1,11 @@ ++++ +title = "A surreal blog" +date = 2023-10-31 +updated = 2023-11-13 +[taxonomies] +tags= ["shortnotes"] ++++ + +I found a blog by someone who works at a polar research station. [Their post on nights](https://brr.fyi/posts/polar-night) there is surreal. It reminds me of Signalis. + +EDIT: I realized while porting this post to Zola that I posted this on Halloween. It wasn't my intention to match that with a horror game reference, but it fits! :D diff --git a/content/posts/2023/10/wordpress-gripes.md b/content/posts/2023/10/wordpress-gripes.md new file mode 100644 index 0000000..994c157 --- /dev/null +++ b/content/posts/2023/10/wordpress-gripes.md @@ -0,0 +1,12 @@ ++++ +title = "Wordpress Gripes" +date = 2023-10-30 +[taxonomies] +tags= ["shortnotes"] ++++ + +Late night thought before work maintenance: I don’t particularly enjoy WordPress’ writing interface. It doesn’t feel suitable for quick or technical writing. Customizing the site feels like fighting against the tool. + +Pelican (the static site generator) felt a lot nicer. Writing in markdown feels much nicer than using Gutenberg or the Classic Editor (plus I can do version control with Git!) and .html.j2 files for customization is easier than WordPress’ syntax. I’m hardly a Python dev – I don’t wanna be a web dev too. + + diff --git a/content/posts/2023/11/_index.md b/content/posts/2023/11/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/11/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/2023/11/google.md b/content/posts/2023/11/google.md new file mode 100644 index 0000000..6302601 --- /dev/null +++ b/content/posts/2023/11/google.md @@ -0,0 +1,18 @@ ++++ +title = "Google finally feels worse" +date = 2023-11-06 +[taxonomies] +tags= ["shortnotes"] ++++ + +I didn’t really agree with statements about Google’s search getting worse until today. + +Using search would usually give me what I wanted within the first few results. All I’d need to do was skip past the inevitable Amazon link that would show up. + +But for the past few days, I feel like I’ve had more and more “junk” in it. + +- Links that look like they are for a specific post on a forum, but take me to the main page instead. +- Links for blogs that look like they were written by an AI. +- Links that go to entirely different websites than those they appear to be for. + +It’s admittedly tiring and makes me want to restart my habit of bookmarking more sites. diff --git a/content/posts/2023/_index.md b/content/posts/2023/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/2023/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/_index.md b/content/posts/_index.md new file mode 100644 index 0000000..3fbf406 --- /dev/null +++ b/content/posts/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Example posts" +sort_by = "date" +template = "posts.html" +page_template = "post.html" +transparent = true ++++ + +Posts diff --git a/content/posts/typography.md b/content/posts/typography.md new file mode 100644 index 0000000..8f3328c --- /dev/null +++ b/content/posts/typography.md @@ -0,0 +1,9 @@ ++++ +title = "Zola Test" +description = "Test of Zola" +date = 2023-01-16 +[taxonomies] +tags= ["Zola", "test"] ++++ + +This is a test of Zola as a website SSG. diff --git a/content/search.md b/content/search.md new file mode 100644 index 0000000..25a1272 --- /dev/null +++ b/content/search.md @@ -0,0 +1,6 @@ ++++ +title = "Search" +images = [] +template = "search.html" +in_search_index = false ++++ \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..9b8bc12 --- /dev/null +++ b/index.html @@ -0,0 +1,7 @@ +{% extends "base.html" %} + +{% block content %} +

+ This is my blog made with Zola. +

+{% endblock content %} diff --git a/sass/base.scss b/sass/base.scss new file mode 100644 index 0000000..8b68a1b --- /dev/null +++ b/sass/base.scss @@ -0,0 +1,142 @@ +/*Resets*/ +@import "normalize.css"; + +/*Site Wide Components*/ +@import "variables.css"; +@import "utilities.css"; +@import "typography.css"; +@import "header.css"; +@import "footer.css"; +@import "search.css"; + +/* Page Specific Components*/ +@import "blog.css"; +@import "gallery.css"; +@import "tags.css"; +@import "custom.css"; + +body { + font-family: var(--font-base); + word-wrap: break-word; + background-color: var(--bg-color); + color: var(--text-color); + max-width: 50em; + font-size: 1.25rem; + margin: 0 auto; + padding: 0 3rem; + line-height: 1.8rem; + display: flex; + min-height: 100vh; + flex-direction: column; + overflow-y: scroll; +} + +::selection { + text-shadow: none; + color: #fff; + background: var(--text-color); +} + +article { + flex: 1; + margin-bottom: 2rem; +} + +.highlight-handle { + background: var(--text-color); + border-radius: 4px; + color: var(--white); + padding: 4px 8px; +} + +pre { + margin-bottom: 0; + margin-top: 0; + padding: 20px; +} + +hr { + border: 0; + height: 1px; + margin: 2rem 0; + background: var(--light-grey); +} + +pre, +textarea { + overflow: auto; +} + +img { + margin: 10px auto 10px auto; + max-width: 100%; + display: block; +} + +a img { + border: none; +} + +figure { + margin: 0; + text-align: center; +} + +fieldset { + border: 0; + margin: 0; + padding: 0; +} + +textarea { + resize: vertical; +} + +.site-name { + color: var(--text-color); +} + + +@media (max-width: 900px) { + body { + padding: 0 2rem; + } + + h1 { + font-size: 2.2rem; + } + + h2 { + font-size: 1.8rem; + } + + h3 { + font-size: 1.5rem; + } + + h4 { + font-size: 1.3rem; + } +} + +@media (max-width: 600px) { + body { + padding: 0 1rem; + } + + h1 { + font-size: 1.8rem; + } + + h2 { + font-size: 1.6rem; + } + + h3 { + font-size: 1.2rem; + } + + h4 { + font-size: 1rem; + } +} \ No newline at end of file diff --git a/sass/blog.scss b/sass/blog.scss new file mode 100644 index 0000000..bff1ed3 --- /dev/null +++ b/sass/blog.scss @@ -0,0 +1,126 @@ +.posts { + margin: 0; + padding: 0; +} + +.post { + display: block; + + article { + img { + // max-width: 800px; + max-height: 90vh; + border-radius: var(--border-radius); + + &.small { + + max-height: none; + width: 100%; + max-width: 500px; + } + } + } +} + +.post-header { + display: flex; + align-items: center; +} + +.post-header .meta .date { + margin-right: 2rem; + width: 64px; + text-align: center; + color: var(--heading-color); +} + +.post-header .meta .date .day { + font-family: "Playfair Display", serif; + font-weight: 700; + line-height: 0.75em; + font-size: 2em; + display: block; + margin: 0 0 0.5rem 0; +} + +.post-header .meta .date .rest { + display: block; + font-size: 0.75em; +} + +.post .title.small { + margin: 0 0 10px 0; +} + +.post .post-header { + margin: 30px 0; +} + +.post-header h1.title { + margin: -10px 0 0 0; +} + +.archive-year { + display: flex; + width: 100%; + justify-content: center; + align-items: center; + text-align: center; +} + +.archive-year:before, +.archive-year:after { + content: ""; + border-top: 1px solid var(--light-grey); + margin: 0 20px 0 0; + flex: 1 0 20px; +} + +.archive-year:after { + margin: 0 0 0 20px; +} + +.youtube { + + position: relative; + padding-bottom: 56.25%; + + iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } +} + +.draft { + color: var(--red); + font-weight: bold; + font-size: 1rem; + margin-left: 0.5rem; + display: inline-block; +} + +.tags { + list-style: none; + padding: 0; + margin: 1rem 0; + + + li { + display: inline-block; + + + a { + display: block; + margin: 0.25rem; + padding: 0.25rem 1rem; + font-size: 0.9em; + background-color: transparent; + border: 1px solid var(--primary); + border-radius: var(--border-radius); + } + + } +} \ No newline at end of file diff --git a/sass/custom.scss b/sass/custom.scss new file mode 100644 index 0000000..43ea6d6 --- /dev/null +++ b/sass/custom.scss @@ -0,0 +1 @@ +// Override this scss file in your own sass folder to add your own styling \ No newline at end of file diff --git a/sass/footer.scss b/sass/footer.scss new file mode 100644 index 0000000..93dce9c --- /dev/null +++ b/sass/footer.scss @@ -0,0 +1,9 @@ +footer { + text-align: right; + font-size: 0.75em; + border-top: 1px solid var(--light-grey); + padding: 1rem 0; + display: flex; + justify-content: space-between; + align-items: center; +} \ No newline at end of file diff --git a/sass/gallery.scss b/sass/gallery.scss new file mode 100644 index 0000000..7e06294 --- /dev/null +++ b/sass/gallery.scss @@ -0,0 +1,50 @@ +.gallery { + margin: 0; + padding: 0; + list-style: none; + display: flex; + flex-wrap: wrap; + align-items: flex-start; + justify-content: flex-start; + align-content: space-around; + +} + +.thumbnail { + display: inline-block; + width: 10rem; + // Body has 1rem horizontal padding + width: calc(100% / 6); + + a { + display: inline-block; + padding: 0.5rem; + + img { + margin: 0; + border-radius: var(--border-radius); + } + } +} + +@media (max-width: 850px) { + .thumbnail { + width: calc(100% / 5); + } +} + +@media (max-width: 700px) { + .thumbnail { + width: calc(100% / 4); + } +} + +@media (max-width: 550px) { + .thumbnail { + width: calc(100% / 3); + + a { + padding: 0.25rem; + } + } +} \ No newline at end of file diff --git a/sass/header.scss b/sass/header.scss new file mode 100644 index 0000000..17cab7b --- /dev/null +++ b/sass/header.scss @@ -0,0 +1,89 @@ +header { + margin: 2rem 0; +} + +header .avatar { + float: left; + margin: 0 2rem 0 0; +} + +header .links { + line-height: 2.2rem; +} + +header .avatar img { + width: 4rem; + height: 4rem; + overflow: hidden; + border-radius: 100%; +} + +header .site-description { + display: flex; + justify-content: space-between; + align-items: center; + + p { + margin: 0 0 1rem 0; + } +} + +header h1 { + margin: 0; + // line-height: 0.2rem; +} + +.social li, +.social ul { + margin: 0; + padding: 0; +} + +.social li { + display: inline-block; + list-style: none; + margin: 0 30px 0 0; +} + +.social a { + color: #333; +} + +.social a:hover { + color: var(--primary); +} + +.social nav { + margin: 0; + padding: 0; + border: none; + min-width: 50px; + margin-left: 15px; +} + +.social ul svg { + max-height: 15px; +} + +nav { + border-top: 1px solid var(--light-grey); + padding-top: 1rem; +} + +nav a { + margin-right: 1.5rem; +} + +@media (max-width: 900px) { + .social li { + margin: 0; + } + + nav a { + margin-right: 0.5rem; + } + + header { + margin: 1rem 0; + } +} \ No newline at end of file diff --git a/sass/normalize.scss b/sass/normalize.scss new file mode 100644 index 0000000..bb6e2a7 --- /dev/null +++ b/sass/normalize.scss @@ -0,0 +1,351 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { + /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { + /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/sass/search.scss b/sass/search.scss new file mode 100644 index 0000000..5cc3079 --- /dev/null +++ b/sass/search.scss @@ -0,0 +1,58 @@ +.search-container input { + + width: 100%; + padding: 0.5rem 1rem; + margin-bottom: 2rem; + font-weight: bold; + background-color: transparent; + border: 1px solid var(--light-grey); + border-radius: var(--border-radius); +} + +.search-container input:focus { + border-color: var(--dark-grey); +} + + +.search-results { + display: none; + color: var(--text-color); + overflow: auto; + +} + +.search-results__items { + list-style: none; +} + +.search-results li { + margin-top: 1rem; + border-bottom: 1px solid var(--light-grey); +} + +.search-results li:last-child { + border-bottom: none; +} + +.search-results li:first-of-type { + margin-top: 0; +} + +.search-results__item { + margin-bottom: 1rem; + + h3 { + margin: 1rem 0 0 0; + } + + p { + margin: 0 0 0 0; + padding-bottom: 1rem; + } +} + +.search-results__item a { + font-size: 1.2rem; + display: inline-block; + margin-bottom: 0.5rem; +} \ No newline at end of file diff --git a/sass/tags.scss b/sass/tags.scss new file mode 100644 index 0000000..ec302c3 --- /dev/null +++ b/sass/tags.scss @@ -0,0 +1,9 @@ +.tag-cloud { + margin-top: 20px; +} + +.tag-cloud li { + display: inline; + list-style-type: none; + padding-right: 20px; +} diff --git a/sass/typography.scss b/sass/typography.scss new file mode 100644 index 0000000..a9a344e --- /dev/null +++ b/sass/typography.scss @@ -0,0 +1,89 @@ +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: var(--font-headings); + line-height: 1.3em; + margin: 30px 0 20px 0; + font-weight: bold; + color: var(--heading-color); +} + +h1 { + font-size: 2.7rem; +} + +h2 { + font-size: 2.3rem; +} + +h3 { + font-size: 1.95rem; +} + +h4 { + font-size: 1.55rem; +} + +h5 { + font-size: 1.25rem; +} + +h6 { + font-size: 1rem; +} + +blockquote { + margin-left: 1rem; + font-style: italic; + font-size: 1.4rem; + font-family: Georgia, bitstream charter, serif; + border-left: 3px solid; + border-color: var(--text-color); + padding-left: 20px; +} + +blockquote cite { + font-size: 70%; + opacity: 0.8; +} + +blockquote em { + font-weight: 600; +} + +a { + color: var(--primary); + text-decoration: none; + +} + +a:hover, +a.active { + text-decoration: underline; +} + +input:focus, +textarea:focus { + outline: none; +} + +pre, +code { + font-family: var(--font-monospace); + text-rendering: optimizeLegibility; +} + +@media (max-width: 700px) { + + h1, + h2, + h3, + h4, + h5, + h6 { + letter-spacing: 1px; + } +} \ No newline at end of file diff --git a/sass/utilities.scss b/sass/utilities.scss new file mode 100644 index 0000000..eebe31b --- /dev/null +++ b/sass/utilities.scss @@ -0,0 +1,19 @@ +.center { + text-align: center; +} + +.ad-info { + border-left: solid 0.3rem #64dd17; + line-height: 24px; + overflow: hidden; + padding: 0.8rem; + background-color: rgba(100, 221, 23, 0.1); +} + +.ad-warning { + border-left: solid 0.3rem #fa9209; + line-height: 24px; + overflow: hidden; + padding: 0.8rem; + background-color: red; +} diff --git a/sass/variables.scss b/sass/variables.scss new file mode 100644 index 0000000..0336112 --- /dev/null +++ b/sass/variables.scss @@ -0,0 +1,17 @@ +:root { + --primary: #661fff; + --red: red; + --heading-color: #1a043b; + --text-color: #3e3f4d; + --bg-color: #f8f5f3; + --black: #212529; + --white: #fdfdfd; + --dark-grey: #343334; + --gray: #616060; + --light-grey: #ccc; + --lighter-gray: #f6f6f6; + --font-base: 'Andada Pro', sans-serif; + --font-monospace: menlo, monaco, lucida console, liberation mono, dejavu sans mono, bitstream vera sans mono, courier new, monospace, serif; + --font-headings: 'Andada Pro', sans-serif; + --border-radius: 0.5rem; +} \ No newline at end of file diff --git a/static/inky.png b/static/inky.png new file mode 100644 index 0000000000000000000000000000000000000000..d2af4148f2b75e7d720895390f2d8efb97b30197 GIT binary patch literal 5294 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 p>e$phtm6WCQn)vjVV>mAS21xv3ZJe*le<5OM$j literal 0 HcmV?d00001 diff --git a/static/js/search.js b/static/js/search.js new file mode 100644 index 0000000..58fc153 --- /dev/null +++ b/static/js/search.js @@ -0,0 +1,180 @@ +function debounce(func, wait) { + var timeout; + + return function () { + var context = this; + var args = arguments; + clearTimeout(timeout); + + timeout = setTimeout(function () { + timeout = null; + func.apply(context, args); + }, wait); + }; +} + +// Taken from mdbook +// The strategy is as follows: +// First, assign a value to each word in the document: +// Words that correspond to search terms (stemmer aware): 40 +// Normal words: 2 +// First word in a sentence: 8 +// Then use a sliding window with a constant number of words and count the +// sum of the values of the words within the window. Then use the window that got the +// maximum sum. If there are multiple maximas, then get the last one. +// Enclose the terms in . +function makeTeaser(body, terms) { + var TERM_WEIGHT = 40; + var NORMAL_WORD_WEIGHT = 2; + var FIRST_WORD_WEIGHT = 8; + var TEASER_MAX_WORDS = 30; + + var stemmedTerms = terms.map(function (w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var termFound = false; + var index = 0; + var weighted = []; // contains elements of ["word", weight, index_in_document] + + // split in sentences, then words + var sentences = body.toLowerCase().split(". "); + + for (var i in sentences) { + var words = sentences[i].split(" "); + var value = FIRST_WORD_WEIGHT; + + for (var j in words) { + var word = words[j]; + + if (word.length > 0) { + for (var k in stemmedTerms) { + if (elasticlunr.stemmer(word).startsWith(stemmedTerms[k])) { + value = TERM_WEIGHT; + termFound = true; + } + } + weighted.push([word, value, index]); + value = NORMAL_WORD_WEIGHT; + } + + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + } + + index += 1; // because we split at a two-char boundary '. ' + } + + if (weighted.length === 0) { + return body; + } + + var windowWeights = []; + var windowSize = Math.min(weighted.length, TEASER_MAX_WORDS); + // We add a window with all the weights first + var curSum = 0; + for (var i = 0; i < windowSize; i++) { + curSum += weighted[i][1]; + } + windowWeights.push(curSum); + + for (var i = 0; i < weighted.length - windowSize; i++) { + curSum -= weighted[i][1]; + curSum += weighted[i + windowSize][1]; + windowWeights.push(curSum); + } + + // If we didn't find the term, just pick the first window + var maxSumIndex = 0; + if (termFound) { + var maxFound = 0; + // backwards + for (var i = windowWeights.length - 1; i >= 0; i--) { + if (windowWeights[i] > maxFound) { + maxFound = windowWeights[i]; + maxSumIndex = i; + } + } + } + + var teaser = []; + var startIndex = weighted[maxSumIndex][2]; + for (var i = maxSumIndex; i < maxSumIndex + windowSize; i++) { + var word = weighted[i]; + if (startIndex < word[2]) { + // missing text from index to start of `word` + teaser.push(body.substring(startIndex, word[2])); + startIndex = word[2]; + } + + // add around search terms + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + startIndex = word[2] + word[0].length; + teaser.push(body.substring(word[2], startIndex)); + + if (word[1] === TERM_WEIGHT) { + teaser.push(""); + } + } + teaser.push("…"); + return teaser.join(""); +} + +function formatSearchResultItem(item, terms) { + return '
' + + `

${item.doc.title}

` + + `

${makeTeaser(item.doc.body, terms)}

` + + '
'; +} + +function initSearch() { + var $searchInput = document.getElementById("search"); + var $searchResults = document.querySelector(".search-results"); + var $searchResultsItems = document.querySelector(".search-results__items"); + var MAX_ITEMS = 20; + + var options = { + bool: "AND", + fields: { + title: { boost: 2 }, + body: { boost: 1 }, + } + }; + var currentTerm = ""; + var index = elasticlunr.Index.load(window.searchIndex); + + $searchInput.addEventListener("keyup", debounce(function () { + var term = $searchInput.value.trim(); + if (term === currentTerm || !index) { + return; + } + $searchResults.style.display = term === "" ? "none" : "block"; + $searchResultsItems.innerHTML = ""; + currentTerm = term; + if (term === "") { + return; + } + + var results = index.search(term, options); + if (results.length === 0) { + $searchResults.style.display = "none"; + return; + } + + for (var i = 0; i < Math.min(results.length, MAX_ITEMS); i++) { + var item = document.createElement("li"); + item.innerHTML = formatSearchResultItem(results[i], term.split(" ")); + $searchResultsItems.appendChild(item); + } + }, 150)); +} + + +if (document.readyState === "complete" || + (document.readyState !== "loading" && !document.documentElement.doScroll) +) { + initSearch(); +} else { + document.addEventListener("DOMContentLoaded", initSearch); +} diff --git a/static/processed_images/inky.14c2be2bf4556dcc.png b/static/processed_images/inky.14c2be2bf4556dcc.png new file mode 100644 index 0000000000000000000000000000000000000000..685f9edeb1848e3fcaf16143f4c18da92f2157a7 GIT binary patch literal 9968 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 literal 0 HcmV?d00001 diff --git a/static/processed_images/inky.509a176c30944214.png b/static/processed_images/inky.509a176c30944214.png new file mode 100644 index 0000000000000000000000000000000000000000..12048d3478fe627f2f07d3fb2c6dd6c6c4759e96 GIT binary patch literal 2848 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 literal 0 HcmV?d00001 diff --git a/static/processed_images/inky.7c7bddb9fe90360e.png b/static/processed_images/inky.7c7bddb9fe90360e.png new file mode 100644 index 0000000000000000000000000000000000000000..2f538171f63ebab945412fba676627ab8e0c6b0d GIT binary patch literal 5673 zcmcIoeLR!v|KFIWAu~h>u}lxAp&Cv!&(HIe()ZLsh{`{7V-~9nf9O75F3M zaK%fm@4f#Y*KZQh0RfU#!o!`N9n+sM%h3Iv;Q{ey6oizQ)#^Y#C=nHugfu zsJfc?ygG>S8nBGxqqf+JRUD?N8$$Dau5VQLl%7<5;c#WyvbmeP^~&-lxsmQYubrz^ zE6){O`DNSYU;8^Z9KjEd9t+JB8L!i#QyK4KLyT<2{kGGbYi5WlzwJ?BXS=J`EUB8a zUqilH&uLhh<%VIA_EPz_2rZo!S%w?xq0#mSR$bn43$k8+wbVtH#`yg_;>bjxvfxAh z(AqGm&{OjdrZ~n80*xwMw+f~0Qn#w8#rzJk? zJ!2l=YGNXj&SrP4Rru8|r)R=9?hCs~22!SL#6$H+_bOCUMB?h$nfGdz z!&Q4vxeQ5bnR-FeTGFyv_S+D18s2bHbdvRvu1C|at*1J8Rt_E`C<9@T{JJ=x6y8p( z!g8yU9xcT@S`zAh_C@=u4vR|)Os5&oc5_)$m=9k?1<|&PZduqfH^}espj>hkR1#6>= zO8y@;E$c)Tty;KMnM^q`j~%_b#ViPyghzEkC2^~El53K-Fy3;87Rzm{JLL)h+@J#o;ak0>uxO~wLRut?ws z`6S_3;;+-U)G5$%{J-=U{Mat)^;?Ac>CdScX3f-9(wb8_l<>n$^Aya79K2X&&M0t# zOy6V${+0TiielE}xQKiD<7N+hiWn9LV5FGv(au->O-sTYY4*2`zv)b+w{vv3941-) zbYF#7H{LoU`br-aNvHg&K!>G>A6Wa!TfzHB#%LlOje_?RRhxtnobGGhRYBuZoD|yI zErjJ$qTztPw_DJVqU9&eQIS9NSu@T^ib>Vq4)4d(IICxWY|;zb@w7+o3XZyXWH)rz z@>96=y0Dj+z_V!Kk7bUJajTcbZTbuCoLd#g7K0qPt6471&HC%^qK^SDU7A@#E+#AN zV}t#`DgqU%>wKLk-e9Hi^uW^SvI>|tuv7~FEQMz;y}U;`a4w-Q{*+fcb+f~~XpJ=0 z(DfQvJH|;66LKJF`Q<_Y2WgNhVqXtF9JhFL{c;Sk?$Tahi^0CUlcZcjmOx=H1ygJbpAnp02O@;NyG0Ka-q z2&u03hQ)KL;vKv<h0J$6f?p+C1^dWtHYSLLNGSlAa4800KdDV zU~S^B{e$rDN#%A!p^HJ=XiJ4I&n_fQ?J)LmigiNmTEE5O zIySI0ERMu9cT?Pt!@9sd{a4r#h`{+MM#cl7EiZT?Ad%TFZu9}F^g>qd9WzeO0=6m_ zc>mMvqRV~Mt@OA)WtBw_&au#Znw(!tWl7THxwbZ&e;2Hb}4PsN=MUVMC^!-Cnl7Y$`w-LdIUkSh6d)1MN! z2SupIj;=QDQ~`UwdO~dTVw+$+o{%i{2k{yieOIDOeNp> zd~Nz&*MaRboL^9L4uRr_3!R#cB_;`h=;o=J5_G`RT1-bU4CN#140#2+q3=+xRBD#)z{$)qhVKT}HW2 zaLQ@NdK>}=2#|KqW%)@&|2olBXuSBSDqUdYaTG&nfS

2FF<=PDjIDNc%+{+J>U%^eSY*0JMR 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 + + + {%- block general_meta -%} + {{ head::general_meta() }} + {%- endblock general_meta -%} + {%- block og_preview -%} + {{ social::og_preview() }} + {%-endblock og_preview -%} + {% block rss -%} + + {% endblock rss -%} + {% if config.extra.google_analytics_tag_id -%} + + + + {% endif -%} + + + + + + + + + +

+ {% if config.extra.avatar -%} + + {% endif -%} + +

{{ config.title }}

+
+
+

{{ config.description }}

+
+ +
+
+ {% block content -%} + {% endblock -%} +
+
+ +

© {{ config.title }} {{ now() | date(format="%Y") }} + + {# If you remove the powered by information, it would be appreciated if + you could add information & links somewhere else on your site to credit + those that have created your tools. #} + {% if config.extra.disable_powered_by and config.extra.disable_powered_by == true %}{% else %}
Powered by Zola. Theme: Inky.{% endif %} +

+
+ + {% block body_end -%} + {% endblock body_end -%} + + diff --git a/templates/blog-page.html b/templates/blog-page.html new file mode 100644 index 0000000..f0f638e --- /dev/null +++ b/templates/blog-page.html @@ -0,0 +1,9 @@ +{% extends "base.html" %} + +{% block content %} +

+ {{ page.title }} +

+

{{ page.date }}

+{{ page.content | safe }} +{% endblock content %} diff --git a/templates/blog.html b/templates/blog.html new file mode 100644 index 0000000..6e7d799 --- /dev/null +++ b/templates/blog.html @@ -0,0 +1,13 @@ +{% extends "base.html" %} + +{% block content %} +

+ {{ section.title }} +

+ +{% endblock content %} diff --git a/templates/gallery.html b/templates/gallery.html new file mode 100644 index 0000000..d8ef9f3 --- /dev/null +++ b/templates/gallery.html @@ -0,0 +1,24 @@ + +{% extends "base.html" -%} +{% block content -%} +

{{ section.title }}

+
{{ section.content | safe }}
+{% for year, posts in section.pages | group_by(attribute="year") -%} + +{% endfor -%} +{% endblock content -%} + diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..ba611ea --- /dev/null +++ b/templates/index.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block content %} +
{{ section.content | safe }}
+ +{% endblock content %} \ No newline at end of file diff --git a/templates/index.md b/templates/index.md new file mode 100644 index 0000000..3a46836 --- /dev/null +++ b/templates/index.md @@ -0,0 +1,8 @@ +{% extends "base.html" %} + +{% block content %} +

+ This is my blog made with Zola. +

+

Click here to see my posts.

+{% endblock content %} diff --git a/templates/macros/head.html b/templates/macros/head.html new file mode 100644 index 0000000..3bab5ea --- /dev/null +++ b/templates/macros/head.html @@ -0,0 +1,11 @@ +{% macro general_meta() %} + + + + + +{% endmacro general_meta %} \ No newline at end of file diff --git a/templates/macros/hooks.html b/templates/macros/hooks.html new file mode 100644 index 0000000..0ceba70 --- /dev/null +++ b/templates/macros/hooks.html @@ -0,0 +1,10 @@ +{% extends "base.html" %} + +{# Page hooks #} +{% macro post_above_content(page) %}{% endmacro post_above_content %} +{% macro post_below_content(page) %}{% endmacro post_below_content %} +{% macro post_below_tags(page) %}{% endmacro post_below_tags %} + +{% macro posts_below_title(page) %} + {{page.description}} +{% endmacro posts_below_title %} \ No newline at end of file diff --git a/templates/macros/images.html b/templates/macros/images.html new file mode 100644 index 0000000..aae4130 --- /dev/null +++ b/templates/macros/images.html @@ -0,0 +1,52 @@ +{% extends "base.html" %} + + +{% macro image(path, src, alt, class="") -%} +{{ alt }} +{% endmacro image -%} + +{# + Original author: crepererum https://github.com/getzola/even/pull/48/files + Adapted to Inky template by jimmyff +#} + +{% macro responsive_image(path, src, alt, default_size, sizes, class="") -%} +{% if config.extra.image_resizing_disabled and config.extra.image_resizing_disabled == true -%} +{{ image(path=path, src=src, alt=alt, class=class) -}} +{% else -%} + {% set abspath = path ~ src -%} + {% set meta = get_image_metadata(path=abspath) -%} + {% set width = meta.width -%} + {% set srcset_list = [] -%} + {% for s in sizes -%} + {% if width >= s -%} + {% set resized = resize_image(format=config.extra.image_format, path=abspath, width=s, op="fit_width", quality=config.extra.image_quality) -%} + {% set element = resized.url ~ " " ~ s ~ "w" -%} + {% set_global srcset_list = srcset_list | concat(with=[element]) -%} + {% endif -%} + {% endfor -%} + {% set default_resized = resize_image(format=config.extra.image_format, path=abspath, width=default_size, op="fit_width", quality=config.extra.image_quality) -%} + {{ alt }} +{% endif -%} +{% endmacro responsive_image -%} + + +{% macro responsive_thumbnail(path, src, alt, default_size, sizes, class="") -%} +{% if config.extra.image_resizing_disabled and config.extra.image_resizing_disabled == true -%} +{{ image(path=path, src=src, alt=alt, class=class) -}} +{% else -%} + {% set abspath = path ~ src -%} + {% set meta = get_image_metadata(path=abspath) -%} + {% set width = meta.width -%} + {% set srcset_list = [] -%} + {% for s in sizes -%} + {% if width >= s -%} + {% set resized = resize_image(format=config.extra.image_format, path=abspath, width=s, height=s, op="fill", quality=config.extra.thumbnail_quality) -%} + {% set element = resized.url ~ " " ~ s ~ "w" -%} + {% set_global srcset_list = srcset_list | concat(with=[element]) -%} + {% endif -%} + {% endfor -%} + {% set default_resized = resize_image(format=config.extra.image_format, path=abspath, width=default_size, height=default_size, op="fill", quality=config.extra.thumbnail_quality) -%} + {{ alt }} +{% endif -%} +{% endmacro responsive_thumbnail -%} \ No newline at end of file diff --git a/templates/macros/opengraph.html b/templates/macros/opengraph.html new file mode 100644 index 0000000..18a036b --- /dev/null +++ b/templates/macros/opengraph.html @@ -0,0 +1,53 @@ +{% macro og_preview() %} +{{config.title}} | {{social::og_title() }} + + + + + + + + + + + + +{% endmacro og_preview %} + +{% macro og_description() %} {%- if section -%} {%- if +section.description -%} {{ section.description }} {%- else -%} {{ +config.description }} {%- endif -%} {%- elif page -%} {%- if page.summary | +string -%} {{ page.summary | striptags | truncate(length=200) }} {%- elif +page.description -%} {{ page.description }} {%- else -%} {{ config.description +}} {%- endif -%} {%- endif -%} +{% endmacro og_description %} + +{% macro og_title() %} +{%- if section -%} +{%- if section.title -%} +{{ section.title | striptags }}{%- else -%} +{{ config.description }}{%- endif -%} +{%- elif page -%} +{%- if page.title -%} +{{ page.title | striptags }} +{%- else -%} +{{ config.description }} +{%- endif -%} +{%- elif term -%} + {%- if term.name -%} + {{ term.name | striptags }} + {%- else -%} + {{ config.description }} + {%- endif -%} +{%- elif taxonomy -%} +{%- if taxonomy.name -%} {{ taxonomy.name | striptags }} {%- else -%} {{ config.description }} {%- endif -%} {%- endif -%} +{% endmacro og_title %} + +{% macro og_image() %} +{%- if page.extra.og_preview_img -%} +{{ get_url(path=page.extra.og_preview_img) | safe }} +{%- endif -%} +{% endmacro og_image %} diff --git a/templates/page.html b/templates/page.html new file mode 100644 index 0000000..bdc5472 --- /dev/null +++ b/templates/page.html @@ -0,0 +1,12 @@ +{% extends "base.html" -%} +{% block title -%} +{{ config.title }} | {{page.title}} +{% endblock title -%} +{% block content -%} +

+ {{ page.title }} +

+
+ {{ page.content | safe }} +
+{% endblock content -%} \ No newline at end of file diff --git a/templates/post.html b/templates/post.html new file mode 100644 index 0000000..a5c7d49 --- /dev/null +++ b/templates/post.html @@ -0,0 +1,33 @@ + +{% extends "base.html" %} +{% block content %} + +
+
+
+
+ {{ page.date | date(format='%d')}} + {{ page.date | date(format='%b %y')}} +
+
+ +
+

{{ page.title }} {% if page.draft %}Draft{% endif %}

+
+
+ {{ hooks::post_above_content(page=page) }} +
{{ page.content | safe }}
+ + + {{ hooks::post_below_content(page=page) }} + {% if page.taxonomies is containing ("tags") %} +
    + {% for tag in page.taxonomies["tags"] %} +
  • {{ tag }}
  • + {% endfor %} +
+ {% endif %} + + {{ hooks::post_below_tags(page=page) }} +
+{% endblock content %} diff --git a/templates/posts.html b/templates/posts.html new file mode 100644 index 0000000..aa4dbaf --- /dev/null +++ b/templates/posts.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} {% block content %} +

{{ section.title }}

+ +
{{ section.content | safe }}
+ +{% for year, posts in section.pages | group_by(attribute="year") %} +
    +

    {{ year }}

    + {% for post in posts %} +
  • +
    +
    +
    + {{ post.day }} + {{ post.date | date(format='%b') }} +
    +
    +
    +
    + {{ post.title }} + {% if post.draft %}(Draft){% endif %} +
    + {{ hooks::posts_below_title(page=post) }} +
    +
    +
  • + {% endfor %} +
+{% endfor %} {% endblock content %} diff --git a/templates/search.html b/templates/search.html new file mode 100644 index 0000000..38283ae --- /dev/null +++ b/templates/search.html @@ -0,0 +1,22 @@ +{% extends "base.html" %} + +{% block content %} + + + + + +
+ +
+
+
+
+ + +{% endblock content %} + + diff --git a/templates/shortcodes/image.html b/templates/shortcodes/image.html new file mode 100644 index 0000000..16ed7dc --- /dev/null +++ b/templates/shortcodes/image.html @@ -0,0 +1,3 @@ + +{% import "macros/images.html" as images -%} +{{ images::responsive_image(path=page.colocated_path, src=src, default_size=config.extra.images_default_size, sizes=config.extra.images_sizes, alt=alt, class=class | default(value="") ) }} diff --git a/templates/shortcodes/image_original.html b/templates/shortcodes/image_original.html new file mode 100644 index 0000000..f272c01 --- /dev/null +++ b/templates/shortcodes/image_original.html @@ -0,0 +1,3 @@ + +{% import "macros/images.html" as images -%} +{{ images::image(path=page.path, src=src, alt=alt, class=class | default(value="") ) }} diff --git a/templates/shortcodes/spotify.html b/templates/shortcodes/spotify.html new file mode 100644 index 0000000..a7eae3d --- /dev/null +++ b/templates/shortcodes/spotify.html @@ -0,0 +1,5 @@ +
+ +
\ No newline at end of file diff --git a/templates/shortcodes/thumbnail.html b/templates/shortcodes/thumbnail.html new file mode 100644 index 0000000..29f7853 --- /dev/null +++ b/templates/shortcodes/thumbnail.html @@ -0,0 +1,22 @@ +{# + Original author: crepererum https://github.com/getzola/even/pull/48/files + Adapted to Inky template by jimmyff +#} + +{% if config.extra.image_resizing_disabled and config.extra.image_resizing_disabled == true %} +{{ alt }} +{% else %} +{% set abspath = "./" ~ page.path ~ src %} +{% set meta = get_image_metadata(path=abspath) %} +{% set width = meta.width %} +{% set srcset_list = [] %} +{% for s in config.extra.thumbnail_sizes %} +{% if width >= s %} +{% set resized = resize_image(format=config.extra.image_format, path=abspath, width=s, height=s, op="fill", quality=config.extra.thumbnail_quality) %} +{% set element = resized.url ~ " " ~ s ~ "w" %} +{% set_global srcset_list = srcset_list | concat(with=[element]) %} +{% endif %} +{% endfor %} +{% set default_resized = resize_image(format=config.extra.image_format, path=abspath, width=config.extra.images_default_size, height=config.extra.images_default_size, op="fill", quality=config.extra.thumbnail_quality) %} +{{ alt }} +{% endif %}1 \ No newline at end of file diff --git a/templates/shortcodes/youtube.html b/templates/shortcodes/youtube.html new file mode 100644 index 0000000..d86d43d --- /dev/null +++ b/templates/shortcodes/youtube.html @@ -0,0 +1,7 @@ +
+ +
\ No newline at end of file diff --git a/templates/taxonomy_list.html b/templates/taxonomy_list.html new file mode 100644 index 0000000..3e53637 --- /dev/null +++ b/templates/taxonomy_list.html @@ -0,0 +1,14 @@ +{% extends "base.html" %} + +{% block content %} + +

{{ taxonomy.name | capitalize }}

+ +{% if terms %} + +{% endif %} +{% endblock content %} \ No newline at end of file diff --git a/templates/taxonomy_single.html b/templates/taxonomy_single.html new file mode 100644 index 0000000..25e9003 --- /dev/null +++ b/templates/taxonomy_single.html @@ -0,0 +1,29 @@ +{% extends "base.html" %} + +{% block content %} +

{{taxonomy.name | capitalize }} » {{ term.name | capitalize }}

+ +{% for year, posts in term.pages | group_by(attribute="year") %} +
    +

    {{ year }}

    + {% for post in posts %} +
  • +
    +
    +
    + {{ post.day }} + {{ post.date | date(format='%b') }} +
    +
    +
    +
    + {{ post.title }} + {% if post.draft %}(Draft){% endif %} +
    + {{ hooks::posts_below_title(page=post) }} +
    +
    +
  • + {% endfor %} +
+ {% endfor %}{% endblock content %} \ No newline at end of file