2010/12/31

今年も一年ありがとうございました。このブログ(Blogger)の記事のタイトル周りのCSSを変更しました。



このブログのデザインについては、「Blogger テンプレート デザイナー」のシンプルカテゴリのブルーを使っています。ただ、デフォルトの記事タイトルの扱いが弱いような気がしていました。気にはなっていたのですが、そのまま使っていました。もう少し、記事タイトルが強調出来るように修正をしました。

編集するのはCSSですが、Bloggerの場合、テンプレートファイルとCSSが一緒になっているので、そのファイルを編集します。管理画面のデザインタブの中にある「デザイン編集」のページにある「テンプレートを編集」の内容を変更します。


記事の部分を目立たせるように、タイトルの横に青いラインを配置して、フォントが弱かったので、フォント指定を変更しました。2箇所のソースを変更しました。

■変更前 その1
h3.post-title, .comments h4 {
  font: $(post.title.font);
  margin: .75em 0 0;
}
■変更後 その1
h3.post-title, .comments h4 {
  font: $(post.title.font);
  margin: .75em 0 0;
  padding:  0 0 0 .30em;
  border-left: 7px solid #66bbdd;
}
■変更前 その2

     
   
■変更後 その2

     
   

変更前
変更後

今年一年、TwitterやBlogでお世話になった皆様、ありがとうございました。来年も宜しくお願いします。

2010/12/30

大掃除が終わりました。窓掃除のためにスクイジーやワイパーを買ってきたので、去年よりは楽に掃除が出来ました。



大掃除が終わりました。毎年、窓・網戸掃除が大変なので、今年は、スクイジーとワイパーを買ってきました。去年までは、ガラス洗剤と雑巾だけで掃除をしていました。そんなに大きな家ではないのですが、窓が多くて、いつも時間が掛かります。

スクイジーやワイパーという道具があることは知っていたのですが、買ってはいませんでした。そういう道具があれば、きっと今よりは楽に掃除が出来るのではないかと思い、ホームセンターで買ってきました。


グラススクイジー30EX 山崎産業
http://amzn.to/geuqgh

窓・網戸きれいワイパー ニトムズ
http://bit.ly/heV1OQ

激落ちダブルキング S-103 レック
http://amzn.to/fBF0aC

ガラスマジックリン 花王
http://bit.ly/he6vci

下の子と、「グラススクイジー30EX」「窓・網戸きれいワイパー」を使って窓と網戸掃除をしました。今まで、大掃除といって数分間しか掃除が出来なかった子も、道具があると面白いのか、沢山手伝ってくれました。

お兄ちゃんは、「激落ちダブルキング」を使って、お風呂を掃除してくれました。お風呂をピカピカにしてくれました。奥さんは台所、レンジ周りを集中的に作業。

窓ガラスにガラスマジックリンを吹きかけ、しばらく経ってぬれた雑巾で拭きます。その後、何度か雑巾で洗剤を拭き取り、最後に「グラススクイジー30EX」を使って、ガラスに残った水滴を拭き取ります。これが気持ちいい。無駄なく一度で綺麗に水滴が取れたら、嬉しくなります。

「窓・網戸きれいワイパー」は、水を使うことなく、窓と網戸の掃除が出来ます。窓用と網戸用の別のシートが付属しており、そのシートを付けて掃除するだけです。とっても簡単でした。

掃除をしていると、岡山には珍しく「ぼたん雪」が降ってきました。写真を撮ってもはっきりと雪が写るくらいの雪でした。



夕方までには、すべての掃除を終えました。綺麗になりました。

Webアプリケーション用Pythonフレームワーク「Nagare project」を試してみるため、Stackless Pythonについて調べてみました。



Nagare project
http://www.nagare.org/


MOONGIFTでは、「Nagare project」を下記のように紹介されています。

Webアプリケーション用Pythonフレームワーク「Nagare project」
http://www.moongift.jp/2010/10/201010220000-2/
Nagare projectはGUI並みの画面と機能を備えたWebアプリケーションを開発するためのフレームワーク。
面白そうです。


このフレームワークには、下記のものがありません。いわゆるWebアプリケーションフレームワークとは、ちょっと違う点にポイントを置いて開発されているようです。

  • no templating languag
  • no explicit URL routing / mapping
  • no controllers proliferation
  • no manual management of the HTTP request / response cycles
  • no global session object
  • no REST by default

