33 Commits

Author SHA1 Message Date
2785d3d6b6 Пофиксил баг
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is passing
2021-11-01 06:07:41 +03:00
f4732836ad Сделал нормальные JSON ответы
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 06:05:33 +03:00
b0bd579357 Верну тишину
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 05:56:22 +03:00
fd341bd9df Поправил тест
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 05:54:36 +03:00
4608125fdf Smol fixes 2021-11-01 05:25:57 +03:00
8e52e543f9 Верну проброс конфига
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 05:19:39 +03:00
80aeafa013 Короче проще поправить конфиг 2021-11-01 05:17:40 +03:00
66d68701c2 Revert "В репе конфиг не нужен"
Some checks failed
continuous-integration/drone/push Build is failing
Все пошло не так

This reverts commit 0ba3b5f037.
2021-11-01 05:13:35 +03:00
94a626e7f1 Не будем пробрасывать конфиг (а нужно ли его вытаскивать наружу?)
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 05:07:50 +03:00
0ba3b5f037 В репе конфиг не нужен
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2021-11-01 05:02:12 +03:00
7544e3c447 Добавил конфигурацию самого приложения
Some checks failed
continuous-integration/drone/push Build is failing
2021-11-01 04:58:13 +03:00
96790be6f7 Вернул метрики
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 04:46:07 +03:00
89dcffa6bb Merge pull request 'prometheus-monitoring' (#3) from prometheus-monitoring into master
All checks were successful
continuous-integration/drone/push Build is passing
Reviewed-on: http://git.lulzette.ru/lulzette/pycms/pulls/3
2021-11-01 04:40:18 +03:00
4f736f763e Нет, надо вот так
Some checks failed
continuous-integration/drone/pr Build is failing
continuous-integration/drone/push Build is passing
continuous-integration/drone Build is failing
2021-11-01 04:38:54 +03:00
f84994999a Добавил остановку текущих контейнеров
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is failing
2021-11-01 04:36:41 +03:00
74cd6c6d4b Revert "Добавил простую метрику"
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone/pr Build is passing
Тут этого быть не должно 0_0

This reverts commit 54139d6f76.
2021-11-01 04:30:27 +03:00
49f981708a Добавил шагов
All checks were successful
continuous-integration/drone/push Build is passing
2021-11-01 04:28:02 +03:00
54139d6f76 Добавил простую метрику
All checks were successful
continuous-integration/drone/push Build is passing
2021-10-31 02:24:54 +03:00
4ab80616a6 Добавил название проекта
All checks were successful
continuous-integration/drone/push Build is passing
2021-10-19 10:32:58 +00:00
04905c59db Merge pull request 'Настроил сборку в drone' (#2) from drone into master
Some checks failed
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is passing
Reviewed-on: http://git.lulzette.ru/lulzette/pycms/pulls/2
2021-10-19 05:29:56 +03:00
c4602b9d4e change runner
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is passing
2021-10-19 02:26:08 +00:00
2f5867028e fix
Some checks reported errors
continuous-integration/drone/push Build is failing
continuous-integration/drone Build was killed
2021-10-19 02:16:18 +00:00
1aa4be2e47 Drone
Some checks reported errors
continuous-integration/drone/push Build encountered an error
2021-10-19 02:14:31 +00:00
3aa77129ec Кое-какие тесты 2021-10-19 00:53:17 +00:00
32a2678170 Запихнул в docker-compose 2021-10-18 15:16:02 +00:00
6cd33f25be requirements 2021-10-18 13:51:01 +00:00
7c7db5bca0 Добавил timestamp создания записи 2021-09-27 02:25:02 +03:00
755e7c5ce4 Проверка на существование БД/коллекции 2021-09-27 02:19:19 +03:00
85a860eb1a TODO's 2021-09-20 02:18:03 +03:00
5aecf2d643 Some fixes 2021-09-18 04:48:04 +03:00
f72c941a3a Сделал создание конфига при его отсутствии 2021-09-17 15:57:50 +03:00
539d53d209 Добавил чтение конфига 2021-09-17 15:50:18 +03:00
28b98a9127 Добавил класс с конфигом, поправил вызов классов 2021-09-17 15:29:50 +03:00
7 changed files with 188 additions and 38 deletions

22
.drone.yml Normal file
View File

@@ -0,0 +1,22 @@
kind: pipeline
type: exec
name: build
steps:
- name: build
commands:
- docker-compose -p pycms build
- name: test
commands:
- docker-compose -p pycms up --build --abort-on-container-exit
- name: push
commands:
- docker-compose -p pycms push
- name: run
commands:
- docker-compose -p pycms down
- docker-compose -p pycms up -d

9
Dockerfile Normal file
View File

@@ -0,0 +1,9 @@
FROM python:latest
ADD . /app
WORKDIR /app
RUN pip3 install --upgrade pip && pip3 install -r requirements.txt
EXPOSE 8080
CMD python3 main.py

8
config.ini Normal file
View File

@@ -0,0 +1,8 @@
[DB]
host = db
port = 27017
name = pycms
[App]
host = 0.0.0.0
port = 8080
debug = True

18
docker-compose.yml Normal file
View File

@@ -0,0 +1,18 @@
version: '3'
services:
server:
build: .
ports:
- 8080:8080
depends_on:
- db
volumes:
- ./config.ini:/app/config.ini
db:
image: mongo
tests:
build: .
command: bash ./test.sh
depends_on:
- db
- server

154
main.py
View File

@@ -1,60 +1,138 @@
#!/usr/bin/python3 #!/usr/bin/python3
from bottle import abort, route, run, request from bottle import abort, route, run, request
import pymongo import pymongo
import time
mongoclient = pymongo.MongoClient('localhost', 27017) # TODO: auth to /admin
database = mongoclient['pycms'] # TODO: timestamps to posts
posts = database['posts'] # TODO: author to posts and multiple users
# TODO: add bottle's params to config
class Init: class Config:
def readConfig(): """
posts - table with posts
config structure:
DB:
- host
- port
- dbname
App:
- host
- port
- debug
"""
def __init__(self):
""" """
Read config file, if not exists - call Init.createConfig() Init config
""" """
pass self.readConfig()
def createConfig(): mongoclient = pymongo.MongoClient(self.host, self.port)
if self.dbname not in mongoclient.list_database_names():
print('DB not found, creating')
database = mongoclient[self.dbname]
if 'posts' not in database.list_collection_names():
print('Table not found, creating')
posts = database['posts']
self.posts = posts
def readConfig(self):
"""
Read config file, if not exists - call self.createConfig()
"""
import configparser
config = configparser.ConfigParser()
if not config.read('config.ini'):
self.createConfig(config)
db = config['DB']
self.host = db['host']
self.port = int(db['port'])
self.dbname = db['name']
app = config['App']
self.apphost = app['host']
self.appport = int(app['port'])
self.appdebug = bool(app['debug'])
def createConfig(self, config):
""" """
Create config file Create config file
""" """
pass config['DB'] = {}
db = config['DB']
db['host'] = 'localhost'
db['port'] = '27017'
db['name'] = 'pycms'
def setupConnect(): config['App'] = {}
""" app = config['App']
Setup MongoDB connection app['port'] = '8080'
""" app['debug'] = 'True'
pass app['host'] = '0.0.0.0'
with open('config.ini', 'w') as cfgfile:
config.write(cfgfile)
class Back: class Back():
""" """
All actions that will be triggered by http All actions that will be triggered by http
""" """
def getRootPost(): def getRootPost(self):
try: try:
return posts.find_one({'name': '_root_'})['text'] return posts.find_one({'name': '_root_'})['text']
except TypeError: except TypeError:
return abort(404, 'No such page') return abort(404, 'No such page')
def getPost(name): def getPost(self, name):
try: try:
return posts.find_one({'name': name})['text'] return posts.find_one({'name': name})['text']
except TypeError: except TypeError:
return abort(404, 'No such page') return abort(404, 'No such page')
def updatePost(name, body): def getAllPosts(self):
# TODO: clear up output, remove '_id' and 'body',
# now there should be only
dict_posts = list()
for i in posts.find():
dict_posts.append(i)
return str(dict_posts)
def updatePost(self, name, body):
# If post exists, update it # If post exists, update it
if posts.find_one({'name': name}): if posts.find_one({'name': name}):
newPost = {'$set': {'text': body}} newPostJson = {'$set': {'text': body}}
return str(posts.update_one({'name': name}, newPost)) newPost = posts.update_one({'name': name}, newPostJson)
result = dict(
status=200, state='updated', count=newPost.matched_count
)
# Else - create new # Else - create new
else: else:
newPost = {'name': name, 'text': body} newPostJson = {'name': name, 'text': body,
return str(posts.insert_one(newPost).inserted_id) 'create_timestamp': str(time.time())}
newPost = posts.insert_one(newPostJson).inserted_id
result = dict(status=200, state='new')
return str(result)
def deletePost(name): def deletePost(self, name):
return posts.delete_one({'name': name}) delete = posts.delete_one({'name': name}).deleted_count
if not delete:
result = dict(status=500, count=delete)
else:
result = dict(status=200, count=delete)
return str(result)
class Metrics:
def alive():
return str("alive 1")
@route('/metrics')
def metrics():
return Metrics.alive()
@route('/post/<name>') @route('/post/<name>')
@@ -62,25 +140,24 @@ def post(name):
''' '''
Get post Get post
''' '''
return Back.getPost(name) return str(back.getPost(name))
@route('/post/<name>', method='POST') @route('/admin/post/<name>', method='POST')
def postUpd(name): def postUpd(name):
''' '''
Insert/Update post Insert/Update post
''' '''
body = request.forms.get('body') body = request.forms.get('body')
return Back.updatePost(name=name, body=body) return back.updatePost(name=name, body=body)
@route('/post/<name>', method='DELETE') @route('/admin/post/<name>', method='DELETE')
def postDel(name): def postDel(name):
''' '''
Delete post by name Delete post by name
''' '''
# return str(posts.delete_one({'name':name})) return str(back.deletePost(name))
return str(Back.deletePost(name))
@route('/post') @route('/post')
@@ -88,17 +165,18 @@ def all_posts():
''' '''
Returns all posts Returns all posts
''' '''
dict_posts = list() return back.getAllPosts()
for i in posts.find():
dict_posts.append(i)
return str(dict_posts)
@route('/') @route('/')
def index(): def index():
return Back.getRootPost() return back.getRootPost()
if __name__ == '__main__': if __name__ == '__main__':
run(host='0.0.0.0', port=8081, reloader=True, debug=True) print("Init")
cfg = Config()
print("Configured")
back = Back()
posts = cfg.posts
run(host=cfg.apphost, port=cfg.appport, reloader=cfg.appdebug, debug=cfg.appdebug)

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
bottle==0.12.19
pymongo==3.12.0

13
test.sh Normal file
View File

@@ -0,0 +1,13 @@
#!/bin/bash
curl_cmd='curl -s -w :%{http_code}'
#curl_cmd='curl -s -w "%{http_code}\t%{stdout}" -o /dev/null'
url='server:8080'
$curl_cmd -X POST $url/admin/post/test -F 'body=testpage' && echo ": Create success" || echo ': create fail'
$curl_cmd $url/post/test && echo ": get Success" || echo ': get fail'
$curl_cmd -X POST $url/admin/post/test -F 'body=testpage2' && echo ": Update success" || echo ': update fail'
$curl_cmd -X DELETE $url/admin/post/test && echo ": delete success" || echo ': delete fail'
$curl_cmd $url/metrics && echo ": metrics available" || echo ': metrics unavailable'