{"id":5025,"date":"2013-05-19T09:03:07","date_gmt":"2013-05-18T15:03:07","guid":{"rendered":"http:\/\/qos.mine.nu\/wordpress\/?p=5025"},"modified":"2013-05-19T22:29:04","modified_gmt":"2013-05-19T13:29:04","slug":"twitter%e3%81%ae1%e6%97%a5%e5%88%86%e3%81%ae%e3%82%bf%e3%82%a4%e3%83%a0%e3%83%a9%e3%82%a4%e3%83%b3%e3%82%92kindle%e3%81%a7%e8%aa%ad%e3%82%80","status":"publish","type":"post","link":"https:\/\/qos.dev7.net\/wordpress\/2013\/05\/twitter%e3%81%ae1%e6%97%a5%e5%88%86%e3%81%ae%e3%82%bf%e3%82%a4%e3%83%a0%e3%83%a9%e3%82%a4%e3%83%b3%e3%82%92kindle%e3%81%a7%e8%aa%ad%e3%82%80.html","title":{"rendered":"Twitter\u306e1\u65e5\u5206\u306e\u30bf\u30a4\u30e0\u30e9\u30a4\u30f3\u3092Kindle\u3067\u8aad\u3080"},"content":{"rendered":"<div id=\"wppda_alert\">\u3053\u306e\u8a18\u4e8b\u306f\uff12\u5e74\u4ee5\u4e0a\u524d\u306b\u66f8\u3044\u305f\u3082\u306e\u3067\u3059\u3002<br\/>\r\n\u305d\u306e\u305f\u3081\u60c5\u5831\u304c\u53e4\u3044\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u3054\u4e86\u627f\u304f\u3060\u3055\u3044\u3002m(_ _)m<\/div><p>\u6642\u9593\u304b\u3051\u3066\u63a2\u305b\u3070\u826f\u3044\u611f\u3058\u306e\u304c\u6709\u308a\u305d\u3046\u3060\u3051\u3069\u3001\u3059\u3050\u306b\u306f\u898b\u3064\u304b\u3089\u306a\u304b\u3063\u305f\u306e\u3067perl\u3067\u66f8\u3044\u3066\u307f\u305f\u3002<\/p>\n<p>\n\u4ed5\u69d8\u7684\u306a\u3082\u306e\u3002<\/p>\n<ul>\n<li>\u5e38\u99d0\u305b\u305a\u306b\u3001\uff11\uff10\u5206\u304a\u304d\u304f\u3089\u3044\u306bcron\u3067\u52d5\u304b\u3059\u3002<\/li>\n<li>1\u65e5\u5206\u306etweet\u306f\u3001$timeline_file\u306b\u6e9c\u3081\u8fbc\u3080\u3002<\/li>\n<li>1\u65e5\u5206\u306e\u5207\u308a\u66ff\u3048\u306f\u3001Log::Dispatch::FileRotate\u306b\u4efb\u305b\u308b\u3002<br \/>\n\uff08\u5fae\u5999\u306b\u305a\u308c\u308b\u5834\u5408\u3082\u3042\u308b\u3051\u3069\u3001\u7d30\u304b\u3044\u3053\u3068\u306f(\uff9f\u03b5\uff9f)\uff77\uff86\uff7c\uff85\uff72!!\uff09<\/li>\n<li>$timeline_file\u3078\u306e\u51fa\u529b\u306f\u3001Log::Log4perl \u306e INFO\u3067\u3002<\/li>\n<li>kindle\u3078\u9001\u4fe1\u3059\u308b\u30bf\u30a4\u30df\u30f3\u30b0\u306f\u3001$timeline_file\u306e\u30b5\u30a4\u30ba\u304c\u5c0f\u3055\u304f\u306a\u3063\u305f\u3089\u3002<br \/>\n\uff08FileRotate\u3067\u5207\u308a\u66ff\u308f\u3063\u305f\u3089\u30d5\u30a1\u30a4\u30eb\u30b5\u30a4\u30ba\u304c\u5c0f\u3055\u304f\u306a\u308b\u306e\u3067\u3001\u305d\u308c\u5951\u6a5f\uff09<\/li>\n<li>kindle\u3078\u306e\u9001\u4fe1\u3059\u308b\u30c7\u30fc\u30bf\u306f\u3001html\u30d5\u30a1\u30a4\u30eb\u3002<\/li>\n<li>\u9001\u4fe1\u5148\u306f\u3001@kindle.com or @free.kindle.com\u3002<br \/>\n\uff08\u81ea\u52d5\u7684\u306b\u5909\u63db\u3057\u3066\u3001\u7aef\u672b\u3078\u914d\u4fe1\u3057\u3066\u304f\u308c\u308b\uff09<\/li>\n<\/ul>\n<p>gettimeline.pl(<a href=\"\/files\/gettimeline.zip\">gettimeline.zip<\/a>)<\/p>\n<pre><code class=\"language-perl\">\n#!\/usr\/bin\/perl\n\nuse 5.010;\nuse strict;\nuse warnings;\nuse Encode;\nuse DateTime;\nuse DateTime::TimeZone;\nuse DateTime::Format::DateParse;\nuse Data::Dumper;\nuse HTML::Entities;\nuse MIME::Lite;\n\nuse Net::Twitter;\nuse Log::Log4perl qw(:easy);\n\n# Twitter key and token\nmy $consumer_key = &#039;xxxxxxxxxxxxxxxxxxxxx&#039;;\nmy $consumer_secret = &#039;yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy&#039;;\nmy $token = &#039;nnnnnnnnnn-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz&#039;;\nmy $token_secret = &#039;sssssssssssssssssssssssssssssssssssssssssss&#039;;\n\n# log\nmy $logfile = &#039;\/home\/user\/tool\/twitter.log&#039;;\nmy $timeline_file = &#039;\/home\/user\/tool\/timeline.log&#039;;\n\n# mail\nmy $mailfrom = &#039;xxxx@xxx.xxx&#039;;\nmy $mailto = &#039;yyyyy@free.kindle.com&#039;;\n\n# title\nmy $title_fmt = &#039;Twitter_Timeline_%Y-%m-%d(%a)&#039;;\n\n\nmy $tid_prefix = &#039;__TID__:&#039;;\nmy $tz = DateTime::TimeZone-&gt;new(name =&gt; &#039;local&#039;);\n\n&amp;loginit;\n\n&amp;main;\n\nexit;\n\nsub main{\n    my $filesize = -s $timeline_file;\n\n    &amp;gettl;\n\n    if($filesize &gt; -s $timeline_file){\n\tsay &#039;send to kindle&#039;;\n\t&amp;send2kindle;\n    }\n}\n\nsub send2kindle{\n    my $dt = DateTime-&gt;now(time_zone =&gt; $tz);\n    $dt-&gt;subtract(days =&gt; 1);\n    my $title = $dt-&gt;strftime($title_fmt);\n    my $fname = $title . &#039;.html&#039;;\n\n    my $timeline_file1 = $timeline_file . &#039;.1&#039;;\n    open my $fh, &#039;&lt;&#039;, &quot;$timeline_file1&quot;\n\tor die &quot;failed to open file: $!&quot;;\n    my $rawdata = do { local $\/; &lt;$fh&gt; };\n\n    my @rawdata_array = grep(!\/^$tid_prefix \\d+$\/, split(\/\\n\/, $rawdata));\n\n\n    my $htmldata = &lt;&lt;_HEADER_;\n&lt;html&gt;\n  &lt;head&gt;\n    &lt;title&gt;$title&lt;\/title&gt;\n    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=utf-8&quot;&gt;\n  &lt;\/head&gt;\n&lt;body&gt;\n  &lt;h3&gt;$title&lt;\/h3&gt;\n&lt;pre&gt;\n_HEADER_\n\n    $htmldata .= Encode::decode_utf8(join(&quot;\\n&quot;, @rawdata_array));\n\n    $htmldata .= &lt;&lt;_FOOTER_;\n&lt;\/pre&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;\n_FOOTER_\n\n    my $subject = $title;\n\n    my $msg = MIME::Lite-&gt;new(\n\tFrom =&gt; &quot;$mailfrom&quot;,\n\tTo =&gt; &quot;$mailto&quot;,\n\tSubject =&gt; &quot;$subject&quot;,\n\tType =&gt; &#039;multipart\/mixed&#039;\n    );\n    $msg-&gt;attach(\n\tType =&gt; &#039;text\/plain; charset=&quot;iso-2022-jp&quot;&#039;,\n\tData =&gt; &quot;no body&quot;\n\t);\n    $msg-&gt;attach(\n\tType =&gt; &#039;text\/html&#039;,\n\tData =&gt; &quot;$htmldata&quot;,\n\tFilename =&gt; &quot;$fname&quot;,\n\tDisposition =&gt; &#039;attachment&#039;\n\t);\n    $msg-&gt;attr(&#039;content-type.charset&#039; =&gt; &#039;UTF-8&#039;);\n\n#    WARN Dumper($msg);\n#    WARN $htmldata;\n\n    $msg-&gt;send();\n\n}\n\nsub gettl{\n    my $nt = Net::Twitter-&gt;new(\n\ttraits =&gt; [qw\/OAuth API::REST\/],\n\tconsumer_key =&gt; $consumer_key,\n\tconsumer_secret =&gt; $consumer_secret,\n\taccess_token =&gt; $token,\n\taccess_token_secret =&gt; $token_secret,\n\t);\n\n#    WARN &quot;TWEET: &quot; . $tweet;\n\n    my @tl = $nt-&gt;home_timeline({count =&gt; 200});\n\n    my @rtl = reverse(@{$tl[0]});\n\n    my $tail_cmd = &quot;tail -2 $timeline_file&quot;;\n    my $grep_cmd = &quot;grep -e \\&quot;$tid_prefix [0-9]\\\\+\\&quot;&quot;;\n    my $sed_cmd = &quot;sed -r \\&quot;s\/[^0-9]+([0-9]+)\/\\\\1\/\\&quot;&quot;;\n    my $lastid = `$tail_cmd | $grep_cmd | $sed_cmd`;\n    chomp $lastid;\n\n    if($lastid){\n\tfor my $i (0 .. $#rtl) {\n\t    if($lastid eq $rtl[$i]-&gt;{id}){\n#say &quot;0 -&gt; &quot; . $i . &quot; ($#rtl)&quot;;\n\t\tsplice(@rtl, 0, $i+1);\n#say &quot;  -&gt; &quot; . $#rtl;\n\t\tlast;\n\t    }\n\t}\n    }\n\n    my $id = &#039;&#039;;\n    foreach my $t(@rtl){\n\tWARN $t-&gt;{id};\n\t$id = $t-&gt;{id};\n\tmy $s = &amp;mklinktag($t-&gt;{text});\n\tmy $dt = DateTime::Format::DateParse-&gt;parse_datetime($t-&gt;{created_at});\n\t$dt-&gt;set_time_zone($tz);\n\n\tINFO encode_utf8($t-&gt;{user}{name}) .\n\t    &#039; (&lt;a href=&quot;https:\/\/twitter.com\/&#039; . $t-&gt;{user}{screen_name} . &#039;&quot;&gt;&#039; .\n\t    &#039;@&#039; . $t-&gt;{user}{screen_name} . &#039;&lt;\/a&gt;)&#039; . &quot;\\n&quot; .\n\t    encode_utf8($s) . &quot;\\n&quot; .\n\t    $dt-&gt;strftime(&#039;(%Y\/%m\/%d %H:%M:%S)&#039;) . &quot;\\n&quot;;\n#\tWARN Dumper($t);\n\tWARN Dumper($s);\n    }\n    INFO &quot;$tid_prefix &quot; . $id . &quot;\\n&quot; if $id;\n}\n\nsub mklinktag{\n    my ($s) = @_;\n\n    $s = encode_entities($s, q{&amp;&lt;&gt;&quot;&#039;});\n\n    $s =~ s!(https?:\/\/)([0-9a-zA-Z\/\\.]+)!&lt;a href=&quot;$1$2&quot;&gt;$2&lt;\/a&gt;!go;\n\n    $s =~ s!@([a-zA-Z0-9_]+)!&lt;a href=&quot;https:\/\/twitter.com\/$1&quot;&gt;\\@$1&lt;\/a&gt;!go;\n\n    $s;\n}\n\nsub loginit{\n  my $logsize = 10*1024*1024;\n  Log::Log4perl-&gt;init(\\ qq{\n    log4perl.logger = INFO, AppError, Tweet\n\n    # filter range\n    log4perl.filter.MatchRange               = Log::Log4perl::Filter::LevelRange\n    log4perl.filter.MatchRange.LevelMin      = WARN\n    log4perl.filter.MatchRange.LevelMax      = ERROR\n    log4perl.filter.MatchRange.AcceptOnMatch = true\n\n    # Error appender\n    log4perl.appender.AppError = Log::Dispatch::FileRotate\n    log4perl.appender.AppError.filename   = $logfile\n    log4perl.appender.AppError.max   = 10\n    log4perl.appender.AppError.autoflush   = 1\n    log4perl.appender.AppError.size   = $logsize\n    log4perl.appender.AppError.mode = append\n    log4perl.appender.AppError.layout   = Log::Log4perl::Layout::PatternLayout\n    log4perl.appender.AppError.layout.ConversionPattern = %d %02X{client} %p %F{1} %L: %m %n\n    log4perl.appender.AppError.Filter   = MatchRange\n\n    # Filter to match level WARN\n    log4perl.filter.MatchInfo  = Log::Log4perl::Filter::LevelMatch\n    log4perl.filter.MatchInfo.LevelToMatch  = INFO\n    log4perl.filter.MatchInfo.AcceptOnMatch = true\n\n    # Error appender\n    log4perl.appender.Tweet = Log::Dispatch::FileRotate\n    log4perl.appender.Tweet.filename   = $timeline_file\n    log4perl.appender.Tweet.max   = 10\n    log4perl.appender.Tweet.autoflush   = 1\n    log4perl.appender.Tweet.DatePattern = yyyy-MM-dd\n    log4perl.appender.Tweet.TZ = JST\n    log4perl.appender.Tweet.mode = append\n    log4perl.appender.Tweet.layout   = Log::Log4perl::Layout::PatternLayout\n    log4perl.appender.Tweet.layout.ConversionPattern = %m %n\n    log4perl.appender.Tweet.Filter   = MatchInfo\n });\n}\n<\/code><\/pre>\n<p>\u2191\u306e\u30b3\u30fc\u30c9\u3067\u9001\u4fe1\u3055\u308c\u305f\u30d5\u30a1\u30a4\u30eb\u306e\u30b9\u30af\u30ea\u30fc\u30f3\u30b7\u30e7\u30c3\u30c8\u304c\u2193\u3002<\/p>\n<p><a href=\"\/wordpress\/wp-content\/uploads\/2013\/05\/screenshot_2013_05_19T09_28_120900.png\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px\" title=\"screenshot_2013_05_19T09_28_12 0900\" border=\"0\" alt=\"screenshot_2013_05_19T09_28_12 0900\" src=\"\/wordpress\/wp-content\/uploads\/2013\/05\/screenshot_2013_05_19T09_28_120900_thumb.png\" width=\"572\" height=\"772\"><\/a><\/p>\n<p>\n\u30a2\u30a4\u30b3\u30f3\u3068\u304b\u3082\u6301\u3063\u3066\u6765\u305f\u307b\u3046\u304c\u898b\u6804\u3048\u304c\u826f\u3044\u3093\u3060\u308d\u3046\u3051\u3069\u3001\u3068\u308a\u3042\u3048\u305a\u30b7\u30f3\u30d7\u30eb\u306a\u3053\u308c\u3067\u4f7f\u3063\u3066\u307f\u308b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u3053\u306e\u8a18\u4e8b\u306f\uff12\u5e74\u4ee5\u4e0a\u524d\u306b\u66f8\u3044\u305f\u3082\u306e\u3067\u3059\u3002 \u305d\u306e\u305f\u3081\u60c5\u5831\u304c\u53e4\u3044\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u3054\u4e86\u627f\u304f\u3060\u3055\u3044\u3002m(_ _)m\u6642\u9593\u304b\u3051\u3066\u63a2\u305b\u3070\u826f\u3044\u611f\u3058\u306e\u304c\u6709\u308a\u305d\u3046\u3060\u3051\u3069\u3001\u3059\u3050\u306b\u306f\u898b\u3064\u304b\u3089\u306a\u304b\u3063\u305f\u306e\u3067perl\u3067\u66f8\u3044\u3066\u307f\u305f\u3002 \u4ed5\u69d8\u7684\u306a\u3082\u306e\u3002 \u5e38 &hellip; <a href=\"https:\/\/qos.dev7.net\/wordpress\/2013\/05\/twitter%e3%81%ae1%e6%97%a5%e5%88%86%e3%81%ae%e3%82%bf%e3%82%a4%e3%83%a0%e3%83%a9%e3%82%a4%e3%83%b3%e3%82%92kindle%e3%81%a7%e8%aa%ad%e3%82%80.html\">\u7d9a\u304d\u3092\u8aad\u3080 <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,126],"tags":[47,172,23,114,247],"class_list":["post-5025","post","type-post","status-publish","format-standard","hentry","category-5","category-afafaafaf","tag-freebsd","tag-kindle","tag-linux","tag-perl","tag-twitter"],"_links":{"self":[{"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/posts\/5025","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/comments?post=5025"}],"version-history":[{"count":20,"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/posts\/5025\/revisions"}],"predecessor-version":[{"id":5047,"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/posts\/5025\/revisions\/5047"}],"wp:attachment":[{"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/media?parent=5025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/categories?post=5025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qos.dev7.net\/wordpress\/wp-json\/wp\/v2\/tags?post=5025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}