Categories: geek

RSS - Atom - Subscribe via email

Using Org Mode, Emacs Lisp, and TRAMP to parse meetup calendar entries and generate a crontab

| org, emacs

Times and time zones trip me up. Even with calendar notifications, I still fumble scheduled events. Automation helps me avoid embarrassing hiccups.

We run BigBlueButton as a self-hosted web conferencing server for EmacsConf. It needs at least 8 GB of RAM when active. When it's dormant, it fits on a 1 GB RAM virtual private server. It's easy enough to scale the server up and down as needed. Using the server for Emacs meetups in between EmacsConfs gives people a way to get together, and it also means I can regularly test the infrastructure. That makes scaling it up for EmacsConf less nerve-wracking.

I have some code that processes various Emacs meetup iCalendar files (often with repeating entries) and combines them into one iCal file that people can subscribe to calendar, as well as Org files in different timezones that they can include in their org-agenda-files. The code I use to parse the iCal seems to handle time zones and daylight savings time just fine. I set it up so that the Org files have simple non-repeating entries, which makes them easy to parse. I can use the Org file to determine the scheduled jobs to run with cron on a home server (named xu4) that's up all the time.

This code parses the Org file for schedule information, then generates pairs of crontab entries. The first entry scales the BigBlueButton server up 1 hour before the event using my bbb-testing script, and the second entry scales the server down 6 hours after the event using my bbb-dormant script (more info). That gives organizers time to test it before the event starts, and it gives people plenty of time to chat. A shared CPU 8 GB RAM Linode costs USD 0.072 per hour, so that's USD 0.50 per meetup hosted.

Using #+begin_src emacs-lisp :file "/ssh:xu4:~/bbb.crontab" :results file as the header for my code block and using an SSH agent for authentication lets me use TRAMP to write the file directly to the server. (See Results of Evaluation (The Org Manual))

(let* ((file "/home/sacha/sync/emacs-calendar/emacs-calendar-toronto.org")
       (time-format "%M %H %d %m")
       (bbb-meetups "OrgMeetup\\|Emacs Berlin\\|Emacs APAC")
       (scale-up "/home/sacha/bin/bbb-testing")
       (scale-down "/home/sacha/bin/bbb-dormant"))
  (mapconcat
   (lambda (o)
     (let ((start-time (format-time-string time-format (- (car o) 3600 )))
           (end-time (format-time-string time-format (+ (car o) (* 6 3600)))))
       (format "# %s\n%s * %s\n%s * %s\n"
               (cdr o)
               start-time
               scale-up
               end-time
               scale-down)))
   (delq nil
         (with-temp-buffer
           (insert-file-contents file)
           (org-mode)
           (goto-char (point-min))
           (org-map-entries
            (lambda ()
              (when (and
                     (string-match bbb-meetups (org-entry-get (point) "ITEM"))
                     (re-search-forward org-tr-regexp (save-excursion (org-end-of-subtree)) t))
                (let ((time (match-string 0)))
                  (cons (org-time-string-to-seconds time)
                        (format "%s - %s" (org-entry-get (point) "ITEM") time)))))
            "LEVEL=1")))
   "\n"))

The code makes entries that look like this:

# OrgMeetup (virtual) - <2025-06-11 Wed 12:00>--<2025-06-11 Wed 14:00>
00 11 11 06 * /home/sacha/bin/bbb-testing
00 18 11 06 * /home/sacha/bin/bbb-dormant

# Emacs Berlin (hybrid, in English) - <2025-06-25 Wed 12:30>--<2025-06-25 Wed 14:30>
30 11 25 06 * /home/sacha/bin/bbb-testing
30 18 25 06 * /home/sacha/bin/bbb-dormant

# Emacs APAC: Emacs APAC meetup (virtual) - <2025-06-28 Sat 04:30>--<2025-06-28 Sat 06:00>
30 03 28 06 * /home/sacha/bin/bbb-testing
30 10 28 06 * /home/sacha/bin/bbb-dormant

This works because meetups don't currently overlap. If there were, I'll need to tweak the code so that the server isn't downscaled in the middle of a meetup. It'll be a good problem to have.

I need to load the crontab entries by using crontab bbb.crontab. Again, I can tell Org Mode to run this on the xu4 home server. This time I use the :dir argument to specify the default directory, like this:

#+begin_src sh :dir "/ssh:xu4:~" :results silent
crontab bbb.crontab
#+end_src

