Commit a9756a47 authored by isillitoe's avatar isillitoe
Browse files

Merge branch 'master' of github.com:CATH-SWISSMODEL/cathsm-server

parents 0c5738c2 dfdb7bbc
......@@ -57,6 +57,7 @@ coverage.xml
*.log
local_settings.py
db.sqlite3
/static
# Flask stuff:
instance/
......
......@@ -35,15 +35,15 @@ ONBUILD RUN apt-get update && \
apt-get install -y --no-install-recommends \
git && \
/bin/rm -rf /var/lib/apt/lists/* && \
/usr/bin/git clone https://github.com/bienchen/cath-swissmodel-api.git \
/tmp/cath-swissmodel-api.git && \
/usr/bin/git clone https://github.com/CATH-SWISSMODEL/cathsm-server.git \
/tmp/cathsm-server.git && \
if test -z "$CATHSMAPI_GITTAG"; then \
cd /tmp/cath-swissmodel-api.git/cathapi && \
cd /tmp/cathsm-server.git/cathapi && \
git checkout $CATHSMAPI_GITTAG && \
cd /; \
fi && \
/bin/mv /tmp/cath-swissmodel-api.git/cathapi $SRC_DIR && \
/bin/rm -rf rm /tmp/cath-swissmodel-api.git && \
/bin/mv /tmp/cathsm-server.git $SRC_DIR && \
/bin/rm -rf rm /tmp/cathsm-server.git && \
apt-get purge -y --auto-remove git
FROM build_${CATHSMAPI_CODEBASE}
......
.subheading {
font-size: 1.25rem;
}
\ No newline at end of file
......@@ -6,7 +6,8 @@ var QUERY = {
(function ($) {
"use strict"; // Start of use strict
var stepper = new Stepper($(".bs-stepper")[0], {
var stepperEl = document.getElementById('cathsm-stepper');
var stepper = new Stepper(stepperEl, {
linear: false,
animation: true,
});
......@@ -63,19 +64,62 @@ var QUERY = {
// Do whatever with pasteddata
};
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function (form) {
form.addEventListener('submit', function (event) {
console.log('checking form for validity: ', form, event, form.checkValidity());
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
// https://stackoverflow.com/a/21311717/821642
function validateTextarea() {
console.log("validateTextarea", this);
var errorMsg = "Please match the format requested.";
var textarea = this;
var pattern = new RegExp('^' + $(textarea).attr('pattern') + '$');
// check each line of text
$.each($(this).val().split("\n"), function () {
// check if the line matches the pattern
var hasError = !this.match(pattern);
console.log("match: ", this, pattern, this.match(pattern), hasError);
if (typeof textarea.setCustomValidity === 'function') {
textarea.setCustomValidity(hasError ? errorMsg : '');
} else {
// Not supported by the browser, fallback to manual error display...
$(textarea).toggleClass('error', !!hasError);
$(textarea).toggleClass('ok', !hasError);
if (hasError) {
$(textarea).attr('title', errorMsg);
} else {
$(textarea).removeAttr('title');
}
}
form.classList.add('was-validated');
return !hasError;
});
}
$('.example-sequence').on('click', function (event) {
var seq = $(this).data('sequence');
var seq_id = $(this).data('sequenceId');
$input_sequence.val(seq);
$input_sequence_id.val(seq_id);
})
// Loop over forms and apply our own validation (prevent auto submission)
var validateForm = function (event) {
var $form = $(this);
var formEl = $form[0];
console.log('checking form for validity: ', formEl, $form.find('textarea'), event, formEl.checkValidity());
$form.find('textarea[pattern]').each(validateTextarea);
if (formEl.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
$form.addClass('was-validated');
};
$('form.needs-validation').each(function (idx, form) {
$(form).on('submit', function (event) {
validateForm(event);
}, false);
});
$input_sequence.on('change keyup', validateForm);
$input_sequence.on('paste', handleSequencePaste);
$('.bs-stepper form').submit(function (event) {
......@@ -93,7 +137,7 @@ var QUERY = {
};
stepper.addEventListener('shown.bs-stepper', function (event) {
stepperEl.addEventListener('shown.bs-stepper', function (event) {
console.warn('step shown')
switch (event.detail.indexStep) {
......
......@@ -19,8 +19,7 @@
<!-- Theme CSS -->
<link href="{% static 'cathapi/css/freelancer.min.css' %}" rel="stylesheet">
<link href="{% static 'cathapi/css/bs-stepper.min.css' %}" rel="stylesheet">
<link href="{% static 'cathapi/css/local.css' %}" ref="stylesheet">
</head>
<body id="page-top">
......@@ -38,175 +37,18 @@
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#model">Model</a>
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#pipeline">Pipeline</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#about">About</a>
</li>
<li class="nav-item mx-0 mx-lg-1">
<a class="nav-link py-3 px-0 px-lg-3 rounded js-scroll-trigger" href="#contact">Contact</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- Masthead -->
<header class="masthead bg-primary text-white text-center">
<div class="container d-flex align-items-center flex-column">
<!-- Masthead Heading -->
<h1 class="masthead-heading text-uppercase mb-0">CathSM</h1>
<!-- Icon Divider -->
<div class="divider-custom divider-light">
<div class="divider-custom-line"></div>
</div>
<!-- Masthead Subheading -->
<p class="masthead-subheading font-weight-light mb-0">
Connecting web services from CATH and SWISS-MODEL <br> to generate model 3D structures from protein
sequences
</p>
<!-- About Section Button -->
<div class="text-center mt-4">
<a class="btn btn-xl btn-outline-light js-scroll-trigger" href="#model">
<i class="fas fa-play mr-2"></i>
Try it out
</a>
<a class="btn btn-xl btn-outline-light js-scroll-trigger" href="#about">
<i class="fas fa-question mr-2"></i>
Find out more
</a>
</div>
</div>
</header>
<!-- Model Section -->
<section class="page-section model" id="model">
<div class="container">
<!-- Model Section Heading -->
<h2 class="page-section-heading text-center text-uppercase text-secondary mb-0">Model</h2>
<!-- Icon Divider -->
<div class="divider-custom">
<div class="divider-custom-line"></div>
</div>
<!-- Model Grid Items -->
{% block content %}
{% endblock %}
<!-- /.row -->
</div>
</section>
<!-- About Section -->
<section class="page-section bg-primary text-white mb-0" id="about">
<div class="container">
<!-- About Section Heading -->
<h2 class="page-section-heading text-center text-uppercase text-white">About</h2>
<!-- Icon Divider -->
<div class="divider-custom divider-light">
<div class="divider-custom-line"></div>
</div>
<!-- About Section Content -->
<div class="row">
<div class="col-lg-4 ml-auto">
<h4>CATH</h4>
<p>CATH is a classification of protein structures that groups
protein domains into superfamilies when there is sufficient evidence
they have diverged from a common ancestor. This
information can be used to provide unique insights into relationships
between protein sequence, structure and function.</p>
</div>
<div class="col-lg-4 mr-auto">
<h4>SWISS-MODEL</h4>
<p>SWISS-MODEL is a fully automated protein structure homology-modelling
server, accessible via the ExPASy web server, or from the program
DeepView (Swiss Pdb-Viewer). The purpose of this server is to make
protein modelling accessible to all life science researchers
worldwide.</p>
</div>
<div class="col-lg-4 ml-auto">
<h4>CATHSM</h4>
<p>Foo</p>
</div>
</div>
<!-- About Section Button -->
<div class="text-center mt-4">
<a class="btn btn-xl btn-outline-light" href="https://github.com/CATH-SWISSMODEL/cath-swissmodel-api">
<i class="fas fa-download mr-2"></i>
View code on GitHub
</a>
</div>
</div>
</section>
<!-- Contact Section -->
<section class="page-section" id="contact">
<div class="container">
<!-- Contact Section Heading -->
<h2 class="page-section-heading text-center text-uppercase mb-0">Contact Us</h2>
<!-- Icon Divider -->
<div class="divider-custom">
<div class="divider-custom-line"></div>
</div>
<!-- Contact Section Form -->
<div class="row">
<div class="col-lg-8 mx-auto">
<!-- To configure the contact form email address, go to mail/contact_me.php and update the email address in the PHP file on line 19. -->
<form name="sentMessage" id="contactForm" novalidate="novalidate">
<div class="control-group">
<div class="form-group floating-label-form-group controls mb-0 pb-2">
<label>Name</label>
<input class="form-control" id="name" type="text" placeholder="Name" required="required"
data-validation-required-message="Please enter your name.">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="control-group">
<div class="form-group floating-label-form-group controls mb-0 pb-2">
<label>Email Address</label>
<input class="form-control" id="email" type="email" placeholder="Email Address" required="required"
data-validation-required-message="Please enter your email address.">
<p class="help-block text-danger"></p>
</div>
</div>
<div class="control-group">
<div class="form-group floating-label-form-group controls mb-0 pb-2">
<label>Message</label>
<textarea class="form-control" id="message" rows="5" placeholder="Message" required="required"
data-validation-required-message="Please enter a message."></textarea>
<p class="help-block text-danger"></p>
</div>
</div>
<br>
<div id="success"></div>
<div class="form-group">
<button type="submit" class="btn btn-primary btn-xl" id="sendMessageButton">Send</button>
</div>
</form>
</div>
</div>
</div>
</section>
{% block content %}
{% endblock %}
<!-- Footer -->
<footer class="footer text-center">
......@@ -215,17 +57,14 @@
<!-- Footer Location -->
<div class="col-lg-4 mb-5 mb-lg-0">
<h4 class="text-uppercase mb-4">References</h4>
<p class="mb-0"><strong>CATH</strong>
<br>Foo</p>
<p class="mb-0"><strong>SWISS-MODEL</strong>
<br>Bar</p>
<h4 class="text-uppercase mb-4">Funding</h4>
<img width="150" src="{% static 'cathapi/img/elixir-logo.png' %}">
</div>
<!-- Footer Social Icons -->
<div class="col-lg-4 mb-5 mb-lg-0">
<h4 class="text-uppercase mb-4">Around the Web</h4>
<a class="btn btn-outline-light btn-social mx-1" href="#">
<a class="btn btn-outline-light btn-social mx-1" href="">
<i class="fab fa-fw fa-github"></i>
</a>
</div>
......
{% extends 'base.html' %}
{% load static %}
{% block content %}
<div class="d-flex justify-content-center">
<div class="bs-stepper">
<div class="bs-stepper-header" role="tablist">
<!-- your steps here -->
<div class="step" data-target="#submit-sequence-part">
<button type="button" class="step-trigger" role="tab" aria-controls="submit-sequence-part"
id="submit-sequence-part-trigger">
<span class="bs-stepper-circle">1</span>
<span class="bs-stepper-label">Submit Sequence</span>
</button>
<!-- Masthead -->
<header class="masthead bg-primary text-white text-center">
<div class="container d-flex align-items-center flex-column">
<!-- Masthead Heading -->
<h1 class="masthead-heading text-uppercase mb-0">CathSM</h1>
<!-- Icon Divider -->
<div class="divider-custom divider-light">
<div class="divider-custom-line"></div>
</div>
<!-- Masthead Subheading -->
<p class="masthead-subheading font-weight-light mb-0">
Connecting web services from CATH and SWISS-MODEL <br>
to generate 3D models from protein sequences.
</p>
<!-- About Section Button -->
<div class="text-center mt-4">
<a class="btn btn-xl btn-outline-light js-scroll-trigger" href="#model">
<i class="fas fa-play mr-2"></i>
Try it out
</a>
<a class="btn btn-xl btn-outline-light js-scroll-trigger" href="#about">
<i class="fas fa-question mr-2"></i>
Find out more
</a>
</div>
</div>
</header>
<!-- Model Section -->
<section class="page-section pipeline" id="pipeline">
<div class="container">
<!-- Model Section Heading -->
<h2 class="page-section-heading text-center text-uppercase text-secondary mb-0">Pipeline</h2>
<!-- Icon Divider -->
<div class="divider-custom">
<div class="divider-custom-line"></div>
</div>
<!-- Model Grid Items -->
<!-- Masthead Subheading -->
<h4 class="font-weight-light text-center mb-4">
The <span class="code">cathsm</span> modelling pipeline can be accessed via:
</h4>
<div class="row">
<div class="col-lg-6 align-content-center ml-auto">
<h4>CLI (Python script and libraries)</h4>
<a href="https://github.com/CATH-SWISSMODEL/cathsm-client"><img
src="{% static 'cathapi/img/cathsm-client-cli.gif' %}" class="img-thumbnail"></a>
<a class="btn" href="https://github.com/CATH-SWISSMODEL/cathsm-client"><i class="fab fa-fw fa-github"></i>
CATH-SWISSMODEL/cathsm-client</a>
</div>
<div class="col-lg-6 justify-content-center ml-auto">
<h4>Web (ReactJS) <small>(under development)</small></h4>
<img src="{% static 'cathapi/img/cathsm-reactjs.png' %}" class="img-thumbnail">
<a class="btn" href="https://github.com/CATH-SWISSMODEL/cathsm-reactjs"><i class="fab fa-fw fa-github"></i>
CATH-SWISSMODEL/cathsm-reactjs</a>
</div>
<div class="line"></div>
<div class="step" data-target="#select-template-part">
<button type="button" class="step-trigger" role="tab" aria-controls="select-template-part"
id="select-template-part-trigger">
<span class="bs-stepper-circle">2</span>
<span class="bs-stepper-label">Select Template</span>
</button>
</div>
<!-- /.row -->
</div>
</section>
<!-- About Section -->
<section class="page-section bg-primary text-white mb-0" id="about">
<div class="container">
<!-- About Section Heading -->
<h2 class="page-section-heading text-center text-uppercase text-white">About</h2>
<!-- Icon Divider -->
<div class="divider-custom divider-light">
<div class="divider-custom-line"></div>
</div>
<!-- About Section Content -->
<div class="row mb-4">
<div class="col-lg-6 ml-auto">
<h4>CATH</h4>
<p>CATH is a classification of protein structures that groups
protein domains into superfamilies when there is sufficient evidence
they have diverged from a common ancestor. This
information can be used to provide unique insights into relationships
between protein sequence, structure and function.</p>
<a class="btn btn-sm btn-outline-light" href="https://cathdb.info">
<i class="fas fa-external-link-alt mr-2"></i>
Visit CATH
</a>
</div>
<div class="line"></div>
<div class="step" data-target="#view-model-part">
<button type="button" class="step-trigger" role="tab" aria-controls="view-model-part"
id="view-model-part-trigger">
<span class="bs-stepper-circle">3</span>
<span class="bs-stepper-label">View Model</span>
</button>
<div class="col-lg-6 mr-auto">
<h4>SWISS-MODEL</h4>
<p>SWISS-MODEL is a fully automated protein structure homology-modelling
server, accessible via the ExPASy web server, or from the program
DeepView (Swiss Pdb-Viewer). The purpose of this server is to make
protein modelling accessible to all life science researchers
worldwide.</p>
<a class="btn btn-sm btn-outline-light" href="https://swissmodel.expasy.org">
<i class="fas fa-external-link-alt mr-2"></i>
Visit SWISS-MODEL
</a>
</div>
</div>
<div class="bs-stepper-content">
<!-- Submit Sequence -->
<div id="submit-sequence-part" class="content fade" role="tabpanel"
aria-labelledby="submit-sequence-part-trigger">
<form class="needs-validation" novalidate>
<div class="form-group">
<label for="input-sequence-id">Sequence ID</label>
<input type="text" class="form-control" id="input-sequence-id"
placeholder="Enter a name/id for your sequence" required>
<div class="invalid-feedback">Please enter a name for your sequence</div>
<small id="input-sequence-id-help" class="form-text text-muted">
If you copy/paste a FASTA formatted sequence in the box below, this field will be filled in
automatically.</small>
</div>
<div class="form-group">
<label for="input-sequence">Sequence</label>
<textarea rows="10" class="form-control" id="input-sequence"
placeholder="Enter the sequence as a string of amino acids" required
pattern="[^GPAVLIMCFYWHKRQNEDST\s]"></textarea>
<div class="invalid-feedback">Please enter a valid amino-acid sequence</div>
<small id="input-sequence-help" class="form-text text-muted">Copy and paste sequence as a string of
amino-acids (or FASTA format).</small>
</div>
<div class="step-actions d-flex justify-content-center">
<button class="btn btn-lg btn-inactive" data-action="clear">Clear</button>
<button class="btn btn-lg btn-primary btn-inactive" data-action="next" type="submit">Next</button>
</div>
</form>
<div class="row mb-4">
<div class="col-lg-6 ml-auto">
<h4>InterPro</h4>
<p>InterPro provides functional analysis of proteins by classifying them into families and predicting domains
and important sites. To classify proteins in this way, InterPro uses predictive models, known as signatures,
provided by several different databases (referred to as member databases) that make up the InterPro
consortium. We combine protein signatures from these member databases into a single searchable resource,
capitalising on their individual strengths to produce a powerful integrated database and diagnostic tool.</p>
<a class="btn btn-sm btn-outline-light" href="https://www.ebi.ac.uk/interpro">
<i class="fas fa-external-link-alt mr-2"></i>
Visit InterPro
</a>
</div>
<!-- Select Template -->
<div id="select-template-part" class="content fade" role="tabpanel"
aria-labelledby="select-template-part-trigger">
<div class="step-content">
Select template content
</div>
<div class="step-actions d-flex justify-content-center">
<button class="btn btn-lg btn-inactive" data-action="back">Back</button>
<button class="btn btn-lg btn-inactive" data-action="next">Next</button>
</div>
<div class="col-lg-6 ml-auto">
<h4>PDBe</h4>
<p>PDBe is a founding member of the Worldwide Protein Data Bank which collects, organises and disseminates data
on biological macromolecular structures. In collaboration with the other Worldwide Protein Data Bank (wwPDB)
partners, we work to collate, maintain and provide access to the global repository of macromolecular structure
models, the Protein Data Bank (PDB).</p>
<a class="btn btn-sm btn-outline-light" href="https://www.ebi.ac.uk/pdbe">
<i class="fas fa-external-link-alt mr-2"></i>
Visit PDBe
</a>
</div>
</div>
<!-- View Model -->
<div id="view-model-part" class="content fade" role="tabpanel" aria-labelledby="view-model-part-trigger">
<div class="step-content">
View model content
</div>
<div class="step-actions d-flex justify-content-center">
<button class="btn btn-lg btn-inactive" data-action="back">Back</button>
</div>
</div>
<!-- About Section Button -->
<div class="text-center mt-4">
</div>
</div>
</div>
<div id="stepper-status" class="alert"></div>
</div>
</section>
{% endblock %}
\ No newline at end of file
......@@ -31,8 +31,8 @@ class CustomOpenAPISchemaGenerator(OpenAPISchemaGenerator):
SelectTemplateApi = get_schema_view(
openapi.Info(
title="CATH-SWISSMODEL API",
default_version='v0.0.1',
title="CATH SelectTemplate API",
default_version='v0.0.2',
description=("Select a template structure on which to model "
"the 3D coordinates of a given protein sequence."),
terms_of_service="https://www.google.com/policies/terms/",
......
......@@ -3,9 +3,9 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1"
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-scripts": "3.1.1"
},
"scripts": {
"precommit": "pretty-quick staged",
......@@ -25,10 +25,11 @@
"not op_mini all"
],
"devDependencies": {
"@material-ui/core": "^3.5.1",
"@material-ui/icons": "^3.0.1",
"@material-ui/core": "^4.3.3",
"@material-ui/icons": "^4.2.1",
"@types/react": "^16.7.6",
"@types/react-dom": "^16.0.9",
"classnames": "^2.2.6",
"enzyme": "^3.7.0",
"enzyme-adapter-react-16": "^1.7.0",
"eslint-plugin-prettier": "^3.0.0",
......
......@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import './App.css';