Last active
July 30, 2019 12:13
-
-
Save Kaiepi/50db432579cc67202328a63c071f9c78 to your computer and use it in GitHub Desktop.
Pokémon Showdown Logs Scraper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Instructions: | |
# - Save this as ps-logs-scraper.p6 | |
# - Install Rakudo Star | |
# - Open up whatever terminal you use (cmd on Windows) | |
# - Enter "zef install Cro::HTTP JSON::Fast URI::Encode" | |
# - Change directory to wherever you saved this ("cd <directory>" on Windows) | |
# - Run perl6 ps-logs-scraper.p6 for usage instructions | |
# | |
# You will probably get a couple scary looking warnings beginning with | |
# "Trailing item in Hash.append" when running this script. Don't worry about this; | |
# this is due to Cro not being able to parse some of the cookies PS sets properly. | |
use v6.d; | |
use Cro::HTTP::Cookie; | |
use Cro::HTTP::Client; | |
use Cro::HTTP::Response; | |
use JSON::Fast; | |
use URI::Encode; | |
sub die(Str $message) { | |
note $message; | |
exit 1; | |
} | |
sub MAIN( | |
Str :$username!, | |
Str :$password!, | |
Str :$room!, | |
Str :$from!, | |
Str :$to!, | |
Str :$path = '.' | |
) { | |
my Cro::HTTP::Client $client .= new: :cookie-jar; | |
{ | |
say 'Logging in...'; | |
my Str $challstr = '4|' ~ (|'a'...'f', |'0'...'9').pick(256).join; | |
my Cro::HTTP::Response $response = await $client.post: | |
'https://play.pokemonshowdown.com/action.php', | |
http => 1.1, | |
content-type => 'application/x-www-form-urlencoded; charset=UTF-8', | |
body => %(:act<login>, :name($username), :pass($password), :$challstr); | |
my Str $data = await $response.body-text; | |
die $data unless $data.starts-with: ']'; | |
my %data = from-json $data.substr: 1; | |
die 'Invalid username or password' unless %data<curuser><loggedin>; | |
die %data<assertion>.substr: 2 if %data<assertion>.starts-with: ';;'; | |
} | |
{ | |
say 'Getting assertion...'; | |
my Cro::HTTP::Response $response = await $client.get: | |
'https://play.pokemonshowdown.com/action.php?act=getassertion&challengekeyid=2', | |
http => 1.1; | |
$client.cookie-jar.add-cookie: Cro::HTTP::Cookie.new: | |
name => 'assertion', | |
value => 'logs2.psim.us_' ~ (uri_encode_component await $response.body-text), | |
domain => 'logs2.psim.us', | |
path => '/'; | |
} | |
{ | |
my Str $roomid = $room.samemark(' ').subst(/ <-[a..z 0..9 -]>+ /, '', :g); | |
my Date $begin .= new: $from; | |
my Date $end .= new: $to; | |
my Str @dates = gather { | |
my Int $month = $begin.month; | |
for $begin.year..$end.year -> Int $year { | |
my Date $date .= new: :$year, :$month; | |
my Int $last-day = $year == $end.year && $month == $end.month | |
?? $end.day | |
!! $date.days-in-month; | |
for $begin.day..$last-day -> Int $day { | |
take Date.new(:$year, :$month, :$day).yyyy-mm-dd; | |
} | |
$month = $month == 12 ?? 1 !! $month + 1; | |
} | |
}; | |
hyper for @dates -> Str $date { | |
say "Fetching logs for $room on $date..."; | |
my Cro::HTTP::Response $response = await $client.get: | |
"http://logs2.psim.us:8080/$roomid/{$date.substr: 0, 7}/$date.txt", | |
http => 1.1, | |
content-type => 'text/plain;charset=utf-8'; | |
die "The account given doesn't have access to logs in $roomid" | |
if $response.request.path eq '/getassertion.html'; | |
say "Writing logs for $room on $date..."; | |
spurt $path.IO.child("$date.txt"), await $response.body-text; | |
} | |
} | |
say 'Done!'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment