Го­ворят, iOS неверо­ятно зак­рытая сис­тема: ни написать свою прог­рамму без лицен­зии раз­работ­чика, ни зас­тавить iPhone или iPad делать что‑то, что не одоб­ряют в Apple. Сегод­ня я поз­наком­лю тебя с Pyto — интер­пре­тато­ром Python для iOS, который поз­воля­ет тво­рить... если не чудеса, то как минимум мно­гие вещи, которые рань­ше счи­тались невоз­можны­ми без джей­лбрей­ка.

Сна­чала пос­мотрим на сам Pyto, а потом смас­терим прос­тень­кий веб‑интерфейс, который поможет более удоб­но ска­чивать видео через youtube-dl. Работать он будет локаль­но на iOS.

 

Pythonista

Pyto — не пер­вая попыт­ка соз­дать сре­ду раз­работ­ки на Python для пор­татив­ных устрой­ств Apple. Уже мно­го лет сущес­тву­ет при­ложе­ние Pythonista. Оно слу­жило мне верой и прав­дой, поз­воляя как решать на ходу сиюми­нут­ные задачи (что‑то пос­читать, рас­шифро­вать, сге­нери­ровать пос­ледова­тель­ность), так и соз­давать неболь­шие полез­ные при­ложе­ния. В Pythonista есть свой гра­фичес­кий интерфейс и некото­рые воз­можнос­ти для вза­имо­дей­ствия с сис­темой. К при­меру, мож­но сде­лать пери­оди­чес­ки обновля­емый вид­жет для экра­на Today.

Од­нако раз­работ­ка Pythonista оста­нови­лась уже боль­ше пяти лет назад. Автор за это вре­мя появил­ся на пуб­лике все­го один раз и выпус­тил неболь­шой апдейт, который поз­волил при­ложе­нию запус­кать­ся на сов­ремен­ных вер­сиях iOS. А затем сно­ва про­пал: ни отве­тов на форуме, ни пос­тов в твит­тере. И уж конеч­но, никаких новых фич в Pythonista.

 

Встречайте — Pyto!

И тут на сце­ну выходит Pyto — тоже тво­рение единс­твен­ного раз­работ­чика, но зато пол­ного сил и энту­зиаз­ма. А так­же, кажет­ся, желания испы­тывать тер­пение модера­торов Apple, пос­тоян­но идя по краю доз­волен­ного в App Store. Pyto, к при­меру, уме­ет запус­кать при­ложе­ния в фоне, поз­воля­ет соз­давать локаль­ные веб‑сер­веры и даже име­ет встро­енную под­дер­жку репози­тория PyPI — ста­вить пакеты мож­но бук­валь­но одной кноп­кой!

info

Ус­танов­ка при­ложе­ний внут­ри при­ложе­ния до сих пор была абсо­лют­ным табу в iOS. Любые лазей­ки в Apple прик­рывали, из‑за чего в ту же Pythonista новые пакеты при­ходи­лось про­тас­кивать слож­ной цепоч­кой дей­ствий. Не исклю­чено, что авто­ру Pyto повез­ло и модера­торы прос­то про­мор­гали наруше­ния. Или же раз­решать прог­раммис­там некото­рые воль­нос­ти — это новая полити­ка Apple. Поживем — уви­дим!

У Pyto боль­шие воз­можнос­ти для работы с матема­тичес­кими фун­кци­ями — к при­меру, пакет NumPy, без которо­го не обхо­дят­ся любые мало‑маль­ски слож­ные вычис­ления, уста­нов­лен по умол­чанию. Так­же в Pyto удоб­но стро­ить гра­фики и даже поль­зовать­ся кое‑какими средс­тва­ми для машин­ного обу­чения. К при­меру, мне без тру­да уда­лось пос­тавить Gensim и пораз­вле­кать­ся с раз­бором тек­стов.

Как и Pythonista, Pyto сто­ит денег: пос­ле трех­днев­ного проб­ного пери­ода тебя поп­росят рас­кошелить­ся на 750 руб­лей за базовую вер­сию и 1400 за рас­ширен­ную, с набором биб­лиотек, тре­бующих ком­пилця­ии. Но необ­ходимость рас­кошели­вать­ся — не глав­ный недос­таток Pyto.

