diff --git a/geomagio/Url.py b/geomagio/Url.py new file mode 100644 index 0000000000000000000000000000000000000000..636a2dd656d93250d76918e68775377ce50c425e --- /dev/null +++ b/geomagio/Url.py @@ -0,0 +1,239 @@ +"""Class to read a file from a URL given a template""" +import os +import urllib2 +from TimeseriesFactoryException import TimeseriesFactoryException + + +class URL(): + """URL class to allow reading of files using the urllib2 class + + Parameters + ---------- + urlTemplate : str + A string that contains any of the following replacement patterns: + - '%(i)s' : interval abbreviation + - '%(interval)s' interval name + - '%(julian)s' julian date + - '%(obs)s' lowercase observatory code + - '%(OBS)s' uppercase observatory code + - '%(t)s' type abbreviation + - '%(type)s' type name + - '%(year)s' year formatted as YYYY + - '%(ymd)s' time formatted as YYYYMMDD + """ + + def __init__(self, urlTemplate): + self.urlTemplate = urlTemplate + + def get_file_from_url(self, url): + """Get a file for writing. + + Ensures parent directory exists. + + Parameters + ---------- + url : str + path to file + + Returns + ------- + str + path to file without file:// prefix + + Raises + ------ + TimeseriesFactoryException + if url does not start with file:// + """ + if not url.startswith('file://'): + raise TimeseriesFactoryException( + 'Only file urls are supported for writing') + filename = url.replace('file://', '') + parent = os.path.dirname(filename) + if not os.path.exists(parent): + os.makedirs(parent) + return filename + + def get_url(self, observatory, date, type='variation', interval='minute'): + """Get the url for a specified file. + + Replaces patterns (described in class docstring) with values based on + parameter values. + + Parameters + ---------- + observatory : str + observatory code. + date : obspy.core.UTCDateTime + day to fetch (only year, month, day are used) + type : {'variation', 'quasi-definitive', 'definitive'} + data type. + interval : {'minute', 'second', 'hourly', 'daily'} + data interval. + + Raises + ------ + TimeseriesFactoryException + if type or interval are not supported. + """ + return self.urlTemplate % { + 'i': self._get_interval_abbreviation(interval), + 'interval': self._get_interval_name(interval), + 'julian': date.strftime("%j"), + 'obs': observatory.lower(), + 'OBS': observatory.upper(), + 't': self._get_type_abbreviation(type), + 'type': self._get_type_name(type), + 'year': date.strftime("%Y"), + 'ymd': date.strftime('%Y%m%d')} + + def read_url(self, url): + """Open and read url contents. + + Parameters + ---------- + url : str + A urllib2 compatible url, such as http:// or file://. + + Returns + ------- + str + contents returned by url. + + Raises + ------ + urllib2.URLError + if any occurs + """ + response = urllib2.urlopen(url) + content = None + try: + content = response.read() + except urllib2.URLError, e: + print e.reason + raise + finally: + response.close() + return content + + def _get_interval_abbreviation(self, interval): + """Get abbreviation for a data interval. + + Used by ``_get_url`` to replace ``%(i)s`` in urlTemplate. + + Parameters + ---------- + interval : {'daily', 'hourly', 'minute', 'monthly', 'second'} + + Returns + ------- + abbreviation for ``interval``. + + Raises + ------ + TimeseriesFactoryException + if ``interval`` is not supported. + """ + interval_abbr = None + if interval == 'daily': + interval_abbr = 'day' + elif interval == 'hourly': + interval_abbr = 'hor' + elif interval == 'minute': + interval_abbr = 'min' + elif interval == 'monthly': + interval_abbr = 'mon' + elif interval == 'second': + interval_abbr = 'sec' + else: + raise TimeseriesFactoryException( + 'Unexpected interval "%s"' % interval) + return interval_abbr + + def _get_interval_name(self, interval): + """Get name for a data interval. + + Used by ``_get_url`` to replace ``%(interval)s`` in urlTemplate. + + Parameters + ---------- + interval : {'minute', 'second'} + + Returns + ------- + name for ``interval``. + + Raises + ------ + TimeseriesFactoryException + if ``interval`` is not supported. + """ + interval_name = None + if interval == 'minute': + interval_name = 'OneMinute' + elif interval == 'second': + interval_name = 'OneSecond' + else: + raise TimeseriesFactoryException( + 'Unsupported interval "%s"' % interval) + return interval_name + + def _get_type_abbreviation(self, type): + """Get abbreviation for a data type. + + Used by ``_get_url`` to replace ``%(t)s`` in urlTemplate. + + Parameters + ---------- + type : {'definitive', 'provisional', 'quasi-definitive', 'variation'} + + Returns + ------- + name for ``type``. + + Raises + ------ + TimeseriesFactoryException + if ``type`` is not supported. + """ + type_abbr = None + if type == 'definitive': + type_abbr = 'd' + elif type == 'provisional': + type_abbr = 'p' + elif type == 'quasi-definitive': + type_abbr = 'q' + elif type == 'variation': + type_abbr = 'v' + else: + raise TimeseriesFactoryException( + 'Unexpected type "%s"' % type) + return type_abbr + + def _get_type_name(self, type): + """Get name for a data type. + + Used by ``_get_url`` to replace ``%(type)s`` in urlTemplate. + + Parameters + ---------- + type : {'variation', 'quasi-definitive'} + + Returns + ------- + name for ``type``. + + Raises + ------ + TimeseriesFactoryException + if ``type`` is not supported. + """ + type_name = None + if type == 'variation': + type_name = '' + elif type == 'quasi-definitive': + type_name = 'QuasiDefinitive' + else: + raise TimeseriesFactoryException( + 'Unsupported type "%s"' % type) + return type_name diff --git a/geomagio/__init__.py b/geomagio/__init__.py index 74c7d9ea771a19bcb02cd7068c234e885425d0f8..47c82746e0de2803d10b49eb2c8907202e162587 100644 --- a/geomagio/__init__.py +++ b/geomagio/__init__.py @@ -11,6 +11,7 @@ from TimeseriesFactory import TimeseriesFactory from TimeseriesFactoryException import TimeseriesFactoryException import TimeseriesUtility import Util +import Url from XYZAlgorithm import XYZAlgorithm __all__ = [ @@ -24,5 +25,6 @@ __all__ = [ 'TimeseriesFactoryException', 'TimeseriesUtility', 'Util', + 'Url', 'XYZAlgorithm' ] diff --git a/geomagio/iaga2002/IAGA2002Factory.py b/geomagio/iaga2002/IAGA2002Factory.py index 1017cc4e21a258beae7539248c6ad6ea047f72dc..43c94f7679b5c4af4df850ca730706bc9bd50719 100644 --- a/geomagio/iaga2002/IAGA2002Factory.py +++ b/geomagio/iaga2002/IAGA2002Factory.py @@ -1,11 +1,10 @@ """Factory that loads IAGA2002 Files.""" import obspy.core -import os -import urllib2 from .. import ChannelConverter from ..TimeseriesFactory import TimeseriesFactory from ..TimeseriesFactoryException import TimeseriesFactoryException +from ..Url import URL from IAGA2002Parser import IAGA2002Parser from IAGA2002Writer import IAGA2002Writer @@ -14,36 +13,6 @@ from IAGA2002Writer import IAGA2002Writer IAGA_FILE_PATTERN = '%(obs)s%(ymd)s%(t)s%(i)s.%(i)s' -def read_url(url): - """Open and read url contents. - - Parameters - ---------- - url : str - A urllib2 compatible url, such as http:// or file://. - - Returns - ------- - str - contents returned by url. - - Raises - ------ - urllib2.URLError - if any occurs - """ - response = urllib2.urlopen(url) - content = None - try: - content = response.read() - except urllib2.URLError, e: - print e.reason - raise - finally: - response.close() - return content - - class IAGA2002Factory(TimeseriesFactory): """TimeseriesFactory for IAGA 2002 formatted files. @@ -103,9 +72,10 @@ class IAGA2002Factory(TimeseriesFactory): interval = interval or self.interval days = self._get_days(starttime, endtime) timeseries = obspy.core.Stream() + url = URL(self.urlTemplate) for day in days: - url = self._get_url(observatory, day, type, interval) - iagaFile = read_url(url) + url_id = url.get_url(observatory, day, type, interval) + iagaFile = url.read_url(url_id) timeseries += self.parse_string(iagaFile) # merge channel traces for multiple days timeseries.merge() @@ -147,159 +117,6 @@ class IAGA2002Factory(TimeseriesFactory): stream += obspy.core.Trace(data[channel], stats) return stream - def _get_url(self, observatory, date, type='variation', interval='minute'): - """Get the url for a specified IAGA2002 file. - - Replaces patterns (described in class docstring) with values based on - parameter values. - - Parameters - ---------- - observatory : str - observatory code. - date : obspy.core.UTCDateTime - day to fetch (only year, month, day are used) - type : {'variation', 'quasi-definitive'} - data type. - interval : {'minute', 'second'} - data interval. - - Raises - ------ - TimeseriesFactoryException - if type or interval are not supported. - """ - return self.urlTemplate % { - 'i': self._get_interval_abbreviation(interval), - 'interval': self._get_interval_name(interval), - 'obs': observatory.lower(), - 'OBS': observatory.upper(), - 't': self._get_type_abbreviation(type), - 'type': self._get_type_name(type), - 'ymd': date.strftime("%Y%m%d")} - - def _get_interval_abbreviation(self, interval): - """Get abbreviation for a data interval. - - Used by ``_get_url`` to replace ``%(i)s`` in urlTemplate. - - Parameters - ---------- - interval : {'daily', 'hourly', 'minute', 'monthly', 'second'} - - Returns - ------- - abbreviation for ``interval``. - - Raises - ------ - TimeseriesFactoryException - if ``interval`` is not supported. - """ - interval_abbr = None - if interval == 'daily': - interval_abbr = 'day' - elif interval == 'hourly': - interval_abbr = 'hor' - elif interval == 'minute': - interval_abbr = 'min' - elif interval == 'monthly': - interval_abbr = 'mon' - elif interval == 'second': - interval_abbr = 'sec' - else: - raise TimeseriesFactoryException( - 'Unexpected interval "%s"' % interval) - return interval_abbr - - def _get_interval_name(self, interval): - """Get name for a data interval. - - Used by ``_get_url`` to replace ``%(interval)s`` in urlTemplate. - - Parameters - ---------- - interval : {'minute', 'second'} - - Returns - ------- - name for ``interval``. - - Raises - ------ - TimeseriesFactoryException - if ``interval`` is not supported. - """ - interval_name = None - if interval == 'minute': - interval_name = 'OneMinute' - elif interval == 'second': - interval_name = 'OneSecond' - else: - raise TimeseriesFactoryException( - 'Unsupported interval "%s"' % interval) - return interval_name - - def _get_type_abbreviation(self, type): - """Get abbreviation for a data type. - - Used by ``_get_url`` to replace ``%(t)s`` in urlTemplate. - - Parameters - ---------- - type : {'definitive', 'provisional', 'quasi-definitive', 'variation'} - - Returns - ------- - name for ``type``. - - Raises - ------ - TimeseriesFactoryException - if ``type`` is not supported. - """ - type_abbr = None - if type == 'definitive': - type_abbr = 'd' - elif type == 'provisional': - type_abbr = 'p' - elif type == 'quasi-definitive': - type_abbr = 'q' - elif type == 'variation': - type_abbr = 'v' - else: - raise TimeseriesFactoryException( - 'Unexpected type "%s"' % type) - return type_abbr - - def _get_type_name(self, type): - """Get name for a data type. - - Used by ``_get_url`` to replace ``%(type)s`` in urlTemplate. - - Parameters - ---------- - type : {'variation', 'quasi-definitive'} - - Returns - ------- - name for ``type``. - - Raises - ------ - TimeseriesFactoryException - if ``type`` is not supported. - """ - type_name = None - if type == 'variation': - type_name = '' - elif type == 'quasi-definitive': - type_name = 'QuasiDefinitive' - else: - raise TimeseriesFactoryException( - 'Unsupported type "%s"' % type) - return type_name - def _get_days(self, starttime, endtime): """Get days between (inclusive) starttime and endtime. @@ -382,42 +199,14 @@ class IAGA2002Factory(TimeseriesFactory): starttime = starttime or stats.starttime endtime = endtime or stats.endtime days = self._get_days(starttime, endtime) + url = URL(self.urlTemplate) for day in days: - day_filename = self._get_file_from_url( - self._get_url(observatory, day, type, interval)) + day_filename = url.get_file_from_url( + url.get_url(observatory, day, type, interval)) day_timeseries = self._get_slice(timeseries, day, interval) with open(day_filename, 'wb') as fh: self.write_file(fh, day_timeseries, channels) - def _get_file_from_url(self, url): - """Get a file for writing. - - Ensures parent directory exists. - - Parameters - ---------- - url : str - Url path to IAGA2002 - - Returns - ------- - str - path to file without file:// prefix - - Raises - ------ - TimeseriesFactoryException - if url does not start with file:// - """ - if not url.startswith('file://'): - raise TimeseriesFactoryException( - 'Only file urls are supported for writing') - filename = url.replace('file://', '') - parent = os.path.dirname(filename) - if not os.path.exists(parent): - os.makedirs(parent) - return filename - def _get_slice(self, timeseries, day, interval): """Get the first and last time for a day diff --git a/geomagio/imfv283/IMFV283Factory.py b/geomagio/imfv283/IMFV283Factory.py index 530ca8e6518a53059db9b7fe7607ab3fb80e412b..2a33a40e7c9fc22f60e40e5985774c16e359f4a0 100644 --- a/geomagio/imfv283/IMFV283Factory.py +++ b/geomagio/imfv283/IMFV283Factory.py @@ -1,64 +1,17 @@ """Factory that loads IAGA2002 Files.""" import obspy.core -import os -import urllib2 import numpy from .. import ChannelConverter from ..TimeseriesFactory import TimeseriesFactory from ..TimeseriesFactoryException import TimeseriesFactoryException +from ..Url import URL from IMFV283Parser import IMFV283Parser -# pattern for IMFV283 file names -IMFV283_FILE_PATTERN = 'dcpmsgs.txt' - - -def read_url(url): - """Open and read url contents. - - Parameters - ---------- - url : str - A urllib2 compatible url, such as http:// or file://. - - Returns - ------- - str - contents returned by url. - - Raises - ------ - urllib2.URLError - if any occurs - """ - response = urllib2.urlopen(url) - content = None - try: - content = response.read() - except urllib2.URLError, e: - print e.reason - raise - finally: - response.close() - return content - - class IMFV283Factory(TimeseriesFactory): """TimeseriesFactory for IMFV283 formatted files. - Parameters - ---------- - urlTemplate : str - A string that contains any of the following replacement patterns: - - '%(i)s' : interval abbreviation - - '%(interval)s' interval name - - '%(obs)s' lowercase observatory code - - '%(OBS)s' uppercase observatory code - - '%(t)s' type abbreviation - - '%(type)s' type name - - '%(ymd)s' time formatted as YYYYMMDD - See Also -------- IMFV283Parser @@ -108,10 +61,11 @@ class IMFV283Factory(TimeseriesFactory): type = type or self.type interval = interval or self.interval timeseries = obspy.core.Stream() - - url = self._get_url(observatory, obspy.core.UTCDateTime(), + url = URL(self.urlTemplate) + url_id = url.get_url(observatory, obspy.core.UTCDateTime(), type, interval) - imfV283File = read_url(url) + + imfV283File = url.read_url(url_id) timeseries += self.parse_string(imfV283File) # merge channel traces for multiple days timeseries.merge() @@ -151,195 +105,6 @@ class IMFV283Factory(TimeseriesFactory): return stream - def _get_url(self, observatory, date, type='variation', interval='minute'): - """Get the url for a specified IMFV283 file. - - Replaces patterns (described in class docstring) with values based on - parameter values. - - Parameters - ---------- - observatory : str - observatory code. - date : obspy.core.UTCDateTime - day to fetch (only year, month, day are used) - type : {'variation', 'quasi-definitive'} - data type. - interval : {'minute', 'second'} - data interval. - - Raises - ------ - TimeseriesFactoryException - if type or interval are not supported. - """ - return self.urlTemplate % { - 'i': self._get_interval_abbreviation(interval), - 'interval': self._get_interval_name(interval), - 'obs': observatory.lower(), - 'OBS': observatory.upper(), - 't': self._get_type_abbreviation(type), - 'type': self._get_type_name(type), - 'ymd': date.strftime("%Y%m%d")} - - def _get_interval_abbreviation(self, interval): - """Get abbreviation for a data interval. - - Used by ``_get_url`` to replace ``%(i)s`` in urlTemplate. - - Parameters - ---------- - interval : {'daily', 'hourly', 'minute', 'monthly', 'second'} - - Returns - ------- - abbreviation for ``interval``. - - Raises - ------ - TimeseriesFactoryException - if ``interval`` is not supported. - """ - print interval - interval_abbr = None - if interval == 'daily': - interval_abbr = 'day' - elif interval == 'hourly': - interval_abbr = 'hor' - elif interval == 'minute': - interval_abbr = 'min' - elif interval == 'monthly': - interval_abbr = 'mon' - elif interval == 'second': - interval_abbr = 'sec' - else: - raise TimeseriesFactoryException( - 'Unexpected interval "%s"' % interval) - return interval_abbr - - def _get_interval_name(self, interval): - """Get name for a data interval. - - Used by ``_get_url`` to replace ``%(interval)s`` in urlTemplate. - - Parameters - ---------- - interval : {'minute', 'second'} - - Returns - ------- - name for ``interval``. - - Raises - ------ - TimeseriesFactoryException - if ``interval`` is not supported. - """ - interval_name = None - if interval == 'minute': - interval_name = 'OneMinute' - elif interval == 'second': - interval_name = 'OneSecond' - else: - raise TimeseriesFactoryException( - 'Unsupported interval "%s"' % interval) - return interval_name - - def _get_type_abbreviation(self, type): - """Get abbreviation for a data type. - - Used by ``_get_url`` to replace ``%(t)s`` in urlTemplate. - - Parameters - ---------- - type : {'definitive', 'provisional', 'quasi-definitive', 'variation'} - - Returns - ------- - name for ``type``. - - Raises - ------ - TimeseriesFactoryException - if ``type`` is not supported. - """ - type_abbr = None - if type == 'definitive': - type_abbr = 'd' - elif type == 'provisional': - type_abbr = 'p' - elif type == 'quasi-definitive': - type_abbr = 'q' - elif type == 'variation': - type_abbr = 'v' - else: - raise TimeseriesFactoryException( - 'Unexpected type "%s"' % type) - return type_abbr - - def _get_type_name(self, type): - """Get name for a data type. - - Used by ``_get_url`` to replace ``%(type)s`` in urlTemplate. - - Parameters - ---------- - type : {'variation', 'quasi-definitive'} - - Returns - ------- - name for ``type``. - - Raises - ------ - TimeseriesFactoryException - if ``type`` is not supported. - """ - type_name = None - if type == 'variation': - type_name = '' - elif type == 'quasi-definitive': - type_name = 'QuasiDefinitive' - else: - raise TimeseriesFactoryException( - 'Unsupported type "%s"' % type) - return type_name - - def _get_days(self, starttime, endtime): - """Get days between (inclusive) starttime and endtime. - - Parameters - ---------- - starttime : obspy.core.UTCDateTime - the start time - endtime : obspy.core.UTCDateTime - the end time - - Returns - ------- - array_like - list of times, one per day, for all days between and including - ``starttime`` and ``endtime``. - - Raises - ------ - TimeseriesFactoryException - if starttime is after endtime - """ - if starttime > endtime: - raise TimeseriesFactoryException( - 'starttime must be before endtime') - days = [] - day = starttime - lastday = (endtime.year, endtime.month, endtime.day) - while True: - days.append(day) - if lastday == (day.year, day.month, day.day): - break - # move to next day - day = obspy.core.UTCDateTime(day.timestamp + 86400) - return days - def write_file(self, fh, timeseries, channels): """writes timeseries data to the given file object. @@ -352,32 +117,3 @@ class IMFV283Factory(TimeseriesFactory): list of channels to store """ raise TimeseriesFactoryException('IAF write_file not implemented.') - - def _get_file_from_url(self, url): - """Get a file for writing. - - Ensures parent directory exists. - - Parameters - ---------- - url : str - Url path to IMFV283 - - Returns - ------- - str - path to file without file:// prefix - - Raises - ------ - TimeseriesFactoryException - if url does not start with file:// - """ - if not url.startswith('file://'): - raise TimeseriesFactoryException( - 'Only file urls are supported for writing') - filename = url.replace('file://', '') - parent = os.path.dirname(filename) - if not os.path.exists(parent): - os.makedirs(parent) - return filename diff --git a/geomagio/pcdcp/PCDCPFactory.py b/geomagio/pcdcp/PCDCPFactory.py index 8d6c0e82be2686887847574ed2b6b90a353c517a..d6b961240904b51b4a893f72fbc576bae6b91ff0 100644 --- a/geomagio/pcdcp/PCDCPFactory.py +++ b/geomagio/pcdcp/PCDCPFactory.py @@ -1,11 +1,10 @@ """Factory that loads PCDCP Files.""" import obspy.core -import os -import urllib2 from .. import ChannelConverter from ..TimeseriesFactory import TimeseriesFactory from ..TimeseriesFactoryException import TimeseriesFactoryException +from ..Url import URL from PCDCPParser import PCDCPParser from PCDCPWriter import PCDCPWriter @@ -14,36 +13,6 @@ from PCDCPWriter import PCDCPWriter PCDCP_FILE_PATTERN = '%(obs)s%(y)s%(j)s.%(i)s' -def read_url(url): - """Open and read url contents. - - Parameters - ---------- - url : str - A urllib2 compatible url, such as http:// or file://. - - Returns - ------- - str - contents returned by url. - - Raises - ------ - urllib2.URLError - if any occurs - """ - response = urllib2.urlopen(url) - content = None - try: - content = response.read() - except urllib2.URLError, e: - print e.reason - raise - finally: - response.close() - return content - - class PCDCPFactory(TimeseriesFactory): """TimeseriesFactory for PCDCP formatted files. @@ -105,10 +74,10 @@ class PCDCPFactory(TimeseriesFactory): interval = interval or self.interval days = self._get_days(starttime, endtime) timeseries = obspy.core.Stream() - + url = URL(self.urlTemplate) for day in days: - url = self._get_url(observatory, day, type, interval) - pcdcpFile = read_url(url) + url_id = url.get_url(observatory, day, type, interval) + pcdcpFile = url.read_url(url_id) timeseries += self.parse_string(pcdcpFile) # merge channel traces for multiple days @@ -174,162 +143,6 @@ class PCDCPFactory(TimeseriesFactory): return stream - def _get_url(self, observatory, date, type='variation', interval='minute'): - """Get the url for a specified PCDCP file. - - Replaces patterns (described in class docstring) with values based on - parameter values. - - Parameters - ---------- - observatory : str - observatory code. - date : obspy.core.UTCDateTime - day to fetch (only year, month, day are used) - type : {'variation', 'quasi-definitive'} - data type. - interval : {'minute', 'second'} - data interval. - - Raises - ------ - TimeseriesFactoryException - If type or interval are not supported. - """ - return self.urlTemplate % { - 'i': self._get_interval_abbreviation(interval), - 'interval': self._get_interval_name(interval), - 'julian': date.strftime("%j"), - 'obs': observatory.lower(), - 'OBS': observatory.upper(), - 't': self._get_type_abbreviation(type), - 'type': self._get_type_name(type), - 'year': date.strftime("%Y"), - 'ymd': date.strftime("%Y%m%d") - } - - def _get_interval_abbreviation(self, interval): - """Get abbreviation for a data interval. - - Used by ``_get_url`` to replace ``%(i)s`` in urlTemplate. - - Parameters - ---------- - interval : {'daily', 'hourly', 'minute', 'monthly', 'second'} - - Returns - ------- - abbreviation for ``interval``. - - Raises - ------ - TimeseriesFactoryException - if ``interval`` is not supported. - """ - interval_abbr = None - if interval == 'daily': - interval_abbr = 'day' - elif interval == 'hourly': - interval_abbr = 'hor' - elif interval == 'minute': - interval_abbr = 'min' - elif interval == 'monthly': - interval_abbr = 'mon' - elif interval == 'second': - interval_abbr = 'sec' - else: - raise TimeseriesFactoryException( - 'Unexpected interval "%s"' % interval) - return interval_abbr - - def _get_interval_name(self, interval): - """Get name for a data interval. - - Used by ``_get_url`` to replace ``%(interval)s`` in urlTemplate. - - Parameters - ---------- - interval : {'minute', 'second'} - - Returns - ------- - name for ``interval``. - - Raises - ------ - TimeseriesFactoryException - if ``interval`` is not supported. - """ - interval_name = None - if interval == 'minute': - interval_name = 'OneMinute' - elif interval == 'second': - interval_name = 'OneSecond' - else: - raise TimeseriesFactoryException( - 'Unsupported interval "%s"' % interval) - return interval_name - - def _get_type_abbreviation(self, type): - """Get abbreviation for a data type. - - Used by ``_get_url`` to replace ``%(t)s`` in urlTemplate. - - Parameters - ---------- - type : {'definitive', 'provisional', 'quasi-definitive', 'variation'} - - Returns - ------- - name for ``type``. - - Raises - ------ - TimeseriesFactoryException - if ``type`` is not supported. - """ - type_abbr = None - if type == 'definitive': - type_abbr = 'd' - elif type == 'provisional': - type_abbr = 'p' - elif type == 'quasi-definitive': - type_abbr = 'q' - elif type == 'variation': - type_abbr = 'v' - else: - raise TimeseriesFactoryException( - 'Unexpected type "%s"' % type) - return type_abbr - - def _get_type_name(self, type): - """Get name for a data type. - - Used by ``_get_url`` to replace ``%(type)s`` in urlTemplate. - - Parameters - ---------- - type : {'variation', 'quasi-definitive'} - - Returns - ------- - name for ``type``. - - Raises - ------ - TimeseriesFactoryException - if ``type`` is not supported. - """ - type_name = None - if type == 'variation': - type_name = '' - elif type == 'quasi-definitive': - type_name = 'QuasiDefinitive' - else: - raise TimeseriesFactoryException( - 'Unsupported type "%s"' % type) - return type_name - def _get_days(self, starttime, endtime): """Get days between (inclusive) starttime and endtime. @@ -414,47 +227,15 @@ class PCDCPFactory(TimeseriesFactory): starttime = starttime or stats.starttime endtime = endtime or stats.endtime days = self._get_days(starttime, endtime) - + url = URL(self.urlTemplate) for day in days: - day_filename = self._get_file_from_url( - self._get_url(observatory, day, type, interval)) + day_filename = url.get_file_from_url( + url.get_url(observatory, day, type, interval)) day_timeseries = self._get_slice(timeseries, day, interval) with open(day_filename, 'wb') as fh: self.write_file(fh, day_timeseries, channels) - def _get_file_from_url(self, url): - """Get a file for writing. - - Ensures parent directory exists. - - Parameters - ---------- - url : str - Url path to PCDCP - - Returns - ------- - str - path to file without file:// prefix - - Raises - ------ - TimeseriesFactoryException - if url does not start with file:// - """ - if not url.startswith('file://'): - raise TimeseriesFactoryException( - 'Only file urls are supported for writing') - - filename = url.replace('file://', '') - parent = os.path.dirname(filename) - - if not os.path.exists(parent): - os.makedirs(parent) - - return filename - def _get_slice(self, timeseries, day, interval): """Get the first and last time for a day