changeset 2868:5546613f5007

plugin android: workaround to seek() bug, fixing file upload: seek() is bugged on current version of P4A, arguments are inverted. More details can be found at https://github.com/kivy/python-for-android/issues/1768
author Goffi <goffi@goffi.org>
date Mon, 25 Mar 2019 07:06:41 +0100
parents 3cac3d050046
children 148d30147890
files sat/plugins/plugin_misc_android.py
diffstat 1 files changed, 34 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/sat/plugins/plugin_misc_android.py	Fri Mar 22 19:26:09 2019 +0100
+++ b/sat/plugins/plugin_misc_android.py	Mon Mar 25 07:06:41 2019 +0100
@@ -20,6 +20,7 @@
 import sys
 import os
 import os.path
+import tempfile
 from sat.core.i18n import _, D_
 from sat.core.constants import Const as C
 from sat.core.log import getLogger
@@ -27,6 +28,7 @@
 from twisted.internet import reactor
 from twisted.internet import protocol
 from twisted.internet import error as int_error
+from twisted.web import client as web_client
 
 log = getLogger(__name__)
 
@@ -57,6 +59,38 @@
 STATES = (STATE_RUNNING, STATE_PAUSED, STATE_STOPPED)
 
 
+def determineLength_workaround(self, fObj):
+    """Method working around seek() bug on Android"""
+    try:
+        seek = fObj.seek
+        tell = fObj.tell
+    except AttributeError:
+        return web_client.UNKNOWN_LENGTH
+    originalPosition = tell()
+    seek(os.SEEK_END)
+    end = tell()
+    seek(os.SEEK_SET, originalPosition)
+    return end - originalPosition
+
+
+def patch_seek_bug():
+    """Check seek bug and apply a workaround if still here
+
+    cf. https://github.com/kivy/python-for-android/issues/1768
+    """
+    with tempfile.TemporaryFile() as f:
+        f.write(b'1234567890')
+        f.seek(0, os.SEEK_END)
+        size = f.tell()
+    if size == 10:
+        log.info(u"seek() bug not present anymore, workaround code can be removed")
+    else:
+        log.warning(u"seek() bug detected, applying a workaround")
+        web_client.FileBodyProducer._determineLength = determineLength_workaround
+
+patch_seek_bug()
+
+
 class FrontendStateProtocol(protocol.Protocol):
 
     def __init__(self, android_plugin):