必要な環境として下記の記載がありました。
 1. Stackless Python installation

The Nagare framework uses Stackless Python (version 2.5.2 or above). So, grab the latest version of Stackless Python for your platform and install it.
Stackless Pythonというものが必要なようです。Stackless Pythonを知りませんでした。ウィキペディアでは、下記の説明がされていました。

Stackless Python
http://ja.wikipedia.org/wiki/Stackless_Python
ソースコードに多数の変更が必要なため、Stackless Python は既存の Python がインストールされた環境にエクステンションやライブラリとしてインストールすることはできない。それ自体が完全な Python の配布系である。
うーん。既存のPythonの実装と同居させていいのか、影響が出るのか、調べてから次へ。Stackless Pythonは「面白そう」と思える記事を書かれているページがありました。

Stackless PythonでUDPなサーバを作る
http://omake.accense.com/wiki/PythonStacklessPythonSocket

2010/12/29

岡山県玉野市にある「みやま公園」の赤松池には、渡り鳥のオナガガモが沢山、越冬に訪れています。



岡山県玉野市にある「みやま公園」の赤松池のカモにえさをあげると、喜んで食べていました。

みやま公園
http://www.tamano.or.jp/usr/miyama/top2.html

赤松池に着くと、女性の方が、オナガガモたちに大量にえさを与えているところでした。オナガガモたちは、えさを求めて密集しており、少し異様な光景でした。

オナガガモが、えさを求めて密集
真上から撮影をすると、少しグロい感じ

えさ用のお菓子を買っていったので、子どもたちは、喜んでえさを与えていました。行く前にMacに寄ったので、マックポテトの入れ物を持っていますが、フライドポテトではなく、お菓子を入れています。

あっと言う間に、すべてのえさをあげました
寒くても、子どもたちは楽しかったようで、大満足
オナガガモを近くから撮影

2010/12/28

青島健太さんに会社の周年記念事業の一つとして、記念講演をしていただきました。



講演タイトルは「青島健太の元気レシピ モチベーションアップ!」

青島 健太(あおしま けんた)さん
http://www.kouenirai.com/profile/208.htm


90分にわたり講演をしていただきました。野球に関するたとえ話で、ビジネスに応用して考えると、「こういうことですね」という流れの中で、お話は進みました。

印象に残ったのは、日本野球の「ストライク」と、大リーグの「Strike」の違いの話でした。大リーグのアンパイアが「Strike!」と動詞を一文字で言うということは、命令をしていることになります。日本語で言えば、バッターに対して「打ちなさい!」と言っていることになります。

それに対して、日本野球の「ストライク」という言い方は、昔「正球」あるいは、「よし」+本数(1本・2本)と言われていました。そこには、バッターに打ちなさいと言っているという意味はなく、ピッチャーに「いい投球でした」と言っているニュアンスがあります。日本の野球自体が、守備を重視した考え方をしているとのこと。

それに対して、バッターに対して「打ちなさい!」と言っているように見える大リーグでは、1球目からいいボールが来れば、どんどん打つ選手が多いとのこと。それが、日米の平均試合時間の差になってあらわれているとのことでした。

他にも、興味深いお話を何点もしていただきました。そのポイントだけを記載しておきます。

  • 日米野球の違いについて
  • イチローについて
  • 黒ひげ危機一髪ゲームをする
  • モチベーションについて
  • 革命家の条件 若くて貧しくて無名であること

最後に幹事より、キャッチボールのお願いをしていました。「こんなお願いは初めてです。」とおっしゃりながらも、会場の何人かと、やわらかいボールでキャッチボールをしてくださいました。

大変楽しい講演でした。青島さん、ありがとうございました。

2010/12/26

Twitterのツイート数がなぜか2倍になって表示されます。以前にも同じ現象が起きました。



Twitterのツイート数がなぜか2倍になって表示されます。


現在、1963ツイートと表示されています。昨日までの正しいツイート数は972でした。以前にも同じ現象が起きました。2010/11/29にツイート数が倍になり、2010/12/12に元に戻りました。そして、今日また、倍の表示になりました。これは何なんでしょうか?

2010/12/24

「育児日記EmiriSystem」にページを作ってみました。子どもが産まれた頃に、このシステムを知っていれば絶対に使っていたと思います。



「育児日記EmiriSystem」にページを作ってみました。

育児日記EmiriSystem
http://www.emiripapas.com/


