Skip to content

Commit

Permalink
Merge pull request #148 from LanceMaverick/skb-dev
Browse files Browse the repository at this point in the history
Skb dev
  • Loading branch information
LanceMaverick committed Jun 20, 2017
2 parents b6b5769 + 5b6898c commit eb94b0a
Show file tree
Hide file tree
Showing 26 changed files with 336 additions and 73 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ config.py
config.yml
.#*
*.db
docker-compose.yml

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM python:3

# Use bash as the shell because we will need to source a virtualenv later
SHELL ["/bin/bash", "-c"]

# Create a skybeard user
RUN useradd -m skybeard
USER skybeard
WORKDIR /home/skybeard

# Make a few directories which will be mounted to later
RUN mkdir code db db_binary_entries skybeard_virtualenv

# Create a base virtualenv. Normally, there's no need for a virtualenv in a
# docker container, but since any beards that run can add to the requirements,
# we'll need a virutalenv tied to a persistant container
RUN python3 -m venv skybeard_virtualenv_frozen
ADD requirements.txt .
RUN . /home/skybeard/skybeard_virtualenv_frozen/bin/activate && pip install -r requirements.txt
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,32 @@ You will then need to make a `config.py`. An example `config.py` is provided so
cp config.py.example config.py
```

## Installation with docker
This method is currently in beta. It requires docker-compose.

```
cp docker-compose.yml.example docker-compose.yml
```
then replace `YOUR_TOKEN_GOES_HERE` in `docker-compose.yml` with your token. Then run

```
docker-compose up --build
```

And skybeard will be (hopefully) running!

## Running Skybeard

To run skybeard define your key in the environment variable `$TG_BOT_TOKEN` or as an argument with `-k` and run `main.py`. this can be done easily e.g.:

./main.py -k 99121185:RUE-UAa7dsEaagAKkysPDjqa2X7KxX48e
./main.py -k 99121185:RUE-ObViouSlyFakeKeyTHaThaSbEEnmad

## Testing skybeard
To test that your skybeard is running out of the box, use the test config like so:

./main.py -k 99121185:RUE-ObViouSlyFakeKeyTHaThaSbEEnmadEuP -c config.tests.yml

and type `/help` to see the commands available.

## Skybeard's many beards
Skybeard source documentation: http://skybeard-2.readthedocs.io/en/latest/
Expand Down
4 changes: 4 additions & 0 deletions beard_repo/enigmabeard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
description: Enigma M3 Emulator plugin for Skybeard v2
git_url: https://github.com/artemis-beta/skb-enigmabeard.git
name: enigmabeard

3 changes: 3 additions & 0 deletions beard_repo/natrailenq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: National Rail Enquiry plugin for Skybeard v2
git_url: https://github.com/artemis-beta/skb-natrailenq.git
name: natrailenq
4 changes: 4 additions & 0 deletions beard_repo/willbeard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
description: 'Skybeard 2 plugin: Find answers to your questions using this Skybeard
2 interface for W.I.L.L: https://github.com/ironman5366/W.I.L.L'
git_url: https://github.com/LanceMaverick/skybeard_willbot.git
name: willbeard
9 changes: 8 additions & 1 deletion circle.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
dependencies:
override:
- pip install tox tox-pyenv
- pyenv install 3.5.2 -s
- pyenv install 3.6.0 -s
- pyenv local 3.5.2 3.6.0
- pip3 install tox tox-pyenv nose
- pip3 install -r requirements.txt

test:
override:
- tox
31 changes: 31 additions & 0 deletions config.docker.yml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
beard_paths:
- beards/
- beard_cache/
- examples/
- integration_test_beards/

beards:
- askfor
- database
- debugonlyexample
- config_helper
# Integration test beards
- different_name_inside
- oldstyle_beard

stache_paths:
- moustaches

staches:
- postcats

db_url: sqlite:///../db/skybeard-2.db
db_bin_path: ../db_binary_entries/

admins:
[
[Nathanael Farley, 89593615],
]

host: 0.0.0.0
port: 8000
62 changes: 62 additions & 0 deletions config.py.old
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import os

from autoloaders import Git

beard_paths = [
"beards/",
"beard_cache/",
"examples/",
# Beards can come from anywhere!
os.path.expanduser("~/git/"),
# Even from git!
#Git("https://github.com/nasfarley88/pdfpreviewbeard.git"),
]

# Beards can be specified as "all" which will attempt to load everything found
# in beard_paths or can be specified as a list of strings of which beards to
# load
# beards = "all"
beards = [
"askfor",
"debugonlyexample",
# "postcats",
# "xkcdbeard",
#"listbeard",
#"relay_beard",
# "repo_helper",
#"except_on_purpose",
# "teleplot",
#"githubbeard",
#"debugbeard",
#"dicebeard",
#"BabyFeederBeard",
# "namedvotebeard",
# "nth_home_beard",
# "pdfpreviewbeard", # From git (above)
]

stache_paths = [
"moustaches",
]

# staches = "all"
staches = [
"postcats",
]

db_url = "sqlite:///skybeard-2.db"
db_bin_path = "./db_binary_entries"

#put yourself, and anyone else you wish to, as an admin
admins = [
("Nathanael Farley", 89593615)
]

#web server config
host = '0.0.0.0'
port = 8000

__doc__ = """This is sample documentation. Please update in your config.py!

Current plugins enabled: {}""".format(beards)

24 changes: 24 additions & 0 deletions config.tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
beard_paths:
- beards/
- integration_test_beards/

beards:
- debugbeard
- different_name_inside
- oldstyle_beard

stache_paths:
- moustaches

staches:
- postcats

db_url: sqlite:///skybeard-2.db
db_bin_path: ./db_binary_entries

admins:
[
]

host: 0.0.0.0
port: 8000
15 changes: 15 additions & 0 deletions docker-compose.yml.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
skybeard:
build: .
environment:
- TG_BOT_TOKEN=YOUR_TOKEN_GOES_HERE
- SKYBEARD_CONFIG=config.docker.yml.example
command: ./code/run_on_docker.sh
user: skybeard
volumes:
# This is where the code is hosted
- .:/home/skybeard/code
# These should be unique per bot. If they are not, database information
# and python packages will be shared between bots.
- skybeard_virtualenv:/home/skybeard/skybeard_virtualenv:z
- skybeard_db:/home/skybeard/db:z
- skybeard_db_binary_entries:/home/skybeard/db_binary_entries:z
1 change: 1 addition & 0 deletions integration_test_beards/different_name_inside/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This beard is designed to test having a different module name to folder name.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from skybeard.beards import BeardChatHandler
from skybeard.decorators import onerror


class YetAnotherDifferentName(BeardChatHandler):

__userhelp__ = """Default help message."""

__commands__ = [
# command, callback coro, help text
("test_different_inside", 'test', 'Tests this beard.')
]

# __init__ is implicit

@onerror()
async def test(self, msg):
await self.sender.sendMessage(
"Test successful! {self} has been successfully imported and instantiated.".format(
**locals()))
5 changes: 5 additions & 0 deletions integration_test_beards/different_name_inside/setup_beard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from skybeard.utils import setup_beard

setup_beard(
"a_name_thats_different_from_the_outside",
)
20 changes: 20 additions & 0 deletions integration_test_beards/oldstyle_beard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from skybeard.beards import BeardChatHandler
from skybeard.decorators import onerror


class OldstyleBeard(BeardChatHandler):

__userhelp__ = """Default help message."""

__commands__ = [
# command, callback coro, help text
("test_oldstyle_beard", 'test', 'Tests this beard.')
]

# __init__ is implicit

@onerror()
async def test(self, msg):
await self.sender.sendMessage(
"Test successful! {self} has been successfully imported and instantiated.".format(
**locals()))
18 changes: 12 additions & 6 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,11 @@ def load_stache(stache_name, possible_dirs):
path = Path(dir_).resolve()
python_path = path.parent
with PythonPathContext(str(python_path)):
module_spec = importlib.util.find_spec(
"{}.{}".format(str(find_last_child(path)), stache_name))
stache_path = find_last_child(path) / stache_name
stache_module = "{}.{}".format(str(find_last_child(path)), stache_name)
module_spec = importlib.util.spec_from_file_location(
stache_module,
"{}.py".format(stache_path))

if module_spec:
foo = importlib.util.module_from_spec(module_spec)
Expand Down Expand Up @@ -100,9 +103,9 @@ def load_beard(beard_name, possible_dirs):
pass

# TODO make this a much better exception
if module:
return
else:
try:
logger.debug("Got module: {}".format(module))
except UnboundLocalError:
raise Exception("No beard found! Looked in: {}. Trying to find: {}".format(possible_dirs, beard_name))

foo = importlib.util.module_from_spec(module_spec)
Expand All @@ -116,6 +119,7 @@ def main():
else:
beards_to_load = pyconfig.get('beards')


for stache in pyconfig.get('staches'):
load_stache(stache, pyconfig.get('stache_paths'))

Expand Down Expand Up @@ -219,7 +223,9 @@ async def bot_message_loop_and_aiothttp_session():
parser = argparse.ArgumentParser(description='Skybeard hails you!')

parser.add_argument('-k', '--key', default=os.environ.get('TG_BOT_TOKEN'))
parser.add_argument('-c', '--config-file', default=os.path.abspath("config.yml"))
parser.add_argument('-c', '--config-file',
default=(os.environ.get('SKYBEARD_CONFIG') or
os.path.abspath("config.yml")))
parser.add_argument('--no-help', action='store_true')
parser.add_argument('-d', '--debug', action='store_const', dest="loglevel",
const=logging.DEBUG, default=logging.INFO)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
aiohttp
telepot>=10.4
pyconfig>=3.1.1
dataset>=0.7.0
Expand Down
12 changes: 12 additions & 0 deletions run_on_docker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# If the virtualenv is not populated, copy it over.
echo "Let's run skybeard!"
if [[ "$(ls -A ~/skybeard_virtualenv)" ]];
then
:
else
cp -r ~/skybeard_virtualenv_frozen/* ~/skybeard_virtualenv
fi
source ~/skybeard_virtualenv/bin/activate
cd code
python main.py
2 changes: 1 addition & 1 deletion skybeard/decorators/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import pyconfig


def admin(f):
def admin():
"""A decorator for checking if the sender of a message
is in the admins list of config.py. Will not call the
coro if not"""
Expand Down
8 changes: 4 additions & 4 deletions skybeard/decorators/getargs.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ async def f(self, msg, arg1, arg2):
If arguments are not provided, gives standard error messages.
"""
def wrapper(f):
def _getargs_wrapper(f):
@wraps(f)
async def g(beard, msg):
args = get_args(msg, return_string=return_string)
try:
if isinstance(args, str):
await f(beard, msg, args)
return await f(beard, msg, args)
else:
await f(beard, msg, *args)
return await f(beard, msg, *args)
except TypeError as exception:
# TODO have configurable messages when args are not enough
err_msg = exception.args[0]
Expand All @@ -46,4 +46,4 @@ async def g(beard, msg):

return g

return wrapper
return _getargs_wrapper

0 comments on commit eb94b0a

Please sign in to comment.