Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • telegram-bots/lenochka
  • aisus/volodya
2 results
Show changes
Commits on Source (9)
Showing with 1146 additions and 1291 deletions
......@@ -65,6 +65,11 @@ ignore =
; Found function with too much cognitive complexity
WPS231,
per-file-ignores =
; all tests
test_*.py,tests.py,tests_*.py,*/tests/*:
; Use of assert detected
S101,
; all init files
__init__.py:
; ignore not used imports
......@@ -74,12 +79,6 @@ ignore =
; Found wrong metadata variable
WPS410,
per-file-ignores =
; all tests
test_*.py,tests.py,tests_*.py,*/tests/*:
; Use of assert detected
S101,
exclude =
./.git,
./venv,
......
# Byte-compiled / optimized / DLL files
.vscode/
.idea/
.gen.env
__pycache__/
*.py[cod]
......
stages:
- tools
- test
- cleanup_tests
- build
- deploy
build_test:
stage: tools
tags:
- bots-deployer
script:
- make build-test
flake8:
stage: test
tags:
- bots-deployer
script:
- make flake8
pytest:
stage: test
tags:
- bots-deployer
script:
- make pytest
black:
stage: test
tags:
- bots-deployer
script:
- make black
mypy:
stage: test
tags:
- bots-deployer
script:
- make mypy
cleanup_tests:
stage: cleanup_tests
tags:
- bots-deployer
when: always
script:
- make clear-test
build:
stage: build
image:
name: alpine:3.18
entrypoint: [""]
tags:
- kube
only:
- master
- tags
tags:
- bots-deployer
script:
- make build push
- apk add --no-cache img
- img login --password "$CI_JOB_TOKEN" --username "$CI_REGISTRY_USER" "$CI_REGISTRY"
- img build --no-console -t "$CI_REGISTRY/telegram-bots/lenochka:latest" .
- img push "$CI_REGISTRY/telegram-bots/lenochka:latest"
deploy:
stage: deploy
image:
name: alpine/helm:3.13.2
entrypoint: ["/bin/sh", "-c"]
tags:
- kube
only:
- master
- tags
when: manual
tags:
- bots-deployer
script:
- make deploy-prod
- helm
upgrade
lenochka
./helm
--install
--wait
--create-namespace
--atomic
--timeout 2m
--namespace "$NAMESPACE"
-f "$HELM_CONFIG"
--set "podAnnotations.deployed_at=$(date +%Y.%m.%d-%H:%M)"
--set image.repository="$CI_REGISTRY/telegram-bots/lenochka"
--set image.tag="latest"
......@@ -12,7 +12,7 @@ repos:
- repo: https://github.com/asottile/add-trailing-comma
rev: v2.1.0
hooks:
- id: add-trailing-comma
- id: add-trailing-comma
- repo: local
hooks:
......@@ -26,38 +26,46 @@ repos:
name: autoflake
entry: autoflake
language: system
types: [ python ]
args: [ --in-place, --remove-all-unused-imports, --remove-duplicate-keys ]
types: [python]
args:
[
--in-place,
--remove-all-unused-imports,
--remove-duplicate-keys,
--recursive,
lenochka,
]
- id: isort
name: isort
entry: isort
language: system
types: [ python ]
types: [python]
- id: flake8
name: Check with Flake8
entry: flake8
language: system
pass_filenames: false
types: [ python ]
args: [--count, .]
types: [python]
args: [--count, lenochka]
- id: mypy
name: Validate types with MyPy
entry: mypy
language: system
types: [ python ]
pass_filenames: false
args: [lenochka]
- id: yesqa
name: Remove usless noqa
entry: yesqa
language: system
types: [ python ]
types: [python]
- id: pytest
name: pytest
entry: pytest
language: system
pass_filenames: false
types: [ python ]
types: [python]
FROM python:3.9-alpine3.13
FROM python:3.9.6-slim-buster
RUN adduser --disabled-password lenochka
RUN apk add --no-cache curl gcc musl-dev
ENV POETRY_VERSION 1.1.6
USER lenochka
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
RUN pip install poetry==1.5.1
ENV PATH="${PATH}:/home/lenochka/.poetry/bin:/home/lenochka/.local/bin"
RUN source "/home/lenochka/.poetry/env"
# Installing requirements
RUN poetry config virtualenvs.create false
COPY pyproject.toml poetry.lock /home/lenochka/app/
WORKDIR /home/lenochka/app/
RUN poetry install --only main
RUN poetry install --no-dev
# Copying actuall application
COPY . /home/lenochka/app/src/
WORKDIR /home/lenochka/app/src/
RUN pip install --use-feature=in-tree-build .
WORKDIR /home/lenochka/app
USER root
RUN rm -rf /home/lenochka/app/src
RUN chown -R lenochka /home/lenochka
RUN chmod -R 700 /home/lenochka
RUN apk del curl gcc musl-dev
USER lenochka
RUN poetry install --only main
CMD "lenochka_wake_up"
version: '3.7'
services:
test_lenochka:
container_name: the_test_lenochka
build:
dockerfile: ./deploy/dockerfiles/test.Dockerfile
context: .
networks:
- lenochka_test_network
networks:
lenochka_test_network:
name: lenochka_test_network
version: '3.7'
services:
lenochka:
container_name: the_lenochka
build:
dockerfile: ./deploy/dockerfiles/Dockerfile
context: .
image: docker.le-memese.com/bots/lenochka-bot:${CI_COMMIT_REF_SLUG:-latest}
env_file:
- .gen.env
FROM python:3.9-alpine3.13
RUN apk add --no-cache curl gcc musl-dev
ENV POETRY_VERSION 1.1.6
RUN curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
ENV PATH="${PATH}:/root/.local/bin:/root/.poetry/bin"
RUN source "/root/.poetry/env"
# Installing requirements
RUN poetry config virtualenvs.create false
COPY . /app/
WORKDIR /app/
RUN poetry install
# 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/
apiVersion: v2
name: lenochka
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
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: 0.1.0
# 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: "1.16.0"
{{/*
Expand the name of the chart.
*/}}
{{- define "lenochka.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "lenochka.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "lenochka.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "lenochka.labels" -}}
helm.sh/chart: {{ include "lenochka.chart" . }}
{{ include "lenochka.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "lenochka.selectorLabels" -}}
app.kubernetes.io/name: {{ include "lenochka.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "lenochka.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "lenochka.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "lenochka.fullname" . }}
labels:
{{- include "lenochka.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
{{- include "lenochka.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "lenochka.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "lenochka.serviceAccountName" . }}
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 }}
{{- with .Values.env }}
env:
{{- range $key, $val := . }}
- name: {{ $key | quote }}
value: {{ $val | quote }}
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "lenochka.serviceAccountName" . }}
labels:
{{- include "lenochka.labels" . | nindent 4 }}
{{- with .Values.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
# Default values for lenochka.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
image:
repository: docker.le-memese.com/bots/lenochka-bot
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: ""
env: {}
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
{}
# fsGroup: 2000
securityContext:
{}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
resources:
{}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
nodeSelector: {}
tolerations: []
affinity: {}
......@@ -24,7 +24,5 @@ class Brain:
:param state_of_mind: lenochka's current state of mind.
It's always clear in order to make the most thoughtful answer.
"""
if not self.cell.do_i_need_to_say_something():
return
thoughtful_answer = self.cell.create_reply(message.text)
await message.reply(thoughtful_answer)
if thoughtful_answer := self.cell.create_reply(message.text):
await message.reply(thoughtful_answer)
import re
import secrets
from typing import Optional
MAX_TRIGGER_WORDS = 3
WORD_PATTERN = re.compile(r"(\w+)")
......@@ -11,20 +12,7 @@ class BrainCell:
It decides when and what to say.
"""
def do_i_need_to_say_something(self) -> bool:
"""
One of the most important decisions.
This brain cell's function looks
deep inside the palaces of the mind,
searching through the secrets of the universe
and decides if she want to say something.
:return: The decision.
"""
return secrets.randbelow(11) < 1 # noqa: WPS432
def create_reply(self, sentence: str) -> str:
def create_reply(self, sentence: str) -> Optional[str]:
"""
The hardest action to accomplish.
......@@ -36,10 +24,10 @@ class BrainCell:
:return: actual reply.
"""
tokens = WORD_PATTERN.findall(sentence)
for token in reversed(tokens):
token_parts = token.lower().split("да")
if len(token_parts) > 1:
postfix = token_parts[-1]
break
return f"Пизда{postfix}."
if not tokens or len(tokens) > MAX_TRIGGER_WORDS:
return None
*_, last_token = tokens
last_token_parts = last_token.lower().split("да")
if len(last_token_parts) > 1:
return f"Пизда{last_token_parts[-1]}."
return None
......@@ -8,7 +8,10 @@ class Memory(BaseSettings):
It holds the most important things for lenochka's life.
"""
token: str = Field(env="LENOCHKA_INSTAGRAM_ID", required=True)
token: str = Field(..., env="LENOCHKA_INSTAGRAM_ID")
class Config:
env_file = ".env"
memory = Memory()
memory = Memory() # type: ignore
This diff is collapsed.
......@@ -9,21 +9,21 @@ python = "^3.9"
aiogram = "^2.13"
pydantic = "^1.8.2"
[tool.poetry.dev-dependencies]
pytest = "^5.2"
black = "^21.5b2"
isort = "^5.8.0"
wemake-python-styleguide = "^0.15.2"
flake8 = "^3.9.2"
mypy = "^0.812"
yesqa = "^1.2.3"
autoflake = "^1.4"
pytest-env = "^0.6.2"
pytest-cov = "^2.12.1"
[tool.poetry.scripts]
lenochka_wake_up = "lenochka.mouth:talk_to_the_wind"
[tool.poetry.group.dev.dependencies]
pytest = "^7.4.2"
black = "^23.9.1"
isort = "^5.12.0"
flake8 = "^6.1.0"
mypy = "^1.5.1"
yesqa = "^1.5.0"
pytest-env = "^1.0.1"
pytest-cov = "^4.1.0"
autoflake = "^2.2.1"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"