子どもが産まれた頃に、このシステムを知っていれば絶対に使っていたと思います。

EmiriSystemとは、サイト上では、下記のように説明をされています。
EmiriSystemは、子どもの成長を写真カレンダーに整理してご家族で楽しむと同時に、せっかくつけた日記をもっとたくさんの人に見て欲しい、けれどもだれにでも見せたいというわけではない、といった育児日記ならではのご要望にお応えできる(Emiriパパ曰く多分世界で唯一の)日記システムです。
子どもが、小学生になると、こういうシステムを使おうという気は強くはないのですが、無料で使える部分を試してみました。

写真をコメント付きで登録します。


1日1件の登録作業が可能です。登録された写真はカレンダー表示で確認も出来ます。


登録した写真は、CDに出来たり、PDFにも変換出来ます。写真をアップロードするための方法も沢山用意されており、デスクトップを登録した写真でスライドショーを表示するガジェットも用意されています。


さらに電子書籍のePub形式にも対応しているとのことです。(サポート会員以上)

2010/12/23

Google Map API helper app for Djangoを使ってみたいので、再度Djangoをチュートリアルからやってみます。その1



Google Map API helper app for Djangoを使ってGoogle Mapsアプリを作ってみたいので、再度Djangoをチュートリアルからやってみます。

Google Map API helper app for Django
http://code.djangoproject.com/wiki/django-gmap


自宅内のLinux(Vine)サーバに現在に最新のDjango安定版をインストールします。

Djangoチュートリアル(前編)
http://codezine.jp/article/detail/4065
の内容をやりながら思い出します。


How to get Django
http://www.djangoproject.com/download/
より、Django-1.2.4.tar.gzをダウンロードしてインストール。