Ос­новной проб­лемой это­го при­ложе­ния оста­ется неверо­ятная сырость. Нас­толь­ко мощ­ная, что в болото багов мож­но про­валить­ся по колено, если не с головой. И я не пре­уве­личи­ваю: один раз мне уда­лось зак­линить Pyto нас­толь­ко, что даже перезаг­рузка не помога­ла.

Од­нако если дер­жать­ся про­торен­ных дорожек и поль­зовать­ся Pyto береж­но и акку­рат­но, то он сос­лужит отличную служ­бу.

 

Особенности Pyto

 

Командная строка

В Pyto есть коман­дная стро­ка. Но учти, что это не Bash и внут­ри — не Linux. Это свой коман­дный интер­пре­татор Pyto. Он под­держи­вает нес­коль­ко основных команд Bash — спи­сок мож­но узнать коман­дой help. Отсю­да ты запус­тишь скрип­ты на Python, но на уста­нов­ку каких‑то дру­гих прог­рамм рас­счи­тывать не при­ходит­ся.

 

Использование файловой системы

Важ­ное отли­чие iOS от дру­гих опе­раци­онок — в том, нас­коль­ко силь­но здесь кон­тро­лиру­ется дос­туп к фай­ловой сис­теме. Без раз­решения скрипт в Pyto не может получить дос­туп ни к одной пап­ке!

Хо­рошая новость зак­люча­ется в том, что зап­рашивать пра­ва очень прос­то. Для это­го в Pyto есть модуль file_system.

Пи­шем прос­тень­кий скрипт:

import file_system as fs
path = fs.FolderBookmark()
print(path)

Пос­ле его запус­ка появит­ся диало­говое окно для выбора пап­ки. Выб­рав ее, ты дашь Pyto пра­ва на дос­туп ко всем фай­лам в ней. Имен­но Pyto, а не сво­ему скрип­ту! Это озна­чает, что даль­ше дос­туп к этой пап­ке будет открыт всем прог­раммам внут­ри Pyto, в том чис­ле пос­ле любых переза­пус­ков и перезаг­рузок.

Ес­ли же по ходу исполне­ния скрип­та тебе понадо­бит­ся получать дос­туп к раз­ным фай­лам или пап­кам, ты можешь вос­поль­зовать­ся фун­кци­ями import_file() и open_directory() из того же модуля. Каж­дый раз при их вызове будет появ­лять­ся диало­говое окно для выбора фай­ла или пап­ки.

 

Запуск фоновых задач

Еще одна осо­бен­ность iOS — неис­поль­зуемые при­ложе­ния при­нуди­тель­но завер­шают­ся и выг­ружа­ются из памяти (если встре­тишь людей, кро­пот­ливо чис­тящих исто­рию задач в iOS, передай им, что это мар­тышкин труд — ОС сама отлично с этим спра­вит­ся). Но что сде­лать, что­бы прог­рамма работа­ла в фоне неп­рерыв­но? Для раз­ных типов задач в iOS сущес­тву­ют API, все же поз­воля­ющие фоновое исполне­ние.

В Pyto исполь­зует­ся нехит­рый при­ем: если тебе нуж­на работа в фоне, то при­ложе­ние будет делать вид, что про­игры­вает ауди­офайл, тог­да как никако­го вос­про­изве­дения в реаль­нос­ти не про­исхо­дит. Для акти­вации это­го поведе­ния исполь­зуй модуль background.

Что­бы прог­рамма начала луч­ше дер­жать­ся на пла­ву, дос­таточ­но написать что‑то в таком духе:

import background as bg
with bg.BackgroundTask() as task:
# Код для исполнения в фоне
 

Другие фичи и модули

В Pyto есть под­дер­жка еще нес­коль­ких инте­рес­ных воз­можнос­тей: нап­ример, ты можешь акти­виро­вать свои скрип­ты вызова­ми из Shortcuts или URL-схе­му и переда­вать им парамет­ры. Дру­гая мощ­ная вещь — мост меж­ду Python и Objective-C на осно­ве биб­лиоте­ки Rubicon-ObjC, он поз­воля­ет вызывать фун­кции из натив­ных фрей­мвор­ков.

