Merge branch 'django1.7' of mus.cacr.caltech.edu:htsworkflow into django1.7
authorDiane Trout <diane@ghic.org>
Fri, 27 Mar 2015 18:13:50 +0000 (11:13 -0700)
committerDiane Trout <diane@ghic.org>
Fri, 27 Mar 2015 18:13:50 +0000 (11:13 -0700)
126 files changed:
bcmagic/admin.py
bcmagic/forms.py
bcmagic/models.py
bcmagic/plugin.py
bcmagic/urls.py
bcmagic/utils.py
bcmagic/views.py
eland_config/admin.py
eland_config/forms.py
eland_config/models.py
eland_config/urls.py
eland_config/views.py
encode_submission/encode3.py
encode_submission/encode_find.py
encode_submission/geo_gather.py
encode_submission/scan_extension.py
encode_submission/test_encode_find.py
encode_submission/test_ucsc_gather.py
encode_submission/ucsc_gather.py
experiments/admin.py
experiments/experiments.py
experiments/experiments_factory.py
experiments/models.py
experiments/test/test_cluster_station.py
experiments/test/test_filetype.py
experiments/test/test_sequencer.py
experiments/test_experiments.py
experiments/urls.py
experiments/views.py
htsworkflow/auth.py
htsworkflow/automation/copier.py
htsworkflow/automation/spoolwatcher.py
htsworkflow/frontend/analysis/main.py
htsworkflow/frontend/reports/reports.py
htsworkflow/pipelines/bustard.py
htsworkflow/pipelines/configure_run.py
htsworkflow/pipelines/desplit_fastq.py
htsworkflow/pipelines/eland.py
htsworkflow/pipelines/firecrest.py
htsworkflow/pipelines/genome_mapper.py
htsworkflow/pipelines/genomemap.py
htsworkflow/pipelines/gerald.py
htsworkflow/pipelines/ipar.py
htsworkflow/pipelines/qseq2fastq.py
htsworkflow/pipelines/retrieve_config.py
htsworkflow/pipelines/runfolder.py
htsworkflow/pipelines/sequences.py
htsworkflow/pipelines/srf.py
htsworkflow/pipelines/srf2fastq.py
htsworkflow/pipelines/summary.py
htsworkflow/pipelines/test/simulate_runfolder.py
htsworkflow/pipelines/test/test_alignment_free.py
htsworkflow/pipelines/test/test_eland.py
htsworkflow/pipelines/test/test_extract_results.py
htsworkflow/pipelines/test/test_genome_mapper.py
htsworkflow/pipelines/test/test_genomemap.py
htsworkflow/pipelines/test/test_retrieve_config.py
htsworkflow/pipelines/test/test_run_xml.py
htsworkflow/pipelines/test/test_runfolder026.py
htsworkflow/pipelines/test/test_runfolder110.py
htsworkflow/pipelines/test/test_runfolder_casava_1_7.py
htsworkflow/pipelines/test/test_runfolder_ipar100.py
htsworkflow/pipelines/test/test_runfolder_ipar130.py
htsworkflow/pipelines/test/test_runfolder_pair.py
htsworkflow/pipelines/test/test_runfolder_rta.py
htsworkflow/pipelines/test/test_runfolder_rta160.py
htsworkflow/pipelines/test/test_runfolder_rta180.py
htsworkflow/pipelines/test/test_runfolder_rta1_12.py
htsworkflow/pipelines/test/test_samplekey.py
htsworkflow/pipelines/test/test_sequences.py
htsworkflow/pipelines/test/test_summary.py
htsworkflow/settings/local.py
htsworkflow/submission/condorfastq.py
htsworkflow/submission/daf.py
htsworkflow/submission/encoded.py
htsworkflow/submission/submission.py
htsworkflow/submission/test/test_condorfastq.py
htsworkflow/submission/test/test_daf.py
htsworkflow/submission/test/test_results.py
htsworkflow/submission/test/test_submission.py
htsworkflow/submission/test/test_ucsc.py
htsworkflow/submission/ucsc.py
htsworkflow/util/alphanum.py
htsworkflow/util/api.py
htsworkflow/util/config_helper.py
htsworkflow/util/conversion.py
htsworkflow/util/ethelp.py
htsworkflow/util/fctracker.py
htsworkflow/util/hashfile.py
htsworkflow/util/hdquery.py
htsworkflow/util/opener.py
htsworkflow/util/rdfhelp.py
htsworkflow/util/rdfjsonld.py
htsworkflow/util/test/test_alphanum.py
htsworkflow/util/test/test_ethelp.py
htsworkflow/util/test/test_makebed.py
htsworkflow/util/test/test_rdfhelp.py
htsworkflow/util/test/test_validate.py
htsworkflow/util/validate.py
htsworkflow/util/version.py
inventory/admin.py
inventory/bcmagic.py
inventory/inventory_factory.py
inventory/models.py
inventory/test_inventory.py
inventory/urls.py
inventory/views.py
labels/admin.py
labels/models.py
labels/test_labels.py
labels/views.py
requirements/base.txt
samples/admin.py
samples/auth_backend.py
samples/changelist.py
samples/models.py
samples/results.py
samples/samples_factory.py
samples/test_samples.py
samples/urls.py
samples/views.py
scripts/htsw-record-runfolder
scripts/htsw-srf
scripts/htsw-update-archive
test/test_copier.py
test/test_srf2fastq.py

index bb1d1d0381e80c718d57f9acecb2ec6562c5f057..a70dad82fe862e7bd80e8199259a8486cca613ea 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.contrib import admin
 from .models import KeywordMap, Printer
 
index 000acd955651d084c0a22da05d5f1eb092072160..c80a44f49e3e0c59a04422ae380ad44a265b6e1a 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django import forms
 
 class BarcodeMagicForm(forms.Form):
index 4db58a3ddd8e5b27bfcc539cae7fd12fa92a4f74..c91905b7259277d2728e61eb6cb010d2fbc070ee 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.db import models
 
 #FIXME: Should be made more generic and probably pre-populated supported list
@@ -27,5 +29,5 @@ class Printer(models.Model):
     label_height = models.FloatField(help_text='height in inches')
     notes = models.TextField()
 
-    def __unicode__(self):
-        return u'%s, %s, %s, %s, %sx%s' % (self.name, self.model, self.ip_address, self.label_shape, self.label_width, self.label_width)
\ No newline at end of file
+    def __str__(self):
+        return '%s, %s, %s, %s, %sx%s' % (self.name, self.model, self.ip_address, self.label_shape, self.label_width, self.label_width)
index 12de8d23d575f1d7721b369ba03cc819764bcb75..09a1f8ad022e70c53b734d3f32e305a9d6cd3e66 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 BCM_PLUGINS = {
     #'cmd_move_sample': bcm_cmds.cmd_move_sample
 }
