みんなが愛しているBoostを使用。データ取得のコードは、公式ドキュメントにあるものを丸パクリしています(ぉ
やっていること
・しょぼいカレンダーの「cal_chk.php」にアクセスしてデータ取得
・XMLを解析
・構造体配列にぶち込む
・表示
以下、簡易版ソース。詳しくは上のGitHubからどうぞ。
#define XML_PATH "./cal_chk.php" #include <iostream> #include <istream> #include <ostream> #include <string> #include <boost/asio.hpp> #include <boost/foreach.hpp> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/xml_parser.hpp> using namespace std; using namespace boost; using namespace boost::asio::ip; using namespace boost::property_tree; struct AnimeList { string title; string count; string sub_title; string st_time; string ch_name; }; int main() { try { boost::asio::io_service io_service; tcp::resolver resolver( io_service ); tcp::resolver::query query( "cal.syoboi.jp", "http" ); tcp::resolver::iterator endpoint_iterator = resolver.resolve( query ); tcp::resolver::iterator end; tcp::socket socket( io_service ); boost::system::error_code error = boost::asio::error::host_not_found; while ( error && endpoint_iterator != end ) { socket.close( ); socket.connect( *endpoint_iterator++, error ); } if ( error ) { throw boost::system::system_error( error ); } boost::asio::streambuf request; ostream request_stream( &request ); request_stream << "GET /cal_chk.php?usr=hogehoge&days=1 HTTP/1.0\r\n"; request_stream << "Host: cal.syoboi.jp\r\n"; request_stream << "Accept: */*\r\n"; request_stream << "Connection: close\r\n\r\n"; boost::asio::write( socket, request ); boost::asio::streambuf response; boost::asio::read_until( socket, response, "\r\n" ); istream response_stream( &response ); string http_version; response_stream >> http_version; unsigned int status_code; response_stream >> status_code; string status_message; getline( response_stream, status_message ); if ( !response_stream || http_version.substr( 0, 5 ) != "HTTP/" ) { cout << "Invalid response\n"; return 1; } if ( status_code != 200 ) { cout << "Response returned with status code " << status_code << "\n"; return 1; } boost::asio::read_until( socket, response, "\r\n\r\n" ); string header; while ( getline( response_stream, header ) && header != "\r" ) { /*cout << header << "\n";*/ } /*cout << "\n";*/ ofstream ofs( XML_PATH ); if ( response.size() > 0 ) { ofs << &response; } while ( boost::asio::read( socket, response, boost::asio::transfer_at_least(1), error ) ) { ofs << &response; } if ( error != boost::asio::error::eof ) { throw boost::system::system_error( error ); } } catch ( std::exception& e ) { cout << "Exception: " << e.what() << "\n"; } AnimeList al[50]; int num = 0; ptree pt; read_xml( XML_PATH, pt ); const ptree & format = pt.get_child( "syobocal.ProgItems" ); BOOST_FOREACH ( const ptree::value_type & child, format ) { const ptree & attributes = child.second.get_child( "<xmlattr>" ); BOOST_FOREACH ( const ptree::value_type &value, attributes ){ const char *cmp_title = "Title"; const char *cmp_count = "Count"; const char *cmp_sub_title = "SubTitle"; const char *cmp_st_time = "StTime"; const char *cmp_ch_name = "ChName"; if ( strcmp( value.first.data( ), cmp_title ) == 0 ) { al[num].title = value.second.data( ); } else if ( strcmp( value.first.data( ), cmp_count ) == 0 ) { al[num].count = value.second.data( ); } else if ( strcmp( value.first.data( ), cmp_sub_title ) == 0 ) { al[num].sub_title = value.second.data( ); } else if ( strcmp( value.first.data( ), cmp_st_time ) == 0 ) { string date = value.second.data( ); date = date.substr( 8, 2 ) + ":" + date.substr( 10, 2 ); al[num].st_time = date; } else if ( strcmp( value.first.data( ), cmp_ch_name ) == 0 ) { al[num].ch_name = value.second.data( ); } } num++; } for ( int i = 0; i < num; i++ ) { cout << al[i].st_time << "\n"; cout << al[i].title << " 第" << al[i].count << "話" << "『" << al[i].sub_title << "』 " << al[i].ch_name << "\n"; } if ( remove( XML_PATH ) != 0 ) { cout << "Error deleting file\n"; } }
実行結果
[hoge@piyo ~]$ ./a.out 13:00 こどものおもちゃ 第67話『ニューヨークったらサスペンス』 アニマックス 13:30 ご近所物語 第14話『ピイちゃんパニック』 アニマックス 17:00 アイカツ!-アイドルカツドウ!- 第156話『YOU! GO! KYOTO!!』 BS Japan 17:29 かみさまみならい ヒミツのここたま 第4話『大ピンチ!出るに出られぬおシャキです!!』 BS Japan 18:00 世界でいちばん強くなりたい! 第話『#11~#12』 AT-X 18:25 おしりかじり虫(第4シリーズ) 第4話『大騒ぎ!?ドキドキパニックバザー』 NHK BSプレミアム 18:30 蟲師 第21話『綿胞子』 アニマックス 18:30 美少女戦士セーラームーン 第30話『お爺ちゃん乱心、レイちゃんの危機』 NHK BSプレミアム 19:00 ダイヤのA 第71話『9月の空の下』 キッズステーション 19:00 ガンダムビルドファイターズトライ 第9話『決戦のソロモン』 アニマックス 20:00 あずきちゃん 第82話『ジダマ様へ?名前のないラブレター』 AT-X 21:30 UFO戦士ダイアポロン 第11話『出た!!必殺デストロイの秘密』 AT-X 22:00 血界戦線 第7話『拳客のエデン』 アニマックス 22:30 魁!!男塾 第9話『塾長恐怖の思いつき オマエら明日から丸坊主だァ!!』 キッズステーション 23:00 這いよれ!ニャル子さん 第11話『星から訪れた迷い子』 キッズステーション 23:30 スタミュ 高校星歌劇 第3話『第3幕』 AT-X 00:00 終わりのセラフ(第2クール) 第15話『帝鬼軍のヤボウ』 BS11デジタル 00:30 スタミュ 高校星歌劇 第4話『第4幕』 BS11デジタル 00:00 アニソンCLUB! 第13話『「アニソンCLUB!-R」ゲスト:影山ヒロノブ』 BSフジ 01:00 進撃!巨人中学校 第4話『清掃!巨人中学校』 BS11デジタル 03:00 櫻子さんの足下には死体が埋まっている 第3話『夏に眠る骨』 BS11デジタル
このままだとアレすぎるので、ちゃんと書き直してgithubやらに上げます(予定)*1
あとは、AT-Xの連続放送みたいなのは、どうも話数が空になっているようで、サブタイトル内に「#11~#12」と入ってるみたい。おう、面倒臭い。
*1:2015.10.27:上げますた