はじめに
iPhone, iPadユーザーの皆さん、iOS端末上でPythonでの開発ができるPythonista3というアプリはご存知でしょうか?
Pythonを実行するだけであれば個人的にはCarnets - Jupyterがおすすめですが、
Pythonista3では各種ショートカットやウィジェットなどといったアブリ外から使用可能な機能の開発や、ゲームを作ることも出来ます。
今回はそんなPythonista3を使って
Qiitaのトレンドを表示してくれて、クリックするとSafariでそのページを開いてくれるウィジェット
を作成したので紹介したいと思います。
やったこと
今回のウィジェットの場合、Example/Widget
下にあるLauncher.py
の内容がほとんどそのまま使えるので、それをベースに、
・QiitaのトップページからトレンドのタイトルとURLを取得してくる機能
・取得した情報を一時的に保存しておく機能
・前回の情報の取得から一定時間上経過していたら再度Qiitaにアクセスし情報を更新する機能
を追加しました。
コード
列数、折り畳んだ状態での行数、フォントサイズの変数をインポート文の後にまとめておいたので、お好みでレイアウトを調節してください。
窮屈&押しにくくなりますが、行数を5以上にすれば全デイリートレンド(30件)を表示できます。
import re
import requests
import appex, ui
import os
from math import ceil, floor
import webbrowser
import pickle
import time
COLS = 1
ROWS = 3
fontsize = 12
def get_trend():
trends = []
text = requests.get('https://qiita.com/').text
titles = re.findall('class="tr-Item_title" href="(.+?)">(.+?)<', text)
urls = re.findall('uuid":".{10,50}?",', text)
for i in titles:
trends.append({'title':i[0], 'url':i[1]})
trends.append({'lastUpdate':time.time()})
with open("trends.pickle", "wb") as f:
pickle.dump(trends, f)
return trends
class LauncherView (ui.View):
def __init__(self, shortcuts, *args, **kwargs):
row_height = 110 / ROWS
super().__init__(self, frame=(0, 0, 300, ceil(len(shortcuts[:-1]) / COLS) * row_height), *args, **kwargs)
self.buttons = []
for s in shortcuts[:-1]:
btn = ui.Button(title=' ' + s['title'], name=s['url'], action=self.button_action, bg_color='#73c239', tint_color='#fff', corner_radius=7, font=('<System-Bold>',fontsize))
self.add_subview(btn)
self.buttons.append(btn)
def layout(self):
bw = (self.width - 10) / COLS
bh = floor(self.height / ROWS) if self.height <= 130 else floor(110 / ROWS)
for i, btn in enumerate(self.buttons):
btn.frame = ui.Rect(i%COLS * bw + 5, i//COLS * bh, bw, bh).inset(2, 2)
btn.alpha = 1 if btn.frame.max_y < self.height else 0
def button_action(self, sender):
webbrowser.open(sender.name)
def main():
widget_name = __file__ + str(os.stat(__file__).st_mtime)
v = appex.get_widget_view()
if v is None or v.name != widget_name:
try:
with open("trends.pickle", "rb") as f:
SHORTCUT = pickle.load(f)
except:
SHORTCUT = [{'lastUpdate':time.time() - 86400}]
with open("trends.pickle", "wb") as f:
pickle.dump(SHORTCUT, f)
SHORTCUTS = get_trend() if time.time() - SHORTCUT[-1]['lastUpdate'] > 1800 else SHORTCUT #前回から1800秒(30分)以上経っていたら更新
v = LauncherView(SHORTCUTS)
v.name = widget_name
appex.set_widget_view(v)
if __name__ == '__main__':
main()
まとめ
Pythonista3はいいぞ(使えるパッケージ増えるといいなあ…)