index 9133391538c3521a44e9ccbdd4ae820d4e3294ee..478e3c848db721014a2fde2b85d9e239abc7066c 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.conf.urls import patterns
 
 urlpatterns = patterns('',
index ace241f4a748cbebe3aab4f98b56459f9fae8224..a7982003d44477aba87a3ef961331ef0af5e3d1c 100644 (file)
@@ -1,8 +1,10 @@
+from __future__ import unicode_literals
+
 from django.conf import settings
 
 import ftplib
 import socket
-import StringIO
+from six.moves import StringIO
 
 
 def print_zpl(zpl_text, host=None):
index df860770fc26309dbfe2aa64cc8bceb63b112989..4efbcaa7503460420b742396fcaa31922f6fed12 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.http import HttpResponse
 from django.template import RequestContext, Template, Context
 from django.shortcuts import render_to_response
@@ -11,7 +13,7 @@ from . import plugin
 
 try:
     import json
-except ImportError, e:
+except ImportError as e:
     import simplejson as json
 
 import re
index 56107ffcca778463f0d86da98acc48d8aa5470a8..895ecb1431a0eae202a0506b49ae5b58247c3284 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.contrib import admin
 from django.utils.translation import ugettext_lazy as _
 
index a2245f9f35548fe8f231f30cfd7505e18230ea9f..c24bb624d1ca4b335c3781db37051113066ff4d3 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django import forms
 from django.forms.util import ErrorList
 
index 71a836239075aa6e6e4ecb700e9c42c95c022d91..bd4b2abe9e8520ac85fee31e2fd7ed02997b4eaa 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.db import models
 
 # Create your models here.
index eff1477fa2c1eb308bd4a12ba3ab00c6875653f7..38a2cc39574fb4e4514b826dddf463cdd2572fbd 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.conf.urls import patterns, url
 
 urlpatterns = patterns('',
index f4d765e807fad5166b9822d464313376c0c2d7ef..db307411e7141eadd740894ae437738671e4745e 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.conf import settings
 from django.http import HttpResponse
index a3f6d29642bd2e391d8f6802bd138c72a76a86f1..1e1a54a64c8f5e441e6b6f085f5b0b55924c6da8 100644 (file)
@@ -1,7 +1,8 @@
+#!/usr/bin/env python
 """Create a track hub
 """
+from __future__ import print_function, unicode_literals
 
-#!/usr/bin/env python
 from ConfigParser import SafeConfigParser
 import fnmatch
 from glob import glob
@@ -12,14 +13,11 @@ from optparse import OptionParser, OptionGroup
 import os
 from pprint import pprint, pformat
 import shlex
-from StringIO import StringIO
+from six.moves import StringIO
 import stat
 import sys
 import time
 import types
-import urllib
-import urllib2
-import urlparse
 from zipfile import ZipFile
 
 import RDF
@@ -123,7 +121,7 @@ def main(cmdline=None):
 
     if opts.print_rdf:
         writer = get_serializer()
-        print writer.serialize_model_to_string(model)
+        print(writer.serialize_model_to_string(model))
 
 
 def make_parser():
index 7589f5487aef5ef85a6c4ec65072aa3d025ef5bc..dd02f31befe84f3d5df1f1cb4d2c3704a25c0030 100644 (file)
@@ -2,6 +2,7 @@
 """
 Gather information about our submissions into a single RDF store
 """
+from __future__ import print_function
 
 from datetime import datetime
 import hashlib
@@ -17,8 +18,7 @@ import re
 # redland rdf lib
 import RDF
 import sys
-import urllib
-import urlparse
+from six.moves import urllib
 
 if not 'DJANGO_SETTINGS_MODULE' in os.environ:
     os.environ['DJANGO_SETTINGS_MODULE'] = 'htsworkflow.settings'
@@ -130,7 +130,7 @@ def main(cmdline=None):
 
     if opts.print_rdf:
         serializer = get_serializer(name=opts.rdf_parser_name)
-        print serializer.serialize_model_to_string(model)
+        print(serializer.serialize_model_to_string(model))
 
 
 def make_parser():
@@ -261,11 +261,11 @@ def report_submissions_with_no_library(model):
     for row in results:
         subid = row['subid']
         name = row['name']
-        print "# {0}".format(name)
-        print "<{0}>".format(subid.uri)
-        print "  encodeSubmit:library_urn "\
-              "<http://jumpgate.caltech.edu/library/> ."
-        print ""
+        print("# {0}".format(name))
+        print("<{0}>".format(subid.uri))
+        print("  encodeSubmit:library_urn "\
+              "<http://jumpgate.caltech.edu/library/> .")
+        print("")
 
 def find_submissions_with_no_library(model):
     missing_lib_query_text = """
@@ -482,7 +482,7 @@ def reload_libraries(model, library_list):
         load_library_detail(model, library_urn)
 
 def user_library_id_to_library_urn(library_id):
-    split_url = urlparse.urlsplit(library_id)
+    split_url = urllib.parse.urlsplit(library_id)
     if len(split_url.scheme) == 0:
         return LIBRARY_NS[library_id]
     else:
@@ -566,7 +566,7 @@ def load_library_detail(model, libraryUrn):
         try:
             body = get_url_as_text(str(libraryUrn.uri), 'GET')
             rdfaParser.parse_string_into_model(model, body, libraryUrn.uri)
-        except httplib2.HttpLib2ErrorWithResponse, e:
+        except httplib2.HttpLib2ErrorWithResponse as e:
             LOGGER.error(str(e))
     elif len(results) == 1:
         pass  # Assuming that a loaded dataset has one record
@@ -644,7 +644,7 @@ def login(cookie=None):
     response, content = http.request(LOGIN_URL,
                                      'POST',
                                      headers=headers,
-                                     body=urllib.urlencode(credentials))
+                                     body=urllib.parse.urlencode(credentials))
     LOGGER.debug("Login to {0}, status {1}".format(LOGIN_URL,
                                                     response['status']))
 
index 751264cc4276a658491c387852a180fff94929a0..46d7635d2f8e319fe12b9e49b090b66a741c47db 100644 (file)
@@ -1,4 +1,6 @@
 #!/usr/bin/env python
+from __future__ import print_function, unicode_literals
+
 from ConfigParser import SafeConfigParser
 import fnmatch
 from glob import glob
@@ -9,14 +11,11 @@ from optparse import OptionParser, OptionGroup
 import os
 from pprint import pprint, pformat
 import shlex
-from StringIO import StringIO
+from six.moves import StringIO
 import stat
 import sys
 import time
 import types
-import urllib
-import urllib2
-import urlparse
 from zipfile import ZipFile
 
 import RDF
@@ -98,7 +97,7 @@ def main(cmdline=None):
 
     if opts.print_rdf:
         writer = get_serializer()
-        print writer.serialize_model_to_string(model)
+        print(writer.serialize_model_to_string(model))
 
 
 def make_parser():
index 39f19c6461c87e86d24f040a81d37f23dbaffd97..88d53f0653f9592d18f9f788044b81fb6db50f72 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import print_function, unicode_literals
+
 from optparse import OptionParser
 import os
 import sys
@@ -13,7 +15,7 @@ def main(cmdline=None):
     if opts.rdf:
         print_rdf(common_extensions)
     else:
-        print common_extensions
+        print(common_extensions)
         
 def make_parser():
     parser = OptionParser("%prog: directory [directory...]")
@@ -70,7 +72,7 @@ def print_rdf(common_extensions):
         
     writer = rdfhelp.get_serializer()
     writer.set_namespace('thisSubmissionView', subView._prefix)
-    print writer.serialize_model_to_string(model)
+    print(writer.serialize_model_to_string(model))
 
 if __name__ == "__main__":
     main()
index d6dbbc6e7963553baeae5b84610f6b0e695fc349..38a4c610593f72437698840449e50b10f0335728 100644 (file)
@@ -1,4 +1,6 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
+
 from datetime import datetime
 import os
 from unittest import TestCase
@@ -21,7 +23,7 @@ class MockKeyring(keyring.backend.KeyringBackend):
 import keyring
 keyring.set_keyring(MockKeyring())
 
-import encode_find
+from . import encode_find
 from htsworkflow.submission.ucsc import submission_view_url
 from htsworkflow.util.rdfhelp import add_default_schemas, \
      dump_model, get_model, fromTypedNode
index 162f56ad4d6730b13cbb41915b723371828f7cf3..9baf16031aa125735f8799f428db2ff24db0e3cd 100644 (file)
@@ -1,6 +1,8 @@
+from __future__ import absolute_import
+
 from unittest import TestCase, TestSuite, defaultTestLoader
 
-import ucsc_gather
+from . import ucsc_gather
 
 class testUCSCGather(TestCase):
     pass
index a9fa72a83ddc1c4263e509070f50053d238fa405..ba1103b853f6f4d9e5c264b67c9d2999621c722f 100644 (file)
@@ -1,5 +1,7 @@
 #!/usr/bin/env python
-from ConfigParser import SafeConfigParser
+from __future__ import print_function, unicode_literals
+
+from six.moves.configparser import SafeConfigParser
 import fnmatch
 from glob import glob
 import json
@@ -9,14 +11,11 @@ from optparse import OptionParser, OptionGroup
 import os
 from pprint import pprint, pformat
 import shlex
-from StringIO import StringIO
+from six.moves import StringIO
 import stat
 import sys
 import time
 import types
-import urllib
-import urllib2
-import urlparse
 from zipfile import ZipFile
 
 import RDF
@@ -119,7 +118,7 @@ def main(cmdline=None):
 
     if opts.print_rdf:
         writer = get_serializer()
-        print writer.serialize_model_to_string(model)
+        print(writer.serialize_model_to_string(model))
 
 
 def make_parser():
index 6290dbfcf7baeb4fc56e55ce848e5f7552e2464d..b8fff8ac8cd62979d13a1df08d96bc2a589176e9 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from itertools import chain
 
@@ -7,7 +7,7 @@ from django.contrib.admin.widgets import FilteredSelectMultiple
 from django.forms import ModelForm
 from django.forms.fields import Field, CharField
 from django.forms.widgets import TextInput, Select
-from django.utils.encoding import force_unicode
+from django.utils.encoding import force_text
 from django.utils.html import escape, conditional_escape
 from django.utils.translation import ugettext_lazy as _
 
@@ -154,11 +154,11 @@ class SequencerSelect(Select):
 
     def render_options(self, choices, selected_choices):
         # Normalize to strings.
-        selected_choices = set([force_unicode(v) for v in selected_choices])
+        selected_choices = set([force_text(v) for v in selected_choices])
         output = []
         for option_value, option_label in chain(self.choices, choices):
             if isinstance(option_label, (list, tuple)):
-                output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value)))
+                output.append(u'<optgroup label="%s">' % escape(force_text(option_value)))
                 for option in option_label:
                     output.append(self.render_option(selected_choices, *option))
                 output.append(u'</optgroup>')
@@ -171,11 +171,11 @@ class SequencerSelect(Select):
     # nested function in render_options
     def render_options(self, choices, selected_choices):
         # Normalize to strings.
-        selected_choices = set([force_unicode(v) for v in selected_choices])
+        selected_choices = set([force_text(v) for v in selected_choices])
         output = []
         for option_value, option_label in chain(self.choices, choices):
             if isinstance(option_label, (list, tuple)):
-                output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value)))
+                output.append(u'<optgroup label="%s">' % escape(force_text(option_value)))
                 for option in option_label:
                     output.append(self.render_option(selected_choices, *option))
                 output.append(u'</optgroup>')
@@ -185,13 +185,13 @@ class SequencerSelect(Select):
 
 
     def render_option(self, selected_choices, option_value, option_label):
-        disabled_sequencers = [ unicode(s.id) for s in self.queryset.filter(active=False) ]
-        option_value = unicode(option_value)
+        disabled_sequencers = [ str(s.id) for s in self.queryset.filter(active=False) ]
+        option_value = str(option_value)
         selected_html = (option_value in selected_choices) and u' selected="selected"' or ''
         cssclass = "strikeout" if option_value in disabled_sequencers else ''
         return u'<option class="%s" value="%s"%s>%s</option>' % (
             cssclass, escape(option_value), selected_html,
-            conditional_escape(force_unicode(option_label)))
+            conditional_escape(force_text(option_label)))
 
 class SequencerOptions(admin.ModelAdmin):
     list_display = ('name', 'active', 'isdefault', 'instrument_name', 'model')
index a5b8436df567ee7396a46abd9697fcb5c1557f79..fd8fd4e5c623c4bfc4f63d41f14707cd5d5cc2bd 100644 (file)
@@ -1,12 +1,7 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 # some core functions of the exp tracker module
 from datetime import datetime, timedelta
-try:
-    import json
-except ImportError, e:
-    import simplejson as json
-
 import os
 import re
 
@@ -14,7 +9,7 @@ from django.contrib.auth.decorators import login_required
 from django.views.decorators.csrf import csrf_exempt
 from django.core.exceptions import ObjectDoesNotExist
 from django.core.mail import send_mail, mail_admins
-from django.http import HttpResponse, Http404
+from django.http import HttpResponse, Http404, JsonResponse
 from django.conf import settings
 from django.utils import timezone
 
@@ -28,7 +23,7 @@ def flowcell_information(flowcell_id):
     """
     try:
         fc = FlowCell.objects.get(flowcell_id__startswith=flowcell_id)
-    except FlowCell.DoesNotExist, e:
+    except FlowCell.DoesNotExist as e:
         return None
 
     lane_set = {}
@@ -43,7 +38,7 @@ def flowcell_information(flowcell_id):
             'library_name': lane.library.library_name,
             'library_id': lane.library.id,
             'library_species': lane.library.library_species.scientific_name,
-            'pM': unicode(lane.pM),
+            'pM': str(lane.pM),
             'read_length': lane.flowcell.read_length,
             'status_code': lane.status,
             'status': LANE_STATUS_MAP[lane.status]
@@ -90,8 +85,7 @@ def flowcell_json(request, fc_id):
     if fc_dict is None:
         raise Http404
 
-    fc_json = json.dumps({'result': fc_dict})
-    return HttpResponse(fc_json, content_type = 'application/json')
+    return JsonResponse({'result': fc_dict})
 
 def lanes_for(username=None):
     """
@@ -126,13 +120,12 @@ def lanes_for_json(request, username):
 
     try:
         result = lanes_for(username)
-    except ObjectDoesNotExist, e:
+    except ObjectDoesNotExist as e:
         raise Http404
 
     #convert query set to python structure
 
-    result_json = json.dumps({'result': result})
-    return HttpResponse(result_json, content_type='application/json')
+    return JsonResponse({'result': result})
 
 
 def updStatus(request):
@@ -148,22 +141,22 @@ def updStatus(request):
       user = request.user
 
     #Check access permission
-    if not (user.is_superuser and settings.ALLOWED_IPS.has_key(ClIP)):
+    if not (user.is_superuser and ClIP in settings.ALLOWED_IPS):
         return HttpResponse("%s access denied from %s." % (user, ClIP))
 
     # ~~~~~~Parameters for the job ~~~~
-    if request.REQUEST.has_key('fcid'):
+    if 'fcid' in request.REQUEST:
       fcid = request.REQUEST['fcid']
     else:
       return HttpResponse('missing fcid')
 
-    if request.REQUEST.has_key('runf'):
+    if 'runf' in request.REQUEST:
       runfolder = request.REQUEST['runf']
     else:
       return HttpResponse('missing runf')
 
 
-    if request.REQUEST.has_key('updst'):
+    if 'updst' in request.REQUEST:
       UpdatedStatus = request.REQUEST['updst']
     else:
       return HttpResponse('missing status')
@@ -179,7 +172,7 @@ def updStatus(request):
       #if there's a message update that too
       mytimestamp = timezone.now().__str__()
       mytimestamp = re.sub(pattern=":[^:]*$",repl="",string=mytimestamp)
-      if request.REQUEST.has_key('msg'):
+      if 'msg' in request.REQUEST:
         rec.run_note += ", "+request.REQUEST['msg']+" ("+mytimestamp+")"
       else :
         if UpdatedStatus == '1':
@@ -201,7 +194,7 @@ def updStatus(request):
 def generateConfile(request,fcid):
     #granted = False
     #ClIP = request.META['REMOTE_ADDR']
-    #if (settings.ALLOWED_IPS.has_key(ClIP)):  granted = True
+    #if (ClIP in settings.ALLOWED_IPS):  granted = True
 
     #if not granted: return HttpResponse("access denied.")
 
@@ -228,7 +221,7 @@ def generateConfile(request,fcid):
 def getConfile(req):
     granted = False
     ClIP = req.META['REMOTE_ADDR']
-    if (settings.ALLOWED_IPS.has_key(ClIP)):  granted = True
+    if (ClIP in settings.ALLOWED_IPS):  granted = True
 
     if not granted: return HttpResponse("access denied. IP: "+ClIP)
 
@@ -236,9 +229,9 @@ def getConfile(req):
     cnfgfile = 'Nothing found'
     runfolder = 'unknown'
     request = req.REQUEST
-    if request.has_key('fcid'):
+    if 'fcid' in request:
       fcid = request['fcid']
-      if request.has_key('runf'):
+      if 'runf' in request:
         runfolder = request['runf']
         try:
           rec = DataRun.objects.get(run_folder=runfolder) #,flowcell_id=fcid)
@@ -262,14 +255,14 @@ def getConfile(req):
 def getLaneLibs(req):
     granted = False
     ClIP = req.META['REMOTE_ADDR']
-    if (settings.ALLOWED_IPS.has_key(ClIP)):  granted = True
+    if (ClIP in settings.ALLOWED_IPS):  granted = True
 
     if not granted: return HttpResponse("access denied.")
 
     request = req.REQUEST
     fcid = 'none'
     outputfile = ''
-    if request.has_key('fcid'):
+    if 'fcid' in request:
       fcid = request['fcid']
       try:
         rec = FlowCell.objects.get(flowcell_id=fcid)
index 1e344b3b86293d52d16fca625fad6f0402e69a31..34e9d5f1d90de80042056c7bd22854cbf3524d13 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 import datetime
 
 import factory
index 6b92a1845dc334b2fa6a1ae3e8a68f2371186253..6e1fe27678ebee218a7bfda5b7f29e54c28c937c 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 import datetime
 import glob
@@ -25,7 +25,7 @@ LOGGER = logging.getLogger(__name__)
 default_pM = 5
 try:
     default_pM = int(settings.DEFAULT_PM)
-except AttributeError, e:
+except AttributeError as e:
     LOGGER.error("invalid value for default_pm")
 
 # how many days to wait before trying to re-import a runfolder
@@ -58,8 +58,8 @@ class ClusterStation(models.Model):
     class Meta:
         ordering = ["-isdefault", "name"]
 
-    def __unicode__(self):
-        return unicode(self.name)
+    def __str__(self):
+        return str(self.name)
 
     @staticmethod
     def update_isdefault(sender, instance, **kwargs):
@@ -96,10 +96,10 @@ class Sequencer(models.Model):
     class Meta:
         ordering = ["-isdefault", "-active", "name"]
 
-    def __unicode__(self):
-        name = [unicode(self.name)]
+    def __str__(self):
+        name = [str(self.name)]
         if self.instrument_name is not None:
-            name.append("(%s)" % (unicode(self.instrument_name),))
+            name.append("(%s)" % (str(self.instrument_name),))
         return " ".join(name)
 
     @models.permalink
@@ -152,8 +152,8 @@ class FlowCell(models.Model):
 
     notes = models.TextField(blank=True)
 
-    def __unicode__(self):
-        return unicode(self.flowcell_id)
+    def __str__(self):
+        return str(self.flowcell_id)
 
     def Lanes(self):
         html = ['<table>']
@@ -187,9 +187,9 @@ class FlowCell(models.Model):
         """Convert our boolean 'is paired' flag to a name
         """
         if self.paired_end:
-            return u"Paired"
+            return "Paired"
         else:
-            return u"Single"
+            return "Single"
 
     @models.permalink
     def get_absolute_url(self):
@@ -309,8 +309,8 @@ class Lane(models.Model):
         return ('experiments.views.flowcell_lane_detail',
                 [str(self.id)])
 
-    def __unicode__(self):
-        return self.flowcell.flowcell_id + ':' + unicode(self.lane_number)
+    def __str__(self):
+        return self.flowcell.flowcell_id + ':' + str(self.lane_number)
 
 
 class DataRun(models.Model):
@@ -423,8 +423,8 @@ class FileType(models.Model):
         return self.name.replace(' ', '_').lower()
     normalized_name = property(_get_normalized_name)
 
-    def __unicode__(self):
-        #return u"<FileType: %s>" % (self.name,)
+    def __str__(self):
+        #return "<FileType: %s>" % (self.name,)
         return self.name
 
 
index 965faa92765f04f89c75614b6cf040a206a6347b..9bd53197f74225083de54236dad8d2bd3406ad00 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.test import TestCase
 from ..models import ClusterStation, cluster_station_default
index fdef8bfffc0cba0d82dc7859a4fe849d6d0290a5..cb89087a797b7ef87fe9ddb8ba71cb471de5ce65 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.test import TestCase
 
@@ -9,8 +9,8 @@ class TestFileType(TestCase):
         file_type_objects = FileType.objects
         name = 'QSEQ tarfile'
         file_type_object = file_type_objects.get(name=name)
-        self.assertEqual(u"QSEQ tarfile",
-                             unicode(file_type_object))
+        self.assertEqual("QSEQ tarfile",
+                         str(file_type_object))
 
     def test_find_file_type(self):
         file_type_objects = FileType.objects
index 0de4f5a4cdf8858e1bb05b163bff14f35f9cf1b8..c3d4a32fd396c4b65e082d657d28950c8a4f2856 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.test import TestCase
 from ..models import Sequencer, sequencer_default
index 5a39d44832ace72af08ffa42f2426bcb71b17846..03ad813b7b4cf907138b5dfbc52bb08a74030df2 100644 (file)
@@ -1,16 +1,16 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 import re
 from lxml.html import fromstring
 try:
     import json
-except ImportError, e:
+except ImportError as e:
     import simplejson as json
 import os
 import shutil
 import sys
 import tempfile
-from urlparse import urljoin
+from six.moves.urllib.parse import urljoin
 
 from django.conf import settings
 from django.core import mail
@@ -19,6 +19,7 @@ from django.test import TestCase
 from django.test.utils import setup_test_environment, teardown_test_environment
 from django.db import connection
 from django.conf import settings
+from django.utils.encoding import smart_text
 
 from .models import ClusterStation, cluster_station_default, \
     DataRun, Sequencer, FlowCell, FileType
@@ -108,7 +109,7 @@ class ExperimentsTestCases(TestCase):
         fc42jtn = self.fc42jtn
         fc42ju1 = FlowCellFactory(flowcell_id='42JU1AAXX')
 
-        for fc_id in [u'FC12150', u"42JTNAAXX", "42JU1AAXX"]:
+        for fc_id in ['FC12150', '42JTNAAXX', '42JU1AAXX']:
             fc_dict = flowcell_information(fc_id)
             fc_django = FlowCell.objects.get(flowcell_id=fc_id)
             self.assertEqual(fc_dict['flowcell_id'], fc_id)
@@ -133,7 +134,7 @@ class ExperimentsTestCases(TestCase):
 
             response = self.client.get('/experiments/config/%s/json' % (fc_id,), apidata)
             # strptime isoformat string = '%Y-%m-%dT%H:%M:%S'
-            fc_json = json.loads(response.content)['result']
+            fc_json = json.loads(smart_text(response.content))['result']
             self.assertEqual(fc_json['flowcell_id'], fc_id)
             self.assertEqual(fc_json['sequencer'], fc_django.sequencer.name)
             self.assertEqual(fc_json['read_length'], fc_django.read_length)
@@ -142,7 +143,7 @@ class ExperimentsTestCases(TestCase):
 
 
             for lane in fc_django.lane_set.all():
-                lane_contents = fc_json['lane_set'][unicode(lane.lane_number)]
+                lane_contents = fc_json['lane_set'][str(lane.lane_number)]
                 lane_dict = multi_lane_to_dict(lane_contents)[lane.library_id]
 
                 self.assertEqual(lane_dict['cluster_estimate'], lane.cluster_estimate)
@@ -166,7 +167,7 @@ class ExperimentsTestCases(TestCase):
         """
         Require logging in to retrieve meta data
         """
-        response = self.client.get(u'/experiments/config/FC12150/json')
+        response = self.client.get('/experiments/config/FC12150/json')
         self.assertEqual(response.status_code, 403)
 
     def test_library_id(self):
@@ -175,7 +176,7 @@ class ExperimentsTestCases(TestCase):
         """
         response = self.client.get('/experiments/config/FC12150/json', apidata)
         self.assertEqual(response.status_code, 200)
-        flowcell = json.loads(response.content)['result']
+        flowcell = json.loads(smart_text(response.content))['result']
 
         # library id is 12150 + lane number (1-8), so 12153
         lane_contents = flowcell['lane_set']['3']
@@ -184,7 +185,7 @@ class ExperimentsTestCases(TestCase):
 
         response = self.client.get('/samples/library/12153/json', apidata)
         self.assertEqual(response.status_code, 200)
-        library_12153 = json.loads(response.content)['result']
+        library_12153 = json.loads(smart_text(response.content))['result']
 
         self.assertEqual(library_12153['library_id'], '12153')
 
@@ -200,7 +201,7 @@ class ExperimentsTestCases(TestCase):
         This tests to make sure that the value entered in the raw library id field matches
         the library id looked up.
         """
-        expected_ids = [ u'1215{}'.format(i) for i in range(1,9) ]
+        expected_ids = [ '1215{}'.format(i) for i in range(1,9) ]
         self.assertTrue(self.client.login(username=self.admin.username, password=self.password))
         response = self.client.get('/admin/experiments/flowcell/{}/'.format(self.fc12150.id))
 
@@ -266,7 +267,7 @@ class ExperimentsTestCases(TestCase):
         self.assertEqual(len(lanes), 8)
 
         response = self.client.get('/experiments/lanes_for/%s/json' % (user,), apidata)
-        lanes_json = json.loads(response.content)['result']
+        lanes_json = json.loads(smart_text(response.content))['result']
         self.assertEqual(len(lanes), len(lanes_json))
         for i in range(len(lanes)):
             self.assertEqual(lanes[i]['comment'], lanes_json[i]['comment'])
@@ -295,7 +296,6 @@ class ExperimentsTestCases(TestCase):
         response = self.client.get('/experiments/lanes_for/%s/json' % (user,), apidata)
         self.assertEqual(response.status_code, 404)
 
-
     def test_raw_data_dir(self):
         """Raw data path generator check"""
         flowcell_id = self.fc1_id
@@ -392,7 +392,7 @@ class ExperimentsTestCases(TestCase):
         if status is not None: self.assertTrue(status)
 
         ns = urljoin('http://localhost', url)
-        load_string_into_model(model, 'rdfa', response.content, ns=ns)
+        load_string_into_model(model, 'rdfa', smart_text(response.content), ns=ns)
         body = """prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
         prefix libns: <http://jumpgate.caltech.edu/wiki/LibraryOntology#>
 
@@ -409,7 +409,7 @@ class ExperimentsTestCases(TestCase):
         count = 0
         for r in query.execute(model):
             count += 1
-            self.assertEqual(fromTypedNode(r['flowcell_id']), u'FC12150')
+            self.assertEqual(fromTypedNode(r['flowcell_id']), 'FC12150')
             lane_id = fromTypedNode(r['lane_id'])
             library_id = fromTypedNode(r['library_id'])
             self.assertTrue(library_id in expected[lane_id])
@@ -460,8 +460,8 @@ class TestEmailNotify(TestCase):
         response = self.client.get(self.url)
         self.assertEqual(response.status_code, 200)
 
-        self.assertTrue(self.affiliation.email in response.content)
-        self.assertTrue(self.library.library_name in response.content)
+        self.assertTrue(self.affiliation.email in smart_text(response.content))
+        self.assertTrue(self.library.library_name in smart_text(response.content))
 
         response = self.client.get(self.url, {'send':'1','bcc':'on'})
         self.assertEqual(response.status_code, 200)
@@ -481,9 +481,10 @@ class TestEmailNotify(TestCase):
         response = self.client.get(self.url)
         self.assertEqual(response.status_code, 200)
         #print("email navigation content:", response.content)
-        self.assertTrue(re.search(self.fc.flowcell_id, response.content))
+        self.assertTrue(re.search(self.fc.flowcell_id, smart_text(response.content)))
         # require that navigation back to the admin page exists
-        self.assertTrue(re.search('<a href="{}">[^<]+</a>'.format(admin_url), response.content))
+        self.assertTrue(re.search('<a href="{}">[^<]+</a>'.format(admin_url),
+                                  smart_text(response.content)))
 
 def multi_lane_to_dict(lane):
     """Convert a list of lane entries into a dictionary indexed by library ID
@@ -502,7 +503,7 @@ class TestSequencer(TestCase):
         seq.instrument_name = "HWI-SEQ1"
         seq.model = "Imaginary 5000"
 
-        self.assertEqual(unicode(seq), "Seq1 (HWI-SEQ1)")
+        self.assertEqual(str(seq), "Seq1 (HWI-SEQ1)")
 
     def test_lookup(self):
         fc = self.fc12150
@@ -554,7 +555,7 @@ class TestSequencer(TestCase):
         status = validate_xhtml(response.content)
         if status is not None: self.assertTrue(status)
 
-        load_string_into_model(model, 'rdfa', response.content)
+        load_string_into_model(model, 'rdfa', smart_text(response.content))
 
         errmsgs = list(inference.run_validation())
         self.assertEqual(len(errmsgs), 0)
@@ -572,11 +573,12 @@ class TestSequencer(TestCase):
 
         url = '/lane/{}'.format(self.lane.id)
         response = self.client.get(url)
+        rdfbody = smart_text(response.content)
         self.assertEqual(response.status_code, 200)
-        status = validate_xhtml(response.content)
+        status = validate_xhtml(rdfbody)
         if status is not None: self.assertTrue(status)
 
-        load_string_into_model(model, 'rdfa', response.content)
+        load_string_into_model(model, 'rdfa', rdfbody)
 
         errmsgs = list(inference.run_validation())
         self.assertEqual(len(errmsgs), 0)
index 8330d91f12c6b5fdf3f8394b1ef6e8be1deac940..0b1722ec1a43df24d2b1626885867b161ab508a6 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.conf.urls import patterns
 
 urlpatterns = patterns('',
index 294aff27a7ee41e664d4d6a86be047761606a38b..7d30bbeb19d337da8ce3b5f2af57422b640da49b 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 # Create your views here.
 from datetime import datetime
@@ -176,7 +176,7 @@ def read_result_file(self, key):
         content_type = data_file.file_type.mimetype
 
     if os.path.exists(data_file.pathname):
-        return HttpResponse(open(data_file.pathname,'r'),
+        return HttpResponse(open(data_file.pathname,'rb'),
                             content_type=content_type)
 
     raise Http404
index 5688cc9c061231c560ade2fe0b694e238193dc82..1d781e19c3a44dda03bd9aacf4c5201a7010945e 100644 (file)
@@ -8,7 +8,7 @@ apidata = {'apiid': u'0', 'apikey': settings.DEFAULT_API_KEY}
 
 def require_api_key(request):
     # make sure we have the api component
-    if not (request.REQUEST.has_key('apiid') or request.REQUEST.has_key('apikey')):
+    if not ('apiid' in request.REQUEST or 'apikey' in request.REQUEST):
         raise PermissionDenied
 
     # make sure the id and key are right
index 1dc719d96b0c0bdfc851e0ef3e56e162b00e77bc..1ba0ab26c8956084498508d19f99bb552fb3bf19 100644 (file)
@@ -9,7 +9,7 @@ import subprocess
 import sys
 import time
 import traceback
-import urlparse
+from six.moves import urllib
 
 from benderjab import rpc
 
@@ -289,13 +289,13 @@ class CopierBot(rpc.XmlRpcBot):
         return reply
 
     def validate_url(self, url):
-        user_url = urlparse.urlsplit(url)
+        user_url = urllib.parse.urlsplit(url)
         user_scheme = user_url[0]
         user_netloc = user_url[1]
         user_path = user_url[2]
 
         for source in self.sources:
-            source_url = urlparse.urlsplit(source)
+            source_url = urllib.parse.urlsplit(source)
             source_scheme = source_url[0]
             source_netloc = source_url[1]
             source_path = source_url[2]
index e226234d6d392f67cd774cb436dc9660ad22e71b..2888be0beaac1d1e46ee0af34b8114ba2c4ecc76 100644 (file)
@@ -72,7 +72,7 @@ class Handler(pyinotify.ProcessEvent):
 
                     # if we've already seen an event in this directory (AKA runfolder)
                     # keep track if its already hit the "completed" flag
-                    if watch_path_events.has_key(target):
+                    if target in watch_path_events:
                        run_already_complete = watch_path_events[target].complete
 
                     watch_path_events[target] = WatcherEvent(target)
index ba2a739d5be0b461aaf02264a40dda6ed90e6863..71d711d72dca7e9dac47806e9b3e4635d842d123 100644 (file)
@@ -14,20 +14,20 @@ def updStatus(request):
     ClIP = request.META['REMOTE_ADDR']
     #Check client access permission                                                                                                                                       
     granted = False
-    if (settings.ALLOWED_ANALYS_IPS.has_key(ClIP)):  granted = True
+    if (ClIP in settings.ALLOWED_ANALYS_IPS):  granted = True
     if not granted: return HttpResponse("access denied.")
 
     output=''
     taskid=-1;
     # Check required param
-    if request.has_key('taskid'): taskid = request['taskid']
+    if 'taskid' in request: taskid = request['taskid']
     else:  return HttpResponse('missing param task id')
 
     try:
       rec = Task.objects.get(id=taskid)
       mytimestamp = datetime.now().__str__()
       mytimestamp = re.sub(pattern=":[^:]*$",repl="",string=mytimestamp)
-      if request.has_key('msg'):
+      if 'msg' in request:
         rec.task_status += ", "+request['msg']+" ("+mytimestamp+")"
       else :
         rec.task_status = "Registered ("+mytimestamp+")"
@@ -43,13 +43,13 @@ def getProjects(request):
     ClIP = request.META['REMOTE_ADDR']
     #Check client access permission 
     granted = False
-    if (settings.ALLOWED_ANALYS_IPS.has_key(ClIP)):  granted = True
+    if (ClIP in settings.ALLOWED_ANALYS_IPS):  granted = True
     if not granted: return HttpResponse("access denied.")
 
     outputfile = ''
     
     All=False
-    if (request.has_key('mode')):
+    if ('mode' in request):
       if request['mode']=='all':
         All=True
 
index 18cd3285c5bb90b4fdeaea37292f02fdb9ade45a..e2ff54f817850babf06791e97ea26d0502af703d 100644 (file)
@@ -27,7 +27,7 @@ def getBgColor(reads_cnt,exp_type):
 def report1(request):
   EXP = 'ChIP-seq'
 
-  if request.GET.has_key('aflid'):
+  if 'aflid' in request.GET:
     AFL_Id = request.GET['aflid']
     try:
       AFL = Affiliation.objects.get(id=AFL_Id).name
@@ -170,10 +170,10 @@ def report1(request):
 def report_RM(request): #for RNA-Seq and Methyl-Seq
   EXP = 'RNA-seq'  
 
-  if request.GET.has_key('exp'):
+  if 'exp' in request.GET:
     EXP = request.GET['exp'] # Methyl-seq
 
-  if request.GET.has_key('aflid'):
+  if 'aflid' in request.GET:
     AFL_Id = request.GET['aflid']
     try:
       AFL = Affiliation.objects.get(id=AFL_Id).name
index 99f231dd73e748a0c88b528f4489968ab20b8428..e56659f6c39975e011695d92813ec468dad5c36a 100644 (file)
@@ -4,6 +4,8 @@ Extract configuration from Illumina Bustard Directory.
 This includes the version number, run date, bustard executable parameters, and
 phasing estimates.
 """
+from __future__ import print_function, unicode_literals
+
 from copy import copy
 from datetime import date
 from glob import glob
@@ -111,7 +113,7 @@ class CrosstalkMatrix(object):
         for b in base_order:
             for value in self.base[b]:
                 crosstalk_value = ElementTree.SubElement(root, CrosstalkMatrix.ELEMENT)
-                crosstalk_value.text = unicode(value)
+                crosstalk_value.text = str(value)
                 crosstalk_value.tail = os.linesep
 
         return root
@@ -289,7 +291,7 @@ class Bustard(object):
     time = property(_get_time, doc='return run time as seconds since epoch')
 
     def dump(self):
-        #print ElementTree.tostring(self.get_elements())
+        #print(ElementTree.tostring(self.get_elements()))
         ElementTree.dump(self.get_elements())
 
     def get_elements(self):
@@ -307,7 +309,7 @@ class Bustard(object):
 
         # add phasing parameters
         for lane in LANE_LIST:
-            if self.phasing.has_key(lane):
+            if lane in self.phasing:
                 params.append(self.phasing[lane].get_elements())
 
         # add crosstalk matrix if it exists
@@ -456,22 +458,22 @@ def main(cmdline):
     opts, args = parser.parse_args(cmdline)
 
     for bustard_dir in args:
-        print u'analyzing bustard directory: ' + unicode(bustard_dir)
+        print(u'analyzing bustard directory: ' + str(bustard_dir))
         bustard_object = bustard(bustard_dir)
         bustard_object.dump()
 
         bustard_object2 = Bustard(xml=bustard_object.get_elements())
-        print ('-------------------------------------')
+        print('-------------------------------------')
         bustard_object2.dump()
-        print ('=====================================')
+        print('=====================================')
         b1_tree = bustard_object.get_elements()
         b1 = ElementTree.tostring(b1_tree).split(os.linesep)
         b2_tree = bustard_object2.get_elements()
         b2 = ElementTree.tostring(b2_tree).split(os.linesep)
         for line1, line2 in zip(b1, b2):
             if b1 != b2:
-                print "b1: ", b1
-                print "b2: ", b2
+                print("b1: ", b1)
+                print("b2: ", b2)
 
 if __name__ == "__main__":
     main(sys.argv[1:])
index 83c7569d2816b03e3a67a3fb4f376589ae472a5f..d0d43d25e579e62e7a7ddceb6774d187457a118b 100644 (file)
@@ -377,16 +377,16 @@ def retrieve_config(conf_info, flowcell, cfg_filepath, genome_dir):
   try:
     saveConfigFile(flowcell, options.url, cfg_filepath)
     conf_info.config_filepath = cfg_filepath
-  except FlowCellNotFound, e:
+  except FlowCellNotFound as e:
     LOGGER.error(e)
     return False
-  except WebError404, e:
+  except WebError404 as e:
     LOGGER.error(e)
     return False
-  except IOError, e:
+  except IOError as e:
     LOGGER.error(e)
     return False
-  except Exception, e:
+  except Exception as e:
     LOGGER.error(e)
     return False
 
index c9947a2ef2317b0a05f7c36e966eb152949fc1f3..b6d740c33df351388c21739b28e522a675dea249 100644 (file)
@@ -31,9 +31,9 @@ def main(cmdline=None):
 
     if opts.output is not None:
         if opts.bzip:
-            output = bz2.BZ2File(opts.output,'w')
+            output = bz2.BZ2File(opts.output, 'wt')
         elif opts.gzip:
-            output = gzip.GzipFile(opts.output, 'w')
+            output = gzip.GzipFile(opts.output, 'wt')
         else:
             output = open(opts.output, 'w')
     else:
index a508a494c8c24900e8574c75f43c3616bf309814..39030fad842f3415d8f29cc3f4ed463a630d0d78 100644 (file)
@@ -1,6 +1,8 @@
 """
 Analyze ELAND files
 """
+from __future__ import print_function
+
 import collections
 from glob import glob
 import logging
@@ -148,7 +150,7 @@ class ElandLane(ResultLane):
         self._reads = 0
 
         for pathname in self.pathnames:
-            stream = autoopen(pathname, 'r')
+            stream = autoopen(pathname, 'rt')
             if self.eland_type == ELAND_SINGLE:
                 result = self._update_eland_result(stream)
             elif self.eland_type == ELAND_MULTI or \
@@ -376,7 +378,7 @@ class ElandLane(ResultLane):
     def get_elements(self):
         lane = ElementTree.Element(ElandLane.LANE,
                                    {'version':
-                                    unicode(ElandLane.XML_VERSION)})
+                                    str(ElandLane.XML_VERSION)})
         sample_tag = ElementTree.SubElement(lane, SAMPLE_NAME)
         sample_tag.text = self.sample_name
         lane_tag = ElementTree.SubElement(lane, LANE_ID)
