積極的にメモっていく姿勢

題名詐欺。更新頻度の低さが売り。

北見菓子宣伝 Bot ちゃん

北見の御菓子を食べまくる会。北見菓子。

宣伝しないと人は来ない→ぼっちが御菓子勝手に食ってる謎の会→ヤバい
ということで、TwitterBotが頑張って宣伝すればいいと思い、書き始めることに。

1.概要

以下の面子で戦うことに。

python2.7.2
tweepy1.8

さくらのvpsの一番安いの借りてるから、そこで働いてもらう事に。
OSはFreesBSDで、バージョンが...

% uname -a

どうやら、8.1のようです。

じゃあ、ソースとか載せてみます。

#! /usr/local/bin/python
# -*- coding: utf-8 -*-

import tweepy
import datetime
import random

sweets = [
  "マンゴープリン",
  "チーズケーキ",
  "シュークリーム",
  "チョコケーキ",
  "コーヒーゼリー",
  "ワッフル"
]

def authentication():
  consumer_key = ""
  consumer_secret = ""
  access_key = ""
  access_secret = ""

  auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
  auth.set_access_token(access_key, access_secret)
  return tweepy.API(auth_handler = auth)

api = authentication()

def tweet(tweet_str):
  api.update_status(tweet_str.decode("utf8"))

url = "http://atnd.org/events/31345"
lim = datetime.datetime(2012, 8, 7, 15) - datetime.datetime.now()

hours = lim.days * 24 + int(lim.seconds / 3600)

time = "後" + str(hours) + "h"

if hours >= 0:
  tweet(random.choice(sweets) + "とか買ってくる!皆で御菓子食べよう!→ " + url + " [" + time  + "]")

御菓子のリストとか雑ですね。
# はてなスーパーpre記法はすごいですね。色までついちゃって。

また、tweepyとかpythonの最初の方の躓きポイントは、

tweepyを使ってみた - syorikenの日記

にちょろっと書いてあります。(書いたのが自分だからもう何でも有り。)

2.記事を書くきっかけ

実はこのソースは、version 1.1くらいのもの。

hours = lim.days * 24 + int(lim.seconds / 3600)

time = "後" + str(hours) + "h"

if hours >= 0:
  tweet(random.choice(sweets) + "とか買ってくる!皆で御菓子食べよう!→ " + url + " [" + time  + "]")

の部分はもともと、

time = "後" + str(lim.days * 24 + int(lim.seconds / 3600)) + "h"

if lim.days > 0 or lim.seconds > 0:
  tweet(random.choice(sweets) + "とか買ってくる!皆で御菓子食べよう!→ " + url + " [" + time  + "]")

って感じになってた。

何がしたかったかというと、
「cronに設定しておくのはいいんだけど、イベント終了時に速攻でcronから消すのめんどいから、時間見てツイートするかどうかくらい、自分で判断しろよbotめ」
ということ。

これでいいべー。とか思ってたら、

[ 後 - 3 h ]

全然かいくぐってんじゃねぇか。
どうしたどうしたと言いながら

% crontab -e

仕方なかった。しかし、なぜこんなことになっちゃったんでしょうね。

3.datetimeとtimedelta

時間云々をいじくる時にはdatetimeモジュールの力を借りましょう。
使い方とかは無視して、今回躓いたところを書き残しておきます。

あと、これ以降

#! /usr/local/bin/python
# -*- coding: utf-8 -*-

import datetime

は省略して書いてありますので、ご了承ください。

timedelta.hourなんてなかった

timedeltaのインスタンスが持ってるのは days, seconds, microseconds の3つだそうです。

hoge = datetime.timedelta(hours=10)
print hoge.hour

実行結果:
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'datetime.timedelta' object has no attribute 'hour'

怒られた。当然である。ややこしくねー?
インスタンス生成するときは hours ぶち込めるのに、見れないとか。

しかし、datetime.hourはある。

hoge = datetime.datetime(2012, 8, 19, hour=5)
print hoge.hour

実行結果:
5

s 付くとか付かないとか以前に、そもそも hour が無い訳ないという思い込みに時間を喰われました。

timedelta.secondsは負にならない

改めて見ると、何故見落としたのか理解に苦しみます。
せっかくなので、ちょっと実験してみました。

today = datetime.datetime(2012, 8, 19, 0)
yesterday = datetime.datetime(2012, 8, 18, 12)

ty = today - yesterday
print ty.days, "日", ty.seconds / 3600, "時間"

yt = yesterday - today
print yt.days, "日", yt.seconds / 3600, "時間"

実行結果:
012 時間
-112 時間

これでわかったのは、「days日後のhours時間後」という見方をしていること。

  0日後の12時間後 →  0 * 24 時間 + 12 時間 後 =  12 時間後
 -1日後の12時間後 → -1 * 24 時間 + 12 時間 後 = -12 時間後

秒は常に正であることから、時間を進めることしか出来ないってこと。
そこで、正負を持てる、つまり時間を進めたり戻したりできる日で調整するって感じかなぁ。

4.最後に

これからも北見菓子は続けるつもりなので、botの調整は不可欠ですな。
まだまだ、直す余地はあるので頑張っていきたいですね。

ということで、

北見菓子 夏の陣 #1 : ATND

宣伝。今回は和菓子を集める予定。

御菓子食べよう!