/**
* Copyright tepe ( http://wonderfl.net/user/tepe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oW2G
*/
package //ozworks
{
import flash.display.Sprite;
import flash.text.*;
import flash.events.*;
import flash.net.*;
public class Main extends Sprite {
private var t:TextField = new TextField();
private var td:TwitData = new TwitData();
public function Main() {
td.addEventListener(Event.COMPLETE,onComplete);
addEventListener(KeyboardEvent.KEY_UP,onKey);
td.requestKeyword("#oshu");
this.graphics.beginFill(0x000000);
this.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
this.graphics.endFill();
scrText.setTextField(466,20);
scrText.speed = 2;
scrText.y = 446;
addChild(scrText);
}
private function onKey(e:KeyboardEvent):void{
if(e.keyCode == 32){
td.addEventListener(Event.COMPLETE,onComplete);
td.moreRequest();
}
if(e.keyCode == 13){
td.addEventListener(Event.COMPLETE,onComplete);
td.reload();
}
if(e.keyCode == 90){
scrText.insert("[速報] Test Test Test Test Test Test");
}
}
private var scrText:scrollText = new scrollText();
private function onComplete(e:Event):void{
td.removeEventListener(Event.COMPLETE,onComplete);
//t.htmlText = td.list.length.toString();
//t.htmlText = "";
for(var i:int=0;i<td.list.length;i++){
var str:String = new String();
str = '<font color="#ffffff">';
str += td.list[i].time.toLocaleTimeString()+" " + '<font color="#00cc00">[ '+td.list[i].user+' ]</font>'+"<br>";
str += '<font color="#dddddd">'+td.list[i].title+' </font>'+"<br><br>";
str += '<font>';
scrText.add(str);
}
/*
var st:scrollText = new scrollText();
st.setTextField(t,466,20);
st.y = 446;
addChild(st);
*/
}
}
}
import flash.display.*;
import flash.events.*;
//------------------------
class TwitData extends Loader{
private var loader:twitLoader = new twitLoader();
public var list:Array;
private var _youngID:Number=0;
private var _oldID:Number=0;
public function TwitData(){
list = new Array();
trace("init");
}
public function get youngID():Number{
return _youngID;
}
public function get oldID():Number{
return _oldID;
}
public function requestUser(userID:String):void{
clear();
loader.addEventListener(Event.COMPLETE,onLoaded);
loader.setUserID(userID);
loader.request();
trace("request_user");
}
public function requestKeyword(key:String):void{
clear();
loader.addEventListener(Event.COMPLETE,onLoaded);
loader.setKeyword(key);
loader.request();
trace("request_keyword");
}
public function moreRequest():void{
loader.addEventListener(Event.COMPLETE,onLoaded);
loader.moreRequest(_oldID);
trace("more_request");
}
private var wait:Boolean = false;
public function reload():void{
if(wait==false){
loader.addEventListener(Event.COMPLETE,onReloaded);
loader.reload(_youngID);
wait=true;
trace("reload");
}
}
public function clear():void{
list.length = 0;
_oldID = 0;
_youngID = 0;
trace("clear");
}
private function onLoaded(e:Event):void{
loader.removeEventListener(Event.COMPLETE,onLoaded);
default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
var len:int = loader.length;
trace(loader.length);
for(var i:int=0;i<len;i++){
var item:Twit = new Twit(XML(loader.result.entry[i]));
list.push(item);
}
if(_youngID == 0)_youngID = loader.youngID;
else if(_youngID < loader.youngID)_youngID = loader.youngID;
if(_oldID == 0)_oldID = loader.oldID;
else if(_oldID > loader.oldID)_oldID = loader.oldID;
dispatchEvent(new Event(Event.COMPLETE) );
}
private function onReloaded(e:Event):void{
loader.removeEventListener(Event.COMPLETE,onReloaded);
wait = false;
default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
var len:int = loader.length;
trace(loader.length);
if(len<2){//レスポンスに新しいツイートがなければ終了
dispatchEvent(new Event(Event.COMPLETE) );
trace("no item");
return;
}
var newList:Array = new Array();
for(var i:int=0;i<len;i++){
var item:Twit = new Twit(XML(loader.result.entry[i]));
if(item.id != _youngID){
newList.push(item);
trace(item.time.toLocaleTimeString());
}
else{//リストをつなげる
list = newList.concat(list);
newList.length = 0;
trace("addList");
break;
}
}
if(newList.length != 0){//新しいツイートが多かったら今までのリストと入れ替え
list = newList;
_youngID = 0;
_oldID = 0;
trace("resetList");
}
if(_youngID == 0)_youngID = loader.youngID;
else if(_youngID < loader.youngID)_youngID = loader.youngID;
if(_oldID == 0)_oldID = loader.oldID;
else if(_oldID > loader.oldID)_oldID = loader.oldID;
dispatchEvent(new Event(Event.COMPLETE) );
}
}
//------------------------
//ツイートデータ
// id:Number ツイートID
// time:Date タイムスタンプ
// text:String オリジナルの本文。
// title:String 本文。htmlText形式。ハッシュタグは非表示。
// user:String ユーザー表示名
// account:String アカウント名
// tag:Array ハッシュタグ
// imgURL:String ユーザーアイコンのURL
// homeURL:String ユーザータイムラインのURL
class Twit{
private var data:Object;
private var itemXML:XML;
public function Twit(entry:XML=null){
default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
if(entry==null)return;
data = twitObj(entry);
}
public function get id():Number{
return data.id;
}
public function get time():Date{
return data.time;
}
public function get text():String{
return data.text;
}
public function get title():String{
return data.title;
}
public function get account():String{
return data.account;
}
public function get user():String{
return data.user;
}
public function get tag():Array{
return data.tag;
}
public function get imgURL():String{
return data.imgURL;
}
public function get homeURL():String{
return data.homeURL;
}
//ツイートデータ
// id:Number ツイートID
// time:Date タイムスタンプ
// text:String オリジナルの本文。
// title:String 本文。htmlText形式。ハッシュタグは非表示。
// user:String ユーザー表示名
// account:String アカウント名
// tag:Array ハッシュタグ
// imgURL:String ユーザーアイコンのURL
// homeURL:String ユーザータイムラインのURL
public function twitObj(entry:XML):Object{
default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
itemXML = entry;
var item:Object = new Object();
item.time = getTime( entry.published);//文字列 → 日時データ
item.id = Number( idNum( entry.id));//ツイートID
item.homeURL = entry.author.uri;//ユーザータイムラインへのリンク
item.user = getUserName( entry.author.name);//ユーザー名(表示名)
item.account = getAccountName( entry.author.name);//アカウント
item.text = entry.title;
item.title = setHttpLink( removeTag( entry.title));//本文 タグ除外
item.tag = getTag( entry.title);//タグリスト
//アイコン画像のURLを取得
var imgURL:String = entry.link[1].@href;
var extention:String = imgURL.substr( -4);
extention = extention.toLowerCase();
if (extention != ".jpg" && extention != ".gif" && extention != ".png") {
imgURL = "http://s.twimg.com/a/1254440757/images/default_profile_mini.png";//デフォルトアイコン
}
imgURL = encodeURI(imgURL);
item.imgURL = imgURL;
return item;
}
private function idNum(id:String):Number{
var reg:RegExp = new RegExp();
reg = /:\d+/;
var result:Object = reg.exec(id);
var str:String = id.substring(result.index+1);
return Number(str);
}
//URLにリンクを付ける
private function setHttpLink(str:String):String{
var reg:RegExp = new RegExp();
reg = /http(:|s:)\/\/[\w.%&\/]+/g;
var result:Object;
var res2:String=new String();
var str2:String;
var prev:int=0;
for(var i:int =0;i<10;i++){
result = reg.exec(str);
if(result == null)break;
if(reg.lastIndex!=0){
res2+=str.substring(prev,result.index);
str2 = str.substring(result.index,reg.lastIndex);
res2+="<a href='" + str2 + "' target='_blank'>"+ '<u><font color="#0088ff">'+ str2+"</font></u>"+"</a>";
prev=reg.lastIndex;
}
else{
res2+=str.substring(prev,result.index);
str2 = str.substring(result.index);
res2+="<a href='" + str2 + "' target='_blank'>"+ '<u><font color="#0088ff">'+ str2+"</font></u>"+"</a>";
prev=str.length;
break;
}
}
res2+=str.substring(prev);
return res2;
}
//表示名取得
private function getUserName(str:String=""):String{
var reg:RegExp = new RegExp();
reg = / (.*)/;
var result:Object;
var str2:String;
result = reg.exec(str);
str2 = str.substring(result.index+2,str.length-1);
return str2;
}
//アカウント名取得
private function getAccountName(str:String=""):String{
var reg:RegExp = new RegExp();
reg = / /;
var result:Object;
var str2:String;
result = reg.exec(str);
str2 = str.substring(0,result.index);
return str2;
}
//ID取得
private function getUserID(str:String=""):String{
var reg:RegExp = new RegExp();
reg = /.+ /;
var result:Object;
var str2:String;
result = reg.exec(str);
str2 = str.substring(result.index,str.length-1);
return str2;
}
//本文からタグ情報を削除する
private function removeTag(str:String=""):String{
var reg:RegExp = new RegExp();
reg = /#[^ $]+/g;
var result:Object;
var res2:String=new String();
var str2:String;
var prev:int=0;
for(var i:int =0;i<10;i++){
result = reg.exec(str);
if(result == null)break;
if(reg.lastIndex!=0){
res2+=str.substring(prev,result.index);
prev=reg.lastIndex;
}
else{
res2+=str.substring(prev,result.index);
prev=str.length;
break;
}
}
res2+=str.substring(prev);
return res2;
}
//タイムスタンプ取得
private function getTime(str:String):Date{
var year:int, mon:int, day:int, hour:int, min:int, sec:int;
//日付取得
var reg:RegExp = new RegExp();
reg = /\d\d\d\d-\d\d-\d\d/g;
var res:Object= reg.exec(str);
var str2:String = str.substring(res.index,reg.lastIndex);
year = parseInt(str2.substring(0,4));
mon = parseInt(str2.substring(5,7))-1;
day = parseInt(str2.substring(8,10));
//時間取得
var reg2:RegExp = new RegExp()
reg2 = /\d\d:\d\d:\d\d/g;
res = reg2.exec(str);
str2 = str.substring(res.index,reg2.lastIndex);
hour = parseInt(str2.substring(0,2));
min = parseInt(str2.substring(3,5));
sec = parseInt(str2.substring(6,8));
//日時データ生成
var dat:Date = new Date(year,mon,day,hour,min,sec);
dat.minutes-=dat.timezoneOffset;//GMTをローカルタイムに修正
return dat;
}
//本文からタグ情報を取得
private function getTag(str:String):Array{
var tagList:Array = new Array();
var reg:RegExp = new RegExp();
var result:Object;
var tag:String;
reg = /#[^ $]+/g;
for(var i:int =0;i<20;i++){//20まで
result = reg.exec(str);
if(result == null)break;
if(reg.lastIndex!=0){
tag = str.substring(result.index,reg.lastIndex);
tagList.push(tag);
}
else{
tag = str.substring(result.index,str.length);
tagList.push(tag);
break;
}
}
return tagList;
}
}
//------------------------
import flash.events.*;
import flash.net.*;
import flash.utils.*;
class twitLoader extends URLLoader{
public var youngID:Number;//リスト内で一番新しいツイート
public var oldID:Number;//リスト内で一番古いツイート
public var result:XML;
public function get length():int {
return int(result.entry.length());
}
//Twitterへ結果をポスト
public function postTwitter(post:String):void {
//var comment:String = tweet;
//var post:String = comment + " " + "http://wonderfl.net/c/kagi" + " " + "#wonderfl";
navigateToURL(new URLRequest("http://twitter.com/home?status=" + escapeMultiByte(post)), "_blank");
}
private var requestURL:String ="";
//リクエスト実行
public function request():void{
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
loader.load(new URLRequest(requestURL));
}
//キーワードを指定してリクエスト
public function setKeyword(keyword:String=""):void{
if(keyword=="")return;
var myURLLoader:URLLoader = new URLLoader();
var xmlURL:String = "http://search.twitter.com/search.atom?q=";
xmlURL += encodeURIComponent(keyword);
requestURL = xmlURL;
}
//ユーザーを指定してリクエスト
public function setUserID(userID:String=""):void{
if(userID=="")return;
//url指定
const SEARCH_PARAMS:Object = { rpp:15 };//取得数
var xmlURL:String = "http://search.twitter.com/search.atom?q="+"from%3A"+ userID
for (var key:String in SEARCH_PARAMS) {
xmlURL += "&" + key + "=" + SEARCH_PARAMS[key];
}
requestURL = xmlURL;
}
//追加リクエスト
public function moreRequest(id:Number=0):void{
if(requestURL=="")return;
if(id==0)id=oldID;
var myURLLoader:URLLoader = new URLLoader();
myURLLoader.addEventListener(Event.COMPLETE, onComplete);
myURLLoader.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
myURLLoader.load(new URLRequest(requestURL + "&max_id=" + id.toString()));
}
//新しいツイート要求
public function reload(id:Number=0):void{
if(requestURL=="")return;
if(id==0)id=youngID;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, onIoError);
loader.load(new URLRequest(requestURL + "&since_id=" + id.toString()));
}
public function onIoError(e:IOErrorEvent):void {
trace(e.type);
}
//ロード完了
private function onComplete(e:Event):void{
//XML型にキャスト
result = new XML(e.currentTarget.data);
default xml namespace = new Namespace("http://www.w3.org/2005/Atom");
var len:int = result.entry.length();
if (len < 1) {//例外処理
trace(result);
dispatchEvent(new Event(Event.COMPLETE) );
return;
}
var id:Number = idNum(result.entry[0].id);
youngID = id;
oldID = id;
for(var i:int=0;i<len;i++){
id = idNum(result.entry[i].id);
//idの評価
if( youngID < id )youngID=id;
if( id < oldID )oldID=id;
}
dispatchEvent(new Event(Event.COMPLETE) );
}
//id要素を数値に変換
private function idNum(id:String):Number{
var reg:RegExp = new RegExp();
reg = /:\d+/;
var result:Object = reg.exec(id);
var str:String = id.substring(result.index+1);
return Number(str);
}
}
//-------------------
import flash.display.*;
import flash.events.*;
import flash.text.*;
class scrollText extends Sprite{
private var m:Sprite = new Sprite();
private var tf:TextField = new TextField();
public var speed:Number = 1;
private var list:Array = new Array();
public function scrollText(){
m.graphics.beginFill(0xff0000,1);
m.graphics.drawRect(40,0,100,20);
m.graphics.endFill();
addChild(m);
tf.mask = m;
//addEventListener(Event.ENTER_FRAME,onEnter);
}
public function add(str:String):int{
list.push(str);
if(list.length==1){
addEventListener(Event.ENTER_FRAME,onEnter);
tf.htmlText = list[0];
tf.width = tf.textWidth;
tf.x = m.width;
}
return list.length;
}
public function clear():void{
list.length = 0;
}
//今流れているテロップをキャンセルし新しいテロップを表示する。キャンセルしたテロップは次に流れる。
public function insert(str:String):void{
if(list.length==0) addEventListener(Event.ENTER_FRAME,onEnter);
tf.htmlText = str;
tf.width = tf.textWidth+20;
tf.x = m.width+30;
}
public function setTextField(w:Number=100,h:Number=20,t:TextField=null):void{
if(t != null)tf=t;
tf.mask = m;
tf.selectable = false;
tf.multiline = false;
tf.wordWrap = false;
tf.width=tf.textWidth;
tf.height=h;
addChild(tf);
m.graphics.clear();
m.graphics.beginFill(0xff0000);
m.graphics.drawRect(0,0,w,h);
m.graphics.endFill();
}
private function onEnter(e:Event):void{
tf.x -= speed;
if(tf.x+tf.width < 0){
list.shift();
if(list.length == 0){
dispatchEvent(new Event(Event.COMPLETE) );
removeEventListener(Event.ENTER_FRAME,onEnter);
}
else{
tf.htmlText = list[0];
tf.width = tf.textWidth;
tf.x = m.width;
}
}
}
}