
The legend of temptation: how to use Python to automate iOS

Often we have to make monotonous and rather boring manipulations with our iPhone, which make us look enviously at desktops with their limitless possibilities for setting up, scripting and automating actions. What desktops are there - even for Android users with their ubiquitous Tasker, with which you can program your smartphone for anything. In iOS, the existence of such applications is impossible, but we have a small loophole.
In this article I want to talk about Pythonista - a development environment in Python (version 2.7.5) for iOS, which also allows you to write full-fledged applications with a graphical interface. However, we will use it for slightly different purposes - to create simple utility scripts that will automate routine operations.

Pythonista includes many pre-installed libraries, including those that help us access iOS functionality. An example is clipboard, which allows you to read and write to the clipboard, contacts for working with the address book, keychain, location, and others.
In addition to the built-in, we will also need third-party Python modules. For Pythonista, there are two counterparts to the well-known pip. These are pipista 2.0 and Pypi . To install the package using the first one, you need to save the script to the root directory and run the following command:
import pipista
pipista.pypi_install('Name_of_library')
This library also has the functions pypi_download (), pypi_search () and pypi_versions (), which allows us to consider it a complete replacement for pip. The second installer requires clearer requests. For example, you must specify the package version - this is convenient if for some reason you do not want to use the latest version.
from Pypi import Installer
Installer('Name_of_library', 'Version').install()
This installer also has additional features.

How to run a script from the main screen
There are two possibilities for this: * Pythonista Shortcut * and * Launch Center Pro *. In the first case, everything is simple: just go from the device to the site , enter the script name and arguments, click the Create Shortcut button, then save this page to the desktop using standard Safari functions.
The second program is much more interesting. To run a script from it, you need to create an event and write the following line in the * URL * field: "pythonista: // script_name? Action = run & args =", where script_name is the name of the script taking into account the directory hierarchy, and after args = you need to list the arguments (if they are). There is also the ability to run on time or with a certain regularity.
There is also the opportunity to pack the script into a full iOS application. To do this, just download the [archive] (goo.gl/jsQK0b) with the Xcode project from the official site and replace the standard script with Hello, world with your own. After that, you can assemble this project in Xcode and run on the simulator, and if you have an Apple developer account, then on the gadget.
INFO
Pythonista includes all the documentation you need, so you don’t need to connect to the Internet to learn it.
The built-in Pythonista editor is quite developed, has syntax highlighting, auto-completion and additional keyboard keys. Moreover, it can also be scripted.
Scripts
Let's write some scripts in order to make life easier for us and our loved ones. Perhaps some of them (or all) will seem useless to someone, but they provide an idea of what can be done using Pythonista, and can act as a kind of base for your experiments. There are nine scripts in total, and they are very diverse.

