東京メトロ UI

やっぱり、「メトロ」といえば、これでしょう?

HTML5 の canvas を利用して、東京メトロUI を実現している方なんて、誰もいませんからッ!!!

HTMLでメトロUIっぽい画面をつくってみた ? テスターですが何か?

http://david9142.wordpress.com/2012/01/18/html%e3%81%a7%e3%83%a1%e3%83%88%e3%83%adui%e3%81%a3%e3%81%bd%e3%81%84%e7%94%bb%e9%9d%a2%e3%82%92%e3%81%a4%e3%81%8f%e3%81%a3%e3%81%a6%e3%81%bf%e3%81%9f/

[inline]

図形を表示するには、canvasタグをサポートしたブラウザが必要です。

[script type=”text/javascript”]

[/script]
[/inline]

ソースコードはこちら

<canvas id=&quot;sample1&quot; style=&quot;background-color:white;&quot; width=&quot;1000&quot; height=&quot;600&quot;>
図形を表示するには、canvasタグをサポートしたブラウザが必要です。
</canvas>

<script type=&quot;text/javascript&quot;>
<!--
function sample() {
var canvas = document.getElementById('sample1');
if (!canvas.getContext) return ;
var ctx = canvas.getContext('2d');

metro( ctx, 60+(100+20)*0,75, 'rgb(243,173,0)',&quot;G&quot; );
metro( ctx, 60+(100+20)*1,75, 'rgb(227,27,11)',&quot;M&quot; );
metro( ctx, 60+(100+20)*2,75, 'rgb(208,200,184)',&quot;H&quot; );
metro( ctx, 60+(100+20)*3,75, 'rgb(11,157,227)',&quot;T&quot; );
metro( ctx, 60+(100+20)*4,75, 'rgb(3,168,90)',&quot;C&quot; );

metro( ctx, 60+(100+20)/2*1,75+150, 'rgb(217,175,82)',&quot;Y&quot; );
metro( ctx, 60+(100+20)/2*3,75+150, 'rgb(147,127,185)',&quot;Z&quot; );
metro( ctx, 60+(100+20)/2*5,75+150, 'rgb(0,175,149)',&quot;N&quot; );
metro( ctx, 60+(100+20)/2*7,75+150, 'rgb(171,91,25)',&quot;F&quot; );

}
function metro(ctx,x,y,col,m)
{
ctx.beginPath();
ctx.fillStyle = col;
ctx.arc(x,y,50,0,Math.PI*2,true);
ctx.fill();

ctx.beginPath();
ctx.arc(x,y,25,0,Math.PI*2,true);
ctx.fillStyle = 'rgb(255,255,255)';
ctx.fill();

ctx.beginPath();
ctx.font = &quot;bold 42px 'Arial'&quot;;
ctx.fillStyle = &quot;black&quot;;
ctx.textAlign = &quot;center&quot;;
ctx.fillText(m, x, y+15);
}
// 実行
sample();
//-->
</script>
カテゴリー: 雑談 | 2件のコメント

C# で XML ファイルを作成するときの比較(XmlDocument, XDocument, ExDoc)

「ツイートキャッチ★★★」で xml 形式でファイルに出力するために、ExDoc を拡張している途中です。ExDoc の主旨として「ユーザーインターフェースを優先する」という項目があるので(勝手に自分で付けたw)、ユーザーから使いやすいコーディングの仕方に合わせて拡張していきます。ユーザーってのは、「コーディングをするプログラマ」ってことですね、新しい UIDD(User Interface Developement Driven)の一環です(というのも、勝手に自分で付けたw)

と前置きはそれくらいにして、コードを晒しておきます。
TwiCatchStar の内部データを直接 xml に書き出します。

■XmlDocument を使う場合

通常の XmlDocument を使う場合です。まあ、旧来の DOM インターフェースを知っていれば作れるので、java などの他言語から入った人にはいいのでしょうが、結構手間です。

