Skip to content

Commit de86964

Browse files
committed
First commit of a functional project
1 parent b0cb5c3 commit de86964

34 files changed

+9575
-0
lines changed

metadata_db_server.py

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
#
4+
# metadata_db_server.py
5+
#
6+
# Copyright 2022 Giorgio Gilestro <giorgio@gilest.ro>
7+
#
8+
# This program is free software; you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation; either version 2 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# This program is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program; if not, write to the Free Software
20+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21+
# MA 02110-1301, USA.
22+
#
23+
#
24+
25+
import os
26+
import logging
27+
import optparse
28+
import json
29+
import bottle
30+
31+
from ast import literal_eval
32+
from ethoscopy.metadata_db import db_organiser, metadata_handler, metadata_crawler
33+
34+
app = bottle.Bottle()
35+
STATIC_DIR = "./static"
36+
37+
@app.route('/static/<filepath:path>')
38+
def server_static(filepath):
39+
return bottle.static_file(filepath, root=STATIC_DIR)
40+
41+
@app.route('/')
42+
def index():
43+
return bottle.static_file('index.html', root=STATIC_DIR)
44+
45+
@app.route('/save', method='POST')
46+
def save():
47+
48+
# text parameters that were received
49+
#for k in bottle.request.forms.keys(): print (k, bottle.request.forms.get(k))
50+
51+
#file upload
52+
allowed_extensions = ['.csv', '.tsv']
53+
54+
upload = bottle.request.files.get('file')
55+
if not upload:
56+
return {'success' : False, 'message' : 'A metadata file was not specified.'}
57+
58+
name, ext = os.path.splitext(upload.filename)
59+
if ext not in allowed_extensions:
60+
return {'success' : False, 'message' : 'Extensions allowed are %s.' % " / ".join(allowed_extensions)}
61+
62+
try:
63+
upload.save(meta_db.upload_folder, overwrite=True)
64+
65+
except Exception as e:
66+
print (e)
67+
return {'success' : False, 'message' : str(e)}
68+
69+
try:
70+
#After saving, creates the info file
71+
uploaded_metadata = metadata_handler ( filename = os.path.join (meta_db.upload_folder, upload.filename),
72+
project = bottle.request.forms.get('project'),
73+
tags = literal_eval(bottle.request.forms.get('tags')),
74+
authors = literal_eval(bottle.request.forms.get('authors')),
75+
doi = bottle.request.forms.get('doi'),
76+
description = bottle.request.forms.get('description')
77+
)
78+
uploaded_metadata.save()
79+
80+
meta_db.refresh_all_info()
81+
82+
return {'success' : True, 'message' : 'Metadata file successfully uploaded.' }
83+
84+
except Exception as e:
85+
return {'success' : False, 'message' : str(e)}
86+
87+
88+
@app.route('/download', method='GET')
89+
def download():
90+
hash_id = bottle.request.query.get('id', '')
91+
dwn_type = bottle.request.query.get('type', '')
92+
fullpath = meta_db.request(hash_id)['filename']
93+
path, filename = os.path.split( fullpath )
94+
95+
if dwn_type == 'metadata':
96+
return bottle.static_file (filename, root=path, download=filename)
97+
98+
elif dwn_type == 'db_found':
99+
md = metadata_handler(fullpath)
100+
fn = os.path.splitext(filename)[0] + '.db_found.csv'
101+
md.list_dbs(notfound=False).to_csv(os.path.join ('/tmp/', fn))
102+
return bottle.static_file (fn, root='/tmp/', download=fn)
103+
104+
elif dwn_type == 'db_notfound':
105+
md = metadata_handler(fullpath)
106+
fn = os.path.splitext(filename)[0] + '.db_notfound.csv'
107+
md.list_dbs(notfound=True).to_csv(os.path.join ('/tmp/', fn))
108+
return bottle.static_file (fn, root='/tmp/', download=fn)
109+
110+
111+
@app.route('/refresh', method='GET')
112+
def refresh():
113+
hash_id = bottle.request.query.get('id', '')
114+
filename = meta_db.request(hash_id)['filename']
115+
md = metadata_handler ( filename )
116+
md.associate_to_db(etho_db)
117+
md.save()
118+
return {'success' : True, 'message' : 'Metadata succefully associated.' }
119+
120+
121+
@app.route('/info_tree', method='GET')
122+
def get_metadata_tree():
123+
return meta_db.all_projects
124+
125+
126+
@app.route('/metadata', method='GET')
127+
def get_metadata():
128+
hash_id = bottle.request.query.get('id', '')
129+
return meta_db.request(hash_id)
130+
131+
@app.route('/known')
132+
def available_options():
133+
return meta_db.available_options
134+
135+
def close(exit_status=0):
136+
logging.info("Closing server")
137+
os._exit(exit_status)
138+
139+
140+
if __name__ == '__main__':
141+
logging.getLogger().setLevel(logging.INFO)
142+
parser = optparse.OptionParser()
143+
parser.add_option("-d", "--db_path", dest="db_path", default="/mnt/ethoscope_results", help="Path to the root of the ethoscope db files")
144+
parser.add_option("-f", "--db_file", dest="db_file", default="/opt/ethoscope_db", help="Path to the saved db file")
145+
146+
parser.add_option("-D", "--debug", dest="debug", default=False, help="Set DEBUG mode ON", action="store_true")
147+
parser.add_option("-p", "--port", dest="port", default=8081, help="port")
148+
149+
(options, args) = parser.parse_args()
150+
151+
option_dict = vars(options)
152+
DB_PATH = option_dict["db_path"]
153+
DB_FILE = option_dict["db_file"]
154+
155+
PORT = option_dict["port"]
156+
DEBUG = option_dict["debug"]
157+
158+
if DEBUG:
159+
logging.basicConfig()
160+
logging.getLogger().setLevel(logging.DEBUG)
161+
logging.info("Logging using DEBUG SETTINGS")
162+
163+
164+
etho_db = db_organiser(DB_PATH, refresh=False)
165+
meta_db = metadata_crawler()
166+
167+
try:
168+
app.run(host='0.0.0.0', port=PORT, debug=DEBUG)
169+
170+
except KeyboardInterrupt:
171+
logging.info("Stopping server cleanly")
172+
pass
173+
174+
except socket.error as e:
175+
logging.error(traceback.format_exc())
176+
logging.error("Port %i is probably not accessible for you. Maybe use another one e.g.`-p 8000`" % PORT)
177+
178+
except Exception as e:
179+
logging.error(traceback.format_exc())

static/css/dropzone.css

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
2+
.dropzone {
3+
width: auto;
4+
height: 100px;
5+
border: 2px dashed #ccc;
6+
color: grey;
7+
line-height: 100px;
8+
text-align: center;
9+
}
10+
11+
.dropzone.dragover {
12+
border-color: #000;
13+
color: #000;
14+
}

static/css/fontawesome-all.min.css

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/css/material-icons.css

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
@font-face {
2+
font-family: 'Material Icons';
3+
font-style: normal;
4+
font-weight: 400;
5+
src: url(https://fonts.gstatic.com/s/materialicons/v139/flUhRq6tzZclQEJ-Vdg-IuiaDsNZ.ttf) format('truetype');
6+
}
7+
8+
.material-icons {
9+
font-family: 'Material Icons';
10+
font-weight: normal;
11+
font-style: normal;
12+
font-size: 24px;
13+
line-height: 1;
14+
letter-spacing: normal;
15+
text-transform: none;
16+
display: inline-block;
17+
white-space: nowrap;
18+
word-wrap: normal;
19+
direction: ltr;
20+
}

0 commit comments

Comments
 (0)