@@ -388,19 +390,19 @@ class ElandLane(ResultLane):
         for k, v in self.genome_map.items():
             item = ElementTree.SubElement(
                 genome_map, GENOME_ITEM,
-                {'name':k, 'value':unicode(v)})
+                {'name':k, 'value':str(v)})
         mapped_reads = ElementTree.SubElement(lane, MAPPED_READS)
         for k, v in self.mapped_reads.items():
             item = ElementTree.SubElement(
                 mapped_reads, MAPPED_ITEM,
-                {'name':k, 'value':unicode(v)})
+                {'name':k, 'value':str(v)})
         match_codes = ElementTree.SubElement(lane, MATCH_CODES)
         for k, v in self.match_codes.items():
             item = ElementTree.SubElement(
                 match_codes, MATCH_ITEM,
-                {'name':k, 'value':unicode(v)})
+                {'name':k, 'value':str(v)})
         reads = ElementTree.SubElement(lane, READS)
-        reads.text = unicode(self.reads)
+        reads.text = str(self.reads)
 
         return lane
 
@@ -546,7 +548,7 @@ class SequenceLane(ResultLane):
         """
         Determine if we have a scarf or fastq sequence file
         """
-        f = open(pathname,'r')
+        f = open(pathname,'rt')
         l = f.readline()
         f.close()
 
@@ -573,8 +575,8 @@ class SequenceLane(ResultLane):
 
         LOGGER.info("summarizing results for %s" % (pathname))
         lines = 0
-        f = open(pathname)
-        for l in f.xreadlines():
+        f = open(pathname, 'rt')
+        for l in f:
             lines += 1
         f.close()
 
@@ -589,7 +591,7 @@ class SequenceLane(ResultLane):
     def get_elements(self):
         lane = ElementTree.Element(SequenceLane.LANE,
                                    {'version':
-                                    unicode(SequenceLane.XML_VERSION)})
+                                    str(SequenceLane.XML_VERSION)})
         sample_tag = ElementTree.SubElement(lane, SAMPLE_NAME)
         sample_tag.text = self.sample_name
         lane_tag = ElementTree.SubElement(lane, LANE_ID)
@@ -598,9 +600,9 @@ class SequenceLane(ResultLane):
             end_tag = ElementTree.SubElement(lane, END)
             end_tag.text = str(self.end)
         reads = ElementTree.SubElement(lane, READS)
-        reads.text = unicode(self.reads)
+        reads.text = str(self.reads)
         sequence_type = ElementTree.SubElement(lane, SequenceLane.SEQUENCE_TYPE)
-        sequence_type.text = unicode(SequenceLane.SEQUENCE_DESCRIPTION[self.sequence_type])
+        sequence_type.text = str(SequenceLane.SEQUENCE_DESCRIPTION[self.sequence_type])
 
         return lane
 
@@ -618,7 +620,7 @@ class SequenceLane(ResultLane):
             elif tag == END.lower():
                 self.end = int(element.text)
             elif tag == READS.lower():
-                self._reads = int(element.text)
+                self._reads = int(float(element.text))
             elif tag == SequenceLane.SEQUENCE_TYPE.lower():
                 self.sequence_type = lookup_sequence_type.get(element.text, None)
             else:
@@ -657,8 +659,7 @@ class ELAND(collections.MutableMapping):
         del self.result[key]
 
     def __iter__(self):
-        keys = self.results.iterkeys()
-        for k in sorted(keys):
+        for k in sorted(self.results):
             yield k
 
     def __len__(self):
@@ -675,13 +676,13 @@ class ELAND(collections.MutableMapping):
 
     def get_elements(self):
         root = ElementTree.Element(ELAND.ELAND,
-                                   {'version': unicode(ELAND.XML_VERSION)})
+                                   {'version': str(ELAND.XML_VERSION)})
 
         for key in self:
             eland_lane = self[key].get_elements()
-            eland_lane.attrib[ELAND.END] = unicode(self[key].end-1)
-            eland_lane.attrib[ELAND.LANE_ID] = unicode(self[key].lane_id)
-            eland_lane.attrib[ELAND.SAMPLE] = unicode(self[key].sample_name)
+            eland_lane.attrib[ELAND.END] = str(self[key].end-1)
+            eland_lane.attrib[ELAND.LANE_ID] = str(self[key].lane_id)
+            eland_lane.attrib[ELAND.SAMPLE] = str(self[key].sample_name)
             root.append(eland_lane)
         return root
         return root
@@ -895,7 +896,7 @@ def main(cmdline=None):
     for a in args:
         LOGGER.info("Starting scan of %s" % (a,))
         e = eland(a)
-        print ElementTree.tostring(e.get_elements())
+        print(ElementTree.tostring(e.get_elements()))
     return
 
 
index 3519eb0123600ef99602cccb25210d119a62a073..fba83f9d97c782b349f5021d6bbbe0919e65b5e4 100644 (file)
@@ -9,6 +9,7 @@ fromxml
   Firecrest factory function initalized from an xml dump from
   the Firecrest object.
 """
+from __future__ import print_function
 
 from datetime import date
 from glob import glob
@@ -66,11 +67,11 @@ class Firecrest(object):
     def dump(self):
         """Report debugginf information
         """
-        print "Starting cycle:", self.start
-        print "Ending cycle:", self.stop
-        print "Firecrest version:", self.version
-        print "Run date:", self.date
-        print "user:", self.user
+        print("Starting cycle:", self.start)
+        print("Ending cycle:", self.stop)
+        print("Firecrest version:", self.version)
+        print("Run date:", self.date)
+        print("user:", self.user)
 
     def get_elements(self):
         """Return XML serialization structure.
@@ -144,7 +145,7 @@ def firecrest(pathname):
     if os.path.exists(matrix_pathname):
         # this is for firecrest < 1.3.2
         f.matrix = open(matrix_pathname, 'r').read()
-    elif glob(bustard_pattern) > 0:
+    elif len(glob(bustard_pattern)) > 0:
         f.matrix = None
         # there are runs here. Bustard should save the matrix.
     else:
index fb16d7ffc60ed70ce11c10b4a204316de9e3f37e..62619e2155362207612a7f0dabf3ed13c5b77db4 100644 (file)
@@ -6,7 +6,7 @@ import re
 
 import logging
 
-from htsworkflow.util.alphanum import alphanum
+from htsworkflow.util.alphanum import natural_sort_key
 
 LOGGER = logging.getLogger(__name__)
 class DuplicateGenome(Exception): pass
@@ -30,7 +30,7 @@ def getAvailableGenomes(genome_base_dir):
   # Need valid directory
   if not os.path.exists(genome_base_dir):
     msg = "Directory does not exist: %s" % (genome_base_dir)
-    raise IOError, msg
+    raise IOError(msg)
 
   # Find all subdirectories
   filepath_list = glob.glob(os.path.join(genome_base_dir, '*'))
@@ -60,7 +60,7 @@ def getAvailableGenomes(genome_base_dir):
     build_dict = d.setdefault(species, {})
     if build in build_dict:
       msg = "Duplicate genome for %s|%s" % (species, build)
-      raise DuplicateGenome, msg
+      raise DuplicateGenome(msg)
 
     build_dict[build] = genome_dir
 
@@ -88,11 +88,10 @@ class constructMapperDict(object):
           builds = self.genome_dict[elements[0]]
 
           # sort build names the way humans would
-          keys = builds.keys()
-          keys.sort(cmp=alphanum)
+          last_key = max(builds, key=natural_sort_key)
 
           # return the path from the 'last' build name
-          return builds[keys[-1]]
+          return builds[last_key]
 
         elif len(elements) == 2:
           # we have species, and build name
@@ -103,7 +102,7 @@ class constructMapperDict(object):
     def get(self, key, default=None):
       try:
         return self[key]
-      except KeyError, e:
+      except KeyError as e:
         return default
 
     def keys(self):
@@ -132,13 +131,13 @@ class constructMapperDict(object):
 if __name__ == '__main__':
 
   if len(sys.argv) != 2:
-    print 'useage: %s <base_genome_dir>' % (sys.argv[0])
+    print('useage: %s <base_genome_dir>' % (sys.argv[0]))
     sys.exit(1)
 
   d = getAvailableGenomes(sys.argv[1])
   d2 = constructMapperDict(d)
 
   for k,v in d2.items():
-    print '%s: %s' % (k,v)
+    print('%s: %s' % (k,v))
 
 
index 6dfcf68fc235775a8280dd1bc0719e4fd513c7e4..d49103fc6c6dec94014a783ba6767ac3540fe03c 100644 (file)
@@ -17,7 +17,7 @@ class GenomeMap(collections.MutableMapping):
         return len(self._contigs)
 
     def __iter__(self):
-        return self._contigs.iterkeys()
+        return iter(self._contigs.keys())
 
     def __getitem__(self, name):
         return self._contigs[name]
index 2eaff677e6d90c75848a24a43f4b28fad8d2beff..e69a330248ab16b445140c7c920ff1e5f9b7821e 100644 (file)
@@ -1,5 +1,7 @@
 """Provide access to information stored in the GERALD directory.
 """
+from __future__ import print_function, unicode_literals
+
 import collections
 from datetime import datetime, date
 import logging
@@ -59,10 +61,10 @@ class Alignment(object):
         """
         Debugging function, report current object
         """
-        print 'Software:'. self.__class__.__name__
-        print 'Alignment version:', self.version
-        print 'Run date:', self.date
-        print 'config.xml:', self.tree
+        print('Software:'. self.__class__.__name__)
+        print('Alignment version:', self.version)
+        print('Run date:', self.date)
+        print('config.xml:', self.tree)
         self.summary.dump()
 
     def get_elements(self, root_tag):
@@ -70,7 +72,7 @@ class Alignment(object):
             return None
 
         gerald = ElementTree.Element(root_tag,
-                                     {'version': unicode(Gerald.XML_VERSION)})
+                                     {'version': str(Gerald.XML_VERSION)})
         gerald.append(self.tree)
         gerald.append(self.summary.get_elements())
         if self.eland_results:
@@ -187,10 +189,10 @@ class CASAVA(Alignment):
             return None
         time_element = self.tree.xpath('TIME_STAMP')
         if len(time_element) == 1:
-           timetuple = time.strptime(
-               time_element[0].text.strip(),
-               "%a %b %d %H:%M:%S %Y")
-           return datetime(*timetuple[:6])
+            timetuple = time.strptime(
+                time_element[0].text.strip(),
+                "%a %b %d %H:%M:%S %Y")
+            return datetime(*timetuple[:6])
         return super(CASAVA, self)._get_date()
     date = property(_get_date)
 
@@ -283,7 +285,7 @@ class LaneParametersGA(LaneParameters):
         lanes = [x.tag.split('_')[1] for x in container.getchildren()]
         try:
             index = lanes.index(self._lane_id)
-        except ValueError, e:
+        except ValueError as e:
             return None
         element = container[index]
         return element.text
@@ -397,7 +399,7 @@ class LaneSpecificRunParameters(collections.MutableMapping):
     def __iter__(self):
         if self._lanes is None:
             self._initialize_lanes()
-        return self._lanes.iterkeys()
+        return iter(self._lanes.keys())
 
     def __getitem__(self, key):
         if self._lanes is None:
index 6c3acbe19b50c8959b5deb011e36eb9cf7396212..4b0c57e4fa817c9f64cc57dfd681bbc3180a3bfe 100644 (file)
@@ -9,6 +9,8 @@ fromxml
     IPAR factory function initalized from an xml dump from
     the IPAR object.
 """
+from __future__ import print_function
+
 __docformat__ = "restructuredtext en"
 
 import datetime
@@ -87,7 +89,7 @@ class IPAR(object):
         else:
             return runfolder[0].text
     runfolder_name = property(_get_runfolder_name)
-    
+
     def _get_software(self):
         """Return software name"""
         if self.tree is None:
@@ -159,7 +161,7 @@ class IPAR(object):
         """
         suffix_node = self.tree.find('RunParameters/CompressionSuffix')
         if suffix_node is None:
-          print "find compression suffix failed"
+          print("find compression suffix failed")
           return None
         suffix = suffix_node.text
         files = []
@@ -172,8 +174,8 @@ class IPAR(object):
         return files
 
     def dump(self):
-        print "Matrix:", self.matrix
-        print "Tree:", self.tree
+        print("Matrix:", self.matrix)
+        print("Tree:", self.tree)
 
     def get_elements(self):
         attribs = {'version': str(IPAR.XML_VERSION) }
@@ -195,7 +197,7 @@ class IPAR(object):
             if element.tag == IPAR.RUN:
                 self.tree = element
             elif element.tag == IPAR.TIMESTAMP:
-               self.time = int(element.text)
+                self.time = int(element.text)
             elif element.tag == IPAR.MATRIX:
                 self.matrix = element.text
             else:
@@ -208,7 +210,7 @@ def load_ipar_param_tree(paramfile):
 
     tree = ElementTree.parse(paramfile).getroot()
     run = tree.find('Run')
-    if run.attrib.has_key('Name') and run.attrib['Name'] in SOFTWARE_NAMES:
+    if run.attrib.get('Name', None) in SOFTWARE_NAMES:
         return run
     else:
         LOGGER.info("No run found")
@@ -228,13 +230,12 @@ def ipar(pathname):
     if not (groups[0] == 'IPAR' or groups[0] == 'Intensities'):
       raise ValueError('ipar can only process IPAR directories')
 
-    bustard_pattern = os.path.join(pathname, 'Bustard*')
     # contents of the matrix file?
     matrix_pathname = os.path.join(pathname, 'Matrix', 's_matrix.txt')
     if os.path.exists(matrix_pathname):
         # this is IPAR_1.01
         i.matrix = open(matrix_pathname, 'r').read()
-    elif glob(bustard_pattern) > 0:
+    else:
         i.matrix = None
         # its still live.
 
@@ -259,16 +260,3 @@ def fromxml(tree):
     f = IPAR()
     f.set_elements(tree)
     return f
-
-#if __name__ == "__main__":
-  #i = ipar(os.path.expanduser('~/gec/081021_HWI-EAS229_0063_30HKUAAXX/Data/IPAR_1.01'))
-  #x = i.get_elements()
-  #j = fromxml(x)
-  #ElementTree.dump(x)
-  #print j.date
-  #print j.start
-  #print j.stop
-  #print i.tiles.keys()
-  #print j.tiles.keys()
-  #print j.tiles.items()
-  #print j.file_list()
index c33d0143228568b36d216986bf0aad47f60d57b9..c2fbcaf65a5962daf42f3c4953490d6fa64c5c95 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 """Convert a collection of qseq or a tar file of qseq files to a fastq file
 """
+from __future__ import print_function, unicode_literals
 from glob import glob
 import os
 from optparse import OptionParser
@@ -19,7 +20,7 @@ def main(cmdline=None):
     opts, args = parser.parse_args(cmdline)
 
     if opts.version:
-        print version()
+        print(version())
         return 0
 
     if opts.infile is not None:
index 7951752318aebe7d2443c010e64ac24149023167..7c64050c0f3d2b5d04e80f9d6391b11e9266a51d 100644 (file)
@@ -1,23 +1,23 @@
 #!/usr/bin/env python
 
 import csv
-from ConfigParser import RawConfigParser
+from six.moves.configparser import RawConfigParser
 import logging
 from optparse import OptionParser, IndentedHelpFormatter
 import os
 import sys
 import types
-import urllib
-import urllib2
+import six
+from six.moves import urllib
 
 try:
     import json
-except ImportError, e:
+except ImportError as e:
     import simplejson as json
 
 from htsworkflow.auth import apidata
 from htsworkflow.util import api
-from htsworkflow.util import alphanum
+from htsworkflow.util.alphanum import natural_sort_key
 from htsworkflow.util.url import normalize_url
 from htsworkflow.pipelines.genome_mapper import \
      getAvailableGenomes, \
@@ -47,9 +47,9 @@ def retrieve_flowcell_info(base_host_url, flowcell):
     url = api.flowcell_url(base_host_url, flowcell)
 
     try:
-        apipayload = urllib.urlencode(apidata)
-        web = urllib2.urlopen(url, apipayload)
-    except urllib2.URLError, e:
+        apipayload = urllib.parse.urlencode(apidata)
+        web = urllib.request.urlopen(url, apipayload)
+    except urllib.request.HTTPError as e:
         errmsg = 'URLError: %d %s' % (e.code, e.msg)
         LOGGER.error(errmsg)
         LOGGER.error('opened %s' % (url,))
@@ -403,15 +403,13 @@ def format_pooled_libraries(shared, library):
     sequences = library.get('index_sequence', None)
     if sequences is None:
         return []
-    elif (type(sequences) in types.StringTypes and
-          sequences.lower().startswith('err')):
+    elif isinstance(sequences, six.string_types):
         shared['Index'] = ''
         shared['SampleProject'] = library['library_id']
         return [shared]
-    elif (type(sequences) == types.DictType):
+    elif isinstance(sequences, dict):
         pooled = []
-        multiplex_ids = sequences.keys()
-        multiplex_ids.sort(cmp=alphanum.alphanum)
+        multiplex_ids = sorted(sequences.keys(), key=natural_sort_key)
         for multiplex_id in multiplex_ids:
             sample = {}
             sample.update(shared)
index 669c5f03363dfc8c647730133af71678319d0336..a5b98a606217cc1e4c09168a2bbe8f7034f554e6 100644 (file)
@@ -22,7 +22,6 @@ from htsworkflow.pipelines import ElementTree, \
                                   VERSION_RE, USER_RE, \
                                   LANES_PER_FLOWCELL, LANE_LIST
 from htsworkflow.pipelines.samplekey import LANE_SAMPLE_KEYS
-from htsworkflow.util.alphanum import alphanum
 from htsworkflow.util.ethelp import indent, flatten
 from htsworkflow.util.queuecommands import QueueCommands
 
@@ -30,7 +29,7 @@ from htsworkflow.pipelines import srf
 
 class PipelineRun(object):
     """Capture "interesting" information about a pipeline run
-    
+
     :Variables:
       - `pathname` location of the root of this runfolder
       - `serialization_filename` read only property containing name of run xml file
@@ -46,12 +45,12 @@ class PipelineRun(object):
 
     def __init__(self, pathname=None, flowcell_id=None, xml=None):
         """Initialize a PipelineRun object
-        
+
         :Parameters:
           - `pathname` the root directory of this run folder.
           - `flowcell_id` the flowcell ID in case it can't be determined
           - `xml` Allows initializing an object from a serialized xml file.
-          
+
         :Types:
           - `pathname` str
           - `flowcell_id` str
@@ -74,7 +73,7 @@ class PipelineRun(object):
 
     def _get_flowcell_id(self):
         """Return the flowcell ID
-        
+
         Attempts to find the flowcell ID through several mechanisms.
         """
         # extract flowcell ID
@@ -96,7 +95,7 @@ class PipelineRun(object):
 
     def _get_flowcell_id_from_flowcellid(self):
         """Extract flowcell id from a Config/FlowcellId.xml file
-        
+
         :return: flowcell_id or None if not found
         """
         config_dir = os.path.join(self.pathname, 'Config')
@@ -139,9 +138,9 @@ class PipelineRun(object):
 
     def _get_run_dirname(self):
         """Return name of directory to hold result files from one analysis
-        
+
         For pre-multiplexing runs this is just the cycle range C1-123
-        For post-multiplexing runs the "suffix" that we add to 
+        For post-multiplexing runs the "suffix" that we add to
         differentiate runs will be added to the range.
         E.g. Unaligned_6mm may produce C1-200_6mm
         """
@@ -158,7 +157,7 @@ class PipelineRun(object):
 
     def get_elements(self):
         """make one master xml file from all of our sub-components.
-        
+
         :return: an ElementTree containing all available pipeline
                  run xml compoents.
         """
