Displaying my monthly goals in org-agenda

Each month I set primary and secondary goals as part of my Groundhog Day Resolutions process. Setting goals is good, but I have a nasty habit of forgetting about them until a few days before they're due. Not good.

To combat this issue I wanted to add my goals somewhere I would see them every day: my org agenda.

My daily agenda display currently looks like this (minus client/private tasks):

My initial org-agenda

I wanted to keep the same agenda information, but with my monthly goals at the top so that I can't ignore them.

Thankfully org-agenda can be configured to show different views and agendas via the org-agenda-custom-commands variable.

The first step was to create a place to store my goals. I created an org file with TODO entries for each goal, all stored under a headline for the month. These entries are tagged with :GHD: so they can be filtered, and I added an :ACTIVE: tag for the current month.

The finished goals.org is laid out like this:

* TODO March 2021 [0/7] :GHD:ACTIVE:
** TODO [#A] Finish version 1.0 of Writing PHP with Emacs
** TODO [#A] Complete another session of deliberate practice
** TODO [#A] Finish version 0.3 of Craft Roulette
** TODO [#A] Contribute to a free software project
** TODO [#C] Run 120 miles
** TODO [#C] Read a book
** TODO [#C] Add detail pages to my secondary goals

The tag properties are inherited from the parent for each child goal, which makes setting the active month much simpler.

My first attempt used A and B for the priorities, but org-agenda gives all tasks a priority of B by default so the month headline was showing in the final view. Using A and C for my primary and secondary goals fixes this.

The custom agenda is made up of three parts:

  1. A list of primary goals.
  2. A list of secondary goals.
  3. The regular org agenda which shows scheduled tasks and deadlines.

I used the tags-todo command to list goals; it can filter tasks by file, tag, and priority which makes it perfect for the job. The configuration to show my primary goals is fairly simple:

(tags-todo "GHD+ACTIVE+PRIORITY=\"A\""
	   ((org-agenda-files '("~/org/goals.org"))))

This displays all TODO items in my "~/org/goals.org" file that have :GHD: and :ACTIVE: tags AND a priority of A. To display secondary goals, all I need to do is replace the priority with C.

After the tags-todo command I use the agenda command with the timespan set to one day/one week depending on the view.

The finished configuration looks like this (with a little modification for brevity/online readability):

(setq org-agenda-custom-commands
'(("d" "Today's Tasks"
	((tags-todo
	  "GHD+ACTIVE+PRIORITY=\"A\""
	  ((org-agenda-files '("~/org/goals.org"))
	   (org-agenda-overriding-header "Primary goals this month")))
	 (tags-todo
	  "GHD+ACTIVE+PRIORITY=\"C\""
	  ((org-agenda-files '("~/org/goals.org"))
	   (org-agenda-overriding-header "Secondary goals this month")))
	 (agenda "" ((org-agenda-span 1)
		     (org-agenda-overriding-header "Today")))))

  ("w" "This Week's Tasks"
       ((tags-todo
	 "GHD+ACTIVE+PRIORITY=\"A\""
	 ((org-agenda-files '("~/org/goals.org"))
	  (org-agenda-overriding-header "Primary goals this month")))
	(tags-todo
	 "GHD+ACTIVE+PRIORITY=\"C\""
	 ((org-agenda-files '("~/org/goals.org"))
	  (org-agenda-overriding-header "Secondary goals this month")))
	(agenda))))
)

I can now view a daily agenda using C-c a d, or a weekly one using C-c a w, and the agenda has both sets of goals at the top:

The new and improved org-agenda

Now I have no excuse for forgetting them.


Adding emoji to Emacs buffers with emojify

emojify is an Emacs package that adds emoji support to any Emacs buffer.

emojify-mode works in all kinds of places

Running M-x emojify-mode will turn on emoji support for the current buffer. It does not alter the contents of the buffer, only how it's displayed. This makes it safer to use, but it does have some weird side-effects when aligning text in certain buffers (like org-agenda).

There is also no support for html export, although there's a GitHub issue open with some workarounds.

Any required images will be downloaded the first time running emojify-mode, and a full list of supported emojis can be viewed with emojify-list-emojis. There are over 5,000 so it can take a while to display.

global-emojify-mode can be used enable the mode everywhere:

;; Enable everywhere via an init hook.
(add-hook 'after-init-hook #'global-emojify-mode)

;; Or with use-package.
(use-package emojify
  :init
  (global-emojify-mode))

I prefer to enable emojify on a per-project basis, so I use .dir-locals.el to enable it for org and markdown buffers:

((org-mode      . ((mode . emojify)))
 (markdown-mode . ((mode . emojify))))

Yet another reason to ❤️ Emacs.


Finding areas to improve

One of my major goals for this year is to improve my processes. It's a bit of a vague goal at the moment, but the general idea is to examine how I currently get things done and to tweak things as needed.

I've been doing the same job for over a decade now (and programming computers even longer) so I feel like there there are plenty of areas where I've stagnated.

The first step is finding where I can make improvements. There are a couple of different ways I can do this:

  1. Thinking through things – This is a bit like proofreading my own work; it finds problems, but it misses just as many. I still think it's useful to sit down and examine my routines, but it's not a foolproof strategy.
  2. Get outside help – If the previous method is proofreading, this is hiring an editor. I get regular feedback on my work from clients, but it's usually on what I've done, not how I've done it.
  3. Record myself working – It's pretty common for people to record themselves to check their form when working out. This is the same thing, but with boring work instead of lifting weights.

Right now I'm trying out #3 with some success. It's a little time consuming to watch videos of my work, but it's helped me find a couple of small things already:

  • When working BlitzMax code I spend a fair amount of time typing closing statements like End Function or End Method. This is something I can fix in blitzmax-mode.
  • I'm not comfortable renaming files I'm working on from within Emacs, so I'll open the file manager to do it.
  • I'll switch to a browser to look something up and usually end up getting distracted. Either blocking distracting sites or using Emacs to search documentation would fix this.

There are still plenty of things I'd like to improve on, but these came up within a few sessions of recording myself.


Filtering referral spam from my server logs, part 2

There are two tasks that never seem to end: removing dog hair from my clothes, and filtering spam.

Last year I implemented a basic system for filtering my logs, but over time it has been less effective. I wanted to create something that:

  • Could be reused across all of my sites.
  • Could be configured through files instead of having update the report generation script.
  • Could utilize third-party spam lists.

Before implementing any changes my goaccess reports looked like this:

Referer spam REALLY ruins everything

Nearly everything on that list is spam, and that's only the top 10. For monthly and yearly reports this amount of spam makes it hard to find pages that are actually doing well.

In the end I modified my existing grep setup with additional passes. It's a little slow on large logs, so I usually save the filtered log to speed up subsequent reports.

I created three files with keywords to remove:

  • bots.list contains a list of bot user agents that I want to ignore. This can also be done from within goaccess, but I wanted them completely scrubbed from my logs.
  • global-spammers.list is the contents of src/domains.txt from the referrer-spam-blocker project. It's a pretty hefty list.
  • spammers.list contains a list of spam domains that aren't in the global list. I normally add new items once or twice a week.

All of these files live in my "~/.config/" directory so I can use them on different projects. They're simple lists that have one entry per line:

spammersdomain.com
spammersdomain.org
anotherspammer.net

Filtering the access log looks like this:

grep -v -e '\"GET / HTTP/1.1\" 301 194' -e '\"HEAD / HTTP/1.1\"' access_log \
    | grep -v -f "~/.config/spammers.list" \
    | grep -v -f "~/.config/bots.list" \
    | grep -v -f "~/.config/global-spammers.list" \
    | goaccess -a

Which results in a report like this (over 50% of the hits before were from bots or spammers):

A yearly report with 90% less spam

No system will be 100% perfect, but so far this has cut out a large portion of the noise from my logs.


Groundhog Day Resolutions - March 2021

February is the shortest month of the year, so naturally I tried to cram in as much as possible. It actually went pretty well.

February's primary goals

1. Finish version 0.3 of Craft Roulette

Ooof, straight into a failure. I didn't even touch this during February.

2. Finish version 0.7 of Writing PHP with Emacs

I published a new version that contains all of the core content. There are still places I'd like to improve, but this was a big step.

3. Complete one session of deliberate practice

My original plan was to experiment with a fullscreen version of Splodey Boats, but I was feeling all 'sploded out so I went for something completely different: setting up my Atari ST development environment.

I'm still writing up the notes for this, but having a plan before I started helped keep me focused and made things much easier.

February's secondary goals

1. Run 90 miles

I had to skip two runs due to being iced in, but I still managed to hit this target. Just.

2. Create detail pages for all my major goals

All of my 2021 major goals now have detail pages.

3. Write a post-mortem for Splodey Boats 2000

Read the Splodey Boats 2000 Post Mortem. It's not very exciting.

Primary goals for March

1. Finish version 1.0 of Writing PHP with Emacs

There are 6 "recipe" chapters to write and then version 1.0 is complete. I still have more ideas for version 1.1 - and beyond - but this version will contain everything I originally had in mind when I started.

2. Complete another session of deliberate practice

I'm on a roll with the Atari development stuff, so I'm going to continue on that path for now.

3. Finish version 0.3 of Craft Roulette

Let's try this again.

4. Contribute to a free software project

This is one of my goals for 2021. I've already contributed a couple of bug fixes this year and I'd like to do the same in March.

Secondary goals for March

1. Run 120 miles

Everything aches, but the training must continue.

2. Read a book

"Read 6 books" is one of my goals for 2021, but I need to actually read books if I want to complete it.

3. Add detail pages to my secondary goals

Not all of them require much explanation, but I'd like to clarify some of the larger ones.

February felt like a really unproductive month, but now that I've looked over everything I'm a little more positive.

My first session of deliberate practice was short but productive. I ended up taking a lot more notes than I expected, so that's something I need to be aware of for future sessions. Having a list of questions I wanted to answer helped keep my focus.

I've also increased my writing output to 3 days a week. My goal for 100 posts meant I would need to publish on different days each week which doesn't really fit my style. I feel much better about a Monday-Wednesday-Friday schedule.

I still have a lot that I want to get done, but I don't think things will really kick in until after my marathon in May. The longer runs are sapping my weekend energy which makes it harder to really sit down and work on things.