--- /dev/null
+# crontab format:
+# m h dom mon dow command
+#
+# Crontab file for 'opensrf'.
+
+# ENVIRONMENT:
+OPENILS = /openils
+SRF_CORE = /openils/conf/opensrf_core.xml
+EG_BIN = /openils/bin
+EG_CONF = /openils/conf
+AT_FILTERS = /openils/conf/a_t_filters/
+SCRIPT_DIR = /home/opensrf/Evergreen/KCLS/util
+PGUSER = evergreen
+PGDATABASE = evergreen
+PGHOST = localhost # change for cluster install
+
+# hold targeter
+*/1 * * * * . ~/.bashrc && $EG_BIN/hold_targeter.pl $SRF_CORE 2> /dev/null
+
+# Run the hold thawer
+5 0 * * * . ~/.bashrc && $EG_BIN/thaw_expired_frozen_holds.srfsh
+
+# Generate fines
+30 3 * * * . ~/.bashrc && $EG_BIN/fine_generator.pl $SRF_CORE
+
+# Custom reshelving completer to avoid statement timeout
+0 1 * * * $SCRIPT_DIR/reshelving/reshelving.sh
+
+# Extend Patron Expiration Date based on activity
+15 0 * * * $SCRIPT_DIR/patron_activity/patron_activity.sh
+
+# create the list of blocked patrons for offline use
+# Note: The resulting list.txt file needs to be copied to all Apache servers
+30 6 * * * . ~/.bashrc && $EG_BIN/offline-blocked-list.pl $SRF_CORE > $OPENILS/var/web/standalone/list.txt
+
+# overdues and predues
+5 2 * * * . ~/.bashrc && cd $SCRIPT_DIR/overdue/ && ./run_overdues.sh
+# holes
+5 0 * * * . ~/.bashrc && cd $SCRIPT_DIR/overdue/ && ./run_holds.sh
+
+# General A/T event firing. Runs every 2 minutes (signed off: Bill)
+*/2 * * * * . ~/.bashrc && $EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending
+
+# batch job to delete empty volumes daily ESI/Galen Charlton 2011-04-21
+20 0 * * * . ~/.bashrc && cd $SCRIPT_DIR/del_empty_vol && ./run_empty_vol_delete.sh
+# batch job to update copy locations to match circ library ESI/Galen Charlton 2011-06-03
+35 0 * * * . ~/.bashrc && cd $SCRIPT_DIR/copy_loc_fix && ./run_copy_location_fix.sh
+# batch job to remove inacitve patron cards per HS#18605 ESI/Galen Charlton 2012-03-27
+45 0 * * * . ~/.bashrc && cd $SCRIPT_DIR/inactive_cards && ./remove_inactive_patron_cards.sh
+
+# circulation purging
+# TODO
+#0 2 * * * cd $SCRIPT_DIR/purge_circs && ./purge_circulations.sh
+
+# EDI
+# TODO: un-comment for EDI
+#45 * * * * . ~/.bashrc && $EG_BIN/edi_pusher.pl -d
+#0 0-23/2 * * * FTP_PASSIVE=1 . ~/.bashrc && $EG_BIN/edi_fetcher.pl -v -d
+
+# Avoid sip login lockout from too many auth failures for 'kcls-sip' login
+# TODO: This is probably no longer needed, but will keep for reference
+#0 14 * * * . ~/.bashrc && memrm --servers memcache01:11211 oils_auth_kcls-sip_count
+
+# TODO: move these into overdue scripts
+# Asterisk telephony for batched hold notices - LFW
+# TODO: un-comment when using telephony/asterisk
+#20 5 * * * . ~/.bashrc && $EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --granularity Telephony-Hold --granularity-only
+
+# Asterisk telephony for seven day overdues - LFW
+# TODO: un-comment when using telephony/asterisk
+#50 5 * * * . ~/.bashrc && $EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Telephony-OD-7 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.7_day_od.json
+
+# In support of Asterisk telephony notices, update the pbx system daily with
+# holiday data from Redmond. Karen Daniel and Chris McQuown say Redmond (1533)
+# should be the reference org unit for holidays, since they don't have holiday
+# data stored for KCLS as a whole. This should run shortly before the call
+# window opens each day. LFW
+# TODO: un-comment when using telephony/asterisk
+#45 8 * * * . ~/.bashrc && /openils/bin/set_pbx_holidays.pl -o 1533
+
+# In support of Asterisk telephony notices, "rollover" failed telephone
+# notices into print notices. Yes, this should run late in the day but before
+# midnight. LFW
+# TODO: un-comment when using telephony/asterisk
+#5 23 * * * . ~/.bashrc && /openils/bin/rollover_phone_to_print.pl
+
+# Compress/Remove log files
+# TODO: un-comment to clean up log files (dev servers only)
+# TODO: use syslog / logrotate instead
+#10 2 * * * find /var/log/evergreen -type f -ctime +60 -delete
+#30 2 * * * find /var/log/evergreen -type f -ctime +2 -exec gzip {} \;
--- /dev/null
+Local scripts which are not part of Evergreen proper.
+
+To apply the crontab file for opensrf:
+
+% sudo su - opensrf
+% crontab CRONTAB
--- /dev/null
+\echo Run job to fix copy locations based on copy circ lib
+
+BEGIN;
+
+UPDATE asset.copy a
+SET location = c.id
+FROM asset.copy_location b, asset.copy_location c
+WHERE a.id IN (
+ SELECT ac.id
+ FROM asset.copy ac
+ JOIN asset.copy_location acl ON (acl.id = ac.location)
+ JOIN asset.copy_location acl2 ON (acl.name = acl2.name AND acl2.owning_lib = ac.circ_lib)
+ WHERE NOT ac.deleted
+ AND circ_lib <> acl.owning_lib
+)
+AND a.location = b.id
+AND c.name = b.name
+AND c.owning_lib = a.circ_lib;
+
+COMMIT;
--- /dev/null
+#!/bin/bash
+
+# Script to change item copy locations so that the
+# copy location owning library matches the item's circ library
+cd /home/opensrf/esi_data_services
+psql -U evergreen < fix_copy_locations.sql > log.fix_copy_locations
+cat log.fix_copy_locations | mailx -s "Copy location fix report" bbonner@kcls.org,mcarlson@kcls.org
--- /dev/null
+\echo running empty volume deletion
+BEGIN;
+
+\echo compiling list of volumes to delete
+TRUNCATE TABLE m_kcls.vols_to_delete;
+
+INSERT INTO m_kcls.vols_to_delete
+SELECT acn.id AS volume_id
+FROM asset.call_number acn
+WHERE NOT acn.deleted
+AND label <> '##URI##'
+AND acn.id > -1
+AND NOT EXISTS (SELECT acp.id FROM asset.copy acp WHERE acp.call_number = acn.id
+AND NOT acp.deleted);
+
+\echo deleting volumes (setting acn.deleted to true, so expected result is 0)
+DELETE FROM asset.call_number WHERE id IN
+(select volume_id from m_kcls.vols_to_delete);
+
+\echo number of volumes deleted
+SELECT COUNT(*) FROM m_kcls.vols_to_delete;
+
+COMMIT;
--- /dev/null
+#!/bin/bash
+
+# Script to delete empty volumes, i.e., non-located-URI
+# acns that have no non-deleted copies linked to them
+
+psql -U evergreen < del_all_empty_vols.sql > log.del_all_empty_volumes
+# TODO: un-comment on prod util server only
+#cat log.del_all_empty_volumes \
+# | mailx -s "Empty volume deletion report" \
+# bbonner@kcls.org,mcarlson@kcls.org
--- /dev/null
+#!/bin/bash
+
+# Script to inactive patron cards, per HS#18506
+
+psql -U evergreen < remove_inactive_patron_cards.sql > log.remove_inactive_patron_cards
+# TODO: un-comment on production util server only
+#cat log.remove_inactive_patron_cards \
+# | mailx -s "Inactive patron card deletion report" \
+# bbonner@kcls.org,mcarlson@kcls.org,ebooks@kcls.org
--- /dev/null
+BEGIN;
+SELECT o.barcode as "Old BC", n.barcode as "New BC" FROM actor.card AS o INNER JOIN actor.card AS n ON o.usr = n.usr WHERE NOT o.active AND n.active AND EXISTS (SELECT usr FROM actor.card WHERE usr = o.usr AND active);
+
+\echo Backing up inactive patron cards
+INSERT INTO esi.saved_inactive_patron_cards
+SELECT * FROM actor.card c WHERE NOT active
+AND EXISTS (SELECT usr FROM actor.card WHERE usr = c.usr AND active);
+
+\echo Deleting inactive patron cards
+DELETE FROM actor.card c WHERE NOT active
+AND EXISTS (SELECT usr FROM actor.card WHERE usr = c.usr AND active);
+
+COMMIT;
--- /dev/null
+#!/bin/bash
+OPENILS=/openils
+SRF_CORE=/openils/conf/opensrf_core.client.xml
+EG_BIN=/openils/bin
+EG_CONF=/openils/conf
+AT_FILTERS=/openils/conf/a_t_filters/
+DAYS_BACK=$1
+[ -z "$DAYS_BACK" ] && DAYS_BACK=0
+DATE=$(date -d"-$DAYS_BACK day" +%Y-%m-%d);
+
+$EG_BIN/send-print-notices.pl --event-def 133 --prefix 7-day-overdue-print --date $DATE --force;
+$EG_BIN/send-print-notices.pl --event-def 139 --prefix 14-day-second-overdue-print --date $DATE --force;
+$EG_BIN/send-print-notices.pl --event-def 134 --prefix 21-day-overdue-print --date $DATE --force;
+$EG_BIN/send-print-notices.pl --event-def 131 --prefix holds-available-print --date $DATE --force;
+$EG_BIN/send-print-notices.pl --event-def 132 --prefix collection --date $DATE --force;
--- /dev/null
+#!/bin/bash
+OPENILS=/openils
+SRF_CORE=/openils/conf/opensrf_core.client.xml
+EG_BIN=/openils/bin
+EG_CONF=/openils/conf
+AT_FILTERS=/openils/conf/a_t_filters/
+
+# Daily batched holds,collection print & phone
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --granularity Daily-Active-Print --granularity-only && ($EG_BIN/send-print-notices.pl --event-def 131 --prefix holds-available-print; $EG_BIN/send-print-notices.pl --event-def 132 --prefix collection;)
+
+# Daily batched holds email (signed off: Bill).
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --granularity Daily-Hold --granularity-only
+
+exit;
--- /dev/null
+#!/bin/bash
+OPENILS=/openils
+SRF_CORE=/openils/conf/opensrf_core.client.xml
+EG_BIN=/openils/bin
+EG_CONF=/openils/conf
+AT_FILTERS=/openils/conf/a_t_filters/
+
+# Daily Mark Lost (signed off: Bill)
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-Lost-28 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.28_lost.json;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-Lost-70 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.70_lost.json;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-Lost-180 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.180_lost.json;
+
+# Daily Overdue Print & Phone
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD-7-Print --granularity-only --custom-filters $AT_FILTERS/a_t_filters.7_day_od.json && $EG_BIN/send-print-notices.pl --event-def 133 --prefix 7-day-overdue-print;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD2-14-Print --granularity-only --custom-filters $AT_FILTERS/a_t_filters.14_day_second_od.json && $EG_BIN/send-print-notices.pl --event-def 139 --prefix 14-day-second-overdue-print;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD-21-Print --granularity-only --custom-filters $AT_FILTERS/a_t_filters.21_day_od.json && $EG_BIN/send-print-notices.pl --event-def 134 --prefix 21-day-overdue-print;
+
+# Daily overdue email
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD-7 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.7_day_od.json;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD-14 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.14_day_od.json;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD2-14 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.14_day_second_od.json;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-OD-21 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.21_day_od.json;
+
+# Daily Predue (signed off: Bill)
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-PD-1 --granularity-only --custom-filters $AT_FILTERS/a_t_filters.1_day_pd.json;
+$EG_BIN/action_trigger_runner.pl --osrf-config $SRF_CORE --run-pending --process-hooks --granularity Daily-PD-3 --granularity-only;
+
+
+exit;
--- /dev/null
+#!/bin/bash
+set -eu
+
+echo -n "Beginning patron activity extension at "
+date +"%F %T"
+
+psql -U evergreen \
+ -f /home/opensrf/scripts/patron_activity/patron_activity.sql
+
+echo -n "Patron activity extension completed at "
+date +"%F %T"
--- /dev/null
+BEGIN;
+SET SESSION STATEMENT_TIMEOUT TO 0;
+
+UPDATE actor.usr usr
+SET expire_date = now() + grp.perm_interval::interval
+FROM permission.grp_tree grp where grp.id = usr.profile and
+usr.id IN (
+SELECT DISTINCT(usr) FROM actor.usr_activity
+WHERE event_time BETWEEN current_date - 2 AND current_date - 1
+AND actor.usr_activity.usr IS NOT NULL
+) AND NOT barred
+AND NOT deleted
+AND profile NOT IN (31, 91, 17, 26, 23, 32, 90);
+
+COMMIT;
--- /dev/null
+--Normally called by a shell script in this same directory.
+--See Redmine #44783, jbas-34
+begin;
+\set ON_ERROR_STOP on
+set client_min_messages = 'notice';
+set statement_timeout = 0;
+
+update config.global_flag set value = '0', enabled = true where name = 'history.circ.retention_count';
+update config.global_flag set value = '6 months', enabled = true where name = 'history.circ.retention_age';
+update config.global_flag set enabled = true where name = 'history.circ.retention_uses_last_finished';
+update config.global_flag set enabled = true where name = 'history.circ.retention_age_is_min';
+\pset tuples_only on
+select action.purge_circulations_custom(:ts_start,:ts_end);
+commit;
--- /dev/null
+#!/bin/bash
+#Archive action.circulation records
+#See Redmine #44783, jbas-34
+USAGE="thisscript.sh --start <xact_finish start date like YYYY-MM-DD> --duration <maximum script duration in minutes>"
+DATE_START="" #action.circulation.xact_finish date to start with; passed as a parameter to psql
+MAX_DURATION_MINUTES="" #Do not call psql again after this many minutes
+MAX_DATE="" # if set, do not process circs whose action.circulation.xact_finish exceeds this date
+while [ $# -gt 0 ] ; do
+ case $1 in
+ --start) DATE_START="$2"
+ shift
+ ;;
+ --duration) MAX_DURATION_MINUTES=$2
+ shift
+ ;;
+ --end) MAX_DATE="$2"
+ shift
+ ;;
+ *) shift
+ ;;
+ esac
+done
+
+if [ "$DATE_START" == "" ] ; then
+ echo $USAGE
+ exit 1
+else
+ echo "$DATE_START" | grep -e '20[01][0-9]-[01][0-9]-[0-3][0-9]' > /dev/null
+ if [ $? -ne 0 ] ; then
+ echo $USAGE
+ exit 1
+ fi
+fi
+if [ -z "$MAX_DURATION_MINUTES" ] ; then
+ echo $USAGE
+ exit 1
+fi
+
+set -e
+echo "DATE_START=$DATE_START"
+echo "DURATION='$MAX_DURATION_MINUTES'"
+EPOCH_START=$(date '+%s') #When this script started, measured as seconds since the Unix epoch
+EPOCH_STOP=$(($EPOCH_START + ($MAX_DURATION_MINUTES * 60) )) #Do not call psql again after this moment
+echo "This script will stop after $(date --date=@$EPOCH_STOP)."
+EPOCH_NOW=$EPOCH_START
+
+function day_increment {
+ DAY_TO_INCREMENT=$(date --date="$DAY_TO_INCREMENT + 1 day" '+%Y-%m-%d')
+};
+
+while [[ $EPOCH_NOW -lt $EPOCH_STOP ]] ; do
+ date
+ DAY_TO_INCREMENT=$DATE_START
+ day_increment
+ DATE_END=$DAY_TO_INCREMENT
+ if [ -n "$MAX_DATE" -a $DATE_START \> $MAX_DATE ]; then
+ echo "Reached max date of $MAX_DATE; exiting"
+ break;
+ fi;
+ echo "Beginning $DATE_START -- $DATE_END ..."
+ psql -U evergreen --file=purge_circulations.psql --quiet --variable=ts_start="'$DATE_START'" --variable=ts_end="'$DATE_END'"
+ DAY_TO_INCREMENT=$DATE_START
+ day_increment
+ DATE_START=$DAY_TO_INCREMENT
+ EPOCH_NOW=$(date '+%s')
+done
--- /dev/null
+#!/bin/bash
+set -eu
+
+echo -n "Reshelving copies at "
+date +"%F %T"
+
+psql -U evergreen \
+ -f /home/opensrf/scripts/reshelving/reshelving.sql
+
+echo -n "Reshelving complete at "
+date +"%F %T"
+
+
--- /dev/null
+BEGIN;
+SET SESSION STATEMENT_TIMEOUT TO 0;
+
+UPDATE asset.copy
+ SET status = 0
+ WHERE id IN (
+ SELECT cp.id
+ FROM asset.copy cp
+ WHERE cp.status = 7
+ AND cp.status_changed_time < NOW() - CAST(
+ COALESCE( BTRIM( (
+ SELECT value
+ FROM actor.org_unit_ancestor_setting(
+ 'circ.reshelving_complete.interval', cp.circ_lib)),'"' ), '24h' ) AS INTERVAL
+ )
+ );
+
+COMMIT;