@@ -202,16 +201,16 @@ class PipelineRun(object):
 
     def _get_serialization_filename(self):
         """Compute the filename for the run xml file
-        
-        Attempts to find the latest date from all of the run 
+
+        Attempts to find the latest date from all of the run
         components.
-        
+
         :return: filename run_{flowcell id}_{timestamp}.xml
         :rtype: str
         """
         if self._name is None:
           components = [self.image_analysis, self.bustard, self.gerald]
-          tmax = max([ c.time for c in components if c ])
+          tmax = max([ c.time for c in components if c and c.time ])
           timestamp = time.strftime('%Y-%m-%d', time.localtime(tmax))
           self._name = 'run_' + self.flowcell_id + "_" + timestamp + '.xml'
         return self._name
@@ -219,7 +218,7 @@ class PipelineRun(object):
 
     def save(self, destdir=None):
         """Save a run xml file.
-        
+
         :param destdir: Directory name to save too, uses current directory
                         if not specified.
         :type destdir: str
@@ -234,10 +233,10 @@ class PipelineRun(object):
 
     def load(self, filename):
         """Load a run xml into this object.
-        
+
         :Parameters:
           - `filename` location of a run xml file
-          
+
         :Types:
           - `filename` str
         """
@@ -260,7 +259,7 @@ def load_pipeline_run_xml(pathname):
 
 def get_runs(runfolder, flowcell_id=None):
     """Find all runs associated with a runfolder.
-    
+
     We end up with multiple analysis runs as we sometimes
     need to try with different parameters. This attempts
     to return a list of all the various runs.
@@ -336,7 +335,7 @@ def build_gerald_runs(runs, b, image_analysis, bustard_pathname, datadir, pathna
             p.bustard = b
             p.gerald = g
             runs.append(p)
-        except IOError, e:
+        except IOError as e:
             LOGGER.error("Ignoring " + str(e))
     return len(runs) - start
 
@@ -367,7 +366,7 @@ def build_hiseq_runs(image_analysis, runs, datadir, runfolder, flowcell_id):
                 p.gerald = gerald.gerald(aligned)
             runs.append(p)
         except (IOError, RuntimeError) as e:
-           LOGGER.error("Exception %s", str(e))
+            LOGGER.error("Exception %s", str(e))
             LOGGER.error("Skipping run in %s", flowcell_id)
     return len(runs) - start
 
@@ -543,8 +542,8 @@ def summary_report(runs):
     for run in runs:
         # print a run name?
         report.append('Summary for %s' % (run.serialization_filename,))
-       # sort the report
-       if run.gerald:
+        # sort the report
+        if run.gerald:
             eland_keys = sorted(run.gerald.eland_results.keys())
         else:
             report.append("Alignment not done, no report possible")
@@ -831,6 +830,3 @@ def clean_runs(runs, dry_run=True):
             clean_process = subprocess.Popen(['make', 'clean_intermediate'],
                                              cwd=run.image_analysis.pathname,)
             clean_process.wait()
-
-
-
index 2aba7099915b95fe0f2097e4445c42dd9b805941..1d746c9844f8a82a15a586f76b8baa65dd594b9a 100644 (file)
@@ -7,7 +7,8 @@ import os
 import types
 import re
 import sys
-from urlparse import urljoin, urlparse
+import six
+from six.moves.urllib.parse import urljoin, urlparse
 
 import RDF
 from htsworkflow.util.rdfhelp import libraryOntology as libNS
@@ -83,8 +84,8 @@ class SequenceFile(object):
     def key(self):
         return (self.flowcell, self.lane, self.read, self.project, self.split)
 
-    def __unicode__(self):
-        return unicode(self.path)
+    def __str__(self):
+        return str(self.path)
 
     def __eq__(self, other):
         """
@@ -162,7 +163,7 @@ class SequenceFile(object):
         def add(model, s, p, o):
             model.add_statement(RDF.Statement(s,p,o))
         # a bit unreliable... assumes filesystem is encoded in utf-8
-        path = os.path.abspath(self.path.encode('utf-8'))
+        path = os.path.abspath(self.path)
         fileNode = RDF.Node(RDF.Uri('file://' + path))
         add(model, fileNode, rdfNS['type'], libNS['IlluminaResult'])
         add_lit(model, fileNode, libNS['flowcell_id'], self.flowcell)
@@ -376,7 +377,7 @@ def scan_for_sequences(dirs):
     Scan through a list of directories for sequence like files
     """
     sequences = []
-    if type(dirs) in types.StringTypes:
+    if isinstance(dirs, six.string_types):
         raise ValueError("You probably want a list or set, not a string")
 
     for d in dirs:
index 03b96b8f35b481fddfb7f41100ed0366c2ef473f..b029339c6aefb3f65839f8faca8da84f0a46a39d 100644 (file)
@@ -112,7 +112,7 @@ def create_qseq_patterns(bustard_dir):
       qseq_patterns = []
       # grab a lane from the dictionary
       # I don't think it matters which one.
-      k = lanes.keys()[0]
+      k = next(iter(lanes.keys()))
       # build the list of patterns
       for read in lanes[k]:
         read = int(read)
@@ -238,7 +238,6 @@ def main(cmdline=None):
         seq_cmds = make_srf_commands(opts.name, source, opts.lanes, opts.site_name, opts.destination, 0)
     else:
         raise ValueError('Unknown --format=%s' % (opts.format))
-    print seq_cmds
     srf.run_commands(args.source, seq_cmds, num_jobs)
 
 def make_parser():
index 0d895d9e4b18c8fbb968da470639df8808424339..e0c80addaaf0746513b773c579d3ca4e8cf4c962 100644 (file)
@@ -1,4 +1,6 @@
 #!/usr/bin/env python
+from __future__ import print_function, unicode_literals
+
 import logging
 import mmap
 from optparse import OptionParser
@@ -27,7 +29,7 @@ def main(cmdline=None):
         logging.basicConfig(level=logging.WARN)
 
     if opts.version:
-        print version()
+        print(version())
         return 0
 
     if len(args) != 1:
@@ -151,7 +153,7 @@ def convert_single_to_two_fastq(instream, target1, target2, mid=None, header='')
         # sequence
         elif state == FASTQ_SEQUENCE:
             if mid is None:
-                mid = len(line)/2
+                mid = len(line) // 2
             write_split_sequence(target1, target2, line, mid)
             state = FASTQ_SEQUENCE_HEADER
         # quality header
@@ -191,19 +193,19 @@ def is_srf(filename):
     """
     Check filename to see if it is likely to be a SRF file
     """
-    f = open(filename, 'r')
+    f = open(filename, 'rb')
     header = f.read(4)
     f.close()
-    return header == "SSRF"
+    return header == b"SSRF"
 
 def is_cnf1(filename):
     """
     Brute force detection if a SRF file is using CNF1/CNF4 records
     """
     max_header = 1024 ** 2
-    PROGRAM_ID = 'PROGRAM_ID\000'
-    cnf4_apps = set(("solexa2srf v1.4",
-                    "illumina2srf v1.11.5.Illumina.1.3"))
+    PROGRAM_ID = b'PROGRAM_ID\000'
+    cnf4_apps = set((b"solexa2srf v1.4",
+                     b"illumina2srf v1.11.5.Illumina.1.3"))
 
     if not is_srf(filename):
         raise ValueError("%s must be a srf file" % (filename,))
@@ -213,7 +215,7 @@ def is_cnf1(filename):
     # alas the max search length requires python 2.6+
     program_id_location = f.find(PROGRAM_ID, 0) #, max_header)
     program_header_start = program_id_location+len(PROGRAM_ID)
-    next_null = f.find('\000', program_header_start) #, max_header)
+    next_null = f.find(b'\000', program_header_start) #, max_header)
     program_id_header = f[program_header_start:next_null]
     f.close()
     os.close(fd)
@@ -241,7 +243,7 @@ def foo():
     target2_name = base + '_r2.fastq'
 
     for target_name in [target1_name, target2_name]:
-        print 'target name', target_name
+        print('target name', target_name)
         if os.path.exists(target_name):
             raise RuntimeError("%s exists" % (target_name,))
 
index 8f47670d99521f37fc8afe75ab8edf292b4c5396..8c3ec7747b551e011fae474ef257f9a276a7ba69 100644 (file)
@@ -1,10 +1,11 @@
 """
 Analyze the Summary.htm file produced by GERALD
 """
+from __future__ import print_function, unicode_literals
+
 import os
 import logging
 import re
-import types
 from pprint import pprint
 
 from lxml import html
@@ -40,7 +41,7 @@ class Summary(object):
 
     def get_elements(self):
         summary = etree.Element(Summary.SUMMARY,
-                                      {'version': unicode(Summary.XML_VERSION)})
+                                      {'version': str(Summary.XML_VERSION)})
         for end in self.lane_results:
             for lane in end.values():
                 summary.append(lane.get_elements())
@@ -67,7 +68,7 @@ class Summary(object):
         Debugging function, report current object
         """
         tree = self.get_elements()
-        print etree.tostring(tree)
+        print(etree.tostring(tree))
 
 class SummaryGA(Summary):
     def __init__(self, filename=None, xml=None):
@@ -130,7 +131,7 @@ class SummaryGA(Summary):
                             ('Lane Results Summary : Read 1', 0),
                             ('Lane Results Summary : Read 2', 1),]
             for name, end in table_names:
-                if tables.has_key(name):
+                if name in tables:
                     self._extract_lane_results_for_end(tables, name, end)
 
         if len(self.lane_results[0])  == 0:
@@ -280,13 +281,12 @@ class LaneResultSummary(object):
     def get_elements(self):
         lane_result = etree.Element(
                         LaneResultSummary.LANE_RESULT_SUMMARY,
-                        {'lane': unicode(self.lane), 'end': unicode(self.end)})
+                        {'lane': str(self.lane), 'end': str(self.end)})
         for tag, variable_name in LaneResultSummary.TAGS.items():
             value = getattr(self, variable_name)
             if value is None:
                 continue
-            # it looks like a sequence
-            elif type(value) in (types.TupleType, types.ListType):
+            elif isinstance(value, (tuple, list)):
                 element = make_mean_range_element(
                   lane_result,
                   tag,
@@ -294,7 +294,7 @@ class LaneResultSummary(object):
                 )
             else:
                 element = etree.SubElement(lane_result, tag)
-                element.text = unicode(value)
+                element.text = str(value)
         return lane_result
 
     def set_elements(self, tree):
@@ -311,7 +311,7 @@ class LaneResultSummary(object):
                 variable_name = tags[element.tag]
                 setattr(self, variable_name,
                         parse_summary_element(element))
-            except KeyError, e:
+            except KeyError as e:
                 LOGGER.warn('Unrecognized tag %s' % (element.tag,))
 
 
@@ -414,7 +414,7 @@ def tonumber(v):
     """
     try:
         v = int(v)
-    except ValueError, e:
+    except ValueError as e:
         v = float(v)
     return v
 
@@ -442,8 +442,8 @@ def make_mean_range_element(parent, name, mean, deviation):
     Make an etree subelement <Name mean='mean', deviation='deviation'/>
     """
     element = etree.SubElement(parent, name,
-                                     { 'mean': unicode(mean),
-                                       'deviation': unicode(deviation)})
+                                     { 'mean': str(mean),
+                                       'deviation': str(deviation)})
     return element
 
 def parse_mean_range_element(element):
index 759a13ee37f2f463771ac2429e64e9be49873031..88e69e1925576f73bcc26dc120440342cb7fee68 100644 (file)
@@ -1,6 +1,8 @@
 """
 Create simulated solexa/illumina runfolders for testing
 """
+from __future__ import print_function, unicode_literals
+
 import gzip
 import os
 import shutil
@@ -536,7 +538,7 @@ def make_aligned_eland_export(aligned_dir, flowcell_id):
             for read in UNALIGNED_READS:
                 suffix = 'R{0}_{1}_export.txt.gz'.format(read, split)
                 pathname = paths.make_test_filename(suffix)
-                stream = gzip.open(pathname, 'w')
+                stream = gzip.open(pathname, 'wt')
                 stream.write(body)
                 stream.close()
 
@@ -574,7 +576,7 @@ def make_unaligned_fastq_sample_1_12(unaligned_dir,
         for read in reads:
             suffix = 'R{0}_{1}.fastq.gz'.format(read, split)
             pathname = paths.make_test_filename(suffix)
-            stream = gzip.open(pathname, 'w')
+            stream = gzip.open(pathname, 'wt')
             stream.write(sample_seq)
             stream.close()
 
@@ -653,12 +655,12 @@ class DemultiplexedPaths(object):
         return pathname
 
     def dump(self):
-        print ('index seq: {0}'.format(self.index_seq))
+        print('index seq: {0}'.format(self.index_seq))
 
-        print ('project dir: {0}'.format(self.project_dir))
-        print ('sample dir: {0}'.format(self.sample_dir))
-        print ('rootname: {0}'.format(self.rootname))
-        print ('path: {0}'.format(
+        print('project dir: {0}'.format(self.project_dir))
+        print('sample dir: {0}'.format(self.sample_dir))
+        print('rootname: {0}'.format(self.rootname))
+        print('path: {0}'.format(
             os.path.join(self.project_dir,
                          self.sample_dir,
                          self.rootname+'R1_001.fastq.gz')))
@@ -697,7 +699,7 @@ def print_ls_tree(root):
     """
     for dirpath, dirnames, filenames in os.walk(root):
         for filename in filenames:
-            print os.path.join(dirpath, filename)
+            print(os.path.join(dirpath, filename))
 
 
 class BaseCallInfo(object):
index ea6e2def0bb71cc2ff65d1a59f497b0a2e251c12..adbe33ae8872bfcf5cc74d26af5765612916e19e 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
index f6851883952332ab4005e06b6713bb011dc928ef..f1b74d8e3f2969b3a416a31846333249a9ea13ee 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 """More direct synthetic test cases for the eland output file processing
 """
-from StringIO import StringIO
+from six.moves import StringIO
 from unittest import TestCase
 
 from htsworkflow.pipelines.eland import ELAND, ElandLane, ElandMatches, \
@@ -20,8 +20,8 @@ class MatchCodeTests(TestCase):
                        'R0':0, 'R1':0, 'R2':0,
                       }
         self.assertEqual(mc.keys(), match_codes.keys())
-        self.assertEqual(mc.items(), match_codes.items())
-        self.assertEqual(mc.values(), match_codes.values())
+        self.assertEqual(list(mc.items()), list(match_codes.items()))
+        self.assertEqual(list(mc.values()), list(match_codes.values()))
         self.assertRaises(KeyError, mc.__getitem__, 'foo')
 
     def test_addition(self):
@@ -53,7 +53,7 @@ class TestMappedReads(TestCase):
         mr1['chr9'] = 7
         self.assertEqual(list(mr1.keys()), ['chr9'])
         self.assertEqual(mr1['chr9'], 7)
-        self.assertEqual(mr1.items(), [('chr9', 7)])
+        self.assertEqual(list(mr1.items()), [('chr9', 7)])
         del mr1['chr9']
         self.assertEqual(len(mr1), 0)
 
@@ -238,7 +238,7 @@ class ElandTests(TestCase):
         e.results[sl3] = 'Lane3'
         e.results[sl1] = 'Lane1'
 
-        e_list = e.values()
+        e_list = list(e.values())
         self.assertEqual(e_list[0], 'Lane1')
         self.assertEqual(e_list[1], 'Lane3')
         self.assertEqual(e_list[2], 'Lane5')
@@ -251,15 +251,15 @@ class TestElandMatches(TestCase):
         em.add('s_1_sequence.txt')
         self.assertEqual(len(em), 1)
         self.assertEqual(len(em[key]), 1)
-        filename = iter(em[key]).next().filename
+        filename = next(iter(em[key])).filename
         self.assertEqual(filename, 's_1_sequence.txt')
-        self.assertEqual(em.keys(), [key])
+        self.assertEqual(list(em.keys()), [key])
         em.add('s_1_eland_result.txt')
         self.assertEqual(len(em), 1)
         self.assertEqual(len(em[key]), 1)
-        filename = iter(em[key]).next().filename
+        filename = next(iter(em[key])).filename
         self.assertEqual(filename, 's_1_eland_result.txt')
-        self.assertEqual(em.keys(), [key])
+        self.assertEqual(list(em.keys()), [key])
 
     def test_parts(self):
         key11111 = SampleKey(1, 1, '11111')
index 29ab3fddd71d7f7af123fc882adec7657f8d8e54..0d96a4553858d4aaa7e3b9aec3a66eb4414c2986 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import logging
@@ -15,7 +16,7 @@ from htsworkflow.pipelines import gerald
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 logging.basicConfig(level=logging.ERROR)
 
index d71755c90c7e639f24b83ad0683614379b04a263..011a42d04cad546923920bcfde9e6e197f3462b0 100644 (file)
@@ -1,6 +1,6 @@
 from unittest import TestCase
 
-from StringIO import StringIO
+from six.moves import StringIO
 from htsworkflow.pipelines import genome_mapper
 
 class testGenomeMapper(TestCase):
index 7640910afd0ae6078a658237049ac89d75f62957..2734676106f917d11dc9efc8aee5ea98f09f920d 100644 (file)
@@ -2,7 +2,7 @@
 """More direct synthetic test cases for the eland output file processing
 """
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 import shutil
 import tempfile
 from unittest import TestCase
index 1a24c633b82314ac40ed933a7bfb2698d27d8510..4ec9d3e755a9ac99cbde2330237f69c70e76fd87 100644 (file)
@@ -1,14 +1,15 @@
 import csv
 import os
 import re
-from StringIO import StringIO
+from six.moves import StringIO
 
 try:
     import json
-except ImportError, e:
+except ImportError as e:
     import simplejson as json
 
 from django.test import TestCase
+from django.utils.encoding import smart_text
 
 from samples.samples_factory import LibraryFactory, LibraryTypeFactory, \
     MultiplexIndexFactory
@@ -33,7 +34,7 @@ class RetrieveTestCases(TestCase):
         flowcell_request = self.client.get('/experiments/config/FC12150/json',
                                            apidata)
         self.failUnlessEqual(flowcell_request.status_code, 200)
-        flowcell_info = json.loads(flowcell_request.content)['result']
+        flowcell_info = json.loads(smart_text(flowcell_request.content))['result']
 
         options = getCombinedOptions(['-f','FC12150','-g',os.getcwd()])
         genome_map = {library.library_species.scientific_name: '/tmp/build' }
@@ -71,7 +72,7 @@ class RetrieveTestCases(TestCase):
         url = '/experiments/config/%s/json' % (fcid,)
         flowcell_request = self.client.get(url, apidata)
         self.failUnlessEqual(flowcell_request.status_code, 200)
-        flowcell_info = json.loads(flowcell_request.content)['result']
+        flowcell_info = json.loads(smart_text(flowcell_request.content))['result']
 
         options = getCombinedOptions(['-f',fcid,'-g',os.getcwd(),])
 
@@ -80,22 +81,22 @@ class RetrieveTestCases(TestCase):
 
         output.seek(0)
         sheet = list(csv.DictReader(output))
-        name1 = library1.id + '_index' + library1.index_sequences().keys()[0]
-        name2 = library2.id + '_index' + library2.index_sequences().keys()[0]
+        name1 = library1.id + '_index' + next(iter(library1.index_sequences()))
+        name2 = library2.id + '_index' + next(iter(library2.index_sequences()))
         expected = [{'SampleProject': name1,
-                     'Index': library1.index_sequences().values()[0],
+                     'Index': next(iter(library1.index_sequences().values())),
                      'Lane': '1',
                      },
                     {'SampleProject': name2,
-                     'Index': library2.index_sequences().values()[0],
+                     'Index': next(iter(library2.index_sequences().values())),
                      'Lane': '1',
                      },
                     {'SampleProject': name1,
-                     'Index': library1.index_sequences().values()[0],
+                     'Index': next(iter(library1.index_sequences().values())),
                      'Lane': '2',
                      },
                     {'SampleProject': name2,
-                     'Index': library2.index_sequences().values()[0],
+                     'Index': next(iter(library2.index_sequences().values())),
                      'Lane': '2',
                      },
                     ]
index 42dedf9be9ed160fc2c6308ce88e3036e98fd1f6..b311df212ef4755b4fef19e5a866811ecd53e953 100644 (file)
@@ -1,8 +1,10 @@
+from __future__ import absolute_import
+
 import os
 from unittest import TestCase
-from StringIO import StringIO
+from six.moves import StringIO
 
-from simulate_runfolder import TESTDATA_DIR
+from .simulate_runfolder import TESTDATA_DIR
 from htsworkflow.pipelines.runfolder import load_pipeline_run_xml
 
 from htsworkflow.pipelines.eland import SampleKey
index fe52a62060fda3b50d815eaae35c0e3d4fb04d8e..dcdd36517e49f0605548ac04f546cf8fe1e0c1e5 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -12,7 +13,7 @@ from htsworkflow.pipelines import gerald
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_summary_htm(gerald_dir):
index bc2b3a60d3ff3d779d290c6a2b18a477ddbd35ce..266fcfdd3ddee9768b3f9f0f8d3e79b02a443748 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -12,7 +13,7 @@ from htsworkflow.pipelines import gerald
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 99364205c7f1412a38a1b60c0b292a8894bd753f..bb9ae5af2ee64c044c8b9187c7afdee63559f136 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import glob
@@ -15,7 +16,7 @@ from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import srf
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 FCID = 'AA01AAABXX'
 RUN_NAME = '110420_SN787_0069_%s' %( FCID,)
index 9de36535e2bd3cff21809570c794b525b719f62f..054fbc79e71add360b5c9c107bea87f9758ddd00 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -12,7 +13,7 @@ from htsworkflow.pipelines import gerald
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 366f588b8b4472d5248a23ca777195ae656625d2..5fe62219a82e36b8caedcfcaf5dc78097ede97de 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -13,7 +14,7 @@ from htsworkflow.pipelines import gerald
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 355765e6f26e852522d3895df85db61afd38ef6e..4f4976e5caa3a71b31e58d772757fdfaea266966 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -13,7 +14,7 @@ from htsworkflow.pipelines.eland import SampleKey
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 9c2a3d1ac88c7d28a30415a78cf643abc5ced9ed..371a49b699479bd35a63067e05e91c0893c27184 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -14,7 +15,7 @@ from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines.samplekey import SampleKey
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 19b0cfad384bf8edd96edf47ec2835f7f8eb2937..621f32d9a187bad6f8bdfa3851b81cfa6edda808 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -14,7 +15,7 @@ from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines.samplekey import SampleKey
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 312d92fbbdf5e5b933fb6521ee497ae3445653fb..df57cf4ce3a944be5dbbec6933faaea607ef316d 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import os
@@ -14,7 +15,7 @@ from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines.samplekey import SampleKey
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index c22535b6bcbf7da056d621e92bc4b9bce1c750d1..c1a33143c4a01df3ee70094b6a19b5cc0f96b575 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from datetime import datetime, date
 import logging
@@ -15,7 +16,7 @@ from htsworkflow.pipelines import gerald
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines import ElementTree
 
-from htsworkflow.pipelines.test.simulate_runfolder import *
+from .simulate_runfolder import *
 
 
 def make_runfolder(obj=None):
index 7861a58763f3d764df43bd3942496fcf218b2e7f..aa0b96c52392d117c3862af0e388e37b27225915 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 """More direct synthetic test cases for the eland output file processing
 """
-from StringIO import StringIO
+from six.moves import StringIO
 from unittest import TestCase
 
 from htsworkflow.pipelines.samplekey import SampleKey
index cd2b852017e97fa48292cdd0ad5b3bbfebf29e5f..6502c64901471753735b777fa292fd33652a4346 100644 (file)
@@ -71,7 +71,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'srf')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<srf 42BW9AAXX 4 %s>" % (pathname,))
         self.assertEqual(f0.flowcell, '42BW9AAXX')
         self.assertEqual(f0.lane, '4')
@@ -96,7 +96,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'qseq')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<qseq 42BW9AAXX 4 %s>" %(pathname,))
         self.assertEqual(f0.flowcell, '42BW9AAXX')
         self.assertEqual(f0.lane, '4')
@@ -119,7 +119,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'qseq')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<qseq ilmn200901 1 %s>" %(pathname,))
         self.assertEqual(f0.lane, '1')
         self.assertEqual(f0.read, 1)
@@ -142,7 +142,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'fastq')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<fastq 42BW9AAXX 4 %s>" % (pathname,))
         self.assertEqual(f0.flowcell, '42BW9AAXX')
         self.assertEqual(f0.lane, '4')
@@ -164,7 +164,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'fastq')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<fastq 42BW9AAXX 4 %s>" %(pathname,))
         self.assertEqual(f0.flowcell, '42BW9AAXX')
         self.assertEqual(f0.lane, '4')
@@ -188,7 +188,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'split_fastq')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<split_fastq 42BW9AAXX 1 %s>" %(pathname,))
         self.assertEqual(f0.flowcell, '42BW9AAXX')
         self.assertEqual(f0.lane, '1')
@@ -212,7 +212,7 @@ class SequenceFileTests(TestCase):
 
         self.assertEqual(f0.filetype, 'split_fastq')
         self.assertEqual(f0.path, pathname)
-        self.assertEqual(unicode(f0), unicode(pathname))
+        self.assertEqual(str(f0), str(pathname))
         self.assertEqual(repr(f0), "<split_fastq 42BW9AAXX 1 %s>" % (pathname,))
         self.assertEqual(f0.flowcell, '42BW9AAXX')
         self.assertEqual(f0.lane, '1')
index fbc025bd2aa79c8759bff1fcaaa93631856bdbf4..98b4fd0fe528a829ca41d3896451568ba6bab47c 100644 (file)
@@ -1,10 +1,12 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
+
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 from unittest import TestCase
 
 from htsworkflow.pipelines import summary
-from simulate_runfolder import TESTDATA_DIR
+from .simulate_runfolder import TESTDATA_DIR
 
 class SummaryTests(TestCase):
     """Test elements of the summary file parser
index f3e2e83f313646ee7dd603849c759e53055f94cf..1d6b138f64fc836458ea9721f39bf5d7d839d182 100644 (file)
@@ -22,5 +22,12 @@ LOGGING = {
             'handlers': ['console'],
             'level': 'WARNING',
         }
+    },
+}
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.postgresql_psycopg2',
+        'USER': 'diane',
+        'NAME': 'htsworkflow',
     }
 }
index 37d60edf9572ff8c51e6328b88ecc53467496ae8..01173cad21404f2e3e1a458c8497bbbd8be92ddc 100644 (file)
@@ -5,7 +5,8 @@ import os
 from pprint import pformat,pprint
 import sys
 import types
-from urlparse import urljoin, urlparse
+import six
+from six.moves.urllib.parse import urljoin, urlparse
 
 from htsworkflow.pipelines.sequences import scan_for_sequences, \
      update_model_sequence_library
@@ -22,6 +23,7 @@ from htsworkflow.util.conversion import parse_flowcell_id
 
 from django.conf import settings
 from django.template import Context, loader
+from django.utils.encoding import smart_str
 
 import RDF
 
@@ -170,8 +172,7 @@ class CondorFastqExtract(object):
 
     def import_libraries(self, result_map):
         for lib_id in result_map.keys():
-            lib_id_encoded = lib_id.encode('utf-8')
-            liburl = urljoin(self.host, 'library/%s/' % (lib_id_encoded,))
+            liburl = urljoin(self.host, 'library/%s/' % (lib_id,))
             library = RDF.Node(RDF.Uri(liburl))
             self.import_library(library)
 
@@ -257,7 +258,7 @@ WHERE {
         """Add link between target pathname and the 'lane' that produced it
         (note lane objects are now post demultiplexing.)
         """
-        target_uri = 'file://' + target.encode('utf-8')
+        target_uri = 'file://' + smart_str(target)
         target_node = RDF.Node(RDF.Uri(target_uri))
         source_stmt = RDF.Statement(target_node, dcNS['source'], seq.filenode)
         self.model.add_statement(source_stmt)
@@ -334,7 +335,7 @@ class SequenceResult(object):
         self.cycle = fromTypedNode(result['cycle'])
         self.lane_number = fromTypedNode(result['lane_number'])
         self.read = fromTypedNode(result['read'])
-        if type(self.read) in types.StringTypes:
+        if isinstance(self.read, six.string_types):
             self.read = 1
         self.library = result['library']
         self.library_id = fromTypedNode(result['library_id'])
index f04ac8fe5328e738a012738a5d256b9307e11504..7f5ed294ef8555efcbcbf26cda24d36c4ee983ca 100644 (file)
@@ -1,13 +1,14 @@
 """Parse UCSC DAF File
 """
+import collections
 import logging
 import os
 from pprint import pformat
 import re
 import string
-from StringIO import StringIO
+from six.moves import StringIO
 import types
-import urlparse
+from six.moves import urllib
 
 import RDF
 from htsworkflow.util.rdfhelp import \
@@ -139,9 +140,9 @@ def _consume_whitespace(line, start=0):
 
     returns length of string if it can't find anything
     """
-    for i in xrange(start, len(line)):
-        if line[i] not in string.whitespace:
-            return i
+    for i, c in enumerate(line[start:]):
+        if c not in string.whitespace:
+            return i+start
 
     return len(line)
 
@@ -151,9 +152,9 @@ def _extract_name_index(line, start=0):
 
     returns length of string if nothing matches
     """
-    for i in xrange(start, len(line)):
-        if line[i] in string.whitespace:
-            return i
+    for i, c in enumerate(line[start:]):
+        if c in string.whitespace:
+            return i+start
 
     return len(line)
 
@@ -232,7 +233,7 @@ def submission_uri_to_string(submission_uri):
 
 def get_view_namespace(submission_uri):
     submission_uri = submission_uri_to_string(submission_uri)
-    view_uri = urlparse.urljoin(submission_uri, 'view/')
+    view_uri = urllib.parse.urljoin(submission_uri, 'view/')
     viewNS = RDF.NS(view_uri)
     return viewNS
 
@@ -265,12 +266,12 @@ class UCSCSubmission(object):
         else:
             self.model = get_model()
 
-        if hasattr(daf_file, 'next'):
+        if isinstance(daf_file, collections.Iterable):
             # its some kind of stream
             self.daf = daf_file.read()
         else:
             # file
-            stream = open(daf_file, 'r')
+            stream = open(daf_file, 'rt')
             self.daf = stream.read()
             stream.close()
 
@@ -300,7 +301,7 @@ class UCSCSubmission(object):
             LOGGER.info("Importing %s from %s" % (lib_id, result_dir))
             try:
                 self.import_submission_dir(result_dir, lib_id)
-            except MetadataLookupException, e:
+            except MetadataLookupException as e:
                 LOGGER.error("Skipping %s: %s" % (lib_id, str(e)))
 
     def import_submission_dir(self, submission_dir, library_id):
@@ -531,7 +532,7 @@ class UCSCSubmission(object):
             LOGGER.debug("Found: %s" % (literal_re,))
             try:
                 filename_re = re.compile(literal_re)
-            except re.error, e:
+            except re.error as e:
                 LOGGER.error("Unable to compile: %s" % (literal_re,))
             patterns[literal_re] = view_name
         return patterns
index 951c28b2463be9d7bd68e6c2b02b58e2d1c3eac1..5a7866f7c35cde54f73f33b4f5ea0e85ffcab12f 100644 (file)
@@ -11,8 +11,8 @@ import json
 import jsonschema
 import os
 import requests
-import types
-from urlparse import urljoin, urlparse, urlunparse
+import six
+from six.moves.urllib.parse import urljoin, urlparse, urlunparse
 
 LOGGER = logging.getLogger(__name__)
 
@@ -132,7 +132,7 @@ class ENCODED:
         and I needed a way to properly compute a the correct base URL.
         '''
         # pretend strings aren't iterable
-        if type(obj) in types.StringTypes:
+        if isinstance(obj, six.string_types):
             return
 
         # recurse on container types
@@ -223,7 +223,7 @@ class ENCODED:
         obj_type = obj.get('@type')
         if not obj_type:
             raise ValueError('None type')
-        if type(obj_type) in types.StringTypes:
+        if isinstance(obj_type, six.string_types):
             raise ValueError('@type should be a list, not a string')
         if not isinstance(obj_type, collections.Sequence):
             raise ValueError('@type is not a sequence')
@@ -303,11 +303,14 @@ class ENCODED:
         url = urlunparse(url.values())
         return url
 
-    def search_jsonld(self, term, **kwargs):
+    def search_jsonld(self, **kwargs):
         '''Send search request to ENCODED
+
+        to do a general search do
+            searchTerm=term
         '''
         url = self.prepare_url('/search/')
-        result = self.get_json(url, searchTerm=term, **kwargs)
+        result = self.get_json(url, **kwargs)
         self.convert_search_to_jsonld(result)
         return result
 
index ee28e91440f4d0056257b73c0140d2dd5ccfb290..b13138ac047109332a9a4dd9de0fbe4f0fbf9ad9 100644 (file)
@@ -45,7 +45,7 @@ class Submission(object):
             LOGGER.info("Importing %s from %s" % (lib_id, result_dir))
             try:
                 self.import_analysis_dir(result_dir, lib_id)
-            except MetadataLookupException, e:
+            except MetadataLookupException as e:
                 LOGGER.error("Skipping %s: %s" % (lib_id, str(e)))
 
     def import_analysis_dir(self, analysis_dir, library_id):
@@ -260,7 +260,7 @@ class Submission(object):
             LOGGER.debug("Importing %s" % (lane.uri,))
             try:
                 parser.parse_into_model(self.model, lane.uri)
-            except RDF.RedlandError, e:
+            except RDF.RedlandError as e:
                 LOGGER.error("Error accessing %s" % (lane.uri,))
                 raise e
 
@@ -315,7 +315,7 @@ class Submission(object):
             LOGGER.debug("Found: %s" % (literal_re,))
             try:
                 filename_re = re.compile(literal_re)
-            except re.error, e:
+            except re.error as e:
                 LOGGER.error("Unable to compile: %s" % (literal_re,))
             patterns[literal_re] = view_name
         return patterns
index 2d232715e5289d93c17b68da92c7dfdac45f6b04..400b4db98d3ba13ec5b4fcff3db66267047be00b 100644 (file)
@@ -2,6 +2,7 @@
 
 import copy
 import os
+import re
 from pprint import pprint
 import shutil
 import tempfile
@@ -598,30 +599,30 @@ class TestCondorFastq(TestCase):
         split_test = dict((( x['target'], x) for x in
             [{'sources': [u'11154_NoIndex_L003_R1_001.fastq.gz',
                          u'11154_NoIndex_L003_R1_002.fastq.gz'],
-             'pyscript': 'desplit_fastq.pyc',
+             'pyscript': 'desplit_fastq.pyc?$',
              'target': u'11154_C02F9ACXX_c202_l3_r1.fastq'},
             {'sources': [u'11154_NoIndex_L003_R2_001.fastq.gz',
                          u'11154_NoIndex_L003_R2_002.fastq.gz'],
-             'pyscript': 'desplit_fastq.pyc',
+             'pyscript': 'desplit_fastq.pyc?$',
              'target': u'11154_C02F9ACXX_c202_l3_r2.fastq'},
             {'sources': [u'12345_CGATGT_L003_R1_001.fastq.gz',
                          u'12345_CGATGT_L003_R1_002.fastq.gz',
                          u'12345_CGATGT_L003_R1_003.fastq.gz',
                          ],
-             'pyscript': 'desplit_fastq.pyc',
+             'pyscript': 'desplit_fastq.pyc?$',
              'target': u'12345_C02F9ACXX_c202_l3_r1.fastq'},
             {'sources': [u'12345_CGATGT_L003_R2_001.fastq.gz',
                          u'12345_CGATGT_L003_R2_002.fastq.gz',
                          u'12345_CGATGT_L003_R2_003.fastq.gz',
                          ],
-             'pyscript': 'desplit_fastq.pyc',
+             'pyscript': 'desplit_fastq.pyc?$',
              'target': u'12345_C02F9ACXX_c202_l3_r2.fastq'}
              ]
          ))
         for arg in split:
             _, target = os.path.split(arg['target'])
             pyscript = split_test[target]['pyscript']
-            self.assertTrue(arg['pyscript'].endswith(pyscript))
+            self.assertTrue(re.search(pyscript, arg['pyscript']))
             filename = split_test[target]['target']
             self.assertTrue(arg['target'].endswith(filename))
             for s_index in range(len(arg['sources'])):
index 5bc9014267cfbbb2c1536e8c21ac83d3d7f57d23..bfaa0b0eb1429b62334e0322640a0adf09a43eae 100644 (file)
@@ -1,7 +1,7 @@
 from contextlib import contextmanager
 import logging
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 import shutil
 import tempfile
 from unittest import TestCase, TestSuite, defaultTestLoader
@@ -160,11 +160,6 @@ def load_daf_mapper(name, extra_statements=None, ns=None, test_daf=test_daf):
     mapper = daf.UCSCSubmission(name, daf_file = test_daf_stream, model=model)
     return mapper
 
-def dump_model(model):
-    writer = get_serializer()
-    turtle =  writer.serialize_model_to_string(model)
-    print turtle
-
 
 class TestUCSCSubmission(TestCase):
     def setUp(self):
@@ -204,7 +199,6 @@ thisView:FastqRd1 dafTerm:filename_re ".*_r1\\\\.fastq" .
 
         view = daf_mapper.find_view('filename_r1.fastq')
 
-        # dump_model(daf_mapper.model)
         view_root = 'http://jumpgate.caltech.edu/wiki/SubmissionsLog/{0}/view/'
         view_root = view_root.format(name)
         self.failUnlessEqual(str(view.uri),
@@ -258,8 +252,6 @@ thisView:FastqRd1 dafTerm:filename_re ".*\\\\.fastq" ;
                                                       libNode,
                                                       filename)
 
-        #dump_model(daf_mapper.model)
-
         sub_root = "http://jumpgate.caltech.edu/wiki/SubmissionsLog/testfind/"
         submission_name = sub_root + analysis_name
         source = daf_mapper.model.get_source(rdfNS['type'], submissionOntology['submission'])
index 08bb413ce49208dafde2e226e23e44f12554ba6f..a7902fed1899306d3c686816783f11185b7b18a7 100644 (file)
@@ -1,4 +1,5 @@
 #!/usr/bin/env python
+from __future__ import absolute_import
 
 from pprint import pprint
 import shutil
@@ -6,7 +7,7 @@ import shutil
 from unittest import TestCase, defaultTestLoader
 
 from htsworkflow.submission.results import ResultMap
-from submission_test_common import *
+from .submission_test_common import *
 
 class TestResultMap(TestCase):
     def setUp(self):
@@ -23,7 +24,7 @@ class TestResultMap(TestCase):
         results['2000'] = 'dir2000'
         results['1500'] = 'dir1500'
 
-        self.failUnlessEqual(results.keys(), ['1000', '2000', '1500'])
+        self.failUnlessEqual(list(results.keys()), ['1000', '2000', '1500'])
         self.failUnlessEqual(list(results.values()),
                              ['dir1000', 'dir2000', 'dir1500'])
         self.failUnlessEqual(list(results.items()),
index 0c4e0870399eb30dbc1702d5fa1912de2a3ab837..b08b330ce0bd853a71228f826f33497c43139f69 100644 (file)
@@ -1,6 +1,6 @@
 
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 import shutil
 import tempfile
 from unittest import TestCase, TestSuite, defaultTestLoader
@@ -19,7 +19,7 @@ from htsworkflow.util.rdfhelp import \
      get_serializer
 from htsworkflow.submission.submission import list_submissions, Submission
 from htsworkflow.submission.results import ResultMap
-from submission_test_common import *
+from .submission_test_common import *
 
 import RDF
 #import logging
index b4cb2d8bef2a24be839c2d631392c2311e6cac98..ebc461074152be6ea144aaa7e23bac811c7572ec 100644 (file)
@@ -1,5 +1,5 @@
 from unittest import TestCase, TestSuite, defaultTestLoader
-from StringIO import StringIO
+from six.moves import StringIO
 
 from htsworkflow.submission import ucsc
 
index f7734adbd972b26db9150b155a7cdeb39818e0c1..f668a2c44a67b9db10a84c6c275cdd8655f1ab46 100644 (file)
@@ -1,8 +1,7 @@
 """Utilities for extracting information from the ENCODE DCC
 """
 import logging
-import urlparse
-import urllib2
+from six.moves import urllib
 
 LOGGER = logging.getLogger(__name__)
 
@@ -21,7 +20,7 @@ def ddf_download_url(submission_id):
     'http://encodesubmit.ucsc.edu/pipeline/download_ddf/1234'
     """
     fragment = 'download_ddf/%s' % (submission_id,)
-    return urlparse.urljoin(UCSCEncodePipeline, fragment)
+    return urllib.parse.urljoin(UCSCEncodePipeline, fragment)
 
 
 def daf_download_url(submission_id):
@@ -31,7 +30,7 @@ def daf_download_url(submission_id):
     'http://encodesubmit.ucsc.edu/pipeline/download_daf/1234'
     """
     fragment = 'download_daf/%s' % (submission_id,)
-    return urlparse.urljoin(UCSCEncodePipeline, fragment)
+    return urllib.parse.urljoin(UCSCEncodePipeline, fragment)
 
 
 def submission_view_url(submission_id):
@@ -41,7 +40,7 @@ def submission_view_url(submission_id):
     'http://encodesubmit.ucsc.edu/pipeline/show/1234'
     """
     fragment = 'show/%s' % (submission_id,)
-    return urlparse.urljoin(UCSCEncodePipeline, fragment)
+    return urllib.parse.urljoin(UCSCEncodePipeline, fragment)
 
 
 def get_encodedcc_file_index(genome, composite):
@@ -58,10 +57,10 @@ def get_encodedcc_file_index(genome, composite):
         request_url = base_url + 'files.txt'
 
         try:
-            request = urllib2.urlopen(request_url)
+            request = urllib.request.urlopen(request_url)
             file_index = parse_ucsc_file_index(request, base_url)
             return file_index
-        except urllib2.HTTPError, e:
+        except urllib.request.HTTPError as e:
             err = e
             pass
 
index c9d66495e76fe672a5c41019ce378358c4ee736b..3729661cc0f5c5199a3ee4779c627ec0d50e9f40 100644 (file)
@@ -1,60 +1,13 @@
-#
-# The Alphanum Algorithm is an improved sorting algorithm for strings
-# containing numbers.  Instead of sorting numbers in ASCII order like
-# a standard sort, this algorithm sorts numbers in numeric order.
-#
-# The Alphanum Algorithm is discussed at http://www.DaveKoelle.com
-#
-#* Python implementation provided by Chris Hulan (chris.hulan@gmail.com)
-#* Distributed under same license as original
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or any later version.
-#
-# This library 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
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-#
+# from http://stackoverflow.com/questions/4836710/does-python-have-a-built-in-function-for-string-natural-sort
+# modified by Diane Trout
 
 import re
-import types
 
-#
-# TODO: Make decimal points be considered in the same class as digits
-#
-
-def chunkify(str):
-    """
-    return a list of numbers and non-numeric substrings of +str+
-    the numeric substrings are converted to integer, non-numeric are left as is
-    """
-    if type(str) in types.StringTypes:
-        chunks = re.findall("(\d+|\D+)",str)
-        #convert numeric strings to numbers
-        chunks = [re.match('\d',x) and int(x) or x for x in chunks]
-        return chunks
-    elif type(str) in [types.IntType, types.LongType, types.FloatType]:
-        return [str]
+def natural_sort_key(s, _nsre=re.compile('([0-9]+)')):
+    if isinstance(s, type("")) or isinstance(s, type(u"")):
+        return [int(text) if text.isdigit() else text.lower()
+                for text in re.split(_nsre, s)]
+    elif isinstance(s, int):
+        return [s]
     else:
-        raise ValueError("Unsupported type %s for input %s" % (type(str), str))
-
-def alphanum(a,b):
-    """
-    breaks +a+ and +b+ into pieces and returns left-to-right comparison of the pieces
-
-    +a+ and +b+ are expected to be strings (for example file names) with numbers and non-numeric characters
-    Split the values into list of numbers and non numeric sub-strings and so comparison of numbers gives
-    Numeric sorting, comparison of non-numeric gives Lexicographic order
-    """
-    # split strings into chunks
-    aChunks = chunkify(a)
-    bChunks = chunkify(b)
-
-    return cmp(aChunks,bChunks) #built in comparison works once data is prepared
+        raise ValueError("Unsupported type %s for input %s" % (type(s), s))
index 76ee84dc318005fea7281d6b838244fb869b811f..e631fa9c5051aeabe2fd39e67bcb7822dd9113b2 100644 (file)
@@ -1,7 +1,10 @@
 """Common functions for accessing the HTS Workflow REST API
 """
+from __future__ import unicode_literals
+
 import base64
