aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--content/blog/2024-01-08-dont-say-hello.org32
-rw-r--r--content/blog/2024-01-09-macos-customization.org120
-rw-r--r--content/blog/2024-01-13-local-llm.org94
-rw-r--r--content/blog/2024-01-26-audit-dashboard.org123
-rw-r--r--content/blog/2024-01-27-tableau-dashboard.org89
-rw-r--r--content/blog/2024-02-06-zfs.org122
-rw-r--r--content/blog/2024-02-13-ubuntu-emergency-mode.org43
-rw-r--r--content/blog/2024-02-21-self-hosting-otter-wiki.org37
-rw-r--r--content/blog/2024-03-13-doom-emacs.org205
-rw-r--r--content/blog/2024-03-15-self-hosting-ddns-updater.org93
-rw-r--r--content/blog/2024-03-29-org-blog.org123
-rw-r--r--content/blog/2024-04-06-convert-onenote-to-markdown.org88
-rw-r--r--content/blog/2024-04-08-docker-local-web-server.org73
-rw-r--r--content/blog/2024-04-18-mu4e.org78
-rw-r--r--content/blog/2024-05-03-ubuntu-on-macos.org80
-rw-r--r--content/blog/2024-06-19-deprecated-trusted-gpg-fix.org68
-rw-r--r--content/blog/2024-07-11-emacs-on-ipad.org52
17 files changed, 700 insertions, 820 deletions
diff --git a/content/blog/2024-01-08-dont-say-hello.org b/content/blog/2024-01-08-dont-say-hello.org
index b2926bf..eaeae61 100644
--- a/content/blog/2024-01-08-dont-say-hello.org
+++ b/content/blog/2024-01-08-dont-say-hello.org
@@ -3,25 +3,25 @@
#+description:
#+slug: dont-say-hello
-I recently came back from a winter break and have started working
-again... only to immediately run into the dilemma of people sending me
-cliffhanger messages again.
+I recently came back from a winter break and have started working again... only
+to immediately run into the dilemma of people sending me cliffhanger messages
+again.
* No Hello
-A year or two ago, I discovered [[https://nohello.net/en/][no hello]]
-and have thought about it often since then. I've even sent it to a few
-people since then (who wouldn't take offense to it).
+A year or two ago, I discovered [[https://nohello.net/en/][no hello]] and have thought about it often since
+then. I've even sent it to a few people since then (who wouldn't take offense to
+it).
-I work in a fast-paced environment where efficiency is extremely
-valuable. Therefore, I have always held a deep displeasure for
-conversations where people start with "Hello" and then.
+I work in a fast-paced environment where efficiency is extremely valuable.
+Therefore, I have always held a deep displeasure for conversations where people
+start with "Hello" and then.
-I searched back through my work messages and found that I received ~50
-messages from ~10 people last year from people that contained "hi",
-"hey", or "hello" and did not contain any indication of the purpose of
-the conversation. I also noticed that a few of the users were
-responsible for the large majority of the cliffhangers.
+I searched back through my work messages and found that I received ~50 messages
+from ~10 people last year from people that contained "hi", "hey", or "hello" and
+did not contain any indication of the purpose of the conversation. I also
+noticed that a few of the users were responsible for the large majority of the
+cliffhangers.
-There's no real point to this post, just a desparate request for people
-to please stop doing this.
+There's no real point to this post, just a desparate request for people to
+please stop doing this.
diff --git a/content/blog/2024-01-09-macos-customization.org b/content/blog/2024-01-09-macos-customization.org
index 82fda5e..6fe3b9a 100644
--- a/content/blog/2024-01-09-macos-customization.org
+++ b/content/blog/2024-01-09-macos-customization.org
@@ -3,73 +3,65 @@
#+description:
#+slug: macos-customization
-I have been using macOS more than Linux lately, so I wrote this post to
-describe some simple options to customize macOS beyond the normal
-built-in settings menu.
+I have been using macOS more than Linux lately, so I wrote this post to describe
+some simple options to customize macOS beyond the normal built-in settings menu.
-While not all-encompassing, the options below should be a good start for
-anyone looking to dive down the rabbit hole.
+While not all-encompassing, the options below should be a good start for anyone
+looking to dive down the rabbit hole.
* Basics
** Package Management
-To install a lot of software on macOS, you will need
-[[https://brew.sh/][Homebrew]]. You can use their installation script to
-get started. Simply open the =Terminal= application and paste the
-following snippet:
+To install a lot of software on macOS, you will need [[https://brew.sh/][Homebrew]]. You can use their
+installation script to get started. Simply open the =Terminal= application and
+paste the following snippet:
#+begin_src sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
#+end_src
-This will allow you to easily install and manage applications and other
-software easily through the =brew= command.
+This will allow you to easily install and manage applications and other software
+easily through the =brew= command.
** Terminal
-If you're serious about customizing your macOS system, I highly
-recommend installing a terminal emulator that you like and if you're not
-comfortable on the command line yet, start learning. A lot of
-customization options require you to edit hidden files, which is easiest
-in a terminal.
+If you're serious about customizing your macOS system, I highly recommend
+installing a terminal emulator that you like and if you're not comfortable on
+the command line yet, start learning. A lot of customization options require you
+to edit hidden files, which is easiest in a terminal.
-There are options like iTerm2, Kitty, Alacritty, Hyper, Warp, or the
-built-in Terminal app.
+There are options like iTerm2, Kitty, Alacritty, Hyper, Warp, or the built-in
+Terminal app.
-I use [[https://iterm2.com/][iTerm2]], which can be installed with
-Homebrew:
+I use [[https://iterm2.com/][iTerm2]], which can be installed with Homebrew:
#+begin_src sh
brew install iterm2
#+end_src
-To install color schemes, such as the Dracula scheme, you visit
-[[https://iterm2colorschemes.com/][iTerm Themes]] and follow their
-installation instructions to install any of the themes.
+To install color schemes, such as the Dracula scheme, you visit [[https://iterm2colorschemes.com/][iTerm Themes]] and
+follow their installation instructions to install any of the themes.
* Desktop
** Window Management
-[[https://github.com/koekeishiya/yabai][yabai]] is a tiling window
-manager for macOS. While other window managers exist, I found that most
-of them struggled to create logical layouts and to allow me to easily
-move windows around the screen.
+[[https://github.com/koekeishiya/yabai][yabai]] is a tiling window manager for macOS. While other window managers exist, I
+found that most of them struggled to create logical layouts and to allow me to
+easily move windows around the screen.
-Some advanced settings for yabai are only available if partially disable
-System Integrity Protection (SIP). However, I chose not to do this and
-it hasn't affected my basic usage of yabai at all.
+Some advanced settings for yabai are only available if partially disable System
+Integrity Protection (SIP). However, I chose not to do this and it hasn't
+affected my basic usage of yabai at all.
-Refer to the
-[[https://github.com/koekeishiya/yabai/wiki/Installing-yabai-(latest-release)][yabai
-wiki]] for installation instructions. You will need to ensure that yabai
-is allowed to access the accessibility and screen recording APIs.
+Refer to the [[https://github.com/koekeishiya/yabai/wiki/Installing-yabai-(latest-release)][yabai wiki]] for installation instructions. You will need to ensure
+that yabai is allowed to access the accessibility and screen recording APIs.
** Keyboard Shortcuts
-[[https://github.com/koekeishiya/skhd][skhd]] is a simple hotkey daemon
-that allows you to define hotkeys in a file for usage on your system.
+[[https://github.com/koekeishiya/skhd][skhd]] is a simple hotkey daemon that allows you to define hotkeys in a file for
+usage on your system.
Installation is simple:
@@ -78,8 +70,8 @@ brew install koekeishiya/formulae/skhd
skhd --start-service
#+end_src
-After installation, be sure to allow =skhd= access to the accessibility
-API in the macOS privacy settings.
+After installation, be sure to allow =skhd= access to the accessibility API in
+the macOS privacy settings.
You can configure your hotkeys in the =~/.config/skhd/skhdrc= file:
@@ -99,53 +91,45 @@ cmd + shift - return : /Applications/LibreWolf.app/Contents/MacOS/librewolf
** Widgets
-[[https://github.com/felixhageloh/uebersicht/][uebersicht]] is a handy
-desktop-based widget tool with a plethora of community-made widgets
-available in the [[https://tracesof.net/uebersicht-widgets/][widgets
-gallery]]. You can also write your own widgets with this tool.
+[[https://github.com/felixhageloh/uebersicht/][uebersicht]] is a handy desktop-based widget tool with a plethora of
+community-made widgets available in the [[https://tracesof.net/uebersicht-widgets/][widgets gallery]]. You can also write your
+own widgets with this tool.
-To install, simply download the latest release from the
-[[https://tracesof.net/uebersicht/][uebersicht website]] and copy it to
-the Applications folder.
+To install, simply download the latest release from the [[https://tracesof.net/uebersicht/][uebersicht website]] and
+copy it to the Applications folder.
-See below for an example of the
-[[https://tracesof.net/uebersicht-widgets/#Mond][Mond]] widget in
-action.
+See below for an example of the [[https://tracesof.net/uebersicht-widgets/#Mond][Mond]] widget in action.
** Status Bar
-[[https://github.com/FelixKratz/SketchyBar][SketchyBar]] is a
-customizable replacement for the macOS status or menu bar.
+[[https://github.com/FelixKratz/SketchyBar][SketchyBar]] is a customizable replacement for the macOS status or menu bar.
-You can browse a discussion where various users shared their
-[[https://github.com/FelixKratz/SketchyBar/discussions/47?sort=top][configurations]]
-for inspiration or to copy their dotfiles.
+You can browse a discussion where various users shared their [[https://github.com/FelixKratz/SketchyBar/discussions/47?sort=top][configurations]] for
+inspiration or to copy their dotfiles.
** Dock
-The easiest way to customize the dock is to install
-[[https://ubarapp.com/][uBar]], which uses a Windows-like menu bar as
-the default style.
+The easiest way to customize the dock is to install [[https://ubarapp.com/][uBar]], which uses a
+Windows-like menu bar as the default style.
-However, the built-in macOS dock cannot be disabled and can only be set
-to "always hidden". This can be annoying as it will pop out any time
-your mouse cursor passes closely to the dock edge of the screen. Because
-of this, I simply use the built-in dock instead of customizing it with
-third-party software.
+However, the built-in macOS dock cannot be disabled and can only be set to
+"always hidden". This can be annoying as it will pop out any time your mouse
+cursor passes closely to the dock edge of the screen. Because of this, I simply
+use the built-in dock instead of customizing it with third-party software.
Regardless, see below for the default installation style of uBar.
** Application Icons
-You can also customize the icon of any application in macOS, which will
-show up in Finder, the Dock, Launchpad, search results, etc. I recommend
-using [[https://macosicons.com/][macOSicons]] to download icons you
-want, and then apply them by following this process.
+You can also customize the icon of any application in macOS, which will show up
+in Finder, the Dock, Launchpad, search results, etc. I recommend using
+[[https://macosicons.com/][macOSicons]] to download icons you want, and then apply them by following this
+process.
1. Open the Finder application.
2. Navigate to the =Applications= folder.
3. Right-click an application of your choice, and select =Get Info=.
-4. Drag the image you downloaded on top of the application's icon at the
- top of information window (you will see a green "plus" symbol when
- you're hovering over it).
+4. Drag the image you downloaded on top of the application's icon at the top of
+ information window (you will see a green "plus" symbol when you're hovering
+ over it).
5. Release the new icon on top of the old icon and it will update!
diff --git a/content/blog/2024-01-13-local-llm.org b/content/blog/2024-01-13-local-llm.org
index d6f173b..0240d81 100644
--- a/content/blog/2024-01-13-local-llm.org
+++ b/content/blog/2024-01-13-local-llm.org
@@ -5,11 +5,10 @@
* Requirements
-I've recently started playing with large language models (LLMs), mostly
-in the popular chatbot form, as part of my job and have decided to see
-if there's a consistent and reliable way to interact with these models
-on Apple devices without sacrificing privacy or requiring in-depth
-technical setup.
+I've recently started playing with large language models (LLMs), mostly in the
+popular chatbot form, as part of my job and have decided to see if there's a
+consistent and reliable way to interact with these models on Apple devices
+without sacrificing privacy or requiring in-depth technical setup.
My requirements for this test:
@@ -18,12 +17,12 @@ My requirements for this test:
- Minimal required configuration
- Preferably pre-built, but a simple build process is acceptable
-I tested a handful of apps and have summarized my favorite (so far) for
-macOS and iOS below.
+I tested a handful of apps and have summarized my favorite (so far) for macOS
+and iOS below.
#+begin_quote
-TL;DR - Here are the two that met my requirements and I have found the
-easiest to install and use so far:
+TL;DR - Here are the two that met my requirements and I have found the easiest
+to install and use so far:
#+end_quote
- macOS: [[https://ollama.ai/][Ollama]]
@@ -31,13 +30,12 @@ easiest to install and use so far:
* macOS
-[[https://ollama.ai/][Ollama]] is a simple Go application for macOS and
-Linux that can run various LLMs locally.
+[[https://ollama.ai/][Ollama]] is a simple Go application for macOS and Linux that can run various LLMs
+locally.
-For macOS, you can download the pplication on the
-[[https://ollama.ai/download/mac][Ollama download page]] and install it
-by unzipping the =Ollama.app= file and moving it to the =Applications=
-folder.
+For macOS, you can download the pplication on the [[https://ollama.ai/download/mac][Ollama download page]] and
+install it by unzipping the =Ollama.app= file and moving it to the
+=Applications= folder.
If you prefer the command line, you can run these commands after the
download finished:
@@ -48,49 +46,43 @@ unzip Ollama-darwin.zip && \
mv ~/Downloads/Ollama.app /Applications/
#+end_src
-After running the app, the app will ask you to open a terminal and run
-the default =llama2= model, which will open an interactive chat session
-in the terminal. You can startfully using the application at this point.
+After running the app, the app will ask you to open a terminal and run the
+default =llama2= model, which will open an interactive chat session in the
+terminal. You can startfully using the application at this point.
-If you don't want to use the default =llama2= model, you can download
-and run additional models found on the
-[[https://ollama.ai/library][Models]] page.
+If you don't want to use the default =llama2= model, you can download and run
+additional models found on the [[https://ollama.ai/library][Models]] page.
To see the information for the currently-used model, you can run the
=/show info= command in the chat.
** Community Integrations
-I highly recommend browsing the
-[[https://github.com/jmorganca/ollama#community-integrations][Community
-Integrations]] section of the project to see how you would prefer to
-extend Ollama beyond a simple command-line interface. There are options
-for APIs, browser UIs, advanced terminal configurations, and more.
+I highly recommend browsing the [[https://github.com/jmorganca/ollama#community-integrations][Community Integrations]] section of the project to
+see how you would prefer to extend Ollama beyond a simple command-line
+interface. There are options for APIs, browser UIs, advanced terminal
+configurations, and more.
* iOS
-While there are a handful of decent macOS options, it was quite
-difficult to find an iOS app that offered an open source platform
-without an extensive configuration and building process. I found LLM
-Farm to be decent enough in quality to sit at the top of my list -
-however, it's definitely not user friendly enough for me to consider
-using it on a daily basis.
-
-[[https://llmfarm.site/][LLM Farm]] is available on TestFlight, so
-there's no manual build process required. However, you can view the
-[[https://github.com/guinmoon/LLMFarm][LLMFarm repository]] if you wish.
-
-The caveat is that you will have to manually download the model files
-from the links in the
-[[https://github.com/guinmoon/LLMFarm/blob/main/models.md][models.md]]
-file to your iPhone to use the app - there's currently no option in the
-app to reach out and grab the latest version of any supported model.
-
-Once you have a file downloaded, you simply create a new chat and select
-the downloaded model file and ensure the inference matches the
-requirement in the =models.md= file.
-
-[[https://github.com/AugustDev/enchanted][Enchanted]] is also an iOS for
-private AI models, but it requires a public-facing Ollama API, which did
-not meet my "on device requirement." Nonetheless, it's an interesting
-looking app and I will likely set it up to test soon.
+While there are a handful of decent macOS options, it was quite difficult to
+find an iOS app that offered an open source platform without an extensive
+configuration and building process. I found LLM Farm to be decent enough in
+quality to sit at the top of my list - however, it's definitely not user
+friendly enough for me to consider using it on a daily basis.
+
+[[https://llmfarm.site/][LLM Farm]] is available on TestFlight, so there's no manual build process
+required. However, you can view the [[https://github.com/guinmoon/LLMFarm][LLMFarm repository]] if you wish.
+
+The caveat is that you will have to manually download the model files from the
+links in the [[https://github.com/guinmoon/LLMFarm/blob/main/models.md][models.md]] file to your iPhone to use the app - there's currently no
+option in the app to reach out and grab the latest version of any supported
+model.
+
+Once you have a file downloaded, you simply create a new chat and select the
+downloaded model file and ensure the inference matches the requirement in the
+=models.md= file.
+
+[[https://github.com/AugustDev/enchanted][Enchanted]] is also an iOS for private AI models, but it requires a public-facing
+Ollama API, which did not meet my "on device requirement." Nonetheless, it's an
+interesting looking app and I will likely set it up to test soon.
diff --git a/content/blog/2024-01-26-audit-dashboard.org b/content/blog/2024-01-26-audit-dashboard.org
index 6b165bf..e2c41ad 100644
--- a/content/blog/2024-01-26-audit-dashboard.org
+++ b/content/blog/2024-01-26-audit-dashboard.org
@@ -3,9 +3,9 @@
#+description:
#+slug: audit-dashboard
-Alteryx and Power BI are powerful tools that can help turn your
-old-school audit trackers into interactive tools that provide useful
-insights and potential action plans.
+Alteryx and Power BI are powerful tools that can help turn your old-school audit
+trackers into interactive tools that provide useful insights and potential
+action plans.
With these tools, we are going to build a dashboard that can effectively
communicate project status.
@@ -15,30 +15,28 @@ communicate project status.
This project assumes the following:
- You have access to Alteryx Designer and Power BI Desktop.
- - If you only have Power BI Desktop, you may need to perform some
- analysis in Power BI instead of Alteryx.
-- Your data is in a format that can be imported into Alteryx and/or
- Power BI.
+ - If you only have Power BI Desktop, you may need to perform some analysis in
+ Power BI instead of Alteryx.
+- Your data is in a format that can be imported into Alteryx and/or Power BI.
- You have a basic understanding of data types and visualization.
* Alteryx: Data Preparation & Analysis
** Import Data
-With Alteryx, importing data is easy with the use of the =Input Data=
-tool. Simply drag this tool onto the canvas from the =In/Out= tab in the
-Ribbon to create it as a node.
+With Alteryx, importing data is easy with the use of the =Input Data= tool.
+Simply drag this tool onto the canvas from the =In/Out= tab in the Ribbon to
+create it as a node.
-You can choose the File Format manually or simply connect to your
-file/database and let Alteryx determine the format for you. For this
-example, we will be importing an Excel file and changing the
-=Start Data Import on Line= variable to =2=.
+You can choose the File Format manually or simply connect to your file/database
+and let Alteryx determine the format for you. For this example, we will be
+importing an Excel file and changing the =Start Data Import on Line= variable to
+=2=.
** Transform Data
-Next, let's replace null data and remove whitespace to clean up our
-data. We can do this with the =Data Cleansing= tool in the =Preparation=
-tab in the Ribbon.
+Next, let's replace null data and remove whitespace to clean up our data. We can
+do this with the =Data Cleansing= tool in the =Preparation= tab in the Ribbon.
Ensure that the following options are enabled:
@@ -48,49 +46,48 @@ Ensure that the following options are enabled:
- Remove Unwanted Characters
- Leading and Trailing Whitespace
-For our next step, we will transform the date fields from strings to
-datetime format. Add a =Datetime= tool for each field you want to
-transform - in the example below, I am using the tool twice for the
-"Started On" and "Submitted On" fields.
+For our next step, we will transform the date fields from strings to datetime
+format. Add a =Datetime= tool for each field you want to transform - in the
+example below, I am using the tool twice for the "Started On" and "Submitted On"
+fields.
-Now that the dates are in the correct format, let's perform a
-calculation based on those fields. Start by adding a =Filter= tool,
-naming a new Output Column, and pasting the formula below into it (the
-two fields used in this formula must match the output of the =Datetime=
-tools above):
+Now that the dates are in the correct format, let's perform a calculation based
+on those fields. Start by adding a =Filter= tool, naming a new Output Column,
+and pasting the formula below into it (the two fields used in this formula must
+match the output of the =Datetime= tools above):
-``=txt DateTimeDiff([SubmittedOn_Out],[StartedOn_Out], "days")=
+```txt
+DateTimeDiff([SubmittedOn_Out],[StartedOn_Out], "days")
+```
** Export Data
-Finalize the process by exporting the transformed data set to a new
-file, for use in the following visualization step.
+Finalize the process by exporting the transformed data set to a new file, for
+use in the following visualization step.
* Power BI: Data Visualization
** Import Data
-To start, open the Power BI Desktop application. Upon first use, Power
-BI will ask if you want to open an existing dashboard or import new
-data.
+To start, open the Power BI Desktop application. Upon first use, Power BI will
+ask if you want to open an existing dashboard or import new data.
-As we are creating our first dashboard, let's import our data. In my
-example below, I'm importing data from the "Tracker" sheet of the Excel
-file I'm using for this project.
+As we are creating our first dashboard, let's import our data. In my example
+below, I'm importing data from the "Tracker" sheet of the Excel file I'm using
+for this project.
-During this process, I also imported the export from the Alteryx
-workflow above. Therefore, we have two different files available for use
-in our dashboard.
+During this process, I also imported the export from the Alteryx workflow above.
+Therefore, we have two different files available for use in our dashboard.
** Add Visuals
-To create the dashboard, you will need to follow the list instructions
-below and format as needed.
+To create the dashboard, you will need to follow the list instructions below and
+format as needed.
Instructions to create the visuals above:
-- =Text Box=: Explain the name and purpose of the dashboard. You can
- also add images and logos at the top of the dashboard.
+- =Text Box=: Explain the name and purpose of the dashboard. You can also add
+ images and logos at the top of the dashboard.
- =Donut Chart=: Overall status of the project.
- =Legend=: Status
- =Values=: Count of Status
@@ -111,13 +108,12 @@ Instructions to create the visuals above:
** Format the Dashboard
-You can choose a theme in the View tab of the Ribbon. You can even
-browse for custom JSON files that define themes, such as ones found
-online or custom ones created by your organization.
+You can choose a theme in the View tab of the Ribbon. You can even browse for
+custom JSON files that define themes, such as ones found online or custom ones
+created by your organization.
-For each visual, you can click the =Format= button in the
-=Visualizations= side pane and explore the options. You can custom
-options such as:
+For each visual, you can click the =Format= button in the =Visualizations= side
+pane and explore the options. You can custom options such as:
- Visual
- Legend
@@ -132,22 +128,21 @@ options such as:
- Tooltips
- Alt text
-You can always look online for inspiration when trying to decide how
-best to organize and style your dashboard.
+You can always look online for inspiration when trying to decide how best to
+organize and style your dashboard.
* Sharing the Results
-Generally, you have a few different options for sharing your dashboards
-with others:
-
-1. Export the dashboard as a PDF in the file menu of Power BI. This will
- export all tabs and visuals as they are set when the export button is
- pressed. You will lose all interactivity with this option.
-2. Send the full Power BI file to those you wish to share the dashboard.
- This will retain all settings and interactivity. However, you will
- also need to send the source files if they need to refresh the
- dashboard and you will need to re-send the files if you make updates.
-3. Store the dashboard in a synced location, such as a shared drive or
- Microsoft Teams. Depending on how a user configures their local
- Windows paths, the data source paths may not be compatible for all
- users with such a setup.
+Generally, you have a few different options for sharing your dashboards with
+others:
+
+1. Export the dashboard as a PDF in the file menu of Power BI. This will export
+ all tabs and visuals as they are set when the export button is pressed. You
+ will lose all interactivity with this option.
+2. Send the full Power BI file to those you wish to share the dashboard. This
+ will retain all settings and interactivity. However, you will also need to
+ send the source files if they need to refresh the dashboard and you will need
+ to re-send the files if you make updates.
+3. Store the dashboard in a synced location, such as a shared drive or Microsoft
+ Teams. Depending on how a user configures their local Windows paths, the data
+ source paths may not be compatible for all users with such a setup.
diff --git a/content/blog/2024-01-27-tableau-dashboard.org b/content/blog/2024-01-27-tableau-dashboard.org
index 7e0e078..f1efc36 100644
--- a/content/blog/2024-01-27-tableau-dashboard.org
+++ b/content/blog/2024-01-27-tableau-dashboard.org
@@ -3,14 +3,12 @@
#+description:
#+slug: tableau-dashboard
-In this project, I am going to show you how to use Tableau Public for
-free to create simple dashboards.
+In this project, I am going to show you how to use Tableau Public for free to
+create simple dashboards.
-I will be creating simple visuals from an Omaha crime data set and
-combining them to create the dashboard below. You can view this
-dashboard interactively online here:
-[[https://public.tableau.com/app/profile/c.c7042/viz/OmahaCrimeData2015-2023/OmahaCrimeData2015-2023#1][Omaha
-Crime Data (2015 - 2023)]].
+I will be creating simple visuals from an Omaha crime data set and combining
+them to create the dashboard below. You can view this dashboard interactively
+online here: [[https://public.tableau.com/app/profile/c.c7042/viz/OmahaCrimeData2015-2023/OmahaCrimeData2015-2023#1][Omaha Crime Data (2015 - 2023)]].
#+caption: Tableau Dashboard
[[https://img.cleberg.net/blog/20240127-tableau-dashboard/dashboard.png]]
@@ -18,18 +16,17 @@ Crime Data (2015 - 2023)]].
* Gather the Data
You can download incident data from the Omaha Police Department on their
-[[https://police.cityofomaha.org/crime-information/incident-data-download][Incident
-Data Download]] page. They currently have files for the years 2015
+[[https://police.cityofomaha.org/crime-information/incident-data-download][Incident Data Download]] page. They currently have files for the years 2015
through 2023.
Each file will be downloaded as a CSV file, approximately 3 MB - 8 MB.
* Clean and Transform the Data
-I have used Python to combine the files into a single CSV file, as well
-as adding a custom =datetime= column. You could do this step in any
-software you prefer, but I prefer Python as its free, easy to use, and
-has a plethora of support resources online.
+I have used Python to combine the files into a single CSV file, as well as
+adding a custom =datetime= column. You could do this step in any software you
+prefer, but I prefer Python as its free, easy to use, and has a plethora of
+support resources online.
Start by opening a terminal, navigating to your Downloads directory, and
creating a python script.
@@ -76,38 +73,37 @@ Once pasted, save and close the file. You can execute the file like so:
python3 data_processing.py
#+end_src
-After this, you should have a combined data file that contains all
-incidents between 2015 and 2023. Mine was approximately 55 MB.
+After this, you should have a combined data file that contains all incidents
+between 2015 and 2023. Mine was approximately 55 MB.
* Tableau Public
-[[https://public.tableau.com/][Tableau Public]] is a free-to-use web
-application that allows you to create visualizations by uploading data
-sources. Note that there's no way to keep the data and visualizations
-private, so don't upload anything private.
+[[https://public.tableau.com/][Tableau Public]] is a free-to-use web application that allows you to create
+visualizations by uploading data sources. Note that there's no way to keep the
+data and visualizations private, so don't upload anything private.
-After creating an account, you can click the =Create= > =Web Authoring=
-link to create your first visualization.
+After creating an account, you can click the =Create= > =Web Authoring= link to
+create your first visualization.
** Upload the Data
-Once you've opened your first project, Tableau will ask you to connect
-to your data. For this project, click the =Upload from computer= button
-and select the CSV file previously combined in the step above.
+Once you've opened your first project, Tableau will ask you to connect to your
+data. For this project, click the =Upload from computer= button and select the
+CSV file previously combined in the step above.
-Once connected, you can refresh the preview of the data with the
-=Refresh Data Source= button in the toolbar.
+Once connected, you can refresh the preview of the data with the =Refresh Data
+Source= button in the toolbar.
-If you need to edit any of the data types, column names, etc., you can
-do so now. Once complete, generate an extract so that you can start
-creating visualizations.
+If you need to edit any of the data types, column names, etc., you can do so
+now. Once complete, generate an extract so that you can start creating
+visualizations.
** Create Visualizations
To start, create a worksheet in the toolbar at the bottom of the screen.
-Within this screen, select a column from the =Data= side bar on the left
-and drag it into the =Columns= or =Rows= area of the canvas.
+Within this screen, select a column from the =Data= side bar on the left and
+drag it into the =Columns= or =Rows= area of the canvas.
See below for the map visualization. You can recreate this by adding the
following fields:
@@ -119,30 +115,29 @@ following fields:
- Datetime
- =Filters=: Datetime
-You can repeat this process for each visualization you want to create.
-Explore your options by dragging data fields to different areas and by
-opening the field options to explore what operations can be performed on
-different data types (e.g., average, count, etc.).
+You can repeat this process for each visualization you want to create. Explore
+your options by dragging data fields to different areas and by opening the field
+options to explore what operations can be performed on different data types
+(e.g., average, count, etc.).
** Create Dashboard
-To create a dashboard, click the button on the toolbar at the bottom of
-the screen. Within the dashboard, drag each sheet from the left side bar
-onto the dashboard canvas.
+To create a dashboard, click the button on the toolbar at the bottom of the
+screen. Within the dashboard, drag each sheet from the left side bar onto the
+dashboard canvas.
** Formatting
-You can explore a ton of different formatting options throughout the
-worksheets and dashboard. Specifically for maps, you can alter the map
-layers, background, and visible features through the =Map= menu in the
-top file menu of the editing screen.
+You can explore a ton of different formatting options throughout the worksheets
+and dashboard. Specifically for maps, you can alter the map layers, background,
+and visible features through the =Map= menu in the top file menu of the editing
+screen.
-In the finished dashboard below, I opted for a dark mode with a map that
-showed county lines and city names.
+In the finished dashboard below, I opted for a dark mode with a map that showed
+county lines and city names.
-There's a ton of other options available to be used in a dashboard like
-this, but this project shows a quick preview of what you can do in
-Tableau Public.
+There's a ton of other options available to be used in a dashboard like this,
+but this project shows a quick preview of what you can do in Tableau Public.
#+caption: Tableau Dashboard
[[https://img.cleberg.net/blog/20240127-tableau-dashboard/dashboard.png]]
diff --git a/content/blog/2024-02-06-zfs.org b/content/blog/2024-02-06-zfs.org
index 410b030..a870a2c 100644
--- a/content/blog/2024-02-06-zfs.org
+++ b/content/blog/2024-02-06-zfs.org
@@ -6,14 +6,11 @@
This post details the process I used to create ZFS pools, datasets, and
snapshots on Ubuntu Server.
-I found the following pages very helpful while going through this
-process:
+I found the following pages very helpful while going through this process:
-- [[https://ubuntu.com/tutorials/setup-zfs-storage-pool][Setup a ZFS
- storage pool]]
+- [[https://ubuntu.com/tutorials/setup-zfs-storage-pool][Setup a ZFS storage pool]]
- [[https://wiki.ubuntu.com/Kernel/Reference/ZFS][Kernel/Reference/ZFS]]
-- [[https://blog.victormendonca.com/2020/11/03/zfs-for-dummies/][ZFS for
- Dummies]]
+- [[https://blog.victormendonca.com/2020/11/03/zfs-for-dummies/][ZFS for Dummies]]
* Installation
@@ -23,8 +20,7 @@ To start, I installed the ZFS package with the following command:
sudo apt install zfsutils-linux
#+end_src
-Once installed, you can check the version to see if it installed
-correctly.
+Once installed, you can check the version to see if it installed correctly.
#+begin_src sh
> zsf --version
@@ -37,9 +33,9 @@ zfs-kmod-2.1.5-1ubuntu6~22.04.1
Now that ZFS is installed, we can create and configure the pool.
-You have various options for configuring ZFS pools that all come
-different pros and cons. I suggest visiting the links at the top of this
-post or searching online for the best configuration for your use-case.
+You have various options for configuring ZFS pools that all come different pros
+and cons. I suggest visiting the links at the top of this post or searching
+online for the best configuration for your use-case.
- Striped VDEVs (Raid0)
- Mirrored VDEVs (Raid1)
@@ -49,20 +45,20 @@ post or searching online for the best configuration for your use-case.
- RAIDz3
- Nested RAIDz (Raid50, Raid60)
-I will be using Raid10 in this guide. However, the majority of the steps
-are the same regardless of your chosen pool configuration.
+I will be using Raid10 in this guide. However, the majority of the steps are the
+same regardless of your chosen pool configuration.
** Creating the Pool
-To start, let's list the disks available to use. You can use =fdisk=
-command to see all available disks.
+To start, let's list the disks available to use. You can use =fdisk= command to
+see all available disks.
#+begin_src sh
sudo fdisk -l
#+end_src
-Or, if you currently have them mounted, you can use the =df= command to
-view your disks.
+Or, if you currently have them mounted, you can use the =df= command to view
+your disks.
#+begin_src sh
> sudo df -h
@@ -77,17 +73,16 @@ Filesystem Size Used Avail Use% Mounted on
/dev/sdf1 7.3T 28K 6.9T 1% /mnt/red-04
#+end_src
-If you're going to use mounted disks, make sure to umount them before
-creating the pool.
+If you're going to use mounted disks, make sure to umount them before creating
+the pool.
#+begin_src sh
sudo umount /dev/sda1
sudo umount /dev/sdb1
#+end_src
-Now that I've identified the disks I want to use and have them
-unmounted, let's create the pool. For this example, I will call it
-=tank=.
+Now that I've identified the disks I want to use and have them unmounted, let's
+create the pool. For this example, I will call it =tank=.
#+begin_src sh
sudo zpool create -f -m /mnt/pool tank mirror /dev/sda /dev/sdb
@@ -119,8 +114,8 @@ config:
errors: No known data errors
#+end_src
-We can also look at the mounted filesystem to see where the pool is
-mounted and some quick stats.
+We can also look at the mounted filesystem to see where the pool is mounted and
+some quick stats.
#+begin_src sh
> df -h
@@ -132,28 +127,25 @@ tank 7.2T 128K 7.2T 1% /tank
** Expanding the Pool
-If you want to expand this pool, you will need to add a new VDEV to the
-pool. Since I am using 2 disks per VDEV, I will need to add a new 2-disk
-VDEV to the existing =tank= pool.
+If you want to expand this pool, you will need to add a new VDEV to the pool.
+Since I am using 2 disks per VDEV, I will need to add a new 2-disk VDEV to the
+existing =tank= pool.
#+begin_src sh
sudo zpool add tank mirror /dev/sdX /dev/sdY
#+end_src
-If you're adding disks of different sizes, you'll need to use the =-f=
-flag. Keep in mind that the max size will be limited to the smallest
-disk added.
+If you're adding disks of different sizes, you'll need to use the =-f= flag.
+Keep in mind that the max size will be limited to the smallest disk added.
#+begin_src sh
sudo zpool add -f tank mirror /dev/sdX /dev/sdY
#+end_src
-I added two 8TB hard drives and this process took around 10 seconds to
-complete.
+I added two 8TB hard drives and this process took around 10 seconds to complete.
-When viewing the pool again, you can see that the pool has now doubled
-in size. We have 14.3 TB useable space and the same space used for
-mirroring.
+When viewing the pool again, you can see that the pool has now doubled in size.
+We have 14.3 TB useable space and the same space used for mirroring.
#+begin_src sh
> zfs list
@@ -166,8 +158,8 @@ tank/media 96K 14.3T 96K /tank/media
*** Converting Disks
-Some disks, such as NTFS-formatted drives, will need to be partitioned
-and formatted prior to being added to the pool.
+Some disks, such as NTFS-formatted drives, will need to be partitioned and
+formatted prior to being added to the pool.
Start by identifying the disks you want to format and add to the pool.
@@ -178,8 +170,8 @@ sudo fdisk -l | grep /dev
I am going to format my =/dev/sdc= and =/dev/sdd= disks with the =fdisk=
command.
-See below for instructions on how to use =fdisk=. Here's what I did to
-create basic Linux formatted disks:
+See below for instructions on how to use =fdisk=. Here's what I did to create
+basic Linux formatted disks:
- =g= : Create GPT partition table
- =n= : Create a new partition, hit Enter for all default options
@@ -191,13 +183,12 @@ I repeated this process for both disks.
#+begin_src sh
> sudo fdisk /dev/sdc
-Welcome to fdisk (util-linux 2.37.2).
-Changes will remain in memory only, until you decide to write them.
-Be careful before using the write command.
+Welcome to fdisk (util-linux 2.37.2). Changes will remain in memory only, until
+you decide to write them. Be careful before using the write command.
-This disk is currently in use - repartitioning is probably a bad idea.
-It's recommended to umount all file systems, and swapoff all swap
-partitions on this disk.
+This disk is currently in use - repartitioning is probably a bad idea. It's
+recommended to umount all file systems, and swapoff all swap partitions on this
+disk.
Command (m for help): m
@@ -243,9 +234,9 @@ sudo zpool add tank mirror /dev/sdc /dev/sdd
#+end_src
When we list the pool again, we can see that our size is now updated to
-approximately 22TB. This represents my hard drives totalling 45.6TB when
-shown with =fdisk -l=, with a Raid10 configuration using 22TB for
-mirroring and 22TB of useable space.
+approximately 22TB. This represents my hard drives totalling 45.6TB when shown
+with =fdisk -l=, with a Raid10 configuration using 22TB for mirroring and 22TB
+of useable space.
#+begin_src sh
> zfs list
@@ -258,17 +249,15 @@ tank/media 145GT 21.7T 96K /tank/media
** Creating Datasets
-According to
-[[https://docs.oracle.com/cd/E18752_01/html/819-5461/ftyue.html][ZFS
-Terminology]], a =dataset= can refer to “clones, file systems,
+According to [[https://docs.oracle.com/cd/E18752_01/html/819-5461/ftyue.html][ZFS Terminology]], a =dataset= can refer to “clones, file systems,
snapshots, and volumes.
-For this guide, I will use the =dataset= term to refer to file systems
-created under a pool.
+For this guide, I will use the =dataset= term to refer to file systems created
+under a pool.
-Within my =tank= pool, I am going to create some datasets to help
-organize my files. This will give me location to store data rather than
-simply dumping everything at the =/tank/= location.
+Within my =tank= pool, I am going to create some datasets to help organize my
+files. This will give me location to store data rather than simply dumping
+everything at the =/tank/= location.
#+begin_src sh
sudo zfs create tank/cloud
@@ -288,9 +277,9 @@ tank/media 96K 7.14T 96K /tank/media
** Creating Snapshots
-Next, let's create our first snapshot. We can do this by calling the
-=snapshot= command and give it an output name. I will be throwing the
-current date and time into my example.
+Next, let's create our first snapshot. We can do this by calling the =snapshot=
+command and give it an output name. I will be throwing the current date and time
+into my example.
#+begin_src sh
sudo zfs snapshot tank@$(date '+%Y-%m-%d_%H-%M')
@@ -321,13 +310,10 @@ no datasets available
* My Thoughts on ZFS So Far
-- I sacrificed 25TB to be able to mirror my data, but I feel more
- comfortable with the potential to save my data by quickly replacing a
- disk if I need to.
+- I sacrificed 25TB to be able to mirror my data, but I feel more comfortable
+ with the potential to save my data by quickly replacing a disk if I need to.
- The set-up was surprisingly easy and fast.
-- Disk I/O is fast as well. I was worried that the data transfer speeds
- would be slower due to the RAID configuration.
-- Media streaming and transcoding has seen no noticeable drop in
- performance.
-- My only limitation really is the number of HDD bays in my server HDD
- cage.
+- Disk I/O is fast as well. I was worried that the data transfer speeds would be
+ slower due to the RAID configuration.
+- Media streaming and transcoding has seen no noticeable drop in performance.
+- My only limitation really is the number of HDD bays in my server HDD cage.
diff --git a/content/blog/2024-02-13-ubuntu-emergency-mode.org b/content/blog/2024-02-13-ubuntu-emergency-mode.org
index e910468..e02c6ec 100644
--- a/content/blog/2024-02-13-ubuntu-emergency-mode.org
+++ b/content/blog/2024-02-13-ubuntu-emergency-mode.org
@@ -5,12 +5,12 @@
* The Problem
-I recently [[../zfs/][migrated my hard drives to a ZFS pool]] and found
-myself stuck in Ubuntu's emergency mode after the first reboot I
-performed after creating the ZFS pool.
+I recently [[../zfs/][migrated my hard drives to a ZFS pool]] and found myself stuck in
+Ubuntu's emergency mode after the first reboot I performed after creating the
+ZFS pool.
-My server was stuck in the boot process and showed the following error
-on the screen:
+My server was stuck in the boot process and showed the following error on the
+screen:
#+begin_src txt
You are in emergency mode.
@@ -19,34 +19,33 @@ After logging in, type "journalctl -xb" to view system logs,
or ^D to try again to boot into default mode".
#+end_src
-After rebooting the server and watching the logs scroll on a monitor, I
-noticed the root cause was related to a very long search for certain
-drives. I kept seeing errors like this:
+After rebooting the server and watching the logs scroll on a monitor, I noticed
+the root cause was related to a very long search for certain drives. I kept
+seeing errors like this:
#+begin_src txt
[ TIME ] Timed out waiting of device dev-disk-by/[disk-uuid]
#+end_src
-I realized that I had not removed the =/etc/fstab= references that asked
-Ubuntu to mount two disks on boot, but I had recently changed those
-disks to be part of my ZFS pool instead. Therefore, Ubuntu was trying to
-identify and mount a disk that was not available.
+I realized that I had not removed the =/etc/fstab= references that asked Ubuntu
+to mount two disks on boot, but I had recently changed those disks to be part of
+my ZFS pool instead. Therefore, Ubuntu was trying to identify and mount a disk
+that was not available.
Now that we have an idea of the issue, let's move to solution.
* The Solution
-In order to fix the issue, I waited until I was allowed to type the root
-user's password, and then I executed the following command:
+In order to fix the issue, I waited until I was allowed to type the root user's
+password, and then I executed the following command:
#+begin_src sh
nano /etc/fstab
#+end_src
-Within the =fstab= file, I needed to comment/remove the following lines
-at the bottom of the file. You can comment-out a line by prepending a
-=#= symbol at the beginning of the line. You can also delete the line
-entirely.
+Within the =fstab= file, I needed to comment/remove the following lines at the
+bottom of the file. You can comment-out a line by prepending a =#= symbol at the
+beginning of the line. You can also delete the line entirely.
#+begin_src conf
# What it looked like when running into the issue:
@@ -58,8 +57,8 @@ UUID=E69867E59867B32B /mnt/white-02 ntfs-3g uid=1000,gid=1000 0 0
# UUID=E69867E59867B32B /mnt/white-02 ntfs-3g uid=1000,gid=1000 0 0
#+end_src
-Once removing the lines above from the =/etc/fstab= file, save and exit
-the file by hitting the =Ctrl= + =x= key combo.
+Once removing the lines above from the =/etc/fstab= file, save and exit the file
+by hitting the =Ctrl= + =x= key combo.
You can now hit =Ctrl= + =D= to continue, or reboot:
@@ -67,5 +66,5 @@ You can now hit =Ctrl= + =D= to continue, or reboot:
systemctl reboot
#+end_src
-Once rebooted, I was able to watch the machine boot properly and launch
-to the TTY login screen without errors!
+Once rebooted, I was able to watch the machine boot properly and launch to the
+TTY login screen without errors!
diff --git a/content/blog/2024-02-21-self-hosting-otter-wiki.org b/content/blog/2024-02-21-self-hosting-otter-wiki.org
index b682db7..844396c 100644
--- a/content/blog/2024-02-21-self-hosting-otter-wiki.org
+++ b/content/blog/2024-02-21-self-hosting-otter-wiki.org
@@ -5,14 +5,14 @@
* An Otter Wiki
-[[https://otterwiki.com/][An Otter Wiki]] is an easy to use wiki
-software that takes almost no effort to set up and maintain.
+[[https://otterwiki.com/][An Otter Wiki]] is an easy to use wiki software that takes almost no effort to set
+up and maintain.
* Installation
To install An Otter Wiki, I'm going to use Docker Compose to create the
-container and then use Nginx as a reverse proxy to allow external access
-via a subdomain I own.
+container and then use Nginx as a reverse proxy to allow external access via a
+subdomain I own.
** Docker Compose
@@ -22,16 +22,14 @@ Start by creating a directory for the container's files.
mkdir ~/otterwiki
#+end_src
-Next, create the =docker-compose.yml= file to define the container's
-parameters.
+Next, create the =docker-compose.yml= file to define the container's parameters.
#+begin_src sh
nano ~/otterwiki/docker-compose.yml
#+end_src
Within the file, paste the following content. You can read the project's
-documentation if you want to further override or customize the
-container.
+documentation if you want to further override or customize the container.
#+begin_src conf
version: '3'
@@ -54,22 +52,22 @@ cd ~/otterwiki
sudo docker-compose up -d
#+end_src
-The container is now available at =localhost:8337=. Next, we will use
-Nginx to serve this app externally.
+The container is now available at =localhost:8337=. Next, we will use Nginx to
+serve this app externally.
** Nginx
-To access the app externally, let's set up a reverse proxy. I'll start
-by creating the Nginx configuration file for my wiki.
+To access the app externally, let's set up a reverse proxy. I'll start by
+creating the Nginx configuration file for my wiki.
#+begin_src sh
sudo nano /etc/nginx/sites-available/wiki
#+end_src
-Within the file, I have saved the following content. This assumes you
-already have a TLS/SSL cert to use with this subdomain. If not, simply
-remove the =ssl_*= variables, remove the =80= server block, and change
-the =443= server block to =80= to serve the app without SSL.
+Within the file, I have saved the following content. This assumes you already
+have a TLS/SSL cert to use with this subdomain. If not, simply remove the
+=ssl_*= variables, remove the =80= server block, and change the =443= server
+block to =80= to serve the app without SSL.
#+begin_src conf
server {
@@ -107,15 +105,14 @@ server {
}
#+end_src
-Save and close the configuration file. On Nginx, we need to symlink the
-file to enable it.
+Save and close the configuration file. On Nginx, we need to symlink the file to
+enable it.
#+begin_src sh
sudo ln -s /etc/nginx/sites-available/wiki /etc/nginx/sites-enabled/wiki
#+end_src
-Once enabled, restart the Nginx server to start serving the app
-externally.
+Once enabled, restart the Nginx server to start serving the app externally.
#+begin_src sh
sudo systemctl restart nginx.service
diff --git a/content/blog/2024-03-13-doom-emacs.org b/content/blog/2024-03-13-doom-emacs.org
index 96b22be..d4f0c19 100644
--- a/content/blog/2024-03-13-doom-emacs.org
+++ b/content/blog/2024-03-13-doom-emacs.org
@@ -5,9 +5,9 @@
** Screenshots
-These screenshots are showing a project opened with projectile, a
-treemacs side pane open with the project contents, multiple buffers
-tiled next to each other, and the help pane open at the bottomm.
+These screenshots are showing a project opened with projectile, a treemacs side
+pane open with the project contents, multiple buffers tiled next to each other,
+and the help pane open at the bottomm.
The themes are =doom-homage-white= and =doom-homage-black=.
@@ -19,44 +19,35 @@ The themes are =doom-homage-white= and =doom-homage-black=.
** Getting Started
-I have been switching back and forth between
-[[https://en.wikipedia.org/wiki/Markdown][markdown]] and
-[[https://en.wikipedia.org/wiki/Org-mode][org-mode]] recently for my
-personal note taking, wiki, and even this blog. As a result, I have been
-stumbling further into the world of Emacs and found myself at a point
-where I now prefer to do most of my basic editing within Emacs.
+I have been switching back and forth between [[https://en.wikipedia.org/wiki/Markdown][markdown]] and [[https://en.wikipedia.org/wiki/Org-mode][org-mode]] recently for
+my personal note taking, wiki, and even this blog. As a result, I have been
+stumbling further into the world of Emacs and found myself at a point where I
+now prefer to do most of my basic editing within Emacs.
I'll leave the markdown vs. org-mode debate for another post, but I love
-org-mode's extensibility and interactive nature within Emacs, but it
-becomes very unwieldy in any other client implementation of org-mode -
-especially on iOS. On the flip side, markdown is limited in
-functionality and fractured into different standards, but it's simple
-and popular enough that there are a plethora of great clients to choose
-from that will get the job done.
+org-mode's extensibility and interactive nature within Emacs, but it becomes
+very unwieldy in any other client implementation of org-mode - especially on
+iOS. On the flip side, markdown is limited in functionality and fractured into
+different standards, but it's simple and popular enough that there are a
+plethora of great clients to choose from that will get the job done.
-For now, I want to focus on how I have been using Emacs and some of the
-things that would have helped me learn it faster had I known where to
-start.
+For now, I want to focus on how I have been using Emacs and some of the things
+that would have helped me learn it faster had I known where to start.
*** Installation
-This post focuses on [[https://github.com/doomemacs/doomemacs][Doom
-Emacs]], which is an Emacs framework that provides an alternative
-experience to the vanilla [[https://www.gnu.org/software/emacs/][GNU
-Emacs]].
+This post focuses on [[https://github.com/doomemacs/doomemacs][Doom Emacs]], which is an Emacs framework that provides an
+alternative experience to the vanilla [[https://www.gnu.org/software/emacs/][GNU Emacs]].
-The
-[[https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org][Getting
-Start Guide]] has an extremely detailed walkthrough of installation for
-all systems, so please refer to that guide for up-to-date instructions.
+The [[https://github.com/doomemacs/doomemacs/blob/master/docs/getting_started.org][Getting Start Guide]] has an extremely detailed walkthrough of installation
+for all systems, so please refer to that guide for up-to-date instructions.
I chose to install on macOS, using the Homebrew option with the
=railwaycat/emacsmacport= version of Emacs.
-Once the program is installed, you can run the program by typing =emacs=
-in a terminal. If you installed a version of Emacs that supports both a
-GUI and TUI, you will have to run =emacs -nw= to get the TUI instead of
-the default GUI.
+Once the program is installed, you can run the program by typing =emacs= in a
+terminal. If you installed a version of Emacs that supports both a GUI and TUI,
+you will have to run =emacs -nw= to get the TUI instead of the default GUI.
*** Configuration
@@ -65,13 +56,12 @@ Once installed, you can configure Doom by editing the files within the
1. =config.el= - Personal configuration file
2. =custom.el= - Custom set variables
-3. =init.el= - Doom modules and load order, must run =doom sync= after
- modifying
-4. =packages.el= - Declare packages to install in this file, then run
- =doom sync= to install
+3. =init.el= - Doom modules and load order, must run =doom sync= after modifying
+4. =packages.el= - Declare packages to install in this file, then run =doom
+ sync= to install
-I only needed a few customizations for my configuration, so I'll list
-them below.
+I only needed a few customizations for my configuration, so I'll list them
+below.
#+begin_src lisp
;; ~/.doom.d/config.el
@@ -145,30 +135,28 @@ them below.
(default +bindings +smartparens))
#+end_src
-If you're editing these files within Doom directly, remember to run
-=SPC h r r= to reload the configuration. Also remember to run
-=doom sync= for any changes to the =init.el= or =packages.el= files.
+If you're editing these files within Doom directly, remember to run =SPC h r r=
+to reload the configuration. Also remember to run =doom sync= for any changes to
+the =init.el= or =packages.el= files.
** Basic Functionality
-I kept a cheat sheet note open at first with all of the basic functions
-typed out, copied as I went through the tutorial. After a little while,
-I no longer needed it. I highly recommend writing down the most
-applicable shortcuts for your preferred functionality and refer back to
-it until you've memorized it.
-
-Memorizing the shortcuts will differ based on the type of Emacs
-framework being used. Personally, migrating from vanilla Emacs to Doom
-Emacs simplified everything by a large factor and instantly enabled me
-to start working on my projects, eliminating most of the hurdles I was
-running into. The vanilla emacs hotkeys became obnoxious and I actually
-stopped using Emacs entirely for about a month before trying Doom.
-
-For me, the first logical step is to interact with the local filesystem.
-To do this, I needed to know how to open directories, open files, save
-files, discard changes, close files, and switch between open files. Here
-are some example shortcuts I've written down in order to accomplish
-file-based actions.
+I kept a cheat sheet note open at first with all of the basic functions typed
+out, copied as I went through the tutorial. After a little while, I no longer
+needed it. I highly recommend writing down the most applicable shortcuts for
+your preferred functionality and refer back to it until you've memorized it.
+
+Memorizing the shortcuts will differ based on the type of Emacs framework being
+used. Personally, migrating from vanilla Emacs to Doom Emacs simplified
+everything by a large factor and instantly enabled me to start working on my
+projects, eliminating most of the hurdles I was running into. The vanilla emacs
+hotkeys became obnoxious and I actually stopped using Emacs entirely for about a
+month before trying Doom.
+
+For me, the first logical step is to interact with the local filesystem. To do
+this, I needed to know how to open directories, open files, save files, discard
+changes, close files, and switch between open files. Here are some example
+shortcuts I've written down in order to accomplish file-based actions.
| Doom Hotkey | Emacs Hotkey | Description |
|-----------------+---------------+----------------------------------------|
@@ -181,30 +169,28 @@ file-based actions.
| =SPC b k= | =C-x k= | Kill current buffer |
| =SPC w h/j/k/l= | =C-x o=[fn:2] | Move left/down/up/right to next buffer |
-In general, when in Doom, you can press =SPC= and wait a second for the
-help pane to appear with all available hotkey options. For example, you
-can press =SPC=, wait for the help pane, and then select a key such as
-=g= to enter the git help pane and explore further command options.
+In general, when in Doom, you can press =SPC= and wait a second for the help
+pane to appear with all available hotkey options. For example, you can press
+=SPC=, wait for the help pane, and then select a key such as =g= to enter the
+git help pane and explore further command options.
** Editing
-Next in my process is to dive into editing for any languages I'm
-currently using. In this post, I will just cover Markdown and Org-Mode
-but I have also been slowly adoping some Python and general web dev
-tools as well.
+Next in my process is to dive into editing for any languages I'm currently
+using. In this post, I will just cover Markdown and Org-Mode but I have also
+been slowly adoping some Python and general web dev tools as well.
*** Markdown
#+caption: Markdown Preview
[[https://img.cleberg.net/blog/20240314-doom-emacs/markdown.png]]
-Markdown is fairly simple as the syntax is limited, so just make sure
-the =~/.doom.d/init.el= includes the =markdown= declaration in the
-=:lang= section.
+Markdown is fairly simple as the syntax is limited, so just make sure the
+=~/.doom.d/init.el= includes the =markdown= declaration in the =:lang= section.
-This package includes the following hotkey menus. The insert and toggle
-menu expands further, allowing you to insert various markdown elements
-and toggle things like link hiding.
+This package includes the following hotkey menus. The insert and toggle menu
+expands further, allowing you to insert various markdown elements and toggle
+things like link hiding.
| Doom Hotkey | Function |
|------------------------------+--------------------------|
@@ -221,14 +207,12 @@ and toggle things like link hiding.
#+caption: Org-Mode Preview
[[https://img.cleberg.net/blog/20240314-doom-emacs/org.png]]
-Similar to the markdown section above, ensure that the
-=~/.doom.d/init.el= includes the =org= declaration in the =:lang=
-section.
+Similar to the markdown section above, ensure that the =~/.doom.d/init.el=
+includes the =org= declaration in the =:lang= section.
-There are a few hot keys, but a quick search with =SPC : org= shows that
-there are 865 possible org-related functions you can run. I won't
-possibly be able to list them all, so I will simply cover a few of the
-basic commands I use myself.
+There are a few hot keys, but a quick search with =SPC : org= shows that there
+are 865 possible org-related functions you can run. I won't possibly be able to
+list them all, so I will simply cover a few of the basic commands I use myself.
| Doom Hotkey | Function |
|----------------+---------------------------------------|
@@ -246,32 +230,28 @@ basic commands I use myself.
1. Org-Publish
- Org includes a
- [[https://orgmode.org/manual/Publishing.html][publishing management
- system]] by default that allows you to export org files to Org,
- iCalendar, HTML, LaTex, Markdown, ODT, and Plain Text. Most of these
- can be exported into another buffer and opened, or simply to an
- external file.
+ Org includes a [[https://orgmode.org/manual/Publishing.html][publishing management system]] by default that allows you to
+ export org files to Org, iCalendar, HTML, LaTex, Markdown, ODT, and Plain
+ Text. Most of these can be exported into another buffer and opened, or simply
+ to an external file.
- While inside an org file, simply run =SPC m e= or
- =M-x org-export-dispatch= to open the export menu. This menu will
- show all options and ask you to select an option. If you want to
- export to HTML, simply press =h= and then =H= (As HTML buffer), =h=
- (As HTML file), or =o= (As HTML file and open).
+ While inside an org file, simply run =SPC m e= or =M-x org-export-dispatch=
+ to open the export menu. This menu will show all options and ask you to
+ select an option. If you want to export to HTML, simply press =h= and then
+ =H= (As HTML buffer), =h= (As HTML file), or =o= (As HTML file and open).
2. Projects
- Some publishing options are easier with a defined project in Emacs.
- To create a project within Emacs, I use two methods:
+ Some publishing options are easier with a defined project in Emacs. To create
+ a project within Emacs, I use two methods:
- 1. Add the project via the projectile command =SPC p a=. Does not
- always work for me.
+ 1. Add the project via the projectile command =SPC p a=. Does not always work
+ for me.
2. Add an empty =.projectile= file in the project root.
- Once a project has been created, you can create custom publishing
- actions within your =~/.doom.d/config.el= file. For example, here's a
- test project I created to try and convert this blog to org-mode
- recently.
+ Once a project has been created, you can create custom publishing actions
+ within your =~/.doom.d/config.el= file. For example, here's a test project I
+ created to try and convert this blog to org-mode recently.
#+begin_src lisp
;; org-publish
@@ -342,19 +322,18 @@ basic commands I use myself.
** General Thoughts
-I have enjoyed Doom Emacs (far more than GNU Emacs) and will likely
-continue to use it as my main editor for the time being. Org-Mode is
-certainly the largest factor here, as I far prefer it over Markdown due
-to its inherent features and detailed markup options. However, working
-with org-mode on iOS has been a pain and I will have to see if there's
-an easier way to resolve those issues or if going back to separate
-Markdown, Reminders, and Calendar apps is easier to work with than an
-all-in-one org solution.
-
-[fn:1] Doom's evil-window functionality is a bit different from GNU
- Emacs, but you can always switch to the "other" buffer with
- =C-x o= or =C-x b= to get a list of buffers to select.
-
-[fn:2] Doom's evil-window functionality is a bit different from GNU
- Emacs, but you can always switch to the "other" buffer with
- =C-x o= or =C-x b= to get a list of buffers to select.
+I have enjoyed Doom Emacs (far more than GNU Emacs) and will likely continue to
+use it as my main editor for the time being. Org-Mode is certainly the largest
+factor here, as I far prefer it over Markdown due to its inherent features and
+detailed markup options. However, working with org-mode on iOS has been a pain
+and I will have to see if there's an easier way to resolve those issues or if
+going back to separate Markdown, Reminders, and Calendar apps is easier to work
+with than an all-in-one org solution.
+
+[fn:1] Doom's evil-window functionality is a bit different from GNU Emacs, but
+ you can always switch to the "other" buffer with =C-x o= or =C-x b= to
+ get a list of buffers to select.
+
+[fn:2] Doom's evil-window functionality is a bit different from GNU Emacs, but
+ you can always switch to the "other" buffer with =C-x o= or =C-x b= to
+ get a list of buffers to select.
diff --git a/content/blog/2024-03-15-self-hosting-ddns-updater.org b/content/blog/2024-03-15-self-hosting-ddns-updater.org
index 4add649..64e7a6c 100644
--- a/content/blog/2024-03-15-self-hosting-ddns-updater.org
+++ b/content/blog/2024-03-15-self-hosting-ddns-updater.org
@@ -6,25 +6,21 @@
#+caption: DDNS Updater Web View
[[https://img.cleberg.net/blog/20240315-ddns-updater/ddns.png]]
-[[https://github.com/qdm12/ddns-updater][DDNS Updater]] is a program to
-keep DNS A and/or AAAA records updated for multiple DNS providers.
+[[https://github.com/qdm12/ddns-updater][DDNS Updater]] is a program to keep DNS A and/or AAAA records updated for multiple
+DNS providers.
-If you've read any of my other posts, you'll notice that I have been
-searching for and using a few different DDNS updating solutions for
-years. You'll also notice that I love any projects that offer a Docker
-Compose solution.
+If you've read any of my other posts, you'll notice that I have been searching
+for and using a few different DDNS updating solutions for years. You'll also
+notice that I love any projects that offer a Docker Compose solution.
Luckily, DDNS Upater fits both of these preferences.
** Installation
-To get started, always make sure to review the project's
-[[https://github.com/qdm12/ddns-updater/blob/master/README.md][README]].
-I'll be documenting my steps below, but they may have changed by the
-time you read this.
+To get started, always make sure to review the project's [[https://github.com/qdm12/ddns-updater/blob/master/README.md][README]]. I'll be
+documenting my steps below, but they may have changed by the time you read this.
-The first step is to set up the directories and files required for the
-project.
+The first step is to set up the directories and files required for the project.
#+begin_src sh
mkdir ~/ddns-updater
@@ -34,43 +30,36 @@ touch ~/ddns-updater/data/config.json
*** Configuration
-The main configuration you need to update is the =data/config.json=
-file. There is a large list of supported providers in the README, but
-I'm going to use Cloudflare in this example.
+The main configuration you need to update is the =data/config.json= file. There
+is a large list of supported providers in the README, but I'm going to use
+Cloudflare in this example.
#+begin_src sh
nano ~/ddns-updater/data/config.json
#+end_src
-When setting up the configuration for Cloudflare, you'll need the
-following:
+When setting up the configuration for Cloudflare, you'll need the following:
- Required Parameters
- - ="zone_identifier"= is the Zone ID of your site from the domain
- overview page
- - ="host"= is your host and can be ="@"=, a subdomain or the wildcard
- ="*"=. See
- [[https://github.com/qdm12/ddns-updater/issues/243#issuecomment-928313949][this
- issue comment for context]].
- - ="ttl"= integer value for record TTL in seconds (specify 1 for
- automatic)
- - One of the following
- ([[https://developers.cloudflare.com/fundamentals/api/get-started/][how
- to find API keys]]):
+ - ="zone_identifier"= is the Zone ID of your site from the domain overview
+ page
+ - ="host"= is your host and can be ="@"=, a subdomain or the wildcard ="*"=.
+ See [[https://github.com/qdm12/ddns-updater/issues/243#issuecomment-928313949][this issue comment for context]].
+ - ="ttl"= integer value for record TTL in seconds (specify 1 for automatic)
+ - One of the following ([[https://developers.cloudflare.com/fundamentals/api/get-started/][how to find API keys]]):
- Email ="email"= and Global API Key ="key"=
- User service key ="user_service_key"=
- - API Token ="token"=, configured with DNS edit permissions for your
- DNS name's zone
+ - API Token ="token"=, configured with DNS edit permissions for your DNS
+ name's zone
- Optional Parameters
- - ="proxied"= can be set to =true= to use the proxy services of
- Cloudflare
- - ="ip_version"= can be =ipv4= (A records), or =ipv6= (AAAA records)
- or =ipv4 or ipv6= (update one of the two, depending on the public
- ip found). It defaults to =ipv4 or ipv6=.
- - ="ipv6_suffix"= is the IPv6 interface identifier suffix to use. It
- can be for example =0:0:0:0:72ad:8fbb:a54e:bedd/64=. If left empty,
- it defaults to no suffix and the raw public IPv6 address obtained is
- used in the record updating.
+ - ="proxied"= can be set to =true= to use the proxy services of Cloudflare
+ - ="ip_version"= can be =ipv4= (A records), or =ipv6= (AAAA records) or =ipv4
+ or ipv6= (update one of the two, depending on the public ip found). It
+ defaults to =ipv4 or ipv6=.
+ - ="ipv6_suffix"= is the IPv6 interface identifier suffix to use. It can be
+ for example =0:0:0:0:72ad:8fbb:a54e:bedd/64=. If left empty, it defaults to
+ no suffix and the raw public IPv6 address obtained is used in the record
+ updating.
#+begin_src conf
{
@@ -90,8 +79,8 @@ following:
}
#+end_src
-Once you have configured the provider of your choice, correct the file
-and directory permissions and ownership.
+Once you have configured the provider of your choice, correct the file and
+directory permissions and ownership.
#+begin_src sh
cd ~/ddns_updater
@@ -105,8 +94,8 @@ chmod 400 data/config.json
*** Docker Compose
-After creating the project structure, let's create the
-=docker-compose.yml= file.
+After creating the project structure, let's create the =docker-compose.yml=
+file.
#+begin_src sh
nano ~/ddns_-pdater/docker-compose.yml
@@ -150,22 +139,22 @@ services:
restart: always
#+end_src
-After configuring your preferences in the =docker-compose.yml=, launch
-the container.
+After configuring your preferences in the =docker-compose.yml=, launch the
+container.
#+begin_src sh
cd ~/ddns-updater
sudo docker-compose up -d
#+end_src
-If you've launched this on your local machine, you can launch
-=localhost:8097= in your browser to see the results.
+If you've launched this on your local machine, you can launch =localhost:8097=
+in your browser to see the results.
*** Nginx Reverse Proxy
-If you launched this service on a server, other machine, or just want to
-access it remotely via a domain name, you can use Nginx as a reverse
-proxy to expose the service publicly.
+If you launched this service on a server, other machine, or just want to access
+it remotely via a domain name, you can use Nginx as a reverse proxy to expose
+the service publicly.
Start by creating the Nginx configuration file.
@@ -193,8 +182,8 @@ server {
}
#+end_src
-Here's a full example that uses my Authelia authentication service to
-require authentication before someone can access the web page.
+Here's a full example that uses my Authelia authentication service to require
+authentication before someone can access the web page.
#+begin_src conf
server {
diff --git a/content/blog/2024-03-29-org-blog.org b/content/blog/2024-03-29-org-blog.org
index db60c65..5ae1a2b 100644
--- a/content/blog/2024-03-29-org-blog.org
+++ b/content/blog/2024-03-29-org-blog.org
@@ -3,48 +3,41 @@
#+description:
#+slug: org-blog
-First and foremost, apologies to those who subscribe via RSS as I know
-that my feed duplicated itself when I moved this blog over to org-mode
-last night.
+First and foremost, apologies to those who subscribe via RSS as I know that my
+feed duplicated itself when I moved this blog over to org-mode last night.
-This post focuses specifically on the configuration and tools I use to
-blog from Emacs with Org-Mode and does not focus on Emacs or Org-Mode
-themselves. Refer to the post I wrote about
-[[https://cleberg.net/blog/doom-emacs-org-mode.html][Doom Emacs & Org-Mode]] for
-more information about my base Emacs configuration.
+This post focuses specifically on the configuration and tools I use to blog from
+Emacs with Org-Mode and does not focus on Emacs or Org-Mode themselves. Refer to
+the post I wrote about [[https://cleberg.net/blog/doom-emacs-org-mode.html][Doom Emacs & Org-Mode]] for more information about my base
+Emacs configuration.
* Weblorg
-The first step in blogging with Org-Mode is to choose a method to
-convert the source files to HTML and publish them. The Worg site
-maintains a nice list of
-[[https://orgmode.org/worg/org-blog-wiki.html][Blogs and Wikis with
-Org]], but the tools are inevitably different and opinionated, so you'll
-need to find what works for you.
-
-I tried using Jekyll, Hugo, ox-hugo, Nikola, Blorg, org-static-blog, and
-the native org-publish functions before finally settling on Weblorg. For
-one reason or another, the other solutions were a drastic step down from
-my previous workflow that used [[https://www.getzola.org/][Zola]] with
-Markdown content.
-
-[[https://github.com/emacs-love/weblorg][Weblorg]] is a static site
-generator for [[https://orgmode.org/][org-mode]], built for use within
-[[https://www.gnu.org/software/emacs/][Emacs]]. Since it's written in
-Emacs Lisp, there's no need to install other languages or frameworks to
-get started. More than that, you can write in any editor you please and
-simply invoke the Emacs build process with the =--script= parameter
+The first step in blogging with Org-Mode is to choose a method to convert the
+source files to HTML and publish them. The Worg site maintains a nice list of
+[[https://orgmode.org/worg/org-blog-wiki.html][Blogs and Wikis with Org]], but the tools are inevitably different and
+opinionated, so you'll need to find what works for you.
+
+I tried using Jekyll, Hugo, ox-hugo, Nikola, Blorg, org-static-blog, and the
+native org-publish functions before finally settling on Weblorg. For one reason
+or another, the other solutions were a drastic step down from my previous
+workflow that used [[https://www.getzola.org/][Zola]] with Markdown content.
+
+[[https://github.com/emacs-love/weblorg][Weblorg]] is a static site generator for [[https://orgmode.org/][org-mode]], built for use within [[https://www.gnu.org/software/emacs/][Emacs]].
+Since it's written in Emacs Lisp, there's no need to install other languages or
+frameworks to get started. More than that, you can write in any editor you
+please and simply invoke the Emacs build process with the =--script= parameter
instead of requiring you to blog inside Emacs.
** Installation
-The [[https://emacs.love/weblorg/doc/index.html][Getting Started]] page
-details broad installation requirements. I am using Doom Emacs on macOS,
-which requires you to add the package to the =~/.doom.d/packages.el=
-file and configure the =publish.el= file slightly differently.
+The [[https://emacs.love/weblorg/doc/index.html][Getting Started]] page details broad installation requirements. I am using
+Doom Emacs on macOS, which requires you to add the package to the
+=~/.doom.d/packages.el= file and configure the =publish.el= file slightly
+differently.
-To start, add the =htmlize= and =weblorg= packages to Doom, sync the
-changes, and reload.
+To start, add the =htmlize= and =weblorg= packages to Doom, sync the changes,
+and reload.
#+begin_src sh
nano ~/.doom.d/packages.el
@@ -63,18 +56,17 @@ Either re-open Emacs or hit =SPC h r r= to reload the changes.
** Configuration
-Now that I've installed weblorg, I need to configure the project. I'll
-start by navigating to my site's source code and creating a =publish.el=
-file.
+Now that I've installed weblorg, I need to configure the project. I'll start by
+navigating to my site's source code and creating a =publish.el= file.
#+begin_src sh
cd ~/Source/cleberg.net && nano publish.el
#+end_src
-Since I'm using Doom, Emacs will not automatically load the packages I
-need later in the build process. To compensate, my =publish.el= file
-needs to explicitly tell Emacs where Doom stores the =htmlize=,
-=weblorg=, and =templatel= packages.
+Since I'm using Doom, Emacs will not automatically load the packages I need
+later in the build process. To compensate, my =publish.el= file needs to
+explicitly tell Emacs where Doom stores the =htmlize=, =weblorg=, and
+=templatel= packages.
#+begin_src lisp
;; explicity load packages since I'm using Doom Emacs
@@ -184,12 +176,10 @@ needs to explicitly tell Emacs where Doom stores the =htmlize=,
** Structure
The project structure for weblorg is highly customizable and the main
-restriction is that the =publish.el= file must point to the correct
-paths.
+restriction is that the =publish.el= file must point to the correct paths.
-For my blog, I prefer to keep the blog content out of the top-level
-directory. This results in the following structure (shortened for
-brevity):
+For my blog, I prefer to keep the blog content out of the top-level directory.
+This results in the following structure (shortened for brevity):
#+begin_src txt
.build/
@@ -217,17 +207,17 @@ build.sh
publish.el
#+end_src
-This is simply my preferred structure and you can alter it to fit your
-needs. The key here really is that you can customize at will, as long as
-the =publish.el= file matches.
+This is simply my preferred structure and you can alter it to fit your needs.
+The key here really is that you can customize at will, as long as the
+=publish.el= file matches.
** Build & Deploy
-Once you're content with the status of the project, you're ready to
-build and deploy the blog.
+Once you're content with the status of the project, you're ready to build and
+deploy the blog.
-My process utilizes a =build.sh= script that combines the steps I take
-every time.
+My process utilizes a =build.sh= script that combines the steps I take every
+time.
#+begin_src sh
touch build.sh && chmod +x build.sh && nano build.sh
@@ -235,16 +225,16 @@ touch build.sh && chmod +x build.sh && nano build.sh
Within this script, I do the following:
-1. Remove any files within the =.build= directory that I use to store
- published files.
-2. Set the environment variable to =prod= to ensure the =base_url=
- matches my configuration in =publish.el=.
+1. Remove any files within the =.build= directory that I use to store published
+ files.
+2. Set the environment variable to =prod= to ensure the =base_url= matches my
+ configuration in =publish.el=.
3. Build the site with Emacs & =publish.el=.
4. Use =scp= to copy files to my site's public directory on my server.
#+begin_src sh
-rm -rf .build/* && \
-ENV=prod emacs --script publish.el && \
+rm -rf .build/* && \
+ENV=prod emacs--script publish.el && \
scp -r .build/* ubuntu:/var/www/cleberg.net/
#+end_src
@@ -252,13 +242,12 @@ scp -r .build/* ubuntu:/var/www/cleberg.net/
My only current complaints are:
-1. Errors messages are not helpful. It takes work to determine what the
- error is and where it's coming from. I generally have to sit and
- watch the build process to see the file that weblorg pubslishes right
- before the error occurred.
-2. The build process re-builds every single file on each run, which
- takes a long time for a blog of my size. See below for the last time
- I measured.
+1. Errors messages are not helpful. It takes work to determine what the error is
+ and where it's coming from. I generally have to sit and watch the build
+ process to see the file that weblorg pubslishes right before the error
+ occurred.
+2. The build process re-builds every single file on each run, which takes a long
+ time for a blog of my size. See below for the last time I measured.
#+begin_src sh
> time ./build.sh
@@ -266,5 +255,5 @@ My only current complaints are:
./build.sh 35.46s user 0.59s system 85% cpu 41.965 total
#+end_src
-Overall, I have thoroughly enjoyed using weblog and will continue to use
-it going forward until I find something better.
+Overall, I have thoroughly enjoyed using weblog and will continue to use it
+going forward until I find something better.
diff --git a/content/blog/2024-04-06-convert-onenote-to-markdown.org b/content/blog/2024-04-06-convert-onenote-to-markdown.org
index 543b2db..87a2cad 100644
--- a/content/blog/2024-04-06-convert-onenote-to-markdown.org
+++ b/content/blog/2024-04-06-convert-onenote-to-markdown.org
@@ -3,54 +3,49 @@
#+description:
#+slug: convert-onenote-to-markdown
-If you're looking to convert your OneNote content to another format,
-such as Markdown or Org-Mode, you're in luck. I use a solution that
-doesn't require other programs, such as Evernote or Notion. Personally,
-I used this solution on a managed corporate laptop that doesn't allow
-installation of other programs like these.
+If you're looking to convert your OneNote content to another format, such as
+Markdown or Org-Mode, you're in luck. I use a solution that doesn't require
+other programs, such as Evernote or Notion. Personally, I used this solution on
+a managed corporate laptop that doesn't allow installation of other programs
+like these.
This solution uses OneNote and Pandoc on Windows 10.
* Export OneNote Content to Word
-To start, export any pages or tabs from OneNote to the Word format
-(=.docx=):
+To start, export any pages or tabs from OneNote to the Word format (=.docx=):
1. Open OneNote desktop.
2. Select =File= and then =Export=.
3. Select the scope of content to export, such as =Tab= or =Page=.
-4. Name and save the file in an easy to remember location. I recommend
- your Downloads or Desktop folder.
+4. Name and save the file in an easy to remember location. I recommend your
+ Downloads or Desktop folder.
See below for a visual walkthrough of the export process.
* Download Pandoc
-Start by downloading Pandoc from their
-[[https://github.com/jgm/pandoc/releases][GitHub releases]] page. I
-cannot install =.msi= files on my corporate laptop, so I downloaded the
-=pandoc-3.1.12.3-windows-x86_64.zip= file, which contains a simple
-=.exe= file that you do not need to install - you will simply run it
-from the command line below.
+Start by downloading Pandoc from their [[https://github.com/jgm/pandoc/releases][GitHub releases]] page. I cannot install
+=.msi= files on my corporate laptop, so I downloaded the
+=pandoc-3.1.12.3-windows-x86_64.zip= file, which contains a simple =.exe= file
+that you do not need to install - you will simply run it from the command line
+below.
-Once downloaded, unzip the archive and move the =pandoc.exe= file to the
-same folder where your Word documents were saved above. If you prefer,
-you can move this file to an easier location, such as
-=C:\Users\youruser\Downloads=.
+Once downloaded, unzip the archive and move the =pandoc.exe= file to the same
+folder where your Word documents were saved above. If you prefer, you can move
+this file to an easier location, such as =C:\Users\youruser\Downloads=.
* Convert Word to Markdown
-In this example, I will be converting the Word documents to Markdown,
-but Pandoc supports
-[[https://github.com/jgm/pandoc?tab=readme-ov-file#the-universal-markup-converter][a
-ton of different formats for conversion]]. Choose the format you prefer
+In this example, I will be converting the Word documents to Markdown, but Pandoc
+supports [[https://github.com/jgm/pandoc?tab=readme-ov-file#the-universal-markup-converter][a ton of different formats for conversion]]. Choose the format you prefer
and then modify the following commands as needed.
-To perform the conversion, open the Command Prompt. If you can't find
-it, open the start menu and search for it.
+To perform the conversion, open the Command Prompt. If you can't find it, open
+the start menu and search for it.
-Within the command prompt, navigate to the directory where you stored
-the =pandoc.exe= file and the Word documents.
+Within the command prompt, navigate to the directory where you stored the
+=pandoc.exe= file and the Word documents.
#+begin_src ps1
cd "C:\Users\yourusername\Downloads"
@@ -63,9 +58,9 @@ command.
dir
#+end_src
-Once you have verified that you have the command prompt open in the
-correct directory with the =pandoc.exe= and the Word documents, you can
-run the following loop to convert all Word documents to Markdown.
+Once you have verified that you have the command prompt open in the correct
+directory with the =pandoc.exe= and the Word documents, you can run the
+following loop to convert all Word documents to Markdown.
#+begin_src ps1
for %f in (*.docx) do (pandoc.exe --extract-media=. --wrap=preserve "%f" -o "%f.md")
@@ -73,25 +68,24 @@ for %f in (*.docx) do (pandoc.exe --extract-media=. --wrap=preserve "%f" -o "%f.
This loop will perform the following actions:
-1. Find all documents matching the pattern =*.docx=, which means all
- Word documents ending with that file extension.
+1. Find all documents matching the pattern =*.docx=, which means all Word
+ documents ending with that file extension.
2. Iterate through all files found in step 1.
3. For each file, perform the pandoc command.
-4. Within the pandoc command, =--extract-media= saves all media found in
- the files to the current folder, with pandoc automatically creating a
- =media= subfolder to hold all images.
-5. Within the pandoc command, =--wrap=preserve= will attempt to prseerve
- the wrapping from the source document.
-6. Within the pandoc command, the final step is to specify the output
- path with =-o=. This option adds the =.md= file extension to
- recognize the output files as Markdown files.
-
-If you want to export to another format, simply specify the
-=-f==/=--from== and =-t==/=--to== options.
-
-For example, you can convert the Word document to org-mode. You can also
-convert to one format and subsequently convert to other formats as
-needed.
+4. Within the pandoc command, =--extract-media= saves all media found in the
+ files to the current folder, with pandoc automatically creating a =media=
+ subfolder to hold all images.
+5. Within the pandoc command, =--wrap=preserve= will attempt to prseerve the
+ wrapping from the source document.
+6. Within the pandoc command, the final step is to specify the output path with
+ =-o=. This option adds the =.md= file extension to recognize the output files
+ as Markdown files.
+
+If you want to export to another format, simply specify the =-f==/=--from== and
+=-t==/=--to== options.
+
+For example, you can convert the Word document to org-mode. You can also convert
+to one format and subsequently convert to other formats as needed.
#+begin_src ps1
pandoc.exe -f docx -t org file.docx
diff --git a/content/blog/2024-04-08-docker-local-web-server.org b/content/blog/2024-04-08-docker-local-web-server.org
index 7333bef..f551450 100644
--- a/content/blog/2024-04-08-docker-local-web-server.org
+++ b/content/blog/2024-04-08-docker-local-web-server.org
@@ -3,43 +3,42 @@
#+description:
#+slug: docker-local-web-server
-When developing websites locally, I often use a simple Python web server
-to observe the changes.
+When developing websites locally, I often use a simple Python web server to
+observe the changes.
#+begin_src sh
python3 -m http.server
#+end_src
-However, this approach has its limitations. For example, this approach
-does not enable logging or access controls. You also need to customize
-=SimpleHTTPServer= if you have advanced needs from your web server.
+However, this approach has its limitations. For example, this approach does not
+enable logging or access controls. You also need to customize =SimpleHTTPServer=
+if you have advanced needs from your web server.
-So, I went to find an alternative that is almost as easy and far more
-extensible and found Docker Desktop to be a suitable replacement.
+So, I went to find an alternative that is almost as easy and far more extensible
+and found Docker Desktop to be a suitable replacement.
* Docker Desktop
** Installation
-[[https://www.docker.com/products/docker-desktop/][Docker Desktop]] is a
-desktop GUI for the phenomenal Docker container software. This allows
-you to manage containers, images, volumes, environments, and extensions
-via an easy-to-use GUI.
+[[https://www.docker.com/products/docker-desktop/][Docker Desktop]] is a desktop GUI for the phenomenal Docker container software.
+This allows you to manage containers, images, volumes, environments, and
+extensions via an easy-to-use GUI.
To install, open the link above and click the =Download= button for your
-platform. I'm going through this process on an M2 Macbook, so I
-downloaded the Mac - Apple Chip version.
+platform. I'm going through this process on an M2 Macbook, so I downloaded the
+Mac - Apple Chip version.
-Open the installer and follow the installation process until the
-application finishes the installation process.
+Open the installer and follow the installation process until the application
+finishes the installation process.
#+caption: Docker Desktop on macOS
[[https://img.cleberg.net/blog/20240408-docker-local-web-server/docker-desktop.png]]
** Creating an Nginx Container
-I prefer to use the command line to create containers, so the following
-commands will be input via the terminal.
+I prefer to use the command line to create containers, so the following commands
+will be input via the terminal.
The following command will create a container, using the =nginx= image:
@@ -61,20 +60,20 @@ You can navigate to [[http://localhost:8000]] to see the resulting page.
** Customizing the Nginx Container
-Now that I have a container running the Nginx web server, I need to link
-some volumes so that I can modify the site configuration and provide the
-web files to serve.
+Now that I have a container running the Nginx web server, I need to link some
+volumes so that I can modify the site configuration and provide the web files to
+serve.
Let's start with the new command, which adds two volumes:
-1. =<your_content>:/usr/share/nginx/html=: This is the directory where
- you will provide the web pages for the server to serve.
+1. =<your_content>:/usr/share/nginx/html=: This is the directory where you will
+ provide the web pages for the server to serve.
2. =<your_config>:/etc/nginx/conf.d/default.conf=: This is the Nginx
configuration file for your site.
-To see the updates, you can delete the previous container in the GUI or
-run =docker stop web= to stop the container. Once stopped, you can run
-the new =docker run= command below.
+To see the updates, you can delete the previous container in the GUI or run
+=docker stop web= to stop the container. Once stopped, you can run the new
+=docker run= command below.
#+begin_src sh
docker run -it -d -p 8000:80 --name web -v ~/Source/cleberg.net/.build:/usr/share/nginx/html -v ~/Source/cleberg.net/nginx-config.conf:/etc/nginx/conf.d/default.conf nginx
@@ -107,16 +106,15 @@ server {
* Customizing Deployment Actions
-I am currently blogging with [[https://emacs.love/weblorg/][weblorg]],
-which uses a custom =publish.el= file to build the static site. Within
-this file, I have configured my deployment process to check for the
-=ENV= variable in thesh and if it's set to =prod=, the script will set
-the base URLs to =https://cleberg.net=. If not, it sets the base URLs to
-=localhost:8000= (which matches the port used in the container above).
+I am currently blogging with [[https://emacs.love/weblorg/][weblorg]], which uses a custom =publish.el= file to
+build the static site. Within this file, I have configured my deployment process
+to check for the =ENV= variable in thesh and if it's set to =prod=, the script
+will set the base URLs to =https://cleberg.net=. If not, it sets the base URLs
+to =localhost:8000= (which matches the port used in the container above).
-Therefore, I have modified my =build.sh= script to build with
-=localhost= URLs if =ENV= is not set to =prod=. It also prevents the
-build process from sending the built files to the production web server.
+Therefore, I have modified my =build.sh= script to build with =localhost= URLs
+if =ENV= is not set to =prod=. It also prevents the build process from sending
+the built files to the production web server.
#+begin_src sh
#!/bin/bash
@@ -133,7 +131,6 @@ else
fi
#+end_src
-You can modify the container in numerous ways and this approach allows
-you to create complex scenarios for your web development purposes. I
-highly recommend switching over to a container-based approach for
-simple, local web development.
+You can modify the container in numerous ways and this approach allows you to
+create complex scenarios for your web development purposes. I highly recommend
+switching over to a container-based approach for simple, local web development.
diff --git a/content/blog/2024-04-18-mu4e.org b/content/blog/2024-04-18-mu4e.org
index e422f88..dadfc0b 100644
--- a/content/blog/2024-04-18-mu4e.org
+++ b/content/blog/2024-04-18-mu4e.org
@@ -3,20 +3,18 @@
#+description:
#+slug: mu4e
-This post was heavily inspired by
-[[https://macowners.club/posts/email-emacs-mu4e-macos/][Email setup in
-Emacs with Mu4e on macOS]], but with my own tweaks for a single-account
-configuration and some Doom-specific configurations.
+This post was heavily inspired by [[https://macowners.club/posts/email-emacs-mu4e-macos/][Email setup in Emacs with Mu4e on macOS]], but
+with my own tweaks for a single-account configuration and some Doom-specific
+configurations.
* Overview
-[[https://github.com/emacsmirror/mu4e][Mu4e]] is an Emacs-based email
-client based on [[https://www.djcbsoftware.nl/code/mu/][mu]], an indexer
-that stores email in the Maildir format.
+[[https://github.com/emacsmirror/mu4e][Mu4e]] is an Emacs-based email client based on [[https://www.djcbsoftware.nl/code/mu/][mu]], an indexer that stores email in
+the Maildir format.
-This blog post covers the installation of Mu4e in Doom Emacs on macOS.
-This guide should be very similar to GNU Emacs and Linux-based systems,
-with a few tweaks required in the various configuration files.
+This blog post covers the installation of Mu4e in Doom Emacs on macOS. This
+guide should be very similar to GNU Emacs and Linux-based systems, with a few
+tweaks required in the various configuration files.
* Installation
@@ -34,21 +32,21 @@ mkdir ~/.maildir/certificates # used to store system root certificates
*** Store Email Account Passwords in macOS Keychain
-Next, I will be using the macOS Keychain to store my email account
-passwords using the command below.
+Next, I will be using the macOS Keychain to store my email account passwords
+using the command below.
#+begin_src sh
security add-generic-password -s mu4e-example -a you@example.com -w
#+end_src
This will prompt you to input your password twice to confirm. Keep the
-=mu4e-example= name in mind, as you will need to reference it later in
-the IMAP and SMTP configuration files.
+=mu4e-example= name in mind, as you will need to reference it later in the IMAP
+and SMTP configuration files.
*** Store Root Certificates
-In order to use IMAP and SMTP, we need to provide certificates to the
-local services. We will use the macOS defaults for this.
+In order to use IMAP and SMTP, we need to provide certificates to the local
+services. We will use the macOS defaults for this.
1. Open =Keychain Access.app=.
2. Select =System Roots= in the sidebar.
@@ -58,8 +56,8 @@ local services. We will use the macOS defaults for this.
*** Install Dependencies
-Install =mbsync= (via =isync=) to fetch emails via IMAP, =mu= to index
-emails, and =msmtp= to send emails via SMTP.
+Install =mbsync= (via =isync=) to fetch emails via IMAP, =mu= to index emails,
+and =msmtp= to send emails via SMTP.
#+begin_src sh
brew install mu isync msmtp
@@ -73,8 +71,8 @@ Within Doom Emacs, we can install Mu4e by enabling the package.
nano ~/.doom.d/init.el
#+end_src
-In this file, uncomment the =mu4e= line within the =:email= section. You
-can also enable the =+org= and =+gmail= options if you prefer.
+In this file, uncomment the =mu4e= line within the =:email= section. You can
+also enable the =+org= and =+gmail= options if you prefer.
#+begin_src lisp
(doom! :input
@@ -88,9 +86,9 @@ can also enable the =+org= and =+gmail= options if you prefer.
* Configuration
-As an overall suggestion, I create the following configuration files in
-the =~/.maildir= directory and using symlinks to their proper locations
-so that I can backup and restore these files easily.
+As an overall suggestion, I create the following configuration files in the
+=~/.maildir= directory and using symlinks to their proper locations so that I
+can backup and restore these files easily.
#+begin_src sh
touch ~/.maildir/.mbsyncrc && \
@@ -99,14 +97,13 @@ ln -s /Users/username/.maildir/.mbsyncrc /Users/username/.mbsyncrc && \
ln -s /Users/username/.maildir/.msmtprc /Users/username/.msmtprc
#+end_src
-You can also create these files in your home directory and skip the
-symlinking process above.
+You can also create these files in your home directory and skip the symlinking
+process above.
** IMAP
-Next, let's configure =mbsync= in the file created above. Paste the
-following information and customize it to match your mail provider's
-information.
+Next, let's configure =mbsync= in the file created above. Paste the following
+information and customize it to match your mail provider's information.
#+begin_src sh
nano ~/.maildir/.mbsyncrc
@@ -142,9 +139,8 @@ SyncState *
** SMTP
-Next, let's configured =msmtprc= in the file created above. Paste the
-following information and customize it to match your mail provider's
-information.
+Next, let's configured =msmtprc= in the file created above. Paste the following
+information and customize it to match your mail provider's information.
#+begin_src sh
nano ~/.maildir/.msmtprc
@@ -176,8 +172,8 @@ account default : startmail
** Doom Emacs
-Finally, we need to configure Doom Emacs to use the proper packages and
-set some variables and functions.
+Finally, we need to configure Doom Emacs to use the proper packages and set some
+variables and functions.
#+begin_src sh
nano ~/.doom.d/config.el
@@ -275,14 +271,12 @@ Be sure to sync Doom to update the current configurations.
doom sync
#+end_src
-If you have Doom open, execute =SPC h r r= to reload the new
-configurations.
+If you have Doom open, execute =SPC h r r= to reload the new configurations.
* Initial Sync
-Once you have configured all of the relevant files, you can perform an
-initial sync. Note that you can perform syncing within Mu4e itself after
-this.
+Once you have configured all of the relevant files, you can perform an initial
+sync. Note that you can perform syncing within Mu4e itself after this.
#+begin_src sh
mbsync -aV
@@ -299,11 +293,11 @@ The emails will now to be ready to use!
* Screenshots
-You can now launch Doom and open Mu4e with =SPC o m=. You can also
-explore the Mu4e options with =SPC : mu4e=.
+You can now launch Doom and open Mu4e with =SPC o m=. You can also explore the
+Mu4e options with =SPC : mu4e=.
-The home page shows various options and metadata about the account
-you've opened.
+The home page shows various options and metadata about the account you've
+opened.
#+caption: Mu4e Home Page
[[https://img.cleberg.net/blog/20240418-mu4e/mu4e.png]]
diff --git a/content/blog/2024-05-03-ubuntu-on-macos.org b/content/blog/2024-05-03-ubuntu-on-macos.org
index fea8162..e474a0d 100644
--- a/content/blog/2024-05-03-ubuntu-on-macos.org
+++ b/content/blog/2024-05-03-ubuntu-on-macos.org
@@ -3,24 +3,24 @@
#+description: Learn how to run Linux machines as applications on macOS with minimal hassle.
#+slug: ubuntu-on-macos
-Being a macOS user who previously used Linux for many years, I often
-find myself searching for alternatives to the Linux-native tools and
-methods that I had become used to over the years.
+Being a macOS user who previously used Linux for many years, I often find myself
+searching for alternatives to the Linux-native tools and methods that I had
+become used to over the years.
-Luckily, there's an option to simply use Linux directly on your macOS
-device without having to boot the whole device into Linux or having to
-SSH into another Linux machine.
+Luckily, there's an option to simply use Linux directly on your macOS device
+without having to boot the whole device into Linux or having to SSH into another
+Linux machine.
-In this post, I use [[https://orbstack.dev/][OrbStack]] to create an
-Ubuntu Linux machine to take advantage of the Linux system.
+In this post, I use [[https://orbstack.dev/][OrbStack]] to create an Ubuntu Linux machine to take advantage
+of the Linux system.
** Installing OrbStack
-OrbStack has a [[https://orbstack.dev/download][download page]] if you
-prefer to use =*.dmg= files to install applications.
+OrbStack has a [[https://orbstack.dev/download][download page]] if you prefer to use =*.dmg= files to install
+applications.
-Personally, I prefer to install everything through Homebrew. For
-OrbStack, run the following to install the application via Homebrew:
+Personally, I prefer to install everything through Homebrew. For OrbStack, run
+the following to install the application via Homebrew:
#+begin_src sh
brew install orbstack
@@ -28,72 +28,68 @@ brew install orbstack
** Creating a Linux Machine
-Once installed, you can launch OrbStack and create a Linux machine in a
-matter of seconds. The creation dialog defaults to Ubuntu.
+Once installed, you can launch OrbStack and create a Linux machine in a matter
+of seconds. The creation dialog defaults to Ubuntu.
#+caption: OrbStack's Linux Machine Creation Page
[[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/create.png]]
** Launching the Machine
-Once created, the dialog will close and you will be presented with your
-new list of machines. Simply double-click on a machine to run it.
+Once created, the dialog will close and you will be presented with your new list
+of machines. Simply double-click on a machine to run it.
-When you run the machine for the first time, it may warn you that a
-program is attempting to run a shell script. You can choose to manually
-inspect this shell script via the provided path if you wish. When you're
-comfortable with the script, you can toggle the
-=Suppress this message permanently= button and click OK to run the
-machine.
+When you run the machine for the first time, it may warn you that a program is
+attempting to run a shell script. You can choose to manually inspect this shell
+script via the provided path if you wish. When you're comfortable with the
+script, you can toggle the =Suppress this message permanently= button and click
+OK to run the machine.
#+begin_quote
*Quick Tip*!
-You will always be able to launch the OrbStack application and control
-the machine via the Machines page, but you can also use the OrbStack
-icon in the macOS menu bar to quickly control the machine without
-launching OrbStack itself.
+You will always be able to launch the OrbStack application and control the
+machine via the Machines page, but you can also use the OrbStack icon in the
+macOS menu bar to quickly control the machine without launching OrbStack itself.
#+end_quote
** Working in Linux
-Once successful, OrbStack will launch your default terminal and log you
-into the Linux machine you created above.
+Once successful, OrbStack will launch your default terminal and log you into the
+Linux machine you created above.
-In the example below, we can see that the machine is using
-=Linux ubuntu 6.9.6= and operates similar to a fresh Ubuntu install on
-bare metal.
+In the example below, we can see that the machine is using =Linux ubuntu 6.9.6=
+and operates similar to a fresh Ubuntu install on bare metal.
#+caption: Ubuntu CLI
[[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/cli.png]]
-You can also click the machine's folder icon in OrbStack to open the
-machine's file system within macOS's native Files app. Within Files, you
-can double-click to open any files and they will open in the macOS
-defaults for those file types (e.g., TextEdit).
+You can also click the machine's folder icon in OrbStack to open the machine's
+file system within macOS's native Files app. Within Files, you can double-click
+to open any files and they will open in the macOS defaults for those file types
+(e.g., TextEdit).
#+caption: Ubuntu Files
[[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/files.png]]
-Here's an example of opening the =test.md= file in the screenshot above,
-which defaults to opening in Xcode on my system.
+Here's an example of opening the =test.md= file in the screenshot above, which
+defaults to opening in Xcode on my system.
#+caption: Ubuntu Files
[[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/xcode.png]]
*** Test Examples
-As a quick example of the system, I installed =neofetch=, switched to
-the =zsh= shell, and ran a few common commands.
+As a quick example of the system, I installed =neofetch=, switched to the =zsh=
+shell, and ran a few common commands.
#+caption: Test Examples
[[https://img.cleberg.net/blog/20240503-ubuntu-on-macos/test.png]]
** Thoughts
-The installation, creation, and launch processes are seamless and
-provide an easy way to test or use Linux on macOS with little to no
-hassle.
+The installation, creation, and launch processes are seamless and provide an
+easy way to test or use Linux on macOS with little to no hassle.
The shell and file integrations are incredibly snappy and I have not
experienced any lag so far. Further, being able to open files in the
diff --git a/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org b/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org
index 532e89d..6041614 100644
--- a/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org
+++ b/content/blog/2024-06-19-deprecated-trusted-gpg-fix.org
@@ -5,8 +5,8 @@
** System Warning
-When running an update on an Ubuntu system, you may have run into a
-system warning that looks like the example below.
+When running an update on an Ubuntu system, you may have run into a system
+warning that looks like the example below.
#+begin_src txt
W: https://dl.yarnpkg.com/debian/dists/stable/InRelease: Key is stored in legacy
@@ -14,34 +14,33 @@ trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in
apt-key(8) for details.
#+end_src
-While this example references the =yarn= package, the warning message is
-the same for any repository using the deprecated =trusted.gpg= key ring.
+While this example references the =yarn= package, the warning message is the
+same for any repository using the deprecated =trusted.gpg= key ring.
-The issue arises from managing keys with the =apt-key= command, which
-utilizes the =/etc/apt/trusted.gpg= file by default. Instead, Ubuntu has
-moved to managing key rings with individual =.gpg= files in the
-=/etc/apt/trusted.gpg.d/= directory.
+The issue arises from managing keys with the =apt-key= command, which utilizes
+the =/etc/apt/trusted.gpg= file by default. Instead, Ubuntu has moved to
+managing key rings with individual =.gpg= files in the =/etc/apt/trusted.gpg.d/=
+directory.
-To fix this issue, let's check to see which keys are using the
-=trusted.gpg= key ring and move them into their own dedicated key ring.
+To fix this issue, let's check to see which keys are using the =trusted.gpg= key
+ring and move them into their own dedicated key ring.
** Finding All Keys in the Keyring
-Let's start by simply listing the keys used by the =apt= commands. To do
-this, run the following command.
+Let's start by simply listing the keys used by the =apt= commands. To do this,
+run the following command.
#+begin_src sh
sudo apt-key list
#+end_src
This command will show an output similar to the one below. You may see
-additional keys in the =/etc/apt/trusted.gpg.d/= directory - this is
-where we will be moving any keys currently found in the =trusted.gpg=
-key ring.
+additional keys in the =/etc/apt/trusted.gpg.d/= directory - this is where we
+will be moving any keys currently found in the =trusted.gpg= key ring.
-In the below example, we can see that this system has four different GPG
-keys stored within the =trusted.gpg= key ring. Let's go ahead and move
-them into their own files.
+In the below example, we can see that this system has four different GPG keys
+stored within the =trusted.gpg= key ring. Let's go ahead and move them into
+their own files.
#+begin_src txt
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead
@@ -73,24 +72,24 @@ uid [ unknown] nginx signing key <signing-key-3@nginx.com>
*** Exporting Keys to New Files
-Now that we know the keys, we will need to move them into their own key
-ring. We can do this by copying the last eight (8) characters from the
-key's signature and exporting it from this key ring into its own.
+Now that we know the keys, we will need to move them into their own key ring. We
+can do this by copying the last eight (8) characters from the key's signature
+and exporting it from this key ring into its own.
-Using the yarn example from the beginning, here's the command to move
-this key into its own key ring.
+Using the yarn example from the beginning, here's the command to move this key
+into its own key ring.
#+begin_src sh
sudo apt-key export 86E50310 | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/yarn.gpg
#+end_src
-You can repeat this process for any other keys, such as the =nginx= keys
-in the example above.
+You can repeat this process for any other keys, such as the =nginx= keys in the
+example above.
*** Cleaning Up
-If you run =sudo apt-key list= again, you should see the keys within
-their own key rings:
+If you run =sudo apt-key list= again, you should see the keys within their own
+key rings:
#+begin_src txt
/etc/apt/trusted.gpg.d/nginx-archive-keyring.gpg
@@ -117,17 +116,16 @@ sub rsa4096 2019-01-02 [S] [expires: 2026-01-23]
sub rsa4096 2019-01-11 [S] [expires: 2026-01-23]
#+end_src
-Once you have verified that the keys are valid and stored in their own
-key rings, you can archive the =trusted.gpg= file and run a system
-update to test the new files.
+Once you have verified that the keys are valid and stored in their own key
+rings, you can archive the =trusted.gpg= file and run a system update to test
+the new files.
#+begin_src sh
sudo mv /etc/apt/trusted.gpg /etc/apt/trusted.gpg.bkp
sudo apt update
#+end_src
-Once you've verified that updates work as expected and that the keys are
-working as intended, you can delete the =.bkp= file created above. If
-you're storing keys that are not easily re-attainable, I suggest keeping
-the =.bkp= file stored in a safe location until you are positive that
-you no longer need it.
+Once you've verified that updates work as expected and that the keys are working
+as intended, you can delete the =.bkp= file created above. If you're storing
+keys that are not easily re-attainable, I suggest keeping the =.bkp= file stored
+in a safe location until you are positive that you no longer need it.
diff --git a/content/blog/2024-07-11-emacs-on-ipad.org b/content/blog/2024-07-11-emacs-on-ipad.org
index 25e752f..662cac3 100644
--- a/content/blog/2024-07-11-emacs-on-ipad.org
+++ b/content/blog/2024-07-11-emacs-on-ipad.org
@@ -5,25 +5,23 @@
#+slug: emacs-on-ipad
-This post describes the process to install and use Emacs on the iPad Air
-13-inch (M2). The iPad used in this post is running iPadOS 17.6.
+This post describes the process to install and use Emacs on the iPad Air 13-inch
+(M2). The iPad used in this post is running iPadOS 17.6.
** Shell Application
-In order to use Emacs on an iPad, you will need a terminal emulator
-application. I recommend
-[[https://apps.apple.com/us/app/ish-shell/id1436902243][iSH]], since it
-runs a version of Alpine Linux within the app itself and will allow you
-to install packages that you need.
+In order to use Emacs on an iPad, you will need a terminal emulator application.
+I recommend [[https://apps.apple.com/us/app/ish-shell/id1436902243][iSH]], since it runs a version of Alpine Linux within the app itself
+and will allow you to install packages that you need.
#+caption: iSH Application
[[https://img.cleberg.net/blog/20240711-emacs-on-ipad/ish.png]]
** Require Packages
-I started by adding the required packages directly within iSH. Emacs
-should install dependencies by default, but I include a few other
-packages that I use in my terminal as well.
+I started by adding the required packages directly within iSH. Emacs should
+install dependencies by default, but I include a few other packages that I use
+in my terminal as well.
#+begin_src sh
apk add emacs ripgrep fd findutils
@@ -34,39 +32,37 @@ apk add emacs ripgrep fd findutils
** Emacs
-Once this is complete, you should be able to run Emacs natively on your
-iPad. It's effective, but can be slow at times.
+Once this is complete, you should be able to run Emacs natively on your iPad.
+It's effective, but can be slow at times.
-I attempted to also install Doom Emacs, which technically worked, but
-was so incredibly slow and buggy that I was not even able to take
-screenshots. Someone smarter than me could likely get it to work with a
-little tinkering.
+I attempted to also install Doom Emacs, which technically worked, but was so
+incredibly slow and buggy that I was not even able to take screenshots. Someone
+smarter than me could likely get it to work with a little tinkering.
#+caption: Emacs
[[https://img.cleberg.net/blog/20240711-emacs-on-ipad/emacs.png]]
*** MELPA
-You also have to remember to hook up MELPA yourself in the =.emacs= file
-to be able to search through their 5700+ packages instead of just ELPA
-packages. If you don't, you will only have access to ELPA packages like
-the ones below.
+You also have to remember to hook up MELPA yourself in the =.emacs= file to be
+able to search through their 5700+ packages instead of just ELPA packages. If
+you don't, you will only have access to ELPA packages like the ones below.
#+caption: package-install
[[https://img.cleberg.net/blog/20240711-emacs-on-ipad/melpa.png]]
-Once you have MELPA, you can install packages like the =dashboard=
-package shown below.
+Once you have MELPA, you can install packages like the =dashboard= package shown
+below.
#+caption: emacs-dashboard
[[https://img.cleberg.net/blog/20240711-emacs-on-ipad/dashboard.png]]
*** Speed
-While Emacs will run on my iPad, it's not perfect. The largest issue on
-my iPad is speed - loading Emacs takes 6-7 seconds and installing the
-=magit= package took 129 seconds.
+While Emacs will run on my iPad, it's not perfect. The largest issue on my iPad
+is speed - loading Emacs takes 6-7 seconds and installing the =magit= package
+took 129 seconds.
-I haven't played around enough to optimize loading times and poke around
-to see why the network requests take so long, but it's a big enough
-issue that I wouldn't see casual Emacs users dealing with the lag.
+I haven't played around enough to optimize loading times and poke around to see
+why the network requests take so long, but it's a big enough issue that I
+wouldn't see casual Emacs users dealing with the lag.