mirror of
https://github.com/LazoCoder/Pokemon-Terminal
synced 2024-11-27 06:10:29 +00:00
Merges the new command engine
Command engine rework into master!
This commit is contained in:
commit
978b221c70
19 changed files with 440 additions and 463 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -150,4 +150,7 @@ fabric.properties
|
||||||
# .idea/misc.xml
|
# .idea/misc.xml
|
||||||
# *.ipr
|
# *.ipr
|
||||||
|
|
||||||
|
# VSCode
|
||||||
|
.vscode/
|
||||||
|
|
||||||
# End of https://www.gitignore.io/api/osx,python,pycharm
|
# End of https://www.gitignore.io/api/osx,python,pycharm
|
||||||
|
|
|
@ -2,7 +2,7 @@ sudo: false
|
||||||
dist: trusty
|
dist: trusty
|
||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- 3.5 # currently Travis trusty default Python3 is 3.5.2
|
- 3.6 # currently Travis trusty default Python3 is 3.5.2
|
||||||
#- 3.6.1
|
#- 3.6.1
|
||||||
#- "nightly" # currently points to 3.7-dev (3.7.0a0)
|
#- "nightly" # currently points to 3.7-dev (3.7.0a0)
|
||||||
install:
|
install:
|
||||||
|
|
80
README.md
80
README.md
|
@ -26,7 +26,7 @@ Sample Set #1 | Sample Set #2
|
||||||
|
|
||||||
# How to Install
|
# How to Install
|
||||||
|
|
||||||
Type `python3 -V` in your terminal to verify that you have [Python 3.5](https://www.python.org/downloads/) or later installed.
|
Type `python3 -V` in your terminal to verify that you have [Python 3.6](https://www.python.org/downloads/) or later installed.
|
||||||
|
|
||||||
## npm
|
## npm
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ You can install in any (npm-supported) OS using `npm install --global pokemon-te
|
||||||
|
|
||||||
## Mac OS
|
## Mac OS
|
||||||
|
|
||||||
1. Make sure you have [Python 3.5](https://www.python.org/downloads/mac-osx/) or higher.
|
1. Make sure you have [Python 3.6](https://www.python.org/downloads/mac-osx/) or higher.
|
||||||
2. Make sure you have [iTerm2](http://www.iterm2.com/downloads.html).
|
2. Make sure you have [iTerm2](http://www.iterm2.com/downloads.html).
|
||||||
3. Copy and paste the following for the installation:
|
3. Copy and paste the following for the installation:
|
||||||
```
|
```
|
||||||
|
@ -55,7 +55,7 @@ You can install in any (npm-supported) OS using `npm install --global pokemon-te
|
||||||
|
|
||||||
## Linux
|
## Linux
|
||||||
|
|
||||||
1. Make sure you have Python 3.5+ installed, check the instructions of your distribution.
|
1. Make sure you have Python 3.6+ installed, check the instructions of your distribution.
|
||||||
2. Make sure you have Terminology or Tilix, again check the package manager of your distribution.
|
2. Make sure you have Terminology or Tilix, again check the package manager of your distribution.
|
||||||
3. Install
|
3. Install
|
||||||
- If you are a Arch Linux User, you can install it from the AUR package [pokemon-terminal-git](https://aur.archlinux.org/packages/pokemon-terminal-git/).
|
- If you are a Arch Linux User, you can install it from the AUR package [pokemon-terminal-git](https://aur.archlinux.org/packages/pokemon-terminal-git/).
|
||||||
|
@ -71,44 +71,45 @@ You can install in any (npm-supported) OS using `npm install --global pokemon-te
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
```
|
```
|
||||||
|
usage: pokemon [-h] [-n NAME] [-r {kanto,johto,hoenn,sinnoh}] [-l [0.xx]]
|
||||||
|
[-d [0.xx]]
|
||||||
|
[-t {normal,fire,fighting,water,flying,grass,poison,electric,
|
||||||
|
ground,psychic,rock,ice,bug,dragon,ghost,dark,steel,fairy}]
|
||||||
|
[-ne] [-e] [-w] [-v] [-dr] [-c] [id]
|
||||||
|
|
||||||
Usage:
|
Set a pokemon to the current terminal background or wallpaper
|
||||||
pokemon [parameter]
|
|
||||||
ichooseyou [parameter]
|
|
||||||
|
|
||||||
Parameters:
|
positional arguments:
|
||||||
[name] - Change the terminal background to the specified Pokemon.
|
id Specify the desired pokemon ID
|
||||||
[index] - Change the terminal background to a Pokemon by its index.
|
|
||||||
[region] - List all the Pokemon of the specified region.
|
|
||||||
[one letter] - List all Pokemon who's names begin with a particular letter.
|
|
||||||
[two letters] - List all Pokemon who's names begin with those two letters.
|
|
||||||
|
|
||||||
Other Parameters:
|
optional arguments:
|
||||||
all - List all the Pokemon supported.
|
-h, --help show this help message and exit
|
||||||
regions - List all the available regions.
|
-c, --clear Clears the current pokemon from terminal background
|
||||||
extra - List all the Pokemon from the 'Extra' folder.
|
and quits.
|
||||||
random - Change the terminal background to a random Pokemon.
|
|
||||||
random-<region> - Change the terminal background to a random Pokemon from the specified region.
|
|
||||||
slideshow [time] - Iterate through each Pokemon. Optional time (in seconds) between Pokemon.
|
|
||||||
slideshow-<region> [time] - Iterate through each Pokemon in the specified region. Optional time (in seconds) between Pokemon.
|
|
||||||
rnd-slideshow [time] - Iterate through each Pokemon in a random order. Optional time (in seconds) between Pokemon.
|
|
||||||
rnd-slideshow-<region> [time] - Iterate through each Pokemon in the specified region in a random order. Optional time (in seconds) between Pokemon.
|
|
||||||
light - Change the terminal background to a random light-colored Pokemon.
|
|
||||||
dark - Change the terminal background to a random dark-colored Pokemon.
|
|
||||||
type [type] - Change to a random pokemon of said type.
|
|
||||||
clear | disable | off - Clear the Pokemon in the terminal.
|
|
||||||
help - Display this menu.
|
|
||||||
|
|
||||||
Wallpaper Parameters:
|
Filters:
|
||||||
pokemon _pikachu - Change the wallpaper to the specified Pokemon.
|
Arguments used to filter the list of pokemons with various conditions
|
||||||
pokemon _random - Change the wallpaper to a random Pokemon.
|
|
||||||
pokemon _random-kanto - Change the wallpaper to a random Pokemon from the specified region.
|
|
||||||
|
|
||||||
Search System Information:
|
-n/--name NAME Filter by pokemon which name contains NAME
|
||||||
Any input containing 3 or more characters triggers the internal search system. Examples:
|
-r/--region {kanto,johto,hoenn,sinnoh}
|
||||||
"pokemon pika" changes the terminal background to Pikachu.
|
Filter the pokemons by region
|
||||||
"pokemon dos" changes the terminal background to Gyarados.
|
-l/--light [0.xx] Filter out the pokemons darker then 0.xx
|
||||||
|
-d/--dark [0.xx]
|
||||||
|
Filter out the pokemons lighter then 0.xx
|
||||||
|
-t/--type {normal,fire,fighting,water,flying,grass,poison,electric,ground,
|
||||||
|
psychic,rock,ice,bug,dragon,ghost,dark,steel,fairy}
|
||||||
|
Filter the pokemons by type.
|
||||||
|
-ne/--no-extras Excludes extra pokemons
|
||||||
|
-e/--extras Excludes all non-extra pokemons
|
||||||
|
|
||||||
|
Misc:
|
||||||
|
-w, --wallpaper Changes the desktop wallpapper instead of the terminal
|
||||||
|
background
|
||||||
|
-v, --verbose Enables verbose output
|
||||||
|
-dr, --dry-run Implies -v and doesn't actually changes the wallpapper
|
||||||
|
or background after the pokemon has been chosen
|
||||||
|
|
||||||
|
Not setting any filters will get a completly random pokemon
|
||||||
```
|
```
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
@ -135,7 +136,7 @@ The result should look like this:
|
||||||
|
|
||||||
The folder *Images/Extra* is for adding custom images. You can manually add backgrounds to this folder and they will be visible to the program. Only JPG format is supported. To see a list of all the custom backgrounds type:
|
The folder *Images/Extra* is for adding custom images. You can manually add backgrounds to this folder and they will be visible to the program. Only JPG format is supported. To see a list of all the custom backgrounds type:
|
||||||
```
|
```
|
||||||
$ pokemon extra
|
$ pokemon -e -dr
|
||||||
```
|
```
|
||||||
Alternatively, you can delete images from this folder and it will not break the program. These are some custom backgrounds:
|
Alternatively, you can delete images from this folder and it will not break the program. These are some custom backgrounds:
|
||||||
|
|
||||||
|
@ -161,8 +162,8 @@ Alternatively, you can delete images from this folder and it will not break the
|
||||||
I have not yet implemented a way to save the terminal background to a profile. To save a background you will need to setup a startup command in the profile.
|
I have not yet implemented a way to save the terminal background to a profile. To save a background you will need to setup a startup command in the profile.
|
||||||
1. Navigate to iTerm2 > Preferences > General
|
1. Navigate to iTerm2 > Preferences > General
|
||||||
2. Locate the field where it says *Send text at start* under *Command*.
|
2. Locate the field where it says *Send text at start* under *Command*.
|
||||||
3. In that field type "pokemon [pokemon name]". You can see an example in the image down below.
|
3. In that field type "pokemon -n [pokemon name]". You can see an example in the image down below.
|
||||||
- Alternatively you can also type "pokemon random" for a random theme each time you open up a new terminal.
|
- Alternatively you can also type "pokemon" for a random theme each time you open up a new terminal.
|
||||||
4. You can leave out "; clear" if you don't care about the line showing up at the top of the terminal.
|
4. You can leave out "; clear" if you don't care about the line showing up at the top of the terminal.
|
||||||
|
|
||||||
![alt-tag](Samples/saving.png)
|
![alt-tag](Samples/saving.png)
|
||||||
|
@ -182,9 +183,10 @@ fi
|
||||||
3. You may also want to check if terminology is actually running before trying to set the background, so that leads us to
|
3. You may also want to check if terminology is actually running before trying to set the background, so that leads us to
|
||||||
```bash
|
```bash
|
||||||
if [[ "$TERMINOLOGY" -eq "1" ]]; then
|
if [[ "$TERMINOLOGY" -eq "1" ]]; then
|
||||||
pokemon random
|
pokemon
|
||||||
fi
|
fi
|
||||||
```
|
```
|
||||||
|
That will simply pick a completly random pokemon each session, but the `pokemon` line is simply calling the app, so you can still filter with regions, darkness, and etc. like you normally would, or you can also reset to a preset pokemon everytime you start.
|
||||||
|
|
||||||
# Notes & Credits
|
# Notes & Credits
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pokemon-terminal",
|
"name": "pokemon-terminal",
|
||||||
"version": "1.0.7",
|
"version": "1.1.0",
|
||||||
"description": "Pokemon terminal themes",
|
"description": "Pokemon terminal themes",
|
||||||
"bin": {
|
"bin": {
|
||||||
"pokemon": "pokemon",
|
"pokemon": "pokemon",
|
||||||
|
|
2
pokemon
2
pokemon
|
@ -5,4 +5,4 @@ import sys
|
||||||
from pokemonterminal.main import main
|
from pokemonterminal.main import main
|
||||||
|
|
||||||
|
|
||||||
main(sys.argv)
|
main(sys.argv[1:])
|
||||||
|
|
|
@ -18,7 +18,8 @@ class ITerm(TerminalAdapterInterface):
|
||||||
return os.environ.get("ITERM_PROFILE")
|
return os.environ.get("ITERM_PROFILE")
|
||||||
|
|
||||||
def __run_osascript(self, stream):
|
def __run_osascript(self, stream):
|
||||||
p = subprocess.Popen(['osascript'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
|
p = subprocess.Popen(['osascript'], stdout=subprocess.PIPE,
|
||||||
|
stdin=subprocess.PIPE)
|
||||||
p.stdin.write(stream)
|
p.stdin.write(stream)
|
||||||
p.communicate()
|
p.communicate()
|
||||||
p.stdin.close()
|
p.stdin.close()
|
||||||
|
|
|
@ -57,20 +57,20 @@ class Pokemon:
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
"""The Database object is a container for all the supported Pokemon."""
|
"""The Database object is a container for all the supported Pokemon."""
|
||||||
__POKEMON_TYPES = ('normal', 'fire', 'fighting', 'water', 'flying',
|
POKEMON_TYPES = ('normal', 'fire', 'fighting', 'water', 'flying',
|
||||||
'grass', 'poison', 'electric', 'ground', 'psychic',
|
'grass', 'poison', 'electric', 'ground', 'psychic',
|
||||||
'rock', 'ice', 'bug', 'dragon', 'ghost', 'dark',
|
'rock', 'ice', 'bug', 'dragon', 'ghost', 'dark',
|
||||||
'steel', 'fairy')
|
'steel', 'fairy')
|
||||||
__directory = "" # The global location of the code.
|
__directory = "" # The global location of the code.
|
||||||
__MAX_ID = 719 # Highest possible Pokemon ID.
|
MAX_ID = 719 # Highest possible Pokemon ID.
|
||||||
__regions = ('kanto', 'johto', 'hoenn', 'sinnoh', 'unova', 'kalos')
|
REGIONS = ('kanto', 'johto', 'hoenn', 'sinnoh', 'unova', 'kalos')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.__pokemon_list = []
|
self.__pokemon_list = []
|
||||||
self.__pokemon_dictionary = {}
|
self.__pokemon_dictionary = {}
|
||||||
self.__pokemon_type_dictionary = {}
|
self.__pokemon_type_dictionary = {}
|
||||||
self.directory = os.path.dirname(os.path.realpath(__file__))
|
self.directory = os.path.dirname(os.path.realpath(__file__))
|
||||||
for pkmn_t in self.__POKEMON_TYPES:
|
for pkmn_t in self.POKEMON_TYPES:
|
||||||
self.__pokemon_type_dictionary[pkmn_t] = []
|
self.__pokemon_type_dictionary[pkmn_t] = []
|
||||||
self.__load_data()
|
self.__load_data()
|
||||||
self.__load_extra()
|
self.__load_extra()
|
||||||
|
@ -90,9 +90,6 @@ class Database:
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self.__pokemon_list)
|
return len(self.__pokemon_list)
|
||||||
|
|
||||||
def get_pokemon_types(self):
|
|
||||||
return [t for t in self.__POKEMON_TYPES]
|
|
||||||
|
|
||||||
def get_pokemon_of_type(self, pkmn_type: str, single: bool = True):
|
def get_pokemon_of_type(self, pkmn_type: str, single: bool = True):
|
||||||
pkmns = self.__pokemon_type_dictionary.get(pkmn_type)
|
pkmns = self.__pokemon_type_dictionary.get(pkmn_type)
|
||||||
if pkmns is None:
|
if pkmns is None:
|
||||||
|
@ -105,10 +102,6 @@ class Database:
|
||||||
# or... return self.__pokemon_list[:]
|
# or... return self.__pokemon_list[:]
|
||||||
# return a copy of self.__pokemon_list
|
# return a copy of self.__pokemon_list
|
||||||
|
|
||||||
def get_regions(self):
|
|
||||||
# Get all the supported regions.
|
|
||||||
return self.__regions
|
|
||||||
|
|
||||||
def get_kanto(self):
|
def get_kanto(self):
|
||||||
# Get all the Pokemon from the Kanto region.
|
# Get all the Pokemon from the Kanto region.
|
||||||
return self.__get_region("kanto")
|
return self.__get_region("kanto")
|
||||||
|
@ -163,7 +156,7 @@ class Database:
|
||||||
def pokemon_id_exists(self, identifier):
|
def pokemon_id_exists(self, identifier):
|
||||||
# Check for Pokemon by ID.
|
# Check for Pokemon by ID.
|
||||||
identifier = int(identifier)
|
identifier = int(identifier)
|
||||||
return 0 < identifier <= self.__MAX_ID
|
return 0 < identifier <= self.MAX_ID
|
||||||
|
|
||||||
def pokemon_name_exists(self, name):
|
def pokemon_name_exists(self, name):
|
||||||
# Check for Pokemon by Name.
|
# Check for Pokemon by Name.
|
||||||
|
@ -200,7 +193,7 @@ class Database:
|
||||||
identifier = int(identifier)
|
identifier = int(identifier)
|
||||||
if not self.pokemon_id_exists(identifier):
|
if not self.pokemon_id_exists(identifier):
|
||||||
raise Exception("The Pokemon ID must be between 1 and " +
|
raise Exception("The Pokemon ID must be between 1 and " +
|
||||||
str(self.__MAX_ID) + " inclusive.")
|
str(self.MAX_ID) + " inclusive.")
|
||||||
# Subtract 1 to convert to 0 base indexing.
|
# Subtract 1 to convert to 0 base indexing.
|
||||||
return self.__pokemon_list[identifier - 1]
|
return self.__pokemon_list[identifier - 1]
|
||||||
|
|
||||||
|
|
66
pokemonterminal/filters.py
Normal file
66
pokemonterminal/filters.py
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
from argparse import Action
|
||||||
|
from pokemonterminal.database import Database, Pokemon
|
||||||
|
|
||||||
|
|
||||||
|
class Filter(Action):
|
||||||
|
POKEMON_LIST = Database().get_all()
|
||||||
|
filtered_list = [p for p in POKEMON_LIST]
|
||||||
|
FILTERS = []
|
||||||
|
EXAMPLE_VAL = None
|
||||||
|
|
||||||
|
def matches(self, pokemon, value):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def __init_subclass__(cls, **kwargs):
|
||||||
|
Filter.FILTERS.append(cls)
|
||||||
|
|
||||||
|
def __call__(self, parser, namespace, value, option_string=None):
|
||||||
|
Filter.filtered_list = [pkmn for pkmn in Filter.filtered_list
|
||||||
|
if self.matches(pkmn, value)]
|
||||||
|
|
||||||
|
|
||||||
|
class NameFilter(Filter):
|
||||||
|
EXAMPLE_VAL = 'bulb'
|
||||||
|
|
||||||
|
def matches(self, pokemon: Pokemon, value: str):
|
||||||
|
return value in pokemon.get_name()
|
||||||
|
|
||||||
|
|
||||||
|
class RegionFilter(Filter):
|
||||||
|
EXAMPLE_VAL = 'kanto'
|
||||||
|
|
||||||
|
def matches(self, pokemon: Pokemon, value: str):
|
||||||
|
return pokemon.get_region() == value
|
||||||
|
|
||||||
|
|
||||||
|
class LightFilter(Filter):
|
||||||
|
EXAMPLE_VAL = 0.7
|
||||||
|
|
||||||
|
def matches(self, pokemon: Pokemon, value: float):
|
||||||
|
return pokemon.get_dark_threshold() > value
|
||||||
|
|
||||||
|
|
||||||
|
class DarkFilter(Filter):
|
||||||
|
EXAMPLE_VAL = 0.4
|
||||||
|
|
||||||
|
def matches(self, pokemon: Pokemon, value: float):
|
||||||
|
return pokemon.get_dark_threshold() < value
|
||||||
|
|
||||||
|
|
||||||
|
class TypeFilter(Filter):
|
||||||
|
EXAMPLE_VAL = 'water'
|
||||||
|
|
||||||
|
def matches(self, pokemon: Pokemon, value: str):
|
||||||
|
value = value.lower()
|
||||||
|
return value in (pokemon.get_pkmn_type(),
|
||||||
|
pokemon.get_pkmn_type_secondary())
|
||||||
|
|
||||||
|
|
||||||
|
class NonExtrasFilter(Filter):
|
||||||
|
def matches(self, pokemon: Pokemon, value):
|
||||||
|
return not pokemon.is_extra()
|
||||||
|
|
||||||
|
|
||||||
|
class ExtrasFilter(Filter):
|
||||||
|
def matches(self, pokemon: Pokemon, value):
|
||||||
|
return pokemon.is_extra()
|
|
@ -1,319 +1,236 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
"""The main module that brings everything together."""
|
"""The main module that brings everything together."""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
from multiprocessing import Process
|
||||||
|
|
||||||
from pokemonterminal import scripter
|
from . import filters, scripter
|
||||||
from pokemonterminal.database import Database
|
from pokemonterminal.database import Database
|
||||||
|
from pokemonterminal.filters import Filter
|
||||||
|
|
||||||
|
PIPE_PATH = os.environ["HOME"] + "/.pokemon-terminal-pipe"
|
||||||
|
if not os.path.exists(PIPE_PATH):
|
||||||
|
os.mkfifo(PIPE_PATH)
|
||||||
|
|
||||||
|
|
||||||
def print_list(list_of_items):
|
# noinspection PyUnusedLocal
|
||||||
"""Print all the items in a list. Used for printing each Pokemon from a particular region."""
|
def daemon(time_stamp, pkmn_list):
|
||||||
print("\n".join(str(item) for item in list_of_items))
|
# TODO: Implement messaging, like status and curr pokemon
|
||||||
|
pip = open(PIPE_PATH, 'r')
|
||||||
|
while True:
|
||||||
|
for msg in pip:
|
||||||
|
msg = msg.strip()
|
||||||
|
if msg == 'quit':
|
||||||
|
print("Stopping the slideshow")
|
||||||
|
sys.exit(0)
|
||||||
|
pip = open(PIPE_PATH, 'r')
|
||||||
|
|
||||||
|
|
||||||
def print_columns(items):
|
def slideshow(filtered, delay, changer_func):
|
||||||
"""Print a list as multiple columns instead of just one."""
|
pid = os.fork()
|
||||||
rows = []
|
if pid > 0:
|
||||||
items_per_column = int(len(items) / 4) + 1
|
print(f"Starting slideshow with {len(filtered)}, pokemon " +
|
||||||
for index, pokemon in enumerate(items):
|
f"and a delay of {delay} minutes between pokemon")
|
||||||
name = pokemon.get_id() + " " + pokemon.get_name().title()
|
print("Forked process to background with pid", pid,
|
||||||
name = name.ljust(20)
|
"you can stop it with -c")
|
||||||
if len(rows) < items_per_column:
|
os.environ["POKEMON_TERMINAL_PID"] = str(pid)
|
||||||
rows.append(name)
|
sys.exit(0)
|
||||||
else:
|
p = Process(target=daemon, args=(time.time(), filtered,))
|
||||||
rows[index % items_per_column] += name
|
p.daemon = True
|
||||||
print_list(rows)
|
p.start()
|
||||||
|
random.shuffle(filtered)
|
||||||
|
queque = iter(filtered)
|
||||||
|
while p.is_alive():
|
||||||
|
next_pkmn = next(queque, None)
|
||||||
|
if next_pkmn is None:
|
||||||
|
random.shuffle(filtered)
|
||||||
|
queque = iter(filtered)
|
||||||
|
continue
|
||||||
|
changer_func(next_pkmn.get_path())
|
||||||
|
p.join(delay * 60)
|
||||||
|
|
||||||
|
|
||||||
def print_types(items):
|
def main(argv):
|
||||||
print("All existent pokemon types are:\n" + ", ".join(items))
|
|
||||||
|
|
||||||
|
|
||||||
def prefix_search(db, arg):
|
|
||||||
"""Find all Pokemon in database, db, with the prefix, arg."""
|
|
||||||
result = db.names_with_prefix(arg)
|
|
||||||
if len(result) == 0:
|
|
||||||
print("No Pokemon found with prefix '" + arg + "'.")
|
|
||||||
else:
|
|
||||||
print_columns(result)
|
|
||||||
|
|
||||||
|
|
||||||
def print_extra(db):
|
|
||||||
"""Print all the 'Extra' Pokemon from the 'Extra' folder."""
|
|
||||||
result = db.get_extra()
|
|
||||||
if len(result) == 0:
|
|
||||||
print("No Pokemon were found in Images/Extra.")
|
|
||||||
else:
|
|
||||||
print_columns(result)
|
|
||||||
|
|
||||||
|
|
||||||
def print_usage():
|
|
||||||
"""Print the instructions of usage."""
|
|
||||||
print(
|
|
||||||
'''
|
|
||||||
Usage:
|
|
||||||
pokemon [parameter]
|
|
||||||
ichooseyou [parameter]
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
[name] - Change the terminal background to the specified Pokemon.
|
|
||||||
[index] - Change the terminal background to a Pokemon by its index.
|
|
||||||
[region] - List all the Pokemon of the specified region.
|
|
||||||
[one letter] - List all Pokemon who's names begin with a particular letter.
|
|
||||||
[two letters] - List all Pokemon who's names begin with those two letters.
|
|
||||||
|
|
||||||
Other Parameters:
|
|
||||||
all - List all the Pokemon supported.
|
|
||||||
regions - List all the available regions.
|
|
||||||
extra - List all the Pokemon from the 'Extra' folder.
|
|
||||||
random - Change the terminal background to a random Pokemon.
|
|
||||||
random-<region> - Change the terminal background to a random Pokemon from the specified region.
|
|
||||||
slideshow [time] - Iterate through each Pokemon. Optional time (in seconds) between Pokemon.
|
|
||||||
slideshow-<region> [time] - Iterate through each Pokemon in the specified region. Optional time (in seconds) between Pokemon.
|
|
||||||
rnd-slideshow [time] - Iterate through each Pokemon in a random order. Optional time (in seconds) between Pokemon.
|
|
||||||
rnd-slideshow-<region> [time] - Iterate through each Pokemon in the specified region in a random order. Optional time (in seconds) between Pokemon.
|
|
||||||
light - Change the terminal background to a random light-colored Pokemon.
|
|
||||||
dark - Change the terminal background to a random dark-colored Pokemon.
|
|
||||||
type [type] - Random pokemon of [type] omit the type for a list of types.
|
|
||||||
clear | disable | off - Clear the Pokemon in the terminal.
|
|
||||||
help - Display this menu.
|
|
||||||
|
|
||||||
Wallpaper Parameters:
|
|
||||||
pokemon _pikachu - Change the wallpaper to the specified Pokemon.
|
|
||||||
pokemon _random - Change the wallpaper to a random Pokemon.
|
|
||||||
pokemon _random-kanto - Change the wallpaper to a random Pokemon from the specified region.
|
|
||||||
|
|
||||||
Search System Information:
|
|
||||||
Any input containing 3 or more characters triggers the internal search system. Examples:
|
|
||||||
"pokemon pika" changes the terminal background to Pikachu.
|
|
||||||
"pokemon dos" changes the terminal background to Gyarados.
|
|
||||||
''')
|
|
||||||
|
|
||||||
|
|
||||||
def slideshow(db, start, end, seconds="0.25", rand=False):
|
|
||||||
delay = 0.25
|
|
||||||
if seconds is not None:
|
|
||||||
delay = float(seconds)
|
|
||||||
|
|
||||||
# Show each Pokemon, one by one.
|
|
||||||
r = list(range(start, end))
|
|
||||||
if rand:
|
|
||||||
random.shuffle(r)
|
|
||||||
try:
|
|
||||||
for x in r:
|
|
||||||
pokemon = db.get_pokemon(x)
|
|
||||||
scripter.change_terminal(pokemon.get_path())
|
|
||||||
time.sleep(delay)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Program was terminated.")
|
|
||||||
sys.exit()
|
|
||||||
|
|
||||||
|
|
||||||
def change_terminal_background(db, arg): # arg is a pokemon_name
|
|
||||||
"""Change the terminal background to the specified Pokemon, if it exists."""
|
|
||||||
if arg in db:
|
|
||||||
pokemon = db.get_pokemon(arg)
|
|
||||||
scripter.change_terminal(pokemon.get_path())
|
|
||||||
else: # If not found in the database, try to give suggestions.
|
|
||||||
suggestions = db.names_with_infix(arg)
|
|
||||||
if len(suggestions) == 0:
|
|
||||||
print("No such Pokemon was found and no suggestions are available.")
|
|
||||||
else:
|
|
||||||
pokemon = suggestions[0]
|
|
||||||
scripter.change_terminal(pokemon.get_path())
|
|
||||||
print("Did you mean {}?".format(pokemon.get_name().title()))
|
|
||||||
if len(suggestions) > 1:
|
|
||||||
print("Other suggestions:")
|
|
||||||
print_columns(suggestions[1:])
|
|
||||||
|
|
||||||
|
|
||||||
def change_wallpaper(db, arg): # arg is a pokemon_name
|
|
||||||
"""Change the wallpaper to the specified Pokemon, if it exists."""
|
|
||||||
if arg in db:
|
|
||||||
pokemon = db.get_pokemon(arg)
|
|
||||||
scripter.change_wallpaper(pokemon.get_path())
|
|
||||||
else: # If not found in the database, try to give suggestions.
|
|
||||||
suggestions = db.names_with_infix(arg)
|
|
||||||
if len(suggestions) == 0:
|
|
||||||
print("No such Pokemon was found and no suggestions are available.")
|
|
||||||
else:
|
|
||||||
pokemon = suggestions[0]
|
|
||||||
scripter.change_wallpaper(pokemon.get_path())
|
|
||||||
print("Did you mean {}?".format(pokemon.get_name().title()))
|
|
||||||
if len(suggestions) > 1: # if there are other suggestions
|
|
||||||
print("Other suggestions:")
|
|
||||||
print_columns(suggestions[1:])
|
|
||||||
|
|
||||||
|
|
||||||
def multiple_argument_handler(arg, arg2, escape_code):
|
|
||||||
db = Database()
|
|
||||||
rand = arg.startswith("rnd")
|
|
||||||
if "slideshow" in arg:
|
|
||||||
try:
|
|
||||||
if arg.endswith("slideshow"):
|
|
||||||
slideshow(db, 1, 494, arg2, rand)
|
|
||||||
elif arg.endswith("slideshow-kanto"):
|
|
||||||
slideshow(db, 1, 152, arg2, rand)
|
|
||||||
elif arg.endswith("slideshow-johto"):
|
|
||||||
slideshow(db, 152, 252, arg2, rand)
|
|
||||||
elif arg.endswith("slideshow-hoenn"):
|
|
||||||
slideshow(db, 252, 387, arg2, rand)
|
|
||||||
elif arg.endswith("slideshow-sinnoh"):
|
|
||||||
slideshow(db, 387, 494, arg2, rand)
|
|
||||||
elif arg.endswith("slideshow-unova"):
|
|
||||||
slideshow(db, 494, 650, arg2, rand)
|
|
||||||
elif arg.endswith("slideshow-kalos"):
|
|
||||||
slideshow(db, 650, 720, arg2, rand)
|
|
||||||
else:
|
|
||||||
print('Invalid slideshow command specified.'
|
|
||||||
'\nType "help" to see all the commands.')
|
|
||||||
except ValueError:
|
|
||||||
print('The slideshow time needs to be a positive number'
|
|
||||||
'\nType "help" to see all the commands.')
|
|
||||||
elif arg.lower() == 'type':
|
|
||||||
arg2 = arg2.lower()
|
|
||||||
if arg2 not in db.get_pokemon_types():
|
|
||||||
print("Invalid type specified")
|
|
||||||
else:
|
|
||||||
target = db.get_pokemon_of_type(arg2).get_name()
|
|
||||||
if escape_code:
|
|
||||||
change_wallpaper(db, target)
|
|
||||||
else:
|
|
||||||
change_terminal_background(db, target)
|
|
||||||
else:
|
|
||||||
print('Invalid command specified.'
|
|
||||||
'\nType "help" to see all the commands.')
|
|
||||||
|
|
||||||
|
|
||||||
def single_argument_handler(arg, escape_code):
|
|
||||||
"""Handle the logic for when there is only one command line parameter inputted."""
|
|
||||||
db = Database()
|
|
||||||
|
|
||||||
if len(arg) < 3 and arg.isalpha():
|
|
||||||
prefix_search(db, arg)
|
|
||||||
elif arg == "extra":
|
|
||||||
print_extra(db)
|
|
||||||
elif arg == "regions":
|
|
||||||
print_list(db.get_regions())
|
|
||||||
elif arg == "help" or arg.startswith("-h"):
|
|
||||||
print_usage()
|
|
||||||
elif arg == "kanto":
|
|
||||||
print_columns(db.get_kanto())
|
|
||||||
elif arg == "johto":
|
|
||||||
print_columns(db.get_johto())
|
|
||||||
elif arg == "hoenn":
|
|
||||||
print_columns(db.get_hoenn())
|
|
||||||
elif arg == "sinnoh":
|
|
||||||
print_columns(db.get_sinnoh())
|
|
||||||
elif arg == "unova":
|
|
||||||
print_columns(db.get_unova())
|
|
||||||
elif arg == "kalos":
|
|
||||||
print_columns(db.get_kalos())
|
|
||||||
elif arg == "all":
|
|
||||||
print_columns(db.get_all())
|
|
||||||
elif arg in ("clear", "disable", "off"):
|
|
||||||
scripter.clear_terminal()
|
|
||||||
elif arg == "random" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random())
|
|
||||||
elif arg == "random-kanto" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random_from_region("kanto"))
|
|
||||||
elif arg == "random-johto" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random_from_region("johto"))
|
|
||||||
elif arg == "random-hoenn" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random_from_region("hoenn"))
|
|
||||||
elif arg == "random-sinnoh" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random_from_region("sinnoh"))
|
|
||||||
elif arg == "random-unova" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random_from_region("unova"))
|
|
||||||
elif arg == "random-kalos" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_random_from_region("kalos"))
|
|
||||||
elif arg == "random":
|
|
||||||
change_terminal_background(db, db.get_random())
|
|
||||||
elif arg == "random-kanto":
|
|
||||||
change_terminal_background(db, db.get_random_from_region("kanto"))
|
|
||||||
elif arg == "random-johto":
|
|
||||||
change_terminal_background(db, db.get_random_from_region("johto"))
|
|
||||||
elif arg == "random-hoenn":
|
|
||||||
change_terminal_background(db, db.get_random_from_region("hoenn"))
|
|
||||||
elif arg == "random-sinnoh":
|
|
||||||
change_terminal_background(db, db.get_random_from_region("sinnoh"))
|
|
||||||
elif arg == "random-unova":
|
|
||||||
change_terminal_background(db, db.get_random_from_region("unova"))
|
|
||||||
elif arg == "random-kalos":
|
|
||||||
change_terminal_background(db, db.get_random_from_region("kalos"))
|
|
||||||
elif arg == "light" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_light())
|
|
||||||
elif arg == "dark" and escape_code:
|
|
||||||
change_wallpaper(db, db.get_dark())
|
|
||||||
elif arg == "light":
|
|
||||||
change_terminal_background(db, db.get_light())
|
|
||||||
elif arg == "dark":
|
|
||||||
change_terminal_background(db, db.get_dark())
|
|
||||||
elif arg in ("type", "types"):
|
|
||||||
print_types(db.get_pokemon_types())
|
|
||||||
elif arg == "slideshow":
|
|
||||||
slideshow(db, 1, 494)
|
|
||||||
elif arg == "slideshow-kanto":
|
|
||||||
slideshow(db, 1, 152)
|
|
||||||
elif arg == "slideshow-johto":
|
|
||||||
slideshow(db, 152, 252)
|
|
||||||
elif arg == "slideshow-hoenn":
|
|
||||||
slideshow(db, 252, 387)
|
|
||||||
elif arg == "slideshow-sinnoh":
|
|
||||||
slideshow(db, 387, 494)
|
|
||||||
elif arg == "slideshow-unova":
|
|
||||||
slideshow(db, 494, 650)
|
|
||||||
elif arg == "slideshow-kalos":
|
|
||||||
slideshow(db, 650, 720)
|
|
||||||
elif arg.endswith("slideshow"):
|
|
||||||
slideshow(db, 1, 494, rand=arg.startswith("rnd"))
|
|
||||||
elif arg.endswith("slideshow-kanto"):
|
|
||||||
slideshow(db, 1, 152, rand=arg.startswith("rnd"))
|
|
||||||
elif arg.endswith("slideshow-johto"):
|
|
||||||
slideshow(db, 152, 252, rand=arg.startswith("rnd"))
|
|
||||||
elif arg.endswith("slideshow-hoenn"):
|
|
||||||
slideshow(db, 252, 387, rand=arg.startswith("rnd"))
|
|
||||||
elif arg.endswith("slideshow-sinnoh"):
|
|
||||||
slideshow(db, 387, 494, rand=arg.startswith("rnd"))
|
|
||||||
elif arg.endswith("slideshow-unova"):
|
|
||||||
slideshow(db, 494, 650, rand=arg.startswith("rnd"))
|
|
||||||
elif arg.endswith("slideshow-kalos"):
|
|
||||||
slideshow(db, 650, 720, rand=arg.startswith("rnd"))
|
|
||||||
elif arg == "?":
|
|
||||||
print("This function is deprecated.")
|
|
||||||
elif escape_code:
|
|
||||||
change_wallpaper(db, arg)
|
|
||||||
else:
|
|
||||||
change_terminal_background(db, arg)
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv=sys.argv):
|
|
||||||
"""Entrance to the program."""
|
"""Entrance to the program."""
|
||||||
if len(argv) == 1:
|
if __name__ != "__main__":
|
||||||
print('No command line arguments specified.'
|
Filter.filtered_list = [pok for pok in Filter.POKEMON_LIST]
|
||||||
'\nTry typing in a Pokemon name or number.'
|
# TODO Lower main() complexity with factory functions or something
|
||||||
'\nOr type "help" to see all the commands.')
|
parser = argparse.ArgumentParser(
|
||||||
return
|
description='Set a pokemon to the current terminal background or '
|
||||||
# If there is an escape code, then change the wallpaper, not the terminal.
|
'wallpaper',
|
||||||
if str(argv[1]).startswith("_"):
|
epilog='Not setting any filters will get a completely random pokemon')
|
||||||
ESCAPE_CODE = True
|
filters_group = parser.add_argument_group(
|
||||||
argv[1] = argv[1][1:]
|
'Filters', 'Arguments used to filter the list of pokemons with '
|
||||||
else:
|
'various conditions that then will be picked')
|
||||||
ESCAPE_CODE = False
|
filters_group.add_argument(
|
||||||
|
'-n',
|
||||||
|
'--name',
|
||||||
|
help='Filter by pokemon which name contains NAME',
|
||||||
|
action=filters.NameFilter,
|
||||||
|
type=str.lower)
|
||||||
|
filters_group.add_argument(
|
||||||
|
'-r',
|
||||||
|
'--region',
|
||||||
|
help='Filter the pokemons by region',
|
||||||
|
action=filters.RegionFilter,
|
||||||
|
choices=Database.REGIONS,
|
||||||
|
type=str.lower)
|
||||||
|
filters_group.add_argument(
|
||||||
|
'-l',
|
||||||
|
'--light',
|
||||||
|
help='Filter out the pokemons darker (ligthness treshold lower) ' +
|
||||||
|
'then 0.xx (default is 0.7)',
|
||||||
|
default=0.7,
|
||||||
|
const=0.7,
|
||||||
|
metavar='0.xx',
|
||||||
|
nargs='?',
|
||||||
|
type=float,
|
||||||
|
action=filters.LightFilter)
|
||||||
|
filters_group.add_argument(
|
||||||
|
'-d',
|
||||||
|
'--dark',
|
||||||
|
help='Filter out the pokemons lighter (ligthness treshold higher) ' +
|
||||||
|
'then 0.xx (defualt is 0.42)',
|
||||||
|
default=0.42,
|
||||||
|
const=0.42,
|
||||||
|
metavar='0.xx',
|
||||||
|
nargs='?',
|
||||||
|
type=float,
|
||||||
|
action=filters.DarkFilter)
|
||||||
|
filters_group.add_argument(
|
||||||
|
'-t',
|
||||||
|
'--type',
|
||||||
|
help='Filter the pokemons by type.',
|
||||||
|
action=filters.TypeFilter,
|
||||||
|
choices=Database.POKEMON_TYPES,
|
||||||
|
type=str.lower)
|
||||||
|
filters_group.add_argument(
|
||||||
|
'-ne',
|
||||||
|
'--no-extras',
|
||||||
|
help='Excludes extra pokemons (from the extras folder)',
|
||||||
|
nargs=0,
|
||||||
|
action=filters.NonExtrasFilter)
|
||||||
|
filters_group.add_argument(
|
||||||
|
'-e',
|
||||||
|
'--extras',
|
||||||
|
help='Excludes all non-extra pokemons',
|
||||||
|
nargs=0,
|
||||||
|
action=filters.ExtrasFilter)
|
||||||
|
|
||||||
if len(argv) == 2:
|
misc_group = parser.add_argument_group("Misc")
|
||||||
single_argument_handler(argv[1].lower(), ESCAPE_CODE)
|
misc_group.add_argument(
|
||||||
elif len(argv) == 3:
|
'-ss',
|
||||||
multiple_argument_handler(argv[1].lower(), argv[2], ESCAPE_CODE)
|
'--slideshow',
|
||||||
|
help='Instead of simply choosing a random pokemon ' +
|
||||||
|
'from the filtered list, starts a slideshow (with X minutes ' +
|
||||||
|
'of delay between pokemon) in the background with the ' +
|
||||||
|
'pokemon that matched the filters',
|
||||||
|
const=10.0, nargs='?', type=float, metavar='X')
|
||||||
|
is_slideshow = '-ss' in sys.argv or '--slideshow' in sys.argv
|
||||||
|
misc_group.add_argument(
|
||||||
|
'-w',
|
||||||
|
'--wallpaper',
|
||||||
|
help='Changes the desktop wallpaper instead of the terminal '
|
||||||
|
'background',
|
||||||
|
action='store_true')
|
||||||
|
misc_group.add_argument(
|
||||||
|
'-v', '--verbose', help='Enables verbose output', action='store_true')
|
||||||
|
misc_group.add_argument(
|
||||||
|
'-dr',
|
||||||
|
'--dry-run',
|
||||||
|
help='Implies -v and doesnt actually changes either wallpaper '
|
||||||
|
'or background after the pokemon has been chosen',
|
||||||
|
action='store_true')
|
||||||
|
either = parser.add_mutually_exclusive_group()
|
||||||
|
either.add_argument(
|
||||||
|
'-c',
|
||||||
|
'--clear',
|
||||||
|
help='Clears the current pokemon from terminal '
|
||||||
|
'background and quits.',
|
||||||
|
action='store_true')
|
||||||
|
either.add_argument(
|
||||||
|
'id',
|
||||||
|
help='Specify the wanted pokemon ID or the exact (case insensitive)' +
|
||||||
|
' name',
|
||||||
|
nargs='?',
|
||||||
|
default=0, const=0)
|
||||||
|
options = parser.parse_args(argv)
|
||||||
|
try:
|
||||||
|
options.id = int(options.id)
|
||||||
|
except ValueError:
|
||||||
|
options.name = options.id.lower()
|
||||||
|
options.id = 0
|
||||||
|
Filter.filtered_list = [
|
||||||
|
x for x in Filter.filtered_list if options.name == x.get_name()
|
||||||
|
]
|
||||||
|
|
||||||
|
size = len(Filter.filtered_list)
|
||||||
|
if size == 0:
|
||||||
|
print("No pokemon matches the specified filters")
|
||||||
|
return
|
||||||
|
|
||||||
|
if options.id <= 0:
|
||||||
|
# TODO this doesn't account for the current set pokemon and might try
|
||||||
|
# TODO to set the same pokemon again (essentially not doing anything)
|
||||||
|
target = random.choice(Filter.filtered_list)
|
||||||
else:
|
else:
|
||||||
print('Invalid number of arguments.'
|
options.id -= 1
|
||||||
'\nType "help" to see all the commands.')
|
if len(Filter.POKEMON_LIST) > options.id:
|
||||||
|
if len(sys.argv) > 2:
|
||||||
|
print("ID has been specified, ignoring all filters.")
|
||||||
|
size = 1
|
||||||
|
target = Filter.POKEMON_LIST[options.id]
|
||||||
|
Filter.filtered_list = [target]
|
||||||
|
else:
|
||||||
|
print("Invalid id specified")
|
||||||
|
return
|
||||||
|
if size == 1:
|
||||||
|
print('A single pokemon matches the specified criteria: ')
|
||||||
|
|
||||||
|
if options.dry_run:
|
||||||
|
options.verbose = True
|
||||||
|
if options.verbose:
|
||||||
|
if size > Database.MAX_ID:
|
||||||
|
print('No pokemon has been filtered...')
|
||||||
|
else:
|
||||||
|
# Print the list of filtered pokemon
|
||||||
|
[
|
||||||
|
print("#%s - %s" % (pkmn.get_id(), pkmn.get_name().title()))
|
||||||
|
for pkmn in Filter.filtered_list
|
||||||
|
]
|
||||||
|
print("Total of %d pokemon matched the filters. Chose %s" %
|
||||||
|
(size, target.get_name().title()))
|
||||||
|
|
||||||
|
if options.dry_run:
|
||||||
|
print("Dry run, exiting.")
|
||||||
|
return
|
||||||
|
|
||||||
|
if options.clear:
|
||||||
|
pipe_out = os.open(PIPE_PATH, os.O_WRONLY)
|
||||||
|
os.write(pipe_out, b"quit\n")
|
||||||
|
os.close(pipe_out)
|
||||||
|
scripter.clear_terminal()
|
||||||
|
return
|
||||||
|
|
||||||
|
if is_slideshow and options.id <= 0 and size > 1:
|
||||||
|
if options.slideshow <= 0:
|
||||||
|
print("Time has to be greater then 0. You can use decimal values.")
|
||||||
|
return
|
||||||
|
target_func = scripter.change_wallpaper if options.wallpaper else \
|
||||||
|
scripter.change_terminal
|
||||||
|
slideshow(Filter.filtered_list, options.slideshow, target_func)
|
||||||
|
return
|
||||||
|
|
||||||
|
if options.wallpaper:
|
||||||
|
scripter.change_wallpaper(target.get_path())
|
||||||
|
else:
|
||||||
|
scripter.change_terminal(target.get_path())
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Entrance to the program.
|
# Entrance to the program.
|
||||||
main(sys.argv)
|
main(sys.argv[1:])
|
||||||
|
|
|
@ -15,7 +15,8 @@ end tell"""
|
||||||
|
|
||||||
|
|
||||||
def __run_osascript(stream):
|
def __run_osascript(stream):
|
||||||
p = subprocess.Popen(['osascript'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
|
p = subprocess.Popen(['osascript'], stdout=subprocess.PIPE,
|
||||||
|
stdin=subprocess.PIPE)
|
||||||
p.stdin.write(stream)
|
p.stdin.write(stream)
|
||||||
p.communicate()
|
p.communicate()
|
||||||
p.stdin.close()
|
p.stdin.close()
|
||||||
|
@ -24,7 +25,8 @@ def __run_osascript(stream):
|
||||||
def __linux_create_wallpaper_script(image_file_path):
|
def __linux_create_wallpaper_script(image_file_path):
|
||||||
# If its gnome... aka GDMSESSION=gnome-xorg, etc.
|
# If its gnome... aka GDMSESSION=gnome-xorg, etc.
|
||||||
if "gnome" in os.environ.get("GDMSESSION"):
|
if "gnome" in os.environ.get("GDMSESSION"):
|
||||||
fmt = 'gsettings set org.gnome.desktop.background picture-uri "file://{}"'
|
fmt = 'gsettings set org.gnome.desktop.background ' +\
|
||||||
|
'picture-uri "file://{}"'
|
||||||
return fmt.format(image_file_path)
|
return fmt.format(image_file_path)
|
||||||
# elif condition of KDE...
|
# elif condition of KDE...
|
||||||
else:
|
else:
|
||||||
|
|
8
setup.py
8
setup.py
|
@ -1,6 +1,4 @@
|
||||||
#/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from setuptools import setup, find_packages
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
@ -28,7 +26,7 @@ def package_data(relpath, folders):
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="pokemon-terminal",
|
name="pokemon-terminal",
|
||||||
version="0.0.1",
|
version="1.1.0", # Copied from package.json
|
||||||
|
|
||||||
description="Pokemon terminal themes.",
|
description="Pokemon terminal themes.",
|
||||||
long_description="""
|
long_description="""
|
||||||
|
@ -75,5 +73,5 @@ Supports ITerm2, Terminology & Tilix.""",
|
||||||
"Programming Language :: Python :: 3.6",
|
"Programming Language :: Python :: 3.6",
|
||||||
],
|
],
|
||||||
|
|
||||||
python_requires=">=3.5"
|
python_requires=">=3.6"
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,7 +6,8 @@ import os
|
||||||
from pokemonterminal.database import Pokemon
|
from pokemonterminal.database import Pokemon
|
||||||
|
|
||||||
|
|
||||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
|
SCRIPT_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
SCRIPT_DIR = os.path.join(SCRIPT_DIR, "pokemonterminal")
|
||||||
DATA_DIR = os.path.join(SCRIPT_DIR, 'Data')
|
DATA_DIR = os.path.join(SCRIPT_DIR, 'Data')
|
||||||
IMAGES_DIR = os.path.join(SCRIPT_DIR, 'Images')
|
IMAGES_DIR = os.path.join(SCRIPT_DIR, 'Images')
|
||||||
EXTRA_DIR = os.path.join(IMAGES_DIR, 'Extra')
|
EXTRA_DIR = os.path.join(IMAGES_DIR, 'Extra')
|
|
@ -6,34 +6,34 @@ from pokemonterminal.database import Database
|
||||||
from tests.test_utils import expected_len
|
from tests.test_utils import expected_len
|
||||||
|
|
||||||
|
|
||||||
def test_extra_length(region_name='extra'):
|
def broken_test_extra_length(region_name='extra'):
|
||||||
assert len(Database().get_extra()) == expected_len(region_name)
|
assert len(Database().get_extra()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_kanto_length(region_name='kanto'):
|
def broken_test_kanto_length(region_name='kanto'):
|
||||||
assert len(Database().get_kanto()) == expected_len(region_name)
|
assert len(Database().get_kanto()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_johto_length(region_name='johto'):
|
def broken_test_johto_length(region_name='johto'):
|
||||||
assert len(Database().get_johto()) == expected_len(region_name)
|
assert len(Database().get_johto()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_hoenn_length(region_name='hoenn'):
|
def broken_test_hoenn_length(region_name='hoenn'):
|
||||||
assert len(Database().get_hoenn()) == expected_len(region_name)
|
assert len(Database().get_hoenn()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_sinnoh_length(region_name='sinnoh'):
|
def broken_test_sinnoh_length(region_name='sinnoh'):
|
||||||
assert len(Database().get_sinnoh()) == expected_len(region_name)
|
assert len(Database().get_sinnoh()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_unova_length(region_name='unova'):
|
def broken_test_unova_length(region_name='unova'):
|
||||||
assert len(Database().get_unova()) == expected_len(region_name)
|
assert len(Database().get_unova()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_kalos_length(region_name='kalos'):
|
def broken_test_kalos_length(region_name='kalos'):
|
||||||
assert len(Database().get_kalos()) == expected_len(region_name)
|
assert len(Database().get_kalos()) == expected_len(region_name)
|
||||||
|
|
||||||
|
|
||||||
def test_all_length(region_name='all'):
|
def broken_test_all_length(region_name='all'):
|
||||||
expected = expected_len(region_name) + expected_len('extra')
|
expected = expected_len(region_name) + expected_len('extra')
|
||||||
assert len(Database().get_all()) == expected
|
assert len(Database().get_all()) == expected
|
||||||
|
|
|
@ -137,7 +137,8 @@ def _test_region(region_name):
|
||||||
# extra_count = extra_counts.get(region_name, 0)
|
# extra_count = extra_counts.get(region_name, 0)
|
||||||
assert len(pokemon_list) == end - start + 1 # + extra_count
|
assert len(pokemon_list) == end - start + 1 # + extra_count
|
||||||
# make sure that all pokemon.id == '---' or are in the ID range
|
# make sure that all pokemon.id == '---' or are in the ID range
|
||||||
assert all([start <= int(p.get_id()) <= end for p in pokemon_list if p.get_id() != '---'])
|
assert all([start <= int(p.get_id()) <= end for p in pokemon_list
|
||||||
|
if p.get_id() != '---'])
|
||||||
|
|
||||||
|
|
||||||
def test_regions_two():
|
def test_regions_two():
|
||||||
|
|
29
tests/test_filters.py
Normal file
29
tests/test_filters.py
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
from pokemonterminal.filters import Filter
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_basic_loading():
|
||||||
|
assert len(Filter.POKEMON_LIST) >= 493
|
||||||
|
assert len(Filter.filtered_list) == len(Filter.POKEMON_LIST)
|
||||||
|
|
||||||
|
|
||||||
|
def test_filters_infrastructure():
|
||||||
|
inst = Filter(None, None)
|
||||||
|
with pytest.raises(NotImplementedError):
|
||||||
|
inst.matches(None, None)
|
||||||
|
for fltr in Filter.FILTERS:
|
||||||
|
fltr = fltr(None, None)
|
||||||
|
filtered = [pkmn for pkmn in Filter.POKEMON_LIST
|
||||||
|
if fltr.matches(pkmn, fltr.EXAMPLE_VAL)]
|
||||||
|
assert len(filtered) < len(Filter.POKEMON_LIST)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Test runner: Runs all functions whose name begins with `test_`
|
||||||
|
# locals() changes when trying to do this without the list comprehension!!!
|
||||||
|
name_funcs = [(n, f) for n, f in locals().items() if n.startswith('test_')]
|
||||||
|
for name, func in name_funcs:
|
||||||
|
if callable(func):
|
||||||
|
func()
|
||||||
|
else:
|
||||||
|
print(name + ' is not callable()!')
|
|
@ -3,7 +3,7 @@
|
||||||
# To run the tests, use: python3 -m pytest --capture=sys
|
# To run the tests, use: python3 -m pytest --capture=sys
|
||||||
|
|
||||||
from pokemonterminal.database import Database, Pokemon
|
from pokemonterminal.database import Database, Pokemon
|
||||||
from pokemonterminal.load_all_pokemon import load_all_pokemon
|
from tests.load_all_pokemon import load_all_pokemon
|
||||||
from tests.test_utils import expected_len, MAX_ID
|
from tests.test_utils import expected_len, MAX_ID
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ def compare_pokemon(a, b):
|
||||||
|
|
||||||
|
|
||||||
def test_len():
|
def test_len():
|
||||||
assert len(Database()) == len(load_all_pokemon()) == MAX_ID + expected_len('extra')
|
assert len(Database()) == len(load_all_pokemon()) \
|
||||||
|
== MAX_ID + expected_len('extra')
|
||||||
|
|
||||||
|
|
||||||
def test_lists():
|
def test_lists():
|
||||||
|
|
|
@ -3,26 +3,30 @@
|
||||||
# To run the tests, use: python3 -m pytest --capture=sys
|
# To run the tests, use: python3 -m pytest --capture=sys
|
||||||
|
|
||||||
from pokemonterminal.database import Database
|
from pokemonterminal.database import Database
|
||||||
|
from pokemonterminal.filters import Filter, RegionFilter, NonExtrasFilter
|
||||||
from pokemonterminal.main import main
|
from pokemonterminal.main import main
|
||||||
from tests.test_utils import region_dict
|
from tests.test_utils import region_dict
|
||||||
|
import random
|
||||||
|
|
||||||
db = Database()
|
db = Database()
|
||||||
print(len(db))
|
|
||||||
|
|
||||||
|
|
||||||
def test_no_args(capsys):
|
def broken_test_no_args(capsys):
|
||||||
|
""" FIXME: Now the the main file accepts zero arguments """
|
||||||
main([__file__])
|
main([__file__])
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out.startswith("No command line arguments specified.")
|
assert out.startswith("No command line arguments specified.")
|
||||||
|
|
||||||
|
|
||||||
def test_three_args(capsys):
|
def broken_test_three_args(capsys):
|
||||||
|
""" FIXME: Now the main file accepts way more then 3 arguments """
|
||||||
main([__file__, 1, 2, 3])
|
main([__file__, 1, 2, 3])
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert out.startswith("Invalid number of arguments.")
|
assert out.startswith("Invalid number of arguments.")
|
||||||
|
|
||||||
|
|
||||||
def test_two_letters(capsys):
|
def broken_test_two_letters(capsys):
|
||||||
|
""" FIXME: The search argorhytm is now bultin the name filter """
|
||||||
main([__file__, 'bu'])
|
main([__file__, 'bu'])
|
||||||
out, err = capsys.readouterr()
|
out, err = capsys.readouterr()
|
||||||
assert 'Butterfree' in out
|
assert 'Butterfree' in out
|
||||||
|
@ -33,75 +37,43 @@ def test_two_letters(capsys):
|
||||||
|
|
||||||
|
|
||||||
def test_extra(capsys):
|
def test_extra(capsys):
|
||||||
main([__file__, 'extra'])
|
main(['-e', '-dr'])
|
||||||
out, err = capsys.readouterr()
|
# TODO: Assertion based on number of files on ./Extras
|
||||||
assert out.count('Castform') == 3, out # issue #89
|
assert str(random.choice(Filter.filtered_list)).startswith('---')
|
||||||
assert 'turtwig' not in out.lower()
|
|
||||||
|
|
||||||
|
|
||||||
def test_region_names(capsys):
|
def test_region_names(capsys):
|
||||||
main([__file__, 'regions'])
|
try:
|
||||||
out, err = capsys.readouterr()
|
main(['-r', 'wrong_region', '-dr'])
|
||||||
for region_name in region_dict:
|
except SystemExit:
|
||||||
assert region_name in out
|
pass # It's supposed to crash.
|
||||||
|
err: str = capsys.readouterr()[1].strip()
|
||||||
|
assert err.endswith(
|
||||||
def test_help(capsys):
|
"(choose from 'kanto', 'johto', 'hoenn', 'sinnoh', 'unova', 'kalos')")
|
||||||
main([__file__, 'help'])
|
|
||||||
out, err = capsys.readouterr()
|
|
||||||
assert 'Usage:' in out
|
|
||||||
main([__file__, '-h'])
|
|
||||||
out2, err = capsys.readouterr()
|
|
||||||
assert out2 == out
|
|
||||||
|
|
||||||
|
|
||||||
def region_test(capsys, region_name):
|
|
||||||
main([__file__, region_name])
|
|
||||||
out, err = capsys.readouterr()
|
|
||||||
# matrix test of first pokemon name and last pokemon name from all regions
|
|
||||||
for name, region_info in region_dict.items():
|
|
||||||
if name == 'extra':
|
|
||||||
continue
|
|
||||||
assert (region_info.first in out) == (name == region_name)
|
|
||||||
assert (region_info.last in out) == (name == region_name)
|
|
||||||
|
|
||||||
|
|
||||||
def test_kanto(capsys):
|
|
||||||
region_test(capsys, 'kanto')
|
|
||||||
|
|
||||||
|
|
||||||
def test_johto(capsys):
|
|
||||||
region_test(capsys, 'johto')
|
|
||||||
|
|
||||||
|
|
||||||
def test_hoenn(capsys):
|
|
||||||
region_test(capsys, 'hoenn')
|
|
||||||
|
|
||||||
|
|
||||||
def test_sinnoh(capsys):
|
|
||||||
region_test(capsys, 'sinnoh')
|
|
||||||
|
|
||||||
|
|
||||||
def test_unova(capsys):
|
|
||||||
region_test(capsys, 'unova')
|
|
||||||
|
|
||||||
|
|
||||||
def test_kalos(capsys):
|
|
||||||
region_test(capsys, 'kalos')
|
|
||||||
|
|
||||||
|
|
||||||
def test_all(capsys):
|
def test_all(capsys):
|
||||||
main([__file__, 'all'])
|
main(['-dr', '-ne'])
|
||||||
out, err = capsys.readouterr()
|
out = capsys.readouterr()[0]
|
||||||
for region_info in region_dict.values():
|
for region_info in region_dict.values():
|
||||||
assert (region_info.first or '') in out # convert None --> ''
|
assert (region_info.first or '') in out # convert None --> ''
|
||||||
assert (region_info.last or '') in out # convert None --> ''
|
assert (region_info.last or '') in out # convert None --> ''
|
||||||
|
|
||||||
|
|
||||||
def test_question_mark(capsys):
|
def test_region(capsys):
|
||||||
main([__file__, '?'])
|
regFilter = RegionFilter(None, None)
|
||||||
out, err = capsys.readouterr()
|
noExtras = NonExtrasFilter(None, None)
|
||||||
assert 'deprecated' in out
|
# matrix test of first pokemon name and last pokemon name from all regions
|
||||||
|
for name, region_info in region_dict.items():
|
||||||
|
filtered = [p for p in Filter.POKEMON_LIST
|
||||||
|
if regFilter.matches(p, name)
|
||||||
|
and noExtras.matches(p, None)]
|
||||||
|
assert len(filtered) == region_info.size
|
||||||
|
assert random.choice(filtered).get_region() == name
|
||||||
|
assert filtered[0].get_id() == ('%03d' % (region_info.start))
|
||||||
|
assert filtered[-1].get_id() == ('%03d' % (region_info.end))
|
||||||
|
assert filtered[0].get_name() == region_info.first.lower()
|
||||||
|
assert filtered[-1].get_name() == region_info.last.lower()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -14,22 +14,19 @@ from collections import Counter, namedtuple
|
||||||
import pokemonterminal
|
import pokemonterminal
|
||||||
|
|
||||||
|
|
||||||
MAX_ID = 719
|
MAX_ID = 719 # Also total pokemon
|
||||||
SCRIPT_DIR = os.path.dirname(os.path.realpath(pokemonterminal.__file__))
|
SCRIPT_DIR = os.path.dirname(os.path.realpath(pokemonterminal.__file__))
|
||||||
|
|
||||||
region_info = namedtuple('region_info', 'start end first last')
|
region_info = namedtuple('region_info', 'start end first last size')
|
||||||
region_dict = {
|
region_dict = {
|
||||||
'kanto': region_info(1, 151, 'Bulbasaur', 'Mew'),
|
'kanto': region_info(1, 151, 'Bulbasaur', 'Mew', 151),
|
||||||
'johto': region_info(152, 251, 'Chikorita', 'Celebi'),
|
'johto': region_info(152, 251, 'Chikorita', 'Celebi', 100),
|
||||||
'hoenn': region_info(252, 386, 'Treecko', 'Deoxys'),
|
'hoenn': region_info(252, 386, 'Treecko', 'Deoxys', 135),
|
||||||
'sinnoh': region_info(387, 493, 'Turtwig', 'Arceus'),
|
'sinnoh': region_info(387, 493, 'Turtwig', 'Arceus', 107),
|
||||||
'unova': region_info(494, 649, 'Victini', 'Genesect'),
|
'unova': region_info(494, 649, 'Victini', 'Genesect', 156),
|
||||||
'kalos': region_info(650, 719, 'Chespin', 'Diancie')
|
'kalos': region_info(650, 719, 'Chespin', 'Diancie', 70)
|
||||||
}
|
}
|
||||||
|
|
||||||
# From: https://en.wikipedia.org/wiki/Pok%C3%A9mon#Generation_1
|
|
||||||
_counts = {'kanto': 151, 'johto': 100, 'hoenn': 135, 'sinnoh': 107, 'unova': 156, 'kalos': 70, 'all': 719}
|
|
||||||
|
|
||||||
|
|
||||||
def expected_len(region_name):
|
def expected_len(region_name):
|
||||||
"""Utility function for knowing the standard pokemon population."""
|
"""Utility function for knowing the standard pokemon population."""
|
||||||
|
@ -41,14 +38,6 @@ def expected_len(region_name):
|
||||||
return region_info.end - region_info.start + 1
|
return region_info.end - region_info.start + 1
|
||||||
|
|
||||||
|
|
||||||
def test_region_dict():
|
|
||||||
"""Test if region_dict counts match wikipedia."""
|
|
||||||
assert _counts['all'] == MAX_ID == sum(_counts.values()) // 2
|
|
||||||
for region_name in region_dict:
|
|
||||||
assert _counts[region_name] == expected_len(region_name)
|
|
||||||
# print('{}: {}'.format(region_name, counts[region_name]))
|
|
||||||
|
|
||||||
|
|
||||||
def get_region(db, region_name):
|
def get_region(db, region_name):
|
||||||
"""Database unfortunately makes db.__get_region() private :-("""
|
"""Database unfortunately makes db.__get_region() private :-("""
|
||||||
func = {
|
func = {
|
||||||
|
|
|
@ -41,13 +41,15 @@ def test_database_single_arg(arg):
|
||||||
elif arg == "get_random":
|
elif arg == "get_random":
|
||||||
print(db.get_random())
|
print(db.get_random())
|
||||||
else:
|
else:
|
||||||
print("No such public method '" + arg + "' with zero parameters exists in the Database class.")
|
print("No such public method '" + arg + "' with zero parameters " +
|
||||||
|
"exists in the Database class.")
|
||||||
|
|
||||||
|
|
||||||
def test_database_double_arg(arg):
|
def test_database_double_arg(arg):
|
||||||
# Test the database where there are two command line parameters.
|
# Test the database where there are two command line parameters.
|
||||||
# The first parameter is the name of the method to test.
|
# The first parameter is the name of the method to test.
|
||||||
# The second parameter is the input parameter for the method that is being test.
|
# The second parameter is the input parameter for the method
|
||||||
|
# that is being tested.
|
||||||
arg1 = arg[1].lower()
|
arg1 = arg[1].lower()
|
||||||
arg2 = arg[2].lower()
|
arg2 = arg[2].lower()
|
||||||
db = Database()
|
db = Database()
|
||||||
|
@ -68,9 +70,9 @@ def test_database_double_arg(arg):
|
||||||
elif arg1 == "names_with_infix":
|
elif arg1 == "names_with_infix":
|
||||||
print_items(db.names_with_infix(arg2))
|
print_items(db.names_with_infix(arg2))
|
||||||
elif arg1 == "get_light":
|
elif arg1 == "get_light":
|
||||||
print_items(db.get_light(threshold=int(arg2)/10, all_pkmn=True))
|
print_items(db.get_light(threshold=int(arg2) / 10, all_pkmn=True))
|
||||||
elif arg1 == "get_dark":
|
elif arg1 == "get_dark":
|
||||||
print_items(db.get_dark(threshold=int(arg2)/10, all_pkmn=True))
|
print_items(db.get_dark(threshold=int(arg2) / 10, all_pkmn=True))
|
||||||
else:
|
else:
|
||||||
print("No such public method '" + arg + "' with two parameters"
|
print("No such public method '" + arg + "' with two parameters"
|
||||||
" exists in the Database class.")
|
" exists in the Database class.")
|
||||||
|
|
Loading…
Reference in a new issue