インストールされたことを確認します。
$ python
Python 2.4.4 (#1, Apr 25 2008, 09:54:36)
[GCC 3.3.6 release (Vine Linux 3.3.6-0vl7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.VERSION
(1, 2, 4, 'final', 0)

Django-1.2.4は、Python 2.4系でも動作するとのことで、これで行きます。

任意の階層にてDjangoプロジェクトを作成します。
$ django-admin.py startproject gmap

必要なファイルが一式生成されます。
$ cd gmap/
$ ls
__init__.py  manage.py  settings.py  urls.py

開発サーバの起動し動作確認をします。
$ ./manage.py runserver
-bash: ./manage.py: 許可がありません

「許可がありません」とエラーが出ます。

所有者の実行権限を加えます。
$ chmod u+x manage.py

再度、開発サーバの起動し動作確認をします。
$ ./manage.py runserver
Validating models...
0 errors found

Django version 1.2.4, using settings 'gmap.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

この状態で、家庭内の他のパソコンから、サーバの指定のポートにアクセスします。しかし、アクセスできません。

manage.py runserver にオプションとして、IPを指定しない (0.0.0.0 を使う)ことによって、ローカル以外からも接続可能になります。

再度、開発サーバの起動し動作確認をします。
$ ./manage.py runserver 0.0.0.0:8000
Validating models...
0 errors found

Django version 1.2.4, using settings 'gmap.settings'
Development server is running at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
[23/Dec/2010 03:32:22] "GET / HTTP/1.1" 200 2047

再度、ローカル以外でのパソコンでアクセスをすると


アクセス出来ました。

ここで作成したソースを一式 Subversionに登録しておきます。登録したソースをチェックアウトして再開。

setting.pyの編集(SQLiteを使う設定)
DATABASES = {
    'default': {
        'ENGINE': 'sqlite3',
        'NAME': 'gmap.sqlite',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}

TIME_ZONE = 'Asia/Tokyo'
LANGUAGE_CODE = 'ja'

DjangoプロジェクトのDB初期化をします。
$./manage.py syncdb

Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'hoge'): hoge
E-mail address: hoge@gmail.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Group_permissions model
Installing index for auth.User_user_permissions model
Installing index for auth.User_groups model
Installing index for auth.Message model
No fixtures found.

manage.pyからのDB接続をして内容の確認
$./manage.py dbshell
SQLite version 3.3.6
Enter ".help" for instructions

実行したSQLの内容を参照できます。
sqlite> .dump
BEGIN TRANSACTION;
CREATE TABLE "auth_permission" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(50) NOT NULL,
    "content_type_id" integer NOT NULL,
    "codename" varchar(100) NOT NULL,
    UNIQUE ("content_type_id", "codename")
);
INSERT INTO "auth_permission" VALUES(1, 'Can add permission', 1, 'add_permission');
INSERT INTO "auth_permission" VALUES(2, 'Can change permission', 1, 'change_permission');
INSERT INTO "auth_permission" VALUES(3, 'Can delete permission', 1, 'delete_permission');
INSERT INTO "auth_permission" VALUES(4, 'Can add group', 2, 'add_group');
INSERT INTO "auth_permission" VALUES(5, 'Can change group', 2, 'change_group');
INSERT INTO "auth_permission" VALUES(6, 'Can delete group', 2, 'delete_group');
INSERT INTO "auth_permission" VALUES(7, 'Can add user', 3, 'add_user');
INSERT INTO "auth_permission" VALUES(8, 'Can change user', 3, 'change_user');
INSERT INTO "auth_permission" VALUES(9, 'Can delete user', 3, 'delete_user');
INSERT INTO "auth_permission" VALUES(10, 'Can add message', 4, 'add_message');
INSERT INTO "auth_permission" VALUES(11, 'Can change message', 4, 'change_message');
INSERT INTO "auth_permission" VALUES(12, 'Can delete message', 4, 'delete_message');
INSERT INTO "auth_permission" VALUES(13, 'Can add content type', 5, 'add_contenttype');
INSERT INTO "auth_permission" VALUES(14, 'Can change content type', 5, 'change_contenttype');
INSERT INTO "auth_permission" VALUES(15, 'Can delete content type', 5, 'delete_contenttype');
INSERT INTO "auth_permission" VALUES(16, 'Can add session', 6, 'add_session');
INSERT INTO "auth_permission" VALUES(17, 'Can change session', 6, 'change_session');
INSERT INTO "auth_permission" VALUES(18, 'Can delete session', 6, 'delete_session');
INSERT INTO "auth_permission" VALUES(19, 'Can add site', 7, 'add_site');
INSERT INTO "auth_permission" VALUES(20, 'Can change site', 7, 'change_site');
INSERT INTO "auth_permission" VALUES(21, 'Can delete site', 7, 'delete_site');
CREATE TABLE "auth_group_permissions" (
    "id" integer NOT NULL PRIMARY KEY,
    "group_id" integer NOT NULL,
    "permission_id" integer NOT NULL REFERENCES "auth_permission" ("id"),
    UNIQUE ("group_id", "permission_id")
);
CREATE TABLE "auth_group" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(80) NOT NULL UNIQUE
);
CREATE TABLE "auth_user_user_permissions" (
    "id" integer NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL,
    "permission_id" integer NOT NULL REFERENCES "auth_permission" ("id"),
    UNIQUE ("user_id", "permission_id")
);
CREATE TABLE "auth_user_groups" (
    "id" integer NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL,
    "group_id" integer NOT NULL REFERENCES "auth_group" ("id"),
    UNIQUE ("user_id", "group_id")
);
CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY,
    "username" varchar(30) NOT NULL UNIQUE,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL,
    "email" varchar(75) NOT NULL,
    "password" varchar(128) NOT NULL,
    "is_staff" bool NOT NULL,
    "is_active" bool NOT NULL,
    "is_superuser" bool NOT NULL,
    "last_login" datetime NOT NULL,
    "date_joined" datetime NOT NULL
);
INSERT INTO "auth_user" VALUES(1, 'hoge', '', '', 'hoge@gmail.com', 'sha1$**********************************', 1, 1, 1, '2010-12-23 19:39:45.831076', '2010-12-23 19:39:45.831076');
CREATE TABLE "auth_message" (
    "id" integer NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL REFERENCES "auth_user" ("id"),
    "message" text NOT NULL
);
CREATE TABLE "django_content_type" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(100) NOT NULL,
    "app_label" varchar(100) NOT NULL,
    "model" varchar(100) NOT NULL,
    UNIQUE ("app_label", "model")
);
INSERT INTO "django_content_type" VALUES(1, 'permission', 'auth', 'permission');
INSERT INTO "django_content_type" VALUES(2, 'group', 'auth', 'group');
INSERT INTO "django_content_type" VALUES(3, 'user', 'auth', 'user');
INSERT INTO "django_content_type" VALUES(4, 'message', 'auth', 'message');
INSERT INTO "django_content_type" VALUES(5, 'content type', 'contenttypes', 'contenttype');
INSERT INTO "django_content_type" VALUES(6, 'session', 'sessions', 'session');
INSERT INTO "django_content_type" VALUES(7, 'site', 'sites', 'site');
CREATE TABLE "django_session" (
    "session_key" varchar(40) NOT NULL PRIMARY KEY,
    "session_data" text NOT NULL,
    "expire_date" datetime NOT NULL
);
CREATE TABLE "django_site" (
    "id" integer NOT NULL PRIMARY KEY,
    "domain" varchar(100) NOT NULL,
    "name" varchar(50) NOT NULL
);
INSERT INTO "django_site" VALUES(1, 'example.com', 'example.com');
CREATE INDEX "auth_permission_1bb8f392" ON "auth_permission" ("content_type_id");
CREATE INDEX "auth_group_permissions_425ae3c4" ON "auth_group_permissions" ("group_id");
CREATE INDEX "auth_group_permissions_1e014c8f" ON "auth_group_permissions" ("permission_id");
CREATE INDEX "auth_user_user_permissions_403f60f" ON "auth_user_user_permissions" ("user_id");
CREATE INDEX "auth_user_user_permissions_1e014c8f" ON "auth_user_user_permissions" ("permission_id");
CREATE INDEX "auth_user_groups_403f60f" ON "auth_user_groups" ("user_id");
CREATE INDEX "auth_user_groups_425ae3c4" ON "auth_user_groups" ("group_id");
CREATE INDEX "auth_message_403f60f" ON "auth_message" ("user_id");
COMMIT;

今日はここまで、次回へ続く

2010/12/20

旅のレストラン「西の屋」へ取材を兼ねて、家族でドライブに出かけました。



 2010/06/13に仕事の取材を兼ねて、「西の屋」さんの4店舗に家族でドライブに出かけました。

「西の屋」さんは山陽自動車道の山陽ICより北上をして、中国自動車道の美作ICまでに4店舗を構えるドライブインです。単にドライブインとしてではなく、各種体験施設や、団体旅行の方への魅力的なプランを提供できる場所であることが、取材をしていて分かってきました。

まず、赤坂店に向かいました。赤坂店には、桃太郎の像があります。あいにくの雨でしたが、その前で写真を撮りました。


その赤坂店で食事をしました。私は「ラーメンセット」、ボリュームがあり、お腹いっぱいになりました。他に「寿司セット(上)」「カツ丼」「和風かつカレー」を頼みました。


西の屋には、すべての店舗に水車が設置されています。


昼まえから、1時ぐらいまでにすべての店舗を回ったのですが、どのお店でも、観光バスが沢山停まっていることに驚きました。後日、平日も何度も取材に伺いましたが、平日でも昼時は観光バスがいつもいっぱいでした。すごいことです。


次に寄った、菊ヶ峠店では、お腹いっぱいのあとなので、鬼の像の前で写真を撮っただけでした。


湯郷店では、足湯を楽しめる施設があり、子ども共々、リフレッシュが出来ました。その後の取材でも何度か足湯に浸かりました。足湯はとても気持ちいいです。


ソフトクリームを食べて次の店舗に向かいました。


美作店に着いた頃には、子どもたちも、私も疲れてきて、「武蔵とお通」の看板で写真を撮るだけでした。


その取材から半年が経ち、今日、サイトリニューアルの公開が出来ました。まだまだ制作は続きますが、ひと段落です。

旅のレストラン西の屋グループ
http://www.nishinoya.co.jp/

2010/12/19

岡山県の「防災情報メール配信サービス」に登録しました。



岡山県の「防災情報メール配信サービス」に登録しました。

下記のチラシを小学校に行くお兄ちゃんが、学校でもらってきました。子どもが小学校でもらってきたものに関しては、よく目を通します。岡山は災害が少ない地域ですが、災害はいつ発生するか分かりません。災害に関する情報は沢山あったほうがよいので、配信をしていただく設定をしました。


岡山県 総合防災情報
http://www.bousai.pref.okayama.jp/bousai/

岡山県 総合防災情報のサイトにて、空メールの送受信でのユーザー確認の後、下記の画面で配信して欲しい情報を選択して登録します。


「地震情報」「避難勧告・避難指示等のお知らせ」をメール配信していただけるように設定しました。

2010/12/18

Google App Engineを使って、OAuth対応のTwitterボットの作り方を調べてみました。まず、Twitter APIの操作から



以前、「ASE(Android Scripting Environment)で作成したPythonスクリプトから、OAuth認証を経てTweet出来ました。」の記事でAndroidアプリから、OAuth認証経由でのTweetが出来たので、今度は、Google App Engineで同じことをやってみます。


ASE(Android Scripting Environment)で作成したPythonスクリプトから、OAuth認証を経てTweet出来ました。
http://vivo-design.blogspot.com/2010/10/aseandroid-scripting.html

同様のことを実装されている方のサイトを色々と拝見しました。その中で、下記のサイトの説明がとても分かりやすかったので、その方法で試させてもらいます。

Google App Engineで手軽にOAuthアプリを作成!(Twitterとか!) - AppEngine-OAuth
http://0-oo.net/sbox/python-box/appengine-oauth

 

必要なファイルを確認します。
  • main.py
  • app.yaml
  • basehandler.py
  • appengine_oauth.py
  • appengine_twitter.py

まず、TwitterアプリケーションをTwitterアプリケーションプラットフォームに登録をします。今回は、赤枠の「vivo_bot_by_gae」というアプリケーションを登録しました。この画面は、登録後の画面ですが、新規に追加をする際は、下部にある「新しいアプリケーションを追加」をクリックします。


 アプリケーション登録申請画面が表示されるので、必要事項を入力します。この画面は設定後のものです。


「アプリケーションの種類」は、「ブラウザアプリケーション」を指定します。「コールバックURL」はユーザ登録をするロジックを用意して、そのURLを設定しなければいけません。今回の場合は、

http://vivo-red.appspot.com/oauth/
にて、Twitterへの認証を申請して

http://vivo-red.appspot.com/oauth/callback
にて、Twitter APIより送られてきた認証結果を記録する処理をしています。その後は、記録した認証情報を使って、アクセスしていきます。

よって、「コールバックURL」には
http://vivo-red.appspot.com/oauth/callback
を指定します。

必要な情報を入力後、「保存する」を押すと申請の登録が完了します。

Application Details画面で表示されるので、
  • Consumer key
  • Consumer secret
の値を控えておきます。


次に main.py を3箇所修正します。
  • Consumer key を設定
  • Consumer secret を設定
  • メッセージの表示の部分を自分用に変更
    msg += u'http://vivo-red.appspot.com/oauth/callback からこんにちは!'

下記が変更したソースです。
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
Sample for AppEngine-OAuth on Google App Engine
 
