Twitterで定期投稿のBotを作ってみました。Unix系(Linux)はcronを使えば定期実行など簡単にできるのですが、windowsは定時のタスクスケジューラーはあっても数分、数時間ごとの実行はできないようです(日、週、月単位まで)。勘違いです。詳細設定すればタスクスケジューラでもできます。ああ、このプログラムの意義が……
ほな、作ってみようかと。ただし、Sleep関数を使っているので厳密ではありません。Atom環境で作ってみたら待ち時間で暴走するので一秒のWaitを入れてます。最小1分から最大???時間まで(int値は制限がないらしいので。ただし、GUIは最大99時間を想定して作ってます)
wxpythonを使ってGUIで指定するようにしました。時間待ちは別スレッド作って、待機してます。パネルのほうで停止ボタンをクリックしたら、待機スレッドは実行部分をスキップして入力待ち状態に遷移します。
sleepに入っているときに割り込むのをシグナルを使ってはどうかと思ったのですが、よく理解できなかったし、僕が良く理解できずに実装できても読者の方が理解できないだろうと思って止めました。Unix系Onlyしか使えないのもあるようですし。後回しにします。
TwitterのBotを作るには、コメントの所に、Twitter APIの関数を書けばよろし。もちろん、importは忘れずに
# pip install wxpython
#
from threading import Thread
import sys
import time
import wxclass
MyThread(Thread):
def __init__(self):
super(MyThread, self).__init__() def run(self):#一定期間待つスレッド(60秒ごと)厳密には入力した分+1秒+数ミリ秒
while True:#setter_getter.getWaitTime()からの入力を待ちながら待機
x = setter_getter.getWaitTime()
wait_splt = int(x / 60)
while wait_splt > 0:#分単位で待つ
wait_splt2 = 60
while wait_splt2 > 0:#割り込みの関係上秒単位で待つ
x = setter_getter.getWaitTime()
if x <= 0:
break
time.sleep(1)
wait_splt2 = wait_splt2 -1
if x <= 0:
break
#ここに指定時間に実行したい文を書く
print('例えばこのようにprint文をいれるとか')
#-----------------
wait_splt = wait_splt - 1
time.sleep(1)#1秒のwaitを入れとかないとAtom環境で暴走するので
class MyApp(wx.Frame):
def __init__(self, *args, **kw):
super(MyApp, self).__init__(*args, **kw)
MyApp.WaitTime = 60
self.init_ui()
def init_ui(self):
self.SetTitle('定期実行プログラム')
self.SetSize((300, 150))
self.Show()
panel_ui = wx.Panel(self, -1, pos=(0, 0), size=(300, 150))
self.label_x = wx.StaticText(panel_ui, -1, '間隔設定', pos=(10, 10))
self.box_h = wx.TextCtrl(panel_ui, -1, pos=(10, 30),size=(30, 20))
label_x = wx.StaticText(panel_ui, -1, '時間', pos=(45, 30),size=(35, 20))
self.box_m = wx.TextCtrl(panel_ui, -1, pos=(80, 30),size=(30, 20))
label_x = wx.StaticText(panel_ui, -1, '分間', pos=(115, 30),size=(35, 20))
self.label_t = wx.StaticText(panel_ui, -1, ' ', pos=(10, 55),size=(150, 20))
btn = wx.Button(panel_ui, -1, '開始', pos=(10, 80))
btn.Bind(wx.EVT_BUTTON, self.clicked)
btn_stop = wx.Button(panel_ui, -1, '停止', pos=(100, 80))
btn_stop.Bind(wx.EVT_BUTTON, self.clicked2)
def clicked(self, event):
if self.box_h.GetValue() == '':
hour = 0
else:
hour = int(self.box_h.GetValue())
if self.box_m.GetValue() == '':
min = 0
else:
min = int(self.box_m.GetValue())
if hour <= 0 and min <= 0:
self.label_t.SetLabel('1分以上の時間を指定してください')
else:
self.label_t.SetLabel(str(hour) + '時' + str(min) + '分ごと実行')
wait_time = hour * 60 * 60 + min * 60
setter_getter.setWaitTime(wait_time)
def clicked2(self, event):
self.label_t.SetLabel('停止中')
setter_getter.setWaitTime(-1)
class setter_getter():
def setWaitTime(x):
MyApp.WaitTime = x
def getWaitTime():
return MyApp.WaitTime
app = wx.App()
MyApp(None)
t = MyThread()
t.setDaemon(True) # メインスレッドが終了すればこのスレッドも有無をいわさずに落とす
t.start()
app.MainLoop()
いじょ。変数とかメソッドの命名方は我流なのですみません。
コメント