チェンジセット 2589
- コミット日時:
- 2009/05/08 18:41:03 (3 年前)
- ファイル:
-
- air/TLife/branches/OAuth/unused/TinyURLDecodeThread.as (追加)
- air/TLife/branches/OAuth/unused/TinyURLEncodeThread.as (追加)
- air/TLife/trunk/bin/TLife.swf (更新) (変更前)
- air/TLife/trunk/bin/doc/readme.html (更新) (2 diffs)
- air/TLife/trunk/bin/doc/sub (追加)
- air/TLife/trunk/bin/doc/sub/globalconfig.html (追加)
- air/TLife/trunk/bin/doc/sub/incremental.html (追加)
- air/TLife/trunk/bin/doc/sub/main.html (追加)
- air/TLife/trunk/bin/doc/sub/mania.html (追加)
- air/TLife/trunk/bin/doc/sub/simpleregexp.html (追加)
- air/TLife/trunk/bin/doc/sub/tabconfig.html (追加)
- air/TLife/trunk/src/Main.mxml (更新) (2 diffs)
- air/TLife/trunk/src/uwi/search/Searcher.as (更新) (1 diff)
- air/TLife/trunk/src/uwi/shortening (追加)
- air/TLife/trunk/src/uwi/shortening/URLExpandThread.as (追加)
- air/TLife/trunk/src/uwi/shortening/URLShortenThread.as (追加)
- air/TLife/trunk/src/uwi/thread/InitialMovementThread.as (更新) (5 diffs)
- air/TLife/trunk/src/uwi/thread/LinkResolveThread.as (更新) (5 diffs)
- air/TLife/trunk/src/uwi/thread/MainThread.as (更新) (6 diffs)
- air/TLife/trunk/src/uwi/thread/NotifyNewThread.as (更新) (1 diff)
- air/TLife/trunk/src/uwi/thread/ReplyGetThread.as (更新) (5 diffs)
- air/TLife/trunk/src/uwi/thread/TimelineThread.as (更新) (7 diffs)
- air/TLife/trunk/src/uwi/thread/TinyURLDecodeThread.as (削除)
- air/TLife/trunk/src/uwi/thread/TinyURLEncodeThread.as (削除)
- air/TLife/trunk/src/uwi/thread/event/ContextMenuItemEventThread.as (更新) (3 diffs)
- air/TLife/trunk/src/uwi/thread/event/IncrementalSearchThread.as (更新) (2 diffs)
- air/TLife/trunk/src/uwi/thread/event/PostEventThread.as (更新) (7 diffs)
- air/TLife/trunk/src/uwi/twitter/TwitterBitScrapeThread.as (更新) (5 diffs)
- air/TLife/trunk/src/uwi/twitter/TwitterFollowingScrapeThread.as (追加)
- air/TLife/trunk/src/uwi/twitter/TwitterLoginThread.as (更新) (3 diffs)
- air/TLife/trunk/src/uwi/twitter/TwitterLogoutThread.as (追加)
- air/TLife/trunk/src/uwi/twitter/TwitterMobileLoginThread.as (追加)
- air/TLife/trunk/src/uwi/twitter/TwitterMobileLogoutThread.as (追加)
- air/TLife/trunk/src/uwi/ui/complete/CompleteThread.as (更新) (1 diff)
- air/TLife/trunk/src/uwi/ui/multipletabbar/MultipleTabBar.as (更新) (6 diffs)
- air/TLife/trunk/src/uwi/ui/multipletabbar/MultipleTabBarDragEventThread.as (更新) (1 diff)
- air/TLife/trunk/src/uwi/ui/multipletabbar/MultipleTabBarEventThread.as (更新) (3 diffs)
- air/TLife/trunk/src/uwi/ui/tabconfig/TabConfigEventThread.as (更新) (1 diff)
- air/TLife/trunk/src/uwi/util/CommonData.as (更新) (2 diffs)
- air/TLife/trunk/src/uwi/util/StatusScraper.as (更新) (9 diffs)
- air/TLife/trunk/src/uwi/util/StatusScraperEn.as (追加)
- air/TLife/trunk/src/uwi/util/TabRuleUtility.as (更新) (1 diff)
- air/TLife/trunk/src/uwi/util/URLPostThread.as (更新) (1 diff)
凡例:
- 変更無し
- 追加
- 削除
- 更新
- コピー
- 移動
air/TLife/trunk/bin/doc/readme.html
r2531 r2589 9 9 <h1>TLife説明書</h1> 10 10 11 <h2>操作説明</h2> 12 <ul> 13 <li><a href="sub/main.html">メイン画面</a></li> 14 <li><a href="sub/tabconfig.html">タブ設定画面</a></li> 15 <li><a href="sub/globalconfig.html">全体設定画面</a></li> 16 <li><a href="sub/mania.html">もっと凝った設定がしたい方へ</a></li> 17 </ul> 18 11 19 <h2>ソフト名</h2> 12 20 <p>TLife</p> … … 20 28 <h2>更新履歴</h2> 21 29 <dl> 22 <dt>2009年4月25日 ver 0.1</dt>30 <dt>2009年4月25日 ver α</dt> 23 31 <dd>α リリース</dd> 24 32 </dl> 25 33 </body> 26 34 </html> 35 air/TLife/trunk/src/Main.mxml
r2546 r2589 116 116 Logger.errorLevel = Logger.INFO; 117 117 Logger.dumpLimDepth = 999; 118 Logger.logging = new FilePutLogging(CommonData.FILE_LOG);119 //Logger.logging = new TraceLogging();118 // Logger.logging = new FilePutLogging(CommonData.FILE_LOG); 119 Logger.logging = new TraceLogging(); 120 120 121 121 postarea.text = ""; … … 425 425 426 426 <mx:VBox id="vbox0" x="0" y="0" width="100%" height="100%" verticalGap="0" verticalScrollPolicy="off"> 427 <mx:VDividedBox id="vdbox00" width="100%" height="100%" dividerThickness="2" >427 <mx:VDividedBox id="vdbox00" width="100%" height="100%" dividerThickness="2" horizontalScrollPolicy="off"> 428 428 <mx:VBox id="vbox000" width="100%" height="100%" verticalScrollPolicy="off" horizontalScrollPolicy="off" verticalGap="0"> 429 429 <uwi:DataGridEx id="datagrid" width="100%" height="100%" dataProvider="{timeline}" air/TLife/trunk/src/uwi/search/Searcher.as
r2546 r2589 188 188 postid : -1, 189 189 newestid : -1, 190 rule : " where " +conds.join(" and "),190 rule : conds.join(" and "), 191 191 type : 1, 192 192 unread : {}, air/TLife/trunk/src/uwi/thread/InitialMovementThread.as
r2533 r2589 7 7 import org.libspark.thread.utils.SerialExecutor; 8 8 import uwi.twitter.TwitterLoginThread; 9 import uwi.twitter.TwitterMobileLoginThread; 9 10 import uwi.util.CommonData; 10 11 import uwi.util.TimerThread; … … 24 25 } 25 26 26 private var tlt : Twitter LoginThread = null;27 private var tlt : TwitterMobileLoginThread = null; 27 28 28 29 protected override function finalize() : void … … 30 31 tlt = null; 31 32 } 33 34 private var s : int; 32 35 33 36 protected override function run() : void … … 47 50 URLRequestDefaults.setLoginCredentialsForHost("twitter.com", CommonData.configxml.login.userid, password); 48 51 49 tlt = new TwitterLoginThread(CommonData.configxml.login.userid, password); 52 s = getTimer(); 53 tlt = new TwitterMobileLoginThread(CommonData.configxml.login.userid, password); 50 54 CommonData.state = 10; 51 55 tlt.start(); … … 56 60 private function onLogin() : void 57 61 { 62 var t : int = getTimer(); 63 trace((t - s) + "ms"); 58 64 if (tlt.result == 0) { 59 65 // ログイン成功時 air/TLife/trunk/src/uwi/thread/LinkResolveThread.as
r2546 r2589 5 5 import org.libspark.thread.Thread; 6 6 import org.libspark.thread.utils.ParallelExecutor; 7 import uwi.shortening.URLExpandThread; 7 8 import uwi.util.CommonData; 8 9 import uwi.util.StringUtility; … … 14 15 public class LinkResolveThread extends Thread 15 16 { 16 private static const PREFIX_TINYURL : String = "http://tinyurl.com/";17 17 18 18 private var src : String; … … 63 63 var href : String = StringUtility.pinch(inner, "href=\"", "\""); 64 64 var text : String = inner.substr(inner.indexOf(">") + 1); 65 if (href.substring(0, PREFIX_TINYURL.length) == PREFIX_TINYURL) { 66 // tinyurlだったらデコード 67 var cache : String = CommonData.urlcache[href]; 68 if (cache == null) { 69 pe.addThread(new TinyURLDecodeThread(href)); 70 dst += "{" + ct + "}"; // 代替テキスト 71 ct++; 72 }else { 73 dst += "<a href=\"" + cache + "\">" + cache + "</a>"; 65 if (href.substring(0, 7) == "http://") { 66 // ドメインを取り出す 67 var slash : int = href.indexOf("/", 7); 68 if (slash != -1) { 69 var domain : String = href.substring(7, slash); 70 if (CommonData.MAP_SHORTENEDDOMAIN[domain]) { 71 var cache : String = CommonData.urlcache[href]; 72 if(cache == null){ 73 // 伸長 74 pe.addThread(new URLExpandThread(href, CommonData.configxml.timeout)); 75 dst += "{" + ct + "}"; 76 ct++; 77 }else { 78 dst += "<a href=\"" + cache + "\">" + cache + "</a>"; 79 } 80 }else { 81 // 普通のリンクでもテキスト部分が省略されている可能性があるため。 82 dst += "<a href=\"" + href + "\">" + href + "</a>"; 83 } 74 84 } 75 85 }else if (href.substring(0, 1) == "/") { … … 77 87 var hrefstart : int = inner.indexOf("href=\"") + 6; 78 88 dst += src.substr(start, startquery.length) + inner.substring(0, hrefstart) + "https://twitter.com" + inner.substring(hrefstart) + endquery; 79 // }else if (text == "...") {80 // ...は何もしない81 }else{82 // 普通のリンクでもテキスト部分が省略されている可能性があるため。83 dst += "<a href=\"" + href + "\">" + href + "</a>";84 89 } 90 85 91 p = end + endquery.length; 86 92 } … … 93 99 private function decodeCompleted() : void 94 100 { 95 // tinyurl分を補充101 // 伸長分を補充 96 102 var decodeds : Array = [dst]; 97 103 for (var i : int = 0; i < pe.numThreads; i++) { 98 var tudt : TinyURLDecodeThread = pe.getThreadAt(i) as TinyURLDecodeThread;99 if( tudt.decoded != null){100 decodeds.push("<a href=\"" + tudt.decoded + "\">" + tudt.url+ "</a>");101 CommonData.urlcache[ tudt.url] = tudt.decoded;104 var uet : URLExpandThread = pe.getThreadAt(i) as URLExpandThread; 105 if(uet.expanded != null){ 106 decodeds.push("<a href=\"" + uet.expanded + "\">" + uet.expanded + "</a>"); 107 CommonData.urlcache[uet.url] = uet.expanded; 102 108 }else { 103 decodeds.push("<a href=\"" + tudt.url + "\">" + tudt.url + "</a>");109 decodeds.push("<a href=\"" + uet.url + "\">" + uet.url + "</a>"); 104 110 } 105 111 } air/TLife/trunk/src/uwi/thread/MainThread.as
r2546 r2589 30 30 import uwi.thread.event.UndoThread; 31 31 import uwi.thread.ReloadTimerThread; 32 import uwi.twitter.TwitterMobileLogoutThread; 32 33 import uwi.ui.multipletabbar.MultipleTabBarDragEventThread; 33 34 import uwi.util.CommonData; … … 35 36 import uwi.ui.globalconfig.GlobalConfig; 36 37 import uwi.util.TabRuleUtility; 37 38 38 39 39 /** … … 45 45 } 46 46 47 protected override function finalize() : void 48 { 49 } 50 47 51 protected override function run() : void 48 52 { 49 53 this.name = "Main"; 50 // event(NativeApplication.nativeApplication, Event.EXITING, onExit); 51 NativeApplication.nativeApplication.addEventListener(Event.EXITING, onExit); 54 event(NativeApplication.nativeApplication, Event.EXITING, onExit); 52 55 53 56 // GlobalConfig後XMLの順序がぐちゃぐちゃになるのでコメントは残せない … … 57 60 CommonData.mainstatusbar = Application.application.statusBar; 58 61 CommonData.searcher = new Searcher(); 62 CommonData.protectedpostidcache = { }; 59 63 60 64 // configxmlの読み込み … … 226 230 } 227 231 228 private function onExit(event : Event) : void 229 { 232 private function onExit(e : Event) : void 233 { 234 e.preventDefault(); 235 230 236 // DBのクローズ 231 237 if(CommonData.migemo != null)CommonData.migemo.close(); … … 233 239 CommonData.db_disk.close(); 234 240 235 // dateformatの保存 236 CommonData.configxml.main.datagrid.dateformat = CommonData.dateformatter_timeline.formatString; 237 238 saveTabRules(); 239 240 // configxmlの保存 241 FileIO.writeAll(CommonData.FILE_CONFIGXML, CommonData.configxml.toXMLString(), "UTF-8"); 241 if(CommonData.configxml.saveconfig == "true"){ 242 // dateformatの保存 243 CommonData.configxml.main.datagrid.dateformat = CommonData.dateformatter_timeline.formatString; 244 245 saveTabRules(); 246 247 // configxmlの保存 248 FileIO.writeAll(CommonData.FILE_CONFIGXML, CommonData.configxml.toXMLString(), "UTF-8"); 249 } 250 251 // ログアウト 252 var tmlt : TwitterMobileLogoutThread = new TwitterMobileLogoutThread(); 253 tmlt.start(); 254 tmlt.join(); 255 next(onLogout); 256 } 257 258 private function onLogout() : void 259 { 260 NativeApplication.nativeApplication.exit(); 242 261 } 243 262 air/TLife/trunk/src/uwi/thread/NotifyNewThread.as
r2546 r2589 59 59 CommonData.TABLE_FOLLOWING + 60 60 " where userid = '" + StringUtility.escapeSQL(CommonData.configxml.login.userid) + "')" + 61 " and " + condnewer + sqlsuffix; 61 " and " + condnewer + 62 (tabinfo.rule != "" ? (" and (" + tabinfo.rule + ")") : "") + 63 sqlsuffix; 62 64 break; 63 65 case CommonData.LABEL_REPLY: 64 sql = sqlprefix + " where content glob '*@" + StringUtility.escapeSQLForLike(CommonData.configxml.login.userid) + "*' and " + condnewer + sqlsuffix; 66 sql = sqlprefix + " where content glob '*@" + StringUtility.escapeSQLForLike(CommonData.configxml.login.userid) + "*' and " + condnewer + 67 (tabinfo.rule != "" ? (" and (" + tabinfo.rule + ")") : "") + 68 sqlsuffix; 69 break; 70 case CommonData.LABEL_FAVORITES: 71 sql = sqlprefix + " where fav = true and " + condnewer + 72 (tabinfo.rule != "" ? (" and (" + tabinfo.rule + ")") : "") + 73 sqlsuffix; 65 74 break; 66 75 default: 67 if(tabinfo.rule != null && tabinfo.rule != ""){ 68 sql = sqlprefix + tabinfo.rule + " and " + condnewer + sqlsuffix; 76 if(tabinfo.rule != ""){ 77 sql = sqlprefix + " where (" + tabinfo.rule + ") and " + 78 condnewer + sqlsuffix; 69 79 } 70 80 break; air/TLife/trunk/src/uwi/thread/ReplyGetThread.as
r2546 r2589 40 40 protected override function run() : void 41 41 { 42 replyname.text = "取得中"; 42 replyname.text = posterid; 43 44 // protectedキャッシュを調べる 45 if (CommonData.protectedpostidcache[postid]) { 46 replypost.text = "protected"; 47 replypost.setStyle("color", CommonData.configxml.main.fontcolor.replypost.protected); 48 return; 49 } 50 43 51 replypost.text = "取得中"; 44 52 replypost.setStyle("color", CommonData.configxml.main.fontcolor.replypost.getting); 45 53 54 // DBから取得。失敗の場合はwebで補う。 46 55 dbst2 = new DBSupplyThread( 47 56 CommonData.db_memory.conn, … … 59 68 var data : Object = dbst2.data; 60 69 if(data != null){ 61 replyname.text = posterid;62 63 70 CommonData.RPATagData = StringUtility.enumerateHTMLATag(data.content); 64 71 CommonData.RPprevpos = -1; … … 67 74 68 75 dbst = new DBSelectThread(CommonData.db_memory.conn, 69 "select name , iconurlfrom " + CommonData.TABLE_POSTER + " where posterid = '" + StringUtility.escapeSQL(posterid) + "'"76 "select name from " + CommonData.TABLE_POSTER + " where posterid = '" + StringUtility.escapeSQL(posterid) + "'" 70 77 ); 71 78 dbst.start(); … … 74 81 interrupted(onInterrupted); 75 82 }else { 76 dbst = new DBSelectThread(CommonData.db_memory.conn, 77 "select protected from " + CommonData.TABLE_POSTER + " where posterid = '" + StringUtility.escapeSQL(posterid) + "'" 78 ); 79 dbst.start(); 80 dbst.join(); 81 next(onProtectedCheckComplete); 83 // 失敗の場合、protectedキャッシュをもう一度調べる。 84 if (CommonData.protectedpostidcache[postid]) { 85 replypost.text = "protected"; 86 replypost.setStyle("color", CommonData.configxml.main.fontcolor.replypost.protected); 87 }else { 88 replypost.text = "Unknown Error"; 89 replypost.setStyle("color", CommonData.configxml.main.fontcolor.replypost.error); 90 } 82 91 } 83 92 } … … 95 104 } 96 105 97 private function onProtectedCheckComplete() : void98 {99 var ret : SQLResult = dbst.Result;100 var ar : Array = ret.data;101 if (ar != null) {102 if (ar.protected == true) {103 replypost.text = "protected";104 replypost.setStyle("color", CommonData.configxml.main.fontcolor.replypost.protected);105 return;106 }107 }108 replypost.text = "Unknown Error";109 replypost.setStyle("color", CommonData.configxml.main.fontcolor.replypost.error);110 }111 112 106 private function onInterrupted() : void 113 107 { air/TLife/trunk/src/uwi/thread/TimelineThread.as
r2546 r2589 41 41 private var tabinfo : Object; 42 42 43 private var conn : SQLConnection; 44 43 45 public function TimelineThread(prefetch : int = -1) { 44 46 this.name = "Timeline"; … … 74 76 } 75 77 78 conn = tabinfo.type == 1 ? CommonData.db_disk.conn : CommonData.db_memory.conn; 79 80 // SQL文の作成 76 81 var sqlprefix : String = "select postid, posterid, content, rawcontent, postedtime, replyid, fav from " + 77 82 CommonData.TABLE_STATUS; … … 84 89 CommonData.TABLE_FOLLOWING + 85 90 " where userid = '" + StringUtility.escapeSQL(CommonData.configxml.login.userid) + "')" + 91 (tabinfo.rule != "" ? (" and (" + tabinfo.rule + ")") : "") + 86 92 sqlsuffix; 87 93 break; 88 94 case CommonData.LABEL_REPLY: 89 sql = sqlprefix + " where content glob '*@" + StringUtility.escapeSQLForLike(CommonData.configxml.login.userid) + "*'" + sqlsuffix; 95 sql = sqlprefix + " where content glob '*@" + StringUtility.escapeSQLForLike(CommonData.configxml.login.userid) + "*'" + 96 (tabinfo.rule != "" ? (" and (" + tabinfo.rule + ")") : "") + 97 sqlsuffix; 98 break; 99 case CommonData.LABEL_FAVORITES: 100 sql = sqlprefix + " where fav = true" + 101 (tabinfo.rule != "" ? (" and (" + tabinfo.rule + ")") : "") + 102 sqlsuffix; 90 103 break; 91 104 default: 92 if(tabinfo.rule != null && tabinfo.rule !=""){93 sql = sqlprefix + tabinfo.rule+ sqlsuffix;105 if(tabinfo.rule != ""){ 106 sql = sqlprefix + " where (" + tabinfo.rule + ")" + sqlsuffix; 94 107 } 95 108 break; … … 97 110 Logger.debug("TimelineThread sql : " + sql); 98 111 if (sql == null) { 112 // 不適切な場合は処理しない 99 113 clearDataGrid(); 100 114 timeline.removeAll(); … … 102 116 } 103 117 104 dbst = new DBSelectThread( CommonData.db_memory.conn, sql);118 dbst = new DBSelectThread(conn, sql); 105 119 dbst.start(); 106 120 dbst.join(); … … 115 129 clearDataGrid(); 116 130 131 // タイムラインの更新 117 132 timeline.disableAutoUpdate(); 118 133 timeline.removeAll(); … … 176 191 for (var posterid : String in tempdbstmap) { 177 192 var sql : String = "select name, iconurl from " + CommonData.TABLE_POSTER + " where posterid = '" + StringUtility.escapeSQL(posterid) + "'"; 178 var ddbst : DBSelectThread = new DBSelectThread( CommonData.db_memory.conn, sql);193 var ddbst : DBSelectThread = new DBSelectThread(conn, sql); 179 194 dbstmap[posterid] = ddbst; 180 195 pe.addThread(ddbst); air/TLife/trunk/src/uwi/thread/event/ContextMenuItemEventThread.as
r2538 r2589 380 380 if (ind + 1 >= tabbar.titles.length) ind = tabbar.titles.length - 1; 381 381 tabbar.titles.addItemAt(newtabname, ind + 1); 382 tabbar.changeLayout(); 383 tabbar.SelectedIndex = ind + 1; 382 tabbar.changeLayout(ind + 1); 384 383 385 384 CommonData.tabmap[newtabname] = { … … 388 387 scrollposid : -1, 389 388 newestid : -1, 390 rule : null,389 rule : "", 391 390 unread : {}, 392 391 numnotify : -1, … … 452 451 tabbar.titles.removeItemAt(index); 453 452 delete CommonData.tabmap[label]; 454 tabbar.changeLayout();455 453 454 var ind : int; 456 455 // タブのフォーカスの移動 457 456 // 選択されていた場合は左側のタブを選択する。 458 457 if (sel >= index) { 459 458 if (sel == 0 && index == 0) { 460 tabbar.SelectedIndex= tabbar.titles.length > 0 ? 0 : -1;459 ind = tabbar.titles.length > 0 ? 0 : -1; 461 460 }else{ 462 tabbar.SelectedIndex= sel - 1;461 ind = sel - 1; 463 462 } 464 463 }else { 465 tabbar.SelectedIndex = sel; 466 } 464 ind = sel; 465 } 466 tabbar.changeLayout(ind); 467 467 468 CommonData.tabrules = TabRuleUtility.optimizeTabRules(tabbar.titles, CommonData.tabrules); 468 469 } air/TLife/trunk/src/uwi/thread/event/IncrementalSearchThread.as
r2497 r2589 118 118 case 2: 119 119 switch(e.keyCode) { 120 case Keyboard.ENTER:121 eraseQuery();122 mode = 0;123 break;124 120 case Keyboard.ESCAPE: 125 121 eraseQuery(); 126 122 Application.application.timeline.filterFunction = null; 123 Application.application.timeline.refresh(); 127 124 mode = 0; 128 125 break; 129 126 case Keyboard.BACKSPACE: 130 127 if (query.length <= 1) { 128 eraseQuery(); 131 129 Application.application.timeline.filterFunction = null; 132 eraseQuery();130 Application.application.timeline.refresh(); 133 131 mode = 0; 134 132 }else{ … … 157 155 case 3: 158 156 switch(e.keyCode) { 159 case Keyboard.ENTER:160 eraseQuery();161 mode = 0;162 break;163 157 case Keyboard.ESCAPE: 164 158 eraseQuery(); 165 159 Application.application.timeline.filterFunction = null; 160 Application.application.timeline.refresh(); 166 161 mode = 0; 167 162 break; 168 163 case Keyboard.BACKSPACE: 169 164 if (query.length <= 1) { 165 eraseQuery(); 170 166 Application.application.timeline.filterFunction = null; 171 eraseQuery();167 Application.application.timeline.refresh(); 172 168 mode = 0; 173 169 }else{ air/TLife/trunk/src/uwi/thread/event/PostEventThread.as
r2492 r2589 6 6 import flash.events.TextEvent; 7 7 import flash.ui.Keyboard; 8 import ken39arg.logging.Logger; 8 9 import mx.controls.Button; 9 10 import mx.controls.Label; … … 14 15 import mx.validators.StringValidator; 15 16 import org.libspark.thread.Thread; 17 import org.libspark.thread.utils.ParallelExecutor; 18 import uwi.shortening.URLShortenThread; 16 19 import uwi.twitter.TwitterPostThread; 17 20 import uwi.twitter.TwitterScrapeThread; … … 33 36 private var sub : EventThread; 34 37 private var uict : UserIDCompleteThread; 38 private var postedtext : String; 35 39 36 40 private static const EVENT_CHANGE : Event = new Event(Event.CHANGE); … … 89 93 private function onSubmit(e : Event) : void 90 94 { 91 if (postarea.text.length > CommonData.LIMLEN_POST) { 95 postedtext = postarea.text; 96 97 if (postedtext.length > CommonData.LIMLEN_POST) { 92 98 return; 93 99 } 94 if (post area.text.length == 0) {100 if (postedtext.length == 0) { 95 101 return; 96 102 } 97 103 104 post(); 105 /* 106 // ポスト直前に短縮する 107 if (CommonData.configxml.shortening != "") { 108 shorten(); 109 }else { 110 post(); 111 } 112 */ 113 } 114 115 private static const PTN_URL : RegExp = /https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/g; 116 117 /* 118 private function shorten() : void 119 { 120 var pe : ParallelExecutor = new ParallelExecutor(); 121 122 var temp : String = postedtext; 123 // 発言からURLを抽出 124 var ret : Object; 125 while (ret = PTN_URL.exec(postedtext)) { 126 var href : String = ret[0]; 127 if (href.substring(0, 7) == "http://") { 128 // ドメインを取り出す 129 var slash : int = href.indexOf("/", 7); 130 if (slash != -1) { 131 var domain : String = href.substring(7, slash); 132 if (!CommonData.MAP_SHORTENEDDOMAIN[domain]) { 133 // 短縮されていない場合短縮する 134 pe.addThread(new URLShortenThread( 135 } 136 } 137 } 138 } 139 } 140 */ 141 142 private function post() : void 143 { 98 144 postbtn.enabled = false; 99 var footer : String = CommonData.configxml.footer .toString();145 var footer : String = CommonData.configxml.footer; 100 146 if (footer != "") footer = " " + footer; 101 147 148 // TODO 複数reply時のin_reply_to_status_idのとりかた 102 149 var tpt : TwitterPostThread = new TwitterPostThread( 103 150 "http://twitter.com/statuses/update.xml", … … 107 154 , "GET"); 108 155 tpt.start(); 109 tpt.join( );156 tpt.join(CommonData.configxml.timeout); 110 157 error(Error, onError); 158 timeout(onTimeout); 111 159 next(onPostCompleted); 112 160 } … … 114 162 private function onPostCompleted() : void 115 163 { 164 Logger.debug("PostEventThread Successed"); 165 116 166 CommonData.in_reply_to_status_id = ""; 117 167 postarea.text = ""; 118 168 Application.application.changeCharLeft(); 119 169 120 new TwitterScrapeThread().start();121 170 postbtn.enabled = true; 122 171 next(waitEvents); … … 125 174 private function onError(e : Error, t : Thread) : void 126 175 { 176 Logger.warn("PostEventThread Error"); 177 Logger.stacktrace(e); 127 178 CommonData.in_reply_to_status_id = ""; 179 postbtn.enabled = true; 180 next(waitEvents); 181 } 182 183 private function onTimeout() : void 184 { 185 Logger.warn("PostEventThread Timeout"); 128 186 postbtn.enabled = true; 129 187 next(waitEvents); air/TLife/trunk/src/uwi/twitter/TwitterBitScrapeThread.as
r2546 r2589 9 9 import org.libspark.thread.utils.ParallelExecutor; 10 10 import uwi.bean.Status; 11 import uwi.db.DBSelectThread; 11 12 import uwi.db.SimpleTransactionThread; 12 13 import uwi.thread.FollowingCheckThread; … … 29 30 30 31 public var posterid : String; 32 public var postid : String; 31 33 32 34 public function TwitterBitScrapeThread(posterid : String, postid : String) … … 34 36 this.name = "TwitterBitScrape"; 35 37 this.posterid = posterid; 38 this.postid = postid; 39 } 40 41 protected override function run() : void 42 { 36 43 var req : URLRequest = new URLRequest("https://twitter.com/" + posterid + "/status/" + postid); 37 44 Logger.debug("TwitterBitScrapeThraed url : " + req.url); 38 45 req.followRedirects = true; 39 46 ult = new URLLoaderThread(req); 40 }41 42 protected override function run() : void43 {44 47 ult.start(); 45 48 waitEvents(); … … 60 63 if (e.status == 403) { 61 64 // protected 62 pe = new ParallelExecutor(); 63 var sql : String = "replace into " + CommonData.TABLE_POSTER + " (posterid, protected, lastupdated) values (:posterid, true, :lastupdated)"; 64 var args : Array = [ { posterid : posterid, lastupdated : new Date()} ]; 65 pe.addThread(new SimpleTransactionThread(CommonData.db_memory.conn, sql, args)); 66 pe.addThread(new SimpleTransactionThread(CommonData.db_disk.conn, sql, args)); 67 68 pe.start(); 69 pe.join(); 70 interrupted(onInterrupted); 65 CommonData.protectedpostidcache[postid] = 0; 71 66 }else { 72 67 next(waitEvents); … … 80 75 81 76 pe = new ParallelExecutor(); 82 83 /*84 if(ret.code == 0 || ret.code == 1){85 var sql : String = "replace into " + CommonData.TABLE_POSTER + " (posterid, protected, lastupdated) values (:posterid, :protected_, :lastupdated)";86 var args : Array = [ { protected_ : ret.code == 1, posterid : posterid, lastupdated : new Date()} ];87 pe.addThread(new SimpleTransactionThread(CommonData.db_memory.conn, sql, args));88 pe.addThread(new SimpleTransactionThread(CommonData.db_disk.conn, sql, args));89 }*/90 77 91 78 switch(ret.code) { air/TLife/trunk/src/uwi/twitter/TwitterLoginThread.as
r2546 r2589 42 42 CommonData.mainstatusbar.write("ログイン中.."); 43 43 44 ult = new URLLoaderThread(new URLRequest("http ://twitter.com/home"));44 ult = new URLLoaderThread(new URLRequest("https://twitter.com/home")); 45 45 ult.start(); 46 46 ult.join(CommonData.configxml.timeout); … … 76 76 ult = new URLLoaderThread(req); 77 77 ult.start(); 78 trace("timeout : " + int(CommonData.configxml.timeout)); 78 79 ult.join(CommonData.configxml.timeout); 79 80 event(ult.loader, HTTPStatusEvent.HTTP_RESPONSE_STATUS, onResponse); … … 104 105 105 106 if (event.status == 200) { 106 if (event.responseURL == "https://twitter.com/ home" || event.responseURL == "http://twitter.com/home") {107 if (event.responseURL == "https://twitter.com/") { 107 108 Logger.info("TwitterLoginThread Login Succeeded"); 108 109 CommonData.mainstatusbar.write("ログイン成功!"); air/TLife/trunk/src/uwi/ui/complete/CompleteThread.as
r2546 r2589 101 101 private function onKeyDown(e : KeyboardEvent) : void 102 102 { 103 trace("onKeyDown " + invalidflag);104 103 if (list.isPopUp) { 105 104 switch(e.keyCode) { air/TLife/trunk/src/uwi/ui/multipletabbar/MultipleTabBar.as
r2546 r2589 28 28 * 領域に収まるようにTabBarの項目を調節する。 29 29 */ 30 public function changeLayout( silent : Boolean = false) : void30 public function changeLayout(index : int = -1) : void 31 31 { 32 32 clear(); 33 // trace("きたー");34 33 35 34 var tab : TabBar = new TabBar(); // カレントタブバー … … 41 40 tablist.push(tab); 42 41 43 trace(this.width);42 // TODO タブ幅をキャッシュ化 44 43 for (var i : int = 0; i < titles.length; i++) { 45 44 var str : String = titles[i]; … … 48 47 tab.validateSize(true); 49 48 // strを加えた時点でカレントタブバーの長さが全体を上回ったら 50 if (tab.measuredWidth >= this. width) {49 if (tab.measuredWidth >= this.owner.width) { 51 50 // カレントタブバーの要素数が1個より大きい場合、strを除いて巻き戻す 52 51 if (tabdp.length > 1) { … … 65 64 } 66 65 this.height = tabheight * tablist.length; 67 if(!silent)SelectedIndex = selectedIndex;66 this.validateNow(); 68 67 68 var ind : int = index != -1 ? index : selectedIndex; 69 setSelectedIndexCore(ind); 69 70 this.validateNow(); 70 71 } … … 113 114 114 115 dispatchEvent(EVENT_CHANGE); 115 selectedIndex = ind; 116 setSelectedIndexCore(ind); 117 } 118 119 private function setSelectedIndexCore(ind : int) : void 120 { 121 this.selectedIndex = ind; 116 122 117 123 var targ : TabBar = null; … … 120 126 for each (targ in tablist) { 121 127 sum -= targ.numChildren; 122 if (sum < =0) {128 if (sum < 0) { 123 129 targ.selectedIndex = sum + targ.numChildren; 124 130 break; air/TLife/trunk/src/uwi/ui/multipletabbar/MultipleTabBarDragEventThread.as
r2531 r2589 63 63 // toind -= fromind < toind ? 1 : 0; 64 64 mtb.titles.addItemAt(mtb.titles.removeItemAt(fromind), toind); 65 mtb.SelectedIndex = toind; 66 mtb.changeLayout(); 65 mtb.changeLayout(toind); 67 66 } 68 67 } air/TLife/trunk/src/uwi/ui/multipletabbar/MultipleTabBarEventThread.as
r2546 r2589 3 3 import flash.events.Event; 4 4 import mx.controls.TabBar; 5 import mx.core.Application; 5 6 import mx.events.CollectionEvent; 6 7 import mx.events.ItemClickEvent; … … 36 37 { 37 38 event(mtb.titles, CollectionEvent.COLLECTION_CHANGE, onResize); 38 event(mtb , Event.RESIZE, onResize);39 event(mtb.owner, Event.RESIZE, onResize); 39 40 for each(var tab : TabBar in mtb.tablist) { 40 41 event(tab, ItemClickEvent.ITEM_CLICK, onItemClick); … … 44 45 private function onResize(e : Event) : void 45 46 { 46 trace("RESIZE"); 47 mtb.changeLayout(true); 47 mtb.changeLayout(); 48 48 next(waitEvents); 49 49 } air/TLife/trunk/src/uwi/ui/tabconfig/TabConfigEventThread.as
r2546 r2589 125 125 scrollposid : -1, 126 126 newestid : -1, 127 rule : null,127 rule : "", 128 128 unread : {}, 129 129 numnotify : -1, air/TLife/trunk/src/uwi/util/CommonData.as
r2546 r2589 116 116 public static var balloons : Dictionary = new Dictionary(true); 117 117 118 public static var protectedpostidcache : Object; 119 118 120 public static var searcher : Searcher; 119 121 … … 142 144 "postedtime" : uwi.ui.TimelineRenderer 143 145 } 146 147 public static const MAP_SHORTENEDDOMAIN : Object = { 148 "tinyurl.com" : "http://tinyurl.com/api-create.php?url={0}", 149 "is.gd" : "http://is.gd/api.php?longurl={0}", 150 "snipurl.com" : "http://snipurl.com/site/snip?r=simple&link={0}", // deprecated? (snipr.com) 151 "snurl.com" : "http://snurl.com/site/snip?r=simple&link={0}", // deprecated? 152 "nsfw.in" : "", 153 "qurlyq.com" : "", 154 "dwarfurl.com" : "", 155 "icanhaz.com" : "", 156 "tiny.cc" : "", 157 "urlenco.de" : "", 158 "bit.ly" : "http://api.bit.ly/?url={0}", // nonstandard? 159 "piurl.com" : "", 160 "traceurl.com" : "", 161 "twurl.nl" : "", 162 "cli.gs" : "", 163 "rubyurl.com" : "", 164 "budurl.com" : "", 165 "friendfeed.com" : "" 166 } 144 167 } 145 168 air/TLife/trunk/src/uwi/util/StatusScraper.as
r2501 r2589 79 79 // replyid 80 80 var replyid : String = ""; 81 var objReply : Object = PTN_REPLYTO.exec(str); 82 if (objReply) replyid = objReply[1]; 83 /* 84 var replyid : String = ""; 81 85 var replytobase : int = str.indexOf(">in reply to"); 82 86 if (replytobase != -1) { 83 87 replyid = StringUtility.pinch(str.substr(replytobase - 30, 30), "status/", "\""); 84 88 } 89 */ 85 90 86 91 // postedtime … … 102 107 var fav : Boolean = (str.indexOf("<a class=\"fav-action non-fav\"") == -1); 103 108 104 //Logger.debug(new Status(postid, postername, posterid, content, replyid, postedtime, iconurl, fav));109 Logger.debug(new Status(postid, postername, posterid, content, replyid, postedtime, iconurl, fav)); 105 110 ret.push(new Status(postid, postername, posterid, content, replyid, postedtime, iconurl, fav)); 106 111 } … … 116 121 private static const ptnNum : RegExp = /[0-9]+/; 117 122 123 // 5秒以内前 124 // 30秒前後前 125 // 1分未満前 126 // 2分前 127 // 約2時間前 128 // 5:12 AM May 6th 118 129 private static function implyTime(datestr : String) : Date 119 130 { 120 131 var result : Object; 121 132 var now : Date = new Date(); 122 if (datestr.lastIndexOf(" ago") != -1) {133 if (datestr.lastIndexOf("前") != -1) { 123 134 result = ptnNum.exec(datestr); 124 135 if (result != null) { 125 136 var num : int = result[0]; 126 137 if (datestr.indexOf("時間") != -1) { 127 // 約n時間 ago138 // 約n時間前 128 139 now.setTime(now.getTime() - num * 60 * 60 * 1000); 129 140 }else { 130 141 if (datestr.indexOf("秒") != -1) { 131 // n秒前後 ago 142 // n秒以内前 143 // n秒前後前 132 144 now.setTime(now.getTime() - num * 1000); 133 145 }else { 134 // 1分未満 ago135 // n分 ago146 // 1分未満前 147 // n分前 136 148 now.setTime(now.getTime() - num * 60 * 1000); 137 149 } … … 151 163 } 152 164 165 private static const PTN_REPLYTO : RegExp = /([0-9]+)\">[A-Za-z0-9_]*宛</; 153 166 154 167 /** … … 173 186 return { status : null, code : 1 }; 174 187 } 175 var title : String = StringUtility.pinch(src, "<title> ", " on Twitter</title>");188 var title : String = StringUtility.pinch(src, "<title>Twitter / ", ":"); 176 189 if (title == "?") { 177 190 return { status : null, code : 2 }; … … 191 204 192 205 // posterid 193 var posterid : String = StringUtility.pinch(thumb, " a href=\"https://twitter.com/", "\">");206 var posterid : String = StringUtility.pinch(thumb, "twitter.com/", "\""); 194 207 195 208 // postername … … 198 211 199 212 var entrymeta : String = StringUtility.pinch(src, "<span class=\"meta entry-meta\">", "</span></span>"); 213 200 214 // postid 201 215 var postid : String = StringUtility.pinch(entrymeta, posterid + "/status/", "\""); … … 215 229 // replyid 216 230 var replyid : String = ""; 231 var objReply : Object = PTN_REPLYTO.exec(entrymeta); 232 if (objReply) replyid = objReply[1]; 233 /* 217 234 var replytobase : int = entrymeta.indexOf(">in reply to"); 218 235 if (replytobase != -1) { 219 236 replyid = StringUtility.pinch(entrymeta.substr(replytobase - 30, 30), "status/", "\""); 220 237 } 238 */ 221 239 222 240 // fav … … 227 245 } 228 246 229 //Logger.debug(new Status(postid, postername, posterid, content, replyid, postedtime, iconurl, fav));247 Logger.debug(new Status(postid, postername, posterid, content, replyid, postedtime, iconurl, fav)); 230 248 return { status : new Status(postid, postername, posterid, content, replyid, postedtime, iconurl, fav), code : 0 }; 231 249 } air/TLife/trunk/src/uwi/util/TabRuleUtility.as
r2538 r2589 86 86 } 87 87 if (sql == "") { 88 sql = " where(" + conds.join(" and ") + ")";88 sql = "(" + conds.join(" and ") + ")"; 89 89 }else { 90 90 sql += " or (" + conds.join(" and ") + ")"; air/TLife/trunk/src/uwi/util/URLPostThread.as
r2501 r2589 60 60 protected function onTimeout() : void 61 61 { 62 ult.interrupt(); 63 ult = null; 62 64 Logger.debug("URLPostThread timeout"); 63 65 }