Fast Tweet
Let's start with the ubiquitous Twitter. It’s not very convenient to open the application or go to the site in order to just send a tweet. Therefore, we will write a script that will tweet what is on the clipboard (do not forget to install the tweepy library).
import tweepy
import clipboard
# Ключи Twitter-приложения
consumer_key = "----------"
consumer_secret = "----------"
access_key="----------"
access_secret="----------"
# Представляемся системе
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api=tweepy.API(auth)
# Публикуем твит
text = clipboard.get()
if len(text)<=140 and len(text)>0:
api.update_status(text)
The script connects to the account using the available keys. They can be obtained on the official Twitter website . To get all the keys, you need to create an application, then go to the Keys and Access Tokens tab and click on the Create my access token button. This way we get the four keys we need. In order for the script to be able to post messages, you must give the application such rights on the Permissions tab.
In all other respects, the functionality is extremely simple. The script takes a line from the clipboard, checks if the line matches the tweet format (no more than 140 characters), and posts it.
Quick save in Instapaper
Now about the equally popular Instapaper service, which allows you to save pages for offline reading. The following three-line script adds a page from the clipboard directly to the service client installed on the device.
import webbrowser, clipboard
addnew='x-callback-instapaper://x-callback-url/add?url='+clipboard.get()
webbrowser.open(addnew)
The script uses the so-called x-callback-url - mini-API applications that can be called through the built-in browser. On the official website of this feature there is a list of applications that support this feature. The structure of x-callback-url requests is as follows:
x-callback-Имя_Приложения://x-callback-url/Функция?Параметр=
Password generator
Yes, it’s a password generator. There are a bunch of applications with similar functionality, but we will do our own. Just because we want :).
import random, string,clipboard
pass = ''
for x in range(random.randrange(8,12)):
pass += random.choice(string.ascii_letters + string.digits)
clipboard.set(pass)
This script will help to create a password with high resistance to selection (with the inclusion of numbers and letters). The idea of the algorithm is extremely simple: a random line (from 8 to 11) the number of characters from the above set is added to the empty line. Next, the password is placed on the clipboard.
Email your current location
Sometimes it’s easier to press a button and send your address to the other person than explain where you are.
import smtplib, location, time
from email.mime.text import MIMEText
# SMTP-сервер
server = "адрес_сервера"
user_passwd = "пароль"
port = 22
user_name = "отправитель@мэйл"
send_name='получатель@мэйл'
# Выполняем подключение и регистрацию
s = smtplib.SMTP(server, port)
s.ehlo()
s.starttls()
s.ehlo()
s.login(user_name, user_passwd)
# Получаем координаты
location.start_updates()
time.sleep(10)
location.stop_updates()
loc = location.get_location()
addr = location.reverse_geocode(loc)[0]
# Формируем и отправляем письмо
Text = 'Я нахожусь по адресу: ' + addr['Country'] + ', город ' + addr['City']+', ' + addr['Name']
letter = MIMEText(Text,'html','utf-8')
letter['Subject']= 'Текущая геолокация'
letter['To']=send_name
letter=letter.as_string()
s.sendmail(user_name,send_name,letter)
s.close
The script consists of two parts: the first is working with the mail server, the second is receiving the current address and sending an email. Let us dwell on the second in more detail. The fact is that there is no “get current location” function in the location library, but there are two functions that allow you to get a list of frequently visited places. Since the creation of the list lasts only ten seconds (time.sleep (10)), there will be only one object with the current address in it. This object is a dictionary. We will get the necessary values by the keys and enter the beautiful phrase in the Text line, which we will send later.

Uploading photos to the server via FTP
The clipboard library already known to us allows us to work not only with text, but also with images. This opens up new possibilities for us. What about a script that allows you to save a photo from the clipboard to an FTP server?
import ftplib, clipboard
# Получаем изображение и сохраняем в виде файла
a=clipboard.get_image()
filename='out.jpg'
a.save(filename)
# Подключаемся к серверу и заливаем картинку
con=ftplib.FTP('Host','Login','Password')
f=open(filename,'rb')
send=con.storbinary(filename,f)
con.close()
The script can be slightly modified by writing in the first two lines
import ftplib, photos
a=photos.get_image()
Then the last captured photo will not be sent to the server, but copied. And if you replace the first two lines with these:
import ftplib, photos
a=photos.capture_image()
then iOS will offer to take a photo.
Work with a remote server via SSH
Many of us have remote servers. Someone has a home media player or file wipe, others steer servers on Amazon. How to manage them from iPhone or iPad? You can download an FTP client, but this is not an option if you need to regularly perform the same tasks, for example, backup. Stephen Millard wrote a [script] (goo.gl/Tt14cC) that allows remote commands to be executed through SSH. In a simplified form (without checking the correctness of the entered data and log output), it looks like this:
import paramiko
import console
# Адрес, логин и имя исполняемой команды
strComputer = 'адрес'
strUser = 'логин'
strPwd = 'пароль'
strCommand = 'имя_команды'
# Подключаемся к серверу
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname=strComputer, username=strUser, password=strPwd)
# Выполняем команду
stdin, stdout, stderr = client.exec_command(strCommand)
print stdout.read()
client.close()
To execute a set of commands, just copy the line “stdin, stdout, stderr = client.exec_command (strCommand)” several times with different commands (or list all the commands separated by semicolons. - Ed.).

