[DEV] a basic version
This commit is contained in:
parent
317b7cc26a
commit
54db5f4a7f
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
config.*
|
||||
config.env
|
||||
.env
|
||||
config
|
||||
data
|
||||
cache
|
||||
|
20
Dockerfile
Executable file
20
Dockerfile
Executable file
@ -0,0 +1,20 @@
|
||||
FROM python:alpine
|
||||
|
||||
RUN pip install --upgrade pip
|
||||
|
||||
RUN pip install flask
|
||||
|
||||
RUN pip install flask_restful
|
||||
|
||||
RUN pip install python-dateutil
|
||||
|
||||
RUN pip install realog
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
ADD src /application/
|
||||
WORKDIR /application/
|
||||
CMD ["python", "-u", "./app_video.py"]
|
||||
|
||||
|
||||
|
10
docker-compose.yaml
Executable file
10
docker-compose.yaml
Executable file
@ -0,0 +1,10 @@
|
||||
version: '3'
|
||||
services:
|
||||
REST_video_service:
|
||||
build: .
|
||||
restart: always
|
||||
image: yui.heero/video_rest_api
|
||||
container_name: video_rest_api
|
||||
ports:
|
||||
- 15080:80
|
||||
|
BIN
src/__pycache__/data_global_elements.cpython-38.pyc
Normal file
BIN
src/__pycache__/data_global_elements.cpython-38.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/data_interface.cpython-38.pyc
Normal file
BIN
src/__pycache__/data_interface.cpython-38.pyc
Normal file
Binary file not shown.
BIN
src/__pycache__/tools.cpython-38.pyc
Normal file
BIN
src/__pycache__/tools.cpython-38.pyc
Normal file
Binary file not shown.
280
src/app_video.py
Executable file
280
src/app_video.py
Executable file
@ -0,0 +1,280 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
##
|
||||
## @author Edouard DUPIN
|
||||
##
|
||||
## @copyright 2019, Edouard DUPIN, all right reserved
|
||||
##
|
||||
## @license MPL v2.0 (see license file)
|
||||
##
|
||||
#pip install flask --user
|
||||
#pip install flask_restful --user
|
||||
#pip install python-dateutil --user
|
||||
|
||||
from flask import Flask
|
||||
from flask_restful import Api, Resource, reqparse
|
||||
import dateutil.parser
|
||||
|
||||
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import datetime
|
||||
import time, threading
|
||||
import realog.debug as debug
|
||||
|
||||
import config
|
||||
import tools
|
||||
import data_interface
|
||||
import data_global_elements
|
||||
|
||||
|
||||
debug.info("connect BDD interface");
|
||||
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
api = Api(app)
|
||||
|
||||
def add_interface(_name):
|
||||
data_global_elements.add_interface(_name, data_interface.DataInterface(_name, os.path.join(tools.get_run_path(), "data", "bdd_" + _name + ".json")))
|
||||
|
||||
API_THEME = "theme"
|
||||
add_interface(API_THEME)
|
||||
API_GROUP = "group"
|
||||
add_interface(API_GROUP)
|
||||
API_SAISON = "saison"
|
||||
add_interface(API_SAISON)
|
||||
API_VIDEO = "video"
|
||||
add_interface(API_VIDEO)
|
||||
|
||||
"""
|
||||
LIST_themes = [
|
||||
{
|
||||
'id': 0,
|
||||
'name': 'Documentary',
|
||||
'description': 'Documentary (annimals, space, earth...)',
|
||||
},{
|
||||
'id': 1,
|
||||
'name': 'Movie',
|
||||
'description': 'Movie with real humans (film)',
|
||||
},{
|
||||
'id': 2,
|
||||
'name': 'Annimation',
|
||||
'description': 'Annimation movies (film)',
|
||||
},{
|
||||
'id': 3,
|
||||
'name': 'Short Films',
|
||||
'description': 'Small movies (less 2 minutes)',
|
||||
},{
|
||||
'id': 4,
|
||||
'name': 'tv show',
|
||||
'description': 'Tv show form old peoples',
|
||||
}, {
|
||||
'id': 5,
|
||||
'name': 'Anniation tv show',
|
||||
'description': 'Tv show form young peoples',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class ThemeList(Resource):
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/theme
|
||||
def get(self):
|
||||
debug.info("Request temes: " + str(time))
|
||||
return LIST_themes, 200
|
||||
|
||||
class Theme(Resource):
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/theme/xxx
|
||||
def get(self, id):
|
||||
debug.info("Request theme: " + str(id))
|
||||
for elem in LIST_themes:
|
||||
if 'id' in elem.keys() \
|
||||
and elem["id"] == id:
|
||||
return elem, 200
|
||||
return "No data found in list of element: " + str(len(LIST_themes)), 404
|
||||
"""
|
||||
|
||||
class ThemeList(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_THEME
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/theme
|
||||
def get(self):
|
||||
return data_global_elements.get_interface(self.name).gets(), 200
|
||||
|
||||
"""
|
||||
def post(self):
|
||||
args = parser.parse_args()
|
||||
todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
|
||||
todo_id = 'todo%i' % todo_id
|
||||
TODOS[todo_id] = {'task': args['task']}
|
||||
return TODOS[todo_id], 201
|
||||
"""
|
||||
|
||||
class Theme(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_THEME
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/theme/xxx
|
||||
def get(self, id):
|
||||
value = data_global_elements.get_interface(self.name).get(id)
|
||||
if value != None:
|
||||
return value, 200
|
||||
return "No data found", 404
|
||||
|
||||
def delete(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).delete(id)
|
||||
if ret == True:
|
||||
return '', 204
|
||||
return "No data found", 404
|
||||
"""
|
||||
def put(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).put(id)
|
||||
return task, 201
|
||||
"""
|
||||
|
||||
api.add_resource(ThemeList, "/api/v1/" + API_THEME)
|
||||
api.add_resource(Theme, "/api/v1/" + API_THEME + "/<int:id>")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
class GroupList(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_GROUP
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/Group
|
||||
def get(self):
|
||||
return data_global_elements.get_interface(self.name).gets(), 200
|
||||
|
||||
"""
|
||||
def post(self):
|
||||
args = parser.parse_args()
|
||||
todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
|
||||
todo_id = 'todo%i' % todo_id
|
||||
TODOS[todo_id] = {'task': args['task']}
|
||||
return TODOS[todo_id], 201
|
||||
"""
|
||||
|
||||
class Group(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_GROUP
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/Group/xxx
|
||||
def get(self, id):
|
||||
value = data_global_elements.get_interface(self.name).get(id)
|
||||
if value != None:
|
||||
return value, 200
|
||||
return "No data found", 404
|
||||
|
||||
def delete(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).delete(id)
|
||||
if ret == True:
|
||||
return '', 204
|
||||
return "No data found", 404
|
||||
"""
|
||||
def put(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).put(id)
|
||||
return task, 201
|
||||
"""
|
||||
|
||||
api.add_resource(GroupList, "/api/v1/" + API_GROUP)
|
||||
api.add_resource(Group, "/api/v1/" + API_GROUP + "/<int:id>")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
class SaisonList(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_SAISON
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/Saison
|
||||
def get(self):
|
||||
return data_global_elements.get_interface(self.name).gets(), 200
|
||||
|
||||
"""
|
||||
def post(self):
|
||||
args = parser.parse_args()
|
||||
todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
|
||||
todo_id = 'todo%i' % todo_id
|
||||
TODOS[todo_id] = {'task': args['task']}
|
||||
return TODOS[todo_id], 201
|
||||
"""
|
||||
|
||||
class Saison(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_SAISON
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/Saison/xxx
|
||||
def get(self, id):
|
||||
value = data_global_elements.get_interface(self.name).get(id)
|
||||
if value != None:
|
||||
return value, 200
|
||||
return "No data found", 404
|
||||
|
||||
def delete(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).delete(id)
|
||||
if ret == True:
|
||||
return '', 204
|
||||
return "No data found", 404
|
||||
"""
|
||||
def put(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).put(id)
|
||||
return task, 201
|
||||
"""
|
||||
|
||||
api.add_resource(SaisonList, "/api/v1/" + API_SAISON)
|
||||
api.add_resource(Saison, "/api/v1/" + API_SAISON + "/<int:id>")
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
|
||||
class VideoList(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_VIDEO
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/Video
|
||||
def get(self):
|
||||
return data_global_elements.get_interface(self.name).gets(), 200
|
||||
|
||||
"""
|
||||
def post(self):
|
||||
args = parser.parse_args()
|
||||
todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1
|
||||
todo_id = 'todo%i' % todo_id
|
||||
TODOS[todo_id] = {'task': args['task']}
|
||||
return TODOS[todo_id], 201
|
||||
"""
|
||||
|
||||
class Video(Resource):
|
||||
def __init__(self):
|
||||
self.name = API_VIDEO
|
||||
|
||||
# example use: curl http://127.0.0.1:15080/api/v1/Video/xxx
|
||||
def get(self, id):
|
||||
value = data_global_elements.get_interface(self.name).get(id)
|
||||
if value != None:
|
||||
return value, 200
|
||||
return "No data found", 404
|
||||
|
||||
def delete(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).delete(id)
|
||||
if ret == True:
|
||||
return '', 204
|
||||
return "No data found", 404
|
||||
"""
|
||||
def put(self, id):
|
||||
ret = data_global_elements.get_interface(self.name).put(id)
|
||||
return task, 201
|
||||
"""
|
||||
|
||||
api.add_resource(VideoList, "/api/v1/" + API_VIDEO)
|
||||
api.add_resource(Video, "/api/v1/" + API_VIDEO + "/<int:id>")
|
||||
|
||||
|
||||
rest_config = config.get_rest_config()
|
||||
|
||||
debug.info("Start REST application: " + str(rest_config["host"]) + ":" + str(rest_config["port"]))
|
||||
|
||||
app.run(debug=False, host=rest_config["host"], port=str(rest_config["port"]))
|
||||
|
||||
debug.info("END program");
|
||||
sys.exit(0)
|
34
src/data_global_elements.py
Normal file
34
src/data_global_elements.py
Normal file
@ -0,0 +1,34 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
##
|
||||
## @author Edouard DUPIN
|
||||
##
|
||||
## @copyright 2019, Edouard DUPIN, all right reserved
|
||||
##
|
||||
## @license MPL v2.0 (see license file)
|
||||
##
|
||||
|
||||
interfaces = {}
|
||||
|
||||
def get_list_interface():
|
||||
global interfaces
|
||||
return interfaces
|
||||
|
||||
def get_interface(_name):
|
||||
global interfaces
|
||||
return interfaces[_name]
|
||||
|
||||
def add_interface(_name, _interface):
|
||||
global interfaces
|
||||
interfaces[_name] = _interface
|
||||
|
||||
|
||||
import time, threading
|
||||
def check_save():
|
||||
print(time.ctime())
|
||||
for elem in interfaces.keys():
|
||||
interfaces[elem].check_save()
|
||||
threading.Timer(10, check_save).start()
|
||||
|
||||
check_save()
|
||||
|
94
src/data_interface.py
Normal file
94
src/data_interface.py
Normal file
@ -0,0 +1,94 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
##
|
||||
## @author Edouard DUPIN
|
||||
##
|
||||
## @copyright 2019, Edouard DUPIN, all right reserved
|
||||
##
|
||||
## @license MPL v2.0 (see license file)
|
||||
##
|
||||
|
||||
global_id = 0;
|
||||
|
||||
import tools
|
||||
import json
|
||||
from realog import debug
|
||||
|
||||
class DataInterface():
|
||||
def __init__(self, _name, _file):
|
||||
self.name = _name
|
||||
self.file = _file
|
||||
self.bdd = []
|
||||
self.need_save = False
|
||||
if tools.exist(self.file) == False:
|
||||
self.need_save = True
|
||||
else:
|
||||
data = tools.file_read_data(self.file)
|
||||
self.bdd = json.loads(data)
|
||||
|
||||
def upgrade_global_bd_id(self):
|
||||
global global_id
|
||||
for elem in self.bdd:
|
||||
if 'id' not in elem.keys():
|
||||
continue
|
||||
if elem["id"] >= global_id:
|
||||
global_id = elem["id"] + 1
|
||||
|
||||
def get_table_index(id):
|
||||
id_in_bdd = 0
|
||||
for elem in self.bdd:
|
||||
if 'id' in elem.keys() \
|
||||
and elem["id"] == id:
|
||||
return id_in_bdd
|
||||
id_in_bdd += 1
|
||||
return None
|
||||
|
||||
def check_save(self):
|
||||
if self.need_save == False:
|
||||
return
|
||||
debug.warning("Save bdd: " + self.file)
|
||||
data = json.dumps(self.bdd, sort_keys=True, indent=4)
|
||||
self.need_save = False
|
||||
tools.file_write_data_safe(self.file, data)
|
||||
|
||||
def gets(self):
|
||||
debug.info("gets " + self.name)
|
||||
return self.bdd
|
||||
|
||||
def get(self, id):
|
||||
debug.info("get " + self.name + ": " + str(id))
|
||||
for elem in self.bdd:
|
||||
if 'id' in elem.keys() \
|
||||
and elem["id"] == id:
|
||||
return elem
|
||||
return None
|
||||
|
||||
def delete(self, id):
|
||||
debug.info("delete " + self.name + ": " + str(id))
|
||||
id_in_bdd = self.get_table_index(id)
|
||||
if id_in_bdd == None:
|
||||
return False
|
||||
del self.bdd[id_in_bdd]
|
||||
self.need_save = True
|
||||
return True
|
||||
|
||||
def put(self, id, value):
|
||||
debug.info("put " + self.name + ": " + str(id))
|
||||
id_in_bdd = self.get_table_index(id)
|
||||
if id_in_bdd == None:
|
||||
return False
|
||||
value["id"] = id
|
||||
self.bdd[id_in_bdd] = value
|
||||
self.need_save = True
|
||||
return True
|
||||
|
||||
def post(self, value):
|
||||
debug.info("post " + self.name)
|
||||
global global_id
|
||||
value["id"] = global_id
|
||||
global_id += 1
|
||||
self.bdd.append(value)
|
||||
self.need_save = True
|
||||
return value
|
||||
|
||||
|
133
src/tools.py
Normal file
133
src/tools.py
Normal file
@ -0,0 +1,133 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
##
|
||||
## @author Edouard DUPIN
|
||||
##
|
||||
## @copyright 2012, Edouard DUPIN, all right reserved
|
||||
##
|
||||
## @license MPL v2.0 (see license file)
|
||||
##
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import errno
|
||||
import fnmatch
|
||||
import stat
|
||||
# Local import
|
||||
from realog import debug
|
||||
|
||||
"""
|
||||
|
||||
"""
|
||||
def get_run_path():
|
||||
return os.getcwd()
|
||||
|
||||
"""
|
||||
|
||||
"""
|
||||
def get_current_path(file):
|
||||
return os.path.dirname(os.path.realpath(file))
|
||||
|
||||
def create_directory_of_file(file):
|
||||
debug.info("Create directory of path: '" + file + "'")
|
||||
path = os.path.dirname(file)
|
||||
debug.info("Create directory: '" + path + "'")
|
||||
try:
|
||||
os.stat(path)
|
||||
except:
|
||||
os.makedirs(path)
|
||||
|
||||
def get_list_sub_path(path):
|
||||
# TODO : os.listdir(path)
|
||||
for dirname, dirnames, filenames in os.walk(path):
|
||||
return dirnames
|
||||
return []
|
||||
|
||||
def remove_path_and_sub_path(path):
|
||||
if os.path.isdir(path):
|
||||
debug.verbose("remove path : '" + path + "'")
|
||||
shutil.rmtree(path)
|
||||
|
||||
def remove_file(path):
|
||||
if os.path.isfile(path):
|
||||
os.remove(path)
|
||||
elif os.path.islink(path):
|
||||
os.remove(path)
|
||||
|
||||
def exist(path):
|
||||
if os.path.isdir(path):
|
||||
return True
|
||||
if os.path.isfile(path):
|
||||
return True
|
||||
if os.path.islink(path):
|
||||
return True
|
||||
return False
|
||||
|
||||
def file_size(path):
|
||||
if not os.path.isfile(path):
|
||||
return 0
|
||||
statinfo = os.stat(path)
|
||||
return statinfo.st_size
|
||||
|
||||
def file_read_data(path, binary=False):
|
||||
debug.verbose("path= " + path)
|
||||
if not os.path.isfile(path):
|
||||
return ""
|
||||
if binary == True:
|
||||
file = open(path, "rb")
|
||||
else:
|
||||
file = open(path, "r")
|
||||
data_file = file.read()
|
||||
file.close()
|
||||
return data_file
|
||||
|
||||
def version_to_string(version):
|
||||
version_ID = ""
|
||||
for id in version:
|
||||
if len(version_ID) != 0:
|
||||
if type(id) == str:
|
||||
version_ID += "-"
|
||||
else:
|
||||
version_ID += "."
|
||||
version_ID += str(id)
|
||||
return version_ID
|
||||
|
||||
##
|
||||
## @brief Write data in a specific path.
|
||||
## @param[in] path Path of the data might be written.
|
||||
## @param[in] data Data To write in the file.
|
||||
## @param[in] only_if_new (default: False) Write data only if data is different.
|
||||
## @return True Something has been copied
|
||||
## @return False Nothing has been copied
|
||||
##
|
||||
def file_write_data(path, data, only_if_new=False):
|
||||
if only_if_new == True:
|
||||
if os.path.exists(path) == True:
|
||||
old_data = file_read_data(path)
|
||||
if old_data == data:
|
||||
return False
|
||||
#real write of data:
|
||||
create_directory_of_file(path)
|
||||
file = open(path, "w")
|
||||
file.write(data)
|
||||
file.close()
|
||||
return True
|
||||
|
||||
def file_write_data_safe(path, data):
|
||||
#real write of data:
|
||||
create_directory_of_file(path)
|
||||
file = open(path + ".tmp", "w")
|
||||
file.write(data)
|
||||
file.close()
|
||||
shutil.move(path + ".tmp", path)
|
||||
return True
|
||||
|
||||
def list_to_str(list):
|
||||
if type(list) == type(str()):
|
||||
return list + " "
|
||||
else:
|
||||
result = ""
|
||||
# mulyiple imput in the list ...
|
||||
for elem in list:
|
||||
result += list_to_str(elem)
|
||||
return result
|
Loading…
Reference in New Issue
Block a user