summaryrefslogtreecommitdiffstats
path: root/bindings
diff options
context:
space:
mode:
authorNicholas Piper <nicholas@users.sourceforge.net>2007-08-07 22:48:06 +0000
committerNicholas Piper <nicholas@users.sourceforge.net>2007-08-07 22:48:06 +0000
commitcbf92d9301730f2e729c33237a5c041fd596c9a0 (patch)
treeb5514079171346a5314ed80eb95e944b2f8f48c2 /bindings
parent27ca3160700a9b7a135ed38911bc51318aa1379e (diff)
downloadlibgpod-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.in56
-rw-r--r--bindings/python/gpod.i.in58
-rw-r--r--bindings/python/ipod.py5
-rw-r--r--bindings/python/tests/tests.py17
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)