User Fingers

This project was made for the 2025 ^C webjam. The idea is simple, make a webpage that will list all finger files of all users of ^C. To make it a bit more challenging (and since I enjoy regex web scraping) I decided to also get finger files from another tilde server. I knew that tilde.green has a public finger server, so tilde.green it is.

The webpage

The script

Explanation

The point of this script is to generate parts of 'my own markup language', internally 'moml', as documented here. This is then later converted to actual pages. Unlike most generation scripts, it is not run with the rest of website generation, but few hours before, as getting all the finger files over the net takes time.

Each source server has three parts: file name, user-getting function and function that turns users into markup chunks. Users without finger entries return empty string.

Since ruby does not need parenthesis to call a function, you can't just pass it as a value. To do so, you use the method function.

def gen_stuff(collections)
  collections.each { |col|
    contents = col["gather_users"].call.map{|i| col["gather_finger"].call i}.join
    File.write FINGER_DIR + col["file_name"], contents
  }
end


gen_stuff [
  {
    "file_name"     => "ctrl-c",
    "gather_users"  => method(:gather_users_local),
    "gather_finger" => method(:gather_finger_local),
  },
  {
    "file_name"     => "tilde.green",
    "gather_users"  => method(:gather_users_green),
    "gather_finger" => method(:gather_finger_green),
  },
]

For local users, user list can easily be gathered from '/home/'. I then look if they have '.project' or '.plan' files. If at least one is present, I generate the listing from it. I check if file exists with 'File.readable?'.

Since the files might have leading or trailing newlines, I run the file contents through 'strip'. I cannot use the regular '.strip', however, as that would also remove any indentation. I solve it by the following function:

def file_strip(str)
  # .slice! removes match from the start
  s = str.rstrip
  s.slice! /\n+/
  s
end

I use '.slice!', since '.slice' returns the match, not the string with removed leading chars.

For tilde.green, I scan for users like so:

def gather_users_green
  # scrape users from the website
  # this are only users with a website, but I would guess most users using
  # finger also have at least something in their website
  site = `curl https://tilde.green/`
  site.scan(/\/~[\w\d_-]+\//).map {|i| i[2..-2]}
end

This first matches all the links to user sites, which are always in the '/~<user>/' format. The '.map' then removes the '/~' and '/'.

As for getting the finger files, I just call the 'finger' command and check if the result contains

Project: No Project.
Plan: No Plan.

If it doesn't, it's a valid entry, so I strip the heading (tilde.green starts all responses with 'Hello 0.0.0.0,') and that's it.

...

Turns out only three users of tilde.green have anything in their finger files, so that's a thing...

But it works, and that is what really matters. Now I can forget about it and leave it never used ever again!