К Pyto при­лага­ется неп­лохой набор модулей, для работы которых тре­бует­ся ком­пиляция. Самос­тоятель­но добав­лять такие модули, к сожале­нию, нель­зя.

А так­же нес­коль­ко собс­твен­ных модулей для работы с iOS. Мы уже рас­смот­рели file_system и background, но есть и дру­гие:

  • apps — интерфей­сы к популяр­ным сто­рон­ним при­ложе­ниям. Поз­воля­ют из скрип­та акти­виро­вать дру­гую прог­рамму и ска­зать ей сде­лать то или иное дей­ствие;
  • pyto_ui — фрей­мворк для раз­работ­ки при­ложе­ний с гра­фичес­ким интерфей­сом. Поз­воля­ет рисовать окош­ки, кно­поч­ки и про­чие эле­мен­ты управле­ния;
  • widgets и watch — биб­лиоте­ки для соз­дания вид­жетов для экра­на «Сегод­ня» и часов Apple Watch;
  • sound, music и speech отве­чают за вос­про­изве­дение зву­ка, музыки и син­тез речи;
  • notifications поз­воля­ет отправ­лять опо­веще­ния;
  • location и motion дают воз­можность получать геокоор­динаты устрой­ства и опра­шивать дат­чики дви­жения;
  • pasteboard — вза­имо­дей­ствие с буфером обме­на;
  • multipeer — поз­воля­ет обме­нивать­ся дан­ными в режиме точ­ка — точ­ка.

Раз­бор всех этих замеча­тель­ных воз­можнос­тей не умес­тится в одну статью, так что выберем одну неболь­шую задачу, на которой испы­таем Pyto в деле.

 

Пишем веб-сервер

 

Задача

Прог­лядывая дос­тупные в Pyto модули, я зап­риметил youtube-dl — широко извес­тную ути­литу для ска­чива­ния видео с виде­охос­тингов. В том чис­ле и тех, которые пыта­ются защитить кон­тент от подоб­ных дей­ствий. В общем, отличная шту­ка! Но поль­зовать­ся модулем Python или ути­литой для коман­дной стро­ки на мобиль­ном устрой­стве не очень‑то удоб­но.

Есть мно­жес­тво спо­собов при­делать с помощью Pyto более удоб­ный интерфейс к youtube-dl, в том чис­ле написать гра­фичес­кое при­ложе­ние на одном из дос­тупных GUI-фрей­мвор­ков. Одна­ко мне приш­ла в голову мысль поп­робовать исполь­зовать Pyto в качес­тве локаль­ного веб‑сер­вера. Заод­но мож­но будет пос­мотреть, как тут дела с веб‑раз­работ­кой.

 

Инструментарий

Пер­вым делом нам пот­ребу­ется веб‑фрей­мворк или как минимум биб­лиоте­ка, которая будет упро­щать работу с HTTP. В докумен­тации мне встре­тилось упо­мина­ние Tornado и Django, но для нашей задачи и то и то — овер­килл. Дос­таточ­но будет Flask, который без проб­лем уста­новил­ся коман­дой pip install flask и зарабо­тал.

Что­бы еще силь­нее упростить себе жизнь, я буду исполь­зовать кли­ент­ский фрей­мворк HTMX, который поз­воля­ет делать асин­хрон­ные зап­росы без исполь­зования JavaScript. С ним дос­таточ­но задать тегу нес­коль­ко HTML-атри­бутов с информа­цией о том, куда слать зап­рос и куда под­став­лять получен­ный ответ. Осталь­ное HTMX сде­лает сам.

Ну и что­бы внеш­ний вид прог­раммы был не кол­хозным, под­клю­чим минима­лис­тичный CSS-фрей­мворк Pico.css.

 

Код

Пер­вым делом импорти­руем все необ­ходимое.

import flask
from youtube_dl import YoutubeDL
from threading import Thread
import sys
import urllib.request
import os
import background as bg
import file_system as fs

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    6 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии