diff --git a/biosql_pyramid/__init__.py b/biosql_pyramid/__init__.py index 0b6c41c..2ceb95b 100644 --- a/biosql_pyramid/__init__.py +++ b/biosql_pyramid/__init__.py @@ -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() diff --git a/biosql_pyramid/static/javascript/summary.js b/biosql_pyramid/static/javascript/summary.js index 449754e..f5f32b3 100644 --- a/biosql_pyramid/static/javascript/summary.js +++ b/biosql_pyramid/static/javascript/summary.js @@ -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: diff --git a/biosql_pyramid/templates/bioentry_details.mako b/biosql_pyramid/templates/bioentry_details.mako index ecd60d4..5bca1f1 100644 --- a/biosql_pyramid/templates/bioentry_details.mako +++ b/biosql_pyramid/templates/bioentry_details.mako @@ -1,25 +1,40 @@ - -% for key, val in annotations: - - - % if isinstance(val, list): - - % else: - - % endif - -% endfor -
${key} - - % for v in val: - - - - % endfor -
${v[0]}
-
${val}
-
-% for seqcol in sequence:
-    ${seqcol}
-% endfor
-
+ +
+
+ +
+
+ + % for key, val in info: + + + % if isinstance(val, list): + + % else: + + % endif + + % endfor +
${key} + + % for v in val: + + + + % endfor +
${v[0]}
+
${val}
+
+    % for seqcol in sequence:
+        ${seqcol}
+    % endfor
+    
+
+
+ diff --git a/biosql_pyramid/templates/summary.mako b/biosql_pyramid/templates/summary.mako index a016489..7007dee 100644 --- a/biosql_pyramid/templates/summary.mako +++ b/biosql_pyramid/templates/summary.mako @@ -13,11 +13,19 @@

BioEntry Records

- % for record in records: - ${record | n} + % for dbid, record in records: +

+ ${record.id} ${record.description} +

+
+
% endfor

GenBank Upload + + diff --git a/biosql_pyramid/views.py b/biosql_pyramid/views.py index 10393b2..14b0e5d 100644 --- a/biosql_pyramid/views.py +++ b/biosql_pyramid/views.py @@ -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' @@ -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. @@ -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 = """ -

${id} ${description}

-
-
-""" + handle.close() + return Response('Success', content_type='text/javascript')