Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
OrBin committed Dec 21, 2022
2 parents b8c06c8 + 2c71e88 commit 9c736fe
Show file tree
Hide file tree
Showing 17 changed files with 251 additions and 96 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/release-helm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Release helm charts

on:
push:
tags:
- '*'
branches:
- dev

jobs:
release:
# depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
# see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Install Helm
uses: azure/setup-helm@v3
with:
version: v3.10.0

- name: Run chart-releaser
uses: helm/chart-releaser-action@v1.4.1
with:
charts_dir: helm
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
10 changes: 0 additions & 10 deletions SETUP_AND_CONFIGURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,6 @@ Getting a Telegram user ID can be done using [@userinfobot](https://telegram.me/
The bot will then print your user ID.
* To get the user ID of another user, just forward a message from this user and the bot will print their user ID.

### Mapping nicknames to user IDs
To use user nicknames, `~/.gramphopper/users.json` should contain an object in which the keys
are nicknames and the values are user IDs, for example:
```json
{
"nickname1": 123456789,
"nickname2": 987654321
}
```

## Rules configuration
The configuration file is located at `~/.gramphopper/rules.yml`.

Expand Down
31 changes: 17 additions & 14 deletions gramhopper/bot.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import logging
import os
from argparse import ArgumentParser
from pathlib import Path
from typing import Optional

from telegram.ext import Updater
from .logging_config import configure_logger
from .paths import token_file_path, default_rules_file_path
from .paths import TOKEN_FILE_PATH, DEFAULT_RULES_FILE_PATH
from .configuration.rules_parser import RulesParser
from .handlers.combined_handlers import CombinedConversationHandler
from .handlers.default_error_handler import handle_error


def _get_rules_file_path(config_path_input: Optional[str]):
if config_path_input:
config_path = os.path.expanduser(os.path.expandvars(config_path_input))
if os.access(config_path, os.R_OK):
return Path(config_path)

logging.warning(f'Cannot read {config_path}, defaulting to {DEFAULT_RULES_FILE_PATH}')

return DEFAULT_RULES_FILE_PATH


def start_bot():
""" Configures and runs the bot """
configure_logger()
Expand All @@ -18,22 +32,11 @@ def start_bot():
args = parser.parse_args()
logging.debug(f'Parsed arguments: {args}')

with open(token_file_path(), 'r', encoding='utf-8') as token_file:
bot_token = token_file.read().strip()
bot_token = TOKEN_FILE_PATH.read_text().strip()

rule_parser = RulesParser()

if args.config:
config_path = os.path.expanduser(os.path.expandvars(args.config))
print(config_path)
if os.access(config_path, os.R_OK):
rules_file_path = config_path
else:
rules_file_path = default_rules_file_path()
logging.warning(f'Cannot read {config_path}, defaulting to {rules_file_path}')
else:
rules_file_path = default_rules_file_path()

rules_file_path = _get_rules_file_path(args.config)
logging.info('Reading and parsing rules file from %s', rules_file_path)
rule_handlers = rule_parser.parse_file(rules_file_path)
logging.info('Found %d rules', len(rule_handlers))
Expand Down
8 changes: 4 additions & 4 deletions gramhopper/configuration/rules_parser.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
from os import PathLike
from typing import Union, List
from pathlib import Path
from typing import List
from ruamel.yaml import YAML
from ruamel.yaml import CommentedMap
from .rules_parsing_helper import RulesParsingHelper
Expand Down Expand Up @@ -29,8 +29,8 @@ def parse_single_rule(self, rule: CommentedMap) -> RuleHandler:
logging.info('Parsed %s', handler.handler_repr)
return handler

def parse_file(self, file_path: Union[PathLike, str, bytes]) -> List[RuleHandler]:
with open(file_path, 'r', encoding='utf-8') as stream:
def parse_file(self, file_path: Path) -> List[RuleHandler]:
with file_path.open('r', encoding='utf-8') as stream:
config = self.yaml.load(stream)

logging.info('Parsing globals from %s', file_path)
Expand Down
7 changes: 4 additions & 3 deletions gramhopper/handlers/default_error_handler.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import logging
from telegram import Bot, Update, TelegramError
from telegram import Update
from telegram.ext import CallbackContext


def handle_error(bot: Bot, update: Update, error: TelegramError):
def handle_error(update: Update, context: CallbackContext):
"""Log Errors caused by Updates."""
logging.error('Update "%s" caused error "%s" on bot "%s"', update, error, bot.name)
logging.error('Update "%s" caused error "%s" on bot "%s"', update, context.error, context.bot.name)
2 changes: 1 addition & 1 deletion gramhopper/handlers/rules_handler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import logging
import random
from telegram import Update, Bot
from telegram import Update
from telegram.ext import CallbackContext
from ..responses.basic_responses import BaseResponse
from ..triggers.basic_triggers import BaseTrigger
Expand Down
17 changes: 2 additions & 15 deletions gramhopper/paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,5 @@


CONFIG_DIR = Path(Path.home(), '.gramhopper/')
TOKEN_FILE_NAME = 'token.txt'
DEFAULT_RULES_FILE_NAME = 'rules.yml'
USERS_FILE_NAME = 'users.json'


def token_file_path():
return Path(CONFIG_DIR, TOKEN_FILE_NAME)


def default_rules_file_path():
return Path(CONFIG_DIR, DEFAULT_RULES_FILE_NAME)


def users_file_path():
return Path(CONFIG_DIR, USERS_FILE_NAME)
TOKEN_FILE_PATH = CONFIG_DIR / 'token.txt'
DEFAULT_RULES_FILE_PATH = CONFIG_DIR / 'rules.yml'
17 changes: 3 additions & 14 deletions gramhopper/triggers/filter_triggers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from ..dict_enum import DictEnum
from .trigger_result import TriggerResult
from .basic_triggers import BaseTrigger
from ..users_helper import DEFAULT_USERS_HELPER


class FilterBasedTrigger(BaseTrigger):
Expand Down Expand Up @@ -33,26 +32,16 @@ class _UserFilterBasedTrigger(FilterBasedTrigger):
specific user.
"""

def __init__(
self,
nickname: Optional[str] = None,
user_id: Optional[int] = None,
username: Optional[str] = None,
):
def __init__(self, user_id: Optional[int] = None, username: Optional[str] = None):
"""
Constructs the trigger.
`nickname` can be used if such a nickname is defined in users.json file.
Otherwise, one of `user_id` and `username` should be specified.
One of `user_id` and `username` should be specified.
:param message_filter: The filter to test if the message passes through
:param nickname: The nickname of the user to pass messages from.
:param user_id: The Telegram user ID of the user to pass messages from.
:param username: The Telegram username of the user to pass messages from.
"""
if nickname is not None:
super().__init__(Filters.user(DEFAULT_USERS_HELPER.get_user_id_by_nickname(nickname)))
else:
super().__init__(Filters.user(user_id, username))
super().__init__(Filters.user(user_id, username))


class _ChatFilterBasedTrigger(FilterBasedTrigger):
Expand Down
29 changes: 0 additions & 29 deletions gramhopper/users_helper.py

This file was deleted.

23 changes: 23 additions & 0 deletions helm/gramhopper/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
16 changes: 16 additions & 0 deletions helm/gramhopper/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v2
name: gramhopper
description: A rule-based Telegram bot engine, no coding required

type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 2.0.1

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "5.0.0"
33 changes: 33 additions & 0 deletions helm/gramhopper/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "gramhopper.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "gramhopper.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "gramhopper.labels" -}}
helm.sh/chart: {{ include "gramhopper.chart" . }}
{{ include "gramhopper.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "gramhopper.selectorLabels" -}}
app.kubernetes.io/name: {{ include "gramhopper.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
8 changes: 8 additions & 0 deletions helm/gramhopper/templates/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Values.configMapName }}
data:
token.txt: {{ required "Must provide gramhopper.botToken" .Values.gramhopper.botToken | quote }}
rules.yml: {{ required "Must provide gramhopper.rulesYaml" .Values.gramhopper.rulesYaml | quote }}
47 changes: 47 additions & 0 deletions helm/gramhopper/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gramhopper
spec:
replicas: 1
selector:
matchLabels:
{{- include "gramhopper.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "gramhopper.selectorLabels" . | nindent 8 }}
spec:
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: gramhopper-config-volume
mountPath: /root/.gramhopper
volumes:
- name: gramhopper-config-volume
configMap:
name: gramhopper-config
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

0 comments on commit 9c736fe

Please sign in to comment.