00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 import urllib2
00021 import tempfile
00022
00023 from ost.io import LoadPDB, LoadMMCIF
00024
00025 class RemoteRepository:
00026 """
00027 A remote repository represents a structural database accessible through the
00028 internet, e.g. the PDB or SWISS-MODEL template library.
00029 """
00030 def __init__(self, name, url_pattern, type, id_transform='upper'):
00031 self.name = name
00032 self.url_pattern = url_pattern
00033 self.type = type
00034 if type not in ('cif', 'pdb'):
00035 raise ValueError('only cif and pdb types are supported')
00036 self.id_transform = id_transform
00037
00038 def URLForID(self, id):
00039 if self.id_transform == 'upper':
00040 id = id.upper()
00041 if self.id_transform == 'lower':
00042 id = id.lower()
00043 return self.url_pattern.replace('$ID', id)
00044
00045 def Get(self, id):
00046 remote_url = self.URLForID(id)
00047 tmp_file_suffix = '.%s' % self.type
00048 if remote_url.endswith('.gz'):
00049 tmp_file_suffix+='.gz'
00050
00051 try:
00052 connection = urllib2.urlopen(remote_url)
00053 if hasattr(connection, 'code'):
00054 status = connection.code
00055 else:
00056 status = connection.getcode()
00057 except urllib2.HTTPError, e:
00058 status = e.code
00059 if status != 200:
00060 raise IOError('Could not load %s from %s (status code %d, url %s)' \
00061 % (id, self.name, status, remote_url))
00062 tmp_file = tempfile.NamedTemporaryFile(suffix=tmp_file_suffix)
00063 contents = ''.join(connection)
00064 tmp_file.write(contents)
00065 tmp_file.flush()
00066 return tmp_file
00067
00068 def Load(self, id):
00069 tmp_file = self.Get(id)
00070 if self.type == 'pdb':
00071 return LoadPDB(tmp_file.name)
00072 if self.type == 'cif':
00073 return LoadMMCIF(tmp_file.name)
00074
00075 REMOTE_REPOSITORIES = {
00076 'pdb' : RemoteRepository('pdb.org (PDB)', 'http://www.pdb.org/pdb/files/$ID.pdb.gz',
00077 type='pdb', id_transform='upper'),
00078 'smtl' : RemoteRepository('SMTL', 'http://swissmodel.expasy.org/templates/$ID.pdb',
00079 type='pdb', id_transform='lower'),
00080 'cif' : RemoteRepository('pdb.org (mmCIF)', 'http://www.pdb.org/pdb/files/$ID.cif.gz',
00081 type='cif', id_transform='lower'),
00082 'pdb_redo' : RemoteRepository('pdbredo', 'http://pdb-redo.eu/db/$ID/$ID_besttls.pdb.gz',
00083 type='pdb', id_transform='lower'),
00084 }
00085
00086 def RemoteGet(id, from_repo='pdb'):
00087 remote_repo = REMOTE_REPOSITORIES.get(from_repo, None)
00088 if not remote_repo:
00089 raise ValueError('%s is not a valid repository' % from_repo)
00090 return remote_repo.Get(id)
00091
00092 def RemoteLoad(id, from_repo='pdb'):
00093 remote_repo = REMOTE_REPOSITORIES.get(from_repo, None)
00094 if not remote_repo:
00095 raise ValueError('%s is not a valid repository' % from_repo)
00096 return remote_repo.Load(id)