def request_background_fetch(): """ This function is used to start fetching information in background. It tells the system to execute the script from which the function is called multiple times a day. The OS decides when it's appropiate to perform the fetch, so it's pretty unreliable. The script cannot take more than 30 seconds to execute. For example, you can write a script for sending notifications or updating a widget. .. highlight:: python .. code-block:: python import background as bg import notifications as nc import widgets as wd import time bg.request_background_fetch() current_time = time.strftime("It is %H:%M") # Send notification notif = nc.Notification() notif.message = current_time nc.send_notification(notif) # Update widget time_label = wd.Text(current_time) widget = wd.Widget() for layout in ( widget.small_layout, widget.medium_layout, widget.large_layout): layout.add_row([time_label]) wd.save_widget(widget, "Fetching Test") """ BackgroundTask = __Class__("BackgroundTask") BackgroundTask.scheduleFetch() script_path = None try: script_path = threading.current_thread().script_path except AttributeError: pass if script_path is not None: BackgroundTask.backgroundScript = script_path
def __init__(self, audio_path: str = None, id: str = None): check(audio_path, "audio_path", [str, None]) check(id, "id", [str, None]) if id is None: self.id = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(5)) else: self.id = id self.__background_task__ = __Class__("BackgroundTask").new() if audio_path is not None: self.__background_task__.soundPath = abspath(audio_path)
def __init__(self, audio_path: str = None, id: str = None): if "widget" in os.environ: raise RuntimeError( "Cannot create a background task from a widget.") check(audio_path, "audio_path", [str, None]) check(id, "id", [str, None]) if id is None: self.id = "".join( random.choice(string.ascii_uppercase + string.digits) for _ in range(5)) else: self.id = id self.__background_task__ = __Class__("BackgroundTask").new() if audio_path is not None: self.__background_task__.soundPath = abspath(audio_path)
import os import sys import builtins import traceback from pyto import __Class__, Python from time import sleep os.environ["widget"] = "1" PyWidget = __Class__("PyWidget") while True: for code in PyWidget.codeToRun: try: exec(str(code[0])) PyWidget.removeWidgetID(code[1]) except Exception as e: PyWidget.breakpoint(traceback.format_exc()) print(e) PyWidget.codeToRun = [] try: # Run code code = str(Python.shared.codeToRun) exec(code) if code == Python.shared.codeToRun: Python.shared.codeToRun = None except: pass
""" A module containing constants for ``pyto_ui``. """ from pyto import __Class__ from UIKit import ( UITapGestureRecognizer, UILongPressGestureRecognizer, UIPanGestureRecognizer, UIGestureRecognizer, ) from UIKit import UIFont as __UIFont__ __PyView__ = __Class__("PyView") __PyColor__ = __Class__("PyColor") __PyControl__ = __Class__("PyControl") __PyButton__ = __Class__("PyButton") __PyLabel__ = __Class__("PyLabel") __PyTableView__ = __Class__("PyTableView") __PyTableViewCell__ = __Class__("PyTableViewCell") __PyTextField__ = __Class__("PyTextField") __PyGestureRecognizer__ = __Class__("PyGestureRecognizer") __PyButtonItem__ = __Class__("PyButtonItem") __PyTextInputTraitsConstants__ = __Class__("PyTextInputTraitsConstants") class Value: def __repr__(self): return None
from UIKit import UIDevice from pyto import __Class__ from types import ModuleType import sys import warnings if UIDevice is not None and float( str(UIDevice.currentDevice.systemVersion).split(".")[0]) < 13: raise ImportError("PytoUI requires iPadOS / iOS 13") if UIDevice is not None and float( str(UIDevice.currentDevice.systemVersion).split(".")[0]) >= 14: _warning = "Today Widgets are deprecated since iPadOS / iOS 14. Use the 'widgets' module instead." warnings.warn(_warning, DeprecationWarning) __PyNotificationCenter__ = __Class__("PyNotificationCenter") class __NotificationCenter__(ModuleType): @property def expandable(self): return __PyNotificationCenter__.canBeExpanded @expandable.setter def expandable(self, new_value): __PyNotificationCenter__.canBeExpanded = new_value @property def maximum_height(self): return __PyNotificationCenter__.maximumHeight
def have_internet(): return __Class__("InternetConnection").isReachable
from pyto import __Class__ import random import string import sys _dir = [] _PyValue = __Class__("PyValue") def random_string(string_length=10): """ Generate a random string of fixed length. Taken from 'https://pynative.com/python-generate-random-string/'. """ letters = string.ascii_lowercase return ''.join(random.choice(letters) for i in range(string_length)) def value(object): if object in globals().values(): for (key, item) in globals().items(): if item is object: return _PyValue.alloc().initWithIdentifier(key) id = random_string() while (id in locals()): id = random_string()
def __init__(self, audio_path=None): self.__background_task__ = __Class__("BackgroundTask").new() if audio_path is not None: self.__background_task__.soundPath = abspath(audio_path)
from contextlib import contextmanager import warnings try: from rubicon.objc import ObjCClass, ObjCInstance except ValueError: def ObjCClass(class_name): return None NSURL = ObjCClass("NSURL") NSItemProvider = ObjCClass("NSItemProvider") PyItemProvider = __Class__("PyItemProvider") def general_pasteboard(): return UIPasteboard.generalPasteboard # MARK: - Item Provider class ItemProvider: """ A bridge to Foundation's ``NSItemProvider`` class. An :class:`~pasteboard.ItemProvider` object can load data as one or more type of data. Instances of this class are returned by :func:`~pasteboard.item_provider` and :func:`~pasteboard.shortcuts_attachments`. """
""" Home Screen Widgets This module is used to present custom UIs on home screen widgets. """ import pyto_ui as ui import os import datetime from pyto import __Class__ from UIKit import UIDevice from typing import Union __PyWidget__ = __Class__("PyWidget") __widget_id__ = None __widget__ = __PyWidget__.alloc().init() __shown_view__ = False if UIDevice is not None and float(str(UIDevice.currentDevice.systemVersion).split(".")[0]) < 14: raise ImportError("Home Screen Widgets were introduced on iPadOS / iOS 14.") if __PyWidget__ is None: raise NotImplementedError("Home Screen Widgets are coming on Pyto 13.") def schedule_next_reload(time: Union[datetime.timedelta, float]): """ Schedules the next reload of the widget. The passed time must be greater than 5 minutes.
MPMusicPlayerController = ObjCClass("MPMusicPlayerController") """ The 'MPMusicPlayerController' class from the 'MediaPlayer' framework. """ MPMediaItem = ObjCClass("MPMediaItem") """ The 'MPMediaItem' class from the 'MediaPlayer' framework. """ MPMediaItemCollection = ObjCClass("MPMediaItemCollection") """ The 'MPMediaItemCollection' class from the 'MediaPlayer' framework. """ MPMediaQuery = ObjCClass("MPMediaQuery") """ The 'MPMusicMPMediaQueryPlayerController' class from the 'MediaPlayer' framework. """ MediaPlayer = cdll.LoadLibrary( "/System/Library/Frameworks/MediaPlayer.framework/MediaPlayer") _PyMusicItem = __Class__("PyMusicItem") except (NameError, ValueError): MPMusicPlayerController = "MPMusicPlayerController" """ The 'MPMusicPlayerController' class from the 'MediaPlayer' framework. """ MPMediaItem = "MPMediaItem" """ The 'MPMediaItem' class from the 'MediaPlayer' framework. """ MPMediaItemCollection = "MPMediaItemCollection" """ The 'MPMediaItemCollection' class from the 'MediaPlayer' framework. """ MPMediaQuery = "MPMediaQuery" """ The 'MPMusicMPMediaQueryPlayerController' class from the 'MediaPlayer' framework. """ MediaPlayer = "MediaPlayer"
from pyto import __Class__ from typing import List, Callable, Union from UIKit import UIDevice, UIImage from pyto import EditorViewController, Python from PIL import Image import builtins import base64 import threading import traceback import pyto_ui as ui if (UIDevice is not None and float(str(UIDevice.currentDevice.systemVersion).split(".")[0]) < 13): raise ImportError("PytoCore requires iPadOS / iOS 13") __py_core__ = __Class__("PyCore") def startup_script(): """ Sets the current running script as startup script, so each time Pyto will be launched, this script will be executed in background. This function cannot be executed on a subthread. Setting the startup script will replace the old one. Only one plugin is supported at time because only one object can be receive editor's events. But nothing stops you from importing other modules. """ script_path = None plugin_path = None try: script_path = threading.current_thread().script_path except AttributeError:
for script in Python.shared.scriptsToExit: # Send SystemExit or MemoryError raise_exception(str(script), exc) if Python.shared.scriptsToExit.count != 0: Python.shared.scriptsToExit = [] for script in Python.shared.scriptsToInterrupt: # Send KeyboardInterrupt raise_exception(str(script), KeyboardInterrupt) if Python.shared.scriptsToInterrupt.count != 0: Python.shared.scriptsToInterrupt = [] if "PYPI_MIRROR" in os.environ: mirror = os.environ["PYPI_MIRROR"] c.setenv(b"PYPI_MIRROR", mirror.encode()) if EditorViewController.isCompleting: sleep(0.02) elif ConsoleViewController.isPresentingView: sleep(0.002) else: sleep(0.2) except AttributeError as e: # May happen very rarely print(Python.shared) Python = __Class__("Python") print(e) except NameError as e: # May happen very rarely print(Python.shared) Python = __Class__("Python") print(e)
""" Receive remote notifications This module has everything needed to receive push notifications from a server. """ from pyto import __Class__ from time import sleep from typing import Dict __RemoteNotifications__ = __Class__("RemoteNotifications") def remove_category(category: str): """ Removes a category with its given identifier. :param category: The identifier of the category to remove. """ __RemoteNotifications__.removeCategory(category) def add_category(id: str, actions: Dict[str, str]): """ Adds a category of notification. A category contains set of actions for a certain type of notifications. :param id: The unique identifier of the category.