SQLの窓

2013年10月11日


VS2012(C#)ストア : ListView Twitter 検索テンプレート

OneDrive へ移動




インターネットから取得した JSON のデータをいかに ListView にバインドするかをまとめたテンプレートです。

Twitter_Search.cs

Twitter API の GET のテンプレートでもあります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Diagnostics;
using System.Net.Http;
using System.IO;
using System.Threading.Tasks;
using Windows.Security.Cryptography;
using Windows.Storage.Streams;
using Windows.Security.Cryptography.Core;

namespace VS2012_Twitter {
	class Twitter_Search {
		private string _consumer_key;
		private string _consumer_secret;
		private string _token;
		private string _secret;

		private string _tweet_api = "https://api.twitter.com/1.1/search/tweets.json";

		public Twitter_Search(
			string consumer_key,
			string consumer_secret,
			string token,
			string secret
			) {
			_consumer_key = consumer_key;
			_consumer_secret = consumer_secret;
			_token = token;
			_secret = secret;
		}

		public async Task<string> Tweet(string text, int count) {

			HttpClient hc = new HttpClient();

			// ソートされるリスト
			SortedDictionary<string, string> sl = new SortedDictionary<string, string>();
			sl.Add("count", count.ToString());
			sl.Add("oauth_consumer_key", _consumer_key);
			sl.Add("oauth_nonce", Nonce());
			sl.Add("oauth_signature_method", "HMAC-SHA1");
			sl.Add("oauth_timestamp", TimeStamp());
			sl.Add("oauth_token", _token);
			sl.Add("oauth_version", "1.0");
			sl.Add("q", Uri.EscapeDataString(text));

			// http ヘッダ用シグネチャ作成
			string work = "";
			foreach (KeyValuePair<string, string> kvp in sl) {
				if (work != "") {
					work += "&";
				}
				work += kvp.Key + "=" + kvp.Value;
			}

			string work2 = "";
			// メソッド
			work2 += "GET" + "&";
			// API URL
			work2 += Uri.EscapeDataString(_tweet_api) + "&";
			// Oauth + データ
			work2 += Uri.EscapeDataString(work);

			// OAuth tool チェック用
			Debug.WriteLine(work2);

			string oauth_signature = Signature(work2);

			// ヘッダ情報を作成
			work = "";
			foreach (KeyValuePair<string, string> kvp in sl) {
				// oauth_* のみを使用する
				if (work != "") {
					if ((kvp.Key + "      ").Substring(0, 6) == "oauth_") {
						work += ", ";
					}
				}
				if ((kvp.Key + "      ").Substring(0, 6) == "oauth_") {
					work += kvp.Key + "=" + Dd(kvp.Value);
				}
			}
			// シグネチャを追加( ヘッダーはソートの必要は無い )
			work += ", oauth_signature=" + Dd(Uri.EscapeDataString(oauth_signature));

			// OAuth tool チェック用
			Debug.WriteLine(work);

			string result = null;
			try {
				// フォーマットは、 OAuth tool で確認。
				hc.DefaultRequestHeaders.Add("Authorization", "OAuth " + work);

				// 投稿
				result = await hc.GetStringAsync(new Uri(
					_tweet_api +
					"?" +
					"q=" + sl["q"] +
					"&count=" + sl["count"]
				));
			}
			catch (Exception ex) {
				result = "{\"error\", \"" + ex.Message + "\" }";
			}

			return result;

		}

		// Framework 4.5 では必要無い
		private string rfc3986(string base_string) {
			string result = base_string.Replace("!", "%21");
			result = result.Replace("'", "%27");
			result = result.Replace("(", "%28");
			result = result.Replace(")", "%29");
			result = result.Replace("*", "%2A");
			return result;
		}

		// ダブルクォートで挟む
		private string Dd(string base_string) {
			return "\"" + base_string + "\"";
		}

		private string Nonce() {
			Random rand = new Random();
			int nonce = rand.Next(1000000000);
			return nonce.ToString();
		}

		// タイムスタンプ
		private string TimeStamp() {
			TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
			return Convert.ToInt64(ts.TotalSeconds).ToString();
		}

		// シグネチャ
		private string Signature(string target) {
			String signingKey = _consumer_secret + "&";
			signingKey += _secret;

			IBuffer keyMaterial = CryptographicBuffer.ConvertStringToBinary(signingKey, BinaryStringEncoding.Utf8);
			MacAlgorithmProvider hmacSha1Provider = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
			CryptographicKey macKey = hmacSha1Provider.CreateKey(keyMaterial);
			IBuffer dataToBeSigned = CryptographicBuffer.ConvertStringToBinary(target, BinaryStringEncoding.Utf8);
			IBuffer signatureBuffer = CryptographicEngine.Sign(macKey, dataToBeSigned);
			String signature = CryptographicBuffer.EncodeToBase64String(signatureBuffer);
			return signature;
		}
	}
}




posted by lightbox at 2013-10-11 11:34 | Win8 ストアアプリ | このブログの読者になる | 更新情報をチェックする

VS2012 ストア : 証明書ファイル名を変更した後の処理方法

ソリューションエクスプローラから .pfx の名前を変更した場合、Package.appxmanifest 内の証明書の参照をしなおす必要があるようです。( 警告が出ます )





この後、変更後のファイルを選択します


posted by lightbox at 2013-10-11 09:34 | VS(C#) | このブログの読者になる | 更新情報をチェックする

2013年10月10日


イラストを背景にして2ページの画面遷移を解りやすくした Windows Store テンプレート

OneDrive へ移動


MainPage

メイン画面の背景に大きなイラストを設定しました。ファイルは、『Assets フォルダ』に保存して参照しています



NextPage

次画面は、LinearGradientBrush でグラデーションにしました。



App.xaml.cs

ページの設定は、Microsoft のテンプレートを無視しました。本来の WPF と同じような形でフレーム内のコンテンツを複数ページで切り替える形にしています。
using System;
using System.Diagnostics;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Simple_Pages {

	// *************************************************
	// クラス
	// *************************************************
	sealed partial class App : Application {

		public static Frame rootFrame = null;
		public static MainPage mainPage;
		public static NextPage nextPage;

		// *************************************************
		// コンストラクタ
		// *************************************************
		public App() {
			this.InitializeComponent();
			this.Suspending += OnSuspending;
		}

		// *************************************************
		// アプリケーションがエンド ユーザーによって正常に起動された
		// *************************************************
		protected override void OnLaunched(LaunchActivatedEventArgs args) {

			// ***********************************************
			// Window => Current => Content
			// Content( Frame => Content(MainPage) )
			// ***********************************************
			// 初回は Windows 内に置く フレームを作成
			if (rootFrame == null) {
				rootFrame = new Frame();
				Window.Current.Content = rootFrame;
			}

			if (rootFrame.Content == null) {
				// メインページの初回ロード
				rootFrame.Content = new MainPage();
				// 次ページを最初に作成しておく
				nextPage = new NextPage();
			}

			// 現在のウィンドウをアクティブにします
			Window.Current.Activate();
		}

		// *************************************************
		// アプリケーションの実行が中断されたときに呼び出されます
		// *************************************************
		private void OnSuspending(object sender, SuspendingEventArgs e) {
			Debug.WriteLine("アプリケーションの実行が中断されました");

			var deferral = e.SuspendingOperation.GetDeferral();
			// アプリケーションの状態を保存してバックグラウンドの動作があれば停止します
			deferral.Complete();
		}
	}
}


MainPage.xaml

MainPage と NextPage を用意していますが、NextPage は、MainPage をコピーしてリネームしたものです。
<Page
	x:Class="Simple_Pages.MainPage"
	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	xmlns:local="using:Simple_Pages"
	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
	mc:Ignorable="d"
	Loaded="Page_Loaded">

	<!--画面定義-->
	<Grid>
		<Grid.Background>
			<ImageBrush
				ImageSource="Assets/1378650512243910.jpeg"
				Stretch="None" />
		</Grid.Background>
		<Button
			Content="次ページ"
			HorizontalAlignment="Left"
			Height="41"
			Margin="34,30,0,0"
			VerticalAlignment="Top"
			Width="136"
			Click="Button_Click_1" />
	</Grid>
	
</Page>


MainPage.xaml.cs

ページの切り替えは、Navigate メソッドを使わずに直接ページのインスタンスをセットしています。そうする為に、App クラスに参照用に static な変数を作成して、インスタンスを保存しています。
App.rootFrame.Content = App.nextPage;
※ よって、Page.OnNavigatedTo イベントは発生しません
using System;
using System.Diagnostics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace Simple_Pages {

	// *************************************************
	// クラス
	// *************************************************
	public sealed partial class MainPage : Page {

		// *************************************************
		// コンストラクタ
		// *************************************************
		public MainPage() {
			this.InitializeComponent();
			App.mainPage = this;
		}

		// *************************************************
		// ページが Frame にロードされた時に実行
		// ( アプリケーション中でページ遷移する毎 )
		// *************************************************
		private void Page_Loaded(object sender, RoutedEventArgs e) {
			Debug.WriteLine("Main Page_Loaded");
		}

		// *************************************************
		// フレームに NextPage をセット
		// *************************************************
		private void Button_Click_1(object sender, RoutedEventArgs e) {
			App.rootFrame.Content = App.nextPage;
		}


	}
}



posted by lightbox at 2013-10-10 21:05 | Win8 ストアアプリ | このブログの読者になる | 更新情報をチェックする

2013年10月08日


RFC 3986 に基づいた URL エンコード の簡単な理解

PHP のマニュアルの、rawurlencode の関数説明で簡潔明快に解説されています。
-_.~ を除くすべての非アルファベット文字をパーセント 記号 (%)に続いて 2 つの 16 進数がある表現形式に 置き換えた文字列を返します。これは、文字定数が特殊な URL デリミタと して解釈されたり、URL デリミタが(いくつかの電子メールシステムのような) 転送メディアにより文字変換されて失われてしまったりすることが ないように、RFC 3986 で定められたエンコーディング方法です。
要するに、-_.~ の4文字以外は全て%エンコーディングされるという事で、通常の URLENCODE でパーセントエンコードされない可能性のある 『+!'()*/』も%エンコーディングされます。ですから、他の言語の同様のメソッドや関数を RFC 3986 対応するには、『+!'()*/』をそれぞれ文字列変換しなおせば良いです。それと、 『~』が『%7E』になっている可能性があるので、元に戻す必要があります ▼ Java による例
String target = "文字列";
target = URLEncoder.encode(target, "UTF-8");
target = target.replace("+", "%20");
target = target.replace("*", "%2A");
target = target.replace("%7E","~");

関連する記事

いろいろな言語におけるバーセントエンコーディング





posted by lightbox at 2013-10-08 08:47 | プログラミング・仕様等 | このブログの読者になる | 更新情報をチェックする

2013年10月04日


Google Chrome の内臓 Flash でのみファイルがダウンロードできないというトラブルが発生してましたが、30.0.1599.66 m で修正されたようです

http://www.gekitetz.com/ は、一面 Flash の Font がダウンロードできるサイトなのですが、いつからかダウンロードできないでいました。

Google Chrome の内臓 Flash を無効にして、Adobe 配布の Flash にするとダウンロードできて、当然他のブラウザではダウンロードできました。

ところが、昨日突然ダウンロードが可能になっていて、Chrome のバージョンが 29 から 30 になっていたのではっきり違いが認識できたので、他の PC で 29 から 30 への差を動作確認しました。

厳密には、30.0.1599.66 m で正常に動作しました。

で、余談ですが今日またアップデートされて、30.0.1599.69 m になってました。( 何が起こってるんでしよう・・・ )


posted by lightbox at 2013-10-04 17:28 | Google | このブログの読者になる | 更新情報をチェックする

Firefox のみのレイアウトトラブル / float:left と line-height

この、『logical error』で起こってました。普段 Google Chrome を使用しているので、相当気が付くのが遅れました。全く logical では無いので恥ずかしい限りです。

Google Chrome と、IE10 では起こっていません。ですから、ブラウザのデフォルトの振る舞いの違いだと思われます。特に、line-height では解りやすいのですぐ正しく修正しましたが、レイアウトが下へ伸びるはずなのに、右へ回り込んでいるのは少し悩みました。

プログラマなんで、float:left やら float:right は苦手なんで、極力使わないようにしているのですが、ブログの初期テンプレートを引きずっていて存在そのものを忘れていました。

よって、clear:left を直前に <br style='clear:left;'> のように挿入しました。

ここで起こった事なので、直接変更せずにページのソースをダウンロードしてローカルのサーバーから見えるところに置いて、広告コードを外してリロードして再現する事を確認。

その後予想される問題を訂正して正しく表示された事を確認してから、Seesaa のデザインを変更して結果を確認。念のため、『設定』から『ブログ設定』で『最新の情報に更新』を実行です。



posted by lightbox at 2013-10-04 16:46 | WEBブラウザ | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり