Skip to content

Commit

Permalink
Merge pull request #1386 from StochSS/example-library-page
Browse files Browse the repository at this point in the history
Example library page
  • Loading branch information
seanebum authored Sep 26, 2022
2 parents f95741e + 04a7ae5 commit dcd82e4
Show file tree
Hide file tree
Showing 9 changed files with 138 additions and 46 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ stochss/dist/stochss-domain-editor.html
stochss/dist/stochss-loading-page.html
stochss/dist/stochss-quick-start.html
stochss/dist/stochss-user-home.html
stochss/dist/stochss-example-library.html
jupyterhub/templates/page.html
jupyterhub/templates/stochss-home.html
jupyterhub/templates/stochss-job-presentation.html
Expand Down
56 changes: 56 additions & 0 deletions client/pages/example-library.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
StochSS is a platform for simulating biochemical systems
Copyright (C) 2019-2022 StochSS developers.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
let $ = require('jquery');
let path = require('path');
//support files
var app = require('../app');
//views
let PageView = require('./base');
//templates
let template = require('../templates/pages/exampleLibrary.pug');

import initPage from './page.js';

let exampleLibrary = PageView.extend({
template: template,
events: {
'click [data-hook=collapse-well-mixed]' : 'changeCollapseButtonText',
'click [data-hook=collapse-spatial]' : 'changeCollapseButtonText'
},
initialize: function (attrs, options) {
PageView.prototype.initialize.apply(this, arguments);
},
render: function (attrs, options) {
PageView.prototype.render.apply(this, arguments);
this.getExampleLibrary();
},
changeCollapseButtonText: function (e) {
app.changeCollapseButtonText(this, e)
},
getExampleLibrary: function () {
let endpoint = path.join(app.getApiPath(), "example-library");
app.getXHR(endpoint, {
success: (err, response, body) => {
$(this.queryByHook('well-mixed-examples')).html(body.wellMixed);
$(this.queryByHook('spatial-examples')).html(body.spatial);
}
});
}
});

initPage(exampleLibrary);
10 changes: 1 addition & 9 deletions client/templates/body.pug
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,7 @@ body
a.nav-link(href="stochss/files#file-browser-section" title="Explore your StochSS files") Files

li.nav_item
div.dropdown
button.dropdown-toggle.nav-item.nav-link.dropbtn.nav-drop#exampleLibrary(
data-hook="example-library",
data-toggle="dropdown",
aria-haspopup="true",
aria-expanded="false",
type="button"
) Example Library <span class="caret"></span>
ul.nav.dropdown-menu.dropdown-content.nav-drop-content(id="exampleLibraryDropdown" aria-labelledby="exampleLibrary")
div: a.nav-link(href="stochss/example-library" title="Import Examples from Library") Example Library

li.nav-item
div: a.nav-link(target="_blank" href="tree" title="Browse your files in a Jupyter interface") Jupyter Notebooks
Expand Down
27 changes: 27 additions & 0 deletions client/templates/pages/exampleLibrary.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
section.page

h2 Example Library

div.card.mt-3#well-mixed-examples

div.card-header.pb-0

h3.inline Well-Mixed

button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-well-mixed" data-hook="collapse-well-mixed") -

div.collapse.show(id="collapse-well-mixed")

div.card-body(data-hook="well-mixed-examples")

div.card.mt-4#spatial-examples

div.card-header.pb-0

h3.inline Spatial

button.btn.btn-outline-collapse(data-toggle="collapse" data-target="#collapse-spatial" data-hook="collapse-spatial") -

div.collapse.show(id="collapse-spatial")

div.card-body(data-hook="spatial-examples")
1 change: 1 addition & 0 deletions stochss/handlers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def get_page_handlers(route_start):
(r'/stochss/project/manager\/?', ProjectManagerHandler),
(r'/stochss/loading-page\/?', LoadingPageHandler),
(r'/stochss/multiple-plots\/?', MultiplePlotsHandler),
(r'/stochss/example-library\/?', ExampleLibraryHandler),
#
## API Handlers
#
Expand Down
3 changes: 2 additions & 1 deletion stochss/handlers/file_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,9 +817,10 @@ async def get(self):
Attributes
----------
'''
home = "/hub/spawn" if str(self.request.path).startswith("/user") else "stochss/home"
try:
system = StochSSBase(path=".example-library.json")
examples = system.load_example_library()
examples = system.load_example_library(home)
self.write(examples)
except StochSSAPIError as err:
report_error(self, log, err)
Expand Down
25 changes: 21 additions & 4 deletions stochss/handlers/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,23 @@ async def get(self):
self.render("stochss-quickstart.html", server_path=self.get_server_path())


class ExampleLibraryHandler(PageHandler):
'''
################################################################################################
StochSS Example Library Page Handler
################################################################################################
'''
@web.authenticated
async def get(self):
'''
Render the StochSS example library page.
Attributes
----------
'''
self.render("stochss-example-library.html", server_path=self.get_server_path())


class ModelBrowserHandler(PageHandler):
'''
################################################################################################
Expand Down Expand Up @@ -267,15 +284,15 @@ async def get(self):
path = os.path.join(os.path.expanduser("~"), ".user-logs.txt")
try:
if os.path.exists(f"{path}.bak"):
with open(path, "r") as log_file:
with open(path, "r", encoding="utf-8") as log_file:
logs = log_file.read().strip().split("\n")
else:
logs = []
with open(path, "r") as log_file:
with open(path, "r", encoding="utf-8") as log_file:
logs.extend(log_file.read().strip().split("\n"))
logs = logs[int(log_num):]
except FileNotFoundError:
open(path, "w").close()
open(path, "w", encoding="utf-8").close()
logs = []
self.write({"logs":logs})
self.finish()
Expand All @@ -298,5 +315,5 @@ async def get(self):
path = os.path.join(os.path.expanduser("~"), ".user-logs.txt")
if os.path.exists(f'{path}.bak'):
os.remove(f'{path}.bak')
open(path, "w").close()
open(path, "w", encoding="utf-8").close()
self.finish()
53 changes: 21 additions & 32 deletions stochss/handlers/util/stochss_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
import json
import time
import shutil
import hashlib
import datetime
import tempfile
import traceback

import requests
Expand Down Expand Up @@ -51,26 +49,30 @@ def __init__(self, path):
self.path = path
self.logs = []

def __build_example_dropdown(self, exm_data):
header = "<li class='dropdown-item py-0'>__KEY__</li>"
divider = "<li class='dropdown-divider'></li>"
entry_li = "<li class='dropdown-item nav-drop-item'>__ENTRY_A__</li>"
entry_a = "<a class='nav-link nav-drop-item__ALERT__' href='__OPEN_LINK__'>__NAME__</a>"
def __build_example_html(self, exm_data, home):
row = "<div class='row'>__CONTENTS__</div>"
entry = "__ALERT__' href='__OPEN_LINK__' role='button' style='width: 100%'>__NAME__</a>"
entry_a = f"<a class='btn box-shadow btn-outline-{entry}"

# Well Mixed Examples
example_list = [header.replace("__KEY__", "Well-Mixed"), divider]
wm_list = []
for entry in exm_data['Well-Mixed']:
exm_a = entry_a.replace("__ALERT__", entry['alert'])
exm_a = exm_a.replace("__OPEN_LINK__", entry['open_link'])
exm_a = exm_a.replace("__OPEN_LINK__", f"{home}?open={entry['open_link']}")
exm_a = exm_a.replace("__NAME__", entry['name'])
example_list.append(entry_li.replace("__ENTRY_A__", exm_a))
wm_list.append(f"<div class='col-md-4 col-lg-3 my-2'>{exm_a}</div>")
well_mixed = row.replace("__CONTENTS__", ''.join(wm_list))

# Spatial Examples
example_list.extend([header.replace("__KEY__", "Spatial"), divider])
s_list = []
for entry in exm_data['Spatial']:
exm_a = entry_a.replace("__ALERT__", entry['alert'])
exm_a = exm_a.replace("__OPEN_LINK__", entry['open_link'])
exm_a = exm_a.replace("__OPEN_LINK__", f"{home}?open={entry['open_link']}")
exm_a = exm_a.replace("__NAME__", entry['name'])
example_list.append(entry_li.replace("__ENTRY_A__", exm_a))
return "".join(example_list)
s_list.append(f"<div class='col-md-4 col-lg-3 my-2'>{exm_a}</div>")
spatial = row.replace("__CONTENTS__", ''.join(s_list))

