Compare commits

..

No commits in common. "main" and "onedb" have entirely different histories.
main ... onedb

13 changed files with 38 additions and 148 deletions

View File

@ -3,21 +3,16 @@ This repo contains some scripts to help automate posting live MLB game updates
to Mastodon. to Mastodon.
## Structure ## Structure
* `mlbgames.sh`, `mlbstartpost.sh`, and `mlbfinalpost.sh` are used to make a
post at the start and end of games. `mlbgames.sh` populates the `games` table
of a SQLite database, which the play and highlight scripts read when running,
so you'll need to run `mlbgames.sh` if you want to use the other scripts.
* `mlbplaysave.sh` and `mlbplaypost.sh` are used in tandem to post scoring * `mlbplaysave.sh` and `mlbplaypost.sh` are used in tandem to post scoring
updates. The former saves new plays to a SQLite database, and the latter updates. The former saves new plays to a SQLite database, and the latter
reads the database and posts any scoring plays that have not been posted yet. reads the database and posts any scoring plays that have not been posted yet.
* `mlbhighlightsave.sh` and `mlbhighlightpost.sh` work similarly to the * `mlbhighlightsave.sh` and `mlbhighlightpost.sh` work similarly to the
previous pair, but post video highlights instead. previous pair, but post video highlights instead.
* `posthighlights.sql`, `postplays.sql`, `poststart.sql`, and `postfinal.sql` * `posthighlights.sql` and `postplays.sql` are used by the posting scripts to
are used by the posting scripts to select unposted data and then mark that select unposted data and then mark that data as posted.
data as posted.
* `schema.sql` defines the table that new data gets saved to. * `schema.sql` defines the table that new data gets saved to.
Note that there are invisible characters (like `0x1f`) in some of the files. Note that there are invisible characters (like 0x1f) in some of the files.
These are used as delimiters when processing the data. These are used as delimiters when processing the data.
## How to use ## How to use
@ -40,14 +35,10 @@ scripts:
2. Pick a directory to keep the SQLite database in (I picked 2. Pick a directory to keep the SQLite database in (I picked
`~/.local/share/mlblive`). `~/.local/share/mlblive`).
3. Create the database with `sqlite3 <filename> < schema.sql` 3. Create the database with `sqlite3 <filename> < schema.sql`
* I recommend making one database for plays and one for highlights * Note that if you intend to run both scripts, or run multiple instances of
(assuming you wish to process both) for each team you want to follow. the scripts, you'll probably want to make a database for each instance.
Separate databases for plays and highlights will reduce delays due to locking.
4. Put the other SQL scripts in the same directory as the database. 4. Put the other SQL scripts in the same directory as the database.
5. Review the shell scripts to see what arguments they require. 5. Review the scripts to see what arguments they require.
6. Write some systemd services and timers to execute the shell scripts 6. Write some systemd services and timers to execute the shell scripts
automatically on some interval. Set the working directory to the directory automatically on some interval. Set the working directory to the directory
with the database. with the database.
* I have `mlbsaveplays.sh` running as a simple service, and all the other
scripts (games, highlights, `mlbpostplays.sh`) running as oneshot
services that execute on timers.

View File

@ -1,35 +0,0 @@
#!/bin/bash
set -e
while getopts 'd:a:' opt
do
case $opt in
d)
db=$OPTARG
;;
a)
account=$OPTARG
;;
?)
exit 1
;;
esac
done
if [[ -z $db ]]
then
echo "$0:" '-d is required' >&2
exit 1
fi
if [[ -z $account ]]
then
echo "$0:" '-a is required' >&2
exit 1
fi
# format each row of data retreived from the select statement and pipe to toot
fmt='printf "Final:\n\n%s %s\n%s %s\n\n#baseball #live\n", $1, $2, $3, $4'
post="\"toot post --using $account\""
sqlite3 $db < postfinal.sql | awk -F  "{$fmt | $post; close($post)}"

View File

@ -1,35 +0,0 @@
#!/bin/bash
set -e
while getopts 'd:a:' opt
do
case $opt in
d)
db=$OPTARG
;;
a)
account=$OPTARG
;;
?)
exit 1
;;
esac
done
if [[ -z $db ]]
then
echo "$0:" '-d is required' >&2
exit 1
fi
if [[ -z $account ]]
then
echo "$0:" '-a is required' >&2
exit 1
fi
# format each row of data retreived from the select statement and pipe to toot
fmt='printf "Starting soon:\n\n%s (%s-%s) @\n%s (%s-%s)\n\n#baseball #live\n", $1, $2, $3, $4, $5, $6'
post="\"toot post --using $account\""
sqlite3 $db < poststart.sql | awk -F  "{$fmt | $post; close($post)}"

View File

@ -1,19 +0,0 @@
.separator 
begin;
select
json ->> 'teams' ->> 'away' ->> 'team' ->> 'name',
json ->> 'teams' ->> 'away' ->> 'score',
json ->> 'teams' ->> 'home' ->> 'team' ->> 'name',
json ->> 'teams' ->> 'home' ->> 'score'
from games
where
json ->> 'status' ->> 'detailedState' = 'Final' and
posted = 0;
update games
set posted = 1
where
json ->> 'status' ->> 'detailedState' = 'Final' and
posted = 0;
commit;

View File

@ -1,21 +0,0 @@
.separator 
begin;
select
json ->> 'teams' ->> 'away' ->> 'team' ->> 'name',
json ->> 'teams' ->> 'away' ->> 'leagueRecord' ->> 'wins',
json ->> 'teams' ->> 'away' ->> 'leagueRecord' ->> 'losses',
json ->> 'teams' ->> 'home' ->> 'team' ->> 'name',
json ->> 'teams' ->> 'home' ->> 'leagueRecord' ->> 'wins',
json ->> 'teams' ->> 'home' ->> 'leagueRecord' ->> 'losses'
from games
where
json ->> 'status' ->> 'detailedState' = 'Warmup' and
posted = 0;
update games
set posted = 1
where
json ->> 'status' ->> 'detailedState' = 'Warmup' and
posted = 0;
commit;

View File

@ -29,7 +29,7 @@ then
exit 1 exit 1
fi fi
jqFilter='.dates[].games[]' jqFilter='.dates[].games[] | "\(.gamePk),\(.status.detailedState)"'
fmt="OFS=\"\"; print \$0, 0" fmt="OFS=\",\"; print \$1, \"$team\", \$2"
save="\"sqlite3 $db '.mode ascii' '.separator ' '.import /dev/stdin games'\"" save="\"sqlite3 $db '.import --csv /dev/stdin games'\""
mlblive schedule -t $team | jq -Sc "$jqFilter" | awk -F  "{$fmt | $save; close($save)}" mlblive schedule -t $team | jq -r "$jqFilter" | awk -F , "{$fmt | $save; close($save)}"

View File

@ -9,6 +9,9 @@ do
d) d)
db=$OPTARG db=$OPTARG
;; ;;
t)
team=$OPTARG
;;
?) ?)
exit 1 exit 1
;; ;;
@ -21,10 +24,17 @@ then
exit 1 exit 1
fi fi
if [[ -z $team ]]
then
echo "$0:" '-t is required' >&2
exit 1
fi
# grab the game pk of a single live game, if multiple (in case of spring # grab the game pk of a single live game, if multiple (in case of spring
# training) # training)
gamePk=$(sqlite3 $db "select json ->> 'gamePk' from games where json ->> 'status' ->> 'detailedState' in ('In Progress', 'Game Over') limit 1") gamePk=$(sqlite3 $db "select gamePk from games where teamId='$team' and state='In Progress' limit 1")
if [[ -z "$gamePk" ]] if [[ -z "$gamePk" ]]
if [[ "$gamePk" = 'null' ]]
then then
echo "$0:" 'no live games found' >&2 echo "$0:" 'no live games found' >&2
exit 1 exit 1

View File

@ -3,12 +3,15 @@
set -e set -e
set -o pipefail set -o pipefail
while getopts 'd:' opt while getopts 'd:t:' opt
do do
case $opt in case $opt in
d) d)
db=$OPTARG db=$OPTARG
;; ;;
t)
team=$OPTARG
;;
?) ?)
exit 1 exit 1
;; ;;
@ -21,9 +24,15 @@ then
exit 1 exit 1
fi fi
if [[ -z $team ]]
then
echo "$0:" '-t is required' >&2
exit 1
fi
# grab the game pk of a single live game, if multiple (in case of spring # grab the game pk of a single live game, if multiple (in case of spring
# training) # training)
gamePk=$(sqlite3 $db "select json ->> 'gamePk' from games where json ->> 'status' ->> 'detailedState' in ('In Progress', 'Warmup') limit 1") gamePk=$(sqlite3 $db "select gamePk from games where teamId='$team' and state in ('In Progress', 'Warmup') limit 1")
if [[ -z "$gamePk" ]] if [[ -z "$gamePk" ]]
then then
echo "$0:" 'no live games found' >&2 echo "$0:" 'no live games found' >&2

View File

@ -5,9 +5,9 @@ select
json ->> 'description', json ->> 'description',
json ->> 'halfInning', json ->> 'halfInning',
json ->> 'inning', json ->> 'inning',
replace(json ->> 'awayTeam', ' ', ''), json ->> 'awayTeam',
json ->> 'awayScore', json ->> 'awayScore',
replace(json ->> 'homeTeam', ' ', ''), json ->> 'homeTeam',
json ->> 'homeScore' json ->> 'homeScore'
from plays from plays
where where

View File

@ -17,18 +17,8 @@ on highlights(posted)
where posted = 0; where posted = 0;
create table if not exists games ( create table if not exists games (
"json" text unique on conflict ignore, gamePk integer,
"posted" integer check ("posted" in (0, 1)) teamId text,
state text,
unique (teamId, gamePk) on conflict replace
); );
create index if not exists nonposted_games
on games(posted)
where posted = 0;
create trigger if not exists delete_old_states
before insert on games
begin
delete from games
where json ->> 'gamePk' = new.json ->> 'gamePk' and
json ->> 'status' ->> 'detailedState' != new.json ->> 'status' ->> 'detailedState';
end;