Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CI

on:
push:
branches: [master]
pull_request:

jobs:
test:
runs-on: ubuntu-latest
services:
redis:
image: redis
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"

- name: Install MeCab
run: sudo apt-get update && sudo apt-get install -y libmecab-dev mecab mecab-ipadic-utf8

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Lint
run: flake8 sun.py subculture tests.py

- name: Make sun.cgi executable
run: chmod 755 sun.cgi

- name: Run tests
run: python tests.py
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,22 @@ docs/_build/
# PyBuilder
target/

# virtualenv
# virtualenv / venv
bin/
include/
local/
share/
.venv/
pyvenv.cfg
CACHEDIR.TAG

# pytest
.pytest_cache/

# runtime artifacts
deploy.log
quiet
dogehouse.txt

# vagrant
.vagrant
Expand Down
24 changes: 0 additions & 24 deletions .travis.yml

This file was deleted.

1 change: 0 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ WORKDIR /sub
RUN python3 -m venv /venv
RUN /venv/bin/pip install -U pip
RUN /venv/bin/pip install -r requirements.txt
RUN /venv/bin/python -m unidic download

COPY ./docker-entrypoint.sh /entrypoint.sh
RUN chmod 755 /entrypoint.sh
Expand Down
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ clean:
find . -name "*.py[co]" -delete

setup:
virtualenv --python=$(which python3) .
python3 -m venv .
./bin/pip install --upgrade pip
./bin/pip install -r requirements.txt

update_packages:
Expand All @@ -17,5 +18,5 @@ status:
sudo service redis-server status

lint:
./bin/flake8 sun.cgi
./bin/flake8 sun.py subculture tests.py

41 changes: 24 additions & 17 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,38 @@
NotSubculture bot
=================

.. image:: https://api.travis-ci.org/tinbotu/sub.svg
:target: https://travis-ci.org/tinbotu/sub
.. image:: https://github.com/tinbotu/sub/actions/workflows/ci.yml/badge.svg
:target: https://github.com/tinbotu/sub/actions/workflows/ci.yml

DevServer Setup
---------------
A chat bot for Lingr / Slack. Incoming messages are matched against a
dictionary of patterns in ``sun.py`` and dispatched to the response
classes under ``subculture/``.

Requirements
------------

- Vagrant > 1.6
- Python 3.10+
- Redis
- MeCab (``libmecab-dev`` / ``mecab-ipadic-utf8``)

::
Setup
-----

main-machine: ~/work$ git clone ${THIS_REPOSITORY}
main-machine: ~/work/sub$ vagrant up
main-machine: ~/work/sub$ vagrant ssh
subculture: ~$ cd /vagrant
subculture:/vagrant$ make test
::

git clone ${THIS_REPOSITORY}
cd sub
make setup # creates ./bin venv and installs requirements
cp settings.yaml.skel settings.yaml
cp bot_secret.yaml.skel bot_secret.yaml
make test

for Lingr
---------
Docker
------

Server Requirements
-------------------
::

Ubuntu 14.04
docker build -t sub .
docker run --rm sub # boots redis and runs the test suite

Packages are listed on scripts/devserver_provisioning.sh
The bot itself is served as a CGI script (``sun.cgi`` -> ``sun.py``).
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
flake8
redis
requests
ipaddress
mecab-python
unidic
ipadic
GitPython
PyYAML
emoji
44 changes: 42 additions & 2 deletions subculture/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

from .base import (
Subculture,
HTMLParserGetElementsByTag,
Expand Down Expand Up @@ -50,3 +48,45 @@
KotoshinoKanjiSubculture,
HateSubculture,
)

__all__ = [
'Subculture',
'HTMLParserGetElementsByTag',
'DogeAwayMessage',
'RedisSubculture',
'KnowerLevelSubculture',
'KnowerLevelUpSubculture',
'KnowerLevelGetSubculture',
'AnotherIsMoreKnowerThanMe',
'RetirementLevelUpSubculture',
'RetirementLevelGetSubculture',
'AtencionSubculture',
'DogeDetailStatusSubculture',
'SelfUpdateSubculture',
'ShowDogeSokuSubculture',
'DogeGoAwaySubculture',
'DogeHouseStatusSubculture',
'HitozumaSubculture',
'KCzumaSubculture',
'OmochiSubculture',
'StoneSubculture',
'WaterFallSubculture',
'KimotiSubculture',
'KimotiYorokobiSubculture',
'CMDSubculture',
'TMDSubculture',
'XamarinSubculture',
'PizzaSubculture',
'METARSubculture',
'MineoSubculture',
'GaishutsuSubculture',
'TwitterScraperSubculture',
'GyazoScraperSubculture',
'TitleExtractSubculture',
'NogataSubculture',
'SilentSubculture',
'HaiSubculture',
'KCSubculture',
'KotoshinoKanjiSubculture',
'HateSubculture',
]
39 changes: 15 additions & 24 deletions subculture/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-

