This commit is contained in:
Administrator 2022-10-03 16:32:43 +03:00
commit 149c251bfa
15 changed files with 315 additions and 0 deletions

53
.deploy/deploy-dev.yaml Normal file
View File

@ -0,0 +1,53 @@
version: "3.4"
services:
b-jokes-nginx:
image: mathwave/sprint-repo:b-jokes-nginx
networks:
- b-jokes-net
- b-jokes-nginx
deploy:
mode: replicated
restart_policy:
condition: any
update_config:
parallelism: 1
order: start-first
api:
image: mathwave/sprint-repo:b-jokes
networks:
- b-jokes-net
environment:
MONGO_HOST: "mongo.develop.sprinthub.ru"
DB_PASSWORD: $MONGO_PASSWORD_DEV
command: api
deploy:
mode: replicated
restart_policy:
condition: any
update_config:
parallelism: 1
order: start-first
poll:
image: mathwave/sprint-repo:b-jokes
environment:
MONGO_HOST: "mongo.develop.sprinthub.ru"
DB_PASSWORD: $MONGO_PASSWORD_DEV
command: poll
deploy:
mode: replicated
restart_policy:
condition: any
update_config:
parallelism: 1
order: start-first
networks:
b-jokes-net:
driver: overlay
b-jokes-nginx:
external: true

53
.deploy/deploy-prod.yaml Normal file
View File

@ -0,0 +1,53 @@
version: "3.4"
services:
b-jokes-nginx:
image: mathwave/sprint-repo:b-jokes-nginx
networks:
- b-jokes-net
- b-jokes-nginx
deploy:
mode: replicated
restart_policy:
condition: any
update_config:
parallelism: 1
order: start-first
api:
image: mathwave/sprint-repo:b-jokes
networks:
- b-jokes-net
environment:
MONGO_HOST: "mongo.sprinthub.ru"
DB_PASSWORD: $MONGO_PASSWORD_PROD
command: api
deploy:
mode: replicated
restart_policy:
condition: any
update_config:
parallelism: 1
order: start-first
poll:
image: mathwave/sprint-repo:b-jokes
environment:
MONGO_HOST: "mongo.sprinthub.ru"
DB_PASSWORD: $MONGO_PASSWORD_PROD
command: poll
deploy:
mode: replicated
restart_policy:
condition: any
update_config:
parallelism: 1
order: start-first
networks:
b-jokes-net:
driver: overlay
b-jokes-nginx:
external: true

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
venv
.idea

46
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,46 @@
stages:
- build
- deploy-dev
- deploy-prod
build:
stage: build
tags:
- dev
before_script:
- docker login -u mathwave -p $DOCKERHUB_PASSWORD
script:
- docker build -t mathwave/sprint-repo:b-jokes .
- docker push mathwave/sprint-repo:b-jokes
- docker build -t mathwave/sprint-repo:b-jokes-nginx nginx
- docker push mathwave/sprint-repo:b-jokes-nginx
.deploy:
before_script:
- docker login -u mathwave -p $DOCKERHUB_PASSWORD
- docker network create -d overlay --attachable b-jokes-nginx || true
deploy-dev:
extends:
- .deploy
stage: deploy-dev
tags:
- dev
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: on_success
- when: manual
script:
- docker stack deploy -c ./.deploy/deploy-dev.yaml b-jokes
deploy-prod:
extends:
- .deploy
stage: deploy-prod
tags:
- prod
only:
- master
when: manual
script:
- docker stack deploy -c ./.deploy/deploy-prod.yaml b-jokes

7
Dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM python:3.10
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
ENTRYPOINT ["python", "entrypoint.py"]

12
entrypoint.py Normal file
View File

@ -0,0 +1,12 @@
import sys
import main
from helpers import jokes
arg = sys.argv[-1]
if arg == "poll":
jokes.poll_jokes()
elif arg == "api":
main.run()
else:
raise NotImplementedError("No arg specified!")

0
helpers/__init__.py Normal file
View File

31
helpers/jokes.py Normal file
View File

@ -0,0 +1,31 @@
from time import sleep
from requests import get
from helpers.mongo import mongo
def fetch_jokes():
i = 1
while True:
info = get(f"https://baneks.ru/{i}")
if info.status_code == 200:
print(i)
content = info.text
anek = content.split("<p>")[1].split("</p>")[0].replace("<br />", "")
if '<a href="random">' in anek:
break
if mongo.jokes_collection.find_one({"id": i}) is None:
mongo.jokes_collection.insert_one({
"id": i,
"text": anek
})
i += 1
def poll_jokes():
while True:
print("start fetching jokes")
fetch_jokes()
print("finished fetching jokes")
sleep(60 * 60 * 24)

22
helpers/mongo.py Normal file
View File

@ -0,0 +1,22 @@
from functools import cached_property
import pymongo
import settings
class Mongo:
def __init__(self):
url = f"mongodb://{settings.MONGO_USER}:{settings.MONGO_PASSWORD}@{settings.MONGO_HOST}:27017/"
self.client = pymongo.MongoClient(url)
self.database = self.client.get_database("b-jokes")
def __getitem__(self, item):
return self.database.get_collection(item)
@cached_property
def jokes_collection(self):
return self["jokes"]
mongo = Mongo()

25
main.py Normal file
View File

@ -0,0 +1,25 @@
import json
from flask import Flask, request
from processor import Processor
def run():
app = Flask(__name__)
@app.route('/', methods=['POST'])
def main():
req = request.json
processor = Processor(req)
response = {
"version": req['version'],
"session": req['session'],
"response": {
"end_session": False
}
}
response['response'].update(processor.process())
return response
app.run()

2
nginx/Dockerfile Normal file
View File

@ -0,0 +1,2 @@
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf

12
nginx/nginx.conf Normal file
View File

@ -0,0 +1,12 @@
events {}
http {
server {
listen 1238;
location / {
proxy_pass http://api:5000/;
}
}
}

36
processor.py Normal file
View File

@ -0,0 +1,36 @@
from functools import cached_property
class Processor:
def __init__(self, data: dict):
self.data = data
self.user_id = data['session']['user']['user_id']
self.message = data['request']['original_utterance']
def next(self):
...
def save(self):
...
def finish(self):
return {
"text": "Пока-пока, заходи еще",
"end_session": True
}
@cached_property
def handlers(self) -> dict:
return {
"следующий": self.next,
"сохрани": self.save,
"закончить": self.finish
}
def process(self) -> dict:
action = self.handlers.get(self.message)
if action is None:
return {
"text": f"Я не понимаю этой команды. Я могу выполнить только действия: {', '.join(self.handlers.keys())}"
}
return action()

7
requirements.txt Normal file
View File

@ -0,0 +1,7 @@
click==8.1.3
Flask==2.2.2
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
pymongo==4.2.0
Werkzeug==2.2.2

7
settings.py Normal file
View File

@ -0,0 +1,7 @@
import os
MONGO_USER = os.getenv("MONGO_USER", "mongo")
MONGO_PASSWORD = os.getenv("MONGO_PASSWORD", "password")
MONGO_HOST = os.getenv("MONGO_HOST", "localhost")
DIALOG_ID = os.getenv("DIALOG_ID", None)