Then cron can take care of things automatically, and I'll just get the e-mail notifications from Linode telling me that the server has been resized. This has already come in handy, like when I thought of Emacs APAC as being on Saturday, but it was actually on Friday my time.

I have another Emacs Lisp block that I use to retrieve all the info and update the list of meetups. I can add (goto-char (org-find-property "CUSTOM_ID" "crontab")) to find this section and use org-babel-execute-subtree to execute all the code blocks. That makes it an automatic part of my process for updating the Emacs Calendar and Emacs News. Here's the code that does the calendar part (Org source):

(defun my-prepare-calendar-for-export ()
  (interactive)
  (with-current-buffer (find-file-noselect "~/sync/emacs-calendar/README.org")
    (save-restriction
      (widen)
      (goto-char (point-min))
      (re-search-forward "#\\+NAME: event-summary")
      (org-ctrl-c-ctrl-c)
      (org-export-to-file 'html "README.html")
      ;; (unless my-laptop-p (my-schedule-announcements-for-upcoming-emacs-meetups))
      ;; update the crontab
      (goto-char (org-find-property "CUSTOM_ID" "crontab"))
      (org-babel-execute-subtree)
      (when my-laptop-p
        (org-babel-goto-named-result "event-summary")
        (re-search-forward "^- ")
        (goto-char (match-beginning 0))
        (let ((events (org-babel-read-result)))
          (oddmuse-edit "EmacsWiki" "Usergroups")
          (goto-char (point-min))
          (delete-region (progn (re-search-forward "== Upcoming events ==\n\n") (match-end 0))
                         (progn (re-search-forward "^$") (match-beginning 0)))
          (save-excursion (insert (mapconcat (lambda (s) (concat "* " s "\n")) events ""))))))))
(my-prepare-calendar-for-export)

I used a similar technique to generate the EmacsConf crontabs for automatically switching to the next talk. For that one, I used Emacs Lisp to write the files directly instead of using the :file header argument for Org Mode source blocks. That made it easier to loop over multiple files.

Hmm. Come to think of it, the technique of "go to a specific subtree and then execute it" is pretty powerful. In the past, I've found it handy to execute source blocks by name. Executing a subtree by custom ID is even more useful because I can easily mix source blocks in different languages or include other information. I think that's worth adding a my-org-execute-subtree-by-custom-id function to my Emacs configuration. Combined with an elisp: link, I can make links that execute functional blocks that might even be in different files. That could be a good starting point for a dashboard.

I love the way Emacs can easily work with files and scripts in different languages on different computers, and how it can help me with times and time zones too. This code should help me avoid brain hiccups and calendar mixups so that people can just enjoy getting together. Now I don't have to worry about whether I remembered to set up cron entries and if I did the math right for the times. We'll see how it holds up!

View org source for this post

2025-06-16 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

2025-06-09 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

2025-06-02 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

Working on the plumbing in a small web community

| connecting, emacs, blogging

The IndieWeb Carnival prompt for May is small web communities. I've been exploring some thoughts on how a little effort goes a long way to connecting a community. Sometimes I think of it as working on the plumbing so that ideas can flow more smoothly. It feels a little different from the direct contribution of knowledge or ideas. I also want to connect with other people who do this kind of thing.

Emacs is a text editor that has been around since the 1970s. It's highly programmable, so people have come up with all sorts of ways to modify it to do what they want. It's not just for programmers. My favourite examples include novelists and bakers and musicians who use Emacs in unexpected ways. Because Emacs is so flexible, community is important. The source code and documentation don't show all the possible workflows. As people figure things out by themselves and together, more possibilities open up.

I love tweaking Emacs to help me with different things I want to do, and I love learning about how other people use it too. I've been sharing my notes on Emacs on this blog since 2001 or so. In 2015, as I was getting ready to become a parent, I knew I was going to have much less time and focused attention, which meant less time playing with Emacs. Fortunately, around that time, John Wiegley (who was one of the maintainers of Emacs at the time) suggested that it would be helpful if I could keep an eye on community updates and summarize them. This worked well with the fragmentation of my time, since I could still speed-read updates and roughly categorize them.

Text from sketch

Community plumbing

You don't have to fill the pipes all by yourself. Just help things flow.

I want to share some of the things we're doing in the Emacs community so that I can convince you that building plumbing for your community can be fun, easy, and awesome. This is great because enthusiasm spreads.

virtuous cycle

  • Other places: YouTube, Reddit, HN, lobste.rs, Mastodon, PeerTube, mailing lists….
  • Blog aggregator
    • Planet Emacs Life (uses Planet Venus) - update: [2025-05-31 Sat] I wrote my own RSS feed aggregator instead.
  • Newsletter: Emacs News, 1-2 hours a week
    • summarize & group
    • announce calendar events
  • User groups
    • [often use Emacs News to get conversations going]
  • iCal & Org files: Emacs Calendar
  • Conference
    • EmacsConf: < USD 50 hosting costs + donated server + volunteer time

Tips:

  • Make it fun for yourself.
  • Build processes and tools.
  • Let people help

2024-01-31-05

Some more notes on the regular flows built up by this kind of community plumbing:

Daily: Lots of people post on reddit.com/r/emacs and on Mastodon with the #emacs hashtag. I also aggregate Emacs-related blog posts at planet.emacslife.com, taking over from planet.emacsen.org when Tess had DNS issues. There are a number of active channels on YouTube and occasionally some on PeerTube instances as well. I don't need to do much work to keep this flowing, just occasionally adding feeds to the aggregator for planet.emacslife.com.

Weekly: I collect posts from different sources, remove duplicates, combine links talking about the same thing, categorize the links, put them roughly in order, and post Emacs News to a website, an RSS feed, and a mailing list. This takes me maybe 1.5 hours each week. It's one of the highlights of my week. I get to learn about all sorts of cool things.

Weekly seems like a good rhythm for me considering how active the Emacs community is. Daily would be too much time. Monthly would lead to either too long of a post or too much lost in curation, and the conversations would be delayed.

Sometimes I feel a twinge of envy when I check out other people's newsletter posts with commentary or screenshots or synthesis. (So cool!) But hey, I'm still here posting Emacs News after almost ten years, so that's something. =) A long list of categorized links fits the time I've got and the way my mind works, and other people can put their own spin on things.

Monthly: There are a number of Emacs user groups, both virtual and in-person. Quite a few of them use Emacs News to get the discussion rolling or fill in gaps in conversation, which is wonderful.

Some meetups use meet.jit.si, Zoom, or Google Meet, but some are more comfortable on a self-hosted service using free software. I help by running a BigBlueButton web conferencing server that I can now automatically scale up and down on a schedule, so the base cost is about 60 USD/year. Scaling it up for each meetup costs about USD 0.43 for a 6-hour span. It's pretty automated now, which is good because I tend to forget things that are scheduled for specific dates. My schedule still hasn't settled down enough for me to host meetups, but I like to drop by once in a while.

Yearly: EmacsConf is the one big project I like to work on. It's completely online. It's more of a friendly get-together than a formal conference. I have fun trying to fit as many proposed talks as possible into the schedule. We nudge speakers to send us recorded presentations of 5-20 minutes (sometimes longer), although they can share live if they want to. A number of volunteers help us caption the videos. Each presentation is followed by Q&A over web conference, text chat, and/or collaborative document. Other volunteers handle checking in speakers and hosting the Q&A sessions.

It's a lot of fun for surprisingly little money. For the two-day conference itself, the website hosting cost for EmacsConf 2024 was about USD 56 and our setup was able to handle 400 viewers online (107 max simultaneous users in various web conferences).

EmacsConf takes more time. For me, it's about 1.5 hours a day for 4 months, but I think mostly that's because I have so much fun figuring out how to automate things and because I help with the captions. Lots of other people put time into preparing presentations, hosting Q&A, participating, etc. It's worth it, though.

I like doing this because it's a great excuse to nudge people to get cool stuff out of their head and into something they can share with other people, and it helps people connect with other people who are interested in the same things. Some Q&A sessions have run for hours and turned into ongoing collaborations. I like turning videos into captions and searchable text because I still don't have the time/patience to actually watch videos, so it's nice to be able to search. And it's wonderful gathering lots of people into the same virtual room and seeing the kind of enthusiasm and energy they share.

So yeah, community plumbing turns out to be pretty enjoyable. If this resonates with you, maybe you might want to see if your small web community could use a blog aggregator or a newsletter. Doesn't have to be anything fancy. You could start with a list of interesting links you've come across. I'm curious about what other people do in their communities to get ideas flowing!

Related: the community plumbing section of my blog post / livestream braindump.

View org source for this post

2025-05-26 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post

2025-05-19 Emacs news

| emacs, emacs-news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links and thanks to tusharhero for some links as well. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View org source for this post