See: http://0-oo.net/sbox/python-box/appengine-oauth
See also: http://apiwiki.twitter.com/OAuth-FAQ
'''
 
import logging
import wsgiref.handlers
from appengine_twitter import AppEngineTwitter
from basehandler import BaseHandler, h
from django.utils import simplejson
from google.appengine.ext import db
from google.appengine.ext import webapp
 
 
OAUTH_KEY = '*** ここにConsumer keyを設定 ***'
OAUTH_SECRET = '*** ここにConsumer secretを設定 ***'
 
 
class DemoHandler(BaseHandler):
 
  def demo_header(self):
    self.simple_header(u'AppEngine-OAuthのデモ')
 
    self.p(u'

AppEngine-OAuthのデモ

') def demo_footer(self): self.p(' ') self.p('
', True) self.p(u'このページは') self.p('') self.p(u'AppEngine-OAuth と ') self.p('') self.p(u'AppEngine-Twitter のデモです') self.simple_footer() class InitHandler(DemoHandler): def get(self): twitter = AppEngineTwitter() twitter.set_oauth(key=OAUTH_KEY, secret=OAUTH_SECRET) req_info = twitter.prepare_oauth_login() # request_tokenはcallbackされた後で使うのでDatastoreに保存しておく OAuthRequestToken(token=req_info['oauth_token'], secret=req_info['oauth_token_secret']).put() self.demo_header() self.p('') self.p(u'TwitterのOAuthログインへ', True) self.demo_footer() class CallbackHandler(DemoHandler): def get(self): twitter = AppEngineTwitter() twitter.set_oauth(OAUTH_KEY, OAUTH_SECRET) # TwitterからHTTP GETでrequest_tokenが渡される req_token = self.request.get('oauth_token') # Datastoreに保存しておいたreqest_token_secretを取り出す query = OAuthRequestToken.all() query.filter('token = ', req_token) req_tokens = query.fetch(1) # request_tokenとaccess_tokenを交換する acc_token = twitter.exchange_oauth_tokens(req_token, req_tokens[0].secret) # ここまで来ればOAuthを使ってAPIが使える。試しにユーザー名を取得 twitter.verify() name = simplejson.loads(twitter.last_response.content)['screen_name'] self.demo_header() self.p(u'こんにちは、' + name + u'さん!', True) self.p(' ') # 以後は再ログインせずにaccess_tokenを繰り返し使うことができる tw2 = AppEngineTwitter() tw2.set_oauth(OAUTH_KEY, OAUTH_SECRET, acc_token['oauth_token'], acc_token['oauth_token_secret']) msg = u'AppEngine-OAuth (on Python and Google App Engine) ' msg += u'http://vivo-red.appspot.com/oauth/callback からこんにちは!' tw2.update(msg.encode('utf8')) self.p(u'つぶやいたよ(自分のTLを見てね)', True) self.p(' ') if tw2.is_following('uresuji_books') == False: tw2.follow('uresuji_books') self.p(u'@uresuji_books をフォローしたよ', True) self.p(' ') self.p(u'最初のページへ戻る', True) self.demo_footer() #Model(s) class OAuthRequestToken(db.Model): token = db.StringProperty() secret = db.StringProperty() logging.getLogger() routing = [('/oauth/', InitHandler), ('/oauth/callback', CallbackHandler)] application = webapp.WSGIApplication(routing, debug=False) wsgiref.handlers.CGIHandler().run(application)
次に、Google App Engine Launcherを使ってアップします。
アプリを選んで、「Deploy」ボタンをクリックします。


Deploy Application to Googleの認証画面で、Emailとパスワードを入れて、「OK」ボタンを押します。


その後は自動でアップロードが始まり、動作状況がモニタされます。アップが完了すると、ウィンドウを閉じてもいいですよと、メッセージが表示されます。


用意が出来たサイトにアクセスをします。
「TwitterのOAuthログインへ」をクリックします。


Twitterへの認証許可の確認ページが表示されます。「許可する」をクリックします。


認証が完了し、Twitterユーザ名の取得と表示、そのTwitterユーザでのツイート、@uresuji_booksへのフォロー追加を実行した旨の表示がされます。


実際に動作したのかどうかを確認します。正常に動作していました。

ツイートの確認

 

フォロー追加の確認


これで後は、つぶやく内容、何をいつ、つぶやくかを設定していきます。

この内容を確認できるまでに、他にも、沢山のサイトに教えていただきました。ありがとうございます。

Twitter OAuth 自動化 with GAE/Py (Python-twoauth 版) - 混沌脳内
http://d.hatena.ne.jp/blaue_fuchs/20100926/1285497228

TwitterのbotをOAuthに対応させる
http://d.hatena.ne.jp/shibason/20090802/1249204953

TwitterボットをOAuthに対応させてみた - Google App Engine(Python)
http://blog.mudaimemo.com/search/label/google%20app%20engine

Google App Engine + Twitter + OAuthでTwitterにつぶやくためのメモ
http://blog.mudaimemo.com/2010/02/google-app-engine-twitter-oauth.html

GAE用のOAuthライブラリ simpleoauth-gae を作ってる

http://d.hatena.ne.jp/tagomoris/20100523/1274603964

python-twitter とついでに Mercurial を入れてみる

http://d.hatena.ne.jp/idemo/20100905/p2

Python-Twitter API構築
http://k-communication.sakura.ne.jp/blog/?p=83

2010/12/17

岡山県立大学にて、EOS Kiss X4で構内を撮影してみました。



仕事で EOS Kiss X4 を使って撮影をしてみました。岡山県立大学にて、構内の各建物を撮影しました。雲が多い天気でしたが、時折、晴れ間が出てきて、きれいな雲の時もありました。寒ーい冬の感じの写真が撮れました。

まだ、かんたん撮影モードと、Av(絞り優先AE)ぐらいしか使えませんが、それでも十分きれいに撮れます。

岡山県立大学
http://www.oka-pu.ac.jp/index.html

講堂
講堂
講堂
情報工学部棟とデザイン学部棟
保健福祉学部棟
保健福祉学部棟
こういった背景のボケた写真を撮ってみたかった

人気の投稿 (過去 30 日間)