GoogleCalendarに特定形式で予定を入れておけば指定したファイルのtailっぽいものをpusherに送信する仕組みを作ってみた 2011/8/27
pusherってどうなの?とおもってつくってみた。
説明
GoogleCalendarに特定形式で予定を入れておけば指定したファイルのtailっぽいものをpusherに送信します。
特定形式
"[Gcal2PusherTail]ファイルへのフルパス"で予定を作ってください。
予定の開始時刻にpusher送信が始まり、予定の終了時刻にpusher送信が終了します。
(例)
[Gcal2PusherTail]/var/log/system.log
開始:2011/9/1 12:00
終了:2011/9/1 13:00
だと/var/log/system.logの更新部分が2011/9/1 12:00 〜 13:00の期間に継続的にpusherに送信されます。
"pusher"
Google検索をお願いします。
使い道
使い道?特にありませんね。。。外部からサーバーのログを見たい時?ログインすればいいですよ
カレンダーからatを設定する部分はlinux環境とかでPT2とか使っているときの予約システムに流用できそうです。
セットアップ
必要なgemは人によって違うと思うのでエラーに従ってインストールしてください。
自環境では保存後のディレクトリはこうなりました
Googleカレンダーから予定を取ってきてatコマンドを入力する部分
gcal2at.rbで保存してください
#! /usr/bin/env ruby # -*- coding:utf-8 -*- require "/Users/seijiro/Desktop/test/my-lib.rb" class ThisDo < MyObject include MyGCalModule include MyAtModule end o = ThisDo.new o.gmail = "xxxxxxxxx" o.gmailpass = "xxxxxxxx" o.gcalfeedurl = 'xxxxxxxxxxxxxxxx' o.myscriptdir = "/xxxxxxxxxxxx/" o.myrbfiledir = "/xxxxxxxxxxxxxxx/" o.gcal_read.gcal_parse_2_jobs.gcaljobs_2_at
#! /bin/bash # cronでキックする用 #ユーザーの環境変数を読み込みたいときとか source /Users/seijiro/.bashrc ruby /Users/seijiro/Desktop/test/gcal2at.rb #使い方 #パスとか環境変数とかいろいろあると思います。適宜。
設定
1.pusher送信を行うPCに保存したスクリプトを設置する
2.このファイルの以下を変更してください
#ファイルを配置した場所に従って
require "/ここを変更/my-lib.rb"
o.gmail = "Gmailアドレス"
o.gmailpass = "Gmailパスワード"
o.gcalfeedurl = 'http://www.google.com/calendar/feeds/あなたのメールアドレスの@を%40にかえたもの/private/full'
# atコマンドがキックするスクリプトファイルを貯めておくディレクトリパス
o.myscriptdir = "/フルパス/at/"
# atコマンドがキックするファイルが存在するディレクトリ
o.myrbfiledir = "/フ/ル/パ/ス/test/"
3.cronで適当な間隔でこのスクリプトまたはgcal2at.shを実行するように設定する。
gacl2at.shをつかうのは自環境ではrubyが特殊な位置にあるためです。
atコマンドからキックされてにtailっぽいものをpusherに送信する部分
pushertail.rbで保存してください
#! /usr/bin/env ruby # -*- coding: utf-8 -*- require "/Users/seijiro/Desktop/test/my-lib.rb" class ThisDo < MyObject include RunPerSecModule include MyPusherModule def initialize @f = open(ARGV[0]||"/var/log/system.log") while @f.gets #最後の行までとりあえず読み込み end @endtime = Time.parse(ARGV[1]) || Time.now + 60 * 5 #5分 @pusher_app_id = 'yourapp_id' @pusher_key = ' your key' @pusher_secret = 'your secret ' end def main_loop data = "" while @f.gets data << $_ print $_ #確認!!! end pusherkick(data) unless data=="" end def loop_hook_post stop_run if loopok? end def pusherkick(data) data = data.toutf8.gsub("\n","<br>") push_pusher('my_app_tail',data) end def loopok? Time.now > @endtime end end instance = ThisDo.new instance.run(1) do puts "check:" + Time.now.to_s end
設定
以下を設定してください
・require "/フルパス/my-lib.rb"
・@pusher_app_id = 'yourapp_id'
・@pusher_key = ' your key'
・@pusher_secret = 'your secret '
pusherを読む部分
適当な名前で保存してchromeで読みこめば(ファイルをドラッグアンドドロップ!!)いいと思います。
もしかするとサーバーからもらわないとchromeがjavascriptが実行しないかも知れない。
そのときはapache経由で読み込んでください。
htmlはどこかからかコピペしました。場所を忘れてしまいました。
<!DOCTYPE html> <head> <title>PusherTail</title> <script src="http://js.pusherapp.com/1.8/pusher.min.js"></script> <script> // Enable pusher logging - don't include this in production Pusher.log = function(message) { if (window.console && window.console.log) window.console.log(message); }; // Flash fallback logging - don't include this in production WEB_SOCKET_DEBUG = true; var pusher = new Pusher('xxxxxx'); var channel = pusher.subscribe('test_channel'); channel.bind('my_event', function(data) { hoge = document.getElementById("main").innerHTML; document.getElementById("main").innerHTML = data['my_app_tail'] + "<hr>" + hoge; }); </script> </head> <body> run at Chrome <div id="main"> </div> </body>
設定
var pusher = new Pusher('xxxxxx');でxxxxxにapp_keyを設定してください
使ってる俺俺ライブラリ
my-lib.rbで保存してください
#! ruby # -*- coding: utf-8 -*- DEBUG = false # # 俺俺な典型的な動作を提供する # # こんな感じで使うと良い # # require "/Users/seijiro/code/ruby/my-lib.rb" # class This < MyObject # include RunPerSecModule # include MyDBModule # include MyPusherModule # ..... # # end # # 俺俺インスタンスをつくるためにクラスを用意した # 典型的なrequireを書きこんでいく # 読み込み済みモジュール # kconv time class MyObject require "kconv" require "time" end # 指定秒数ごとにrun関数をループする # 各メソッドを必要に応じて再定義して使う。 # # 使い方: # someinstance.extend RunPerSecModule # someinstance.run(ループのインターバルsec){ # __block__for__yield__ # } # # OR # # class ThisDo < MyObject # include RunPerSecModule # ..... # module RunPerSecModule # ループフラグ @loop_flg # main_loopをループする # sec : ループ間隔 秒 # before_run_loop,ループ,after_run_loopの順番で実行する。 # ループの中身はloop_hook_pre,与えられたブロック,main_loop,loop_hook_postの順番で実行する def run(sec) init_run_per_sec_module before_run_loop while @loop_flg loop_hook_pre yield main_loop loop_hook_post sleep sec end after_run_loop end # 外からは使わない # 無限ループフラグを立てる def init_run_per_sec_module @loop_flg = true end # runのループを止める def stop_run @loop_flg = false end # runメソッドが呼ばれるとループの前に一回だけ実行される def before_run_loop puts "beforerun" if DEBUG end # runメソッドのloopの中で最初に実行される def loop_hook_pre puts "prehook" if DEBUG end # runメソッドのloopの中で実行される def main_loop puts "main loop" if DEBUG end # runのループの中でmain_loopのあとで実行される def loop_hook_post puts "posthook" if DEBUG end # runメソッドが呼ばれるとループのあとで実行される def after_run_loop puts "afterrun" if DEBUG end end # Pusherサービスへのアクセスを提供する # https://app.pusherapp.com/apps/7449/api_access?welcome=true # @pusher_app_id = 'your pusher app id' # @pusher_key = 'pusher key' # @pusher_secret = 'pusher secret' # # 使い方など # class ThisDo # include MyPusherModule # して # o = ThisDo.new # o.pusher_app_id = 'your pusher app id' # o.puserh_key = 'your pusher key' # o.pusher_secret = 'your pusher secret' # o.push_pusher('test_app','test') # とかでok module MyPusherModule #pussherが設定されているか? @pusherconnected #設定 attr_accessor :pusher_app_id,:pusher_key,:pusher_secret # Pusherへの接続を設定する def set_my_pusher require "pusher" Pusher.app_id = @pusher_app_id Pusher.key = @pusher_key Pusher.secret = @pusher_secret @pusher_event = 'my_event' @pusher_channel = 'test_channel' end # Pusherにデータをpushする # args # app_name : string アプリの名前 # data : string データ def push_pusher(app_name='test_app',data='test') if @pusherconnected == nil set_my_pusher @pusherconnected = true end begin Pusher[@pusher_channel].trigger!(@pusher_event, { app_name => data}) rescue Pusher::Error => e p e if DEBUG end end end # Googleカレンダーへのアクセスを提供する # @gmail = "your gamil address" # @gmailpass = "your gmail password" # @gcalfeedurl = "your gmail feedurl" # # 使い方など # class ThisDo # include MyGCalModule # して # o = ThisDo.new # o.gmail = "your gamil address" # o.gmailpass = "your gmail password" # o.gcalfeedurl = "your gmail feedurl" # #最近の日程を取ってくる # o.gcal_read # とかでok module MyGCalModule attr_accessor :gmail,:gmailpass,:gcalfeedurl,:gcal_query def gcal_read service @gcal_events = @gcal.events return self end #GCalへ書きこむ def gcal_write(eventdata) service event = @gcal.create_event event.title = eventdata[:title] event.st = eventdata[:start] event.en = eventdata[:end] event.save! @gcal_event = event return self end # gcalのイベントをAtMduleが食べれる形に変換する #共通のJOBクラスで包もうかしら? def gcal_parse_2_jobs @gcal_jobs = [] q = @gcal_query ||= '[Gcal2PusherTail' @gcal_events.each do |event| begin kind,filename = event.title.split(']') if(kind == @gcal_query && filename != nil) @gcal_jobs << {:filename => filename, :start => event.st, :end => event.en, :object => event} end rescue #握りつぶす end end return self end #fetchしたデータの取り込み済みマークを立てる def gcal_checkout(event) event.title = '[FETCHED]' + event.title event.save! return self end # GCalへのアクセス def service if @gcal_srv.nil? require 'gcalapi' @gcal_srv = GoogleCalendar::Service.new(@gmail, @gmailpass) end @gcal = GoogleCalendar::Calendar::new(@gcal_srv, @gcalfeedurl) end end # Atコマンドを突っ込む # MyGCalModuleとの連携で使う # 使い方など # class ThisDo # include MyAtModule # include MyGCalModule # して # o = ThisDo.new #o.gmail = "your gamil address" #o.gmailpass = "your gmail password" #o.gcalfeedurl = "your gmail feedurl" #o.myscriptdir = "path/to/generatedscriptfilesavepath/" #o.myrbfiledir = "path/to/rubyscriptpath/" # # とかでok module MyAtModule #設定 attr_accessor :myscriptdir,:myrbfiledir def gcaljobs_2_at @gcal_jobs.each { |job| jobs2at(job) } return self end def jobs2at(job) command = _at_command(job) File.open("#{_at_scriptpath(job)}","w") do |io| io.write(command) end atcommand = "/usr/bin/at -f #{_at_scriptpath(job)} #{job[:start].localtime.strftime("%H:%M %m/%d/%y")}" atcommand = "/usr/bin/at -f #{_at_scriptpath(job)} #{(Time.now.localtime + 60).strftime("%H:%M %m/%d/%y")}" if DEBUG p atcommand p command system atcommand gcal_checkout(job[:object]) unless DEBUG end def _at_scriptpath(job) "#{@myscriptdir}job2at_#{job[:start].localtime.strftime("%Y%m%d%H%M")}.sh" end def _at_command(job) "#! /bin/bash #ユーザーの環境変数パスを使いたい source ~/.bashrc; growlnotify -t 'Gcal2At' -m 'pusher tail #{job[:filename]} start . end is #{job[:start].localtime.strftime("%Y/%m/%d/%H/%M")}' ruby #{@myrbfiledir}pushertail.rb #{job[:filename]} '#{job[:end].to_s}' " end end