Comics Aggregator user guide

The comics aggregator (https://comics.kamens.us/) is a little tool I wrote for my own use to pull the comic strips and columns I read from the various sites that host them into a single web page so I can read them all in one place. Word about it has gradually spread since I wrote it, so I’m not the only one using it anymore. This page explains how to use it.

Basic usage is very simple:

  1. Go to https://comics.kamens.us/.
  2. Check the things you want to read every day.
  3. Click the “submit” button (the one on the page, not your browser’s!).
  4. Bookmark the resulting page and visit it every day to see that day’s feed.
  5. If you enjoy using the aggregator and are so inclined, kick in a few bucks toward my hosting costs.

That’s it! See, I told you it was simple.

Now let’s get into more of the details…

Saving your settings in an account on the server

Although you can certainly use the aggregator via a bookmarked link as described above, you can also create an account on the aggregator by clicking the “Create account” link at the top right. Once you’ve created your account and logged into it, proceed as above through step 3, but then instead of bookmarking the resulting link, click the “Save selections to account” button at the bottom, and your currently selected comics and any other settings (e.g., width and height) will be saved into your account. then the next time you visit the aggregator your desired comics will be displayed automatically without you needing to reselect them or visit a long, bookmarked URL.

You don’t need to use your email address as your username, but if you do then you’ll be able to reset your password if you forget it; otherwise, you’ll just have to create a new account. The aggregator only saves a hash of your username, not your actual username, so you don’t have to worry about me using it to spam you if it’s an email address, or about someone breaking into my server and stealing it; the aggregator never saves it anywhere but in a cookie stored locally in your browser.

User accounts which are not used for 30 days are deleted automatically. This is necessary for both private reasons (I don’t want to save even the minimal information I’m saving about users for longer than necessary) and because I can’t afford to have the aggregator take up ever-increasing storage space. However, if your account gets deleted the data are backed up for a year before they’re permanently purged, so you can email me if you’d like me to restore your account.

Aggregator links with and without timestamps

At the top and bottom of the aggregator page, you will see links to the currently displayed date in the middle, with the day before on the left and the day after on the right. At the far right you’ll see an additional link labeled “>>”.

The dated links do what you expect, i.e., they are essentially “permalinks” to the selected comics pegged to those specific dates. The “>>” link is unpegged, meaning it’s not associated with any particular date. If you click on that link, or if you bookmark that link and then visit it later, it’ll take you to the comics for whatever the current date is when you visit it.

The thing which pegs a link to a specific date is the “stamp” query parameter in its URL. If you bookmark a URL with that query parameter in it, the bookmark will be stuck on that day forever, i.e., you won’t see today’s items when you visit that link. So if that’s not your intention, then be careful not to bookmark a time-stamped URL! Or, if you accidentally do, edit the bookmark to remove “&stamp=##########”.

Yes, by the way, this means that you can use the aggregator to view past days’ comics. Alas, it does not generally mean that you can view comics in the future.

Note, incidentally, that the “stamp” query parameter accepts dates, not just numbers, so if you want to go directly to your feed for a specific day, you can add “&stamp=MM/DD/YYYY” to the URL to do that.

“1-day delay” item feeds

Some items appear twice in the list, once with and once without a “(1-day delay)” suffix. These items are sometimes published late in the day, such that if you view your comics early, they might not yet be available. If you run into this, you can switch to the delayed version of an item, which will show you yesterday’s instead of today’s, so it should always be there.

“Comics Kingdom” comics

If you try to view a comic that is syndicated by Comics Kingdom, You will see this message: “Click here for more information about viewing this strip through this aggregator.” Basically, Comics Kingdom doesn’t want you viewing their comics without paying for them. That’s perfectly reasonable, and it is not the intention of my aggregator to circumvent other people’s copyrights. Therefore, here’s what you need to do if you want to view these strips through my tool:

  1. Sign up for an account at Comics Kingdom.
  2. Email me and tell me you want to read your Comics Kingdom strips through the aggregator.
  3. I will provide you with a special email address on my server.
  4. Configure your Comics Kingdom account to use that special email address, or configure your email account to forward copies of your daily favorites emails to that address (for example, it’s easy to create a filter to do this in Gmail).
  5. Early every morning, when the Comics Kingdom daily email arrives at my server, my server parses it and authorizes you to view the strips it contains.
  6. You need to create an account on the aggregator whose username matches the email address you have registered with Comics Kingdom. You will be able to access Comics Kingdom strips in the aggregator when logged into that account.

To prevent my aggregator from being used to bypass Comics Kingdom’s security, each Comics Kingdom strip can only be viewed a few times through my aggregator by each authorized user, though even if you exceed that limit, you can still view the strip by logging into your Comics Kingdom account. Unless you’re in the habit of reading your comics lots of times, this shouldn’t be a problem.

Note that if you want to share Comics Kingdom strips through the aggregator, you should use the “get sharing link” to generate a sharing link rather than sharing the links in the header or footer; those links won’t work, since they don’t have information embedded in them to associate your access with the link.

To edit your subscriptions

To edit your subscriptions, click the “Show comics list” button near the bottom to display the hidden list of comics and check or uncheck comics as desired. Then use the “Save selections” button to save your changes to your account, or click the “submit” button and bookmark the new “>>” in the upper right corner of the page.

Viewing multiple days at once

If you’ve been away from your feed for a while and you want to catch up all on one page, you can use the trick described above for going directly to the first day you missed, then enter the number of days you want to view into the “# of days” box at the bottom of the page and click “submit” to view all the days at once. Alternatively, of course, you can use the date links at the top and bottom of the page to catch up on your feed one day at a time.

Making the page more or less compact

You can set the maximum width and/or height of all displayed comics by entering it in the “width” or “height” box and clicking “submit”. Bookmark the result if you want it to be persistent. This setting is included when saving settings to your account.

If you just want to see the comics, and not the headers, you can check “omit strip headers” and click “submit”. This setting is also included when saving to your account.

Sharing with other people

You can share the dated links at the top and bottom of the page with other people (though as noted above, this won’t work 100% if you’re a Comics Kingdom reader), but you can also use the “get sharing link” button at the bottom which will generate and display (next to the button) a short Bitly link.

The sharing link that is generated and displayed when you click this button exactly reproduces the comics visible on the screen on which the generated link is displayed. In other words, if you are viewing comics, and you select or deselect some of them in the list, and then you click the button, the resulting sharing link reflects your changed selections, not the comics that were displayed immediately before you clicked the button.

API

If you would like to take advantage of the logic built into my aggregator for locating comics and columns, but you’d like to do something different then viewing them on the aggregator page, there’s a primitive API you can use to query the aggregator and get back results in text format rather than HTML:

  • If you add “&list=true” to any feed URL, then you will get back a list of comics, one per line, that would be included in that feed page.
  • If you add “&urls=true” to any feed URL, then you will get back a list of URLs, one per line, for all the items that would be included in that feed page. Note that you could get back more than one URL if you asked for multiple days, or if there are multiple URLs for an item in a single day (e.g., some columnists publish both a column and a live chat on the same day).
  • You can add ‘&numdays=#” to fetch multiple days as described above.
  • You can add “&stamp=MM/DD/YYYY” as described above to fetch a particular day.
  • If you want to construct a URL to explicitly specify one or more items to fetch, the URL format would look like this: “https://comics.kamens.us/cgi-bin/comics?comic name=include”. You can specify additional comics by appending “&comic name=include” for each one.

Putting this all together, suppose you wanted to write a script which fetches all the items in your feed every day and does something separately with all of them. Your script would first fetch your feed URL with “&list=true” appended to it. Then, it would iterate through the returned content lines, i.e., the names of all available comics for that day, and construct a “?comic name=include” URL for each of them, and fetch it. Each such fetch would return the URLs for the specified comic, which you could then do whatever you want with.

If you have a user account you can an API key on your profile page and add it to your API request URLs with “api_key=key“. There are two reasons why you might want to do this:

  1. It uses your saved settings, i.e., the list of comics you want, so you don’t have to specify them in the URL.
  2. If you’re a Comics Kingdom reader, it gives you access to Comics Kingdom strips through the API.

API JSON output

If you add json=1 as a query parameter in API calls, the response will be formatted in JSON. For the list call that just means you’ll get back an array of comic names one per line as plain text, but for the urls call you’ll get back additional details. Each item in the array will be a dictionary instead of a string, with the following keys and values:

  • comic is the name of the comic or column and will always be present
  • url is its URL and will always be present
  • source is the source URL for a comic image, i.e., the “canonical” web page where the comic is located on its own web site, and it may not always be present
  • title is the title for an image at its source URL, i.e., the text that shows on the source page when you hover your mouse over the image (useful for xkcd.com!)

How to get help

Please email me if you have any comments about the aggregator, encounter any problems, or would like me to add a new comic or column to it. I’ll do the best I can to help.

Don’t forget to kick in a few bucks if you find this service useful.

Making the ads go away

I will disable the Google AdSense ads in the aggregator for anyone who supports me on Patreon and asks me to do so. To get the ads turned off, you need to:

  • create an aggregator account as described above, and log into it;
  • support me on Patreon; and
  • send me email telling me who you are on Patreon and what your aggregator username is, and asking me to turn off the ads for you.

Privacy policy

I’m just a random guy who built this thing because I wanted it for myself and then shared it with others for free because I thought people might find it useful. I’m not making any money from this other than donations which are few and far between, and I don’t have attorneys at my disposal to help me craft a long, obscurely worded privacy policy to cover my a**.

Having said that, I care a lot both about my own privacy and about not violating other people’s privacy, so I am sharing here exactly what data the aggregator collects about it users and what is done with it. Given that I do information security and compliance work for a living, I know what the requirements are for something like this, and I’m confident that I’m checking all the important boxes even if this privacy policy isn’t written in the legalese you’ve come to expect.

Having said all that, here is the very limited data which the aggregator collects:

  • Logs of all browser and API requests sent to the server. These include the internet address of the machine making the request and the details of the request, e.g., which comics to display and what settings to apply when displaying them. These logs are saved for about a year and then deleted.
  • As noted above, I display Google AdSense ads on the aggregator, so additional information may be collected about you by Google AdSense. The ads displayed by Google AdSense have links in them which you can click on to find out more information about this.

If all you do with the aggregator is create a bookmarkable link to the comics you want to read and then bookmark and visit it periodically, the one bullet point above is literally all the information I have about you. However, if you create and use an account on the aggregator, more data is collected:

  • I store a one-way hash of your username so that I can find your account when you log in or request a password reset. It’s impossible for me or anyone else to derive your username from the stored hash.
  • I store a secure, one-way hash of your password so that I can verify that you’ve provided the correct password when logging in. It’s nearly impossible for me or anyone else to derive your password from the stored hash; it would require a huge amount of computational effort which it’s hard to imagine would ever be justified.
  • I store the date and time when your account was created and the date and time when it was last used, so that I can prune accounts that are no longer being used, and so that I can prevent people from flooding the server by creating too many accounts in too short of a time.
  • I store the timestamps, username hashes, and IP addresses of failed login events, so that I can detect suspicious behavior and temporarily block logins as needed for security purposes.
  • I store the timestamp, username hash, and token for each password request, so that these requests can be handled securely without allowing an attacker to use the password reset functionality to flood someone else’s inbox with emails.
  • If you are a Comics Kingdom reader as described above:
    • While your email address is not saved anywhere within the aggregator itself, I do receive emails from Comics Kingdom on your behalf with your email address in them, and those emails are saved on my mail server for about a week.
    • The aggregator knows the list of “favorites” you’ve selected on Comics Kingdom, because those favorites are included in the daily emails.
    • For each of the Comics Kingdom strips you’ve selected for viewing through the aggregator, an access count in the database is incremented every time you or someone with whom you’ve shared an aggregator link views a strip.

The only thing any of this data is used for is providing the comics aggregator service to its users. I don’t do anything else with the data or share it with anyone else for any reason. I suppose this is the point at which I say that I may be compelled to share data with government authorities through a subpoena or some other binding legal process, but while it’s true that I will indeed abide by any government orders to share such data, it seems highly unlikely that this would ever be an issue.

The data enumerated above are not encrypted on the server, though as noted above, some of them are securely hashed, and any data sent between your browser and the server are securely encrypted in transit.

These data are all stored on a single, highly secure server in the United States. Unencrypted backups of some of this data are stored on a highly secure computer in my basement, also in the United States. Backups are also stored, using an extremely secure encryption algorithm, on Backblaze servers also located in the United States.

Regarding the “right to be forgotten” as required by the GDPR and some other regulatory regimens. I will happily remove upon request all the data that is practicable for me to remove pertaining to you as a user of the aggregator. Having said that, logs and backups cannot be selectively removed, but if you stop using the aggregator then those data about you will eventually be removed automatically as the relevant logs and backups age out and are purged.

Regarding the right for you to see the specific data I have stored about you as required by the GDPR and some other regulatory regimens, I will happily respond promptly to such requests by email. Please note, however, that since I intentionally collect as little data as possible about users to protect their privacy, it is impossible for me to accurately associate all data with specific individuals, so I can only provide data to one user to the extent that it is possible to do so without violating the privacy of others. For example, I do not track the IP addresses of individual users, and I do not include user IDs in request logs, so I cannot provide you with request logs of your previous communication with the server.

You can email me with any questions or concerns you have about this policy. I’m not providing a mailing address here because as noted above I’m just a random guy, and this aggregator isn’t a business, so that mailing address would be my home, whose address I prefer not to publish for privacy reasons.

Print Friendly, PDF & Email
Share