Shorten links with goo.gl
Often you have to resort to shorten links. But every time you go to the site, copy, paste - it's somehow boring. Fortunately, the goo.gl API exists.
import googl, clipboard
client = googl.Googl("ключ")
result = client.shorten(clipboard.get())
clipboard.set(result['id'])
The script receives the URL from the clipboard, converts it and puts it back to the clipboard. Before running the script, you need to get the Access Key API. To do this, go to the API page , click Add project and include the URL Shortener API in the list of available services. Next, in the left menu, select the APIs & auth tab, the Credentials submenu and click the Create new Key button, then the Browser Key. After receiving the key, insert it into the script.
Please note that during the execution of the script, the result variable is assigned a dictionary of the form {'kind': 'urlshortener # url', 'id': ShortLink ', u'longUrl': 'LongLink'}. Since we need only a short link, the value by the key 'id' is entered into the clipboard.
Notebook cleaning
Walking through the search engines, we will find only two ways to clear the notebook: deleting one contact or synchronization with an empty contact list on your computer. No, that’s not interesting.
import contacts
a = contacts.get_all_people()
for i in a:
contacts.remove_person(i)
contacts.save()
Just go over the contact list. The main thing is not to forget to save the changes made (the last line).
Import friends from VK to notebook
Finally, the most complex and longest script is importing phone numbers from VKontakte into a notebook. Like everyone else, VKontakte has an API. For python, there are several libraries for working with it. The most famous and easiest to use is the library with the modest name vk.
import vk, datetime, contacts
# Функция для конвертации даты из формата ВК в формат iOS
def convertdate(date):
date = date.split('.')
if len(date) == 2:
return datetime.datetime.combine(datetime.date(1604,int(date[1]),int(date[0])),datetime.time(0, 0))
else:
return datetime.datetime.combine(datetime.date(int(date[2]),int(date[1]),int(date[0])),datetime.time(0, 0))
# Подключаемся к ВК и получаем список друзей
vkapi = vk.API('ID-приложения', 'логин', 'пароль')
a = vkapi.friends.get(fields='contacts,bdate')
a = a['items']
# Проходим по списку полученных контактов и импортируем их по одному
for i in a:
Temp = contacts.Person()
Temp.last_name= i['last_name']
Temp.first_name = i['first_name']
if 'mobile_phone' in i.keys():
try:
Temp.phone=[('mobile',i['mobile_phone'])]
except:
pass
if 'home_phone' in i.keys():
try:
Temp.phone.append(('home',i['home_phone']))
except:
pass
Temp.url = [('vk','http://vk.com/id'+str(i['id']))]
if 'bdate' in i.keys():
Temp.birthday = convertdate(i['bdate'])
contacts.add_person(Temp)
# Сохраняем контакты
contacts.save()
As with Twitter, you need to create an “application” inside the “VKontakte” for the script. To do this, go to the “Applications” tab on the VK website, then to the “Management” tab and click on the “Create Application” button. On the application page, go to the “Settings” tab and copy the “Application ID”. Insert “Application ID”, “Login” and “Password” into the script.
Let's see how this script works. First we get a list of friends. By default, the friends.get () function returns a dictionary consisting of two fields: count and items. We are undoubtedly interested in the second, but since we want to get not only names and surnames, we will pass the fields parameter to the function, indicating what we want to know. Next, we go through the list of dictionaries, where each dictionary is a user. At each iteration, we create a Temp variable of type Person and, in turn, add fields to it.
In the process of going through contacts, the script solves several problems. The first problem arises when exporting phone numbers, because very often we find numbers like “whoever needs to know,” “secret,” and the like in VK. In order for the script to be able to process such records without crashing, the try statement is used. The second problem occurred with a mismatch in the format of the date of birth. In the dictionary received from VK, it is written as a string in the format DD.MM.YYYY, and in the birthday field, you must enter data in the format datetime.datetime. For this, we need the convertdate function at the beginning of the script. In addition, the date of birth may not be indicated at all.
Pythonista Embedded Libraries
- canvas - a vector graphics library;
- clipboard - work with the clipboard;
- console - functions related to input and output of text;
- contacts - access to the notebook;
- editor - work with the text editor Pythonista;
- keychain - access to the Keychain API;
- linguistictagger - linguistic analysis;
- location - geolocation services;
- motion - sensor readings;
- notification - work with notifications;
- photos - work with saved photos;
- scene - 2D graphics and animation;
- sound - a library of sounds;
- speech - text to speech conversion;
- ui is a native GUI for iOS.
Conclusion
Despite the large number of examples, we have considered far from all the features of Pythonista. But its functionality is enough for a lot. For example, the App Store has already posted several applications created in this program. In addition, soon the creator of Pythonista promises to release an update with support for the iPhone 6 and 6+ and two new modules for working with reminders and peripheral Bluetooth devices.
WWW
Pythonista Official Forum: omz-forums.appspot.com/pythonista Built-in
Documentation: omz-software.com/pythonista/docs/ios
Great article about Pythonista features: www.macstories.net/stories/automating-ios-how-pythonista -changed-my-workflow
Collection of Pythonista scripts: github.com/Pythonista-Tools/Pythonista-Tools

First published in the Hacker Magazine from 02/2015.
Posted by Victor Paperno (@ Snusmumrick97)
Subscribe to Hacker