Compare commits
20 Commits
Author | SHA1 | Date |
---|---|---|
|
120604c131 | |
|
72aa69088a | |
|
6de414d359 | |
|
97b63bfeba | |
|
0a15e0586b | |
|
5e2cabd8b7 | |
|
318b048090 | |
|
5197766815 | |
|
9ecc9a358b | |
|
c85c101b59 | |
|
ac38f8f28d | |
|
7f1938c9e5 | |
|
62c429dafb | |
|
ddf5d7f34f | |
|
8654bb13c3 | |
|
41d494eab4 | |
|
972a6226a2 | |
|
a8f4bc5e30 | |
|
5015924d19 | |
|
02b63027e2 |
21
README.md
21
README.md
|
@ -3,16 +3,21 @@ This repo contains some scripts to help automate posting live MLB game updates
|
|||
to Mastodon.
|
||||
|
||||
## 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
|
||||
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.
|
||||
* `mlbhighlightsave.sh` and `mlbhighlightpost.sh` work similarly to the
|
||||
previous pair, but post video highlights instead.
|
||||
* `posthighlights.sql` and `postplays.sql` are used by the posting scripts to
|
||||
select unposted data and then mark that data as posted.
|
||||
* `posthighlights.sql`, `postplays.sql`, `poststart.sql`, and `postfinal.sql`
|
||||
are used by the posting scripts to select unposted data and then mark that
|
||||
data as posted.
|
||||
* `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.
|
||||
|
||||
## How to use
|
||||
|
@ -35,10 +40,14 @@ scripts:
|
|||
2. Pick a directory to keep the SQLite database in (I picked
|
||||
`~/.local/share/mlblive`).
|
||||
3. Create the database with `sqlite3 <filename> < schema.sql`
|
||||
* Note that if you intend to run both scripts, or run multiple instances of
|
||||
the scripts, you'll probably want to make a database for each instance.
|
||||
* I recommend making one database for plays and one for highlights
|
||||
(assuming you wish to process both) for each team you want to follow.
|
||||
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.
|
||||
5. Review the scripts to see what arguments they require.
|
||||
5. Review the shell scripts to see what arguments they require.
|
||||
6. Write some systemd services and timers to execute the shell scripts
|
||||
automatically on some interval. Set the working directory to the directory
|
||||
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.
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#!/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)}"
|
|
@ -29,7 +29,7 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
jqFilter='.dates[].games[] | "\(.gamePk),\(.status.detailedState)"'
|
||||
fmt="OFS=\",\"; print \$1, \"$team\", \$2"
|
||||
save="\"sqlite3 $db '.import --csv /dev/stdin games'\""
|
||||
mlblive schedule -t $team | jq -r "$jqFilter" | awk -F , "{$fmt | $save; close($save)}"
|
||||
jqFilter='.dates[].games[]'
|
||||
fmt="OFS=\"\"; print \$0, 0"
|
||||
save="\"sqlite3 $db '.mode ascii' '.separator ' '.import /dev/stdin games'\""
|
||||
mlblive schedule -t $team | jq -Sc "$jqFilter" | awk -F "{$fmt | $save; close($save)}"
|
|
@ -0,0 +1,35 @@
|
|||
#!/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)}"
|
|
@ -0,0 +1,19 @@
|
|||
.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;
|
|
@ -0,0 +1,21 @@
|
|||
.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;
|
|
@ -9,9 +9,6 @@ do
|
|||
d)
|
||||
db=$OPTARG
|
||||
;;
|
||||
t)
|
||||
team=$OPTARG
|
||||
;;
|
||||
?)
|
||||
exit 1
|
||||
;;
|
||||
|
@ -24,17 +21,10 @@ then
|
|||
exit 1
|
||||
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
|
||||
# training)
|
||||
gamePk=$(sqlite3 $db "select gamePk from games where teamId='$team' and state='In Progress' limit 1")
|
||||
gamePk=$(sqlite3 $db "select json ->> 'gamePk' from games where json ->> 'status' ->> 'detailedState' in ('In Progress', 'Game Over') limit 1")
|
||||
if [[ -z "$gamePk" ]]
|
||||
if [[ "$gamePk" = 'null' ]]
|
||||
then
|
||||
echo "$0:" 'no live games found' >&2
|
||||
exit 1
|
|
@ -3,15 +3,12 @@
|
|||
set -e
|
||||
set -o pipefail
|
||||
|
||||
while getopts 'd:t:' opt
|
||||
while getopts 'd:' opt
|
||||
do
|
||||
case $opt in
|
||||
d)
|
||||
db=$OPTARG
|
||||
;;
|
||||
t)
|
||||
team=$OPTARG
|
||||
;;
|
||||
?)
|
||||
exit 1
|
||||
;;
|
||||
|
@ -24,15 +21,9 @@ then
|
|||
exit 1
|
||||
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
|
||||
# training)
|
||||
gamePk=$(sqlite3 $db "select gamePk from games where teamId='$team' and state in ('In Progress', 'Warmup') limit 1")
|
||||
gamePk=$(sqlite3 $db "select json ->> 'gamePk' from games where json ->> 'status' ->> 'detailedState' in ('In Progress', 'Warmup') limit 1")
|
||||
if [[ -z "$gamePk" ]]
|
||||
then
|
||||
echo "$0:" 'no live games found' >&2
|
|
@ -5,9 +5,9 @@ select
|
|||
json ->> 'description',
|
||||
json ->> 'halfInning',
|
||||
json ->> 'inning',
|
||||
json ->> 'awayTeam',
|
||||
replace(json ->> 'awayTeam', ' ', ''),
|
||||
json ->> 'awayScore',
|
||||
json ->> 'homeTeam',
|
||||
replace(json ->> 'homeTeam', ' ', ''),
|
||||
json ->> 'homeScore'
|
||||
from plays
|
||||
where
|
18
schema.sql
18
schema.sql
|
@ -17,8 +17,18 @@ on highlights(posted)
|
|||
where posted = 0;
|
||||
|
||||
create table if not exists games (
|
||||
gamePk integer,
|
||||
teamId text,
|
||||
state text,
|
||||
unique (teamId, gamePk) on conflict replace
|
||||
"json" text unique on conflict ignore,
|
||||
"posted" integer check ("posted" in (0, 1))
|
||||
);
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue