From 699cd3f086df741074b1c447aa701f07a6250e94 Mon Sep 17 00:00:00 2001 From: HyTurtle <81598434+HyTurtle@users.noreply.github.com> Date: Wed, 9 Feb 2022 13:42:35 +0000 Subject: [PATCH 01/30] Update gps.py Add onLocationChangedList to account for onLocationChanged method added in API31 --- plyer/platforms/android/gps.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/plyer/platforms/android/gps.py b/plyer/platforms/android/gps.py index 17fd86e97..8ed86d9cd 100644 --- a/plyer/platforms/android/gps.py +++ b/plyer/platforms/android/gps.py @@ -29,6 +29,17 @@ def onLocationChanged(self, location): altitude=location.getAltitude(), accuracy=location.getAccuracy()) + @java_method('(Ljava/util/List;)V', name='onLocationChanged') + def onLocationChangedList(self, location_list): + location = location_list[-1] + self.root.on_location( + lat=location.getLatitude(), + lon=location.getLongitude(), + speed=location.getSpeed(), + bearing=location.getBearing(), + altitude=location.getAltitude(), + accuracy=location.getAccuracy()) + @java_method('(Ljava/lang/String;)V') def onProviderEnabled(self, status): if self.root.on_status: From 1f84fcd24a44877522a8e2edf885c708e8158466 Mon Sep 17 00:00:00 2001 From: HyTurtle <81598434+HyTurtle@users.noreply.github.com> Date: Wed, 9 Feb 2022 14:09:27 +0000 Subject: [PATCH 02/30] Update gps.py java List correction --- plyer/platforms/android/gps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plyer/platforms/android/gps.py b/plyer/platforms/android/gps.py index 8ed86d9cd..30c0a9063 100644 --- a/plyer/platforms/android/gps.py +++ b/plyer/platforms/android/gps.py @@ -31,7 +31,7 @@ def onLocationChanged(self, location): @java_method('(Ljava/util/List;)V', name='onLocationChanged') def onLocationChangedList(self, location_list): - location = location_list[-1] + location = location_list.get(location_list.size() - 1) self.root.on_location( lat=location.getLatitude(), lon=location.getLongitude(), From 04aa4406bcab39fb0a1f71e649cb11a7b2ad42c2 Mon Sep 17 00:00:00 2001 From: HyTurtle <81598434+HyTurtle@users.noreply.github.com> Date: Wed, 25 May 2022 12:16:07 +0100 Subject: [PATCH 03/30] Update gps.py --- plyer/platforms/android/gps.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/plyer/platforms/android/gps.py b/plyer/platforms/android/gps.py index 30c0a9063..cd70bebe8 100644 --- a/plyer/platforms/android/gps.py +++ b/plyer/platforms/android/gps.py @@ -31,14 +31,9 @@ def onLocationChanged(self, location): @java_method('(Ljava/util/List;)V', name='onLocationChanged') def onLocationChangedList(self, location_list): + ''' Called when location data is sent in a batch (API31) ''' location = location_list.get(location_list.size() - 1) - self.root.on_location( - lat=location.getLatitude(), - lon=location.getLongitude(), - speed=location.getSpeed(), - bearing=location.getBearing(), - altitude=location.getAltitude(), - accuracy=location.getAccuracy()) + self.onLocationChanged(location) @java_method('(Ljava/lang/String;)V') def onProviderEnabled(self, status): From 4d323401aafb46651cbf8f1e861786c4953989a9 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sun, 5 Feb 2023 04:54:19 -0500 Subject: [PATCH 04/30] Add Maps example (#742) * Add Maps example * Style changes * Fix E302 --- examples/maps/main.py | 108 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 examples/maps/main.py diff --git a/examples/maps/main.py b/examples/maps/main.py new file mode 100644 index 000000000..cc675fd15 --- /dev/null +++ b/examples/maps/main.py @@ -0,0 +1,108 @@ +from kivy.app import App +from kivy.uix.widget import Widget +from kivy.lang import Builder + +Builder.load_string(''' +#:import maps plyer.maps +: + GridLayout: + cols: 1 + size_hint_y: None + size: root.width, root.height + + TextInput: + id: saddr + hint_text: "Enter Start Address" + background_color: 1,1,1,1 + + TextInput: + id: daddr + hint_text: "Destination address (or leave blank for sliders)" + background_color: 1,1,1,1 + + Label: + text: "Destination by Latitude/Longitude:" + font_size: 40 + color: 0.12156862745098039, 0.9176470588235294, 0, 1 + + GridLayout: + cols: 2 + + Label: + id: lat + text: "Latitude: 0.0" + font_size: 40 + color: 0.12156862745098039, 0.9176470588235294, 0, 1 + + Slider: + id: lat_slider + min: -90 + max: 90 + step: 0.00001 + orientation: "horizontal" + on_value: + lat.text = f"Latitude: {self.value:.5f}" + + Label: + id: long + text: "Longitude: 0.0" + font_size: 40 + color: 0.12156862745098039, 0.9176470588235294, 0, 1 + + Slider: + id: long_slider + min: -180 + max: 180 + step: 0.00001 + orientation: "horizontal" + on_value: + long.text = f"Longitude: {self.value:.5f}" + + FloatLayout: + Button: + text: "Open Maps" + font_name: 'Roboto-Bold' + color: 0.12156862745098039, 0.9176470588235294, 0, 1 + background_color: 1,1,1,1 + background_normal: '' + pos_hint: {'center_x': 0.5, "top": .6} + size_hint: (.6, .4) + on_press: + end = daddr.text if daddr.text != '' \ + else f"{lat_slider.value},{long_slider.value}" + start = saddr.text if saddr.text != '' else 'Here' + maps.route(start, end) + + GridLayout: + cols: 2 + padding: 0, 10 + + TextInput: + id: query + hint_text: "Enter Search Term (e.g. Mexican Restaurants)" + background_color: 1,1,1,1 + + FloatLayout: + Button: + text: "Search on Maps" + font_name: 'Roboto-Bold' + color: 0.12156862745098039, 0.9176470588235294, 0, 1 + background_color: 1,1,1,1 + background_normal: '' + pos_hint: {'center_x': 0.5, "top": .7} + size_hint: (.6, .4) + on_press: + maps.search(query.text) +''') + + +class MainScreen(Widget): + pass + + +class MapsApp(App): + def build(self): + return MainScreen() + + +MapsApp().run() From 36ce4f4e3efd1d6e5c7ec76c44e3c31cc934f6ed Mon Sep 17 00:00:00 2001 From: barries Date: Thu, 16 Feb 2023 16:15:45 -0500 Subject: [PATCH 05/30] YADFileChooser: s/--file-selection/--file/ (#745) YAD removed support for its --file-selection option, which was an alias for --file, in commit 50c964d742 on Aug 4, 2019 (that commit removed all ...-selection aliases). This change passes --file instead, which is present in all versions of YAD on GitHub to date. --- plyer/platforms/linux/filechooser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plyer/platforms/linux/filechooser.py b/plyer/platforms/linux/filechooser.py index cfdb1ae9d..a2c0f5527 100644 --- a/plyer/platforms/linux/filechooser.py +++ b/plyer/platforms/linux/filechooser.py @@ -195,7 +195,7 @@ class YADFileChooser(SubprocessFileChooser): def _gen_cmdline(self): cmdline = [ which(self.executable), - "--file-selection", + "--file", "--confirm-overwrite", "--geometry", "800x600+150+150" From bcba3f37176648f47d9e20c3ff07c88265f35561 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sat, 11 Mar 2023 15:30:49 -0500 Subject: [PATCH 06/30] Add iOS implementation --- plyer/platforms/ios/maps.py | 78 +++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 plyer/platforms/ios/maps.py diff --git a/plyer/platforms/ios/maps.py b/plyer/platforms/ios/maps.py new file mode 100644 index 000000000..88024e570 --- /dev/null +++ b/plyer/platforms/ios/maps.py @@ -0,0 +1,78 @@ +''' +Module of iOS API for plyer.maps. +''' + +import webbrowser +from plyer.facades import Maps +from urllib.parse import quote_plus + + +class iOSMaps(Maps): + ''' + Implementation of iOS Maps API. + ''' + + def _open_by_address(self, address, **kwargs): + ''' + :param address: An address string that geolocation can understand. + ''' + + address = quote_plus(address, safe=',') + maps_address = 'http://maps.apple.com/?address=' + address + + webbrowser.open(maps_address) + + def _open_by_lat_long(self, latitude, longitude, **kwargs): + ''' + Open a coordinate span denoting a latitudinal delta and a + longitudinal delta (similar to MKCoordinateSpan) + + :param name: (optional), will set the name of the dropped pin + ''' + + name = kwargs.get("name", "Selected Location") + maps_address = 'http://maps.apple.com/?ll={},{}&q={}'.format( + latitude, longitude, name) + + webbrowser.open(maps_address) + + def _search(self, query, **kwargs): + ''' + :param query: A string that describes the search object (ex. "Pizza") + + :param latitude: (optional), narrow down query within area, + MUST BE USED WITH LONGITUDE + + :param longitude: (optional), narrow down query within area, + MUST BE USED WITH LATITUDE + ''' + + latitude = kwargs.get('latitude') + longitude = kwargs.get('longitude') + + query = quote_plus(query, safe=',') + maps_address = 'http://maps.apple.com/?q=' + query + + if latitude is not None and longitude is not None: + maps_address += '&sll={},{}'.format(latitude, longitude) + + webbrowser.open(maps_address) + + def _route(self, saddr, daddr, **kwargs): + ''' + :param saddr: can be given as 'address' or 'lat,long' + :param daddr: can be given as 'address' or 'lat,long' + ''' + saddr = quote_plus(saddr, safe=',') + daddr = quote_plus(daddr, safe=',') + + maps_address = 'http://maps.apple.com/?saddr={}&daddr={}'.format( + saddr, daddr) + webbrowser.open(maps_address) + + +def instance(): + ''' + Instance for facade proxy. + ''' + return iOSMaps() From f152489e96281d17c0cad8f46e57924d15452ab4 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sat, 11 Mar 2023 16:00:57 -0500 Subject: [PATCH 07/30] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 000bddc43..1daf5c3f4 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ implement the api in the easiest way, depending on the current platform. | IR Blaster | ✔ | | | | | | Keystore | ✔ | ✔ | ✔ | ✔ | ✔ | | Light | ✔ | | | | | -| Maps | | | | ✔ | | +| Maps | | ✔ | | ✔ | | | Native file chooser | ✔ | ✔ | ✔ | ✔ | ✔ | | Notifications | ✔ | | ✔ | ✔ | ✔ | | Orientation | ✔ | | | | ✔ | From 386f07fb25722aeacce3c970859c376af891b144 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sat, 11 Mar 2023 16:01:45 -0500 Subject: [PATCH 08/30] update supported platforms --- plyer/facades/maps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plyer/facades/maps.py b/plyer/facades/maps.py index cd1804a03..ba8d5fea7 100644 --- a/plyer/facades/maps.py +++ b/plyer/facades/maps.py @@ -31,7 +31,7 @@ Supported Platforms ------------------- -macOS +macOS, iOS --------------- ''' From 76a7f8eff0ce02931402ba23d1a0bb6793e203c8 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Thu, 23 Mar 2023 09:17:05 -0400 Subject: [PATCH 09/30] Fix docs rendering --- plyer/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plyer/__init__.py b/plyer/__init__.py index 7d4ef2717..a66d3e1d4 100644 --- a/plyer/__init__.py +++ b/plyer/__init__.py @@ -123,5 +123,5 @@ #: devicename proxy to :class:`plyer.facades.DeviceName` devicename = Proxy('devicename', facades.DeviceName) -#: Maps proxy to :class: `plyer.facades.Maps` +#: Maps proxy to :class:`plyer.facades.Maps` maps = Proxy('maps', facades.Maps) From a50e355ac6bc05128a4988e7f329b6c6cd0e7f28 Mon Sep 17 00:00:00 2001 From: Dexer <73297572+DexerBR@users.noreply.github.com> Date: Wed, 29 Mar 2023 12:24:49 -0300 Subject: [PATCH 10/30] Fixed issue accessing sd_card path in newer APIs --- plyer/platforms/android/storagepath.py | 34 ++++++++++++++------------ 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/plyer/platforms/android/storagepath.py b/plyer/platforms/android/storagepath.py index 788e3fceb..a2b4c102a 100755 --- a/plyer/platforms/android/storagepath.py +++ b/plyer/platforms/android/storagepath.py @@ -3,14 +3,12 @@ -------------------- ''' -from os import listdir, access, R_OK -from os.path import join from plyer.facades import StoragePath -from jnius import autoclass +from jnius import autoclass, cast from android import mActivity -Environment = autoclass('android.os.Environment') -Context = autoclass('android.content.Context') +Environment = autoclass("android.os.Environment") +Context = autoclass("android.content.Context") class AndroidStoragePath(StoragePath): @@ -25,17 +23,23 @@ def _get_sdcard_dir(self): ''' .. versionadded:: 1.4.0 ''' - # folder in /storage/ that is readable - # and is not internal SD card path = None - for folder in listdir('/storage'): - folder = join('/storage', folder) - if folder in self._get_external_storage_dir(): - continue - if not access(folder, R_OK): - continue - path = folder - break + context = mActivity.getApplicationContext() + storage_manager = cast( + "android.os.storage.StorageManager", + context.getSystemService(Context.STORAGE_SERVICE), + ) + + if storage_manager is not None: + storage_volumes = storage_manager.getStorageVolumes() + for storage_volume in storage_volumes: + if storage_volume.isRemovable(): + try: + directory = storage_volume.getDirectory() + except AttributeError: + directory = storage_volume.getPathFile() + path = directory.getAbsolutePath() + return path def _get_root_dir(self): From 9b65ab43c91291b65a9f197da570c51e40bfb4dc Mon Sep 17 00:00:00 2001 From: Dexer <73297572+DexerBR@users.noreply.github.com> Date: Wed, 29 Mar 2023 14:52:03 -0300 Subject: [PATCH 11/30] update to match sd_card path changes --- plyer/platforms/android/filechooser.py | 29 +++++++++----------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/plyer/platforms/android/filechooser.py b/plyer/platforms/android/filechooser.py index 9dadbba44..edb4158c0 100644 --- a/plyer/platforms/android/filechooser.py +++ b/plyer/platforms/android/filechooser.py @@ -43,7 +43,7 @@ .. versionadded:: 1.4.0 ''' -from os.path import join, basename +from os.path import join from random import randint from android import activity, mActivity @@ -252,28 +252,19 @@ def _handle_external_documents(uri): file_id = DocumentsContract.getDocumentId(uri) file_type, file_name = file_id.split(':') - # internal SD card mostly mounted as a files storage in phone - internal = storagepath.get_external_storage_dir() + primary_storage = storagepath.get_external_storage_dir() + sdcard_storage = storagepath.get_sdcard_dir() - # external (removable) SD card i.e. microSD - external = storagepath.get_sdcard_dir() - try: - external_base = basename(external) - except TypeError: - external_base = basename(internal) + directory = primary_storage - # resolve sdcard path - sd_card = internal - - # because external might have /storage/.../1 or other suffix - # and file_type might be only a part of the real folder in /storage - if file_type in external_base or external_base in file_type: - sd_card = external + if file_type == "primary": + directory = primary_storage elif file_type == "home": - sd_card = join(Environment.getExternalStorageDirectory( - ).getAbsolutePath(), Environment.DIRECTORY_DOCUMENTS) + directory = join(primary_storage, Environment.DIRECTORY_DOCUMENTS) + elif sdcard_storage and file_type in sdcard_storage: + directory = sdcard_storage - return join(sd_card, file_name) + return join(directory, file_name) @staticmethod def _handle_media_documents(uri): From da41ed2bbbeec40cbab89af42ae5cbc3a2f68c46 Mon Sep 17 00:00:00 2001 From: Dexer <73297572+DexerBR@users.noreply.github.com> Date: Wed, 29 Mar 2023 15:20:08 -0300 Subject: [PATCH 12/30] Fixes error when selecting a file from the Documents option in newer APIs --- plyer/platforms/android/filechooser.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/plyer/platforms/android/filechooser.py b/plyer/platforms/android/filechooser.py index 9dadbba44..0f33727ea 100644 --- a/plyer/platforms/android/filechooser.py +++ b/plyer/platforms/android/filechooser.py @@ -62,6 +62,7 @@ IMedia = autoclass('android.provider.MediaStore$Images$Media') VMedia = autoclass('android.provider.MediaStore$Video$Media') AMedia = autoclass('android.provider.MediaStore$Audio$Media') +Files = autoclass('android.provider.MediaStore$Files') FileOutputStream = autoclass('java.io.FileOutputStream') @@ -294,6 +295,11 @@ def _handle_media_documents(uri): uri = VMedia.EXTERNAL_CONTENT_URI elif file_type == 'audio': uri = AMedia.EXTERNAL_CONTENT_URI + + # Other file type was selected (probably in the Documents folder) + else: + uri = Files.getContentUri("external") + return file_name, selection, uri @staticmethod From 5262087c85b2c82c69e702fe944069f1d8465fdf Mon Sep 17 00:00:00 2001 From: SomberNight Date: Thu, 6 Apr 2023 17:05:59 +0000 Subject: [PATCH 13/30] android: fix notification.notify() for sdk>=31, by setting new req flag fixes https://github.com/kivy/plyer/issues/702 see https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability > Pending intents mutability > If your app targets Android 12, you must specify the mutability of > each PendingIntent object that your app creates. This additional > requirement improves your app's security. see https://stackoverflow.com/q/69088578 --- plyer/platforms/android/notification.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plyer/platforms/android/notification.py b/plyer/platforms/android/notification.py index a5113ed64..9e1f25ba1 100644 --- a/plyer/platforms/android/notification.py +++ b/plyer/platforms/android/notification.py @@ -148,10 +148,15 @@ def _set_open_behavior(notification): notification_intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) notification_intent.setAction(Intent.ACTION_MAIN) notification_intent.addCategory(Intent.CATEGORY_LAUNCHER) + if SDK_INT >= 23: + # FLAG_IMMUTABLE added in SDK 23, required since SDK 31: + pending_flags = PendingIntent.FLAG_IMMUTABLE + else: + pending_flags = 0 # get our application Activity pending_intent = PendingIntent.getActivity( - app_context, 0, notification_intent, 0 + app_context, 0, notification_intent, pending_flags ) notification.setContentIntent(pending_intent) From 50806c39724c75ee4529b6cc32b97c267b95d881 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sat, 22 Apr 2023 11:47:38 -0400 Subject: [PATCH 14/30] whoops --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1daf5c3f4..3a106753c 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ implement the api in the easiest way, depending on the current platform. | Orientation | ✔ | | | | ✔ | | Proximity | ✔ | | | | | | Screenshot | | | ✔ | ✔ | ✔ | -| SMS (send messages) | ✔ | ✔ | | | ✔ | +| SMS (send messages) | ✔ | ✔ | | ✔ | | | Spatial Orientation | ✔ | ✔ | | | | | Speech to text | ✔ | | | | | | Storage Path | ✔ | ✔ | ✔ | ✔ | ✔ | From aeac0aaac4e352cf166cd1bf51b825710fa98f6e Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sat, 22 Apr 2023 11:56:52 -0400 Subject: [PATCH 15/30] Revert "whoops" This reverts commit 50806c39724c75ee4529b6cc32b97c267b95d881. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3a106753c..1daf5c3f4 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ implement the api in the easiest way, depending on the current platform. | Orientation | ✔ | | | | ✔ | | Proximity | ✔ | | | | | | Screenshot | | | ✔ | ✔ | ✔ | -| SMS (send messages) | ✔ | ✔ | | ✔ | | +| SMS (send messages) | ✔ | ✔ | | | ✔ | | Spatial Orientation | ✔ | ✔ | | | | | Speech to text | ✔ | | | | | | Storage Path | ✔ | ✔ | ✔ | ✔ | ✔ | From dfc26182c08ed4fbb24219214b718ef938459936 Mon Sep 17 00:00:00 2001 From: Rohan Shah <57906961+rshah713@users.noreply.github.com> Date: Sun, 23 Apr 2023 05:08:54 -0400 Subject: [PATCH 16/30] Fix typo on supported matrix for `SMS` (#760) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 000bddc43..0c03b4e29 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,7 @@ implement the api in the easiest way, depending on the current platform. | Orientation | ✔ | | | | ✔ | | Proximity | ✔ | | | | | | Screenshot | | | ✔ | ✔ | ✔ | -| SMS (send messages) | ✔ | ✔ | | | ✔ | +| SMS (send messages) | ✔ | ✔ | | ✔ | | | Spatial Orientation | ✔ | ✔ | | | | | Speech to text | ✔ | | | | | | Storage Path | ✔ | ✔ | ✔ | ✔ | ✔ | From 0d4135bb26420ad29e8db1f229ac2ff3b1118ba2 Mon Sep 17 00:00:00 2001 From: Andre Miras Date: Tue, 25 Apr 2023 09:38:29 +0200 Subject: [PATCH 17/30] :pencil2: Fix github.ref typo on coverage upload (#762) This led to the coverage never being uploaded for this job --- .github/workflows/ci_ubuntu.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci_ubuntu.yml b/.github/workflows/ci_ubuntu.yml index bade4ae8a..a408a9a8f 100644 --- a/.github/workflows/ci_ubuntu.yml +++ b/.github/workflows/ci_ubuntu.yml @@ -47,7 +47,7 @@ jobs: tests - name: Upload Coverage - if: github.event_name == 'push' && github.ref == 'refs/head/master' + if: github.event_name == 'push' && github.ref == 'refs/heads/master' env: COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} run: | From 9d96fe56f241e03728ec4fffde9b58ddc50f0ee5 Mon Sep 17 00:00:00 2001 From: Dexer <73297572+DexerBR@users.noreply.github.com> Date: Wed, 1 Nov 2023 13:47:56 -0300 Subject: [PATCH 18/30] fix _get_sdcard_dir for Android API < 24 (#781) --- plyer/platforms/android/storagepath.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/plyer/platforms/android/storagepath.py b/plyer/platforms/android/storagepath.py index a2b4c102a..d18ea614f 100755 --- a/plyer/platforms/android/storagepath.py +++ b/plyer/platforms/android/storagepath.py @@ -4,6 +4,7 @@ ''' from plyer.facades import StoragePath +from plyer.platforms.android import SDK_INT from jnius import autoclass, cast from android import mActivity @@ -31,14 +32,20 @@ def _get_sdcard_dir(self): ) if storage_manager is not None: - storage_volumes = storage_manager.getStorageVolumes() - for storage_volume in storage_volumes: - if storage_volume.isRemovable(): - try: - directory = storage_volume.getDirectory() - except AttributeError: - directory = storage_volume.getPathFile() - path = directory.getAbsolutePath() + if SDK_INT >= 24: + storage_volumes = storage_manager.getStorageVolumes() + for storage_volume in storage_volumes: + if storage_volume.isRemovable(): + try: + directory = storage_volume.getDirectory() + except AttributeError: + directory = storage_volume.getPathFile() + path = directory.getAbsolutePath() + else: + storage_volumes = storage_manager.getVolumeList() + for storage_volume in storage_volumes: + if storage_volume.isRemovable(): + path = storage_volume.getPath() return path From 353be52583b128c0a4ecc56416fdffc7ce3280aa Mon Sep 17 00:00:00 2001 From: Xnot <28331593+Xnot@users.noreply.github.com> Date: Wed, 1 Nov 2023 22:45:05 +0000 Subject: [PATCH 19/30] use MaxFile arg to increase buffer instead of artificially inflating the filename --- plyer/platforms/win/filechooser.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plyer/platforms/win/filechooser.py b/plyer/platforms/win/filechooser.py index d61fdc115..8625429b3 100644 --- a/plyer/platforms/win/filechooser.py +++ b/plyer/platforms/win/filechooser.py @@ -41,6 +41,7 @@ class Win32FileChooser: title = None icon = None show_hidden = False + buffer_size = 4096 def __init__(self, *args, **kwargs): self._handle_selection = kwargs.pop( @@ -76,10 +77,7 @@ def run(self): args["Title"] = self.title if self.title else "Pick a file..." args["CustomFilter"] = 'Other file types\x00*.*\x00' args["FilterIndex"] = 1 - file = "" - if "File" in args: - file = args["File"] - args["File"] = file + ("\x00" * 4096) + args["MaxFile"] = self.buffer_size # e.g. open_file(filters=['*.txt', '*.py']) filters = "" From 9c874abc68f7706d959a1350747827479df68c23 Mon Sep 17 00:00:00 2001 From: Dexer <73297572+DexerBR@users.noreply.github.com> Date: Fri, 3 Nov 2023 14:37:38 -0300 Subject: [PATCH 20/30] fix downloads folder issue (#753) --- plyer/platforms/android/filechooser.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/plyer/platforms/android/filechooser.py b/plyer/platforms/android/filechooser.py index a7a8beae7..bcc45ed31 100644 --- a/plyer/platforms/android/filechooser.py +++ b/plyer/platforms/android/filechooser.py @@ -322,6 +322,23 @@ def _handle_downloads_documents(uri): .. versionadded:: 1.4.0 ''' + try: + download_dir = Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_DOWNLOADS + ).getPath() + path = AndroidFileChooser._parse_content( + uri=uri, + projection=["_display_name"], + selection=None, + selection_args=None, + sort_order=None, + ) + return join(download_dir, path) + + except Exception: + import traceback + traceback.print_exc() + # known locations, differ between machines downloads = [ 'content://downloads/public_downloads', From 8c0e11ff2e356ea677e96b0d7907d000c8f4bbd0 Mon Sep 17 00:00:00 2001 From: Julian Date: Fri, 10 Nov 2023 18:37:13 +1100 Subject: [PATCH 21/30] Create `no-response.yml` (#783) Support the no-response bot. Direct copy of the kivy/kivy one. --- .github/workflows/no-response.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/no-response.yml diff --git a/.github/workflows/no-response.yml b/.github/workflows/no-response.yml new file mode 100644 index 000000000..f34d06413 --- /dev/null +++ b/.github/workflows/no-response.yml @@ -0,0 +1,30 @@ +name: No Response + +# Both `issue_comment` and `scheduled` event types are required for this Action +# to work properly. +on: + issue_comment: + types: [created] + schedule: + # Schedule for five minutes after the hour, every hour + - cron: '5 * * * *' + +jobs: + noResponse: + runs-on: ubuntu-latest + steps: + - uses: lee-dohm/no-response@9bb0a4b5e6a45046f00353d5de7d90fb8bd773bb + # This commit hash targets release v0.5.0 of lee-dohm/no-response. + # Targeting a commit hash instead of a tag has been done for security reasons. + # Please be aware that the commit hash specifically targets the "Automatic compilation" + # done by `github-actions[bot]` as the `no-response` Action needs to be compiled. + with: + token: ${{ github.token }} + daysUntilClose: 42 + responseRequiredLabel: 'awaiting-reply' + closeComment: > + This issue has been automatically closed because there has been no response + to our request for more information from the original author. With only the + information that is currently in the issue, we don't have the means + to take action. Please reach out if you have or find the answers we need so + that we can investigate further. From fee1bb2c534904dbc273f5089cac1ce5c267009b Mon Sep 17 00:00:00 2001 From: Julian Date: Fri, 8 Dec 2023 04:40:14 +1100 Subject: [PATCH 22/30] Make doc structure consistent and up-to-date (#786) * Make doc structure consistent and up-to-date This is part of an effort to make the Kivy sibling projects' documentation structure consistent and up-to-date. Unrelated changes: * Readme Copy-edit. Reformat markdown table * RST added structure, including API page * Congrats, promoted from "beta" to "stable" in setup classifiers CHECKLIST * CONTRIBUTING.md [x] If repo takes user contributions, is present [x] In root dir (not .github dir) [x] Refers to kivy/kivy Contribution Guidelines. * LICENSE [x] If repo takes user contributions, is present. [x] Acknowledges the range of years to 2023. [x] Acknowledges Kivy Team and other contributors [x] Mentions it is an MIT License. * CODE_OF_CONDUCT.md [x] If repo takes user contributions or hosts discussions, is present. [x] Refers to kivy/kivy CODE_OF_CONDUCT.md * CONTACT.md [x] Refers to kivy/kivy CONTACT.md * FAQ.md [NA] If repo is big enough for RST documentation, is present. (RST documentation exists but is trivial) * README: [x] Is a Markdown file. [x] Describes the project. [x] Describes its place in the Kivy sibling projects. [x] If CONTRIBUTING exists, mentions it. [x] If LICENSE exists, mentions it. [x] If CODE_OF_CONDUCT exists, mentions it. [x] Mentions kivy/kivy CONTACT.md [NA] Uses Python syntax colouring for embedded Python code. [x] Uses badges to display current status. * RST documentation, if present [x] Describes the project. [x] Describes its place in the Kivy sibling projects. [x] Mentions LICENSE. [x] Mentions CONTRIBUTING [NA] Mentions FAQ [x] conf.py mentioned Kivy Team and other contributors - copyright, latex_documents, man_pages, texinfo documents * WORKFLOWS [x] NO_RESPONSE.yml is present if the repo has awaiting_reply tag. [x] NO_RESPONSE uses latest script versions. [x] SUPPORT.yml is present if the repo has a `support` tag. [x] SUPPORT.yml refers to kivy/kivy CONTACT.md * setup.py/cfg, if present and on PyPI [x] Supplies description to PyPI [x] Supplies Python versions to PyPI [x] Supplies Documentation, if any, to PyPI * PEP8 fixes Fixed some I am reasponsible for (setup and conf), and some I am not responsible for (space before line continuation) but did not fix all I wasn't responsible for. * Updated according to new checklist Includes adding FAQ. This is part of an effort to make the Kivy sibling projects' documentation structure consistent and up-to-date. CHECKLIST * CONTRIBUTING.md [x] If repo takes user contributions, is present [x] In root dir (not .github dir) [x] Explains relationship to Kivy, if unclear. [x] Refers to kivy/kivy Contribution Guidelines. * LICENSE [x] If repo takes user contributions, is present. [x] Acknowledges the range of years to 2023. [x] Acknowledges Kivy Team and other contributors [x] Mentions it is an MIT License. * CODE_OF_CONDUCT.md [x] If repo takes user contributions or hosts discussions, is present. [x] Refers to kivy/kivy CODE_OF_CONDUCT.md * CONTACT.md [x] Refers to kivy/kivy CONTACT.md * FAQ.md [x] If repo is big enough for RST documentation, is present. * README: [x] Is a Markdown file. [x] Describes the project. [x] Describes its place in the Kivy sibling projects. [x] If Documentation exists, mention it. [x] If CONTRIBUTING exists, mentions it. [x] If LICENSE exists, mentions it. [x] If CODE_OF_CONDUCT exists, mentions it. [x] Mentions kivy/kivy CONTACT.md [NA] Uses Python syntax colouring for embedded Python code. [x] Uses badges to display current status, including: [x] Backers [x] Sponsors [x] GitHub contributors [x] Contributor Covenant [x] PyPI Version [x] PyPI Python Version [x] Build/Test status [x] Displays all contributors to the repo. [x] Displays backers [x] Displays top sponsors. * RST documentation, if present [x] Describes the project. [x] Describes its place in the Kivy sibling projects. [x] Mentions (Kivy/Kivy) Contact Us link. [x] Mentions LICENSE. [x] Mentions CONTRIBUTING [x] Mentions FAQ [x] conf.py mentioned Kivy Team and other contributors - copyright, latex_documents, man_pages, texinfo documents * WORKFLOWS [x] NO_RESPONSE.yml is present if the repo has awaiting_reply tag. [x] NO_RESPONSE uses latest script versions. [x] SUPPORT.yml is present if the repo has a `support` tag. [x] SUPPORT.yml refers to repo's CONTACT.md * setup.py/cfg, if present and on PyPI [x] Supplies description to PyPI [x] Supplies Python versions to PyPI [x] Supplies Documentation, if any, to PyPI * Review comments * PEP8 Was bitten by PEP's 79 versus 80 width. Decided to fix one more style-failure-that-wasn't-my-fault while I was here - redid the imports on garden.graph. (Bring on `black`!) --- .github/workflows/support.yml | 27 +++ CODE_OF_CONDUCT.md | 8 + CONTACT.md | 8 + CONTRIBUTING.md | 10 + FAQ.md | 13 ++ LICENSE | 4 +- README.md | 197 +++++++++++------- docs/source/api.rst | 11 + docs/source/conf.py | 13 +- docs/source/contact.rst | 8 + docs/source/contribute.rst | 14 ++ docs/source/faq.rst | 7 + docs/source/index.rst | 25 ++- .../libs/garden/garden.graph/__init__.py | 28 ++- examples/compass/main.py | 2 +- examples/gyroscope/main.py | 2 +- setup.py | 10 +- 17 files changed, 277 insertions(+), 110 deletions(-) create mode 100644 .github/workflows/support.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTACT.md create mode 100644 CONTRIBUTING.md create mode 100644 FAQ.md create mode 100644 docs/source/api.rst create mode 100644 docs/source/contact.rst create mode 100644 docs/source/contribute.rst create mode 100644 docs/source/faq.rst diff --git a/.github/workflows/support.yml b/.github/workflows/support.yml new file mode 100644 index 000000000..944addf4c --- /dev/null +++ b/.github/workflows/support.yml @@ -0,0 +1,27 @@ +name: 'Support Requests' + +on: + issues: + types: [labeled, unlabeled, reopened] + +permissions: + issues: write + +jobs: + action: + runs-on: ubuntu-latest + steps: + - uses: dessant/support-requests@v4 + with: + github-token: ${{ github.token }} + support-label: 'support' + issue-comment: > + 👋 We use the issue tracker exclusively for bug reports and feature requests. + However, this issue appears to be a support request. Please use our + [support channels](https://github.com/kivy/plyer/blob/master/CONTACT.md) + to get help with the project. + + Let us know if this comment was made in error, and we'll be happy + to reopen the issue. + close-issue: true + lock-issue: false diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..29d18faa2 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,8 @@ +In the interest of fostering an open and welcoming community, we as +contributors and maintainers need to ensure participation in our project and +our sister projects is a harassment-free and positive experience for everyone. +It is vital that all interaction is conducted in a manner conveying respect, +open-mindedness and gratitude. + +Please consult the [latest Kivy Code of Conduct](https://github.com/kivy/kivy/blob/master/CODE_OF_CONDUCT.md). + diff --git a/CONTACT.md b/CONTACT.md new file mode 100644 index 000000000..a98bb331a --- /dev/null +++ b/CONTACT.md @@ -0,0 +1,8 @@ +.. _contact: + +Contact Us +========== + +If you are looking to contact the Kivy Team (who are responsible for managing the +Plyer project), including looking for support, please see our +`latest contact details `_. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..eccdf08d0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# Contribution Guidelines + +Plyer is part of the [Kivy](https://kivy.org) ecosystem - a large group of +products used by many thousands of developers for free, but it +is built entirely by the contributions of volunteers. We welcome (and rely on) +users who want to give back to the community by contributing to the project. + +Contributions can come in many forms. See the latest +[Contribution Guidelines](https://github.com/kivy/kivy/blob/master/CONTRIBUTING.md) +for how you can help us. diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 000000000..8d6ee2edc --- /dev/null +++ b/FAQ.md @@ -0,0 +1,13 @@ +# FAQ for Plyer + +## Introduction + +Plyer is a platform-independent Python API for accessing hardware features +of various platforms (Android, iOS, macOS, Linux and Windows). + +Plyer is managed by the [Kivy Team](https://kivy.org/about.html). It is suitable for +use with Kivy apps, but can be used independently. + +## No questions yet + +No Frequently Asked Questions have been identified yet. Please contribute some. diff --git a/LICENSE b/LICENSE index d5d6b13c8..4e3506010 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,6 @@ -Copyright (c) 2010-2017 Kivy Team and other contributors +MIT License + +Copyright (c) 2010-2023 Kivy Team and other contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 3a106753c..0afa8a518 100644 --- a/README.md +++ b/README.md @@ -1,134 +1,171 @@ # Plyer -Plyer is a platform-independent api to use features commonly found on various -platforms, notably mobile ones, in Python. +Plyer is a platform-independent Python API for accessing hardware features +of various platforms (Android, iOS, macOS, Linux and Windows). + +Plyer is managed by the [Kivy Team](https://kivy.org/about.html). It is suitable for +use with Kivy apps, but can be used independently. -[![coverage](https://coveralls.io/repos/kivy/plyer/badge.svg?branch=master)](https://coveralls.io/r/kivy/plyer?branch=master) [![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](#sponsors) -![Continuous Integration with Ubuntu](https://github.com/kivy/plyer/workflows/Continuous%20Integration%20with%20Ubuntu/badge.svg) +[![GitHub contributors](https://img.shields.io/github/contributors-anon/kivy/plyer)](https://github.com/kivy/plyer/graphs/contributors) +[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](code_of_conduct.md) + + +![PyPI - Version](https://img.shields.io/pypi/v/plyer) +![PyPI - Python Version](https://img.shields.io/pypi/pyversions/plyer) + + +[![coverage](https://coveralls.io/repos/kivy/plyer/badge.svg?branch=master)](https://coveralls.io/r/kivy/plyer?branch=master) +![Continuous Integration with Ubuntu](https://github.com/kivy/plyer/workflows/Continuous%20Integration%20with%20Ubuntu/badge.svg) ![Continuous Integration with OSX](https://github.com/kivy/plyer/workflows/Continuous%20Integration%20with%20OSX/badge.svg) ![Continuous Integration with Windows](https://github.com/kivy/plyer/workflows/Continuous%20Integration%20with%20Windows/badge.svg) ![Deploy to PyPI](https://github.com/kivy/plyer/workflows/Deploy%20to%20PyPI/badge.svg) - ## How plyer works? -Plyer tries not to reinvent the wheel, and will call for external libraries to -implement the api in the easiest way, depending on the current platform. +Plyer tries not to reinvent the wheel, and will call external libraries to +implement the API in the easiest way, depending on the current platform. -- On Android(python-for-android), pyjnius is used -- On iOS(kivy-ios), pyobjus is used -- On windows/mac/linux, commonly found libraries and programs will be used +- On Android ([python-for-android](https://python-for-android.readthedocs.io/)), [PyJNIus](https://pypi.org/project/pyjnius/) is used. +- On iOS ([kivy-ios](https://pypi.org/project/kivy-ios/)) and macOS, + [pyobjus](https://pypi.org/project/pyobjus/) is used. +- On Windows, macOS and Linux, other commonly found libraries and programs + are used. ## Supported APIs -| Platform | Android | iOS | Windows | OS X | Linux | -| ------------------------------ | ------- | --- | ------- | ---- | ----- | -| Accelerometer | ✔ | ✔ | | ✔ | ✔ | -| Audio recording | ✔ | | ✔ | ✔ | | -| Barometer | ✔ | ✔ | | | | -| Battery | ✔ | ✔ | ✔ | ✔ | ✔ | -| Bluetooth | ✔ | | | ✔ | | -| Brightness | ✔ | ✔ | | | ✔ | -| Call | ✔ | ✔ | | | | -| Camera (taking picture) | ✔ | ✔ | | | | -| Compass | ✔ | ✔ | | | | -| CPU count | | | ✔ | ✔ | ✔ | -| Devicename | ✔ | | ✔ | ✔ | ✔ | -| Email (open mail client) | ✔ | ✔ | ✔ | ✔ | ✔ | -| Flash | ✔ | ✔ | | | | -| GPS | ✔ | ✔ | | | | -| Gravity | ✔ | ✔ | | | | -| Gyroscope | ✔ | ✔ | | | | -| Humidity | ✔ | | | | | -| IR Blaster | ✔ | | | | | -| Keystore | ✔ | ✔ | ✔ | ✔ | ✔ | -| Light | ✔ | | | | | -| Maps | | ✔ | | ✔ | | -| Native file chooser | ✔ | ✔ | ✔ | ✔ | ✔ | -| Notifications | ✔ | | ✔ | ✔ | ✔ | -| Orientation | ✔ | | | | ✔ | -| Proximity | ✔ | | | | | -| Screenshot | | | ✔ | ✔ | ✔ | -| SMS (send messages) | ✔ | ✔ | | ✔ | | -| Spatial Orientation | ✔ | ✔ | | | | -| Speech to text | ✔ | | | | | -| Storage Path | ✔ | ✔ | ✔ | ✔ | ✔ | -| Temperature | ✔ | | | | | -| Text to speech | ✔ | ✔ | ✔ | ✔ | ✔ | -| Unique ID | ✔ | ✔ | ✔ | ✔ | ✔ | -| Vibrator | ✔ | ✔ | | | | -| Wifi | | | ✔ | ✔ | ✔ | - +| Platform | Android | iOS | Windows | macOS | Linux | +| ------------------------------ |:-------:|:---:|:-------:|:-----:|:-----:| +| Accelerometer | ✔ | ✔ | | ✔ | ✔ | +| Audio recording | ✔ | | ✔ | ✔ | | +| Barometer | ✔ | ✔ | | | | +| Battery | ✔ | ✔ | ✔ | ✔ | ✔ | +| Bluetooth | ✔ | | | ✔ | | +| Brightness | ✔ | ✔ | | | ✔ | +| Call | ✔ | ✔ | | | | +| Camera (taking picture) | ✔ | ✔ | | | | +| Compass | ✔ | ✔ | | | | +| CPU count | | | ✔ | ✔ | ✔ | +| Devicename | ✔ | | ✔ | ✔ | ✔ | +| Email (open mail client) | ✔ | ✔ | ✔ | ✔ | ✔ | +| Flash | ✔ | ✔ | | | | +| GPS | ✔ | ✔ | | | | +| Gravity | ✔ | ✔ | | | | +| Gyroscope | ✔ | ✔ | | | | +| Humidity | ✔ | | | | | +| IR Blaster | ✔ | | | | | +| Keystore | ✔ | ✔ | ✔ | ✔ | ✔ | +| Light | ✔ | | | | | +| Maps | | ✔ | | ✔ | | +| Native file chooser | ✔ | ✔ | ✔ | ✔ | ✔ | +| Notifications | ✔ | | ✔ | ✔ | ✔ | +| Orientation | ✔ | | | | ✔ | +| Proximity | ✔ | | | | | +| Screenshot | | | ✔ | ✔ | ✔ | +| SMS (send messages) | ✔ | ✔ | | ✔ | | +| Spatial Orientation | ✔ | ✔ | | | | +| Speech to text | ✔ | | | | | +| Storage Path | ✔ | ✔ | ✔ | ✔ | ✔ | +| Temperature | ✔ | | | | | +| Text to speech | ✔ | ✔ | ✔ | ✔ | ✔ | +| Unique ID | ✔ | ✔ | ✔ | ✔ | ✔ | +| Vibrator | ✔ | ✔ | | | | +| Wifi | | | ✔ | ✔ | ✔ | + +## Documentation + +Full documentation, including details about the API, is available +[online](https://plyer.readthedocs.io/en/latest/). If you are not using the +latest version of Plyer, earlier versions of the documentations are linked +from there. ## Installation To use on desktop: `pip install plyer` -To use in python-for-android/kivy-ios: add `plyer` to your requirements if needed. - -## Support +To use in python-for-android and Kivy for iOS, add `plyer` to your requirements +if needed. -If you need assistance, you can ask for help on our mailing list: +## License -* User Group : https://groups.google.com/group/kivy-users -* Email : kivy-users@googlegroups.com +Plyer is [MIT licensed](LICENSE), actively developed by a great +community and is supported by many projects managed by the +[Kivy Organization](https://www.kivy.org/about.html). -Discord channel: +## Support -* Server : https://chat.kivy.org -* Channel : #dev +Are you having trouble using Plyer or any of its related projects in the Kivy +ecosystem? +Is there an error you don’t understand? Are you trying to figure out how to use +it? We have volunteers who can help! +The best channels to contact us for support are listed in the latest +[Contact Us](https://github.com/kivy/plyer/blob/master/CONTACT.md) document. ## Contributing -We love pull requests and discussing novel ideas. Check out our -[contribution guide](http://kivy.org/docs/contribute.html) and -feel free to improve Plyer. - -The following mailing list and IRC channel are used exclusively for -discussions about developing the Kivy framework and its sister projects: +Plyer is part of the [Kivy](https://kivy.org) ecosystem - a large group of +products used by many thousands of developers for free, but it +is built entirely by the contributions of volunteers. We welcome (and rely on) +users who want to give back to the community by contributing to the project. -* Dev Group : https://groups.google.com/group/kivy-dev -* Email : kivy-dev@googlegroups.com +Contributions can come in many forms. See the latest +[Contribution Guidelines](https://github.com/kivy/plyer/blob/master/CONTRIBUTING.md) +for how you can help us. -IRC channel: +## Code of Conduct -* Server : irc.freenode.net -* Port : 6667, 6697 (SSL only) -* Channel : #kivy-dev - - -## License +In the interest of fostering an open and welcoming community, we as +contributors and maintainers need to ensure participation in our project and +our sister projects is a harassment-free and positive experience for everyone. +It is vital that all interaction is conducted in a manner conveying respect, +open-mindedness and gratitude. -Plyer is released under the terms of the MIT License. Please refer to the -LICENSE file. +Please consult the [latest Code of Conduct](https://github.com/kivy/plyer/blob/master/CODE_OF_CONDUCT.md). ## Contributors -This project exists thanks to all the people who contribute. [[Contribute](http://kivy.org/docs/contribute.html)]. +This project exists thanks to +[all the people who contribute](https://github.com/kivy/plyer/graphs/contributors). +[[Become a contributor](CONTRIBUTING.md)]. - + ## Backers -Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/kivy#backer)] - - +Thank you to [all of our backers](https://opencollective.com/kivy)! +🙏 [[Become a backer](https://opencollective.com/kivy#backer)] + ## Sponsors -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/kivy#sponsor)] +Special thanks to +[all of our sponsors, past and present](https://opencollective.com/kivy). +Support this project by +[[becoming a sponsor](https://opencollective.com/kivy#sponsor)]. + +Here are our top current sponsors. Please click through to see their websites, +and support them as they support us. + + + + + + + + + + diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 000000000..7be16c4fe --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,11 @@ + +.. _api: + +API +=== + +.. automodule:: plyer + :members: + +.. automodule:: plyer.facades + :members: diff --git a/docs/source/conf.py b/docs/source/conf.py index e08f9fe20..68248b87e 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -43,7 +43,7 @@ # General information about the project. project = u'Plyer' -copyright = u'2013, Mathieu Virbel, Akshay Aurora, Gabriel Petier, Ben Rousch' +copyright = u'2013-2023, Kivy Team and other contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -189,7 +189,7 @@ # (source start file, target name, title, author, documentclass [howto/manual]) latex_documents = [( 'index', 'Plyer.tex', u'Plyer Documentation', - u'Mathieu Virbel, Akshay Aurora, Gabriel Petier, Ben Rousch', 'manual' + u'Kivy Team and other contributors', 'manual' ), ] # The name of an image file (relative to this directory) to place at the top of @@ -219,7 +219,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'plyer', u'Plyer Documentation', - [u'Mathieu Virbel, Akshay Aurora, Gabriel Petier, Ben Rousch'], 1) + [u'Kivy Team and other contributors'], 1) ] # If true, show URL addresses after external links. @@ -233,8 +233,11 @@ # dir menu entry, description, category) texinfo_documents = [( 'index', 'Plyer', u'Plyer Documentation', - u'Mathieu Virbel, Akshay Aurora, Gabriel Petier, Ben Rousch', - 'Plyer', 'One line description of project.', 'Miscellaneous' + u'Kivy Team and other contributors', + 'Plyer', + 'Plyer is a platform-independent Python API for accessing hardware ' + 'features of various platforms (Android, iOS, macOS, Linux and Windows).', + 'Miscellaneous' ), ] # Documents to append as an appendix to all manuals. diff --git a/docs/source/contact.rst b/docs/source/contact.rst new file mode 100644 index 000000000..d57f1ebea --- /dev/null +++ b/docs/source/contact.rst @@ -0,0 +1,8 @@ +.. _contact: + +Contact Us +========== + +If you are looking to contact the Kivy Team (who are responsible for managing the +Plyer project), including looking for support, please see our +`latest contact details `_. \ No newline at end of file diff --git a/docs/source/contribute.rst b/docs/source/contribute.rst new file mode 100644 index 000000000..651b6a7ea --- /dev/null +++ b/docs/source/contribute.rst @@ -0,0 +1,14 @@ +.. _contribute: + +Contribution Guidelines +======================= + + +Plyer is part of the `Kivy `_ ecosystem - a large group of +products used by many thousands of developers for free, but it +is built entirely by the contributions of volunteers. We welcome (and rely on) +users who want to give back to the community by contributing to the project. + +Contributions can come in many forms. See the latest +[Contribution Guidelines](https://github.com/kivy/plyer/blob/master/CONTRIBUTING.md) +for general guidelines of how you can help us. \ No newline at end of file diff --git a/docs/source/faq.rst b/docs/source/faq.rst new file mode 100644 index 000000000..55ec8476e --- /dev/null +++ b/docs/source/faq.rst @@ -0,0 +1,7 @@ +.. _faq: + +FAQ +=== + +Plyer has an `online FAQ `_. It contains the answers to +questions that repeatedly come up. diff --git a/docs/source/index.rst b/docs/source/index.rst index 20ae9d6f9..57893003e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,18 +1,23 @@ -.. Plyer documentation master file, created by - sphinx-quickstart on Wed Jul 3 15:18:02 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - Welcome to Plyer ================ -Plyer is a Python library for accessing features of your hardware / platforms. +Plyer is a platform-independent Python API for accessing hardware features +of various platforms (Android, iOS, macOS, Linux and Windows). + +Plyer is managed by the `Kivy Team ` +and is suitable for use with Kivy apps. + +Plyer is released and distributed under the terms of the MIT license. Our +`latest license `_ +is available. -.. automodule:: plyer - :members: +.. toctree:: + :maxdepth: 2 -.. automodule:: plyer.facades - :members: + api + contact + contribute + faq Indices and tables ================== diff --git a/examples/accelerometer/using_graph/libs/garden/garden.graph/__init__.py b/examples/accelerometer/using_graph/libs/garden/garden.graph/__init__.py index 841e83536..28a28e0a9 100644 --- a/examples/accelerometer/using_graph/libs/garden/garden.graph/__init__.py +++ b/examples/accelerometer/using_graph/libs/garden/garden.graph/__init__.py @@ -47,20 +47,28 @@ __all__ = ('Graph', 'Plot', 'MeshLinePlot', 'MeshStemPlot') from math import radians -from kivy.uix.widget import Widget -from kivy.uix.label import Label -from kivy.uix.stencilview import StencilView -from kivy.properties import NumericProperty, BooleanProperty,\ - BoundedNumericProperty, StringProperty, ListProperty, ObjectProperty,\ - DictProperty, AliasProperty +from math import log10, floor, ceil +from decimal import Decimal + +from kivy import metrics from kivy.clock import Clock +from kivy.event import EventDispatcher from kivy.graphics import Mesh, Color from kivy.graphics.transformation import Matrix -from kivy.event import EventDispatcher from kivy.lang import Builder -from kivy import metrics -from math import log10, floor, ceil -from decimal import Decimal +from kivy.properties import ( + NumericProperty, + BooleanProperty, + BoundedNumericProperty, + StringProperty, + ListProperty, + ObjectProperty, + DictProperty, + AliasProperty, +) +from kivy.uix.label import Label +from kivy.uix.stencilview import StencilView +from kivy.uix.widget import Widget Builder.load_string(''' #:kivy 1.1.0 diff --git a/examples/compass/main.py b/examples/compass/main.py index 6a4de0c87..a2bdaa59b 100644 --- a/examples/compass/main.py +++ b/examples/compass/main.py @@ -101,7 +101,7 @@ def get_field(self, dt): def get_field_uncalib(self, dt): if self.facade.field_uncalib != (None, None, None, None, None, None): - self.x_field, self.y_field, self.z_field, self.x_iron,\ + self.x_field, self.y_field, self.z_field, self.x_iron, \ self.y_iron, self.z_iron = self.facade.field_uncalib diff --git a/examples/gyroscope/main.py b/examples/gyroscope/main.py index 636457303..31d2d5bf2 100644 --- a/examples/gyroscope/main.py +++ b/examples/gyroscope/main.py @@ -98,7 +98,7 @@ def get_rotation_uncalib(self, dt): empty = tuple([None for i in range(6)]) if self.facade.rotation_uncalib != empty: - self.x_speed, self.y_speed, self.z_speed, self.x_drift,\ + self.x_speed, self.y_speed, self.z_speed, self.x_drift, \ self.y_drift, self.z_drift = self.facade.rotation_uncalib diff --git a/setup.py b/setup.py index 1467e9245..80f65af73 100644 --- a/setup.py +++ b/setup.py @@ -56,7 +56,8 @@ setup( name='plyer', version=plyer.__version__, - description='Platform-independent wrapper for platform-dependent APIs', + description='A platform-independent Python API for accessing hardware' + 'features of various platforms (Android, iOS, macOS, Linux and Windows).', long_description=README + u"\n\n" + CHANGELOG + u"\n\n", long_description_content_type='text/markdown', author='Kivy team', @@ -69,7 +70,7 @@ license='MIT', zip_safe=False, classifiers=[ - 'Development Status :: 4 - Beta', + 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Natural Language :: English', 'License :: OSI Approved :: MIT License', @@ -81,5 +82,10 @@ 'Programming Language :: Python :: 3.10', 'Programming Language :: Python :: 3.11', ], + project_urls={ + 'Documentation': "https://plyer.readthedocs.io", + 'Source': "https://github.com/kivy/plyer", + 'Bug Reports': "https://github.com/kivy/plyer/issues", + }, **EXTRA_OPTIONS ) From d16addd9d950105da664c4c5963d3d922cd5263b Mon Sep 17 00:00:00 2001 From: Mirko Galimberti Date: Fri, 8 Dec 2023 10:01:17 +0100 Subject: [PATCH 23/30] Add (now mandatory) `.readthedocs.yaml` file, add docs extras and update sphinx conf (#787) --- .readthedocs.yaml | 16 ++++++++++++++++ docs/requirements.txt | 2 ++ docs/source/conf.py | 37 ++++++++++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 docs/requirements.txt diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..1aed295c8 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,16 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3" + +python: + install: + - requirements: docs/requirements.txt + +sphinx: + configuration: docs/source/conf.py \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 000000000..2a72e6870 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +Sphinx~=7.2.6 +furo==2023.9.10 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 68248b87e..f898c84c2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -11,9 +11,10 @@ # All configuration values have a default; values that are commented out # serve to show the default. +import datetime import os +import re import sys -import plyer # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -42,17 +43,35 @@ master_doc = 'index' # General information about the project. -project = u'Plyer' -copyright = u'2013-2023, Kivy Team and other contributors' +project = 'Plyer' + +_today = datetime.datetime.now() + +author = "Kivy Team and other contributors" + +copyright = f'{_today.year}, {author}' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # + +# Lookup the version from the pyjnius module, without installing it +# since readthedocs.org may have issue to install it. +# Read the version from the __init__.py file, without importing it. +def get_version(): + with open( + os.path.join(os.path.abspath("../.."), "plyer", "__init__.py") + ) as fp: + for line in fp: + m = re.search(r'^\s*__version__\s*=\s*([\'"])([^\'"]+)\1\s*$', line) + if m: + return m.group(2) + # The short X.Y version. -version = plyer.__version__ +version = get_version() # The full version, including alpha/beta/rc tags. -release = plyer.__version__ +release = get_version() # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -96,7 +115,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = 'furo' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -189,7 +208,7 @@ # (source start file, target name, title, author, documentclass [howto/manual]) latex_documents = [( 'index', 'Plyer.tex', u'Plyer Documentation', - u'Kivy Team and other contributors', 'manual' + author, 'manual' ), ] # The name of an image file (relative to this directory) to place at the top of @@ -219,7 +238,7 @@ # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'plyer', u'Plyer Documentation', - [u'Kivy Team and other contributors'], 1) + [author], 1) ] # If true, show URL addresses after external links. @@ -233,7 +252,7 @@ # dir menu entry, description, category) texinfo_documents = [( 'index', 'Plyer', u'Plyer Documentation', - u'Kivy Team and other contributors', + author, 'Plyer', 'Plyer is a platform-independent Python API for accessing hardware ' 'features of various platforms (Android, iOS, macOS, Linux and Windows).', From 47fbce1feb49828c300acca5933be0ca970a33f5 Mon Sep 17 00:00:00 2001 From: Mirko Galimberti Date: Fri, 8 Dec 2023 15:36:36 +0100 Subject: [PATCH 24/30] Fix pep8 failures, and apply black formatting where applicable. (#788) --- docs/source/conf.py | 7 ++++++- plyer/platforms/android/filechooser.py | 16 ++++++++++------ plyer/platforms/linux/filechooser.py | 6 +++--- plyer/platforms/macosx/filechooser.py | 2 +- plyer/platforms/win/filechooser.py | 2 +- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index f898c84c2..fcda58aaa 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -56,6 +56,7 @@ # built documents. # + # Lookup the version from the pyjnius module, without installing it # since readthedocs.org may have issue to install it. # Read the version from the __init__.py file, without importing it. @@ -64,10 +65,14 @@ def get_version(): os.path.join(os.path.abspath("../.."), "plyer", "__init__.py") ) as fp: for line in fp: - m = re.search(r'^\s*__version__\s*=\s*([\'"])([^\'"]+)\1\s*$', line) + m = re.search( + r'^\s*__version__\s*=\s*([\'"])([^\'"]+)\1\s*$', + line, + ) if m: return m.group(2) + # The short X.Y version. version = get_version() # The full version, including alpha/beta/rc tags. diff --git a/plyer/platforms/android/filechooser.py b/plyer/platforms/android/filechooser.py index bcc45ed31..b8c943cf3 100644 --- a/plyer/platforms/android/filechooser.py +++ b/plyer/platforms/android/filechooser.py @@ -143,9 +143,11 @@ def _open_file(self, **kwargs): # create Intent for opening file_intent = Intent(Intent.ACTION_GET_CONTENT) - if not self.selected_mime_type or \ - type(self.selected_mime_type) != str or \ - self.selected_mime_type not in self.mime_type: + if ( + not self.selected_mime_type + or not isinstance(self.selected_mime_type, str) + or self.selected_mime_type not in self.mime_type + ): file_intent.setType("*/*") else: file_intent.setType(self.mime_type[self.selected_mime_type]) @@ -176,9 +178,11 @@ def _save_file(self, **kwargs): kwargs.pop("filters")[0] if "filters" in kwargs else "" file_intent = Intent(Intent.ACTION_CREATE_DOCUMENT) - if not self.selected_mime_type or \ - type(self.selected_mime_type) != str or \ - self.selected_mime_type not in self.mime_type: + if ( + not self.selected_mime_type + or not isinstance(self.selected_mime_type, str) + or self.selected_mime_type not in self.mime_type + ): file_intent.setType("*/*") else: file_intent.setType(self.mime_type[self.selected_mime_type]) diff --git a/plyer/platforms/linux/filechooser.py b/plyer/platforms/linux/filechooser.py index a2c0f5527..e4ac8570e 100644 --- a/plyer/platforms/linux/filechooser.py +++ b/plyer/platforms/linux/filechooser.py @@ -122,7 +122,7 @@ def _gen_cmdline(self): if self.icon: cmdline += ["--window-icon", self.icon] for f in self.filters: - if type(f) == str: + if isinstance(f, str): cmdline += ["--file-filter", f] else: cmdline += [ @@ -150,7 +150,7 @@ def _gen_cmdline(self): filt = [] for f in self.filters: - if type(f) == str: + if isinstance(f, str): filt += [f] else: filt += list(f[1:]) @@ -215,7 +215,7 @@ def _gen_cmdline(self): if self.icon: cmdline += ["--window-icon", self.icon] for f in self.filters: - if type(f) == str: + if isinstance(f, str): cmdline += ["--file-filter", f] else: cmdline += [ diff --git a/plyer/platforms/macosx/filechooser.py b/plyer/platforms/macosx/filechooser.py index 85fb91c76..38ab99d01 100644 --- a/plyer/platforms/macosx/filechooser.py +++ b/plyer/platforms/macosx/filechooser.py @@ -80,7 +80,7 @@ def run(self): if self.filters: filthies = [] for f in self.filters: - if type(f) == str: + if isinstance(f, str): f = (None, f) for s in f[1:]: if not self.use_extensions: diff --git a/plyer/platforms/win/filechooser.py b/plyer/platforms/win/filechooser.py index d61fdc115..8a26fe3c9 100644 --- a/plyer/platforms/win/filechooser.py +++ b/plyer/platforms/win/filechooser.py @@ -84,7 +84,7 @@ def run(self): # e.g. open_file(filters=['*.txt', '*.py']) filters = "" for f in self.filters: - if type(f) == str: + if isinstance(f, str): filters += (f + "\x00") * 2 else: filters += f[0] + "\x00" + ";".join(f[1:]) + "\x00" From ceafe1bd522662108120131bcd2851c02443557d Mon Sep 17 00:00:00 2001 From: Xnot <28331593+Xnot@users.noreply.github.com> Date: Fri, 29 Dec 2023 01:26:27 +0000 Subject: [PATCH 25/30] normalize path when passing args to windows filechooser --- plyer/platforms/win/filechooser.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plyer/platforms/win/filechooser.py b/plyer/platforms/win/filechooser.py index 8a26fe3c9..688b361d0 100644 --- a/plyer/platforms/win/filechooser.py +++ b/plyer/platforms/win/filechooser.py @@ -12,7 +12,7 @@ import win32gui import win32con import pywintypes -from os.path import dirname, splitext, join, isdir +from os.path import dirname, splitext, join, isdir, normpath class Win32FileChooser: @@ -65,6 +65,7 @@ def run(self): args = {} if self.path: + self.path = normpath(self.path) if isdir(self.path): args["InitialDir"] = self.path else: From c9e73f395e2b51d46ada68119abfae2973591c00 Mon Sep 17 00:00:00 2001 From: Alexandre Detiste Date: Sun, 28 Apr 2024 10:15:51 +0200 Subject: [PATCH 26/30] replace old mock by unittest.mock (#807) --- devrequirements.txt | 1 - plyer/tests/test_battery.py | 2 +- plyer/tests/test_cpu.py | 2 +- plyer/tests/test_devicename.py | 5 +++-- plyer/tests/test_email.py | 2 +- plyer/tests/test_facade.py | 2 +- plyer/tests/test_notification.py | 2 +- plyer/tests/test_screenshot.py | 2 +- plyer/tests/test_uniqueid.py | 3 ++- plyer/tests/test_utils.py | 2 +- setup.py | 2 +- 11 files changed, 13 insertions(+), 12 deletions(-) diff --git a/devrequirements.txt b/devrequirements.txt index 986100695..7ebfe87b8 100644 --- a/devrequirements.txt +++ b/devrequirements.txt @@ -1,4 +1,3 @@ -mock coverage coveralls cython diff --git a/plyer/tests/test_battery.py b/plyer/tests/test_battery.py index b44d504d3..619a3b283 100644 --- a/plyer/tests/test_battery.py +++ b/plyer/tests/test_battery.py @@ -13,7 +13,7 @@ from io import BytesIO from os.path import join from textwrap import dedent -from mock import patch, Mock +from unittest.mock import patch, Mock from plyer.tests.common import PlatformTest, platform_import diff --git a/plyer/tests/test_cpu.py b/plyer/tests/test_cpu.py index 8882522cb..ccd22bb1d 100644 --- a/plyer/tests/test_cpu.py +++ b/plyer/tests/test_cpu.py @@ -11,8 +11,8 @@ import unittest from os import environ from os.path import join -from mock import patch, Mock from textwrap import dedent +from unittest.mock import patch, Mock from plyer.tests.common import PlatformTest, platform_import, splitpath diff --git a/plyer/tests/test_devicename.py b/plyer/tests/test_devicename.py index cbb0fc4be..7dac23362 100644 --- a/plyer/tests/test_devicename.py +++ b/plyer/tests/test_devicename.py @@ -7,10 +7,11 @@ * Windows ''' +import socket import unittest -from mock import patch +from unittest.mock import patch + from plyer.tests.common import PlatformTest, platform_import -import socket class TestDeviceName(unittest.TestCase): diff --git a/plyer/tests/test_email.py b/plyer/tests/test_email.py index 60aa86f0c..5c4c25e49 100644 --- a/plyer/tests/test_email.py +++ b/plyer/tests/test_email.py @@ -8,8 +8,8 @@ ''' import unittest +from unittest.mock import Mock, patch -from mock import Mock, patch from plyer.tests.common import PlatformTest, platform_import diff --git a/plyer/tests/test_facade.py b/plyer/tests/test_facade.py index b49b15f73..f264882b1 100644 --- a/plyer/tests/test_facade.py +++ b/plyer/tests/test_facade.py @@ -16,7 +16,7 @@ import sys from types import MethodType -from mock import Mock, patch +from unittest.mock import Mock, patch import plyer diff --git a/plyer/tests/test_notification.py b/plyer/tests/test_notification.py index 7177ad7a4..f4c6a5a98 100644 --- a/plyer/tests/test_notification.py +++ b/plyer/tests/test_notification.py @@ -13,8 +13,8 @@ from time import sleep from os.path import dirname, abspath, join +from unittest.mock import Mock, patch -from mock import Mock, patch from plyer.tests.common import PlatformTest, platform_import diff --git a/plyer/tests/test_screenshot.py b/plyer/tests/test_screenshot.py index 931fac280..94839a212 100644 --- a/plyer/tests/test_screenshot.py +++ b/plyer/tests/test_screenshot.py @@ -12,8 +12,8 @@ from os import mkdir, remove from os.path import join, expanduser, exists +from unittest.mock import patch -from mock import patch from plyer.tests.common import PlatformTest, platform_import diff --git a/plyer/tests/test_uniqueid.py b/plyer/tests/test_uniqueid.py index 629c840a3..befed2d6c 100644 --- a/plyer/tests/test_uniqueid.py +++ b/plyer/tests/test_uniqueid.py @@ -8,7 +8,8 @@ ''' import unittest -from mock import patch, Mock +from unittest.mock import patch, Mock + from plyer.tests.common import PlatformTest, platform_import diff --git a/plyer/tests/test_utils.py b/plyer/tests/test_utils.py index 3532b76ba..9207e27b7 100644 --- a/plyer/tests/test_utils.py +++ b/plyer/tests/test_utils.py @@ -12,7 +12,7 @@ ''' import unittest -from mock import patch +from unittest.mock import patch class TestUtils(unittest.TestCase): diff --git a/setup.py b/setup.py index 80f65af73..d2d17e69b 100644 --- a/setup.py +++ b/setup.py @@ -26,7 +26,7 @@ 'ios': ['pyobjus'], 'macosx': ['pyobjus'], 'android': ['pyjnius'], - 'dev': ['mock', 'flake8'] + 'dev': ['flake8'] } } ) From ab04099e371216fa1feafb5ebf1899d89db417c6 Mon Sep 17 00:00:00 2001 From: "Kulothungan U.G" Date: Sun, 4 Aug 2024 17:29:02 +0530 Subject: [PATCH 27/30] fix: ImportError linux filechooser --- plyer/platforms/linux/filechooser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plyer/platforms/linux/filechooser.py b/plyer/platforms/linux/filechooser.py index e4ac8570e..c4849749d 100644 --- a/plyer/platforms/linux/filechooser.py +++ b/plyer/platforms/linux/filechooser.py @@ -4,7 +4,7 @@ ''' from plyer.facades import FileChooser -from distutils.spawn import find_executable as which +from shutil import which import os import subprocess as sp import time From f52b36b1625452d7a54533b9514dc632090277c9 Mon Sep 17 00:00:00 2001 From: Brent Picasso Date: Sat, 26 Oct 2024 06:44:23 -0700 Subject: [PATCH 28/30] remove unsupported options for Zenity (#822) --- plyer/platforms/linux/filechooser.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/plyer/platforms/linux/filechooser.py b/plyer/platforms/linux/filechooser.py index e4ac8570e..5c5aa6024 100644 --- a/plyer/platforms/linux/filechooser.py +++ b/plyer/platforms/linux/filechooser.py @@ -106,8 +106,7 @@ class ZenityFileChooser(SubprocessFileChooser): def _gen_cmdline(self): cmdline = [ which(self.executable), - "--file-selection", - "--confirm-overwrite" + "--file-selection" ] if self.multiple: cmdline += ["--multiple"] @@ -117,10 +116,6 @@ def _gen_cmdline(self): cmdline += ["--directory"] if self.path: cmdline += ["--filename", self.path] - if self.title: - cmdline += ["--name", self.title] - if self.icon: - cmdline += ["--window-icon", self.icon] for f in self.filters: if isinstance(f, str): cmdline += ["--file-filter", f] From bab47e7eb0f56cca3a2bd5751707a64aae7f7548 Mon Sep 17 00:00:00 2001 From: Scott Pinkham Date: Sat, 30 Nov 2024 16:54:14 -0700 Subject: [PATCH 29/30] Set "DefExt" argument in Win32FileChooser run method. Set value for the "DefExt" key so that Windows will append the extension to the returned file name. --- plyer/platforms/win/filechooser.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plyer/platforms/win/filechooser.py b/plyer/platforms/win/filechooser.py index 8a26fe3c9..b0623f437 100644 --- a/plyer/platforms/win/filechooser.py +++ b/plyer/platforms/win/filechooser.py @@ -90,6 +90,15 @@ def run(self): filters += f[0] + "\x00" + ";".join(f[1:]) + "\x00" args["Filter"] = filters + # === PATCH === + # Set the default extension using the value from the first filter. + # A side-effect of this is the dialog will append the currently + # selected filter extension to the filename if the user does not provide one. + if self.filters: + # get the characters of the first filter (after the .) + args["DefExt"] = self.filters[0][1].partition(".") + # === END PATCH === + flags = win32con.OFN_OVERWRITEPROMPT flags |= win32con.OFN_HIDEREADONLY From f5cda818ce15831eee3757716d8b402b93d89b0f Mon Sep 17 00:00:00 2001 From: Akshay Arora Date: Tue, 7 Jan 2025 19:04:36 +0530 Subject: [PATCH 30/30] Update filechooser.py Options are still supported, Just in different order. --- plyer/platforms/linux/filechooser.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plyer/platforms/linux/filechooser.py b/plyer/platforms/linux/filechooser.py index 5c5aa6024..6df92d099 100644 --- a/plyer/platforms/linux/filechooser.py +++ b/plyer/platforms/linux/filechooser.py @@ -106,16 +106,20 @@ class ZenityFileChooser(SubprocessFileChooser): def _gen_cmdline(self): cmdline = [ which(self.executable), - "--file-selection" - ] + "--file-selection"] + if self.title: + cmdline += ["--title", self.title] if self.multiple: cmdline += ["--multiple"] + if self.mode == "save": cmdline += ["--save"] elif self.mode == "dir": cmdline += ["--directory"] if self.path: cmdline += ["--filename", self.path] + if self.icon: + cmdline += ["--icon", self.icon] for f in self.filters: if isinstance(f, str): cmdline += ["--file-filter", f]