return {"wellMixed": well_mixed, "spatial": spatial}

def __get_entry(self, entries, name):
for entry in entries:
Expand Down Expand Up @@ -98,13 +100,13 @@ def __get_from_remote(self):

def __update_exm_data(self, exm_data, old_exm_data=None):
for entry in exm_data['Well-Mixed']:
entry['alert'] = " text-success"
entry['alert'] = "success"
if old_exm_data is not None:
old_entry = self.__get_entry(old_exm_data['Well-Mixed'], entry['name'])
entry['mod_time'] = old_entry['mod_time']
entry['umd5_sum'] = old_entry['umd5_sum']
for entry in exm_data['Spatial']:
entry['alert'] = " text-success"
entry['alert'] = "success"
if old_exm_data is not None:
old_entry = self.__get_entry(old_exm_data['Spatial'], entry['name'])
entry['mod_time'] = old_entry['mod_time']
Expand All @@ -126,7 +128,6 @@ def __update_umd5_sums(self, exm_data, files=None):
self.__update_umd5_sums(exm_data, files=non_projs)
self.__update_umd5_sums(exm_data, files=projs)
else:
tmp_dir = tempfile.TemporaryDirectory()
for example in files:
if example in exm_data['Names']:
entry = self.__get_entry(
Expand All @@ -136,19 +137,7 @@ def __update_umd5_sums(self, exm_data, files=None):
entry = self.__get_entry(
exm_data['Spatial'], exm_data['Name-Mappings'][example]
)
# Update MD5 Sum for users example files
# if os.path.getmtime(os.path.join(e_path, example)) != entry['mod_time']:
# entry['mod_time'] = os.path.getmtime(os.path.join(e_path, example))
# zip_path = os.path.join(tmp_dir.name, exm_data['Name-Mappings'][example])
# shutil.make_archive(zip_path, "zip", e_path, example)
# with open(f"{zip_path}.zip", "rb") as zip_file:
# entry['umd5_sum'] = hashlib.md5(zip_file.read()).hexdigest()
# if entry['umd5_sum'] == entry['error']:
# entry['alert'] = " text-danger"
# elif entry['umd5_sum'] != entry['md5_sum']:
# entry['alert'] = " text-warning"
# else:
entry['alert'] = ""
entry['alert'] = "primary"

def add_presentation_name(self, file, name):
'''
Expand Down Expand Up @@ -451,7 +440,7 @@ def get_unique_copy_path(self, path=None):

return os.path.join(dirname, cp_file)

def load_example_library(self):
def load_example_library(self, home):
'''
Load the example library dropdown list.
'''
Expand All @@ -472,7 +461,7 @@ def load_example_library(self):
with open(self.path, "w", encoding="utf-8") as data_file:
json.dump(exm_data, data_file, sort_keys=True, indent=4)

return self.__build_example_dropdown(exm_data)
return self.__build_example_html(exm_data, home)

def log(self, level, message):
'''
Expand Down
8 changes: 8 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = {
entry: {
home: './client/pages/users-home.js',
quickstart: './client/pages/quickstart.js',
exampleLibrary: './client/pages/example-library.js',
browser: './client/pages/browser.js',
editor: './client/pages/model-editor.js',
domainEditor: './client/pages/domain-editor.js',
Expand Down Expand Up @@ -35,6 +36,13 @@ module.exports = {
name: 'quickstart',
inject: false
}),
new HtmlWebpackPlugin({
title: 'StochSS | Example Library',
filename: 'stochss-example-library.html',
template: 'page_template.pug',
name: 'exampleLibrary',
inject: false
}),
new HtmlWebpackPlugin({
title: 'StochSS | Model Browser',
filename: 'stochss-file-browser.html',
Expand Down

0 comments on commit dcd82e4

Please sign in to comment.