Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working on #4 #7

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions biosql_pyramid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ def main(global_config, **settings):
#config.add_route('home', '/')
config.add_route('summary', '/')
config.add_route('bioentry_details', 'bioentry_details')
config.add_route('genbank_upload', 'genbank_upload')
config.add_route('download_file', 'download_file')
config.scan()
return config.make_wsgi_app()
8 changes: 5 additions & 3 deletions biosql_pyramid/static/javascript/summary.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,13 @@ $(document).ready(function() {
this.disable();
},
onComplete: function(file, response) {
console.info(response);
if (response.indexOf('Success') == -1) {
alert(response);
}
//button.text('Upload');
button.removeClass("ui-state-disabled");
this.enable();
}
location.reload();
},
});

/* Hover and click logic for buttons:
Expand Down
65 changes: 40 additions & 25 deletions biosql_pyramid/templates/bioentry_details.mako
Original file line number Diff line number Diff line change
@@ -1,25 +1,40 @@
<table id="hor-minimalist-a">
% for key, val in annotations:
<tr>
<td><b>${key}</b></td>
% if isinstance(val, list):
<td>
<table>
% for v in val:
<tr>
<td>${v[0]}</td>
</tr>
% endfor
</table>
</td>
% else:
<td>${val}</td>
% endif
</tr>
% endfor
</table>
<pre>
% for seqcol in sequence:
${seqcol}
% endfor
</pre>
<script src="${request.static_url('biosql_pyramid:static/javascript/jquery/jquery-1.3.2.min.js')}"></script>
<div id='bioentry-${id}'>
<div style='float: right'>
<button id="download-fasta-${id}">Download Fasta</button>
</div>
<div>
<table id="hor-minimalist-a">
% for key, val in info:
<tr>
<td><b>${key}</b></td>
% if isinstance(val, list):
<td>
<table>
% for v in val:
<tr>
<td>${v[0]}</td>
</tr>
% endfor
</table>
</td>
% else:
<td>${val}</td>
% endif
</tr>
% endfor
</table>
<pre>
% for seqcol in sequence:
${seqcol}
% endfor
</pre>
</div>
</div>
<script type='text/javascript'>
// Provide download fasta interaction
$( ":button" ).click(function() {
accession = this.id.split('-')[2];
window.location.href = 'download_file?accession=' + accession + '&format=fasta'
});
</script>
12 changes: 10 additions & 2 deletions biosql_pyramid/templates/summary.mako
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,19 @@
<body>
<h1>BioEntry Records</h1>
<div id="bioentry_records">
% for record in records:
${record | n}
% for dbid, record in records:
<h3>
<a href="bioentry_details?bioentry_key=${dbid}">${record.id} ${record.description}</a>
</h3>
<div>
</div>
% endfor
</div>
<br/>
<a href="#" id="button1" class="fg-button ui-state-default fg-button-icon-left ui-corner-all"><span class="ui-icon ui-icon-newwin"></span>GenBank Upload</a>
</body>
</html>

<!-- <a href="#" id="button_download_${id}" class="fg-button ui-state-default fg-button-icon-left ui-corner-all">
<span class="ui-icon ui-icon-newwin"></span>GenBank Upload</a>
--!>
85 changes: 52 additions & 33 deletions biosql_pyramid/views.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import collections
import json
from StringIO import StringIO

from pyramid.view import view_config
from pyramid.response import Response, FileIter
import pyramid.httpexceptions as httpexceptions
from mako.template import Template

from BioSQL import BioSeqDatabase
from Bio import SeqIO

dbpath = 'biosql.sqlite3'
dbname = 'local_db'
Expand All @@ -25,26 +30,8 @@ def __init__(self, request):
self.request = request

def __call__(self):
return {'records': self._get_records('')}

def _get_records(self, biodb_name):
"""Retrieve BioSQL records in the database.
"""
bioentries = self._get_bioentries(biodb_name)
records = []
for bioentry in bioentries:
key = bioentry[0]
entry = bioentry[1]
b_tmpl = Template(bioentry_template)
retrieve_url = "bioentry_details?bioentry_key=%s" % key
records.append(
b_tmpl.render(
id=entry.id,
description=entry.description,
retrieve_url=retrieve_url
)
)
return records
#return {'records': self._get_records('')}
return {'records': self._get_bioentries('')}

def _get_bioentries(self, biodb_name, start=0, limit=10):
"""Retreive bioentries associated with the database.
Expand All @@ -63,32 +50,64 @@ def bioentry_details(request):
bioentry_key = request.params.get('bioentry_key', '')
biodb = _get_db()
bioentry = biodb.get_Seq_by_primary_id(bioentry_key)
annotations = _build_annotations(bioentry)
annotations.sort()
info = _build_info(bioentry.annotations) + _build_info(bioentry.features[0].qualifiers)
info.sort()
seqstr = str(bioentry.seq)
seqstr = [
seqstr[pos:pos+80] for pos in range(0, len(seqstr), 80)
]
return {'annotations': annotations, 'sequence': seqstr}
return {'id': bioentry.id, 'info': info, 'sequence': seqstr}

def _build_annotations(bioentry):
@view_config(route_name='download_file')
def download_file(request):
biodb = _get_db()
bioentry_id = request.params.get('accession')
outformat = request.params.get('format', 'fasta')
if not bioentry_id:
raise httpexceptions.HTTPBadRequest('No Accession given')
try:
bioentry = biodb.get_Seq_by_ver(bioentry_id)
except Exception as e:
raise httpexceptions.HTTPNotFound('No entry found for %s' % bioentry_id)
try:
out = bioentry.format(outformat)
except ValueError as e:
raise httpexceptions.HTTPBadRequest('%s is not a supported format' % outformat)
output = StringIO(bioentry.format(outformat))
response = request.response
response.content_type = 'text/plain'
response.content_disposition = 'attachment; filename="%s.%s"' % (bioentry_id, outformat)
response.app_iter = FileIter(output)
return response

def _build_info(info_dict):
'''
build a simple (key, value) list from dictionary but for all values that are
iterable, " ,".join(value) them
'''
ann = {}
for key, value in bioentry.annotations.items():
info = {}
for key, value in info_dict.items():
if key.lower() == 'references':
strval = [(ref.title, ref.authors) for ref in value]
elif isinstance(value, list):
strval = ", ".join(map(str, value))
else:
strval = str(value)
ann[key] = strval
return ann.items()
info[key] = strval
return info.items()

@view_config(route_name='genbank_upload')
def genbank_upload(request):
# XXX hack for os.linesep not being present; where did it go?
# os.linesep = "\n"
biodb = _get_db()
handle = request.POST['upload_file'].file
try:
biodb.load(SeqIO.parse(handle, "genbank"))
biodb.adaptor.commit()
except Exception as e: # I would catch the IntegrityError, however, would have to somehow dynamically detect db driver and import that exception
# columns identifier, biodatabase_id are not unique
raise httpexceptions.HTTPClientError("Failed Saving record to database. Likely duplicate record")

bioentry_template = """
<h3><a href="${retrieve_url}">${id} ${description}</a></h3>
<div>
</div>
"""
handle.close()
return Response('Success', content_type='text/javascript')