diff options
author | Nicholas Piper <nicholas@users.sourceforge.net> | 2007-08-07 22:48:06 +0000 |
---|---|---|
committer | Nicholas Piper <nicholas@users.sourceforge.net> | 2007-08-07 22:48:06 +0000 |
commit | cbf92d9301730f2e729c33237a5c041fd596c9a0 (patch) | |
tree | b5514079171346a5314ed80eb95e944b2f8f48c2 /bindings | |
parent | 27ca3160700a9b7a135ed38911bc51318aa1379e (diff) | |
download | libgpod-tmz-cbf92d9301730f2e729c33237a5c041fd596c9a0.tar.gz libgpod-tmz-cbf92d9301730f2e729c33237a5c041fd596c9a0.tar.xz libgpod-tmz-cbf92d9301730f2e729c33237a5c041fd596c9a0.zip |
Try to deal with typestamps in a sane way in the Python bindings
git-svn-id: https://gtkpod.svn.sf.net/svnroot/gtkpod/libgpod/trunk@1672 f01d2545-417e-4e96-918e-98f8d0dbbcb6
Diffstat (limited to 'bindings')
-rw-r--r-- | bindings/python/README.in | 56 | ||||
-rw-r--r-- | bindings/python/gpod.i.in | 58 | ||||
-rw-r--r-- | bindings/python/ipod.py | 5 | ||||
-rw-r--r-- | bindings/python/tests/tests.py | 17 |
4 files changed, 133 insertions, 3 deletions
diff --git a/bindings/python/README.in b/bindings/python/README.in index f5c4501..a71c6b2 100644 --- a/bindings/python/README.in +++ b/bindings/python/README.in @@ -41,3 +41,59 @@ The current helper functions are: @WRAPPER_LIST@ Please see the example scripts for ideas on how to use these functions. + + +The time_t mapping has changed recently: + ++------------------------+-------------+-------------+ +|Version | Reading | Writing | +| | | | ++------------------------+-------------+-------------+ +|r1669 < libgpod |C style API: |C style API: | +| |As a unix |As a unix | +| |timestamp |timestamp | +| |integer |integer or a | +| | |Python | +| |OO style API:|datetime | +| |As a Python |instance | +| |datetime | | +| | |OO style API:| +| | |As a unix | +| | |timestamp | +| | |integer or a | +| | |Python | +| | |datetime | +| | |instance | +| | | | ++------------------------+-------------+-------------+ +|r1433 < libgpod < r1669 |As a unix |As a unix | +| |timestamp |timestamp | +| |integer |integer | +| | | | +| | | | ++------------------------+-------------+-------------+ +|r1417 < libgpod < r1433 |Not possible |Not possible | +| |(time_t not |(time_t not | +| |mapped to |mapped to | +| |Python type) |Python type) | +| | | | ++------------------------+-------------+-------------+ +|libgpod < r1417 |As an integer|As an integer| +| |with a |with a | +| |2082844800 |2082844800 | +| |offset |offset | ++------------------------+-------------+-------------+ + +This table means that as a user of the Python bindings, you likely +want to detect libgpod < r1417. One way would be to test for the +presence of some of the renamed constants in 0.5: + + # libgpod>= 0.5.2 doesn't use mac-type timestamps anymore. check + # if we're using a newer version by looking for a renamed constant. + if hasattr(gpod, 'ITDB_SPL_STRING_MAXLEN'): + track.time_released = int(time.mktime(ipod_date) + else: + track.time_release = int(time.mktime(ipod_date) + 2082844800 + +(Since r1633 there exists a gpod.version_info tuple, which will make +such things easier to cope with in the future. diff --git a/bindings/python/gpod.i.in b/bindings/python/gpod.i.in index b7da152..7e4366c 100644 --- a/bindings/python/gpod.i.in +++ b/bindings/python/gpod.i.in @@ -56,6 +56,8 @@ version = '.'.join(map(str, version_info)) #include "itdb.h" #include "itdb_device.h" #include "itdb_private.h" +#include <time.h> +#include <datetime.h> #ifdef HAVE_GDKPIXBUF #ifdef HAVE_PYGOBJECT #include <gdk-pixbuf/gdk-pixbuf.h> @@ -298,6 +300,7 @@ PyObject* sw_get_photo(GList *list, gint index) { #ifdef HAVE_GDKPIXBUF #ifdef HAVE_PYGOBJECT g_type_init (); + PyDateTime_IMPORT; init_pygobject (); #endif #endif @@ -311,8 +314,59 @@ PyObject* sw_get_photo(GList *list, gint index) { # them utf8 encoded Strings. typedef char gchar; -# treat time_t as long -typedef long time_t; +%typemap(in) time_t { + struct tm tmvalue; + PyObject* pydatetime = NULL; + if (PyDateTime_Check($input)) { + pydatetime = $input; + Py_INCREF(pydatetime); + } else if ((PyInt_Check($input)) || (PyLong_Check($input)) || (PyFloat_Check($input))) { + PyObject* pyargs; + Py_INCREF($input); + pyargs = PyTuple_Pack(1, $input); + if ((pydatetime = PyDateTime_FromTimestamp(pyargs)) == NULL) { + Py_DECREF(pyargs); + Py_DECREF($input); + SWIG_fail; + } + Py_DECREF(pyargs); + Py_DECREF($input); + } else { + PyErr_SetString(PyExc_ValueError, "$symname: Value must be a datetime.datetime, int or float"); + SWIG_fail; + } + tmvalue.tm_year = PyDateTime_GET_YEAR(pydatetime) - 1900; + tmvalue.tm_mon = PyDateTime_GET_MONTH(pydatetime) - 1; + tmvalue.tm_mday = PyDateTime_GET_DAY(pydatetime); + tmvalue.tm_hour = PyDateTime_DATE_GET_HOUR(pydatetime); + tmvalue.tm_min = PyDateTime_DATE_GET_MINUTE(pydatetime); + tmvalue.tm_sec = PyDateTime_DATE_GET_SECOND(pydatetime); + + Py_DECREF(pydatetime); + + $1 = mktime(&tmvalue); + if ($1 == -1) { + PyErr_SetString(PyExc_ValueError, "$symname: Failed to parse provided time"); + SWIG_fail; + } +} + +%typemap(out) time_t { +#ifdef 0 + /* for libgpod 0.6.x.. maybe ? */ + struct tm *tmvalue; + tmvalue = localtime(&$1); + $result = PyDateTime_FromDateAndTime(tmvalue->tm_year + 1900, + tmvalue->tm_mon + 1, + tmvalue->tm_mday, + tmvalue->tm_hour, + tmvalue->tm_min, + tmvalue->tm_sec, + 0); +#else + $result = PyLong_FromUnsignedLong((unsigned long) $1); +#endif +} %typemap(in) guint8 { unsigned long ival; diff --git a/bindings/python/ipod.py b/bindings/python/ipod.py index c287171..20fd510 100644 --- a/bindings/python/ipod.py +++ b/bindings/python/ipod.py @@ -461,7 +461,10 @@ class Track: if item == "userdata": return gpod.sw_get_track_userdata(self._track) elif item in self._proxied_attributes: - return getattr(self._track, item) + if item.startswith("time_"): + return datetime.datetime.fromtimestamp(getattr(self._track, item)) + else: + return getattr(self._track, item) else: raise KeyError('No such key: %s' % item) diff --git a/bindings/python/tests/tests.py b/bindings/python/tests/tests.py index 09c89bf..f52015e 100644 --- a/bindings/python/tests/tests.py +++ b/bindings/python/tests/tests.py @@ -2,6 +2,8 @@ import unittest import shutil import tempfile import os +import datetime +import time import types gpod = __import__('__init__') @@ -63,6 +65,21 @@ class TestiPodFunctions(unittest.TestCase): self.db.remove(track, ipod=True) self.failIf(os.path.exists(track_file)) + def testDatestampSetting(self): + trackname = os.path.join(self.mp, + 'iPod_Control', + 'tiny.mp3') + t = self.db.new_Track(filename=trackname) + date = datetime.datetime.now() + t['time_added'] = date + self.assertEqual(date.year, t['time_added'].year) + self.assertEqual(date.second, t['time_added'].second) + # microsecond won't match, that's lost in the itdb + date = datetime.datetime.now() + t['time_added'] = time.mktime(date.timetuple()) + self.assertEqual(date.year, t['time_added'].year) + self.assertEqual(date.second, t['time_added'].second) + def testVersion(self): self.assertEqual(type(gpod.version_info), types.TupleType) |