// XmlDocument を使う場合
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("TwiCatchStar");
root.SetAttribute("version", APPVERSION);
root.SetAttribute("created_at", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
doc.AppendChild(root);
XmlElement user = doc.CreateElement("user");
root.AppendChild(user);
user.AppendChild(doc.CreateElement("screen_name")).InnerText= username;
user.AppendChild(doc.CreateElement("profile_image_url")).InnerText= profile_image_url;
XmlElement statuses = doc.CreateElement("statuses");
statuses.SetAttribute("type", "array");
root.AppendChild(statuses);
foreach (Tweet twi in items)
{
	XmlElement status = doc.CreateElement("status");
	statuses.AppendChild(status);
	status.AppendChild(doc.CreateElement("id")).InnerText= twi.ID;
	status.AppendChild(doc.CreateElement("text")).InnerText= twi.text;
	status.AppendChild(doc.CreateElement("created_at")).InnerText= twi.CreatedAt.ToString("yyyy/MM/dd HH:mm:ss");
}

■LINQ to XML を使う場合

今後、.NET 言語でデータストレージ絡み(XML形式も含む)のは、一括して LINQ が推奨、ってことになるんでしょうが、LINQ to XML っていまいち使いづらいんですよね。それでも、XmlDocument よりは直感的かも。

// LINQ to XML を使う場合
XDocument doc = new XDocument();
XElement root = new XElement("TwiCatchStar");
doc.Add(root);
root.SetAttributeValue("version", APPVERSION);
root.SetAttributeValue("created_at", DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"));
XElement user = new XElement("user");
root.Add(user);
user.Add(new XElement("screen_name", username));
user.Add(new XElement("profile_image_url", profile_image_url));
XElement statuses = new XElement("statuses");
statuses.SetAttributeValue("type", "array");
foreach (Tweet twi in items)
{
	XElement status = new XElement("status");
	statuses.Add(status);
	status.Add(new XElement("id", twi.ID));
	status.Add(new XElement("text", twi.text));
	status.Add(new XElement("created_at", twi.CreatedAt.ToString("yyyy/MM/dd HH:mm:ss")));
}

■ExDoc を使う場合

ExDoc は「もう LINQ to XML はいらない」を主旨にして作っているので、+= 演算子や []演算子を適当にオーバーライドして作成できるようにします。
本来ならば、CreateElement とか AppendElement という「名前」を使わずにやりたいのですが、ちょっと模索中。

EXDocument doc = new EXDocument("TwiCatchStar");
doc.Root["version"] = APPVERSION;
doc.Root["created_at"] = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
EXElement user = doc.Root.AppendElement("user");
user += doc.CreateElement("screen_name", username);
user += doc.CreateElement("profile_image_url", profile_image_url);
EXElement statuses = doc.Root.AppendElement("statuses");
statuses["type"] = "array";
foreach (Tweet twi in items)
{
	EXElement status = statuses.AppendElement("status");
	status += doc.CreateElement("id", twi.ID);
	status += doc.CreateElement("text", twi.text);
	status += doc.CreateElement("created_at", twi.CreatedAt.ToString("yyyy/MM/dd HH:mm:ss"));
}

LINQ to XML では、Add メソッド内で要素を作成していますが、実は適当な拡張メソッドを作れば AppendElement のような形でアクセスが可能なので、ExDoc の優位性というのはこの場合はあまりありません。

■VB で作る場合

実は、VB で作るのが一番直感的なんですよね。XML 用の拡張文法が VB に備わっているので、これを使うと…

'''
''' コレクション
'''
'''
Public _tweets As List(Of Tweet)
'''
''' エンティティクラス
'''
'''
Public Class Tweet
	Public Property ID As String
	Public Property Text As String
	Public Property Create_at As Date
End Class

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
	Dim APPVERSION = &quot;0.3&quot;
	Dim username = &quot;moonmile&quot;
	Dim profile_image_url = &quot;&quot;

	Dim root As XElement =
	 <TwiCatchStar version=<%= APPVERSION %> created_at=<%= Date.Now.ToString(&quot;yyyy/MM/dd HH:mm:ss&quot;) %>>
	 </TwiCatchStar>

	Dim user As XElement =
	 <user>
		 <screen_name><%= username %></screen_name>
		 <profile_image_url><%= profile_image_url %></profile_image_url>
	 </user>

	Dim statuses =
	 <statues>
		 <%= From t In _tweets Select
			 <status>
				 <id><%= t.ID %></id>
				 <text><%= t.Text %></text>
				 <create_at><%= t.Create_at.ToString(&quot;yyyy/MM/dd HH:mm:ss&quot;) %></create_at>
			 </status> %>
	 </statues>

	root.Add(user)
	root.Add(statuses)

	Me.TextBox1.Text = root.ToString()

End Sub

のように、なんて直感的に書けるんでしょうッ!!! まるで、ASP.NET の埋め込みか、PHP のように記述ができます。これには、ExDoc も脱帽 orz
一見、VB のほうが行数が長いので非効率に見えるのですが、保守性は抜群ですよね。一瞥しただけで変更が可能です。このために VB を使うのもいいかも(違

2012/07/08 追記

Egtra さんより教えて貰った方法で、LINQ to XML を書き直すとこんな感じ。
この記事を書いたときに、XElement に子のコレクションをどう入れれば分からなかったのですが、items.Select な感じでコレクションを渡すと、自動的に子に配列として付け加わるのですね。なるほど。

XDocument doc = new XDocument(
	new XElement(&quot;TwiCatchStar&quot;,
		new XAttribute(&quot;version&quot;, APPVERSION),
		new XAttribute(&quot;created_at&quot;, DateTime.Now.ToString(&quot;yyyy/MM/dd HH:mm:ss&quot;)),
		new XElement(&quot;user&quot;,
			new XElement(&quot;screen_name&quot;, username),
			new XElement(&quot;profile_image_url&quot;, profile_image_url)),
		new XElement(&quot;statuses&quot;,
			new XAttribute(&quot;type&quot;, &quot;array&quot;),
			items.Select(twi =>
				new XElement(&quot;status&quot;,
					new XElement(&quot;id&quot;, twi.ID),
					new XElement(&quot;text&quot;, twi.Text),
					new XElement(&quot;created_at&quot;, twi.CreatedAt.ToString(&quot;yyyy/MM/dd HH:mm:ss&quot;)))))));

実は以前、XElement を扱った時「これってDOMに準拠していない」(DocumentからNodeを作成しない)という点でちょっと嫌っていたのですが、こういう書き方ができると、VB のように XML の構造通りに書けるからいいですよね。
ExDoc も doc.CreateElement のようにせずに、やっぱり doc += new EXElement(…) とか、doc.Append( new EXElement(…), new EXElemnet(…)) のように羅列できるように改造しようかな。

カテゴリー: UIDD, C#, VB | 2件のコメント

XmlWriter で StringWriter を使うと Encoding が「UTF-16」になってしまうの対処方法

ExDoc 絡みで、今更ながら XmlWriter クラスを使って xml 形式のデータを出力しています。
そこで、XmlWriter クラスのエンコードなのですが、デフォルトでは「UTF-8」なんだけど、何故か StringWriter を使って文字列に吐き出させると「<?xml version=”1.0″ encoding=”utf-16″?>
」として吐き出されてしまう、問題があります。

ファイル自身は「utf-8」なのに、xml ヘッダが「utf-16」では、困るわけですね。

ややこしいのでコードの抜粋を示すと、

/// <summary>
/// ドキュメントから文字列に変換
/// </summary>
/// <returns></returns>
public string SaveXML()
{
	StringWriter sw = new StringWriter();
	XmlWriterSettings setting = new XmlWriterSettings();
	setting.Indent = true;
	XmlWriter writer = XmlWriter.Create(sw, setting);

	writer.WriteStartDocument();
	SaveXML(writer, this.DocumentElement);
	writer.WriteEndDocument();
	writer.Close();
	string xml = sw.ToString();
	sw.Close();
	return xml;
}

こんな風に、XmlWriter を使って出力する先を、StringWriter にしています。MSDN のドキュメントを見ると、

XmlWriterSettings.Encoding プロパティ (System.Xml)
http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=JA-JP&k=k(SYSTEM.XML.XMLWRITERSETTINGS.ENCODING);k(SOLUTIONITEMSPROJECT);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true

なところで、XmlWriter は渡されたクラスのエンコードを使うので、XmlWriter 自身のエンコードは無視される、という書き方がされています。実際、StringWriter は内部コードなので、Unicode を使っているので「UTF-16」となるのは動きとしては正しいのですが、この StringWriter オブジェクトを、ファイルに書き込もうとするとちょっと困ったことになるのです。

/// <summary>
/// ドキュメントからファイルを作成する
/// </summary>
/// <param name=&quot;path&quot;></param>
public void Save(string path)
{
	StreamWriter sr = new StreamWriter(new FileStream(path, FileMode.Create));
	string xml = SaveXML();
	sr.Write(xml);
	sr.Close();
}

こんな風にエンコードを指定しないと、ファイルは「UTF-8」で書かれてしまうのです。なので、

  • ファイルのコードは「UTF-8」なのだが、
  • XML のヘッダには「UTF-16」と書いてある。

という不整合のファイルができてしまいます。仕方がないので、どちらかのエンコードを替えます。ファイルのエンコードを「UTF-16」に揃えてもよいのですが、どちらかというと XML ファイル自体を「UTF-8」に揃えておきたい訳です。
そうなると、先の StringWriter の Encoding プロパティの値が邪魔で、なんともできないなぁ、と思っていたのですが。

下記のように、StringWriter クラスを継承して、Encoding プロパティでは、常に「UTF-8」を返すようにすれば良いのでした。なるほど、確かにこれで XML のヘッダ部分が「UTF-8」になります。

private class StringWriterUTF8 : StringWriter
{
	public override System.Text.Encoding Encoding
	{
		get { return System.Text.Encoding.UTF8; }
	}
}

/// <summary>
/// ドキュメントから文字列に変換
/// </summary>
/// <returns></returns>
public string SaveXML()
{
	StringWriter sw = new StringWriterUTF8();
	XmlWriterSettings setting = new XmlWriterSettings();
	setting.Indent = true;
	XmlWriter writer = XmlWriter.Create(sw, setting);

	writer.WriteStartDocument();
	SaveXML(writer, this.DocumentElement);
	writer.WriteEndDocument();
	writer.Close();
	string xml = sw.ToString();
	sw.Close();
	return xml;
}

こんな風に、内部クラスとして StringWriter を継承したクラスを作ると、変更が局所化されて便利です。

カテゴリー: C#, EXDoc | 1件のコメント

クラウドの課金は高いのか?

結論から言うと「無償で提供するには、限りなく高いッ!!!」です。まぁ、大人の道楽として月の呑み代を2,3回分突っ込む気持ちでいればいいんでしょうけど。単純にショバ代を払っているだけだと、アレかなぁと。

敢えて「某ひと目 Azure」(伏字になってないw)では課金の話はハズしてあります。将来的にどうなるか分からないし、開発者としては課金よりも「どう使うのか」、「どこから手をつけたらいいのか」のところから入るほうがいいでしょうから、お金の話はオミットしたのですね。

で、原稿の執筆のために「MSDN サブスクリプション」で windows azure を利用していたのですが、いやぁ、これが結構高くつきます。

執筆の開始は、実は去年の4月頃なので「クラウドアプリケーションって cpu 時間による課金だから、あまり使われないサービスであれば、セッション料金などを含めても、ほぼ無料で使えるよね」と軽く思っていた次第です。それがですね、去年の9月の google app engine の料金改定、windows azure の課金開始にあたって、実際に請求がきてみると、cpu 時間ではなくて「コンピューティング時間」というものに変わっていました。
この「コンピューティング時間」というのは、何者かというと、いわゆる「アプリがデプロイ(配置)されている時間」を示します。前後、デプロイしている時間も含まれるのですが、細かい話は別として、「アプリケーションが置いてある時間」なのです。ということは、アプリをアップロードして、1ヶ月ほど放置すると、「1ヶ月」まるごとの課金が掛かってしまう訳ですね。時間単位だと、24時間x30日=680時間ほどかかります。なので、普通のレンタルホスティングサーバー(月額1,000円やら500円やらの格安サーバー)感覚で使うと、ひどく痛い目に遭います。

azure の場合、MSDN サブスクリプションを使うと「S プラン」というものが適用されるので、単位時間あたり約10円かかります。

デプロイ1つに対して x 24時間 x 30日 x 約10円 = 7,200円/月

程度かかるわけです(この他に転送などが多ければ、それも加算される)。

# ちょっと、補記 2012/01/30
# 実は、サブスクリプション版は、1500時間/月の無料分が付いている(月でリセットされる)ので
# 総計が、2プロセス x 24時間 x 30 日 = 1,440時間 の範囲であれば、無料になります。
# この 1500 時間を超えた分に 10円/時間 単位で課金されます。
運用時には XS プランという最低限のプランがあるのですが、これが単位時間あたり 3.5円です。

デプロイ1つに対して x 24時間 x 30日 x 約10円 = 2,520円/月

まぁ、払えない金額ではないのですが「デプロイ1つにつき」というのが曲者で、azure の場合、ステージング環境という試験環境と、運用環境の2つを使うことが通例ですから、開発時にはこの倍ば掛かるんですね。ちょっと、個人では出しにくい金額です。

デプロイしている時間を減らそうと思って、追加削除を繰り返せばよいのかというとそうでもなくて、azure の場合、1時間単位等で課金がされるので、ちょっとテストのつもりで5分間デプロイしただけでも、あっという間に課金されてしまいます…といいますか、開発中にいちいちデプロイを削除するのは面倒なので、1か月間放置ということが多いですよね。そうなると、まるごと1か月ほど課金されてしまうわけです。

windows azure が「意外と高い」ことが分かりましたが、じゃあ、google app engine が安いのかというとそうではなくて、google の場合は、0.08$/h という課金がかかります。これが1分単位で計算されるわけですが、上記の通り開発時にはデプロイしたままが普通なので、同じように1ヶ月まるごと課金がかかるわけです。(ただし、放置していてほとんどアクセスがない場合は、課金はされない模様なんだけど、その差がよくわからず)

デプロイ1つに対して x 24時間 x 30日 x 0.08ドル = 4,600円/月 (1$ = 80円換算)

これにアプリ料金(だっけ)が900円ほどかかるので、azure と比べても決して安いわけではありません。

▼参照先

6 か月プラン (Windows Azure) – Windows Azure
https://www.windowsazure.com/ja-jp/offers/ms-azr-0019p

App Engine の料金体系変更に関する FAQ – Google Japan Developer Relations Blog
http://googledevjp.blogspot.com/2011/07/app-engine-faq.html

■じゃあ、何に使えばよいのか?

なので個人で web サービスを開始するのであれば、レンタルサーバーで十分です。レンタルサーバーの場合、言語が限られている(php, python, ruby)のですが、mysql がそのまま使えたりします。
ただし、ある程度スケールアップをしたい場合には、クラウド環境に移行したいですよね。自作サーバーを家で運用するのもいいのでしょうが、終日動いているのは電気代もかかるし、家族持ちには辛いものです。独身だと、まぁ、暖房替わりになるけど。

あと、月額4,000円ぐらい出せば、仮想専用サーバーが借りられので、クラウドのセッション数の課金などを気にせずに使えます。まぁ、環境が linux が多いとは思いますが、確か windows server もあったはずです。

なので、最低のランニングコストが、1万円/月を超えるような場合は、クラウド環境を利用したほうがお得という感じですかね。実は、このランニングコストには、人件費である SE 費用も入るんですよね。「某ひと目」に書きましたが、クラウドを使う利点として、

  • サーバー機の故障などのメンテナンスがフリーである。
  • サーバー機の電気代が料金に含まれている。

ということになります。レンタルサーバーの場合にも電気代、メンテナンス代が入っているので、小さい場合にはいいのですが、社内サーバーと比較すると月額1万円というの人件費からすれば結構格安でしょう。社内サーバーのメンテをしていて、保守料金数万円を支払っているならば、クラウドに移行するのもアリだと思います。

ただし、安く上がるための条件がいくつかあって、

  • デプロイするアプリケーション数が、開発時に減らせること。
  • アプリケーションのセッション数、転送量が減らせること。
  • 大きすぎる静的なストレージを持たないこと。

などがあります。課金をまじめに考えて(請求書を見て、えッ???と思ったので)みると、結構クラウド開発をするときには、設計時のノウハウが必要な気がします。漠然と、インスタンスを沢山作ってしまうと、cpu 課金ではないので、ランニングコストが莫大になってしまうので、注意しないといけません。

ええ、クラウドアプリを提供する側としては、そういう姿勢で良いかと。下手な設計をすると、課金が莫大になるという点で、ちょっと経済性に踏み込む必要があります。

カテゴリー: Azure | 1件のコメント

素早く顔を入れ替えるとモンスターに見える?

元ネタ

意外と作るのが大変でした…orz ソースは下記で。

private void button1_Click(object sender, EventArgs e)
{
	List lst = new List();
	lst.Add(&quot;野田佳彦&quot;);
	lst.Add(&quot;平野博文&quot;);
	lst.Add(&quot;平野達男&quot;);
	lst.Add(&quot;藤村修&quot;);
	lst.Add(&quot;田中直紀&quot;);
	lst.Add(&quot;前田武志&quot;);
	lst.Add(&quot;川端達夫&quot;);
	lst.Add(&quot;松原仁&quot;);
	lst.Add(&quot;小川敏夫&quot;);
	lst.Add(&quot;小宮山洋子&quot;);
	lst.Add(&quot;鹿野道彦&quot;);
	lst.Add(&quot;自見庄三郎&quot;);
	lst.Add(&quot;枝野幸男&quot;);
	lst.Add(&quot;細野豪志&quot;);
	lst.Add(&quot;古川元久&quot;);
	lst.Add(&quot;玄葉光一郎&quot;);
	lst.Add(&quot;岡田克也&quot;);
	lst.Add(&quot;安住淳&quot;);

	Random rnd = new Random(DateTime.Now.Second);
	int MAX = 100;
	for (int i = 0; i < MAX; i++)
	{
		string fname1 = lst[rnd.Next(lst.Count)] + &quot;.png&quot;;
		string fname2 = lst[rnd.Next(lst.Count)] + &quot;.png&quot;;
		fname1 = @&quot;D:\temp\野田改造内閣\out\&quot; + fname1;
		fname2 = @&quot;D:\temp\野田改造内閣\out\&quot; + fname2;

		Bitmap bmp1 = new Bitmap(fname1);
		Bitmap bmp2 = new Bitmap(fname2);
		Bitmap bmp = new Bitmap(bmp1.Width * 2, bmp1.Height);

		Graphics g = Graphics.FromImage(bmp);
		g.DrawImage(bmp1, 0, 0);
		g.DrawImage(bmp2, bmp1.Width, 0);

		string fname = string.Format(@&quot;D:\temp\野田改造内閣\out2\{0:000}.png&quot;, i);
		bmp.Save(fname);
	}
}
  1. 「野田改造内閣」の面子を google る
  2. wikipedia にあるパブリック…だと足りないので、適当に拾ってくる。
  3. 画像のサイズをツールを使って揃える。
  4. 画像のサイズをツールを使って切り取る。
  5. ランダム配置するツールをこれ専用に作成。
  6. windows live ムービーメーカーで 0.20 秒間隔で表示させる。
  7. youtube にアップ…って、ムービーメーカーからアップできる。

な感じ。

カテゴリー: 雑談, C# | 2件のコメント

ツイートキャッチ★★★ ver.0.2 を公開

先日、以下の記事で過去ツイートをクロールするツールを作ったものの…

指定したTwitterアカウントの全ツイートを取得(暫定.NET版) | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/2851

あまりに遅いので、やっぱり twitter api を使うように書き直しました。oauth 認証を使わない場合は、150/h の制限が掛かるのですが、oauth 認証をした後だと 500/h 位?は呼び出しが可能なので、大抵の場合は大丈夫かなと。

200 件ずつ api で拾ってきています。@moonmile の約3000件が、1分ちょっとぐらいで取得可能です。過去3200件までなので、それ以前の場合は、別途作らないと駄目かなと。

■ダウンロード

TwiCatchStar.0.2.zip をダウンロードして解凍してください。

EXDoc.dll
TwiLib.dll
TwiCatchStar.exe
読んでね.txt

の4つのファイルがあるので、適当なフォルダにコピーしてください。
TwiCatchStar.exe が本体です。

■初期設定

初回だけ、oauth 認証の設定をします。

1.「初期化」ボタンを押して、oauth 認証をします。

2.内容を確認して「連携アプリを認証」ボタンをクリックします。

3.PIN 番号をコピーします(番号は、その時によって違います)

4.左側にあるテキストボックスに番号をコピーして、設定ボタンをクリック。

5.認証が成功すると、「取得」ボタンに変わります。

■取得の仕方

左側にあるテキストボックスに「moonmile」のように twitter で使われている名前(screen name)を入れて、「取得」ボタンをクリックしてください。

だいたい1分ぐらい経つと取得が終了します。最新のものから取得するので、途中で辞めたい場合は「中断」ボタンをクリックしてください。

「コピー」ボタンをクリックすると、クリップボードにコピーするのでメモ帳かExcelにペーストして使って下さい。

■今後の予定

保存に関しては、

  • 適当なファイルに保存する。
  • 適当なデータベースに保存する。

予定です。

あとは、外部からの呼び出しが可能にするとか。

カテゴリー: 開発, ツール | 2件のコメント

指定したTwitterアカウントの全ツイートを取得(暫定.NET版)

以前、ツイートのクローラーを perl で作ってみたのですが、

指定したTwitterアカウントの全ツイートを取得(perl版) | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/860

この perl スクリプトは古い公式クライアントにしか対応していないので、現在のバージョンではクロールできません…ってな訳で、C# で作り直してみました。

通称「ツイートキャッチ ★★キュア」…★は各自考えるように、とか。

実行ファイルは、CrawlTwitter.0.1.zip をダウンロードしてください。ドキュメントとか一切ないけど、まぁ、暫定版ということで。
ソースコードのほうは、CrawlTwitter at master from moonmile/etc – GitHub にあります。

実行すると結構かかります。3000 ツイートで 15 分ぐらいなので、掛かり過ぎ。これは高速化する予定です。
「コピー」ボタンをクリックすると、グリッドの情報をクリップボードにコピーします。Excel などに貼りつけて使って下さい。

下にあるテキストボックスは、取得したドキュメントのソースですね。デバッグ用に表示しているので、コピーして使ってみてください。中身がわかります。

仕掛けとしては、「もっと見る」のボタン(アンカー)を javascript でクリックしています。C# から WebBrowser オブジェクト経由でクリックする場合は、下記のように

橋本商会 ≫ C#のWebBrowserコンポーネントからJavaScriptを実行
http://shokai.org/blog/archives/1234

ブックマーレットにするといいみたいです。詳しくは git のソースコードを見てください。


ちなみに、リンク先の質問に「逆にWebBrowserから情報を得られるのか?」という質問がありますが、ソースコードを見るとわかりますが、

HtmlDocument doc = webBrowser1.Document;

な形で、ブラウザの DOM が取得できます。これを使うと javascript から dom を使うのと同じように扱えます。なので、javascript 側から値を返す場合は、適当なタグを作っておいて、取り出した HtmlDocument オブジェクトから直接取り出せばいい(getelementbyidとか)のです。

カテゴリー: ツール, C# | 4件のコメント

Microsoft MVP 受賞しました(ASP.NET/IIS)

そんな訳で(どんな訳で)、MVP を受賞しました。
去年、つーか一昨年は「Visual C++」だったのですが、今回は「ASP.NET/IIS」です。連載! コードで学ぶ ASP.NET MVC アプリケーション開発入門 | Code Recipe | MSDN あたりの記事と、その元ネタの「ひと目でわかる ASP.NET MVC アプリケーション入門」ですね。おそらく。

手元のブログのほうは、諸々(C/C#/C++/VB)と書き綴っているわけで、最近は objective-c とか。あまり言語にとらわれず、工学系の強みを出してというところです。理論的なところはさておき「どうやって使っていくか」「どう使いこなしていくのか?」に焦点を当てる感じ。

そう云えば「コードで学ぶ ASP.NET MVC」って、もともと12回の予定で、例の地震の関係でラストの2回は尻切れトンボになってしまったのですよね。当初の企画としては、

11. セッション管理
12. Oracle や MySQL を利用するには

を追加する予定だったので、このあたりも時間があれば手元のブログで晒しておきましょうか。

セッション管理については、InProc のセッション管理から、セッションサーバーの設定、SQL Server の設定に切り替えていくパターンを。
MySQL を利用する場合は、例の connect/net を使って、asp.net mvc を動かそうという訳です。先日 Entity Model を使うとそのまま linq が使えることが分かったので、これは「コードで学ぶ~」のほう(ASP.NET MVC アプリケーション開発入門: 第 4 回 Entitiy Frameworkを利用する – MSDN サンプル ギャラリー)で使っているコードをそのまま流用できそうです。「ひと目でわかる~」のほうは、LINQ to SQL を使っているので、両方ともに参考になると思います。

という訳で、今後とも宜しゅう。

カテゴリー: 雑談 | 2件のコメント

ローカルデータベースである SQL Server Compact Edition を使う

SQL Server や MySQL は、ローカルコンピュータにデータベースをインストールしないといけないので、業務先のコンピュータにインストールするにはちょっと、という感じがします(まぁ、そういう場合は別途サーバー機を作るわけですが)。
逆に、データベース専用にサーバーを作るほどでもない、あるいは、個々のアプリケーションのデータを database として保存しておきたい場合は、「ファイルベース」のデータベースを使うと良いです。
筆頭に上がるのが、SQLite で、データベースのファイルをコピーするだけで使えます。この他にも、

  • xml 形式のファイルをデータベースとして扱う。
  • access 形式ファイルを扱う。
  • Berkeley DB を使う。

という方法もあります。

で、実は余り知られていない(と思う)のですが、SQL Server 互換のファイルベースのデータベースがあります。

ダウンロード詳細 Windows デスクトップ向け Microsoft SQL Server Compact 3.5 および Microsoft Synchronization Services for ADO.Net v1.0
http://www.microsoft.com/downloads/ja-jp/details.aspx?FamilyID=7849b34f-67ab-481f-a5a5-4990597b0297
ダウンロード詳細 Windows デスクトップ用 Microsoft SQL Server Compact 3.5 Service Pack 2
http://www.microsoft.com/downloads/ja-jp/details.aspx?FamilyID=e497988a-c93a-404c-b161-3a0b323dce24
SQL Server Compact 3.5 オンライン ブック
http://msdn.microsoft.com/ja-jp/library/bb734673(v=sql.100).aspx

と前置きはこれくらいにして、SQLite を使うのもいいけど、compact edition もね、という感じで。compact edition に関しては、windows ce の頃に調べていたのですが、windows phone 7 の場合はどうなんでしょうねえ。次期モバイルには入るらしいのですが。

■ローカルデータベースを追加

visual studio にローカルデータベース(compact edition)を追加します。拡張子は「sdf」ですね。ちなみに、「サービスベースのデータベース」というのは、本家の sql server が使うデータベースファイルです。こっちの拡張子は「mdf」です。

Visual Studio 2010 で作成されるローカルデータベースは、v3.5 のプロバイダでアクセスしています。
「System.Data.SqlServerCe.3.5」のところ。

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<configuration>
 <connectionStrings>
 <add name=&quot;Model1Container&quot; connectionString=&quot;metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlServerCe.3.5;provider connection string=&quot;Data Source=|DataDirectory|\Database1.sdf&quot;&quot; providerName=&quot;System.Data.EntityClient&quot; />
 </connectionStrings>
</configuration>

■Entity Model を作成

ちょっと工夫が要りますが、Enity Model を作成します。初期値は「Model1Container」になってます。

[img 20120110_05.jpg]

作成されたスクリプトはこんな感じ

-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------

-- Creating table 'Company'
CREATE TABLE [Company] (
    [ID] int IDENTITY(1,1) NOT NULL,
    [Name] nvarchar(100)  NOT NULL
);
GO

-- Creating table 'Person'
CREATE TABLE [Person] (
    [ID] int IDENTITY(1,1) NOT NULL,
    [Name] nvarchar(100)  NOT NULL,
    [Age] int  NULL,
    [UpdateDate] datetime  NOT NULL,
    [Company_ID] int  NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [ID] in table 'Company'
ALTER TABLE [Company]
ADD CONSTRAINT [PK_Company]
    PRIMARY KEY ([ID] );
GO

-- Creating primary key on [ID] in table 'Person'
ALTER TABLE [Person]
ADD CONSTRAINT [PK_Person]
    PRIMARY KEY ([ID] );
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- Creating foreign key on [Company_ID] in table 'Person'
ALTER TABLE [Person]
ADD CONSTRAINT [FK_CompanyPerson]
    FOREIGN KEY ([Company_ID])
    REFERENCES [Company]
        ([ID])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_CompanyPerson'
CREATE INDEX [IX_FK_CompanyPerson]
ON [Person]
    ([Company_ID]);
GO

compact edtion の場合は、文字列は nvarchar に統一されています。なので、sql server からスクリプトを流用するときは、ちょっと変換が必要ですね。

■接続テスト

簡単な接続テスト

///
/// 接続テスト
///
/// <param name=&quot;sender&quot; />
/// <param name=&quot;e&quot; />
private void button1_Click(object sender, EventArgs e)
{
	Model1Container ent = new Model1Container();
	var persons = from t in ent.Person select t;
	dataGridView1.DataSource = persons;
}

ナビゲーションプロパティを使って person と company を結合。

///
/// リンク付きで検索
///
/// <param name=&quot;sender&quot; />
/// <param name=&quot;e&quot; />
private void button2_Click(object sender, EventArgs e)
{
	Model1Container ent = new Model1Container();
	var items = from t in ent.Person
				orderby t.Age
				select new {
					t.Name,
					t.Age,
					CompanyName = t.Company.Name };
	dataGridView1.DataSource = items;
}

データベースファイル自体は、「Database1.sdf」というひとつのファイルになるので、これをコピーすればどこでも使えます。ああ、あと .net framework 4.0 も必要ですが。

.NET Framework 4 ダウンロード: SDK | MSDN
http://msdn.microsoft.com/ja-jp/netframework/ff687189

ダウンロード詳細 Windows デスクトップ用 Microsoft SQL Server Compact 3.5 Service Pack 2
http://www.microsoft.com/downloads/ja-jp/details.aspx?FamilyID=e497988a-c93a-404c-b161-3a0b323dce24


追記
SQL Server Compact の場合は、実行ファイルとデータベースファイル(*.sdf)をコピーすれば動くのかと思ったら、別途 SQL Server Compact 3.5 等のインストールが必要になる模様。動かしたときに、プロバイダーが作成できない、という例外が発生する。なので、クリーンなクライアントマシンで単純コピーでは動かないから、数百台のインストールのようなものが発生する場合は、SQLite のほうがいいのかなぁ。できれば、SQL Server Compact のインストールはしたくないので(.NET Framework 4.0 は仕方がないにしても)、適当なアセンブリ(*.dll)をコピーすれば、クリーンな windows 7 マシンでも動作する、っていうのがいいなぁ。

 

カテゴリー: 開発, C# | 1件のコメント

ADO.NET Entity Data Modelの接続先を動的に切り替える

LINQを使う時に、ADO.NET Entity Data Modelを作成する、ってのが今後の主流な訳ですが、Data Model を作るときの接続先をアプリケーションを実行するときに、どうやって切り替えられるのか?という問題があって…いや、知らなかっただけなんですけどね。良く見たら MSDN に書いてあったので。

ConnectionString プロパティ
http://msdn.microsoft.com/ja-jp/library/system.data.entityclient.entityconnection.connectionstring.aspx

普通に作成すると、web.config/app.config に書かれるので、さてこれをどうやって実行時に変えたらいいものか?と悩むわけです。某ひと目 Azure でもかなり悩んだ。

ソースコードは MySQL 接続になっていますが、基本的なところは SQL Server でも同じです。

■web.config/app.confg の connectionStrings で切り替える

Data Entity を作ると、config に connectionStrings/add が作成されます。

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<configuration>
  <connectionStrings>
    <add name=&quot;wordpressEntities&quot; connectionString=&quot;metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=localhost;User Id=wordpress;password=wordpress;Persist Security Info=True;database=wordpress;Allow Zero Datetime=True;Convert Zero Datetime=True;&quot;&quot; providerName=&quot;System.Data.EntityClient&quot; />
  </connectionStrings>
</configuration>

こんな風に、作成時の接続文字列が作られるので、同じように別の接続文字列も作ってみます。

<?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?>
<configuration>
  <connectionStrings>
    <add name=&quot;wordpressEntities&quot; connectionString=&quot;metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=localhost;User Id=wordpress;password=wordpress;Persist Security Info=True;database=wordpress;Allow Zero Datetime=True;Convert Zero Datetime=True;&quot;&quot; providerName=&quot;System.Data.EntityClient&quot; />
    <add name=&quot;wp33jEntities&quot; connectionString=&quot;metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;server=localhost;User Id=wpuser;password=wppass;Persist Security Info=True;database=wp33jp;Allow Zero Datetime=True;Convert Zero Datetime=True;&quot;&quot; providerName=&quot;System.Data.EntityClient&quot; />
  </connectionStrings>
</configuration>

これを、

// 公開している記事一覧を表示
wordpressEntities ent = new wordpressEntities();

のように接続すると、デフォルトで「wordpressEntities」に接続されるようになっています。ここのコードは、model のファイルを開いて「Model1.Designer.cs」を見ると、次のように name が指定されています。

/// <summary>
/// アプリケーション構成ファイルの 'wordpressEntities' セクションにある接続文字列を使用して新しい wordpressEntities オブジェクトを初期化します。
/// </summary>
public wordpressEntities() : base(&quot;name=wordpressEntities&quot;, &quot;wordpressEntities&quot;)
{
    this.ContextOptions.LazyLoadingEnabled = true;
    OnContextCreated();
}

なので、config ファイルに書いていある別の接続文字列を持ってきたい場合は、次のようにコンストラクタで「name=接続名」を指定します。ここでは、config にあらかじめ設定した「wp33jEntities」を取得して表示します。

private void button3_Click(object sender, EventArgs e)
{
	// web.config から設定値を取得
	wordpressEntities ent = new wordpressEntities("name=wp33jEntities");
	var posts = from t in ent.wp_posts
				where t.post_status == "publish"
				&& t.post_type == "post"
				orderby t.post_date descending
				select new { t.ID, t.post_title, t.post_date };
	// バインド
	dataGridView1.DataSource = posts;
}

■接続文字列を動的に設定する

上記の方法だと、あらかじめ web.config/app.config に接続文字列を書いておかないとだめなので、何らかの独自の設定ファイルからの読み出した情報からはコネクションを構築できませんよね。ユーザー名やらパスワードや、サーバー名などを動的に切り替えたい場合があります。
そんな場合は、接続文字列を独自に作成して渡します。先の「wordpressEntities」クラスは、ObjectContext クラスを継承しているので、直接接続文字列を渡せそうなのですが、普通にデータベースに接続する場合とはちょっと違うので、ConnectionString プロパティ を参考にして、EntityConnection オブジェクトを渡すようにします。

private void button4_Click(object sender, EventArgs e)
{
	// 接続文字列を直接指定
	MySqlConnectionStringBuilder sb = new MySqlConnectionStringBuilder();
	sb.Server = "localhost";
	sb.Database = "wp33jp";
	sb.UserID = "wpuser";
	sb.Password = "wppass";
	sb.AllowZeroDateTime = true;
	sb.ConvertZeroDateTime = true;

	EntityConnectionStringBuilder esb = new EntityConnectionStringBuilder();
	esb.Provider = "MySql.Data.MySqlClient";
	esb.ProviderConnectionString = sb.ToString();
	esb.Metadata = "res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl";
	EntityConnection cn = new EntityConnection(esb.ToString());

	wordpressEntities ent = new wordpressEntities(cn);
	var posts = from t in ent.wp_posts
				where t.post_status == "publish"
				&& t.post_type == "post"
				orderby t.post_date descending
				select new { t.ID, t.post_title, t.post_date };
	// バインド
	dataGridView1.DataSource = posts;
}

なにやらややこしいですが、MySqlConnectionStringBuilder クラスで「接続文字列」を作成しておいて、EntityConnectionStringBuilder クラスでプロバイダ名やメタデータ(テーブル情報)を指定するという具合です。メタデータ自体は Entity Model クラスのファイル名が出てくるので、それぞれ合わせる必要があります。ファイル名が違っているとリソースから読み込めずにエラーになります。ちなみに、SQL Server に接続する場合は、「SqlConnectionStringBuilder」クラスです。
なお、MySqlConnectionStringBuilder クラスを使うには、「using MySql.Data.MySqlClient;」することになります。

このあたりの接続文字列は、Release時とDebug時に切り替えたり、SQL Azure接続とローカルコンピュータへの接続とかに使えますね。

カテゴリー: C#, MySQL | ADO.NET Entity Data Modelの接続先を動的に切り替える はコメントを受け付けていません