added executable
This commit is contained in:
parent
15e5ec9c18
commit
83ff9d58c3
8 changed files with 172 additions and 87 deletions
30
README.md
30
README.md
|
@ -13,6 +13,36 @@ _Fasttyper_ is currently maintained on [PyPi](https://pypi.org/) Python Package
|
|||
|
||||
# Usage
|
||||
|
||||
With installation of fasttyper you should have new executable - `fasttyper`. It takes two optional positional arguments, amount of words and language (like in monkeytype: english, english_1k etc).
|
||||
|
||||
Avalibe options:
|
||||
|
||||
```
|
||||
usage: fasttyper [-h] [--config FILE] [--unclutter-backspace] [--no-cursor] [amount] [language]
|
||||
|
||||
positional arguments:
|
||||
amount Amount of words
|
||||
language Language
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--config FILE, -c FILE
|
||||
configuration file
|
||||
--unclutter-backspace, -b
|
||||
unclutter backspace, when it raises ctrl+backspace instead
|
||||
--no-cursor, -n disable cursos
|
||||
```
|
||||
|
||||
I personally use alias:
|
||||
|
||||
```
|
||||
alias ff='fasttyper -n`
|
||||
```
|
||||
|
||||
because i don't like having cursor.
|
||||
|
||||
# Usage as module, piping stuff, custom scripts etc
|
||||
|
||||
_Fasttyper_ is ran as an python module, so to execute it simply type:
|
||||
|
||||
`python3 -m fasttyper`
|
||||
|
|
|
@ -1,81 +1,15 @@
|
|||
from .application import Application
|
||||
from .interface import Interface
|
||||
from .components import (
|
||||
CursorComponent,
|
||||
StatsComponent,
|
||||
TextBox,
|
||||
TopMargin,
|
||||
)
|
||||
from .listener import Listener
|
||||
from .buffer import UserBuffer, Buffer
|
||||
from .config import Config
|
||||
from curses import wrapper
|
||||
from .cli import initialize, get_parser
|
||||
import sys
|
||||
import io
|
||||
import os
|
||||
import argparse
|
||||
import json
|
||||
|
||||
|
||||
def initialize(configmap, rbuffer, backspace_debug, no_cursor):
|
||||
config = Config(configmap)
|
||||
|
||||
reference_buffer = Buffer(rbuffer)
|
||||
user_buffer = UserBuffer()
|
||||
|
||||
top_margin = TopMargin(config)
|
||||
cursor_component = CursorComponent(config)
|
||||
text_box = TextBox(config, cursor_component)
|
||||
stats_component = StatsComponent(config)
|
||||
|
||||
listener = Listener(backspace_debug)
|
||||
application = Application(listener, user_buffer, reference_buffer, config)
|
||||
|
||||
interface = Interface(
|
||||
application,
|
||||
[
|
||||
top_margin,
|
||||
text_box,
|
||||
stats_component,
|
||||
cursor_component,
|
||||
],
|
||||
no_cursor,
|
||||
)
|
||||
wrapper(interface)
|
||||
|
||||
application.summarize()
|
||||
application.exit()
|
||||
|
||||
|
||||
def main():
|
||||
is_tty = sys.stdin.isatty()
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser = get_parser()
|
||||
|
||||
if is_tty:
|
||||
parser.add_argument("file", metavar="FILE", help="file to type")
|
||||
|
||||
parser.add_argument(
|
||||
"--config",
|
||||
"-c",
|
||||
metavar="FILE",
|
||||
help="configuration file",
|
||||
default="~/.config/fasttyper/config.json",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--unclutter-backspace",
|
||||
"-b",
|
||||
action="store_true",
|
||||
help="unclutter backspace, when it raises ctrl+backspace instead",
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-cursor",
|
||||
"-n",
|
||||
action="store_true",
|
||||
help="disable cursos",
|
||||
default=False,
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if is_tty:
|
||||
|
@ -89,13 +23,7 @@ def main():
|
|||
|
||||
rbuffer = "".join(input_lines)
|
||||
|
||||
try:
|
||||
with open(os.path.expanduser(args.config)) as f:
|
||||
configmap = json.load(f)
|
||||
except FileNotFoundError:
|
||||
configmap = {}
|
||||
|
||||
initialize(configmap, rbuffer, args.unclutter_backspace, args.no_cursor)
|
||||
initialize(args.config, rbuffer, args.unclutter_backspace, args.no_cursor)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -58,9 +58,7 @@ class Application:
|
|||
input()
|
||||
|
||||
def exit(self):
|
||||
if self.finished or self.silent_exit:
|
||||
sys.exit(0)
|
||||
else:
|
||||
if not self.finished and not self.silent_exit:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
|
77
fasttyper/cli.py
Normal file
77
fasttyper/cli.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
from .application import Application
|
||||
from .interface import Interface
|
||||
from .components import (
|
||||
CursorComponent,
|
||||
StatsComponent,
|
||||
TextBox,
|
||||
TopMargin,
|
||||
)
|
||||
from .listener import Listener
|
||||
from .buffer import UserBuffer, Buffer
|
||||
from .config import Config
|
||||
from curses import wrapper
|
||||
import os
|
||||
import argparse
|
||||
import json
|
||||
|
||||
|
||||
def initialize(config_path, rbuffer, backspace_debug, no_cursor):
|
||||
try:
|
||||
with open(os.path.expanduser(config_path)) as f:
|
||||
configmap = json.load(f)
|
||||
except FileNotFoundError:
|
||||
configmap = {}
|
||||
|
||||
config = Config(configmap)
|
||||
|
||||
reference_buffer = Buffer(rbuffer)
|
||||
user_buffer = UserBuffer()
|
||||
|
||||
top_margin = TopMargin(config)
|
||||
cursor_component = CursorComponent(config)
|
||||
text_box = TextBox(config, cursor_component)
|
||||
stats_component = StatsComponent(config)
|
||||
|
||||
listener = Listener(backspace_debug)
|
||||
application = Application(listener, user_buffer, reference_buffer, config)
|
||||
|
||||
interface = Interface(
|
||||
application,
|
||||
[
|
||||
top_margin,
|
||||
text_box,
|
||||
stats_component,
|
||||
cursor_component,
|
||||
],
|
||||
no_cursor,
|
||||
)
|
||||
wrapper(interface)
|
||||
|
||||
application.summarize()
|
||||
application.exit()
|
||||
|
||||
|
||||
def get_parser():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--config",
|
||||
"-c",
|
||||
metavar="FILE",
|
||||
help="configuration file",
|
||||
default="~/.config/fasttyper/config.json",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--unclutter-backspace",
|
||||
"-b",
|
||||
action="store_true",
|
||||
help="unclutter backspace, when it raises ctrl+backspace instead",
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-cursor",
|
||||
"-n",
|
||||
action="store_true",
|
||||
help="disable cursos",
|
||||
default=False,
|
||||
)
|
||||
return parser
|
|
@ -14,7 +14,7 @@ class Action(enum.Enum):
|
|||
class Listener:
|
||||
def __init__(self, backspace_debug=False):
|
||||
self.tabbed = False
|
||||
self.backspace_debug = backspace_debug
|
||||
self.backspace_debug = not backspace_debug
|
||||
|
||||
def handle_key(self, key):
|
||||
action = Action.invalid
|
||||
|
|
55
fasttyper/runner.py
Normal file
55
fasttyper/runner.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from .cli import initialize, get_parser
|
||||
from random import choice
|
||||
import os
|
||||
import requests
|
||||
import pathlib
|
||||
|
||||
|
||||
MONKEYTYPE_WORDS_PATT = "https://raw.githubusercontent.com/Miodec/monkeytype/master/frontend/static/languages/{language}.json"
|
||||
|
||||
|
||||
def get_words(language):
|
||||
home = os.environ.get("HOME", "")
|
||||
sfile = os.path.join(home, ".cache", "fasttyper", language)
|
||||
words = None
|
||||
|
||||
try:
|
||||
with open(sfile) as f:
|
||||
words = f.read().splitlines()
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
if words is None:
|
||||
source_path = MONKEYTYPE_WORDS_PATT.format(language=language)
|
||||
|
||||
words = requests.get(source_path).json()["words"]
|
||||
|
||||
p = pathlib.Path(os.path.join(home, ".cache", "fasttyper"))
|
||||
p.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(sfile, "w") as f:
|
||||
f.write("\n".join(words))
|
||||
|
||||
return words
|
||||
|
||||
|
||||
def runner():
|
||||
parser = get_parser()
|
||||
|
||||
parser.add_argument(
|
||||
"amount", type=int, default=25, help="Amount of words", nargs="?"
|
||||
)
|
||||
parser.add_argument(
|
||||
"language", type=str, default="english", help="Language", nargs="?"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
words = get_words(args.language)
|
||||
|
||||
while True:
|
||||
rbuffer = " ".join([choice(words) for _ in range(args.amount)])
|
||||
initialize(args.config, rbuffer, args.unclutter_backspace, args.no_cursor)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
runner()
|
|
@ -1,8 +0,0 @@
|
|||
[bumpversion]
|
||||
current_version = 1.5.2
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
||||
|
||||
[metadata]
|
||||
description-file = README.md
|
5
setup.py
5
setup.py
|
@ -19,4 +19,9 @@ setup(
|
|||
],
|
||||
packages=find_packages(),
|
||||
python_requires=">=3.6",
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"fasttyper=fasttyper.runner:runner",
|
||||
]
|
||||
},
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue