2010年06月11日 Google カレンダーをJAVAで操作する
_ Google カレンダーをJAVAで操作する
Googleカレンダーをjavaで操作する仕事を依頼されそうになった。慌てて調べてみた。すごく苦労した。なのでまとめておく。
CalendarTest.java
// // GoogleCalendar操作実験プログラム by m-ito // // 「わし、くらうどになるねん」 // // Download : gdata-samples.java-1.41.3.zip from http://code.google.com/p/gdata-java-client/ // // CLASSPATH=.; // C:\Program Files\Java\jre1.6.0_02\lib\ext\QTJava.zip; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\lib\gdata-client-1.0.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\lib\gdata-client-meta-1.0.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\lib\gdata-calendar-2.0.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\lib\gdata-calendar-meta-2.0.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\lib\gdata-maps-2.0.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\lib\gdata-maps-meta-2.0.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\deps\google-collect-1.0-rc1.jar; // C:\Some_Where\gdata-samples.java-1.41.3\gdata\java\deps\jsr305.jar // // Compile : javac -encoding utf-8 CalendarTest.java // // Usage : java CalendarTest Googleのアカウント パスワード // import com.google.gdata.client.*; import com.google.gdata.client.calendar.*; import com.google.gdata.data.*; import com.google.gdata.data.acl.*; import com.google.gdata.data.calendar.*; import com.google.gdata.data.extensions.*; import com.google.gdata.util.*; import java.net.*; import java.io.*; import java.util.List; public class CalendarTest { public static void main(String[] args) throws Exception { //============================================================ // プロキシーの設定 //============================================================ System.setProperty("http.proxyHost", "192.168.0.100"); System.setProperty("http.proxyPort", "8080"); System.setProperty("https.proxyHost", "192.168.0.100"); System.setProperty("https.proxyPort", "8080"); //============================================================ // カレンダーサービスオブジェクト作成 // o この親玉オブジェクトを介してGoogleCalendarを操作していく // o 引数はオブジェクトを識別するための(?)任意文字列 //============================================================ CalendarService myService = new CalendarService("Sample-Service-Name"); //============================================================ // ログイン処理 //============================================================ String account = args[0]; // 1個目の引数 String password = args[1]; // 2個目の引数 myService.setUserCredentials(account, password); //============================================================ // アクセスするURLオブジェクトの作成 // o 操作対象や、希望する機能ごとにいろんなURLが定められているみたい // o とりあえず個人のカレンダーに登録されたイベントを操作する場合はこのURL //============================================================ // URL postUrl = new URL("http://www.google.com/calendar/feeds/カレンダーID/private/full"); // o カレンダーIDがdefaultの場合はアカウントを指定したのと同じ // URL feedUrl = new URL("http://www.google.com/calendar/feeds/default/private/full"); //============================================================ // 全件のイベントを取得 //============================================================ System.out.println("===== 全件のイベントを取得 ====="); // // イベントオブジェクトを作成 // o カレンダー上の全イベント情報を持つオブジェクト // CalendarEventFeed myFeed1 = myService.getFeed(feedUrl, CalendarEventFeed.class); // // 全イベントをイベントエントリオブジェクトのリスト形式で取得 // List<CalendarEventEntry> feeds1 = myFeed1.getEntries(); // // 個々のイベントエントリオブジェクトから項目を取り出して表示 // for (CalendarEventEntry entry1 : feeds1) { System.out.println(entry1.getTitle().getPlainText() + "|" + entry1.getTextContent().getContent().getPlainText() + "|" + entry1.getTimes().get(0).getStartTime().toString() + "|" + entry1.getTimes().get(0).getEndTime().toString()); } //============================================================ // 開始日時、終了日時を指定してイベントを取得 //============================================================ System.out.println("===== 開始日時、終了日時を指定してイベントを取得 ====="); // // カレンダー問い合わせオブジェクト作成 // o 問合せ条件を設定するためのオブジェクト // CalendarQuery myQuery2 = new CalendarQuery(feedUrl); // // 問合せ条件(開始日時下限〜上限)設定 // o yyyy-mm-ddThh:mm:ss.mmm+09:00 // - yyyy : 西暦年 // - mm : 月 // - dd : 日 // - T : 固定値(?) // - hh : 時 // - mm : 分 // - ss : 秒 // - mmm : マイクロ秒 // - +09:00 : 固定値(グリニッジ標準時 + 09:00 = 日本標準時間) // myQuery2.setMinimumStartTime(DateTime.parseDateTime("2010-05-01T00:00:00.000+09:00")); myQuery2.setMaximumStartTime(DateTime.parseDateTime("2010-05-15T23:59:59.999+09:00")); // // 問合せを実行し、イベントオブジェクトを得る // o 問合せ結果の全イベント情報を持つオブジェクト // CalendarEventFeed ResultsFeed2 = myService.query(myQuery2, CalendarEventFeed.class); // // 問合せ結果の全イベントをイベントエントリオブジェクトのリスト形式で取得 // List<CalendarEventEntry> feeds2 = ResultsFeed2.getEntries(); // // 個々のイベントエントリオブジェクトから項目を取り出して表示 // for (CalendarEventEntry entry2 : feeds2) { System.out.println(entry2.getTitle().getPlainText() + "|" + entry2.getTextContent().getContent().getPlainText() + "|" + entry2.getTimes().get(0).getStartTime().toString() + "|" + entry2.getTimes().get(0).getEndTime().toString()); } //============================================================ // 全文検索でイベントを取得 // o 時に曖昧な結果を返す(日本語を含む場合?は使えないと思っ // ておいたほうが...) //============================================================ System.out.println("===== 全文検索でイベントを取得 ====="); // // カレンダー問い合わせオブジェクト作成 // o 問合せ条件を設定するためのオブジェクト // CalendarQuery myQuery3 = new CalendarQuery(feedUrl); // // 問合せ条件(全文検索文字列)設定 // myQuery3.setFullTextQuery("NW"); // // 問合せ条件(何件目から結果を受け取るか)設定 // myQuery3.setStartIndex(1); // // 問合せ条件(最大何件結果を受け取るか)設定 // myQuery3.setMaxResults(3); // // 問合せを実行し、イベントオブジェクトを得る // o 問合せ結果の全イベント情報を持つオブジェクト // CalendarEventFeed ResultsFeed3 = myService.query(myQuery3, CalendarEventFeed.class); // // 問合せ結果の全イベントをイベントエントリオブジェクトのリスト形式で取得 // List<CalendarEventEntry> feeds3 = ResultsFeed3.getEntries(); // // 個々のイベントエントリオブジェクトから項目を取り出して表示 // for (CalendarEventEntry entry3 : feeds3) { System.out.println(entry3.getTitle().getPlainText() + "|" + entry3.getTextContent().getContent().getPlainText() + "|" + entry3.getTimes().get(0).getStartTime().toString() + "|" + entry3.getTimes().get(0).getEndTime().toString()); } //============================================================ // イベントを追加 //============================================================ System.out.println("===== イベントを追加 ====="); // // 追加用のイベントエントリオブジェクトを作成 // CalendarEventEntry myEntry = new CalendarEventEntry(); // // 追加用のイベントエントリオブジェクトにタイトル設定 // myEntry.setTitle(new PlainTextConstruct("秘密3")); // // 追加用のイベントエントリオブジェクトに本文設定 // myEntry.setContent(new PlainTextConstruct("ないしょだよーん3")); // // 日時オブジェクトに開始日時設定 // DateTime startTime = DateTime.parseDateTime("2010-06-30T08:45:00.000+09:00"); // // 日時オブジェクトに終了日時設定 // DateTime endTime = DateTime.parseDateTime("2010-06-30T17:15:00.000+09:00"); // // 何時オブジェクト作成 // When eventTimes = new When(); // // 何時オブジェクトに開始日時、終了日時設定 // eventTimes.setStartTime(startTime); eventTimes.setEndTime(endTime); // // 追加用のイベントエントリオブジェクトに何時オブジェクト(開始日時、終了日時)追加 // myEntry.addTime(eventTimes); // // 追加実行 // CalendarEventEntry insertedEntry = myService.insert(feedUrl, myEntry); //============================================================ // イベントを更新 //============================================================ System.out.println("===== イベントを更新 ====="); // // カレンダー問い合わせオブジェクト作成 // o 問合せ条件を設定するためのオブジェクト // CalendarQuery myQuery4 = new CalendarQuery(feedUrl); // // 問合せ条件(開始日時下限〜上限)設定 // myQuery4.setMinimumStartTime(DateTime.parseDateTime("2010-06-30T08:45:00.000+09:00")); myQuery4.setMinimumStartTime(DateTime.parseDateTime("2010-06-30T08:45:00.999+09:00")); // // 問合せを実行し、イベントオブジェクトを得る // o 問合せ結果の全イベント情報を持つオブジェクト // CalendarEventFeed ResultsFeed4 = myService.query(myQuery4, CalendarEventFeed.class); // // 問合せ結果の全イベントをイベントエントリオブジェクトのリスト形式で取得 // List<CalendarEventEntry> feeds4 = ResultsFeed4.getEntries(); // // 個々のイベントエントリオブジェクトから項目を取り出して更新 // for (CalendarEventEntry entry4 : feeds4) { System.out.println("今から修正するイベント : " + entry4.getTitle().getPlainText() + "|" + entry4.getTextContent().getContent().getPlainText() + "|" + entry4.getTimes().get(0).getStartTime().toString() + "|" + entry4.getTimes().get(0).getEndTime().toString()); // // イベントエントリオブジェクト中のタイトルと本文を修正 // o 開始日時、終了日時の修正はできないみたい // entry4.setTitle(new PlainTextConstruct("すっごい秘密3")); entry4.setContent(new PlainTextConstruct("絶対ないしょだよーん3")); // // 検索&修正したイベントエントリオブジェクトから更新用のURLオブジェクトを生成 // URL editUrl = new URL(entry4.getEditLink().getHref()); // // 更新実行 // CalendarEventEntry updatedEntry = (CalendarEventEntry)myService.update(editUrl, entry4); } //============================================================ // イベントを削除 //============================================================ System.out.println("===== イベントを削除 ====="); // // カレンダー問い合わせオブジェクト作成 // o 問合せ条件を設定するためのオブジェクト // CalendarQuery myQuery5 = new CalendarQuery(feedUrl); // // 問合せ条件(開始日時下限〜上限)設定 // myQuery5.setMinimumStartTime(DateTime.parseDateTime("2010-06-30T08:45:00.000+09:00")); myQuery5.setMaximumStartTime(DateTime.parseDateTime("2010-06-30T17:15:00.999+09:00")); // // 問合せを実行し、イベントオブジェクトを得る // o 問合せ結果の全イベント情報を持つオブジェクト // CalendarEventFeed ResultsFeed5 = myService.query(myQuery5, CalendarEventFeed.class); // // 問合せ結果の全イベントをイベントエントリオブジェクトのリスト形式で取得 // List<CalendarEventEntry> feeds5 = ResultsFeed5.getEntries(); // // 個々のイベントエントリオブジェクトを削除 // for (CalendarEventEntry entry5 : feeds5) { System.out.println("今から削除するイベント : " + entry5.getTitle().getPlainText() + "|" + entry5.getTextContent().getContent().getPlainText() + "|" + entry5.getTimes().get(0).getStartTime().toString() + "|" + entry5.getTimes().get(0).getEndTime().toString()); // // 検索したイベントエントリオブジェクトから削除用のURLオブジェクトを生成 // URL deleteUrl = new URL(entry5.getEditLink().getHref()); // // 削除用のURLオブジェクトから削除用イベントエントリオブジェクトを作成 // CalendarEventEntry delentry = myService.getEntry(deleteUrl, CalendarEventEntry.class); // // 削除実行 // delentry.delete(); } } }
結局その案件は無くなった:(
2019年06月11日 UiPath memo (RPA)
_ UiPath memo (RPA)
フローチャート
使用可能 -> ワークフロー -> フローチャート -> フローチャート(Flowchart)
順実行
使用可能 -> ワークフロー -> 制御 -> シーケンス(Sequence)
並列実行
使用可能 -> ワークフロー -> 制御 -> 並列(Parallel)
if文
使用可能 -> ワークフロー -> 制御 -> 条件分岐(If)
繰り返し
使用可能 -> ワークフロー -> 制御 -> 繰り返し(前判定)(While)
配列の内容分繰り返す
使用可能 -> ワークフロー -> コントロール -> 繰り返し(コレクションの各要素)(ForEach)
- コレクション -> CTRL-K 変数 -> IEnumerable型(デフォルト)。
- Misc -> TypeArgument -> コレクションの型を選択できる。
指定時間スリープ
使用可能 -> ワークフロー -> 制御 -> 待機(Delay)
- 待機時間 -> hh:mm:ss.MMM (時間:分:秒.ミリ秒)。
エラー処理(割込)
使用可能 -> ワークフロー -> エラー処理 -> トライキャッチ(Try Catch)
- CTRL-T
ワークフローファイル(サブルーチン)をプロジェクト内に追加作成(引数受渡し可能)
CTRL-N
サブルーチン(ワークフローファイル)呼出(引数受渡し可能)
使用可能 -> ワークフロー -> 呼び出し -> ワークフローファイルを呼び出し(Invoke Workflow File)
- 引数のインポート前には、サブルーチン側の引数定義を完成し、保存しておくこと。
- 引数は変数ではないので、直接に値の代入はできない。
- 引数定義で実際の値や変数と結びつける。
変数に値を代入
使用可能 -> ワークフロー -> 制御 -> 代入(Assign)
クリップボードから変数に代入
使用可能 -> システム -> クリップボード -> クリップボードから取得(Get From Clipboard)
- 出力 -> 結果 -> CTRL-K 変数 -> GenericValue型。
文字列置換
使用可能 -> プログラミング -> 文字列 -> 置換(Replace)
- 結果 -> 出力変数。
- パターン -> 置換前文字列。
- 入力 -> 入力文字列。
- 置換 -> 置換後文字列。
文字列比較
使用可能 -> プログラミング -> 文字列 -> 文字列の一致をチェック(Is Match)
- Misc -> 結果 -> CTRL-K 変数 -> boolean型。
メッセージボックス
使用可能 -> システム -> ダイアログ -> メッセージボックス(Message Box)
入力ダイアログ
使用可能 -> システム -> ダイアログ -> 入力ダイアログ(Input Dialog)
- タイトル -> タイトルバーに表示。
- ラベル -> 入力欄の左側に表示。
- 出力 -> 結果 -> CTRL-K 変数 -> GenericValue型。
アプリケーションの起動
使用可能 -> システム -> アプリケーション -> プロセスを開始(Start Process)
キーボード入力
使用可能 -> UI Automation -> 要素 -> キーボード -> 文字を入力(Type Into)
- ウィンドウメッセージを送信 -> バックグラウンド実行可能。互換性が高い。まぁまぁ早い。
- 入力をシミュレート -> バックグラウンド実行可能。互換性が低い。早い。
- フィールド内を削除 -> フィールド内の文字列を消してから、文字列を送信する。
制御キーを入力
使用可能 -> UI Automation -> 要素 -> キーボード -> ホットキーを押下(Send Hotkey)
- ウィンドウメッセージを送信 -> バックグラウンド実行可能。
マウスクリック
使用可能 -> UI Automation -> 要素 -> マウス -> クリック(Click)
- ウィンドウメッセージを送信 -> バックグラウンド実行可能。互換性が高い。まぁまぁ早い。
- クリックをシミュレート -> バックグラウンド実行可能。互換性が低い。早い。
- X,Yのオフセット -> 原点からの相対位置を指定する。
- 位置 -> 原点を指定する。
- クリックの種類 -> シングル、ダブル、アップ、ダウン。
- キー修飾子 -> ALT, CTRL, SHIFT, WIN。
- マウスボタン -> 右、左、中央。
テキストをクリック
使用可能 -> UI Automation -> テキスト -> マウス -> クリック(Click Text)
画像をクリック
使用可能 -> UI Automation -> 画像 -> マウス -> 画像をクリック(Click Image)
画像が出現したとき
使用可能 -> UI Automation -> 画像 -> イベント -> 画像が出現したとき(On Image Appear)
画像が消滅したとき
使用可能 -> UI Automation -> 画像 -> イベント -> 画像が消滅したとき(On Image Vanish)
要素が出現したとき
使用可能 -> UI Automation -> 要素 -> イベント -> 要素が出現したとき(On Element Appear)
要素が消滅したとき
使用可能 -> UI Automation -> 要素 -> イベント -> 要素が消滅したとき(On Element Vanish)
リストボックスの選択
使用可能 -> UI Automation -> 要素 -> コントロール -> 項目を選択(Select Items)
テキストの位置を探す
使用可能 -> UI Automation -> テキスト -> 画面スクレイピング -> テキスト位置を探す(Find Text Position)
- 出力 -> UI要素 -> CTRL-K 変数名 -> UiElement型
- 「テキストの位置を探す」で取得した「UiElement uiLoc」からテキスト文字列の真ん中をクリックするための座標を求める方法。
- clickX = CInt(uiLoc.ClippingRegion.Rectangle.Value.X + uiLoc.ClippingRegion.Rectangle.Value.Width / 2)。
- clickY = CInt(uiLoc.ClippingRegion.Rectangle.Value.Y + uiLoc.ClippingRegion.Rectangle.Value.Height / 2)。
フルテキストを取得
使用可能 -> UI Automation -> テキスト -> 画面スクレイピング -> フルテキストを取得(Get Full Text)
OCR日本語対応 tesseract OCR
ttps://github.com/tesseract-ocr/tessdata/blob/4.00/jpn.traineddata -> mkdir & copy into C:\Users\(自分のログイン名)\AppData\Local\UiPath\app-XX.X.X\tessdata\ or C:\Program Files\UiPath\Studio\tessdata\
OCRで文字列取得
使用可能 -> UI Automation -> OCR -> 画面スクレイピング -> OCRでテキストを取得(Get OCR Text)
- 出力 -> テキスト -> CTRL-K 変数 -> GenericValue型。
OCRエンジン
使用可能 -> UI Automation -> OCR -> エンジン -> tesseract OCR
OCRで検出した文字列をマウスでクリック
使用可能 -> UI Automation -> OCR -> マウス -> OCRで検出したテキストをクリック(Click OCR Text)
- ウィンドウメッセージを送信 -> バックグラウンド実行可能。互換性が高い。まぁまぁ早い。
- X,Yのオフセット -> 原点からの相対位置を指定する。
- 位置 -> 原点を指定する。
- クリックの種類 -> シングル、ダブル、アップ、ダウン。
- キー修飾子 -> ALT, CTRL, SHIFT, WIN。
- マウスボタン -> 右、左、中央。
画面内の文字列の有無チェック(非OCR)
使用可能 -> UI Automation -> テキスト -> 検出 -> テキストの有無を確認(Text Exists)
- 出力 -> 存在の有無 -> CTRL-K 変数 -> boolean型。
ウインドウを最小化する
使用可能 -> UI Automation -> ウィンドウ -> ウィンドウにアタッチ(Attach Window) 使用可能 -> UI Automation -> ウィンドウ -> ウィンドウを最小化(Minimize Window)
エクセルのセルの内容を読み込む
使用可能 -> システム -> ファイル -> ワークブック -> セルを読み込み(Read Cell)
- 出力 -> 結果 -> CTRL-K 変数 -> GenericValue型。
エクセルの行の内容を読み込む
使用可能 -> システム -> ファイル -> ワークブック -> 行を読み込み(Read Row)
- 開始セル -> 指定したセルから読み込む。
- 出力 -> 結果 -> CTRL-K 変数 -> IEnumerable<System.Object>型。
- Null判定 -> 変数 is nothing, 変数 isNot nothing。
- 1個目の項目 -> 変数(0).toString()、100個目の項目 -> 変数(99).toString()。
エクセルの全行の内容を読み込む
使用可能 -> システム -> ファイル -> ワークブック -> 範囲を読み込み(Read Range)
- ヘッダーの追加 -> 1行目を列名として認識させる。
- 範囲 -> 読み込み範囲を指定(無指定時は全部)。
- 出力 -> データテーブル -> CTRL-K 変数名 -> DataTable型。
- 1行目の1個目の項目 -> 変数(0).Item(0).toString()、10行目の100個目の項目 -> 変数(9).Item(99).toString()。
- 1行目の1個目の項目 -> 変数(0).Item("列名0").toString()、10行目の100個目の項目 -> 変数(9).Item("列名99").toString()。
CSVの読み込み
使用可能 -> アプリの連携 -> CSV -> CSVを読む(Read CSV)
- エンコーディング -> "SJIS"、"UTF-8" etc。
- 列名を含める -> 1行目を列名として認識させる。
- 区切り文字 -> "\t"、","、";"、"|"。
- 出力 -> データテーブル -> CTRL-K 変数名 -> DataTable型。
- 1行目の1個目の項目 -> 変数(0).Item(0).toString()、10行目の100個目の項目 -> 変数(9).Item(99).toString()。
- 1行目の1個目の項目 -> 変数(0).Item("列名0").toString()、10行目の100個目の項目 -> 変数(9).Item("列名99").toString()。
DataTable型 変数(Excel、CSV全行読み込んだ変数)分繰り返す
使用可能 -> プログラミング -> データテーブル -> 繰り返し(各行)(For Each Row)
- 1個目の項目 -> row.Item(0).toString()、2個目の項目 -> row.Item(1).toString()。
- 1個目の項目 -> row.Item("列名0").toString()、2個目の項目 -> row.Item("列名1").toString()。
エクセルのセルに色を付ける
使用可能 -> アプリの連携 -> Excel -> Excelアプリケーションスコープ(Excel Application Scope)
- 可視 -> シートを表示する。
- 自動保存 -> 修正内容を自動的に保存する。
使用可能 -> アプリの連携 -> Excel -> 範囲の色を設定(Set Range Color)
- 入力 -> 色 -> Color.red etc。
デバッグ出力
使用可能 -> プログラミング -> デバッグ -> 1行を書き込み(Write Line)
- 「出力」タブに出力される。
コメント文挿入
使用可能 -> プログラミング -> デバッグ -> コメント(Comment)
コメント化
使用可能 -> プログラミング -> デバッグ -> コメントアウト(Comment Out)
- CTRL-D コメント化
- CTRL-E 非コメント化
Misc
- 整数化 -> CInt(変数)。
- 文字列化 -> 変数.toString。
- 数値チェック -> isNumeric(変数)。
- CTRL-C(コピー)した文字列には改行(vbCrLf)が含まれる。
- 空セルをCTRL-C(コピー)した時も改行(vbCrLf)が取り込まれる。
- InternetExplorer -> インターネットオプション -> 詳細設定 -> セキュリティ -> マイコンピュータのファイルでのアクティブコンテンツでの実行を許可する。
- publishを取り消す。
- C:\ProgramData\UiPath\Package\対象パッケージ.nupkg を削除する。
- C:\Users\ユーザ\.nuget\packages\対象パッケージ\ を削除する。
- 操作対象アプリケーションの画面遷移の確定を判断する手法
- 使用可能 -> UI Automation -> テキスト -> 画面スクレイピング -> フルテキストを取得(Get Full Text)
- 使用可能 -> UI Automation -> テキスト -> 検出 -> テキストの有無を確認(Text Exists)
- 使用可能 -> UI Automation -> 要素 -> イベント -> 要素が出現したとき(On Element Appear)
- 使用可能 -> UI Automation -> 要素 -> イベント -> 要素が消滅したとき(On Element Vanish)
- 使用可能 -> UI Automation -> 画像 -> イベント -> 画像が出現したとき(On Image Appear)
- 使用可能 -> UI Automation -> 画像 -> イベント -> 画像が消滅したとき(On Image Vanish)
- 使用可能 -> UI Automation -> OCR -> 画面スクレイピング -> OCRでテキストを取得(Get OCR Text)