import hashlib
import json
import traceback
Expand All @@ -10,7 +8,7 @@
import yaml


class Subculture(object):
class Subculture:
""" abstract """
content = None
speaker = None
Expand Down Expand Up @@ -66,17 +64,15 @@ def response(self):
def read_bot_api(self, filename='bot_secret.yaml'):
if self.api_secret is not None:
return
yaml_file = open(filename)
content = yaml_file.read()
yaml_file.close()
self.api_secret = yaml.safe_load(content)
with open(filename) as yaml_file:
self.api_secret = yaml.safe_load(yaml_file)

@property
def settings(self):
if self._settings is not None:
return self._settings
fp = open(self.settings_filename).read()
self._settings = yaml.safe_load(fp)
with open(self.settings_filename) as fp:
self._settings = yaml.safe_load(fp)
return self._settings

def build_say_payload(self, room, bot, text, apikey):
Expand All @@ -87,7 +83,7 @@ def build_say_payload(self, room, bot, text, apikey):
'room': room,
'bot': bot,
'text': demoji,
'bot_verifier': hashlib.sha1(str(bot + apikey).encode()).hexdigest(),
'bot_verifier': hashlib.sha1(f"{bot}{apikey}".encode()).hexdigest(),
}

def say_lingr(self, message, speaker='doge', anti_double_sec=15, anti_double=True):
Expand All @@ -99,7 +95,7 @@ def say_lingr(self, message, speaker='doge', anti_double_sec=15, anti_double=Tru
self.api_secret.get("room") is None:
return

if anti_double and self.check_flood("bot_say_"+speaker, anti_double_sec) is False:
if anti_double and not self.check_flood(f"bot_say_{speaker}", anti_double_sec):
print("301 Flood")
return

Expand All @@ -114,14 +110,15 @@ def say_slack(self, message, speaker='doge', anti_double_sec=15, anti_double=Tru
if self.api_secret.get("slack_webhook_url") is None:
return

if anti_double and self.check_flood("bot_say_slack_"+speaker, anti_double_sec) is False:
if anti_double and not self.check_flood(f"bot_say_slack_{speaker}", anti_double_sec):
print("301 Flood")
return

payload = {}
payload["text"] = message
payload["channel"] = "#general"
payload["username"] = "main"
payload = {
"text": message,
"channel": "#general",
"username": "main",
}
self.fetch(self.api_secret.get("slack_webhook_url"), payload=json.dumps(payload))

def doge_soku(self):
Expand All @@ -146,14 +143,14 @@ class HTMLParserGetElementsByTag(HTMLParser):
_count = 0

def __init__(self, target_tag, target_meta_property=None, count=None):
HTMLParser.__init__(self)
super().__init__()
self.target_tag = target_tag
self.target_meta_property = target_meta_property
self.countlimit = count
self._content = ''

def handle_starttag(self, tag, attrs):
if type(self.countlimit) is int and self._count >= self.countlimit:
if isinstance(self.countlimit, int) and self._count >= self.countlimit:
return

attrs = dict(attrs)
Expand All @@ -170,12 +167,6 @@ def handle_starttag(self, tag, attrs):
def handle_data(self, data):
self.concat_content(data)

def handle_charref(self, data):
self.concat_content(self.unescape('&#'+data+';'))

def handle_entityref(self, data):
self.concat_content(self.unescape('&'+data+';'))

def handle_endtag(self, tag):
if tag == self.target_tag:
self.reading = False
Expand Down
10 changes: 0 additions & 10 deletions subculture/doge.py

This file was deleted.

8 changes: 0 additions & 8 deletions subculture/knower.py

This file was deleted.

Loading
Loading