diff --git a/doc/source/release.rst b/doc/source/release.rst index 7171b48f4097a..ed1834f14fc2e 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -186,6 +186,7 @@ Improvements to existing features - DatetimeIndex (and date_range) can now be constructed in a left- or right-open fashion using the ``closed`` parameter (:issue:`4579`) - Python csv parser now supports usecols (:issue:`4335`) + - Added support for Google Analytics v3 API segment IDs that also supports v2 IDs. (:issue:`5271`) API Changes ~~~~~~~~~~~ diff --git a/pandas/io/ga.py b/pandas/io/ga.py index dcbecd74886ac..78c331cda829c 100644 --- a/pandas/io/ga.py +++ b/pandas/io/ga.py @@ -5,6 +5,7 @@ 4. Download JSON secret file and move into same directory as this file """ from datetime import datetime +import re from pandas import compat import numpy as np from pandas import DataFrame @@ -359,7 +360,10 @@ def format_query(ids, metrics, start_date, end_date=None, dimensions=None, [_maybe_add_arg(qry, n, d) for n, d in zip(names, lst)] if isinstance(segment, compat.string_types): - _maybe_add_arg(qry, 'segment', segment, 'dynamic::ga') + if re.match("^[a-zA-Z0-9]+\-*[a-zA-Z0-9]*$", segment): + _maybe_add_arg(qry, 'segment', segment, 'gaid:') + else: + _maybe_add_arg(qry, 'segment', segment, 'dynamic::ga') elif isinstance(segment, int): _maybe_add_arg(qry, 'segment', segment, 'gaid:') elif segment: diff --git a/pandas/io/tests/test_ga.py b/pandas/io/tests/test_ga.py index a0f4dc45725a3..166917799ca82 100644 --- a/pandas/io/tests/test_ga.py +++ b/pandas/io/tests/test_ga.py @@ -10,8 +10,9 @@ try: import httplib2 + import pandas.io.ga as ga from pandas.io.ga import GAnalytics, read_ga - from pandas.io.auth import AuthenticationConfigError, reset_token_store + from pandas.io.auth import AuthenticationConfigError, reset_default_token_store from pandas.io import auth except ImportError: raise nose.SkipTest("need httplib2 and auth libs") @@ -25,7 +26,7 @@ def test_remove_token_store(self): with open(auth.DEFAULT_TOKEN_FILE, 'w') as fh: fh.write('test') - reset_token_store() + reset_default_token_store() self.assert_(not os.path.exists(auth.DEFAULT_TOKEN_FILE)) @slow @@ -98,6 +99,26 @@ def test_iterator(self): except AuthenticationConfigError: raise nose.SkipTest("authentication error") + def test_v2_advanced_segment_format(self): + advanced_segment_id = 1234567 + query = ga.format_query('google_profile_id', ['visits'], '2013-09-01', segment=advanced_segment_id) + assert query['segment'] == 'gaid::' + str(advanced_segment_id), "An integer value should be formatted as an advanced segment." + + def test_v2_dynamic_segment_format(self): + dynamic_segment_id = 'medium==referral' + query = ga.format_query('google_profile_id', ['visits'], '2013-09-01', segment=dynamic_segment_id) + assert query['segment'] == 'dynamic::ga:' + str(dynamic_segment_id), "A string value with more than just letters and numbers should be formatted as a dynamic segment." + + def test_v3_advanced_segment_common_format(self): + advanced_segment_id = 'aZwqR234' + query = ga.format_query('google_profile_id', ['visits'], '2013-09-01', segment=advanced_segment_id) + assert query['segment'] == 'gaid::' + str(advanced_segment_id), "A string value with just letters and numbers should be formatted as an advanced segment." + + def test_v3_advanced_segment_weird_format(self): + advanced_segment_id = 'aZwqR234-s1' + query = ga.format_query('google_profile_id', ['visits'], '2013-09-01', segment=advanced_segment_id) + assert query['segment'] == 'gaid::' + str(advanced_segment_id), "A string value with just letters, numbers, and hyphens should be formatted as an advanced segment." + @slow @with_connectivity_check("http://www.google.com") def test_segment(self):