サイボウズ9・サイボウズ10のスケジュールをiCal形式でGoogleカレンダーに同期(一方通行)
公開日:
:
最終更新日:2015/03/11
プログラミング
スポンサーリンク
目次
サイボウズ10対応(2015/3/11)
なんか同期してないなと思ったらいつの間にかサイボウズってUTF-8になってるし、一部変わってしまってるみたいなので頑張って直し中。あぁ、10にあげてからずっとだったのか・・・。とほほ。
ということで変更しました。サイボウズ10は文字コードとスケジュールIDを取得するところが変更になります。サイボウズ Office Version 10.1.2 20140605223446にて動作確認。
「サイボウズofffice8と同期するツール暫定版」に感謝
サイボウズ→Googleカレンダーの一方通行同期なのですが、「名古屋ではたらく社長ブログだもんで」さんで公開されておられる「サイボウズofffice8と同期するツール暫定版」を便利に使わせていただいておりました。.htaccessとindex.phpだけで構成されています。シンプルにしてしっかり動作。素晴らしい。
サイボウズ9対応
このたびサイボウズ9用にバージョンアップしたところ、スケジュールのHTML構成が若干変わっておりましたので、変更部に応じてスクリプトを勝手改変しました。とりあえず的にかなり決め打ちなことをしているので、バージョンアップの際には対応しなくてはいけなくなると思います。
オリジナルとの変更点
- 複数人で使用できるようにコンフィグファイルを分離
- 変更されたHTMLになんとか無理やり対応
- スケジュールタイトルをCybozuで固定
- 各種修正(職場のサイボウズの予定をiPodで持ち歩く | Sunvisor Lab.も反映
設置方法
オリジナルファイルのreadme.txtをご参照ください。
.htaccessとindex.php、namethis.phpを設置。
namethis.phpは適当な名前に変更してください。この名前.icsに対してGoogleカレンダーからアクセスさせます。Googleカレンダーの設定は「他のカレンダー」→「URLで追加」からhttp://hoge.hoge/namethis.icsとします。
残念ながら、Googleカレンダーの外部参照は更新頻度が数時間に一回程度なのでなかなか更新されないことがあります。また、スケジュールが丸見えになるのでGoogle以外には見せないなどの対応も必要になります。
その他
自己責任でお願い致します。使用上のいかなる不都合、損害、トラブルに関しましても一切責任を負いません。
Gist
https://gist.github.com/guitarmasaki/6337430
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
<?php /* 名古屋ではたらく社長ブログだもんで サイボウズofffice8と同期するツール暫定版 http://ameblo.jp/sitescope/entry-10260113074.html 上記にて公開していただいているスクリプトをサイボウズ9用に勝手改変版 */ $sstitle = @$_REQUEST['data']; $uid = ''; if ( strlen($sstitle) > 5 ) { $uid = substr($sstitle, 4); } //ユーザ名・パスワードをロード require_once($sstitle.'.php'); //------------------------------------------------------------------------------------------------------------------- // 設定 //------------------------------------------------------------------------------------------------------------------- //define("CHAR_CODE", 'SJIS'); //サイボウズの文字コード サイボウズ9はSJIS define("CHAR_CODE", 'UTF-8'); //サイボウズの文字コード サイボウズ10はUTF define("SCHEDULE_TITLE", 'Cybozu'); //スケジュールタイトル define("SCHEDULE_MEMO", TRUE); //スケジュールメモまで取得する場合は'TRUE' define('PRODID', 'Cybozu2iCal'); //http://ameblo.jp/sitescope/entry-10260113074.html //------------------------------------------------------------------------------------------------------------------- //POSTデータ組み立て $data = array( "_System" => "login", "_Login" => "1", "LoginMethod" => "2", "_Account" => LOGIN_ID, "Password" => LOGIN_PASS ); $data = http_build_query($data, "", "&"); //headerにセット $header = array( "Content-Type: application/x-www-form-urlencoded", "Content-Length: ".strlen($data) ); $context = array( "http" => array( "method" => "POST", "header" => implode("\r\n", $header), "content" => $data ) ); //とりあえず個人月間スケジュール if ( UID == "" ) { $url = CYBOZU_URL . '?page=ScheduleUserMonth'; } else { $url = CYBOZU_URL . '?page=ScheduleUserMonth&UID=' . UID; } //サイボウズからHTMLデータ取得 $work = file_get_contents($url, false, stream_context_create($context)); //文字コードをUTF-8へ変換 $work = mb_convert_encoding($work, "UTF-8", CHAR_CODE); //正規表現がめんどくさいのでそのまま文字列比較で不要なとこをまず削除 $work = substr(strchr($work,'<table class="schedule usermonth" id="schedulemonth" width="100%" >'), 0); $work = substr($work, 0, strpos($work, '<table class="monthNavi" ')); $work = substr(strchr($work,'<tbody id="um__body">'), 0); $work = substr($work, 0, strpos($work, '</table>')); //文字列比較でとりあえず、スケジュールを配列に格納 $wdate1 = ""; $wdate2 = ""; $schedule_list = ""; $loop_flg = TRUE; while ( $loop_flg == TRUE ) { //日付の取得 $wdate = ""; $wdate = substr(strchr($work,'<span class="date">'), 19); $wdate = substr($wdate, 0, strpos($wdate, '</span>')); if ($wdate == "") { break; } //日付のフォーマットを変更 $date_sp = ""; $date_sp = split('/', $wdate); $schedule_date = Date('Y') . sprintf("%02d",$date_sp[0]) . sprintf("%02d",$date_sp[1]); //次の日も取得しとく $schedule_date_tommorow = ""; $schedule_date_tommorow = Date('Ymd', mktime(0, 0, 0, (int)$date_sp[0], (int)((int)$date_sp[1] + 1), (int)Date('Y') ) ); //日付部分をカット $work = substr(strchr($work,'<span class="date">'), 30); $loop_flg2 = TRUE; while ( $loop_flg2 == TRUE ) { if ( strpos($work, '<a class="event" href=') > strpos($work, '<span class="date">') ) { break; } else { //スケジュールIDを取得 //サイボウズ9 // $schedule_id = substr(strchr($work,'<div class="eventLink scheduleMarkTitle0" name="'), 53); // $schedule_id = substr($schedule_id, 0, strpos($schedule_id, '">')); //サイボウズ10 $schedule_id = substr(strchr($work,'<div class="eventLink scheduleMarkTitle0 highlight-event'), 56); $schedule_id = substr($schedule_id, 0, strpos($schedule_id, '" ')); if ( $schedule_id == "" ) { break; } //---------------------------------- if ( SCHEDULE_MEMO ) { //スケジュール内容まで取得 $wlink = substr(strchr($work,'<a class="event" href="ag.cgi?'), 30); $wlink = substr($wlink, 0, strpos($wlink, '" title="')); $url = CYBOZU_URL . '?' . $wlink; //サイボウズからHTMLデータ取得 $work2 = file_get_contents($url, false, stream_context_create($context)); //文字コードをUTF-8へ変換 $work2 = mb_convert_encoding($work2, "UTF-8", CHAR_CODE); //正規表現がめんどくさいのでそのまま文字列比較で不要なとこをまず削除 $work2 = substr(strchr($work2,'<table class="dataView scheduleDataView" width="100%" >'), 0); $work2 = substr($work2, 0, strpos($work2, '<span class="vr_scheduleUserCount">')); //スケジュールタイトルを取得 $work2 = str_replace("\n\r","", $work2); $work2 = str_replace("\n","", $work2); $work2 = str_replace("\r","", $work2); $schedule_description = substr(strchr($work2,'<div id="scheduleMemo"><tt>'), 27); $schedule_description = substr($schedule_description, 0, strpos($schedule_description, '</tt>')); $schedule_description = strip_tags($schedule_description); } //---------------------------------- //スケジュールタイトルを取得 $schedule_title = substr(strchr($work,'=sm" title="'), 12); $schedule_title = substr($schedule_title, 0, strpos($schedule_title, '">')); //時刻を取得 if (strpos($work, '<span class="eventDateTime">') < strpos($work, '=sm" title="')) { $schedule_time = substr(strchr($work, '<span class="eventDateTime">'), 28); $schedule_time = substr($schedule_time, 0, strpos($schedule_time, ' ')); } else { $schedule_time = ''; } //タイトル部分をカット $work = substr(strchr($work,'=sm" title="'), 12); //時間指定があるか判定 if ( !empty($schedule_time) ) { $time_sp = ""; $time_sp = split('-', $schedule_time); $from_sp = split(':', @$time_sp[0]); //http://www.sunvisor.net/node/383 if ( count($time_sp) > 1 ) { $to_sp = split(':', @$time_sp[1]); } else { $to_sp = $from_sp; } $from_sp[0] = sprintf('%02d', @$from_sp[0]); $to_sp[0] = sprintf('%02d', @$to_sp[0]); $from_hour = ""; $to_hour = ""; if ($from_sp[0]<10) { $from_hour = '0' . @$from_sp[0]; } else { $from_hour = $from_sp[0]; } if ($to_sp[0]<10) { $to_hour = '0' . $to_sp[0]; } else { $to_hour = $to_sp[0]; } if (count($to_sp)<2){ $to_hour = $from_hour + 1; $to_sp[1] = $from_sp[1]; } $schedule_summary = $schedule_title; //http://www.sunvisor.net/node/383 $schedule_from = ':' . $schedule_date . 'T' . @$from_sp[0] . @$from_sp[1]. '00'; $schedule_to = ':' . $schedule_date . 'T' . @$to_sp[0] . @$to_sp[1]. '00'; $schedule_description = $schedule_title . " " . $schedule_description; } else { $schedule_summary = $schedule_title; //http://www.sunvisor.net/node/383 $schedule_from = ';VALUE=DATE:' . $schedule_date; $schedule_to = ';VALUE=DATE:' . $schedule_date_tommorow; $schedule_description = $schedule_title . " " . $schedule_description; } //http://www.sunvisor.net/node/383 $schedule_list[] = Array('id' => $schedule_id.$schedule_date, 'description' => $schedule_description, 'dtstart' => $schedule_from, 'dtend' => $schedule_to, 'summary' => $schedule_summary); } } } //ここから出力 header('Content-Type: text/calendar; charset=utf-8'); echo 'BEGIN:VCALENDAR'. "\n"; echo 'PRODID:' . PRODID. "\n"; echo 'VERSION:2.0'. "\n"; echo 'METHOD:PUBLISH'. "\n"; echo 'CALSCALE:GREGORIAN'. "\n"; echo 'X-WR-CALNAME:' . SCHEDULE_TITLE . "\n"; echo 'X-WR-CALDESC:' . SCHEDULE_TITLE . "\n"; echo 'X-WR-TIMEZONE:Asia/Tokyo'. "\n"; if ( !empty($schedule_list) ) { foreach ( $schedule_list as $key => $vale ) { echo 'BEGIN:VEVENT'. "\n"; echo 'UID:' . SCHEDULE_TITLE . '-' . $vale['id'] . "\n"; echo 'DESCRIPTION:' . $vale['description']. "\n"; //http://www.sunvisor.net/node/383 echo 'DTSTART;TZID=Asia/Tokyo' . $vale['dtstart'] . "\n"; echo 'DTEND;TZID=Asia/Tokyo' . $vale['dtend'] . "\n"; echo 'SUMMARY:'. $vale['summary']. "\n"; echo 'END:VEVENT'. "\n"; } } echo 'BEGIN:VTIMEZONE'. "\n"; echo 'TZID:Asia/Tokyo'. "\n"; echo 'BEGIN:STANDARD'. "\n"; echo 'DTSTART:19700101T000000'. "\n"; echo 'TZOFFSETFROM:+0900'. "\n"; echo 'TZOFFSETTO:+0900'. "\n"; echo 'END:STANDARD'. "\n"; echo 'END:VTIMEZONE'. "\n"; echo 'END:VCALENDAR'. "\n"; ?> |
Comment
[…] […]