-from ConfigParser import SafeConfigParser
+from six.moves import configparser
+from six import int2byte
 import random
 import logging
 
@@ -13,9 +16,7 @@ except ImportError:
 
 import os
 from optparse import OptionGroup
-import urllib
-import urllib2
-import urlparse
+from six.moves import urllib
 
 LOGGER = logging.getLogger(__name__)
 
@@ -23,7 +24,7 @@ def add_auth_options(parser):
     """Add options OptParser configure authentication options
     """
     # Load defaults from the config files
-    config = SafeConfigParser()
+    config = configparser.SafeConfigParser()
     config.read([os.path.expanduser('~/.htsworkflow.ini'),
                  '/etc/htsworkflow.ini'
                  ])
@@ -79,7 +80,7 @@ def library_url(root_url, library_id):
 
     """
     url_fragment = '/samples/library/%s/json' % (library_id,)
-    url = urlparse.urljoin(root_url, url_fragment)
+    url = urllib.parse.urljoin(root_url, url_fragment)
 
     return url
 
@@ -99,7 +100,7 @@ def flowcell_url(root_url, flowcell_id):
     http://localhost/experiments/config/1234AAXX/json
     """
     url_fragment = '/experiments/config/%s/json' % (flowcell_id,)
-    url = urlparse.urljoin(root_url, url_fragment)
+    url = urllib.parse.urljoin(root_url, url_fragment)
 
     return url
 
@@ -120,7 +121,7 @@ def lanes_for_user_url(root_url, username):
 
     """
     url_fragment = '/lanes_for/%s/json' % (username,)
-    url = urlparse.urljoin(root_url, url_fragment)
+    url = urllib.parse.urljoin(root_url, url_fragment)
 
     return url
 
@@ -129,9 +130,9 @@ def retrieve_info(url, apidata):
     Return a dictionary from the HTSworkflow API
     """
     try:
-        apipayload = urllib.urlencode(apidata)
-        web = urllib2.urlopen(url, apipayload)
-    except urllib2.URLError, e:
+        apipayload = urllib.parse.urlencode(apidata)
+        web = urllib.request.urlopen(url, apipayload)
+    except urllib.request.URLError as e:
         if hasattr(e, 'code') and e.code == 404:
             LOGGER.info("%s was not found" % (url,))
             return None
@@ -168,15 +169,15 @@ def make_django_secret_key(size=216):
     """return key suitable for use as secret key"""
     try:
         source = random.SystemRandom()
-    except AttributeError, e:
+    except AttributeError as e:
         source = random.random()
     bits = source.getrandbits(size)
     chars = []
     while bits > 0:
         byte = bits & 0xff
-        chars.append(chr(byte))
+        chars.append(int2byte(byte))
         bits >>= 8
-    return base64.encodestring("".join(chars)).strip()
+    return base64.encodestring(b"".join(chars)).strip()
 
 if __name__ == "__main__":
     from optparse import OptionParser
index 162580f2765d4cd72a27f16bd7911b4dbf3082ac..b14e95d006a79b50dda19897864cc7513b036d79 100644 (file)
@@ -2,20 +2,20 @@
 """
 import logging
 import os
-import ConfigParser
+from six.moves import configparser
 
 from htsworkflow.util.api import make_django_secret_key
 
 LOGGER = logging.getLogger(__name__)
 
-class HTSWConfig(ConfigParser.SafeConfigParser):
+class HTSWConfig(configparser.SafeConfigParser):
     '''Customization of SafeConfigParser that can open and save itself.
     '''
     def __init__(self, path=[os.path.expanduser("~/.htsworkflow.ini"),
                              '/etc/htsworkflow.ini',]):
         # ConfigParser isn't a new-style class? lame
-        # super(ConfigParser.SafeConfigParser, self).__init__()
-        ConfigParser.SafeConfigParser.__init__(self)
+        # super(configparser.SafeConfigParser, self).__init__()
+        configparser.SafeConfigParser.__init__(self)
         read_path = self.read(path)
         if len(read_path) > 0:
             self.filename = read_path[0]
@@ -39,5 +39,5 @@ class HTSWConfig(ConfigParser.SafeConfigParser):
             ini_stream = open(self.filename, 'w')
             self.write(ini_stream)
             ini_stream.close()
-        except IOError, e:
+        except IOError as e:
             LOGGER.info("Error saving setting: %s" % (str(e)))
index d3eb4f6cc5dad43f619ca8db662ed6abbcc402a2..f294e6ff2533c404887de3d66644bd024c64e8b2 100644 (file)
@@ -1,15 +1,16 @@
 """
 Miscellaneous, more refined type casting functions
 """
+from __future__ import unicode_literals
 
-def unicode_or_none(value):
+def str_or_none(value):
     """
-    Convert value to unicode if its not none.
+    Convert value to unicode string if its not none.
     """
     if value is None:
         return None
     else:
-        return unicode(value)
+        return str(value)
 
 def parse_flowcell_id(flowcell_id):
     """
index f2f3e019b20782146c0855f32a4e41e02468336e..beaeb382c0f8112fcb816b54c8f04608ea5f7884 100644 (file)
@@ -45,7 +45,7 @@ def validate_xhtml(html, base_url='http://localhost'):
     and False if it fails.
     """
     try:
-        XHTML_RDF_DTD = lxml.etree.DTD(external_id='-//W3C//DTD XHTML+RDFa 1.0//EN')
+        XHTML_RDF_DTD = lxml.etree.DTD(external_id=b'-//W3C//DTD XHTML+RDFa 1.0//EN')
     except lxml.etree.DTDParseError as e:
         LOGGER.warn("Unable to load XHTML DTD %s" % (str(e),))
         return
index 5ba33892f741213bb1932292e5821551df379295..da90bbe68e12b9b11ce6cc10fbf7cd29755e2b6c 100644 (file)
@@ -72,7 +72,7 @@ class fctracker:
             lane_library = [ (x[0][5], x[1]) for x in fc.items() 
                                              if library_id_re.match(x[0]) ]
             for lane, library_id in lane_library:
-                if not self.library[library_id].has_key('lanes'):
+                if 'lanes' not in self.library[library_id]:
                     self.library[library_id]['lanes'] = []
                 self.library[library_id]['lanes'].append((fc_id, lane))
 
index fcfb7a386edbb1453d85275167be641ab358b236..5382865bd8757676d939df1e75f19e5801c3df15 100644 (file)
@@ -4,6 +4,8 @@ import logging
 import os
 from subprocess import Popen, PIPE
 
+from django.utils.encoding import smart_text
+
 logger = logging.getLogger(__name__)
 
 def make_md5sum(filename):
@@ -12,7 +14,7 @@ def make_md5sum(filename):
     md5_cache = os.path.join(filename+".md5")
     if os.path.exists(md5_cache):
         logger.debug("Found md5sum in {0}".format(md5_cache))
-        stream = open(md5_cache,'r')
+        stream = open(md5_cache,'rt')
         lines = stream.readlines()
         md5sum = parse_md5sum_line(lines, filename)
     else:
@@ -29,17 +31,17 @@ def make_md5sum_unix(filename, md5_cache):
     if retcode != 0:
         logger.error("Trouble with md5sum for {0}".format(filename))
         return None
-    lines = stdin.split(os.linesep)
+    lines = stdin.splitlines()
     md5sum = parse_md5sum_line(lines, filename)
     if md5sum is not None:
         logger.debug("Caching sum in {0}".format(md5_cache))
-        stream = open(md5_cache, "w")
-        stream.write(stdin)
+        stream = open(md5_cache, "wt")
+        stream.write(smart_text(stdin))
         stream.close()
     return md5sum
 
 def parse_md5sum_line(lines, filename):
-    md5sum, md5sum_filename = lines[0].split()
+    md5sum, md5sum_filename = smart_text(lines[0]).split()
     md5sum_filename = os.path.basename(md5sum_filename)
     filename = os.path.basename(filename)
     if md5sum_filename != filename:
index 57c05e6025bf847e31e32875f44b34ea49c6adc6..b1ac611a0a75b763ba561cb0bce40d0f6f399023 100644 (file)
@@ -1,5 +1,8 @@
 import os
 import sys
+import logging
+
+LOGGER = logging.getLogger(__name__)
 
 try:
     import py_sg
@@ -23,8 +26,8 @@ try:
         #  the 2nd of which is the serial number
         return data.strip('\x00').split()[1]
     
-except ImportError, e:
-    print >>sys.stderr, "hdquery requires py_sg"
+except ImportError as e:
+    LOGGER.error("hdquery requires py_sg")
 
     def get_hd_serial_num(device):
         raise NotImplemented('get_hd_serial_num is not available for anything other than linux')
index 035bb24dabc9cc43d2f9ae10a3fe8562243230fd..c599975da5ae2ee4457f83d0eecef665e551f9e6 100644 (file)
@@ -4,8 +4,15 @@ Helpful utilities for turning random names/objects into streams.
 import os
 import gzip
 import bz2
-import types
-import urllib2
+import six
+from six.moves import urllib
+
+if six.PY2:
+    import types
+    FILE_CLASS = types.FileType
+else:
+    import io
+    FILE_CLASS = io.IOBase
 
 def isfilelike(file_ref, mode):
     """Does file_ref have the core file operations?
@@ -31,7 +38,7 @@ def isurllike(file_ref, mode):
     (AKA does it start with protocol:// ?)
     """
     #what if mode is 'w'?
-    parsed = urllib2.urlparse.urlparse(file_ref)
+    parsed = urllib.parse.urlparse(file_ref)
     schema, netloc, path, params, query, fragment = parsed
     
     return len(schema) > 0
@@ -41,13 +48,13 @@ def autoopen(file_ref, mode='r'):
     Attempt to intelligently turn file_ref into a readable stream
     """
     # catch being passed a file
-    if type(file_ref) is types.FileType:
+    if isinstance(file_ref, FILE_CLASS):
         return file_ref
     # does it look like a file?
     elif isfilelike(file_ref, mode):
         return file_ref
     elif isurllike(file_ref, mode):
-        return urllib2.urlopen(file_ref)
+        return urllib.request.urlopen(file_ref)
     elif os.path.splitext(file_ref)[1] == ".gz":
         return gzip.open(file_ref, mode)
     elif os.path.splitext(file_ref)[1] == '.bz2':
index 48294416abf1def5a9bc1c3d77b0a4eaa1a607b0..30d91788c47565174ef12a6133a5093c350409e8 100644 (file)
@@ -1,10 +1,12 @@
 """Helper features for working with librdf
 """
+from __future__ import print_function
+
 import collections
 from datetime import datetime
 from glob import glob
-from urlparse import urlparse, urlunparse
-from urllib2 import urlopen
+import six
+from six.moves import urllib
 import logging
 import os
 import sys
@@ -43,8 +45,8 @@ def display_query_results(results):
     """
     for row in results:
         for k, v in row.items()[::-1]:
-            print "{0}: {1}".format(k, v)
-        print
+            print("{0}: {1}".format(k, v))
+        print()
 
 def html_query_results(result_stream):
     from django.conf import settings
@@ -69,7 +71,7 @@ def html_query_results(result_stream):
             new_row[k] = Simplified(v)
         results.append(new_row)
     context = Context({'results': results,})
-    print template.render(context)
+    print(template.render(context))
 
 def blankOrUri(value=None):
     """Return a blank node for None or a resource node for strings.
@@ -77,7 +79,7 @@ def blankOrUri(value=None):
     node = None
     if value is None:
         node = RDF.Node()
-    elif type(value) in types.StringTypes:
+    elif isinstance(value, six.string_types):
         node = RDF.Node(uri_string=value)
     elif isinstance(value, RDF.Node):
         node = value
@@ -88,18 +90,18 @@ def blankOrUri(value=None):
 def toTypedNode(value, language="en"):
     """Convert a python variable to a RDF Node with its closest xsd type
     """
-    if type(value) == types.BooleanType:
+    if isinstance(value, bool):
         value_type = xsdNS['boolean'].uri
         if value:
             value = u'1'
         else:
             value = u'0'
-    elif type(value) in (types.IntType, types.LongType):
+    elif isinstance(value, int):
         value_type = xsdNS['decimal'].uri
-        value = unicode(value)
-    elif type(value) == types.FloatType:
+        value = str(value)
+    elif isinstance(value, float):
         value_type = xsdNS['float'].uri
-        value = unicode(value)
+        value = str(value)
     elif isinstance(value, datetime):
         value_type = xsdNS['dateTime'].uri
         if value.microsecond == 0:
@@ -108,12 +110,15 @@ def toTypedNode(value, language="en"):
             value = value.strftime(ISOFORMAT_MS)
     else:
         value_type = None
-        value = unicode(value)
+        if six.PY3:
+            value = str(value)
+        else:
+            value = unicode(value).encode('utf-8')
 
     if value_type is not None:
         node = RDF.Node(literal=value, datatype=value_type)
     else:
-        node = RDF.Node(literal=unicode(value).encode('utf-8'), language=language)
+        node = RDF.Node(literal=value, language=language)
     return node
 
 
@@ -147,7 +152,7 @@ def fromTypedNode(node):
     elif value_type in ('dateTime'):
         try:
             return datetime.strptime(literal, ISOFORMAT_MS)
-        except ValueError, _:
+        except ValueError:
             return datetime.strptime(literal, ISOFORMAT_SHORT)
     return literal
 
@@ -203,7 +208,7 @@ def simplify_uri(uri):
     if isinstance(uri, RDF.Uri):
         uri = str(uri)
 
-    parsed = urlparse(uri)
+    parsed = urllib.parse.urlparse(uri)
     if len(parsed.query) > 0:
         return parsed.query
     elif len(parsed.fragment) > 0:
@@ -251,7 +256,7 @@ def get_model(model_name=None, directory=None, use_contexts=True):
 
 
 def load_into_model(model, parser_name, path, ns=None):
-    if type(ns) in types.StringTypes:
+    if isinstance(ns, six.string_types):
         ns = RDF.Uri(ns)
 
     if isinstance(path, RDF.Node):
@@ -260,13 +265,13 @@ def load_into_model(model, parser_name, path, ns=None):
         else:
             raise ValueError("url to load can't be a RDF literal")
 
-    url_parts = list(urlparse(path))
+    url_parts = list(urllib.parse.urlparse(path))
     if len(url_parts[0]) == 0 or url_parts[0] == 'file':
         url_parts[0] = 'file'
         url_parts[2] = os.path.abspath(url_parts[2])
     if parser_name is None or parser_name == 'guess':
         parser_name = guess_parser_by_extension(path)
-    url = urlunparse(url_parts)
+    url = urllib.parse.urlunparse(url_parts)
     logger.info("Opening {0} with parser {1}".format(url, parser_name))
 
     rdf_parser = RDF.Parser(name=parser_name)
@@ -280,7 +285,7 @@ def load_into_model(model, parser_name, path, ns=None):
             statements = rdf_parser.parse_as_stream(url, ns)
             retries = 0
             succeeded = True
-        except RDF.RedlandError, e:
+        except RDF.RedlandError as e:
             errmsg = "RDF.RedlandError: {0} {1} tries remaining"
             logger.error(errmsg.format(str(e), retries))
 
@@ -294,7 +299,7 @@ def load_string_into_model(model, parser_name, data, ns=None):
     ns = fixup_namespace(ns)
     logger.debug("load_string_into_model parser={0}, len={1}".format(
         parser_name, len(data)))
-    rdf_parser = RDF.Parser(name=parser_name)
+    rdf_parser = RDF.Parser(name=str(parser_name))
 
     for s in rdf_parser.parse_string_as_stream(data, ns):
         conditionally_add_statement(model, s, ns)
@@ -303,7 +308,7 @@ def load_string_into_model(model, parser_name, data, ns=None):
 def fixup_namespace(ns):
     if ns is None:
         ns = RDF.Uri("http://localhost/")
-    elif type(ns) in types.StringTypes:
+    elif isinstance(ns, six.string_types):
         ns = RDF.Uri(ns)
     elif not(isinstance(ns, RDF.Uri)):
         errmsg = "Namespace should be string or uri not {0}"
@@ -333,6 +338,9 @@ def add_default_schemas(model, schema_path=None):
     schemas = resource_listdir(__name__, 'schemas')
     for s in schemas:
         schema = resource_string(__name__,  'schemas/' + s)
+        if six.PY3:
+            # files must be encoded utf-8
+            schema = schema.decode('utf-8')
         namespace = 'file://localhost/htsworkflow/schemas/'+s
         add_schema(model, schema, namespace)
 
@@ -343,7 +351,7 @@ def add_default_schemas(model, schema_path=None):
         for path in schema_path:
             for pathname in glob(os.path.join(path, '*.turtle')):
                 url = 'file://' + os.path.splitext(pathname)[0]
-                stream = open(pathname, 'r')
+                stream = open(pathname, 'rt')
                 add_schema(model, stream, url)
                 stream.close()
 
@@ -379,7 +387,10 @@ def sanitize_literal(node):
         element = lxml.html.fromstring(s)
         cleaner = lxml.html.clean.Cleaner(page_structure=False)
         element = cleaner.clean_html(element)
-        text = lxml.html.tostring(element)
+        if six.PY3:
+            text = lxml.html.tostring(element, encoding=str)
+        else:
+            text = lxml.html.tostring(element)
         p_len = 3
         slash_p_len = 4
 
index 45046a58c069776e26ca07984b1052ad43f9647a..e81319f3ab5c6fba0267fd69d9d595a2a3f9b6e6 100644 (file)
@@ -1,5 +1,6 @@
 import RDF
 from pyld import jsonld
+import six
 
 def load_into_model(model, json_data):
     '''Given a PyLD dictionary, load its statements into our Redland model
@@ -29,5 +30,9 @@ def to_node(item):
     elif nodetype == 'IRI':
         return RDF.Node(uri_string=str(value))
     else:
-        return RDF.Node(literal=unicode(value).encode('utf-8'),
+        if six.PY2:
+            literal = unicode(value).encode('utf-8')
+        else:
+            literal = value
+        return RDF.Node(literal=literal,
                         datatype=RDF.Uri(datatype))
index a47e682d977a2f9099ac876e55b3859961acd40b..b9ff4939d2e8415dc6b830b536013d6b6525f7d4 100644 (file)
@@ -2,43 +2,43 @@ import copy
 import os
 from unittest import TestCase
 
-from htsworkflow.util.alphanum import alphanum
+from htsworkflow.util.alphanum import natural_sort_key
 
 class testAlphanum(TestCase):
     def test_string(self):
       unsorted = ['z5', 'b3', 'b10', 'a001', 'a2']
       sorted = [ 'a001', 'a2', 'b3', 'b10', 'z5']
       scratch = copy.copy(unsorted)
-      scratch.sort(alphanum)
+      scratch.sort(key=natural_sort_key)
 
-      for i in xrange(len(scratch)):
-        self.failIfEqual(scratch[i], unsorted[i])
-      for i in xrange(len(scratch)):
-        self.failUnlessEqual(scratch[i], sorted[i])
+      for i, s in enumerate(scratch):
+        self.failIfEqual(s, unsorted[i])
+      for i, s in enumerate(scratch):
+        self.failUnlessEqual(s, sorted[i])
 
     def test_numbers(self):
       unsorted = [5,7,10,18,-1,3]
       sorted = [-1,3,5,7,10,18]
       scratch = copy.copy(unsorted)
-      scratch.sort(alphanum)
+      scratch.sort(key=natural_sort_key)
 
-      for i in xrange(len(scratch)):
-        self.failIfEqual(scratch[i], unsorted[i])
-      for i in xrange(len(scratch)):
-        self.failUnlessEqual(scratch[i], sorted[i])
+      for i, s in enumerate(scratch):
+        self.failIfEqual(s, unsorted[i])
+      for i, s in enumerate(scratch):
+        self.failUnlessEqual(s, sorted[i])
 
     def test_long_names(self):
         unsorted = ["1000X Radonius Maximus","10X Radonius","200X Radonius","20X Radonius","20X Radonius Prime","30X Radonius","40X Radonius","Allegia 50 Clasteron","Allegia 500 Clasteron","Allegia 51 Clasteron","Allegia 51B Clasteron","Allegia 52 Clasteron","Allegia 60 Clasteron","Alpha 100","Alpha 2","Alpha 200","Alpha 2A","Alpha 2A-8000","Alpha 2A-900","Callisto Morphamax","Callisto Morphamax 500","Callisto Morphamax 5000","Callisto Morphamax 600","Callisto Morphamax 700","Callisto Morphamax 7000","Callisto Morphamax 7000 SE","Callisto Morphamax 7000 SE2","QRS-60 Intrinsia Machine","QRS-60F Intrinsia Machine","QRS-62 Intrinsia Machine","QRS-62F Intrinsia Machine","Xiph Xlater 10000","Xiph Xlater 2000","Xiph Xlater 300","Xiph Xlater 40","Xiph Xlater 5","Xiph Xlater 50","Xiph Xlater 500","Xiph Xlater 5000","Xiph Xlater 58"]
         expected = ['10X Radonius', '20X Radonius', '20X Radonius Prime', '30X Radonius', '40X Radonius', '200X Radonius', '1000X Radonius Maximus', 'Allegia 50 Clasteron', 'Allegia 51 Clasteron', 'Allegia 51B Clasteron', 'Allegia 52 Clasteron', 'Allegia 60 Clasteron', 'Allegia 500 Clasteron', 'Alpha 2', 'Alpha 2A', 'Alpha 2A-900', 'Alpha 2A-8000', 'Alpha 100', 'Alpha 200', 'Callisto Morphamax', 'Callisto Morphamax 500', 'Callisto Morphamax 600', 'Callisto Morphamax 700', 'Callisto Morphamax 5000', 'Callisto Morphamax 7000', 'Callisto Morphamax 7000 SE', 'Callisto Morphamax 7000 SE2', 'QRS-60 Intrinsia Machine', 'QRS-60F Intrinsia Machine', 'QRS-62 Intrinsia Machine', 'QRS-62F Intrinsia Machine', 'Xiph Xlater 5', 'Xiph Xlater 40', 'Xiph Xlater 50', 'Xiph Xlater 58', 'Xiph Xlater 300', 'Xiph Xlater 500', 'Xiph Xlater 2000', 'Xiph Xlater 5000', 'Xiph Xlater 10000']
 
         s = unsorted[:]
-        s.sort(alphanum)
+        s.sort(key=natural_sort_key)
         self.failUnlessEqual(s, expected)
 
     def test_bad_input(self):
         unsorted = [object(), (1,3j)]
         s = unsorted[:]
-        self.failUnlessRaises(ValueError, s.sort, alphanum)
+        self.failUnlessRaises(ValueError, s.sort, key=natural_sort_key)
 
 
 def suite():
index 379dd9e1e525e45bc81e414a60d21b07694d9333..b3519f4d245baa67e1e27f64d441a96a42a83b81 100644 (file)
@@ -1,9 +1,11 @@
+from __future__ import print_function, unicode_literals
+
 import os
 from unittest import TestCase
 
 try:
   from xml.etree import ElementTree
-except ImportError, e:
+except ImportError as e:
   from elementtree import ElementTree
 
 from htsworkflow.util.ethelp import indent, flatten
@@ -15,11 +17,11 @@ class testETHelper(TestCase):
 
     def test_indent(self):
         flat_foo = ElementTree.tostring(self.foo_tree)
-        self.failUnlessEqual(len(flat_foo.split('\n')), 1)
+        self.failUnlessEqual(len(flat_foo.splitlines()), 1)
 
         indent(self.foo_tree)
         pretty_foo = ElementTree.tostring(self.foo_tree)
-        self.failUnlessEqual(len(pretty_foo.split('\n')), 5)
+        self.failUnlessEqual(len(pretty_foo.splitlines()), 4)
 
     def test_flatten(self):
         self.failUnless(flatten(self.foo_tree), 'asdf')
index 50d2c64a638f5f8b84bff93f0418090c3fc7094d..daf618b2136132f8287bec33b57e6b62857d5285 100644 (file)
@@ -1,5 +1,5 @@
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 from unittest import TestCase
 
 from htsworkflow.util import makebed
index 9694c37e244658b274735603c8723fc9986f3e32..c71d3d76899c04e0ea9e6afa3413d8d6366cd566 100644 (file)
@@ -1,8 +1,10 @@
+from __future__ import print_function
+
 import os
 import types
 from unittest import TestCase
-
 from datetime import datetime
+import six
 
 from htsworkflow.util.rdfhelp import \
      add_default_schemas, \
@@ -67,7 +69,7 @@ try:
             s = "Argh matey"
             node = toTypedNode(s)
             self.assertEqual(fromTypedNode(node), s)
-            self.assertEqual(type(fromTypedNode(node)), types.UnicodeType)
+            self.assertTrue(isinstance(fromTypedNode(node), six.text_type))
 
         def test_blank_or_uri_blank(self):
             node = blankOrUri()
@@ -88,8 +90,7 @@ try:
         def test_unicode_node_roundtrip(self):
             literal = u'\u5927'
             roundtrip = fromTypedNode(toTypedNode(literal))
-            self.assertEqual(roundtrip, literal)
-            self.assertEqual(type(roundtrip), types.UnicodeType)
+            self.assertTrue(isinstance(roundtrip, six.text_type))
 
         def test_datetime_no_microsecond(self):
             dateTimeType = xsdNS['dateTime'].uri
@@ -261,8 +262,8 @@ _:a owl:imports "{loc}extra.turtle" .
             self.assertTrue(model.contains_statement(s))
 
 
-except ImportError, e:
-    print "Unable to test rdfhelp"
+except ImportError as e:
+    print("Unable to test rdfhelp")
 
 def suite():
     from unittest import TestSuite, defaultTestLoader
index c906cd5592fdc689509fe8e67d6339c20091b668..dc253b8d3edbfc7f375d9198b63cbf97c1a7b12a 100644 (file)
@@ -1,5 +1,5 @@
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 from unittest import TestCase
 
 from htsworkflow.util import validate
index 959acc281db0b951d0d0dc2dec17023eddc9be47..60566a7961b0e6ef10f0be8d947cd84ac70f81ee 100644 (file)
@@ -1,9 +1,11 @@
 #!/usr/bin/env python
-
 from optparse import OptionParser
 import os
 import re
 import sys
+import logging
+
+LOGGER = logging.getLogger(__name__)
 
 def main(cmdline=None):
     parser = make_parser()
@@ -19,7 +21,7 @@ def main(cmdline=None):
                                     opts.uniform_lengths,
                                     opts.max_errors)
             if errors > 0:
-                print "%s failed validation" % (filename,)
+                LOGGER.error("%s failed validation", filename)
                 error_happened = True
 
         stream.close()
@@ -110,7 +112,7 @@ def validate_fastq(stream, format='phred33', uniform_length=False, max_errors=No
 
 def validate_re(pattern, line, line_number, errmsg):
     if pattern.match(line) is None:
-        print errmsg, "[%d]: %s" % (line_number, line)
+        LOGGER.error("%s [%d]: %s", errmsg, line_number, line)
         return 1
     else:
         return 0
@@ -123,7 +125,7 @@ def validate_length(line, line_length, line_number, errmsg):
     if line_length is None:
         line_length = len(line)
     elif len(line) != line_length:
-        print errmsg, "%d: %s" %(line_number, line)
+        LOGGER.error("%s %d: %s", errmsg, line_number, line)
         error_count = 1
     return line_length, error_count
     
index 8097edbedb8d95acddad2c9626d47050c4d92817..56a1b113513345e0fe4fcf84115d70e86c774379 100644 (file)
@@ -8,13 +8,13 @@ def version():
     version = None
     try:
         import pkg_resources
-    except ImportError, e:
+    except ImportError as e:
         LOGGER.error("Can't find version number, please install setuptools")
         raise e
 
     try:
         version = pkg_resources.get_distribution("htsworkflow")
-    except pkg_resources.DistributionNotFound, e:
+    except pkg_resources.DistributionNotFound as e:
         LOGGER.error("Package not installed")
 
     return version
index b418f997ed2f00855bd2376ec2ed221c635d6e04..5c17d3d35a3d5e6d8dc92916beb72566f6022ec6 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.contrib import admin
 
index a3cb409ca429ff6166a04affe0bc3b775401bc5b..703c0973b39729233e93aa6f52623f10f7319347 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from .models import Item
 
index 1698f279825554dc31ff62d3661c3c9660590bf5..e75ea415ddd25a63a360381705a5ccfb91fc5712 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 import datetime
 
index deefeedb64e50c37c0855d4c66fb0b24eaf214c9..7e5c2390777565d83a9c288f3259893de7fadbb0 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 import logging
 
@@ -13,7 +13,7 @@ LOGGER = logging.getLogger(__name__)
 
 try:
     import uuid
-except ImportError, e:
+except ImportError as e:
     # Some systems are using python 2.4, which doesn't have uuid
     # this is a stub
     LOGGER.warning('Real uuid is not available, initializing fake uuid module')
@@ -28,7 +28,6 @@ def _assign_uuid(sender, instance, **kwargs):
     """
     Assigns a UUID to model on save
     """
-    #print 'Entered _assign_uuid'
     if instance.uuid is None or len(instance.uuid) != 32:
         instance.uuid = uuid.uuid1().hex
 
@@ -49,8 +48,8 @@ class Vendor(models.Model):
     name = models.CharField(max_length=256)
     url = models.URLField(blank=True, null=True)
 
-    def __unicode__(self):
-        return u"%s" % (self.name)
+    def __str__(self):
+        return "%s" % (self.name)
 
 
 class Location(models.Model):
@@ -65,11 +64,11 @@ class Location(models.Model):
 
     notes = models.TextField(blank=True, null=True)
 
-    def __unicode__(self):
+    def __str__(self):
         if len(self.location_description) > 16:
-            return u"%s: %s" % (self.name, self.location_description[0:16]+u"...")
+            return "%s: %s" % (self.name, self.location_description[0:16]+"...")
         else:
-            return u"%s: %s" % (self.name, self.location_description)
+            return "%s: %s" % (self.name, self.location_description)
 
 post_init.connect(_assign_uuid, sender=Location)
 
@@ -89,16 +88,16 @@ class ItemInfo(models.Model):
 
     notes = models.TextField(blank=True, null=True)
 
-    def __unicode__(self):
+    def __str__(self):
         name = u''
         if self.model_id:
-            name += u"model:%s " % (self.model_id)
+            name += "model:%s " % (self.model_id)
         if self.part_number:
-            name += u"part:%s " % (self.part_number)
+            name += "part:%s " % (self.part_number)
         if self.lot_number:
-            name += u"lot:%s " % (self.lot_number)
+            name += "lot:%s " % (self.lot_number)
 
-        return u"%s: %s" % (name, self.purchase_date)
+        return "%s: %s" % (name, self.purchase_date)
 
     class Meta:
         verbose_name_plural = "Item Info"
@@ -109,15 +108,15 @@ class ItemType(models.Model):
     name = models.CharField(max_length=64, unique=True)
     description = models.TextField(blank=True, null=True)
 
-    def __unicode__(self):
-        return u"%s" % (self.name)
+    def __str__(self):
+        return "%s" % (self.name)
 
 
 class ItemStatus(models.Model):
     name = models.CharField(max_length=64, unique=True)
     notes = models.TextField(blank=True, null=True)
 
-    def __unicode__(self):
+    def __str__(self):
         return self.name
 
     class Meta:
@@ -150,11 +149,11 @@ class Item(models.Model):
 
     notes = models.TextField(blank=True, null=True)
 
-    def __unicode__(self):
+    def __str__(self):
         if self.barcode_id is None or len(self.barcode_id) == 0:
-            return u"invu|%s" % (self.uuid)
+            return "invu|%s" % (self.uuid)
         else:
-            return u"invb|%s" % (self.barcode_id)
+            return "invb|%s" % (self.barcode_id)
 
     def get_absolute_url(self):
         return '/inventory/%s/' % (self.uuid)
@@ -173,7 +172,7 @@ class PrinterTemplate(models.Model):
 
     template = models.TextField()
 
-    def __unicode__(self):
+    def __str__(self):
         if self.default:
             return u'%s %s' % (self.item_type.name, self.printer.name)
         else:
@@ -191,8 +190,8 @@ class LongTermStorage(models.Model):
     creation_date = models.DateTimeField(auto_now_add=True)
     modified_date = models.DateTimeField(auto_now=True)
 
-    def __unicode__(self):
-        return u"%s: %s" % (str(self.flowcell), ', '.join([str(s) for s in self.storage_devices.iterator()]))
+    def __str__(self):
+        return "%s: %s" % (str(self.flowcell), ', '.join([str(s) for s in self.storage_devices.iterator()]))
 
     class Meta:
         verbose_name_plural = "Long Term Storage"
@@ -214,8 +213,8 @@ class ReagentFlowcell(ReagentBase):
     """
     flowcell = models.ForeignKey(FlowCell)
 
-    def __unicode__(self):
-        return u"%s: %s" % (str(self.flowcell), ', '.join([str(s) for s in self.reagent.iterator()]))
+    def __str__(self):
+        return "%s: %s" % (str(self.flowcell), ', '.join([str(s) for s in self.reagent.iterator()]))
 
 
 class ReagentLibrary(ReagentBase):
@@ -224,5 +223,5 @@ class ReagentLibrary(ReagentBase):
     """
     library = models.ForeignKey(Library)
 
-    def __unicode__(self):
-        return u"%s: %s" % (str(self.library), ', '.join([str(s) for s in self.reagent.iterator()]))
+    def __str__(self):
+        return "%s: %s" % (str(self.library), ', '.join([str(s) for s in self.reagent.iterator()]))
index b30da8c757ebfb5603cf442ad0ec6c0270afc4e4..9967d4411df4de916cf51b5763396daa636a9f79 100644 (file)
@@ -10,6 +10,7 @@ from django.conf import settings
 
 from django.contrib.auth.models import User
 from django.core.urlresolvers import reverse
+from django.utils.encoding import smart_text
 
 from .models import Item, Vendor
 from .inventory_factory import ItemFactory, LongTermStorageFactory
@@ -37,7 +38,7 @@ class InventoryTestCase(TestCase):
         self.failUnlessEqual(response.status_code, 200)
 
         model = get_model()
-        load_string_into_model(model, 'rdfa', response.content, url)
+        load_string_into_model(model, 'rdfa', smart_text(response.content), url)
 
         itemNode = RDF.Node(RDF.Uri(url))
         item_type = fromTypedNode(
index ff71a6bc9534183edaf16ee052237e6077658031..98ece191231dd9b48d48ae0ea770c9aa34b7e614 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.conf.urls import patterns
 
 urlpatterns = patterns('',
index 05f300a08fdde5d4329f26f3d896ea8c2092e5d6..63f91a04634ad326329c26dc6e3b8e08469c7cb2 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.conf import settings
 from django.contrib.auth.decorators import login_required
@@ -21,7 +21,7 @@ register_search_plugin('Inventory Item', item_search)
 
 try:
     import json
-except ImportError, e:
+except ImportError as e:
     import simplejson as json
 
 INVENTORY_CONTEXT_DEFAULTS = {
@@ -90,7 +90,7 @@ def getPrinterTemplateByType(item_type):
             printer_template = PrinterTemplate.objects.get(default=True)
         except ObjectDoesNotExist:
             msg = "No template for item type (%s) and no default template found" % (item_type.name)
-            raise ValueError, msg
+            raise ValueError(msg)
 
         return printer_template
 
@@ -216,7 +216,7 @@ def item_summary_by_barcode(request, barcode_id, msg=''):
     """
     try:
         item = Item.objects.get(barcode_id=barcode_id)
-    except ObjectDoesNotExist, e:
+    except ObjectDoesNotExist as e:
         item = None
 
     return item_summary_by_uuid(request, None, msg, item)
@@ -231,7 +231,7 @@ def item_summary_by_uuid(request, uuid, msg='', item=None):
     if item is None:
         try:
             item = Item.objects.get(uuid=uuid)
-        except ObjectDoesNotExist, e:
+        except ObjectDoesNotExist as e:
             item = None
 
     context_dict = {
@@ -291,7 +291,7 @@ def item_print(request, uuid):
     """
     try:
         item = Item.objects.get(uuid=uuid)
-    except ObjectDoesNotExist, e:
+    except ObjectDoesNotExist as e:
         item = None
         msg = "Item with UUID %s does not exist" % (uuid)
 
@@ -316,7 +316,7 @@ def link_flowcell_and_device(request, flowcell, serial):
     # Retrieve Storage Device
     try:
         sd = Item.objects.get(barcode_id=serial)
-    except ObjectDoesNotExist, e:
+    except ObjectDoesNotExist as e:
         msg = "Item with barcode_id of %s not found." % (serial)
         raise ObjectDoesNotExist(msg)
 
@@ -324,7 +324,7 @@ def link_flowcell_and_device(request, flowcell, serial):
     # Retrieve FlowCell
     try:
         fc = FlowCell.objects.get(flowcell_id__startswith=flowcell)
-    except ObjectDoesNotExist, e:
+    except ObjectDoesNotExist as e:
         msg = "FlowCell with flowcell_id of %s not found." % (flowcell)
         raise ObjectDoesNotExist(msg)
 
@@ -334,7 +334,7 @@ def link_flowcell_and_device(request, flowcell, serial):
     lts = None
     if count > 1:
         msg = "There really should only be one longtermstorage object per flowcell"
-        raise ValueError, msg
+        raise ValueError(msg)
     elif count == 1:
         # lts already attached to flowcell
         lts = fc.longtermstorage_set.all()[0]
index 3ae391ec64e43a3a4be76810e3875064f39cd0aa..d2c7fcf07e024d18cc858669e693b62701c050c5 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.template import Context, Template
 from django.contrib import admin
 
index 8794492d0e5dab2b85f92ea58d656d65474f32e7..fa5920bb5a10ebe26c12966b6c453524aff09704 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.db import models
 
 class LabelPrinter(models.Model):
@@ -10,8 +12,8 @@ class LabelPrinter(models.Model):
     labels = models.CharField(max_length=200)
     notes = models.TextField(null=True, blank=True)
 
-    def __unicode__(self):
-        return u'%s: %s' % (self.name, self.labels)
+    def __str__(self):
+        return '%s: %s' % (self.name, self.labels)
 
 class LabelTemplate(models.Model):
     """
@@ -23,7 +25,7 @@ class LabelTemplate(models.Model):
     
     ZPL_code = models.TextField('template')
     
-    def __unicode__(self):
+    def __str__(self):
             return '%s %s' % (self.name, self.printer.name)
 
 class LabelContent(models.Model):
index ca3633bb6d2c73635640d8dca26ef16f3fc9999b..b09de7a301caeacc8b66aee9b01d45c4ff1b5bf0 100644 (file)
@@ -4,6 +4,7 @@ unittest). These will both pass when you run "manage.py test".
 
 Replace these with more appropriate tests for your application.
 """
+from __future__ import unicode_literals
 
 from django.test import TestCase
 
index 60f00ef0ef347811e7b0c0921b7fda097acd9fcc..6f984966c521f47889eb0e3c9143b3d3899906a0 100644 (file)
@@ -1 +1,2 @@
+from __future__ import unicode_literals
 # Create your views here.
index 34f86923597aaa7f6991bfcda61f62a3e65f8011..ccfb05d5d2e34ac16841597874c57d4f605c81f8 100644 (file)
@@ -11,3 +11,4 @@ pytz>=2011
 requests>=2.0
 wsgiref==0.1.2
 factory_boy>=2.4
+six>=1.8
index 5b9b858b1cb52297a9c70cdb5b6243f031516175..69fe059db1931231b7e34cf06e47385fe3caf8f4 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.contrib import admin
 from django.contrib.admin import widgets
index d3f4330bc49385ca4449d1eb75b0496524aab5d5..18fbe5c61fd19c7850db91bb4f0feb1ce1c3236a 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 from django.conf import settings
 from django.contrib.auth.backends import ModelBackend
@@ -17,7 +17,7 @@ class HTSUserModelBackend(ModelBackend):
             if user.check_password(password):
                 return user
         #except self.user_class.DoesNotExist:
-        except Exception, e:
+        except Exception as e:
             logger.error(str(e))
             return None
 
@@ -25,7 +25,7 @@ class HTSUserModelBackend(ModelBackend):
         try:
             return self.user_class.objects.get(pk=user_id)
         #except self.user_class.DoesNotExist:
-        except Exception, e:
+        except Exception as e:
             logger.error(str(e))
             return None
 
index 716713aa0d4042961b4dc22f585000c153c35213..842eb0adc04c8cfc51ccdc020de7ded052888895 100644 (file)
@@ -1,4 +1,4 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 import django
 from django.contrib.admin.views.main import ChangeList
index 5c5c27c951efd831efabaa3e5495e8287dbe20c7..eaa433b7f86caf6367b3d036e8805cba96f8bdf4 100644 (file)
@@ -1,11 +1,13 @@
+from __future__ import unicode_literals
+
 import types
 import logging
-import urlparse
 from django.db import models
 from django.contrib.auth.models import User, UserManager
 from django.core import urlresolvers
 from django.db.models.signals import pre_save, post_save
 from django.db import connection
+import six
 
 logger = logging.getLogger(__name__)
 
@@ -25,8 +27,8 @@ class Antibody(models.Model):
     source = models.CharField(max_length=500, blank=True, null=True, db_index=True)
     biology = models.TextField(blank=True, null=True)
     notes = models.TextField(blank=True, null=True)
-    def __unicode__(self):
-        return u'%s - %s' % (self.antigene, self.antibodies)
+    def __str__(self):
+        return '%s - %s' % (self.antigene, self.antibodies)
     class Meta:
         verbose_name_plural = "antibodies"
         ordering = ["antigene"]
@@ -39,8 +41,8 @@ class Cellline(models.Model):
         db_index=True)
 
     notes = models.TextField(blank=True)
-    def __unicode__(self):
-        return unicode(self.cellline_name)
+    def __str__(self):
+        return str(self.cellline_name)
 
     class Meta:
         ordering = ["cellline_name"]
@@ -55,8 +57,8 @@ class Condition(models.Model):
         verbose_name = 'Short Name')
     notes = models.TextField(blank=True)
 
-    def __unicode__(self):
-        return unicode(self.condition_name)
+    def __str__(self):
+        return str(self.condition_name)
 
     class Meta:
         ordering = ["condition_name"]
@@ -65,8 +67,8 @@ class Condition(models.Model):
 class ExperimentType(models.Model):
   name = models.CharField(max_length=50, unique=True)
 
-  def __unicode__(self):
-    return unicode(self.name)
+  def __str__(self):
+    return str(self.name)
 
 class Tag(models.Model):
   tag_name = models.CharField(max_length=100, db_index=True,blank=False,null=False)
@@ -80,8 +82,8 @@ class Tag(models.Model):
   context = models.CharField(max_length=50,
       choices=TAG_CONTEXT, default='Library')
 
-  def __unicode__(self):
-    return u'%s' % (self.tag_name)
+  def __str__(self):
+    return '%s' % (self.tag_name)
 
   class Meta:
     ordering = ["context","tag_name"]
@@ -94,8 +96,8 @@ class Species(models.Model):
   common_name = models.CharField(max_length=256, blank=True)
   #use_genome_build = models.CharField(max_length=100, blank=False, null=False)
 
-  def __unicode__(self):
-    return u'%s (%s)' % (self.scientific_name, self.common_name)
+  def __str__(self):
+    return '%s (%s)' % (self.scientific_name, self.common_name)
 
   class Meta:
     verbose_name_plural = "species"
@@ -112,15 +114,15 @@ class Affiliation(models.Model):
   users = models.ManyToManyField('HTSUser', null=True, blank=True)
   users.admin_order_field = "username"
 
-  def __unicode__(self):
-    str = unicode(self.name)
+  def __str__(self):
+    name = str(self.name)
     if self.contact is not None and len(self.contact) > 0:
-      str += u' ('+self.contact+u')'
-    return str
+      name += ' ('+self.contact+')'
+    return name
 
   def Users(self):
       users = self.users.all().order_by('username')
-      return ", ".join([unicode(a) for a in users ])
+      return ", ".join([str(a) for a in users ])
 
   class Meta:
     ordering = ["name","contact"]
@@ -134,8 +136,8 @@ class LibraryType(models.Model):
   can_multiplex = models.BooleanField(default=True,
                     help_text="Does this adapter provide multiplexing?")
 
-  def __unicode__(self):
-      return unicode(self.name)
+  def __str__(self):
+      return str(self.name)
 
   class Meta:
       ordering = ["-id"]
@@ -202,7 +204,7 @@ class Library(models.Model):
 
   undiluted_concentration = models.DecimalField("Concentration",
       max_digits=5, decimal_places=2, blank=True, null=True,
-      help_text=u"Undiluted concentration (ng/\u00b5l)")
+      help_text = "Undiluted concentration (ng/\u00b5l)")
       # note \u00b5 is the micro symbol in unicode
   successful_pM = models.DecimalField(max_digits=9,
                                       decimal_places=1, blank=True, null=True)
@@ -214,11 +216,11 @@ class Library(models.Model):
   bioanalyzer_summary = models.TextField(blank=True,default="")
   bioanalyzer_concentration = models.DecimalField(max_digits=5,
                                 decimal_places=2, blank=True, null=True,
-                                help_text=u"(ng/\u00b5l)")
+                                help_text="(ng/\u00b5l)")
   bioanalyzer_image_url = models.URLField(blank=True,default="")
 
-  def __unicode__(self):
-    return u'#%s: %s' % (self.id, self.library_name)
+  def __str__(self):
+    return '#%s: %s' % (self.id, self.library_name)
 
   class Meta:
       verbose_name_plural = "libraries"
@@ -272,7 +274,7 @@ class Library(models.Model):
               adapter_type = self.library_type.id,
               multiplex_id = multiplex_id)
           return multiplex.sequence
-      except MultiplexIndex.DoesNotExist, e:
+      except MultiplexIndex.DoesNotExist as e:
           return None
 
   def index_sequence_text(self, seperator=' '):
@@ -280,7 +282,7 @@ class Library(models.Model):
       sequences = self.index_sequences()
       if sequences is None:
           return ""
-      if type(sequences) in types.StringTypes:
+      if isinstance(sequences, six.string_types):
           return sequences
       multiplex_ids = sequences.keys()
       multiplex_ids.sort()
@@ -293,7 +295,7 @@ class Library(models.Model):
     tstr = ''
     ar = []
     for t in affs:
-        ar.append(t.__unicode__())
+        ar.append(t.__str__())
     return '%s' % (", ".join(ar))
 
   def is_archived(self):
@@ -318,8 +320,8 @@ class Library(models.Model):
     affs = self.tags.all().order_by('tag_name')
     ar = []
     for t in affs:
-      ar.append(t.__unicode__())
-    return u'%s' % ( ", ".join(ar))
+      ar.append(t.__str__())
+    return '%s' % ( ", ".join(ar))
 
   def DataRun(self):
     str ='<a target=_self href="/admin/experiments/datarun/?q='+self.id+'" title="Check All Data Runs for This Specific Library ..." ">Data Run</a>'
@@ -334,7 +336,7 @@ class Library(models.Model):
 
     # Check data sanity
     if res[2] != "OK":
-      return u'<div style="border:solid red 2px">'+res[2]+'</div>'
+      return '<div style="border:solid red 2px">'+res[2]+'</div>'
 
     rc = "%1.2f" % (res[1]/1000000.0)
     # Color Scheme: green is more than 10M, blue is more than 5M, orange is more than 3M and red is less. For RNAseq, all those thresholds should be doubled
@@ -353,7 +355,7 @@ class Library(models.Model):
            if res[1] > rc_thr[2]:
              bgcolor ='#ffcc33'  # Orange
       tstr = '<div style="background-color:'+bgcolor+';color:black">'
-      tstr += res[0].__unicode__()+' Lanes, '+rc+' M Reads'
+      tstr += res[0].__str__()+' Lanes, '+rc+' M Reads'
       tstr += '</div>'
     else: tstr = 'not processed yet'
     return tstr
@@ -385,9 +387,9 @@ class HTSUser(User):
     def admin_url(self):
         return '/admin/%s/%s/%d' % (self._meta.app_label, self._meta.module_name, self.id)
 
-    def __unicode__(self):
-        #return unicode(self.username) + u" (" + unicode(self.get_full_name()) + u")"
-        return unicode(self.get_full_name()) + u' (' + unicode(self.username) + ')'
+    def __str__(self):
+        #return str(self.username) + " (" + str(self.get_full_name()) + u")"
+        return str(self.get_full_name()) + ' (' + str(self.username) + ')'
 
 def HTSUserInsertID(sender, instance, **kwargs):
     """
index 2724a378a3f6b50610a13325a92812df5252bc41..6949d4d269118c965785e87e4ee21155c9da9863 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.conf import settings
 
 import glob
index 3dd35f5b13f6b9ac8b3467b9fe7b3bd9b57faad0..09b7988d90c936bf0953d2dba3a415891cd87683 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 import datetime
 
 import factory
index c339619eb0309ce9dfed96142010309891a7971f..1c53f3ccdc3dcb9f51a9388028f396db0a42057d 100644 (file)
@@ -6,13 +6,14 @@ import json
 
 from django.test import TestCase, RequestFactory
 from django.conf import settings
+from django.utils.encoding import smart_text, smart_str
 
 from .models import Affiliation, ExperimentType, Species, Library
 from .views import library_dict, library_json, library
 from .samples_factory import *
 
 from htsworkflow.auth import apidata
-from htsworkflow.util.conversion import unicode_or_none
+from htsworkflow.util.conversion import str_or_none
 from htsworkflow.util.ethelp import validate_xhtml
 
 class LibraryTestCase(TestCase):
@@ -52,7 +53,7 @@ class SampleWebTestCase(TestCase):
         lib_dict = library_dict(library.id)
         url = '/samples/library/%s/json' % (library.id,)
         lib_response = self.client.get(url, apidata)
-        lib_json = json.loads(lib_response.content)['result']
+        lib_json = json.loads(smart_text(lib_response.content))['result']
 
         for d in [lib_dict, lib_json]:
             # amplified_from_sample is a link to the library table,
@@ -63,7 +64,7 @@ class SampleWebTestCase(TestCase):
             #self.failUnlessEqual(d['amplified_from_sample'], lib.amplified_from_sample)
             self.failUnlessEqual(d['antibody_id'], library.antibody_id)
             self.failUnlessEqual(d['cell_line_id'], library.cell_line_id)
-            self.failUnlessEqual(d['cell_line'], unicode_or_none(library.cell_line))
+            self.failUnlessEqual(d['cell_line'], str_or_none(library.cell_line))
             self.failUnlessEqual(d['experiment_type'], library.experiment_type.name)
             self.failUnlessEqual(d['experiment_type_id'], library.experiment_type_id)
             self.failUnlessEqual(d['gel_cut_size'], library.gel_cut_size)
@@ -82,7 +83,7 @@ class SampleWebTestCase(TestCase):
             self.failUnlessEqual(d['stopping_point'], library.stopping_point)
             self.failUnlessEqual(d['successful_pM'], library.successful_pM)
             self.failUnlessEqual(d['undiluted_concentration'],
-                                 unicode(library.undiluted_concentration))
+                                 str(library.undiluted_concentration))
 
 
         def junk(self):
@@ -150,7 +151,7 @@ class SampleWebTestCase(TestCase):
 
         response = self.client.get(library.get_absolute_url())
         self.assertEqual(response.status_code, 200)
-        content = response.content
+        content = smart_text(response.content)
         load_string_into_model(model, 'rdfa', content)
 
         body = """prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
@@ -199,7 +200,7 @@ class SampleWebTestCase(TestCase):
 
         response = self.client.get('/library/')
         self.assertEqual(response.status_code, 200)
-        load_string_into_model(model, 'rdfa', response.content)
+        load_string_into_model(model, 'rdfa', smart_text(response.content))
 
         errmsgs = list(inference.run_validation())
         self.assertEqual(len(errmsgs), 0)
@@ -276,7 +277,7 @@ try:
     libNS = RDF.NS("http://jumpgate.caltech.edu/wiki/LibraryOntology#")
 
     from htsworkflow.util.rdfhelp import dump_model
-except ImportError,e:
+except ImportError as e:
     HAVE_RDF = False
 
 
@@ -298,12 +299,13 @@ class TestRDFaLibrary(TestCase):
         ## request = self.request.get(url)
         ## lib_response = library(request)
         lib_response = self.client.get(url)
-        with open('/tmp/body.html', 'w') as outstream:
-            outstream.write(lib_response.content)
-        self.failIfEqual(len(lib_response.content), 0)
+        lib_body = smart_str(lib_response.content)
+        self.failIfEqual(len(lib_body), 0)
+        with open('/tmp/body.html', 'wt') as outstream:
+            outstream.write(lib_body)
 
         parser.parse_string_into_model(model,
-                                       lib_response.content,
+                                       lib_body,
                                        'http://localhost'+url)
         # help debugging rdf errrors
         #with open('/tmp/test.ttl', 'w') as outstream:
@@ -340,7 +342,7 @@ class TestRDFaLibrary(TestCase):
         self.failUnlessEqual(len(statements), len(values),
                         "Couln't find %s %s %s" % (s,p,o))
         for s in statements:
-            self.failUnless(unicode(s.object.uri) in values)
+            self.failUnless(str(s.object.uri) in values)
 
 
 
index 3d09dd4182718d97da0bbf5605639d9f8667ad3b..1bda463ed3c6a965d61ee287e464e13e984a3277 100644 (file)
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
 from django.conf.urls import patterns, url
 
 urlpatterns = patterns('samples.views',
index 79e7856f1041db732a1d3c5020fe8652cc9c82c4..cc94c620474ce1e8267b0e969921157141e63a3a 100644 (file)
@@ -1,14 +1,13 @@
-from __future__ import absolute_import, print_function
+from __future__ import absolute_import, print_function, unicode_literals
 
 # Create your views here.
-import StringIO
 import logging
 import os
 import sys
 
 try:
     import json
-except ImportError, e:
+except ImportError as e:
     import simplejson as json
 
 from django.views.decorators.csrf import csrf_exempt
@@ -31,7 +30,7 @@ from bcmagic.forms import BarcodeMagicForm
 from htsworkflow.pipelines import runfolder
 from htsworkflow.pipelines.eland import ResultLane
 from htsworkflow.pipelines.samplekey import SampleKey
-from htsworkflow.util.conversion import unicode_or_none, parse_flowcell_id
+from htsworkflow.util.conversion import str_or_none, parse_flowcell_id
 from htsworkflow.util import makebed
 from htsworkflow.util import opener
 
@@ -94,7 +93,7 @@ def create_library_context(cl):
         summary['lanes_run'] = lanes_run
         summary['is_archived'] = lib.is_archived()
         records.append(summary)
-    cl.result_count = unicode(cl.paginator._count)
+    cl.result_count = str(cl.paginator._count)
     return {'library_list': records}
 
 
@@ -338,7 +337,7 @@ def _summary_stats(flowcell_id, lane_id, library_id):
 
             summary_list.append(eland_summary)
 
-        #except Exception, e:
+        #except Exception as e:
         #    summary_list.append("Summary report needs to be updated.")
         #    LOGGER.error("Exception: " + str(e))
 
@@ -471,7 +470,7 @@ def library_dict(library_id):
     """
     try:
         lib = Library.objects.get(id=library_id)
-    except Library.DoesNotExist, e:
+    except Library.DoesNotExist as e:
         return None
 
     #lane_info = lane_information(lib.lane_set)
@@ -493,7 +492,7 @@ def library_dict(library_id):
         #'antibody_name': lib.antibody_name(), # we have no antibodies.
         'antibody_id': lib.antibody_id,
         'cell_line_id': lib.cell_line_id,
-        'cell_line': unicode_or_none(lib.cell_line),
+        'cell_line': str_or_none(lib.cell_line),
         'experiment_type': lib.experiment_type.name,
         'experiment_type_id': lib.experiment_type_id,
         'gel_cut_size': lib.gel_cut_size,
@@ -512,8 +511,8 @@ def library_dict(library_id):
         'notes': lib.notes,
         'replicate': lib.replicate,
         'stopping_point': lib.stopping_point,
-        'successful_pM': unicode_or_none(lib.successful_pM),
-        'undiluted_concentration': unicode_or_none(lib.undiluted_concentration)
+        'successful_pM': str_or_none(lib.successful_pM),
+        'undiluted_concentration': str_or_none(lib.undiluted_concentration)
         }
     if lib.library_type_id is None:
         info['library_type'] = None
index 674cd52fb918db49e7650d8ae6a8aa716e211722..dfd0ae11b437e1dda5a045852997aaf85cea26c8 100755 (executable)
@@ -4,8 +4,7 @@ from optparse import OptionParser
 import os
 import re
 import sys
-import urllib2
-import urlparse
+from six.moves import urllib
 
 from django.conf import settings
 
@@ -42,12 +41,12 @@ def update_db(root_url, flowcells, serial, debug=False):
     Creates link between flowcell and storage device over http
     """
     for fc in flowcells:
-        url = urlparse.urljoin(root_url, '%s/%s/' % (fc, serial))
+        url = urllib.parse.urljoin(root_url, '%s/%s/' % (fc, serial))
 
-        req = urllib2.Request(url)
+        req = urllib.request.Request(url)
         try:
             response = urllib2.urlopen(req)
-        except urllib2.URLError, e:
+        except urllib.request.HTTPError, e:
             print 'ERROR - HTTP OUTPUT (Return Code: %s); use -v/--verbose for more details.' % (e.code)
             if debug:
                 print e.read()
index bcf835dbfa29c1d3707d0e9e602d5c5882093ce4..06ca25d8fb6c2d981c6ef6e035e2b4a07f126d5f 100755 (executable)
@@ -1,4 +1,5 @@
 #!/usr/bin/python
+from __future__ import print_function, unicode_literals
 
 import logging
 import optparse
@@ -10,6 +11,8 @@ from htsworkflow.pipelines.srf import make_srf_commands, make_qseq_commands, \
                                       run_commands, pathname_to_run_name
 from htsworkflow.pipelines.srf import ILLUMINA2SRF10, ILLUMINA2SRF11, SOLEXA2SRF
 
+LOGGER = logging.getLogger(__name__)
+
 def make_parser():
   usage = '%prog: [options] runfolder -l 1,2,3 [runfolder -l 5,6 ...]'
 
@@ -97,7 +100,7 @@ def main(cmdline=None):
         runs = runfolder.get_runs(runfolder_path)
         # give up if there are anything other than 1 run
         if len(runs) > 1:
-          print 'ERROR: Too many run directories in %s' %(runfolder_path,)
+          LOGGER.error('Too many run directories in %s', runfolder_path)
           return 1
         elif len(runs) == 1:
           bustard_dir = runs[0].bustard.pathname
@@ -108,7 +111,8 @@ def main(cmdline=None):
                                             opts.dest_dir,
                                             opts.runfolder_version)
         else:
-          print "ERROR: Couldn't find a bustard directory in", runfolder_path
+          LOGGER.error("Couldn't find a bustard directory in %s",
+                       runfolder_path)
           return 1
 
     if not opts.dry_run:
@@ -116,9 +120,9 @@ def main(cmdline=None):
         run_commands(cwd, cmd_list, opts.jobs)
     else:
       for cwd, cmd_list in cmds.items():
-        print cwd
-        print cmd_list
-        print 'jobs: ', opts.jobs
+        print(cwd)
+        print(cmd_list)
+        print('jobs: ', opts.jobs)
 
     return 0
 
index aeabc57ff20189d716746de5f1afa7d8494f51eb..302fbfe45abcb3e979dc0ea52fb8bde4cfd64e39 100755 (executable)
@@ -26,7 +26,7 @@ def build_flowcell_db(fcdb_filename, sequences, baseurl, apiid, apikey):
         flowcell_info = None
 
         # get info about flowcell from server or shelf
-        if not fcdb.has_key(flowcell):
+        if flowcell not in fcdb:
             url = api.flowcell_url(baseurl, flowcell)
             flowcell_info = api.retrieve_info(url, apidata)
             if flowcell_info is not None:
index 52bd8e2879dfe47e4bf444ead9924873728942ee..b88b1a49248ba7d539003163f6f468ade4f551a7 100644 (file)
@@ -1,6 +1,6 @@
 from unittest import TestCase, skipIf
 
-from StringIO import StringIO
+from six.moves import StringIO
 from htsworkflow.automation.solexa import is_runfolder
 
 try:
index e06ec82ed31e197e464665d2a68e9c99bb53d3b5..9e96de59811ca3fabb4a8324308754a82c19c0cc 100644 (file)
@@ -1,5 +1,5 @@
 import os
-from StringIO import StringIO
+from six.moves import StringIO
 import sys
 from unittest import TestCase
 
@@ -24,19 +24,19 @@ IIIIB+++
 
         target1.seek(0)
         lines1 = target1.readlines()
-        self.failUnlessEqual(len(lines1),4)
-        self.failUnlessEqual(lines1[0].rstrip(), '@header/1')
-        self.failUnlessEqual(lines1[1].rstrip(), 'AGCT')
-        self.failUnlessEqual(lines1[2].rstrip(), '+')
-        self.failUnlessEqual(lines1[3].rstrip(), 'IIII')
+        self.assertEqual(len(lines1),4)
+        self.assertEqual(lines1[0].rstrip(), '@header/1')
+        self.assertEqual(lines1[1].rstrip(), 'AGCT')
+        self.assertEqual(lines1[2].rstrip(), '+')
+        self.assertEqual(lines1[3].rstrip(), 'IIII')
 
         target2.seek(0)
         lines2 = target2.readlines()
-        self.failUnlessEqual(len(lines2),4)
-        self.failUnlessEqual(lines2[0].rstrip(), '@header/2')
-        self.failUnlessEqual(lines2[1].rstrip(), 'TTTT')
-        self.failUnlessEqual(lines2[2].rstrip(), '+')
-        self.failUnlessEqual(lines2[3].rstrip(), 'B+++')
+        self.assertEqual(len(lines2),4)
+        self.assertEqual(lines2[0].rstrip(), '@header/2')
+        self.assertEqual(lines2[1].rstrip(), 'TTTT')
+        self.assertEqual(lines2[2].rstrip(), '+')
+        self.assertEqual(lines2[3].rstrip(), 'B+++')
 
     def test_split_at_with_header(self):
         source = StringIO("""@header1
@@ -55,19 +55,19 @@ IIIIB+++
 
         target1.seek(0)
         lines1 = target1.readlines()
-        self.failUnlessEqual(len(lines1),8)
-        self.failUnlessEqual(lines1[0].rstrip(), '@foo_header1/1')
-        self.failUnlessEqual(lines1[1].rstrip(), 'AGCT')
-        self.failUnlessEqual(lines1[2].rstrip(), '+')
-        self.failUnlessEqual(lines1[3].rstrip(), '@III')
+        self.assertEqual(len(lines1),8)
+        self.assertEqual(lines1[0].rstrip(), '@foo_header1/1')
+        self.assertEqual(lines1[1].rstrip(), 'AGCT')
+        self.assertEqual(lines1[2].rstrip(), '+')
+        self.assertEqual(lines1[3].rstrip(), '@III')
 
         target2.seek(0)
         lines2 = target2.readlines()
-        self.failUnlessEqual(len(lines2),8)
-        self.failUnlessEqual(lines2[0].rstrip(), '@foo_header1/2')
-        self.failUnlessEqual(lines2[1].rstrip(), 'TTTT')
-        self.failUnlessEqual(lines2[2].rstrip(), '+')
-        self.failUnlessEqual(lines2[3].rstrip(), 'B+++')
+        self.assertEqual(len(lines2),8)
+        self.assertEqual(lines2[0].rstrip(), '@foo_header1/2')
+        self.assertEqual(lines2[1].rstrip(), 'TTTT')
+        self.assertEqual(lines2[2].rstrip(), '+')
+        self.assertEqual(lines2[3].rstrip(), 'B+++')
 
     def test_single_at(self):
         source = StringIO("""@header1
@@ -85,11 +85,11 @@ IIIIB+++
 
         target1.seek(0)
         lines1 = target1.readlines()
-        self.failUnlessEqual(len(lines1),8)
-        self.failUnlessEqual(lines1[0].rstrip(), '@header1')
-        self.failUnlessEqual(lines1[1].rstrip(), 'AGCTTTTT')
-        self.failUnlessEqual(lines1[2].rstrip(), '+')
-        self.failUnlessEqual(lines1[3].rstrip(), '@IIIB+++')
+        self.assertEqual(len(lines1),8)
+        self.assertEqual(lines1[0].rstrip(), '@header1')
+        self.assertEqual(lines1[1].rstrip(), 'AGCTTTTT')
+        self.assertEqual(lines1[2].rstrip(), '+')
+        self.assertEqual(lines1[3].rstrip(), '@IIIB+++')
 
     def test_single_at_with_header(self):
         source = StringIO("""@header1
@@ -107,11 +107,11 @@ IIIIB+++
 
         target1.seek(0)
         lines1 = target1.readlines()
-        self.failUnlessEqual(len(lines1),8)
-        self.failUnlessEqual(lines1[0].rstrip(), '@foo_header1')
-        self.failUnlessEqual(lines1[1].rstrip(), 'AGCTTTTT')
-        self.failUnlessEqual(lines1[2].rstrip(), '+')
-        self.failUnlessEqual(lines1[3].rstrip(), '@IIIB+++')
+        self.assertEqual(len(lines1),8)
+        self.assertEqual(lines1[0].rstrip(), '@foo_header1')
+        self.assertEqual(lines1[1].rstrip(), 'AGCTTTTT')
+        self.assertEqual(lines1[2].rstrip(), '+')
+        self.assertEqual(lines1[3].rstrip(), '@IIIB+++')
 
     def test_is_srf(self):        
         cnf4_srf = 'woldlab_070829_USI-EAS44_0017_FC11055_1.srf'
@@ -120,9 +120,9 @@ IIIIB+++
         cnf1_path = os.path.join(TESTDATA_DIR, cnf1_srf)
         
         is_srf = srf2fastq.is_srf
-        self.failUnlessEqual(is_srf(__file__), False)
-        self.failUnlessEqual(is_srf(cnf4_path), True)
-        self.failUnlessEqual(is_srf(cnf1_path), True)
+        self.assertEqual(is_srf(__file__), False)
+        self.assertEqual(is_srf(cnf4_path), True)
+        self.assertEqual(is_srf(cnf1_path), True)
 
     def test_is_cnf1(self):        
         cnf4_srf = 'woldlab_070829_USI-EAS44_0017_FC11055_1.srf'
@@ -132,8 +132,8 @@ IIIIB+++
         
         is_cnf1 = srf2fastq.is_cnf1
         self.failUnlessRaises(ValueError, is_cnf1, __file__)
-        self.failUnlessEqual(is_cnf1(cnf4_path), False)
-        self.failUnlessEqual(is_cnf1(cnf1_path), True)
+        self.assertEqual(is_cnf1(cnf4_path), False)
+        self.assertEqual(is_cnf1(cnf1_path), True)
 
 
 def suite():