Fix line-endings; Increase portability; Add speedtyper.py
This commit is contained in:
@@ -1,25 +1,22 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Discard on use
|
# Increase nice and rtprio limits.
|
||||||
rm $0
|
local user=$(cut -d' ' -f1 <<< $(who))
|
||||||
|
echo "$user - nice -20
|
||||||
# Increase nice and rtprio limits.
|
$user - rtprio 99" | sudo tee --append /etc/security/limits.conf
|
||||||
local user=$(cut -d' ' -f1 <<< $(who))
|
|
||||||
echo "$user - nice -20
|
# Create pulseaudio config.
|
||||||
$user - rtprio 99" | sudo tee --append /etc/security/limits.conf
|
sudo mkdir -p /etc/pulse/daemon.conf.d/
|
||||||
|
echo "high-priority = yes
|
||||||
# Create pulseaudio config.
|
nice-level = -15
|
||||||
sudo mkdir -p /etc/pulse/daemon.conf.d/
|
|
||||||
echo "high-priority = yes
|
realtime-scheduling = yes
|
||||||
nice-level = -15
|
realtime-priority = 50
|
||||||
|
|
||||||
realtime-scheduling = yes
|
resample-method = speex-float-0
|
||||||
realtime-priority = 50
|
|
||||||
|
default-fragments = 5
|
||||||
resample-method = speex-float-0
|
default-fragment-size-msec = 2" | sudo tee --append /etc/pulse/daemon.conf.d/10-lower-latency.conf
|
||||||
|
|
||||||
default-fragments = 5
|
# Disable timer-based scheduling.
|
||||||
default-fragment-size-msec = 2" | sudo tee --append /etc/pulse/daemon.conf.d/10-lower-latency.conf
|
sudo sed -i 's/load-module module-udev-det*/load-module module-udev-detect tsched=0/g' /etc/pulse/default.pa
|
||||||
|
|
||||||
# Disable timer-based scheduling.
|
|
||||||
sudo sed -i 's/load-module module-udev-det*/load-module module-udev-detect tsched=0/g' /etc/pulse/default.pa
|
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Discard on use
|
sudo mkdir -p /etc/X11/xorg.conf.d/
|
||||||
rm $0
|
echo 'Section "InputClass"
|
||||||
|
Identifier "My Mouse"
|
||||||
sudo mkdir -p /etc/X11/xorg.conf.d/
|
Driver "libinput"
|
||||||
echo 'Section "InputClass"
|
MatchIsPointer "yes"
|
||||||
Identifier "My Mouse"
|
Option "AccelProfile" "flat"
|
||||||
Driver "libinput"
|
EndSection' | sudo tee --append /etc/X11/xorg.conf.d/50-mouse-acceleration.conf
|
||||||
MatchIsPointer "yes"
|
|
||||||
Option "AccelProfile" "flat"
|
|
||||||
EndSection' | sudo tee --append /etc/X11/xorg.conf.d/50-mouse-acceleration.conf
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
USERNAME=""
|
USERNAME=""
|
||||||
PASSWORD=""
|
PASSWORD=""
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
KEYMAP="dvorak-programmer"
|
KEYMAP="dvorak-programmer"
|
||||||
DEVICE="/dev/sda"
|
DEVICE="/dev/sda"
|
||||||
|
|||||||
@@ -1,43 +1,40 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Discard on use
|
# https://blog.thepoon.fr/osuLinuxAudioLatency/
|
||||||
rm $0
|
sudo pacman-key --keyserver hkps://hkps.pool.sks-keyservers.net -r C0E7D0CDB72FBE95
|
||||||
|
sudo pacman-key --keyserver hkps://hkps.pool.sks-keyservers.net --lsign-key C0E7D0CDB72FBE95
|
||||||
# https://blog.thepoon.fr/osuLinuxAudioLatency/
|
|
||||||
sudo pacman-key --keyserver hkps://hkps.pool.sks-keyservers.net -r C0E7D0CDB72FBE95
|
echo "[thepoon]
|
||||||
sudo pacman-key --keyserver hkps://hkps.pool.sks-keyservers.net --lsign-key C0E7D0CDB72FBE95
|
Server = https://archrepo.thepoon.fr
|
||||||
|
Server = https://mirrors.celianvdb.fr/archlinux/thepoon
|
||||||
echo "[thepoon]
|
" | sudo tee --append /etc/pacman.conf
|
||||||
Server = https://archrepo.thepoon.fr
|
|
||||||
Server = https://mirrors.celianvdb.fr/archlinux/thepoon
|
sudo pacman -S wine-osu winetricks
|
||||||
" | sudo tee --append /etc/pacman.conf
|
|
||||||
|
mkdir ~/osu!
|
||||||
sudo pacman -S wine-osu winetricks
|
cd ~/osu!
|
||||||
|
wget https://m1.ppy.sh/r/osu\!install.exe
|
||||||
mkdir ~/osu!
|
|
||||||
cd ~/osu!
|
export WINEPREFIX="$HOME/.wine_osu"
|
||||||
wget https://m1.ppy.sh/r/osu\!install.exe
|
export WINEARCH=win32
|
||||||
|
|
||||||
export WINEPREFIX="$HOME/.wine_osu"
|
winetricks dotnet40 &
|
||||||
export WINEARCH=win32
|
|
||||||
|
cat <<EOF > ~/osu!/start.sh
|
||||||
winetricks dotnet40 &
|
#!/bin/sh
|
||||||
|
|
||||||
cat <<EOF > ~/osu!/start.sh
|
export WINEPREFIX="$HOME/.wine_osu"
|
||||||
#!/bin/sh
|
export STAGING_AUDIO_DURATION=8000
|
||||||
|
export PATH=/opt/wine-osu/bin:$PATH
|
||||||
export WINEPREFIX="$HOME/.wine_osu"
|
|
||||||
export STAGING_AUDIO_DURATION=8000
|
cd ~/osu!
|
||||||
export PATH=/opt/wine-osu/bin:$PATH
|
wine osu!.exe "$@"
|
||||||
|
EOF
|
||||||
cd ~/osu!
|
|
||||||
wine osu!.exe "$@"
|
cat <<EOF > ~/osu!/kill.sh
|
||||||
EOF
|
#!/bin/sh
|
||||||
|
|
||||||
cat <<EOF > ~/osu!/kill.sh
|
export WINEPREFIX="$HOME/.wine_osu"
|
||||||
#!/bin/sh
|
|
||||||
|
wineserver -k
|
||||||
export WINEPREFIX="$HOME/.wine_osu"
|
EOF
|
||||||
|
|
||||||
wineserver -k
|
|
||||||
EOF
|
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
# Discard on use
|
echo "[multilib]
|
||||||
rm $0
|
Include = /etc/pacman.d/mirrorlist
|
||||||
|
" | sudo tee --append /etc/pacman.conf
|
||||||
echo "[multilib]
|
|
||||||
Include = /etc/pacman.d/mirrorlist
|
sudo pacman -S steam steam-native-runtime
|
||||||
" | sudo tee --append /etc/pacman.conf
|
|
||||||
|
|
||||||
sudo pacman -S steam steam-native-runtime
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
#yay -S yaru-gtk-theme yaru-sound-theme gnome-shell-extension-ubuntu-dock
|
#yay -S yaru-gtk-theme yaru-sound-theme gnome-shell-extension-ubuntu-dock
|
||||||
#yay -S yaru-icon-theme # needs to be installed seperately for some reason
|
#yay -S yaru-icon-theme # needs to be installed seperately for some reason
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
constexpr auto num_points = 10;
|
constexpr auto num_points = 10;
|
||||||
constexpr auto sleep_msec = 1;
|
constexpr auto sleep_msec = 1;
|
||||||
constexpr auto radius = 100.0f;
|
constexpr auto radius = 100.0f;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
const auto window_handle = FindWindow(nullptr, "osu!");
|
const auto window_handle = FindWindow(nullptr, "osu!");
|
||||||
if (!window_handle) {
|
if (!window_handle) {
|
||||||
printf("FATAL: Could not find osu!. (0x%X)\n", GetLastError());
|
printf("FATAL: Could not find osu!. (0x%X)\n", GetLastError());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto get_desired_pos = [&]() -> std::tuple<int, int> {
|
auto get_desired_pos = [&]() -> std::tuple<int, int> {
|
||||||
static auto counter = 0;
|
static auto counter = 0;
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetWindowRect(window_handle, &rect);
|
GetWindowRect(window_handle, &rect);
|
||||||
|
|
||||||
const auto center_x = rect.left + (rect.right - rect.left) / 2;
|
const auto center_x = rect.left + (rect.right - rect.left) / 2;
|
||||||
const auto center_y = rect.top + (rect.bottom - rect.top) / 2;
|
const auto center_y = rect.top + (rect.bottom - rect.top) / 2;
|
||||||
|
|
||||||
const auto angle = 3.1415926f * 2.0f * (float)counter / (float)num_points;
|
const auto angle = 3.1415926f * 2.0f * (float)counter / (float)num_points;
|
||||||
|
|
||||||
if (counter > num_points) {
|
if (counter > num_points) {
|
||||||
counter = 0;
|
counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { center_x + radius * sin(angle), center_y + radius * cos(angle) };
|
return { center_x + radius * sin(angle), center_y + radius * cos(angle) };
|
||||||
};
|
};
|
||||||
|
|
||||||
while (!GetAsyncKeyState(VK_DELETE)) {
|
while (!GetAsyncKeyState(VK_DELETE)) {
|
||||||
if (GetAsyncKeyState('P')) {
|
if (GetAsyncKeyState('P')) {
|
||||||
std::apply(SetCursorPos, get_desired_pos());
|
std::apply(SetCursorPos, get_desired_pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
Sleep(sleep_msec);
|
Sleep(sleep_msec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# bulk file renamer that you interface with using intermediary text file.
|
|
||||||
|
# bulk file renamer that you interface with using intermediary text file.
|
||||||
import os
|
|
||||||
|
import os
|
||||||
def setup_file():
|
|
||||||
files = open('files.txt', 'w')
|
def setup_file():
|
||||||
|
files = open('files.txt', 'w')
|
||||||
for file in os.listdir('.'):
|
|
||||||
files.write(file + '\n')
|
for file in os.listdir('.'):
|
||||||
|
files.write(file + '\n')
|
||||||
def rename_files():
|
|
||||||
new_names = open('files.txt', 'r')
|
def rename_files():
|
||||||
|
new_names = open('files.txt', 'r')
|
||||||
for file in os.listdir('.'):
|
|
||||||
new_name = str(new_names.readline()).rstrip('\n')
|
for file in os.listdir('.'):
|
||||||
|
new_name = str(new_names.readline()).rstrip('\n')
|
||||||
if (new_name == file) or new_name == "files.txt":
|
|
||||||
continue
|
if (new_name == file) or new_name == "files.txt":
|
||||||
|
continue
|
||||||
os.rename(file, new_name)
|
|
||||||
|
os.rename(file, new_name)
|
||||||
print("bulk renamer by Olari.\n")
|
|
||||||
|
print("bulk renamer by Olari.\n")
|
||||||
print("Generating files.txt")
|
|
||||||
print("Modify it to rename files\n")
|
print("Generating files.txt")
|
||||||
setup_file()
|
print("Modify it to rename files\n")
|
||||||
|
setup_file()
|
||||||
input("Waiting for input...\n")
|
|
||||||
|
input("Waiting for input...\n")
|
||||||
print("Renaming files")
|
|
||||||
rename_files()
|
print("Renaming files")
|
||||||
|
rename_files()
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# deadsimple discord bot
|
|
||||||
|
# deadsimple discord bot
|
||||||
import discord
|
|
||||||
import asyncio
|
import discord
|
||||||
|
import asyncio
|
||||||
client = discord.Client()
|
|
||||||
|
client = discord.Client()
|
||||||
async def task():
|
|
||||||
await client.wait_until_ready()
|
async def task():
|
||||||
|
await client.wait_until_ready()
|
||||||
while not client.is_closed:
|
|
||||||
server = client.get_channel('channel id')
|
while not client.is_closed:
|
||||||
await client.send_message(server, 'message')
|
server = client.get_channel('channel id')
|
||||||
await asyncio.sleep(60) # time to sleep
|
await client.send_message(server, 'message')
|
||||||
|
await asyncio.sleep(60) # time to sleep
|
||||||
@client.event
|
|
||||||
async def on_ready():
|
@client.event
|
||||||
print('Logged in as')
|
async def on_ready():
|
||||||
print(client.user.name)
|
print('Logged in as')
|
||||||
print(client.user.id)
|
print(client.user.name)
|
||||||
print('------')
|
print(client.user.id)
|
||||||
|
print('------')
|
||||||
client.loop.create_task(task())
|
|
||||||
client.run('username', 'password')
|
client.loop.create_task(task())
|
||||||
|
client.run('username', 'password')
|
||||||
|
|||||||
@@ -1,257 +1,257 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# overly complicated flac reencoder originally written for the big touhou music torrent on nyaa.si
|
# overly complicated flac reencoder originally written for the big touhou music torrent on nyaa.si
|
||||||
# contains example of process calling and multithreading
|
# contains example of process calling and multithreading
|
||||||
# not recommended to use (probably destructive)
|
# not recommended to use (probably destructive)
|
||||||
|
|
||||||
import os, re, time
|
import os, re, time
|
||||||
import subprocess
|
import subprocess
|
||||||
import wave
|
import wave
|
||||||
|
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
f = open("errlog", "w", encoding="UTF-8")
|
f = open("errlog", "w", encoding="UTF-8")
|
||||||
|
|
||||||
def remove_if_exists(filename):
|
def remove_if_exists(filename):
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
|
|
||||||
def opus_enc(queue, split_track_filename, track, quality=140.0):
|
def opus_enc(queue, split_track_filename, track, quality=140.0):
|
||||||
subprocess.call([
|
subprocess.call([
|
||||||
'opusenc',
|
'opusenc',
|
||||||
'--vbr',
|
'--vbr',
|
||||||
'--bitrate', str(quality),
|
'--bitrate', str(quality),
|
||||||
#'--comp', 10, #default
|
#'--comp', 10, #default
|
||||||
#'--framesize', '60', # default 20
|
#'--framesize', '60', # default 20
|
||||||
'--artist', track.performer,
|
'--artist', track.performer,
|
||||||
'--comment', 'tracknumber={}'.format(track.index),
|
'--comment', 'tracknumber={}'.format(track.index),
|
||||||
'--title', track.title,
|
'--title', track.title,
|
||||||
'--date', track.cd_date,
|
'--date', track.cd_date,
|
||||||
'--genre', track.cd_genre,
|
'--genre', track.cd_genre,
|
||||||
'--album', track.cd_title,
|
'--album', track.cd_title,
|
||||||
split_track_filename,
|
split_track_filename,
|
||||||
'{}.opus'.format(os.path.splitext(split_track_filename)[0]),
|
'{}.opus'.format(os.path.splitext(split_track_filename)[0]),
|
||||||
])
|
])
|
||||||
queue.get()
|
queue.get()
|
||||||
|
|
||||||
class Track():
|
class Track():
|
||||||
def __init__(self, track_index, filename, parent):
|
def __init__(self, track_index, filename, parent):
|
||||||
for member in ('cd_performer', 'cd_title', 'cd_date', 'cd_genre'):
|
for member in ('cd_performer', 'cd_title', 'cd_date', 'cd_genre'):
|
||||||
setattr(self, member, getattr(parent, member))
|
setattr(self, member, getattr(parent, member))
|
||||||
|
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.filepath = filename[:filename.rfind('\\')+1]
|
self.filepath = filename[:filename.rfind('\\')+1]
|
||||||
self.title = ''
|
self.title = ''
|
||||||
self.index = track_index
|
self.index = track_index
|
||||||
self.performer = self.cd_performer
|
self.performer = self.cd_performer
|
||||||
self.time = { 1:0.0 }
|
self.time = { 1:0.0 }
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{} - {} - {}".format(self.index, self.title, self.time)
|
return "{} - {} - {}".format(self.index, self.title, self.time)
|
||||||
|
|
||||||
class CueSheet():
|
class CueSheet():
|
||||||
def __init__(self, filename):
|
def __init__(self, filename):
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.filepath = filename[:filename.rfind('\\')+1]
|
self.filepath = filename[:filename.rfind('\\')+1]
|
||||||
|
|
||||||
self.cd_performer = ''
|
self.cd_performer = ''
|
||||||
self.cd_title = ''
|
self.cd_title = ''
|
||||||
self.cd_genre = ''
|
self.cd_genre = ''
|
||||||
self.cd_date = ''
|
self.cd_date = ''
|
||||||
|
|
||||||
self.current_file = ''
|
self.current_file = ''
|
||||||
|
|
||||||
self.tracks = []
|
self.tracks = []
|
||||||
|
|
||||||
self.regex_lst = (
|
self.regex_lst = (
|
||||||
(re.compile(r'PERFORMER\s(.+)'), self.__performer),
|
(re.compile(r'PERFORMER\s(.+)'), self.__performer),
|
||||||
(re.compile(r'REM DATE\s(.+)'), self.__date),
|
(re.compile(r'REM DATE\s(.+)'), self.__date),
|
||||||
(re.compile(r'REM GENRE\s(.+)'), self.__genre),
|
(re.compile(r'REM GENRE\s(.+)'), self.__genre),
|
||||||
(re.compile(r'TITLE\s(.+)'), self.__title),
|
(re.compile(r'TITLE\s(.+)'), self.__title),
|
||||||
(re.compile(r'FILE\s(.+)\sWAVE'), self.__file),
|
(re.compile(r'FILE\s(.+)\sWAVE'), self.__file),
|
||||||
(re.compile(r'TRACK\s(\d{2})\sAUDIO'), self.__track),
|
(re.compile(r'TRACK\s(\d{2})\sAUDIO'), self.__track),
|
||||||
(re.compile(r'INDEX\s(\d{2})\s(\d{1,3}:\d{2}:\d{2})'), self.__index),
|
(re.compile(r'INDEX\s(\d{2})\s(\d{1,3}:\d{2}:\d{2})'), self.__index),
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
value = "Title: {}\nPerformer: {}\nGenre: {}\nDate: {}\n".format(self.cd_title, self.cd_performer, self.cd_genre, self.cd_date)
|
value = "Title: {}\nPerformer: {}\nGenre: {}\nDate: {}\n".format(self.cd_title, self.cd_performer, self.cd_genre, self.cd_date)
|
||||||
for track in self.tracks:
|
for track in self.tracks:
|
||||||
value += ' ' + str(track) + '\n'
|
value += ' ' + str(track) + '\n'
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def read(self):
|
def read(self):
|
||||||
with open(self.filename, 'r', encoding='utf-8-sig') as f:
|
with open(self.filename, 'r', encoding='utf-8-sig') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
for regex, handler in self.regex_lst:
|
for regex, handler in self.regex_lst:
|
||||||
mobj = regex.match(line.strip())
|
mobj = regex.match(line.strip())
|
||||||
if mobj:
|
if mobj:
|
||||||
handler(*self.unquote(mobj.groups()))
|
handler(*self.unquote(mobj.groups()))
|
||||||
|
|
||||||
def split(self):
|
def split(self):
|
||||||
encoding_queue = multiprocessing.Queue(multiprocessing.cpu_count())
|
encoding_queue = multiprocessing.Queue(multiprocessing.cpu_count())
|
||||||
|
|
||||||
cds = set()
|
cds = set()
|
||||||
tracks = set()
|
tracks = set()
|
||||||
|
|
||||||
for i, track in enumerate(self.tracks):
|
for i, track in enumerate(self.tracks):
|
||||||
# FATAL: sheet is not for .tta file
|
# FATAL: sheet is not for .tta file
|
||||||
if track.filename[-4:] != '.tta':
|
if track.filename[-4:] != '.tta':
|
||||||
f.write("\nFilename isn't .tta ({}):\n{}\n".format(track.filename, str(self)))
|
f.write("\nFilename isn't .tta ({}):\n{}\n".format(track.filename, str(self)))
|
||||||
return
|
return
|
||||||
|
|
||||||
track_path = track.filepath + ' - '.join((track.index, track.title)).replace('?', '').replace('\\', '').replace('\\', '').replace(':', '')
|
track_path = track.filepath + ' - '.join((track.index, track.title)).replace('?', '').replace('\\', '').replace('\\', '').replace(':', '')
|
||||||
|
|
||||||
track_opus = track_path + '.opus'
|
track_opus = track_path + '.opus'
|
||||||
track_wav = track_path + '.wav'
|
track_wav = track_path + '.wav'
|
||||||
|
|
||||||
if os.path.exists(track_opus):
|
if os.path.exists(track_opus):
|
||||||
f.write("File already exists, continuing... ({})".format(track_opus))
|
f.write("File already exists, continuing... ({})".format(track_opus))
|
||||||
remove_if_exists(track_wav)
|
remove_if_exists(track_wav)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
cd_wav = track.filename[:-4] + '.wav'
|
cd_wav = track.filename[:-4] + '.wav'
|
||||||
|
|
||||||
# decode .tta if needed
|
# decode .tta if needed
|
||||||
if not os.path.exists(cd_wav):
|
if not os.path.exists(cd_wav):
|
||||||
# FATAL: no file to decode
|
# FATAL: no file to decode
|
||||||
if not os.path.exists(track.filename):
|
if not os.path.exists(track.filename):
|
||||||
f.write("\nFile doesn't exist ({}):\n{}\n".format(track.filename, str(self)))
|
f.write("\nFile doesn't exist ({}):\n{}\n".format(track.filename, str(self)))
|
||||||
return
|
return
|
||||||
|
|
||||||
result = subprocess.call([
|
result = subprocess.call([
|
||||||
'tta', #'ttaenc',
|
'tta', #'ttaenc',
|
||||||
'-d',
|
'-d',
|
||||||
track.filename,
|
track.filename,
|
||||||
#'-o',
|
#'-o',
|
||||||
cd_wav
|
cd_wav
|
||||||
])
|
])
|
||||||
|
|
||||||
# FATAL: .tta decode failed
|
# FATAL: .tta decode failed
|
||||||
if result != 0:
|
if result != 0:
|
||||||
f.write("Failed to decode .tta ({}):\n{}\n\n".format(track.index, str(self)))
|
f.write("Failed to decode .tta ({}):\n{}\n\n".format(track.index, str(self)))
|
||||||
return
|
return
|
||||||
|
|
||||||
# remove .tta
|
# remove .tta
|
||||||
remove_if_exists(track.filename)
|
remove_if_exists(track.filename)
|
||||||
|
|
||||||
# split .wav into track
|
# split .wav into track
|
||||||
if not os.path.exists(track_wav):
|
if not os.path.exists(track_wav):
|
||||||
wafi = wave.open(cd_wav, 'rb')
|
wafi = wave.open(cd_wav, 'rb')
|
||||||
param_names = ('nchannels', 'sampwidth', 'framerate', 'nframes', 'comptype', 'compname')
|
param_names = ('nchannels', 'sampwidth', 'framerate', 'nframes', 'comptype', 'compname')
|
||||||
params = wafi.getparams()
|
params = wafi.getparams()
|
||||||
param_dict = dict(zip(param_names, params))
|
param_dict = dict(zip(param_names, params))
|
||||||
|
|
||||||
start = int(param_dict['framerate'] * track.time[1])
|
start = int(param_dict['framerate'] * track.time[1])
|
||||||
stop = param_dict['nframes']
|
stop = param_dict['nframes']
|
||||||
if len(sheet.tracks) > i+1 and sheet.tracks[i+1].filename == track.filename:
|
if len(sheet.tracks) > i+1 and sheet.tracks[i+1].filename == track.filename:
|
||||||
stop = int(param_dict['framerate'] * sheet.tracks[i+1].time.get(0, sheet.tracks[i+1].time[1]))
|
stop = int(param_dict['framerate'] * sheet.tracks[i+1].time.get(0, sheet.tracks[i+1].time[1]))
|
||||||
|
|
||||||
wafi_write = wave.open(track_wav, 'wb')
|
wafi_write = wave.open(track_wav, 'wb')
|
||||||
newparams = list(params)
|
newparams = list(params)
|
||||||
newparams[3] = 0
|
newparams[3] = 0
|
||||||
wafi_write.setparams( tuple(newparams) )
|
wafi_write.setparams( tuple(newparams) )
|
||||||
|
|
||||||
wafi.setpos(start)
|
wafi.setpos(start)
|
||||||
wafi_write.writeframes(wafi.readframes(stop-start))
|
wafi_write.writeframes(wafi.readframes(stop-start))
|
||||||
wafi_write.close()
|
wafi_write.close()
|
||||||
|
|
||||||
wafi.close()
|
wafi.close()
|
||||||
|
|
||||||
encoding_queue.put(track_wav)
|
encoding_queue.put(track_wav)
|
||||||
p = multiprocessing.Process(
|
p = multiprocessing.Process(
|
||||||
target=opus_enc,
|
target=opus_enc,
|
||||||
args=(
|
args=(
|
||||||
encoding_queue,
|
encoding_queue,
|
||||||
track_wav,
|
track_wav,
|
||||||
track
|
track
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
p.start()
|
p.start()
|
||||||
|
|
||||||
if cd_wav not in cds:
|
if cd_wav not in cds:
|
||||||
cds.add(cd_wav)
|
cds.add(cd_wav)
|
||||||
|
|
||||||
tracks.add(track_wav)
|
tracks.add(track_wav)
|
||||||
|
|
||||||
while not encoding_queue.empty():
|
while not encoding_queue.empty():
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|
||||||
for cd in cds:
|
for cd in cds:
|
||||||
remove_if_exists(cd)
|
remove_if_exists(cd)
|
||||||
|
|
||||||
for track in tracks:
|
for track in tracks:
|
||||||
remove_if_exists(track)
|
remove_if_exists(track)
|
||||||
|
|
||||||
remove_if_exists(self.filename)
|
remove_if_exists(self.filename)
|
||||||
|
|
||||||
print(self.filename, "done!")
|
print(self.filename, "done!")
|
||||||
|
|
||||||
|
|
||||||
def __performer(self, s):
|
def __performer(self, s):
|
||||||
if not self.tracks:
|
if not self.tracks:
|
||||||
self.cd_performer = s
|
self.cd_performer = s
|
||||||
else:
|
else:
|
||||||
self.tracks[-1].performer = s
|
self.tracks[-1].performer = s
|
||||||
|
|
||||||
def __title(self, s):
|
def __title(self, s):
|
||||||
if not self.tracks:
|
if not self.tracks:
|
||||||
self.cd_title = s
|
self.cd_title = s
|
||||||
else:
|
else:
|
||||||
self.tracks[-1].title = s
|
self.tracks[-1].title = s
|
||||||
|
|
||||||
def __genre(self, s):
|
def __genre(self, s):
|
||||||
self.cd_genre = s
|
self.cd_genre = s
|
||||||
|
|
||||||
def __date(self, s):
|
def __date(self, s):
|
||||||
self.cd_date = s
|
self.cd_date = s
|
||||||
|
|
||||||
def __file(self, s):
|
def __file(self, s):
|
||||||
self.current_file = s
|
self.current_file = s
|
||||||
|
|
||||||
def __track(self, s):
|
def __track(self, s):
|
||||||
self.tracks.append( Track(s, self.filepath + self.current_file, self) )
|
self.tracks.append( Track(s, self.filepath + self.current_file, self) )
|
||||||
|
|
||||||
def __index(self, idx, s):
|
def __index(self, idx, s):
|
||||||
idx = int(idx)
|
idx = int(idx)
|
||||||
self.tracks[-1].time[idx] = self.index_split(s)
|
self.tracks[-1].time[idx] = self.index_split(s)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def index_split(s):
|
def index_split(s):
|
||||||
t = s.split(':')
|
t = s.split(':')
|
||||||
return float(t[0])*60 + float(t[1]) + float(t[2]) / 75.0
|
return float(t[0])*60 + float(t[1]) + float(t[2]) / 75.0
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def dqstrip(s):
|
def dqstrip(s):
|
||||||
if s[0] == '"' and s[-1] == '"': return s[1:-1]
|
if s[0] == '"' and s[-1] == '"': return s[1:-1]
|
||||||
return s
|
return s
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unquote(t):
|
def unquote(t):
|
||||||
return tuple([CueSheet.dqstrip(s.strip()) for s in t])
|
return tuple([CueSheet.dqstrip(s.strip()) for s in t])
|
||||||
|
|
||||||
class SplitterWorker(Thread):
|
class SplitterWorker(Thread):
|
||||||
def __init__(self, queue, filename):
|
def __init__(self, queue, filename):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
sheet = CueSheet(self.filename)
|
sheet = CueSheet(self.filename)
|
||||||
sheet.read()
|
sheet.read()
|
||||||
sheet.split()
|
sheet.split()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
|
|
||||||
for root, dirs, files in os.walk('.'):
|
for root, dirs, files in os.walk('.'):
|
||||||
for name in files:
|
for name in files:
|
||||||
if name[-4:].lower() == '.cue':
|
if name[-4:].lower() == '.cue':
|
||||||
worker = SplitterWorker(queue, root + '\\' + name)
|
worker = SplitterWorker(queue, root + '\\' + name)
|
||||||
worker.daemon = True
|
worker.daemon = True
|
||||||
worker.start()
|
worker.start()
|
||||||
|
|
||||||
if os.path.exists('./stop'):
|
if os.path.exists('./stop'):
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# extracts cover from flac audio file
|
|
||||||
|
# extracts cover from flac audio file
|
||||||
from mutagen.flac import FLAC, Picture
|
|
||||||
|
from mutagen.flac import FLAC, Picture
|
||||||
song = "cover.flac"
|
|
||||||
|
song = "cover.flac"
|
||||||
var = FLAC(song)
|
|
||||||
pics = var.pictures
|
var = FLAC(song)
|
||||||
print (pics)
|
pics = var.pictures
|
||||||
for p in pics:
|
print (pics)
|
||||||
if p.type == 3: #front cover
|
for p in pics:
|
||||||
print("\nfound front cover")
|
if p.type == 3: #front cover
|
||||||
with open("cover.jpg", "wb") as f:
|
print("\nfound front cover")
|
||||||
|
with open("cover.jpg", "wb") as f:
|
||||||
f.write(p.data)
|
f.write(p.data)
|
||||||
@@ -1,45 +1,46 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import numpy as np
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
class Ore:
|
|
||||||
def __init__(self, name, low, high):
|
class Ore:
|
||||||
self.name = name
|
def __init__(self, name, low, high):
|
||||||
self.low = low
|
self.name = name
|
||||||
self.high = high
|
self.low = low
|
||||||
|
self.high = high
|
||||||
oregen = (
|
|
||||||
Ore('gold', 0, 32),
|
oregen = (
|
||||||
Ore('iron', 0, 64),
|
Ore('gold', 0, 32),
|
||||||
Ore('coal', 0, 128),
|
Ore('iron', 0, 64),
|
||||||
Ore('lapis', 0, 32),
|
Ore('coal', 0, 128),
|
||||||
Ore('diamond', 0, 16),
|
Ore('lapis', 0, 32),
|
||||||
Ore('redstone', 0, 16),
|
Ore('diamond', 0, 16),
|
||||||
Ore('emerald', 0, 16),
|
Ore('redstone', 0, 16),
|
||||||
Ore('certuz', 24, 48),
|
Ore('emerald', 0, 16),
|
||||||
Ore('apatite', 54, 96),
|
Ore('certuz', 24, 48),
|
||||||
Ore('uranium', 16, 42),
|
Ore('apatite', 54, 96),
|
||||||
Ore('ruby', 16, 42),
|
Ore('uranium', 16, 42),
|
||||||
Ore('sapphire', 16, 42),
|
Ore('ruby', 16, 42),
|
||||||
Ore('bauxite', 48, 72),
|
Ore('sapphire', 16, 42),
|
||||||
Ore('tungsten', 0, 10),
|
Ore('bauxite', 48, 72),
|
||||||
Ore('peridot', 16, 42),
|
Ore('tungsten', 0, 10),
|
||||||
Ore('copper', 40, 75),
|
Ore('peridot', 16, 42),
|
||||||
Ore('tin', 20, 55),
|
Ore('copper', 40, 75),
|
||||||
Ore('silver', 5, 30),
|
Ore('tin', 20, 55),
|
||||||
Ore('lead', 5, 30),
|
Ore('silver', 5, 30),
|
||||||
Ore('aluminum', 48, 72),
|
Ore('lead', 5, 30),
|
||||||
Ore('nickel', 5, 20),
|
Ore('aluminum', 48, 72),
|
||||||
Ore('platinum', 7, 75),
|
Ore('nickel', 5, 20),
|
||||||
Ore('iridium', 8, 75),
|
Ore('platinum', 7, 75),
|
||||||
)
|
Ore('iridium', 8, 75),
|
||||||
|
)
|
||||||
oregen = sorted(oregen, key=lambda x: x.low, reverse=True)
|
|
||||||
|
oregen = sorted(oregen, key=lambda x: x.low, reverse=True)
|
||||||
plt.boxplot([(x.high, x.low) for x in oregen], labels=[x.name.title() for x in oregen], vert=False)
|
|
||||||
plt.title('FTB Continuum Oregen')
|
plt.boxplot([(x.high, x.low) for x in oregen], labels=[x.name.title() for x in oregen], vert=False)
|
||||||
plt.xlabel('Y-level')
|
plt.title('FTB Continuum Oregen')
|
||||||
plt.xticks()
|
plt.xlabel('Y-level')
|
||||||
|
plt.xticks()
|
||||||
plt.savefig('oregen.svg', format='svg')
|
|
||||||
|
plt.savefig('oregen.svg', format='svg')
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# converts code signatures found in ida to ones easily usable in c++ code
|
|
||||||
|
# converts code signatures found in ida to ones easily usable in c++ code
|
||||||
import sys
|
|
||||||
|
import sys
|
||||||
if len(sys.argv) < 2:
|
|
||||||
print("Usage: " + sys.argv[0] + " [ida style sig]")
|
if len(sys.argv) < 2:
|
||||||
exit(1)
|
print("Usage: " + sys.argv[0] + " [ida style sig]")
|
||||||
|
exit(1)
|
||||||
print(
|
|
||||||
'"' + ''.join([('\\x' + (byte if byte != '?' else '00')) for byte in sys.argv[1:]]) + '", "' +
|
print(
|
||||||
''.join([('x' if byte != '?' else '?') for byte in sys.argv[1:]]) + '"'
|
'"' + ''.join([('\\x' + (byte if byte != '?' else '00')) for byte in sys.argv[1:]]) + '", "' +
|
||||||
)
|
''.join([('x' if byte != '?' else '?') for byte in sys.argv[1:]]) + '"'
|
||||||
|
)
|
||||||
|
|||||||
97
python/speedtyper.py
Normal file
97
python/speedtyper.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import curses
|
||||||
|
|
||||||
|
|
||||||
|
class Word():
|
||||||
|
def __init__(self, target, x, y):
|
||||||
|
self.target = target
|
||||||
|
self.input = ""
|
||||||
|
self.x = x
|
||||||
|
self.y = y
|
||||||
|
|
||||||
|
|
||||||
|
def get_words(text, max_x, max_y):
|
||||||
|
curr_x = 0
|
||||||
|
curr_y = 0
|
||||||
|
|
||||||
|
words = []
|
||||||
|
for word in text.split():
|
||||||
|
if curr_x + len(word) > max_x:
|
||||||
|
curr_y += 1
|
||||||
|
curr_x = 0
|
||||||
|
|
||||||
|
if curr_y > max_y:
|
||||||
|
print("text too long, scrolling not implemented.")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
words.append(Word(word, curr_x, curr_y))
|
||||||
|
curr_x += len(word) + 1
|
||||||
|
|
||||||
|
return words
|
||||||
|
|
||||||
|
|
||||||
|
def main_curses(stdscr, text):
|
||||||
|
curses.use_default_colors()
|
||||||
|
curses.init_pair(1, curses.COLOR_GREEN, -1)
|
||||||
|
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_RED)
|
||||||
|
|
||||||
|
key = old_max_y = old_max_x = curr_word = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
# rewrap words on screen size change
|
||||||
|
max_y, max_x = stdscr.getmaxyx()
|
||||||
|
if max_y != old_max_y or max_x != old_max_x:
|
||||||
|
words = get_words(text, max_x, max_y)
|
||||||
|
old_max_x = max_x
|
||||||
|
old_max_y = max_y
|
||||||
|
|
||||||
|
if key in (curses.KEY_BACKSPACE, 'KEY_BACKSPACE', '\b', '\x7f', 127): # fml
|
||||||
|
words[curr_word].input = words[curr_word].input[:-1]
|
||||||
|
elif key >= 32 and key <= 126:
|
||||||
|
words[curr_word].input += chr(key)
|
||||||
|
|
||||||
|
# increment current word if its completed
|
||||||
|
if words[curr_word].input == words[curr_word].target:
|
||||||
|
curr_word += 1
|
||||||
|
|
||||||
|
# text complete
|
||||||
|
if curr_word == len(words):
|
||||||
|
break
|
||||||
|
|
||||||
|
stdscr.clear()
|
||||||
|
|
||||||
|
for word in words:
|
||||||
|
if word.input == word.target:
|
||||||
|
stdscr.addstr(word.y, word.x, word.target, curses.A_DIM)
|
||||||
|
elif word == words[curr_word]:
|
||||||
|
stdscr.addstr(word.y, word.x, word.target, curses.A_UNDERLINE)
|
||||||
|
else:
|
||||||
|
stdscr.addstr(word.y, word.x, word.target)
|
||||||
|
|
||||||
|
for i, c in enumerate(words[curr_word].input):
|
||||||
|
if i >= len(words[curr_word].target) or words[curr_word].input[i] != words[curr_word].target[i]:
|
||||||
|
stdscr.addstr(words[curr_word].y, words[curr_word].x + i, c, curses.color_pair(2) | curses.A_BOLD)
|
||||||
|
else:
|
||||||
|
stdscr.addstr(words[curr_word].y, words[curr_word].x + i, c, curses.color_pair(1))
|
||||||
|
|
||||||
|
stdscr.move(words[curr_word].y, words[curr_word].x + len(words[curr_word].input))
|
||||||
|
|
||||||
|
key = stdscr.getch()
|
||||||
|
|
||||||
|
|
||||||
|
def main(argv):
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
parser = ArgumentParser()
|
||||||
|
parser.add_argument("input")
|
||||||
|
args = parser.parse_args(argv[1:])
|
||||||
|
|
||||||
|
text = open(args.input).read()
|
||||||
|
|
||||||
|
curses.wrapper(main_curses, text)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
||||||
@@ -1,45 +1,46 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
import bs4
|
|
||||||
import sys
|
import bs4
|
||||||
import os
|
import sys
|
||||||
import glob
|
import os
|
||||||
|
import glob
|
||||||
# converts MyAnimeList's XML exports to readable (but less informative) text files.
|
|
||||||
|
# converts MyAnimeList's XML exports to readable (but less informative) text files.
|
||||||
animelists = glob.glob('animelist*.xml')
|
|
||||||
|
animelists = glob.glob('animelist*.xml')
|
||||||
for animelist in animelists:
|
|
||||||
with open(animelist, 'r') as xml, open(animelist + '.txt', 'w') as file:
|
for animelist in animelists:
|
||||||
soup = bs4.BeautifulSoup(xml.read(), 'html.parser')
|
with open(animelist, 'r') as xml, open(animelist + '.txt', 'w') as file:
|
||||||
|
soup = bs4.BeautifulSoup(xml.read(), 'html.parser')
|
||||||
completed = []
|
|
||||||
ptw = []
|
completed = []
|
||||||
movies = []
|
ptw = []
|
||||||
for anime in soup.select('anime'):
|
movies = []
|
||||||
line = anime.select('series_title')[0].text + ' ' + anime.select('my_watched_episodes')[0].text + '/' + anime.select('series_episodes')[0].text + '\n'
|
for anime in soup.select('anime'):
|
||||||
|
line = anime.select('series_title')[0].text + ' ' + anime.select('my_watched_episodes')[0].text + '/' + anime.select('series_episodes')[0].text + '\n'
|
||||||
series_type = anime.select('series_type')[0].text
|
|
||||||
status = anime.select('my_status')[0].text
|
series_type = anime.select('series_type')[0].text
|
||||||
|
status = anime.select('my_status')[0].text
|
||||||
if series_type == 'Movie':
|
|
||||||
movies.append(line)
|
if series_type == 'Movie':
|
||||||
continue
|
movies.append(line)
|
||||||
|
continue
|
||||||
if status == 'Completed':
|
|
||||||
completed.append(line)
|
if status == 'Completed':
|
||||||
elif status == 'Plan to Watch':
|
completed.append(line)
|
||||||
ptw.append(line)
|
elif status == 'Plan to Watch':
|
||||||
|
ptw.append(line)
|
||||||
for title in completed:
|
|
||||||
file.write(title)
|
for title in completed:
|
||||||
|
file.write(title)
|
||||||
file.write('\n')
|
|
||||||
|
file.write('\n')
|
||||||
for title in ptw:
|
|
||||||
file.write(title)
|
for title in ptw:
|
||||||
|
file.write(title)
|
||||||
file.write('\n')
|
|
||||||
|
file.write('\n')
|
||||||
for title in movies:
|
|
||||||
file.write(title)
|
for title in movies:
|
||||||
|
file.write(title)
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# converts youtube subscriptions export .xml to simple text file
|
|
||||||
|
# converts youtube subscriptions export .xml to simple text file
|
||||||
with open('subscription_manager', 'r', encoding='utf-8') as f:
|
|
||||||
while f:
|
with open('subscription_manager', 'r', encoding='utf-8') as f:
|
||||||
line = f.readline()
|
while f:
|
||||||
if not 'channel_id' in line:
|
line = f.readline()
|
||||||
continue
|
if not 'channel_id' in line:
|
||||||
|
continue
|
||||||
idpos = line.find('channel_id=') + len('channel_id=')
|
|
||||||
|
idpos = line.find('channel_id=') + len('channel_id=')
|
||||||
channel_id = line[idpos:idpos + len('UC3Y4vKAzTCqSdOt0ZeYWvTg')]
|
|
||||||
print('https://www.youtube.com/channel/' + channel_id)
|
channel_id = line[idpos:idpos + len('UC3Y4vKAzTCqSdOt0ZeYWvTg')]
|
||||||
|
print('https://www.youtube.com/channel/' + channel_id)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/env python3
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|||||||
@@ -1,47 +1,50 @@
|
|||||||
import requests
|
#!/usr/bin/env python3
|
||||||
import json
|
# -*- coding: utf-8 -*-
|
||||||
import sys
|
|
||||||
|
import requests
|
||||||
if len(sys.argv) < 3:
|
import json
|
||||||
print("usage: python get_7k_pp.py [api key] [username]")
|
import sys
|
||||||
exit(0)
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
api_key = sys.argv[1]
|
print("usage: python get_7k_pp.py [api key] [username]")
|
||||||
usernames = sys.argv[2:]
|
exit(0)
|
||||||
|
|
||||||
def get_json(url):
|
api_key = sys.argv[1]
|
||||||
page = requests.get(url)
|
usernames = sys.argv[2:]
|
||||||
|
|
||||||
try:
|
def get_json(url):
|
||||||
page.raise_for_status()
|
page = requests.get(url)
|
||||||
except:
|
|
||||||
print("Could not get '{}'".format(url))
|
try:
|
||||||
return []
|
page.raise_for_status()
|
||||||
|
except:
|
||||||
return json.loads(page.text)
|
print("Could not get '{}'".format(url))
|
||||||
|
return []
|
||||||
def get_user_best(api_key, username):
|
|
||||||
return get_json("https://osu.ppy.sh/api/get_user_best?k={}&limit=100&m=3&u={}".format(api_key, username))
|
return json.loads(page.text)
|
||||||
|
|
||||||
def get_beatmap(api_key, id):
|
def get_user_best(api_key, username):
|
||||||
return get_json("https://osu.ppy.sh/api/get_beatmaps?k={}&b={}".format(api_key, id))
|
return get_json("https://osu.ppy.sh/api/get_user_best?k={}&limit=100&m=3&u={}".format(api_key, username))
|
||||||
|
|
||||||
for username in usernames:
|
def get_beatmap(api_key, id):
|
||||||
scores_7k = []
|
return get_json("https://osu.ppy.sh/api/get_beatmaps?k={}&b={}".format(api_key, id))
|
||||||
pp_7k = 0.0
|
|
||||||
for score in get_user_best(api_key, username):
|
for username in usernames:
|
||||||
info = get_beatmap(api_key, score["beatmap_id"])[0]
|
scores_7k = []
|
||||||
if info["diff_size"] == '7':
|
pp_7k = 0.0
|
||||||
# theres probably a prettier solution for this
|
for score in get_user_best(api_key, username):
|
||||||
percentage = 100.0
|
info = get_beatmap(api_key, score["beatmap_id"])[0]
|
||||||
for num in range(len(scores_7k)):
|
if info["diff_size"] == '7':
|
||||||
percentage *= 0.95
|
# theres probably a prettier solution for this
|
||||||
|
percentage = 100.0
|
||||||
pp_7k += float(score["pp"]) / 100.0 * percentage
|
for num in range(len(scores_7k)):
|
||||||
scores_7k.append("[{:.2f}+ ({:.2f}%)] {:.2f} {} [{}] {}k".format(pp_7k, percentage, float(score["pp"]), info["title"], info["version"], score["score"][:3]))
|
percentage *= 0.95
|
||||||
|
|
||||||
print("7k pp for '{}'".format(username))
|
pp_7k += float(score["pp"]) / 100.0 * percentage
|
||||||
print("Total = {}".format(pp_7k))
|
scores_7k.append("[{:.2f}+ ({:.2f}%)] {:.2f} {} [{}] {}k".format(pp_7k, percentage, float(score["pp"]), info["title"], info["version"], score["score"][:3]))
|
||||||
|
|
||||||
for score_7k in scores_7k:
|
print("7k pp for '{}'".format(username))
|
||||||
print(score_7k)
|
print("Total = {}".format(pp_7k))
|
||||||
|
|
||||||
|
for score_7k in scores_7k:
|
||||||
|
print(score_7k)
|
||||||
|
|||||||
@@ -1,34 +1,37 @@
|
|||||||
import sys
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
from selenium import webdriver
|
|
||||||
|
import sys
|
||||||
def login(driver, username, password):
|
|
||||||
driver.get("https://osu.ppy.sh/forum/ucp.php?mode=login")
|
from selenium import webdriver
|
||||||
driver.find_element_by_name("username").send_keys(username)
|
|
||||||
driver.find_element_by_name("password").send_keys(password)
|
def login(driver, username, password):
|
||||||
driver.find_element_by_name("login").click()
|
driver.get("https://osu.ppy.sh/forum/ucp.php?mode=login")
|
||||||
|
driver.find_element_by_name("username").send_keys(username)
|
||||||
def main(argv):
|
driver.find_element_by_name("password").send_keys(password)
|
||||||
if len(argv) < 5:
|
driver.find_element_by_name("login").click()
|
||||||
print("Usage: {} [USERNAME] [PASSWORD] [SEARCH PARAMS] [NUM PAGES]".format(argv[0]))
|
|
||||||
return
|
def main(argv):
|
||||||
|
if len(argv) < 5:
|
||||||
username = argv[1]
|
print("Usage: {} [USERNAME] [PASSWORD] [SEARCH PARAMS] [NUM PAGES]".format(argv[0]))
|
||||||
password = argv[2]
|
return
|
||||||
|
|
||||||
search_params = argv[3].strip('"')
|
username = argv[1]
|
||||||
num_pages = int(argv[4])
|
password = argv[2]
|
||||||
|
|
||||||
with webdriver.Firefox() as driver:
|
search_params = argv[3].strip('"')
|
||||||
login(driver, username, password)
|
num_pages = int(argv[4])
|
||||||
|
|
||||||
for page_nr in range(1, num_pages + 1):
|
with webdriver.Firefox() as driver:
|
||||||
if page_nr == 0:
|
login(driver, username, password)
|
||||||
continue
|
|
||||||
|
for page_nr in range(1, num_pages + 1):
|
||||||
driver.get("https://old.ppy.sh/p/beatmaplist?{}&page={}".format(search_params, page_nr))
|
if page_nr == 0:
|
||||||
for beatmap_elem in driver.find_elements_by_class_name("beatmap"):
|
continue
|
||||||
print(beatmap_elem.get_property("id"))
|
|
||||||
|
driver.get("https://old.ppy.sh/p/beatmaplist?{}&page={}".format(search_params, page_nr))
|
||||||
if __name__ == "__main__":
|
for beatmap_elem in driver.find_elements_by_class_name("beatmap"):
|
||||||
main(sys.argv)
|
print(beatmap_elem.get_property("id"))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
||||||
|
|||||||
@@ -1,23 +1,24 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
import requests # http requests
|
|
||||||
import bs4 # html parser
|
import requests # http requests
|
||||||
|
import bs4 # html parser
|
||||||
with open("titles.txt", "w", encoding="UTF-8") as file:
|
|
||||||
for index in range(1, 175):
|
with open("titles.txt", "w", encoding="UTF-8") as file:
|
||||||
url = "https://www.gogdb.org/products?page=" + str(index)
|
for index in range(1, 175):
|
||||||
print(url)
|
url = "https://www.gogdb.org/products?page=" + str(index)
|
||||||
|
print(url)
|
||||||
page = requests.get("https://www.gogdb.org/products?page=" + str(index))
|
|
||||||
page.raise_for_status()
|
page = requests.get("https://www.gogdb.org/products?page=" + str(index))
|
||||||
|
page.raise_for_status()
|
||||||
soup = bs4.BeautifulSoup(page.text, "html.parser")
|
|
||||||
|
soup = bs4.BeautifulSoup(page.text, "html.parser")
|
||||||
producttable = soup.select("#product-table")[0]
|
|
||||||
titles = producttable.select("tr")
|
producttable = soup.select("#product-table")[0]
|
||||||
for title in titles:
|
titles = producttable.select("tr")
|
||||||
if len(title.select(".col-type")) == 0:
|
for title in titles:
|
||||||
continue
|
if len(title.select(".col-type")) == 0:
|
||||||
|
continue
|
||||||
if title.select(".col-type")[0].text == 'Game':
|
|
||||||
file.write(title.select(".col-name")[0].text.strip() + '\n')
|
if title.select(".col-type")[0].text == 'Game':
|
||||||
|
file.write(title.select(".col-name")[0].text.strip() + '\n')
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import requests, bs4, time
|
import requests, bs4, time
|
||||||
|
|
||||||
def get_titles(filename, title_type, maxrank):
|
def get_titles(filename, title_type, maxrank):
|
||||||
|
|||||||
@@ -1,137 +1,138 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
# reads SteamIDs from ./accounts.txt and outputs ban information into ./output.html
|
|
||||||
|
# reads SteamIDs from ./accounts.txt and outputs ban information into ./output.html
|
||||||
import urllib.request
|
|
||||||
import json
|
import urllib.request
|
||||||
import time
|
import json
|
||||||
|
import time
|
||||||
steamapikey = ""
|
|
||||||
|
steamapikey = ""
|
||||||
# read file and remove trailing newline because we're making a list
|
|
||||||
account_lines = [line.rstrip("\n") for line in open("accounts.txt").readlines()]
|
# read file and remove trailing newline because we're making a list
|
||||||
|
account_lines = [line.rstrip("\n") for line in open("accounts.txt").readlines()]
|
||||||
ids = []
|
|
||||||
for line in account_lines:
|
ids = []
|
||||||
# https://developer.valvesoftware.com/wiki/SteamID
|
for line in account_lines:
|
||||||
Z = int(line.split(':')[2])
|
# https://developer.valvesoftware.com/wiki/SteamID
|
||||||
V = 0x0110000100000000 # profile ID constant
|
Z = int(line.split(':')[2])
|
||||||
Y = int(line.split(':')[1])
|
V = 0x0110000100000000 # profile ID constant
|
||||||
W = Z * 2 + V + Y
|
Y = int(line.split(':')[1])
|
||||||
ids.append(str(W))
|
W = Z * 2 + V + Y
|
||||||
|
ids.append(str(W))
|
||||||
# API takes in comma seperated steamids
|
|
||||||
ids_string = ",".join([x for x in ids])
|
# API takes in comma seperated steamids
|
||||||
|
ids_string = ",".join([x for x in ids])
|
||||||
# https://developer.valvesoftware.com/wiki/Steam_Web_API
|
|
||||||
summaries = json.load(urllib.request.urlopen("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" + steamapikey + "&steamids=" + ids_string))
|
# https://developer.valvesoftware.com/wiki/Steam_Web_API
|
||||||
bans = json.load(urllib.request.urlopen("http://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=" + steamapikey + "&steamids=" + ids_string))
|
summaries = json.load(urllib.request.urlopen("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=" + steamapikey + "&steamids=" + ids_string))
|
||||||
|
bans = json.load(urllib.request.urlopen("http://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=" + steamapikey + "&steamids=" + ids_string))
|
||||||
output_file = open("output.html", "w", encoding="utf-8")
|
|
||||||
|
output_file = open("output.html", "w", encoding="utf-8")
|
||||||
output_file.write('\
|
|
||||||
<!DOCTYPE html>\n\
|
output_file.write('\
|
||||||
<html>\n\
|
<!DOCTYPE html>\n\
|
||||||
<head>\n\
|
<html>\n\
|
||||||
<style>\n\
|
<head>\n\
|
||||||
body {\n\
|
<style>\n\
|
||||||
font-family: sans-serif;\n\
|
body {\n\
|
||||||
}\n\
|
font-family: sans-serif;\n\
|
||||||
\n\
|
}\n\
|
||||||
table {\n\
|
\n\
|
||||||
color: #222;\n\
|
table {\n\
|
||||||
border-collapse: collapse;\n\
|
color: #222;\n\
|
||||||
}\n\
|
border-collapse: collapse;\n\
|
||||||
\n\
|
}\n\
|
||||||
tr, th, td {\n\
|
\n\
|
||||||
border: 1px solid #a2a9b1;\n\
|
tr, th, td {\n\
|
||||||
padding: 0.2em 0.4em;\n\
|
border: 1px solid #a2a9b1;\n\
|
||||||
}\n\
|
padding: 0.2em 0.4em;\n\
|
||||||
\n\
|
}\n\
|
||||||
.pwned {\n\
|
\n\
|
||||||
background-color: #ffb6c1\n\
|
.pwned {\n\
|
||||||
}\n\
|
background-color: #ffb6c1\n\
|
||||||
\n\
|
}\n\
|
||||||
th {\n\
|
\n\
|
||||||
background-color: #eaecf0;\n\
|
th {\n\
|
||||||
text-align: center;\n\
|
background-color: #eaecf0;\n\
|
||||||
}\n\
|
text-align: center;\n\
|
||||||
\n\
|
}\n\
|
||||||
a:hover, a:visited, a:link, a:active {\n\
|
\n\
|
||||||
text-decoration: none;\n\
|
a:hover, a:visited, a:link, a:active {\n\
|
||||||
}\n\
|
text-decoration: none;\n\
|
||||||
</style>\n\
|
}\n\
|
||||||
</head>\n\
|
</style>\n\
|
||||||
\n\
|
</head>\n\
|
||||||
<body>\n\
|
\n\
|
||||||
<table>\n\
|
<body>\n\
|
||||||
<tr>\n\
|
<table>\n\
|
||||||
<th>ID</th>\n\
|
<tr>\n\
|
||||||
<th>Name</th>\n\
|
<th>ID</th>\n\
|
||||||
<th>Status</th>\n\
|
<th>Name</th>\n\
|
||||||
<th>Type</th>\n\
|
<th>Status</th>\n\
|
||||||
<th>BanDays</th>\n\
|
<th>Type</th>\n\
|
||||||
<th>LogDays</th>\n\
|
<th>BanDays</th>\n\
|
||||||
<th>Profile</th>\n\
|
<th>LogDays</th>\n\
|
||||||
</tr>\n\
|
<th>Profile</th>\n\
|
||||||
')
|
</tr>\n\
|
||||||
|
')
|
||||||
numbanned = 0
|
|
||||||
|
numbanned = 0
|
||||||
for i in range(len(ids)):
|
|
||||||
try:
|
for i in range(len(ids)):
|
||||||
for summary in summaries['response']['players']:
|
try:
|
||||||
if summary['steamid'] == str(ids[i]):
|
for summary in summaries['response']['players']:
|
||||||
break
|
if summary['steamid'] == str(ids[i]):
|
||||||
except:
|
break
|
||||||
continue
|
except:
|
||||||
|
continue
|
||||||
try:
|
|
||||||
for ban in bans['players']:
|
try:
|
||||||
if ban['SteamId'] == str(ids[i]):
|
for ban in bans['players']:
|
||||||
break
|
if ban['SteamId'] == str(ids[i]):
|
||||||
except:
|
break
|
||||||
continue
|
except:
|
||||||
|
continue
|
||||||
status = ""
|
|
||||||
bantype = ""
|
status = ""
|
||||||
bandays = ""
|
bantype = ""
|
||||||
|
bandays = ""
|
||||||
if ban['VACBanned']:
|
|
||||||
status = "Pwned"
|
if ban['VACBanned']:
|
||||||
bantype = "VAC"
|
status = "Pwned"
|
||||||
bandays = str(ban['DaysSinceLastBan'])
|
bantype = "VAC"
|
||||||
numbanned += 1
|
bandays = str(ban['DaysSinceLastBan'])
|
||||||
|
numbanned += 1
|
||||||
if ban['NumberOfGameBans'] > 0:
|
|
||||||
status = "Pwned"
|
if ban['NumberOfGameBans'] > 0:
|
||||||
bantype = "Gameban"
|
status = "Pwned"
|
||||||
bandays = str(ban['DaysSinceLastBan'])
|
bantype = "Gameban"
|
||||||
numbanned += 1
|
bandays = str(ban['DaysSinceLastBan'])
|
||||||
|
numbanned += 1
|
||||||
name = summary['personaname']
|
|
||||||
name = name.replace("<", "<") # escape html tag names
|
name = summary['personaname']
|
||||||
name = name.replace(">", ">")
|
name = name.replace("<", "<") # escape html tag names
|
||||||
|
name = name.replace(">", ">")
|
||||||
logdays = str(int((time.time() - summary['lastlogoff']) / 86400)) # length of a day in epoch
|
|
||||||
|
logdays = str(int((time.time() - summary['lastlogoff']) / 86400)) # length of a day in epoch
|
||||||
line_start = ' <td>' if status != "Pwned" else ' <td class="pwned">'
|
|
||||||
|
line_start = ' <td>' if status != "Pwned" else ' <td class="pwned">'
|
||||||
output_file.write(' <tr>\n')
|
|
||||||
output_file.write(line_start + '<a target="_blank" href="' + 'https://steamcommunity.com/profiles/' + str(ids[i]) + '">' + str(ids[i]) + '</a></td>\n')
|
output_file.write(' <tr>\n')
|
||||||
output_file.write(line_start + name + '</td>\n')
|
output_file.write(line_start + '<a target="_blank" href="' + 'https://steamcommunity.com/profiles/' + str(ids[i]) + '">' + str(ids[i]) + '</a></td>\n')
|
||||||
output_file.write(line_start + status + '</td>\n')
|
output_file.write(line_start + name + '</td>\n')
|
||||||
output_file.write(line_start + bantype + '</td>\n')
|
output_file.write(line_start + status + '</td>\n')
|
||||||
output_file.write(line_start + bandays + '</td>\n')
|
output_file.write(line_start + bantype + '</td>\n')
|
||||||
output_file.write(line_start + logdays + '</td>\n')
|
output_file.write(line_start + bandays + '</td>\n')
|
||||||
output_file.write(line_start + '<a target="_blank" href="' + 'https://steamcommunity.com/profiles/' + str(ids[i]) + '"><img src=' + summary['avatarmedium'] + ">"+ '</img></td>\n')
|
output_file.write(line_start + logdays + '</td>\n')
|
||||||
output_file.write(' </tr>\n')
|
output_file.write(line_start + '<a target="_blank" href="' + 'https://steamcommunity.com/profiles/' + str(ids[i]) + '"><img src=' + summary['avatarmedium'] + ">"+ '</img></td>\n')
|
||||||
|
output_file.write(' </tr>\n')
|
||||||
i += 1
|
|
||||||
|
i += 1
|
||||||
output_file.write('\
|
|
||||||
</table>\n\
|
output_file.write('\
|
||||||
' + str(numbanned) + '/' + str(len(ids)) + ' banned\n\
|
</table>\n\
|
||||||
</body>\n\
|
' + str(numbanned) + '/' + str(len(ids)) + ' banned\n\
|
||||||
\
|
</body>\n\
|
||||||
</html>\n')
|
\
|
||||||
|
</html>\n')
|
||||||
|
|||||||
@@ -1,58 +1,59 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
import requests
|
|
||||||
import bs4
|
import requests
|
||||||
import sys
|
import bs4
|
||||||
|
import sys
|
||||||
if len(sys.argv) < 4:
|
|
||||||
print('Usage: ' + sys.argv[0] + ' [login] [password] [page name]')
|
if len(sys.argv) < 4:
|
||||||
exit(1)
|
print('Usage: ' + sys.argv[0] + ' [login] [password] [page name]')
|
||||||
|
exit(1)
|
||||||
login = sys.argv[1]
|
|
||||||
password = sys.argv[2]
|
login = sys.argv[1]
|
||||||
page_name = sys.argv[3]
|
password = sys.argv[2]
|
||||||
|
page_name = sys.argv[3]
|
||||||
def download_sheet(s, url):
|
|
||||||
page = s.get(url)
|
def download_sheet(s, url):
|
||||||
|
page = s.get(url)
|
||||||
try:
|
|
||||||
page.raise_for_status()
|
try:
|
||||||
except:
|
page.raise_for_status()
|
||||||
print("Couldn't get %s" % url)
|
except:
|
||||||
return
|
print("Couldn't get %s" % url)
|
||||||
|
return
|
||||||
soup = bs4.BeautifulSoup(page.text, 'html.parser')
|
|
||||||
|
soup = bs4.BeautifulSoup(page.text, 'html.parser')
|
||||||
links = soup.select('a')
|
|
||||||
for link in links:
|
links = soup.select('a')
|
||||||
if '.pdf' in link.text:
|
for link in links:
|
||||||
with open(link.text[1:link.text.find('.pdf') + 4], 'wb') as f:
|
if '.pdf' in link.text:
|
||||||
file = s.get(link.attrs['href'])
|
with open(link.text[1:link.text.find('.pdf') + 4], 'wb') as f:
|
||||||
|
file = s.get(link.attrs['href'])
|
||||||
try:
|
|
||||||
page.raise_for_status()
|
try:
|
||||||
except:
|
page.raise_for_status()
|
||||||
print("Couldn't get %s" % link.text)
|
except:
|
||||||
return
|
print("Couldn't get %s" % link.text)
|
||||||
|
return
|
||||||
for chunk in file.iter_content(100000):
|
|
||||||
f.write(chunk)
|
for chunk in file.iter_content(100000):
|
||||||
|
f.write(chunk)
|
||||||
with requests.session() as s:
|
|
||||||
login = s.post('https://hi10anime.com/wp-login.php', { 'login':login, 'password':password })
|
with requests.session() as s:
|
||||||
login.raise_for_status()
|
login = s.post('https://hi10anime.com/wp-login.php', { 'login':login, 'password':password })
|
||||||
|
login.raise_for_status()
|
||||||
if not 'You have successfully logged in. Welcome back!' in login.text:
|
|
||||||
print("Couldn't log in")
|
if not 'You have successfully logged in. Welcome back!' in login.text:
|
||||||
exit(1)
|
print("Couldn't log in")
|
||||||
|
exit(1)
|
||||||
page = s.get('https://sheet.host/user/%s/sheets' % page_name)
|
|
||||||
page.raise_for_status()
|
page = s.get('https://sheet.host/user/%s/sheets' % page_name)
|
||||||
|
page.raise_for_status()
|
||||||
soup = bs4.BeautifulSoup(page.text, 'html.parser')
|
|
||||||
|
soup = bs4.BeautifulSoup(page.text, 'html.parser')
|
||||||
titles = soup.select('.score-title')
|
|
||||||
|
titles = soup.select('.score-title')
|
||||||
for title in titles:
|
|
||||||
print('Getting %s' % title.text)
|
for title in titles:
|
||||||
download_sheet(s, title.attrs['href'])
|
print('Getting %s' % title.text)
|
||||||
|
download_sheet(s, title.attrs['href'])
|
||||||
|
|||||||
@@ -1,66 +1,67 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
import requests
|
|
||||||
import bs4
|
import requests
|
||||||
|
import bs4
|
||||||
def download_file(url):
|
|
||||||
filename = url[url.rfind('/') + 1:]
|
def download_file(url):
|
||||||
|
filename = url[url.rfind('/') + 1:]
|
||||||
print('Downloading %s' % filename)
|
|
||||||
|
print('Downloading %s' % filename)
|
||||||
file = requests.get(url)
|
|
||||||
|
file = requests.get(url)
|
||||||
try:
|
|
||||||
file.raise_for_status()
|
try:
|
||||||
except:
|
file.raise_for_status()
|
||||||
open(filename + '.failed', 'w')
|
except:
|
||||||
|
open(filename + '.failed', 'w')
|
||||||
with open(filename, 'wb') as f:
|
|
||||||
for chunk in file.iter_content(100000):
|
with open(filename, 'wb') as f:
|
||||||
f.write(chunk)
|
for chunk in file.iter_content(100000):
|
||||||
|
f.write(chunk)
|
||||||
f.close()
|
|
||||||
|
f.close()
|
||||||
def get_file_name(url):
|
|
||||||
page = requests.get(url)
|
def get_file_name(url):
|
||||||
page.raise_for_status()
|
page = requests.get(url)
|
||||||
|
page.raise_for_status()
|
||||||
soup = bs4.BeautifulSoup(page.text, "html.parser")
|
|
||||||
|
soup = bs4.BeautifulSoup(page.text, "html.parser")
|
||||||
cells = soup.select('td.even') # gay retardness
|
|
||||||
for cell in cells:
|
cells = soup.select('td.even') # gay retardness
|
||||||
text = cell.getText()
|
for cell in cells:
|
||||||
|
text = cell.getText()
|
||||||
if '.rar' in text or '.zip' in text or '.7z' in text:
|
|
||||||
return text
|
if '.rar' in text or '.zip' in text or '.7z' in text:
|
||||||
|
return text
|
||||||
|
|
||||||
def scrape_site(url):
|
|
||||||
# split the url to use later for constructing new urls
|
def scrape_site(url):
|
||||||
base_url = url[:url.rfind('/') + 1]
|
# split the url to use later for constructing new urls
|
||||||
url = url[url.rfind('/') + 1:]
|
base_url = url[:url.rfind('/') + 1]
|
||||||
|
url = url[url.rfind('/') + 1:]
|
||||||
while True:
|
|
||||||
print('Getting %s' % url)
|
while True:
|
||||||
|
print('Getting %s' % url)
|
||||||
page = requests.get(base_url + url)
|
|
||||||
page.raise_for_status() # throw on fail
|
page = requests.get(base_url + url)
|
||||||
|
page.raise_for_status() # throw on fail
|
||||||
soup = bs4.BeautifulSoup(page.text, "html.parser")
|
|
||||||
|
soup = bs4.BeautifulSoup(page.text, "html.parser")
|
||||||
titles = soup.select('a[title]')
|
|
||||||
for title in titles:
|
titles = soup.select('a[title]')
|
||||||
link = title.attrs['href']
|
for title in titles:
|
||||||
|
link = title.attrs['href']
|
||||||
if 'id' in link and not 'dl' in link: # find content links
|
|
||||||
print('Found %s' % title.attrs['title'])
|
if 'id' in link and not 'dl' in link: # find content links
|
||||||
download_file(base_url + 'sub/enganime/' + get_file_name(base_url + link))
|
print('Found %s' % title.attrs['title'])
|
||||||
|
download_file(base_url + 'sub/enganime/' + get_file_name(base_url + link))
|
||||||
next_link = soup.select('span.pagenav_next > a')
|
|
||||||
if len(next_link) == 0:
|
next_link = soup.select('span.pagenav_next > a')
|
||||||
print('End of site')
|
if len(next_link) == 0:
|
||||||
break
|
print('End of site')
|
||||||
|
break
|
||||||
url = next_link[0].attrs['href']
|
|
||||||
|
url = next_link[0].attrs['href']
|
||||||
scrape_site('http://subs.com.ru/list.php?c=enganime&p=5&w=asc&d=1')
|
|
||||||
|
scrape_site('http://subs.com.ru/list.php?c=enganime&p=5&w=asc&d=1')
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>JavaScript</title>
|
<title>JavaScript</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="style.css">
|
<link rel="stylesheet" href="style.css">
|
||||||
|
|
||||||
|
|
||||||
<h1>HTML/JavaScript mini-projects</h1>
|
<h1>HTML/JavaScript mini-projects</h1>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="reaction/reaction.html">Reaction test</a></li>
|
<li><a href="reaction/reaction.html">Reaction test</a></li>
|
||||||
<li><a href="trill/trill.html">Trill test</a></li>
|
<li><a href="trill/trill.html">Trill test</a></li>
|
||||||
<li><a href="mania/mania.html">osu!mania playfield simulator</a></li>
|
<li><a href="mania/mania.html">osu!mania playfield simulator</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -1,36 +1,36 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>osu!mania playfield</title>
|
<title>osu!mania playfield</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../style.css">
|
<link rel="stylesheet" href="../style.css">
|
||||||
<script src="../shared.js"></script>
|
<script src="../shared.js"></script>
|
||||||
<script src="mania.js"></script>
|
<script src="mania.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<canvas id="playfield" width="800" height="600" style="border: 1px solid #000000"></canvas>
|
<canvas id="playfield" width="800" height="600" style="border: 1px solid #000000"></canvas>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
<label for="columnstart">Column start</label><br>
|
<label for="columnstart">Column start</label><br>
|
||||||
<input type="range" id="columnstart" min="0" max="200" value="150">
|
<input type="range" id="columnstart" min="0" max="200" value="150">
|
||||||
<output id="columnstart_out"></output><br>
|
<output id="columnstart_out"></output><br>
|
||||||
|
|
||||||
<label for="columnwidth">Column width</label><br>
|
<label for="columnwidth">Column width</label><br>
|
||||||
<input type="range" id="columnwidth" min="16" max="70" value="40">
|
<input type="range" id="columnwidth" min="16" max="70" value="40">
|
||||||
<output id="columnwidth_out"></output><br>
|
<output id="columnwidth_out"></output><br>
|
||||||
|
|
||||||
<label for="hitposition">Hit position</label><br>
|
<label for="hitposition">Hit position</label><br>
|
||||||
<input type="range" id="hitposition" min="350" max="480" value="420">
|
<input type="range" id="hitposition" min="350" max="480" value="420">
|
||||||
<output id="hitposition_out"></output><br>
|
<output id="hitposition_out"></output><br>
|
||||||
|
|
||||||
<label for="scrollspeed">Scroll speed</label><br>
|
<label for="scrollspeed">Scroll speed</label><br>
|
||||||
<input type="range" id="scrollspeed" min="12" max="40" value="28">
|
<input type="range" id="scrollspeed" min="12" max="40" value="28">
|
||||||
<output id="scrollspeed_out"></output><br>
|
<output id="scrollspeed_out"></output><br>
|
||||||
|
|
||||||
<label for="noteratio">Note ratio</label><br>
|
<label for="noteratio">Note ratio</label><br>
|
||||||
<input type="range" id="noteratio" min="0" max="1" value="0.5" step="0.1">
|
<input type="range" id="noteratio" min="0" max="1" value="0.5" step="0.1">
|
||||||
<output id="noteratio_out"></output><br>
|
<output id="noteratio_out"></output><br>
|
||||||
|
|
||||||
<label for="keycount">Key count</label><br>
|
<label for="keycount">Key count</label><br>
|
||||||
<input type="range" id="keycount" min="4" max="9" value="7">
|
<input type="range" id="keycount" min="4" max="9" value="7">
|
||||||
<output id="keycount_out"></output><br>
|
<output id="keycount_out"></output><br>
|
||||||
@@ -1,112 +1,112 @@
|
|||||||
var canvas;
|
var canvas;
|
||||||
var ctx;
|
var ctx;
|
||||||
|
|
||||||
/* Base resolution in osu! skins used for scaling */
|
/* Base resolution in osu! skins used for scaling */
|
||||||
const internal_width = 640;
|
const internal_width = 640;
|
||||||
const internal_height = 480;
|
const internal_height = 480;
|
||||||
|
|
||||||
/* Updates per second */
|
/* Updates per second */
|
||||||
const framerate = 60;
|
const framerate = 60;
|
||||||
|
|
||||||
/* Colors for playfield */
|
/* Colors for playfield */
|
||||||
const colors = {
|
const colors = {
|
||||||
playfield: "#000",
|
playfield: "#000",
|
||||||
lane_separator: "#222",
|
lane_separator: "#222",
|
||||||
hitposition: "#AA0",
|
hitposition: "#AA0",
|
||||||
note: "#FFF"
|
note: "#FFF"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Values retrieved from DOM */
|
/* Values retrieved from DOM */
|
||||||
var options = {
|
var options = {
|
||||||
columnstart: 0,
|
columnstart: 0,
|
||||||
columnwidth: 0,
|
columnwidth: 0,
|
||||||
hitposition: 0,
|
hitposition: 0,
|
||||||
scrollspeed: 0,
|
scrollspeed: 0,
|
||||||
noteratio: 0,
|
noteratio: 0,
|
||||||
keycount: 0
|
keycount: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clears the canvas */
|
/* Clears the canvas */
|
||||||
function clear() {
|
function clear() {
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draws a rectangle */
|
/* Draws a rectangle */
|
||||||
function rect(x, y, w, h, color) {
|
function rect(x, y, w, h, color) {
|
||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
ctx.fillRect(x, y, w, h);
|
ctx.fillRect(x, y, w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draws a string */
|
/* Draws a string */
|
||||||
function text(string, x, y, color) {
|
function text(string, x, y, color) {
|
||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
ctx.fillText(string, x, y);
|
ctx.fillText(string, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translates osu! coordinates to screen coordinates */
|
/* Translates osu! coordinates to screen coordinates */
|
||||||
function translate_pos(x, y) {
|
function translate_pos(x, y) {
|
||||||
return {
|
return {
|
||||||
x: Math.floor(x / internal_width * canvas.width),
|
x: Math.floor(x / internal_width * canvas.width),
|
||||||
y: Math.floor(y / internal_height * canvas.height)
|
y: Math.floor(y / internal_height * canvas.height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw() {
|
function draw() {
|
||||||
clear()
|
clear()
|
||||||
|
|
||||||
const columnstart = translate_pos(options.columnstart, 0);
|
const columnstart = translate_pos(options.columnstart, 0);
|
||||||
const columnwidth = translate_pos(options.columnwidth, 0);
|
const columnwidth = translate_pos(options.columnwidth, 0);
|
||||||
const hitposition = translate_pos(options.columnstart, options.hitposition);
|
const hitposition = translate_pos(options.columnstart, options.hitposition);
|
||||||
|
|
||||||
const playfield_width = columnwidth.x * options.keycount;
|
const playfield_width = columnwidth.x * options.keycount;
|
||||||
const note_height = columnwidth.x * options.noteratio;
|
const note_height = columnwidth.x * options.noteratio;
|
||||||
|
|
||||||
// playfield background
|
// playfield background
|
||||||
rect(columnstart.x, 0, playfield_width, canvas.height, colors.playfield);
|
rect(columnstart.x, 0, playfield_width, canvas.height, colors.playfield);
|
||||||
|
|
||||||
// lane separators
|
// lane separators
|
||||||
for (var i = 0; i <= options.keycount; i++) {
|
for (var i = 0; i <= options.keycount; i++) {
|
||||||
rect(columnstart.x + i * columnwidth.x, 0, 1, canvas.height, colors.lane_separator);
|
rect(columnstart.x + i * columnwidth.x, 0, 1, canvas.height, colors.lane_separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hitpos
|
// hitpos
|
||||||
rect(hitposition.x, hitposition.y, playfield_width, 5, colors.hitposition);
|
rect(hitposition.x, hitposition.y, playfield_width, 5, colors.hitposition);
|
||||||
|
|
||||||
// notes
|
// notes
|
||||||
let y_pos = hitposition.y - note_height;
|
let y_pos = hitposition.y - note_height;
|
||||||
while (y_pos > 0) {
|
while (y_pos > 0) {
|
||||||
for (let i = 0; i < options.keycount; ++i) {
|
for (let i = 0; i < options.keycount; ++i) {
|
||||||
rect (
|
rect (
|
||||||
columnstart.x + i * columnwidth.x,
|
columnstart.x + i * columnwidth.x,
|
||||||
y_pos,
|
y_pos,
|
||||||
columnwidth.x, note_height, colors.note
|
columnwidth.x, note_height, colors.note
|
||||||
);
|
);
|
||||||
|
|
||||||
// completely inaccurate but i cba to simulate the whole playfield
|
// completely inaccurate but i cba to simulate the whole playfield
|
||||||
y_pos -= options.scrollspeed * 3;
|
y_pos -= options.scrollspeed * 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
create_prologue();
|
create_prologue();
|
||||||
|
|
||||||
canvas = document.getElementById("playfield");
|
canvas = document.getElementById("playfield");
|
||||||
ctx = canvas.getContext("2d");
|
ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
ctx.font = "15px Arial";
|
ctx.font = "15px Arial";
|
||||||
ctx.textBaseline = "hanging";
|
ctx.textBaseline = "hanging";
|
||||||
|
|
||||||
for (let input of document.getElementsByTagName("input")) {
|
for (let input of document.getElementsByTagName("input")) {
|
||||||
input.onchange = function () {
|
input.onchange = function () {
|
||||||
options[this.id] = this.value;
|
options[this.id] = this.value;
|
||||||
document.getElementById(this.id + "_out").innerText = this.value;
|
document.getElementById(this.id + "_out").innerText = this.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
input.onchange();
|
input.onchange();
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(function () {
|
setInterval(function () {
|
||||||
draw();
|
draw();
|
||||||
}, 1000 / framerate);
|
}, 1000 / framerate);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>Reaction time test</title>
|
<title>Reaction time test</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../style.css">
|
<link rel="stylesheet" href="../style.css">
|
||||||
<link rel="stylesheet" href="area.css">
|
<link rel="stylesheet" href="area.css">
|
||||||
<script src="../shared.js"></script>
|
<script src="../shared.js"></script>
|
||||||
<script src="reaction.js"></script>
|
<script src="reaction.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<div id="area"></div>
|
<div id="area"></div>
|
||||||
<h3 id="average"></h3>
|
<h3 id="average"></h3>
|
||||||
<ul id="times"></ul>
|
<ul id="times"></ul>
|
||||||
@@ -1,88 +1,88 @@
|
|||||||
|
|
||||||
const states = {
|
const states = {
|
||||||
START: 'start',
|
START: 'start',
|
||||||
TIMEOUT: 'timeout',
|
TIMEOUT: 'timeout',
|
||||||
READY: 'ready'
|
READY: 'ready'
|
||||||
}
|
}
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
TIMEOUT: 'crimson',
|
TIMEOUT: 'crimson',
|
||||||
START: 'dodgerblue',
|
START: 'dodgerblue',
|
||||||
READY: 'limegreen'
|
READY: 'limegreen'
|
||||||
}
|
}
|
||||||
|
|
||||||
var state = states.START;
|
var state = states.START;
|
||||||
var times = [];
|
var times = [];
|
||||||
|
|
||||||
var ready_time;
|
var ready_time;
|
||||||
var ready_id; // timeout id
|
var ready_id; // timeout id
|
||||||
|
|
||||||
const min_time = 1000;
|
const min_time = 1000;
|
||||||
const max_time = 3000;
|
const max_time = 3000;
|
||||||
|
|
||||||
function handle_click() {
|
function handle_click() {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
// click received on start, activate timer and set state to timeout
|
// click received on start, activate timer and set state to timeout
|
||||||
case states.START: {
|
case states.START: {
|
||||||
|
|
||||||
// this is a hack to access thisptr from setTimeout
|
// this is a hack to access thisptr from setTimeout
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
ready_id = setTimeout(function () {
|
ready_id = setTimeout(function () {
|
||||||
ready_time = Date.now();
|
ready_time = Date.now();
|
||||||
|
|
||||||
self.style["background-color"] = colors.READY;
|
self.style["background-color"] = colors.READY;
|
||||||
self.innerText = "Click now!";
|
self.innerText = "Click now!";
|
||||||
|
|
||||||
state = states.READY;
|
state = states.READY;
|
||||||
}, min_time + (Math.random() * (max_time - min_time)));
|
}, min_time + (Math.random() * (max_time - min_time)));
|
||||||
|
|
||||||
this.style["background-color"] = colors.TIMEOUT;
|
this.style["background-color"] = colors.TIMEOUT;
|
||||||
this.innerText = "Get ready!";
|
this.innerText = "Get ready!";
|
||||||
|
|
||||||
state = states.TIMEOUT;
|
state = states.TIMEOUT;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// click received during timeout, clear timeout and reset
|
// click received during timeout, clear timeout and reset
|
||||||
case states.TIMEOUT: {
|
case states.TIMEOUT: {
|
||||||
clearTimeout(ready_id);
|
clearTimeout(ready_id);
|
||||||
|
|
||||||
this.style["background-color"] = colors.START;
|
this.style["background-color"] = colors.START;
|
||||||
this.innerText = "Too early!";
|
this.innerText = "Too early!";
|
||||||
|
|
||||||
state = states.START;
|
state = states.START;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// click received after timeout, calculate score and reset
|
// click received after timeout, calculate score and reset
|
||||||
case states.READY: {
|
case states.READY: {
|
||||||
let time = (Date.now() - ready_time);
|
let time = (Date.now() - ready_time);
|
||||||
times.push(time);
|
times.push(time);
|
||||||
|
|
||||||
let average = times.reduce((a, b) => a + b) / times.length;
|
let average = times.reduce((a, b) => a + b) / times.length;
|
||||||
|
|
||||||
// update average text
|
// update average text
|
||||||
document.getElementById("average").innerText = "Average: " + average + "ms";
|
document.getElementById("average").innerText = "Average: " + average + "ms";
|
||||||
|
|
||||||
// create and add time listing
|
// create and add time listing
|
||||||
var li = document.createElement("li");
|
var li = document.createElement("li");
|
||||||
li.appendChild(document.createTextNode(time + "ms"));
|
li.appendChild(document.createTextNode(time + "ms"));
|
||||||
document.getElementById("times").appendChild(li);
|
document.getElementById("times").appendChild(li);
|
||||||
|
|
||||||
this.style["background-color"] = colors.START;
|
this.style["background-color"] = colors.START;
|
||||||
this.innerText = time + "ms";
|
this.innerText = time + "ms";
|
||||||
|
|
||||||
state = states.START;
|
state = states.START;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
create_prologue();
|
create_prologue();
|
||||||
|
|
||||||
let area = document.getElementById("area");
|
let area = document.getElementById("area");
|
||||||
area.innerText = "Click here to begin!";
|
area.innerText = "Click here to begin!";
|
||||||
area.onclick = handle_click;
|
area.onclick = handle_click;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
body {
|
body {
|
||||||
color: #444;
|
color: #444;
|
||||||
font: 18px/1.6 Arial, Helvetica, sans-serif;
|
font: 18px/1.6 Arial, Helvetica, sans-serif;
|
||||||
margin: 40px auto;
|
margin: 40px auto;
|
||||||
max-width: 650px;
|
max-width: 650px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
h3 {
|
h3 {
|
||||||
line-height: 1.2
|
line-height: 1.2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>Trill test</title>
|
<title>Trill test</title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../style.css">
|
<link rel="stylesheet" href="../style.css">
|
||||||
<link rel="stylesheet" href="area.css">
|
<link rel="stylesheet" href="area.css">
|
||||||
<script src="../shared.js"></script>
|
<script src="../shared.js"></script>
|
||||||
<script src="trill.js"></script>
|
<script src="trill.js"></script>
|
||||||
|
|
||||||
|
|
||||||
<div id="area"></div>
|
<div id="area"></div>
|
||||||
<h3 id="average"></h3>
|
<h3 id="average"></h3>
|
||||||
<ul id="times"></ul>
|
<ul id="times"></ul>
|
||||||
@@ -1,102 +1,102 @@
|
|||||||
|
|
||||||
const states = {
|
const states = {
|
||||||
GETKEYS: 'getkeys',
|
GETKEYS: 'getkeys',
|
||||||
TRILLING: 'trilling',
|
TRILLING: 'trilling',
|
||||||
READY: 'ready',
|
READY: 'ready',
|
||||||
RESULT: 'result'
|
RESULT: 'result'
|
||||||
}
|
}
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
GETKEYS: 'gray',
|
GETKEYS: 'gray',
|
||||||
TRILLING: 'crimson',
|
TRILLING: 'crimson',
|
||||||
READY: 'darkgray',
|
READY: 'darkgray',
|
||||||
RESULT: 'dodgerblue'
|
RESULT: 'dodgerblue'
|
||||||
}
|
}
|
||||||
|
|
||||||
var state = states.GETKEYS;
|
var state = states.GETKEYS;
|
||||||
var times = []
|
var times = []
|
||||||
|
|
||||||
const max_count = 20;
|
const max_count = 20;
|
||||||
|
|
||||||
var key1, key2;
|
var key1, key2;
|
||||||
var time_start;
|
var time_start;
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
|
|
||||||
function handle_press(e) {
|
function handle_press(e) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case states.GETKEYS: {
|
case states.GETKEYS: {
|
||||||
if (!key1) {
|
if (!key1) {
|
||||||
key1 = e.code;
|
key1 = e.code;
|
||||||
|
|
||||||
area.style["background-color"] = colors.GETKEYS;
|
area.style["background-color"] = colors.GETKEYS;
|
||||||
area.innerText = "Press 2nd key!";
|
area.innerText = "Press 2nd key!";
|
||||||
} else {
|
} else {
|
||||||
key2 = e.code;
|
key2 = e.code;
|
||||||
state = states.READY;
|
state = states.READY;
|
||||||
|
|
||||||
area.style["background-color"] = colors.READY;
|
area.style["background-color"] = colors.READY;
|
||||||
area.innerText = "Test will start on first keypress.";
|
area.innerText = "Test will start on first keypress.";
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case states.READY: {
|
case states.READY: {
|
||||||
if (e.code == key1 || e.code == key2) {
|
if (e.code == key1 || e.code == key2) {
|
||||||
state = states.TRILLING;
|
state = states.TRILLING;
|
||||||
|
|
||||||
time_start = Date.now();
|
time_start = Date.now();
|
||||||
|
|
||||||
area.style["background-color"] = colors.TRILLING;
|
area.style["background-color"] = colors.TRILLING;
|
||||||
handle_press(e); // update couter/text for first keypress
|
handle_press(e); // update couter/text for first keypress
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case states.TRILLING: {
|
case states.TRILLING: {
|
||||||
if (e.code == key1 || e.code == key2) {
|
if (e.code == key1 || e.code == key2) {
|
||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
area.innerText = counter + "/" + max_count;
|
area.innerText = counter + "/" + max_count;
|
||||||
|
|
||||||
if (counter == max_count) {
|
if (counter == max_count) {
|
||||||
state = states.RESULT;
|
state = states.RESULT;
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
let time = parseInt((max_count / ((Date.now() - time_start) / 1000) * 60 / 4));
|
let time = parseInt((max_count / ((Date.now() - time_start) / 1000) * 60 / 4));
|
||||||
times.push(time);
|
times.push(time);
|
||||||
|
|
||||||
let average = times.reduce((a, b) => a + b) / times.length;
|
let average = times.reduce((a, b) => a + b) / times.length;
|
||||||
|
|
||||||
document.getElementById("average").innerText = "Average: " + average + "bpm";
|
document.getElementById("average").innerText = "Average: " + average + "bpm";
|
||||||
|
|
||||||
var li = document.createElement("li");
|
var li = document.createElement("li");
|
||||||
li.appendChild(document.createTextNode(time + "bpm"));
|
li.appendChild(document.createTextNode(time + "bpm"));
|
||||||
document.getElementById("times").appendChild(li);
|
document.getElementById("times").appendChild(li);
|
||||||
|
|
||||||
area.style["background-color"] = colors.RESULT;
|
area.style["background-color"] = colors.RESULT;
|
||||||
area.innerText = time + "bpm" + '\n(press space to try again)';
|
area.innerText = time + "bpm" + '\n(press space to try again)';
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case states.RESULT: {
|
case states.RESULT: {
|
||||||
if (e.code == "Space") {
|
if (e.code == "Space") {
|
||||||
state = states.READY;
|
state = states.READY;
|
||||||
|
|
||||||
area.style["background-color"] = colors.READY;
|
area.style["background-color"] = colors.READY;
|
||||||
area.innerText = "Test will start on first keypress.";
|
area.innerText = "Test will start on first keypress.";
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
create_prologue();
|
create_prologue();
|
||||||
|
|
||||||
area = document.getElementById("area");
|
area = document.getElementById("area");
|
||||||
area.innerText = "Press 1st key!";
|
area.innerText = "Press 1st key!";
|
||||||
|
|
||||||
document.addEventListener('keydown', handle_press);
|
document.addEventListener('keydown', handle_press);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user