Revision: 1672
          http://gtkpod.svn.sourceforge.net/gtkpod/?rev=1672&view=rev
Author:   nicholas
Date:     2007-08-07 15:48:06 -0700 (Tue, 07 Aug 2007)

Log Message:
-----------
Try to deal with typestamps in a sane way in the Python bindings

Modified Paths:
--------------
    libgpod/trunk/ChangeLog
    libgpod/trunk/bindings/python/README.in
    libgpod/trunk/bindings/python/gpod.i.in
    libgpod/trunk/bindings/python/ipod.py
    libgpod/trunk/bindings/python/tests/tests.py

Modified: libgpod/trunk/ChangeLog
===================================================================
--- libgpod/trunk/ChangeLog     2007-08-06 14:46:46 UTC (rev 1671)
+++ libgpod/trunk/ChangeLog     2007-08-07 22:48:06 UTC (rev 1672)
@@ -1,3 +1,16 @@
+2007-08-07  Nicholas Piper  <nicholas at users.sourceforge.net>
+
+       * bindings/python/gpod.i.in: Return an integer for time_t (note,
+       no to/from mac timestamp mapping required), accept an integer or
+       datetime object for a time_t
+
+       * bindings/python/ipod.py (Track.__getitem__): for the Python OO
+       interface, map reading time_* attributes in Tracks to a datetime
+       object
+
+       * bindings/python/tests/tests.py 
(TestiPodFunctions.testDatestampSetting): 
+       test reading/writing the Track timestamp attributes
+
 2007-08-04  Todd Zullinger  <tmzullinger at users.sourceforge.net>
 
        * src/db-parse-context.h:

Modified: libgpod/trunk/bindings/python/README.in
===================================================================
--- libgpod/trunk/bindings/python/README.in     2007-08-06 14:46:46 UTC (rev 
1671)
+++ libgpod/trunk/bindings/python/README.in     2007-08-07 22:48:06 UTC (rev 
1672)
@@ -41,3 +41,59 @@
 @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.

Modified: libgpod/trunk/bindings/python/gpod.i.in
===================================================================
--- libgpod/trunk/bindings/python/gpod.i.in     2007-08-06 14:46:46 UTC (rev 
1671)
+++ libgpod/trunk/bindings/python/gpod.i.in     2007-08-07 22:48:06 UTC (rev 
1672)
@@ -56,6 +56,8 @@
 #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 @@
 #ifdef HAVE_GDKPIXBUF
 #ifdef HAVE_PYGOBJECT
    g_type_init ();
+   PyDateTime_IMPORT;
    init_pygobject ();
 #endif
 #endif
@@ -311,9 +314,60 @@
 # 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;
    ival = PyInt_AsUnsignedLongMask($input);

Modified: libgpod/trunk/bindings/python/ipod.py
===================================================================
--- libgpod/trunk/bindings/python/ipod.py       2007-08-06 14:46:46 UTC (rev 
1671)
+++ libgpod/trunk/bindings/python/ipod.py       2007-08-07 22:48:06 UTC (rev 
1672)
@@ -461,7 +461,10 @@
         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)
 

Modified: libgpod/trunk/bindings/python/tests/tests.py
===================================================================
--- libgpod/trunk/bindings/python/tests/tests.py        2007-08-06 14:46:46 UTC 
(rev 1671)
+++ libgpod/trunk/bindings/python/tests/tests.py        2007-08-07 22:48:06 UTC 
(rev 1672)
@@ -2,6 +2,8 @@
 import shutil
 import tempfile
 import os
+import datetime
+import time
 import types
 
 gpod = __import__('__init__')
@@ -63,6 +65,21 @@
             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)


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/
_______________________________________________
gtkpod-cvs2 mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to