Automating RSS Feed Updates in Specify 7 with Cron

:book: This guide describes how to schedule the update_feed management command inside your Specify 7 Docker container so that the RSS feed is updated automatically.

[!warning]
This must be initially configured in the Specify 7 server settings by an IT administrator.


1. Note Your Container & Command

From docker ps, identify your Specify container name (e.g. specifycloud-workshop-1) and the update command:

docker exec specifycloud-workshop-1 \
  ve/bin/python manage.py update_feed --force

Use --force to update all feeds unconditionally; omit it to update only feeds older than their configured days.


2. Create a Simple Shell Script

Wrap the command in a script for maintainability & for automation. Save the following as /usr/local/bin/update_specify_feed.sh:

#!/usr/bin/env bash

docker exec specifycloud-workshop-1 \
  ve/bin/python manage.py update_feed --force

Make it executable:

sudo chmod +x /usr/local/bin/update_specify_feed.sh

If you prefer, you can skip this script and use the docker exec … line directly in your cron.


3. Schedule via Cron

Edit your crontab:

crontab -e

Add a line such as the following to run daily at 2 AM:

0 2 * * * /usr/local/bin/update_specify_feed.sh

Or, to run it once a week (e.g. Sunday at 3:30 AM):

30 3 * * 0 docker exec specifycloud-workshop-1 \
  ve/bin/python manage.py update_feed

Save and exit. Cron will execute the update RSS command on your chosen schedule.


4. Confirm Update

After the first scheduled run, verify by fetching the RSS feed:

curl -s https://SITE/export/rss/ | grep pubDate

You should see a recent <pubDate> timestamp.

That’s it! Your Specify 7 RSS feed will now update automatically via cron. :tada:


Configure Refresh Frequency

The days threshold that controls how often each feed item is regenerated is not set in cron or the wrapper script, but in your ExportFeed app resource itself.

When you edit the ExportFeed resource (located at the Global Resources level under App ResourcesGlobalExportFeed), each <item> element has a days="N" attribute. If this is not yet configured, please follow this guide.

That value N tells Specify:

  • On a normal (non---force) run of
    manage.py update_feed
    only items whose existing archive is more than N days old will be updated.

  • Items newer than N days are skipped to save time.

Example snippet from an ExportFeed resource:

<channel>
  <!-- … -->
  <item
    collectionId="4"
    userId="2"
    definition="DwCA_voucher"
    metadata="DwCA_voucher_metadata"
    days="7"
    filename="kui-dwca.zip"
    publish="true">
    <title>KU Fish</title>
    <id>8f79c802-…</id>
  </item>
  <!-- … -->
</channel>

Here, days="7" means “only regenerate this item if its existing archive is older than 7 days.”

If you run:

ve/bin/manage.py update_feed

without --force, Specify will check each item’s days setting. To ignore those thresholds and rebuild everything, you use:

ve/bin/manage.py update_feed --force

Your cron job simply schedules the command; the per-item timing logic lives entirely in the days attributes of your ExportFeed app resource.

1 Like