From 1b359aa81295b67d42654126ee725b274e31d792 Mon Sep 17 00:00:00 2001 From: Pagwin Date: Sun, 23 Nov 2025 16:05:37 -0500 Subject: [PATCH] lots of changes so remake of static site generator can handle the blog markdown --- posts/HackBU2024.md | 2 + posts/gh_actions.md | 59 ---------------------------- posts/how.md | 19 +++++++++ posts/invidious_and_goals.md | 12 +++++- posts/micro_blogs.md | 6 +-- posts/micro_blogs_2.md | 5 +++ posts/mineflayer_why.md | 19 +++++++++ posts/new_blog_who_dis.md | 3 +- posts/rust_enums.md | 8 +++- posts/rust_type_hiccups.md | 8 +++- posts/soft_eng_class_weekly_notes.md | 2 - posts/speedrun.md | 2 + posts/universal_proc_tut.md | 19 ++++++++- posts/writing_things.md | 7 ++-- 14 files changed, 96 insertions(+), 75 deletions(-) diff --git a/posts/HackBU2024.md b/posts/HackBU2024.md index dbbaf7a..ff6d87e 100644 --- a/posts/HackBU2024.md +++ b/posts/HackBU2024.md @@ -97,6 +97,7 @@ services: - backend ``` and here's an nginx config + ```nginx worker_processes 1; @@ -172,6 +173,7 @@ Okay I didn't say this outright before so I'll say it now. Google's documentatio >`~oia@ here's what I wrote trying to implement that + ```rs fn enc_float(num:f64)->String{ let mut working:i32 = (num*1e5).round() as i32; diff --git a/posts/gh_actions.md b/posts/gh_actions.md index e2b31a5..31a9ca5 100644 --- a/posts/gh_actions.md +++ b/posts/gh_actions.md @@ -31,18 +31,12 @@ Then for a couple of reasons wanted to write a blog article about progress on [P So with inspiration in my heart to go and do stuff with Github actions I began. First off I needed to set up the condition for my workflow running which was a pretty simple as I wasn't really doing anything interesting here. ```yaml - on: - push: - branches: - - master - ``` - ## The jobs I knew due to reading some pages on Github's action market place and previous context that I would need to have at least 3 if not more steps @@ -82,35 +76,22 @@ Conveniently while `$user_home/.ssh/authorized_keys` is the default location for anyways yeah this is what I initially(spoiler I change it) wrote for Github actions to go and deploy the app. ```yaml - uses: up9cloud/action-rsync@master - env: - HOST: pagwin.xyz - KEY: ${{secrets.SSH_KEY}} - TARGET: /var/www/pagwin.xyz/ - ``` With that I saved the file to `.github/website-publish.yml` and felt a mild sense of accomplishment. In hindsight that sense and first file are hilarious and while I would love to immediately explain why first I want to take a second to show a step I added after I finished dealing with my stupidity. That step is a cleanup step that deletes the old site before copying over the new one so people can't snoop around in redundant files. I implemented that with this tidbit. ```yaml - uses: appleboy/ssh-action@master - with: - host: pagwin.xyz - username: website - key: ${{secrets.SSH_KEY}} - script: rm -rf /var/www/pagwin.xyz/* - ``` @@ -126,79 +107,39 @@ The obvious act of stupidity if you paid attention to what I wrote is that I sav Overall I'm very happy I did this because it gave me a nice bit of practical understanding of how to set up Github actions for future projects. I hope reading about my technical spaghetti VPS and idiocy wasn't too boring. Oh yeah for those who care this is what the yaml file looked like in the end ```yaml - name: Website publish - - - on: - push: - branches: - - master - - - jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Code Checkout - uses: actions/checkout@v2 - with: - submodules: true - fetch-depth: 0 - - name: Hugo Setup - uses: peaceiris/actions-hugo@v2 - with: - hugo-version: '0.91.2' - - name: Build - run: hugo --minify - - name: Clean - uses: appleboy/ssh-action@master - with: - host: pagwin.xyz - username: website - key: ${{secrets.SSH_KEY}} - script: rm -rf /var/www/pagwin.xyz/* - - name: Deploy - uses: up9cloud/action-rsync@master - env: - HOST: pagwin.xyz - USER: website - KEY: ${{secrets.SSH_KEY}} - SOURCE: ./public/* - TARGET: /var/www/pagwin.xyz/ - ``` diff --git a/posts/how.md b/posts/how.md index 8fe7729..e1958e5 100644 --- a/posts/how.md +++ b/posts/how.md @@ -5,18 +5,25 @@ date: 2020-09-30 draft: false tags: [] --- + ## Prelude + Before we get to how I actually made this site let's discussed how I failed to make this site(repeatedly). I was inspired to make a simple website/blog from [this blog post](https://k1ss.org/blog/20191004a), I rapidly regretted having that as my main inspiration. I tried setting up scripts for generating pages using the output from pandoc, making the pages look nice and what not as well as make a script for generating an rss feed but rapidly realized that all of this was going to be a pain and gave up. Rinse and repeat a couple of times over several months to a year or so. ## Actually making this website + One day(2 days before this post was written actually) I was browsing reddit when I came across [this comment](https://www.reddit.com/r/linuxquestions/comments/j0wcfj/i_hand_you_a_computer_with_a_minimalistic_install/g6vxxxj/) and realized that I'm an idiot because static site generators exist and what I had previously been doing was basically writing my own, I may still write my own but more so as a project on it's own than as something that's contributing to something else. After that work went relatively smoothly with me spending the first day learning what the fuck hugo(no I didn't do my research into static site generators don't judge me okay) is then on the second day I actually started to get into writing all the stuff for the site. For my theme as you may already know if you've looked at the footer for this website I'm using liquorice as my theme. I chose it for being simple, very nice for reading text(what I expect will be the main thing that's done on this website) and because I just liked the overall feel. There were some aspects that I felt the need to improve though such as the homepage being a bit more than just a list of every page on the site, something about lists(I don't remember what), making the subsections of these blogs and other pages in the future jump points in case I write something that would actually benefit from those jump points and not just a short one page piece and finally making the links actually look visually distinct from the text beyond simply being bold. There are probably other changes I'm forgetting and in the future I expect I'll tweak this further but that's all for now. Some of those tweaks will be me making the website smaller and more compressed following the original spirit of that kiss blog and I can already see some points where I can shave some size off but that's a story for another time. ## Making the jump points + most of those points are pretty easy if you read hugo's documentation and are willing to try random things but the jump points are a slight challenge and something worth writing about in more detail. First things first ignoring all this being generated from markdown causing some oddities how do we make a jump point on a webpage? Well with anchor tags of course! + ```html some content doesn't matter ``` + this is nice now if somebody goes to `example.com/#some_name_or_something_idk` their browser will jump them straight down to wherever that anchor tag is. But it doesn't jump to the anchorblock when we click on it it simply sets our url and if we reload it jumps to it. *Editor's note: as I write this I'm unsure if I'm an idiot who didn't need to do the work with this javascript I'm about to talk about so it may well be possible that it's unnecessary and the above code already does that*. So in order to fix that we'll be adding an event to our anchor element like this. + ```html some text ``` + Technically the event could be added by adding an onclick parameter to the anchor element in the dom but we we start dealing with another problem which I'll get to after explaining this it'll be way cleaner to just use `addEventListener` anyway the code is relatively self explanatory but I'll explain it anyways. Our element has an id that we attached to it by adding the parameter `id="name"` we can get our element in our code by asking the browser to give our element to us using the id as a reference to find the element with the method `document.getElementById`. We could totally just use `document.getElementsByName` and take the first element from that but I personally chose to add and use the id. With `addEventListener` we can attach a function that'll be called when an event fires in this case the click event for when the user clicks on the anchor element. The function in question take the event object given to it and takes out the dom element that was actually clicked on with the target property. We then scroll to that dom element with scrollIntoView. Now all we need to do is have it so that when we write out our header elements we just surround them with anchor elements and... wait. ## We didn't write those header elements though + Oh yeah we didn't write the header elements in the first place they're written in from whatever markdown generator that hugo uses. Well how do we handle this? There may be some way of changing how hugo generates html from the markdown but that sounds hard let's just write some javascript. + ```js let elems = document.getElementsByTagName("h2"); for(let elem of elems){ @@ -39,23 +49,32 @@ for(let elem of elems){ }); } ``` + Ok so you already understand that last bit with the event listener and what not so allow me to explain the rest. `document.getElementsByTagName` is the same as `document.getElementById` except it gets more than one element and does it by their tag name. The for loop iterates through all the elements we just got and through each iteration we can refer to the element we're on by the variable `elem`. The parameter of `outerHTML` isn't used very often `innerHTML` and `innerText` are used more often because most people only want to control the text inside of a dom element but want to leave the outer tags untouched but in this case that's useful because we actually want to add anchor tags around our header tags which is what we do. Hooray the problem with the markdown generation not allowing fine enough control was solved. Now about adding that script in to do that work. ## Adding the script in + You'd think this was simple and it kinda was but keep in mind that I've only been using hugo for less than 3 days at this point. Besides that I also only wanted this script in the single pages or the pages that blog/articles/whatever were on and not on list pages which list out all the pages as the list pages also used h2 elements but I didn't want the h2 elements there to be modified by this script. Thankfully this was easy because I had shortly before hand wanted to do something similar with a stylesheet but man adding in that stylesheet had some nuisances. The first thing I found of use for this purpose was [cond](https://gohugo.io/functions/cond/) but I still needed to figure out how to test for whether the page was a list or not so I started looking through hugo's page variables and I found 3 candidates for this `.IsNode`, `.IsPage` and `.IsSection` with the last one just being the negate. I got somewhat frustrated when I found none of these useful for what I was trying to do. Eventually I stumbled upon `.Kind` and bumbled about a bit trying to figure out how to test for a `.Kind` of page until I found [eq](https://gohugo.io/functions/eq/). So great I now can test for whether a page is a page I want the stylesheet applied to so + ```html {{ cond (eq .Page.Kind "page") "" "" }} ``` + should work right? Nope nope nope for multiple reasons nope. For one thing trying to put the base url with curly brackets didn't work because apparently hugo doesn't do curly brackets in curly brackets also when I opened the page in a browser the tag and all the tags beneath it(which were placed in the head in the partial template btw) are now in the body??? Also I made it seem like I had solved the cond thing before this came up but that was happening at this point as well. So first things first how do we put a variable midway through a tag that we're inserting? Well apparently the answer to that is [printf](https://gohugo.io/functions/printf/)(I personally would've named it something like format rather than printf even if it uses something called printf internally but maybe that's just me) so now we have. + ```html {{ cond (eq .Page.Kind "page") (printf "" .Site.BaseURL) "" }} ``` + which is closer but it still jumps into the body for some reason. That reason as it turns out is because Hugo ~~being somewhat annoying because it decides not to warn you for failing to be explicit about whether you want a tag as a tag~~ being very cool and safe escaping all the tags to prevent cross site scripting/injection or whatever else problems in code that you're explicitly writing out in a folder for templates. Ugh anyways after running the output of the printf through [SafeHTML](https://gohugo.io/functions/safehtml/) we get this final iteration that works how I want it to of. + ```html {{ cond (eq .Page.Kind "page") ( safeHTML (printf "" .Site.BaseURL)) "" }} ``` + Nothing about this changes for the script that we want on our blog pages only other than that we replace link with a script tag. ## Conclusion + This was fun and I'm glad I found out about the existance of [hugo](https://gohugo.io/). I'll probably update this site in the future and this blog will probably get outdated but unless I decide the site looks almost completely different run into a very annoying or interesting problem or completely remake the site for osme reason or another I probably won't update this blog or release any other blogs with updates on changes I make to this site(and knowing me even when those things come up I probably won't write about them) one of the things I want to change is the links to different platforms/feeds/whatever but based on already made efforts I think I'll save that for another time. diff --git a/posts/invidious_and_goals.md b/posts/invidious_and_goals.md index 999d57a..8661de4 100644 --- a/posts/invidious_and_goals.md +++ b/posts/invidious_and_goals.md @@ -13,13 +13,13 @@ tags: [] So recently I’ve engaged in a renewed push to be productive somewhat consistently and this time it just may work(unlike the 3-5 other times). With this push, I’ve decided to begin moving off of youtube by going down to my subscriptions. In order to do that I implemented a few small projects. ## Getting the feeds(but not really) + So to enforce that my initial plan was to only watch the content I saw through an RSS feed, preferably via mpv. In order to do that I needed a list of channel ids corresponding to the youtube channels I was subscribed to. In order to get that I could’ve gone through and manually gotten each channel id through youtube’s web interface… But that would take forever and ain’t nobody got time for that manual labor when you can spend twice as long automating(although doing that automation gave me experience that may save me time now). So to do that I looked into google’s [Youtube Api](https://developers.google.com/youtube/v3) and found a way to get a list of [subscriptions](https://developers.google.com/youtube/v3/docs/subscriptions/list). But to make use of that I’d need to go and learn how to do stuff with OAuth. Thankfully after faffing about a bit I realized that there’s an [npm package](https://www.npmjs.com/package/googleapis) that does a lot of that work for me. Anyways with that, it was time to ~~steal example code~~ write software, oh hey where did all that preexisting code come from? ## Oh the callbacks Well, that code came from [here](https://developers.google.com/youtube/v3/quickstart/nodejs) and oh my god do they use callbacks. Personally, I think callbacks suck and are the worst way of having some sort of asynchronous task. So I did a decent amount of refactoring to convert things to use promises. However much to my chagrin I found that I couldn’t use async await because apparently the npm package didn’t return normal promises, or maybe something else was happening I’m not entirely sure looking over the code now with intellisense but trust me when I tried back when I was figuring this out it didn’t work and it was annoying. Though that said I also don’t know why I couldn’t/wouldn’t convert from the weird promises to normal promises due to that being relatively easy with js’s promise api but I digress. - ## Getting the subs I don’t remember if I implemented the code that got my subscriptions concurrently with the callback refactor or if I did it after. In any case, all of the code to get the subscriptions is 2 relatively small functions. @@ -48,12 +48,15 @@ function handlePage(authority,response){ } ``` Yeah, pretty simple but allow me to explain what bits of these 2 functions are doing and why. + ```js var service = google.youtube("v3"); //... let items = response.data.items; ``` + Both of these are done primarily for convenience so I'm not writing the same thing over and over again. If you notice the service one uses the inferior var instead of let it's because I was lazy and didn't change that bit from the example code. And now that I'm done with the bit you can find that code [here](https://developers.google.com/youtube/v3/quickstart/nodejs). + ```js return service.subscriptions.list({ mine:true, @@ -63,24 +66,30 @@ Both of these are done primarily for convenience so I'm not writing the same thi pageToken: page ? page:"" }); ``` + The only other bit of code in the getSubscriptions function just calls the method in the npm package to make a request for the subscriptions of the user who provided Oauth authorization, 50 results at a time specifically giving things under the "snippet" category of data. For the pageToken bit what it's doing is if it's null/undefined it specifies it as an empty string so we get the first page and if it's not then it's just itself so we can get the next page. + ```js for(let item of items){ console.log(item.snippet.title+" ".repeat(60-item.snippet.title.length)+item.snippet.resourceId.channelId); } ``` + This bit of code just outputs each of the fetched channels' names and their id such that all the ids visually align for the part of my brain that wants everything to look neat. The reason I wanted things in this format was that I wanted to manually filter out the channels I didn't watch so having the channel name with the id would make it faster to get through for the obvious ones. The reason I was console.logging instead of writing to a file via the fs module was because I was lazy and decided to just have the information output via stdout and redirected to a file via a > operator in bash. + ```js if(response.data.nextPageToken){ getSubscriptions(authority, response.data.nextPageToken) .then(handlePage.bind(null,authority)) } ``` + This last bit of code checks to see if there's a token for the next page of subscriptions and if there is it gets them, providing the nextPageToken to do just that in the getSubscriptions function and once the new response pops up it sends it to handlePage. More specifically what happens is I use the bind method of js functions as a way to have a partial function which can otherwise be said as a function that already has one of its arguments passed in. Until somewhat recently I wasn't aware you could use bind like that but one time when I was commenting an amount of annoyance at js not having a built-in function that allows for the easy construction of partial functions like Python's functools.partial or Haskell's function currying built into the language in a discord server a friend pointed out that the bind method can be used for that so the more you know I guess. ## Why I specified but not really for getting the feeds As it turns out what I wanted could be better accomplished by self-hosting an [Invidious](https://github.com/iv-org/invidious) instance. However, my weird format that I had of my subs wouldn't work and I didn't want to redo filtering out channels I don't want so I decided to make a script that would make an opml file which is one of the file types that invidious could import. To do that I wrote a rust script. + ```rs use std::fs::File; use std::io::Read; @@ -108,6 +117,7 @@ fn gen_middle(line:&str)->String{ format!("",name,name,id) } ``` + TLDR on that whole bunch of code is I have a constant string as the start of the file which gets output. Then there's a middle that's generated from the list of channels in that weird format the previous script generated such that every entry gets put into the template `"` and then all the channel entries are joined together. After that, I put a constant value at the end to close everything up. Developing that script there was a bit of a hiccup where Invidious wouldn't take it because the channel name only had the first word due to me making an initial mistake which I eventually fixed. ### Wait what about hosting an Invidious instance? diff --git a/posts/micro_blogs.md b/posts/micro_blogs.md index bd455d6..8f2fa3e 100644 --- a/posts/micro_blogs.md +++ b/posts/micro_blogs.md @@ -16,14 +16,13 @@ Same deal as the [speedrun blog](https://pagwin.xyz/blog/speedrun/) putting down ## The entire set plus one more in the set -Let me start off where I started off[[1]](#1) lets say that someone who we shall name Steve anonymously puts a bounty on themselves which is described as "$1 in addition to whatever money Steve has on their person" how much money should be payed out to whoever collects the bounty on Steve and where would it come from? Well in this case the way that reality works and the set of actors involved constrains us to the answer of "whatever money Steve has on their person" and no more. This answer would correspond to addition being equivalent to the set union operator. That does work but with slightly different context it seems like the answer would be different, for example pretend that a god came down and said "I am going to transfer ten humans in addition to the entire human population to a habitable planet in a different galaxy". In this case specifying ten humans in addition implies that we're transferring a number of humans greater than just the current human population but also ten more because otherwise why specify those ten humans. The problem that I have is how many humans come out on the other side. "Why not just the current population plus ten?" well because transfer implies they already exist and aren't being created in that moment so the number should be the same and also my brain thinks there's an interpretation or slightly different wording where you could argue there'll be infinitely many humans. I'm pretty sure this is a [type 5 paradox](https://youtu.be/ppX7Qjbe6BM?t=2035) +Let me start off where I started off[1] lets say that someone who we shall name Steve anonymously puts a bounty on themselves which is described as "$1 in addition to whatever money Steve has on their person" how much money should be payed out to whoever collects the bounty on Steve and where would it come from? Well in this case the way that reality works and the set of actors involved constrains us to the answer of "whatever money Steve has on their person" and no more. This answer would correspond to addition being equivalent to the set union operator. That does work but with slightly different context it seems like the answer would be different, for example pretend that a god came down and said "I am going to transfer ten humans in addition to the entire human population to a habitable planet in a different galaxy". In this case specifying ten humans in addition implies that we're transferring a number of humans greater than just the current human population but also ten more because otherwise why specify those ten humans. The problem that I have is how many humans come out on the other side. "Why not just the current population plus ten?" well because transfer implies they already exist and aren't being created in that moment so the number should be the same and also my brain thinks there's an interpretation or slightly different wording where you could argue there'll be infinitely many humans. I'm pretty sure this is a [type 5 paradox](https://youtu.be/ppX7Qjbe6BM?t=2035) ## Excel with types/static analysis? So I think I started thinking about this when I rewatched [this Matt Parker video](https://www.youtube.com/watch?v=yb2zkxHDfUE). I'm wondering if there's a niche for some spreadsheet software is intended to require the user to specify types for cells or a full sql-esque table or something in addition to doing some nice lints/static analysis like you would see in software to minimize errors. My mind has also feature creeped this idea out a bit to have this program capable of exporting some file package/sql database and an executable so you can have something maintaining the structure of the data while other programs do automated stuff in the hopes that Ludicity doesn't come in for a [drop kick](https://ludic.mataroa.blog/blog/i-will-fucking-dropkick-you-if-you-use-that-spreadsheet/). - -## PSA please check to make sure browser zoom works okay on your site [[2]](#2) +## PSA please check to make sure browser zoom works okay on your site [2] And also phones and screen readers but the browser zoom one is the one that affected me when I'm writing this (over 2 months after the prior 2 sections). Particularly if you have a blog with some text content that's centered with whitespace as the margins and I zoom in I don't just want to see the text get bigger I also want the margins to shrink so the text has more room. Reason being so zooming isn't proportional to additional scrolling. Thanks. @@ -31,7 +30,6 @@ And also phones and screen readers but the browser zoom one is the one that affe I was exploring the CSS to understand how the margins shrank for my site but not the offending site and I noticed on both sites that the css styling jumped a bit as I shrank and grew the page width only to realize the reason was because of some [CSS if statement(s)](https://css-tricks.com/a-complete-guide-to-css-media-queries/). I don't know why I previously thought you could deal with this in some other way but TIL. - ## How long should I make these? I've never thought about this before but how long should I make blogs? How long should I make microblog dumps? I don't know I should probably think about that... later I will think about that later. diff --git a/posts/micro_blogs_2.md b/posts/micro_blogs_2.md index e5748b8..5adc765 100644 --- a/posts/micro_blogs_2.md +++ b/posts/micro_blogs_2.md @@ -39,6 +39,7 @@ Example: Is it pseudo elements/pseudo classes? If so why not use this pattern where the `style` tag is directly next to what the CSS is touching? + ```html ``` + Replace `unique_name` with gibberish as needed. Once [scope](https://developer.mozilla.org/en-US/docs/Web/CSS/@scope) is ubiquitous you could even do this. + ```html @@ -74,6 +77,7 @@ Once [scope](https://developer.mozilla.org/en-US/docs/Web/CSS/@scope) is ubiquit ``` + Maybe the gibberish solution doesn't scale without additional tooling and the scope solution will become standard practice in a few years, idk man. ### pre-publishing update @@ -160,6 +164,7 @@ I made an [Excalidraw](https://excalidraw.com/) drawing for that post. I modified the svg export to add a style tag which makes the colors follow Excalidraw's light vs dark theming depending on a css media query. Thankfully whoever did light/dark theming was super lazy and just did a filter which I could replicate in CSS rather than needing to painstakingly pick every color from their site. After removing their filter from the XML I just added the following to the SVG. + ```xml