主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

新しいブログをぼちぼちと

                
tags:
1606290009159.png

 .NET Coreの正式版がリリースされた。それにさきがけてブログを引っ越そうと、新しいブログをその.NET Coreベースで書いていた。モデルが揃ってきてぼちぼち形にはなってきたが、使用しているライブラリの都合などからまだデプロイできない。ただデプロイをAzureのWebアプリとしてやるか、それともDockerコンテナとしてやるかと迷ってもいるが。とりあえず今週末を一つの目安として考える。
スポンサーサイト



ASP.NET on Linux

                
 .NET CoreのLinux対応によってASP.NETがクロスプラットフォームでもということで、ASP.NETアプリをLiinuxで動かしてみる。以前にもASP.NET + NancyをLinux上で動かしてみたりしたが、それはコンパイル済みの実行ファイルにして動作させていた。今回は実行ファイルではなくコードのままLinux環境へ持っていきそのままWebアプリとして動くようにしたい。

 とりあえず動くことを確認したいのでHelloWorld程度のものでいい。MSの記事を参考にやってみる。ありがたいことにDockerfileまでついたサンプルを紹介してくれているのでそれを使う。
http://blogs.msdn.com/b/webdev/archive/2015/01/14/running-asp-net-5-applications-in-linux-containers-with-docker.aspx


 まずはASP.NETから。下記からサンプルとしてBeta6をもってきて解凍する。自分のマシンでは既にBoot2Dockerが使えるようにしてある。
https://github.com/aspnet/Home/releases
 解凍したらBoot2Dockerを立ち上げてそこにlatest/HelloWebをマウントし、HelloWebへ移動する。あとはdocker buildする。Dockerfile内では、project.jsonを参考に依存パッケージがこのプロジェクト用にダウンロードするコマンドを実行している”dnu restore”。これがタイムアウトになってエラーでDockerイメージのビルドが中断されたりするが、あきらめずに2、3回程度ビルドを実行したら最後まで通った。……NuGet安定してないんだろか?それともこっちの問題だろか。同様のエラーケースの報告は簡単に見つかったが。
 Dockerイメージのビルドが済んだらあとは走らせるだけ。特にファイル編集もなく問題なし?でASP.NET on Linuxが動作確認できた。
1508111230175.jpg


 続いてASP.NET MVCのサンプルを動かす。上で解凍したサンプルの中にlatest/HelloMvcというのがある。これをDockerで動かそうとしたところ、依存パッケージ収集コマンドであるdnu restoreが成功しなかったのでDockerでなく仮想マシンで用意したLinuxMint環境でファイルをいじって試行錯誤しながら進めた。
 まずドキュメントに従ってもろもろインストール。.NET系の実行環境としてMono、ASP.NET 5が依存のあるlibuv、.NETのバージョンマネージャを入れ、NuGetの設定ファイルを用意する。
http://docs.asp.net/en/latest/getting-started/installing-on-linux.html
 NuGetの設定ファイルはドキュメントにのったままのものではdnu restore実行時にエラーが出たので内容を追加したものを用意した(参考)。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="AspNetVNext" value="https://www.myget.org/F/aspnetvnext/api/v2" />
<add key="NuGet" value="https://nuget.org/api/v2/" />
<add key="Roslyn" value="https://www.myget.org/F/roslyn-nightly/" />
<add key="DotNet" value="https://www.myget.org/F/dotnet-corefx/" />
</packageSources>
</configuration>


 必要なものがそろったらdnvmのアップデート。
dnvm update

 Mint内でサンプルを落としてきて解凍し、HelloMvcディレクトリへ移動。
https://github.com/aspnet/Home/releases

 dnu restoreを実行。エラーで失敗するかもしれない。単純なサーバーとの通信のタイムアウトもあるし、もうちょい別の理由もある。エラー内容でぐぐったりGithubのissuesを見ればどうにかなった。とりあえず依存パッケージが落ちてくるまでめげずにdnu restoreすること、NuGet.configの書き換え(上で既に説明済み)などで解決できた。

 ここまできたらあとはWebアプリとして実行するだけである。コマンドは"dnx kestrel"。Dockerfikeにはあいだに"."が入っていたりしたが、「"."? dnxでは引数をWebかkestrelで実行せんか」とメッセージをもらったので"dnx kestrel"として実行した。これでWebサーバとして動くはずである。もし実行環境がdnvmの最新版を求めていたりしたら下記コマンド。
dnvm upgrade -u

1508121351102.jpg


 とりあえずLinuxにコードを持って行ってもASP.NET、ASP.NET MVCが動くことは確認できた。ただこれはまだベータ段階である。この先の正式リリースで細かいコマンドが変わることは考えられる。

Windowsのデスクトップアプリに使うデータベースにドキュメント指向データベースを使う

                
tags: couchbase
 オーディオライブラリ再生のユニバーサルアプリを作ってみた。
http://elicon.blog57.fc2.com/blog-entry-463.html
 アルバム情報を格納するデータベースにSQLiteを使った。できれば柔軟なドキュメント指向のデータベースが使いたかったが、それがまだなかったのでSQLiteを選んだ。
 SQLiteではアルバム一件の情報を保存しようと考えると、アルバムタイトルやアーティスト名を入れたアルバム情報のレコードと、そのレコードと結びつけられる情報を持った曲名や曲番を入れた曲情報に分散して保存する必要があるだろう。↑のユニバーサルアプリでは単純にしたかったので、工夫をしてアルバムと曲情報の分裂を避けて一件のレコードにそれらをまとめたが。
 ドキュメント指向のデータベースでJSONがドキュメントとなっているものを選べば、情報の収納にはJSONが使えるので柔軟な構成が可能で、工夫がいらずにCDアルバムの情報を一件のレコード(正しくはドキュメントと呼ぶ)にまとめられる。
 一件のドキュメントに柔軟に情報をまとめられる一方で、無理をすると情報構造が複雑になってしまう。複雑になる場合はわかりやすくきれいに切り分けたほうがいいこともあるだろうから、そこらへんはSQLiteのようなリレーショナルデータベースを選ぶのも吉。ただデータベース選択の一種としてドキュメント指向データベースも持っておきたいので、CDアルバムという例をとおしてドキュメント指向データベースの使い方を確認しておく。

 SQLiteと同様にローカルで使うことを目的としたドキュメント指向データベースにはCouchbase Liteがある。
http://developer.couchbase.com/mobile/get-started/couchbase-lite-overview/index.html
 動作ターゲットはLinux、Win、MacはもちろんiOS、AndroidからUnityもターゲットになっているので、デスクトップだけでなくスマフォアプリのデータベースとしても使えるだろう。今回は.NET Frameworkのデスクトップアプリで使う。

 VisualStudioでCouchbase Liteを入れたいプロジェクトを開く。Package Manage Consoleを開いて"Install-Package Couchbase.Lite"を実行。依存ライブラリとともにインストールが始まる。

 使用準備ができたら始める。依存ライブラリに入っているNewtonsoftのJsonツールも入っているので使えるようにしておくとデータの取り回しが楽になる。
http://www.newtonsoft.com/json/help/html/SerializingJSON.htm
using Couchbase.Lite;
using Newtonsoft.Json.Linq;


 データベース接続。
var dirInfo = new System.IO.DirectoryInfo(System.IO.Directory.GetCurrentDirectory());
var manager = new Manager(dirInfo, ManagerOptions.Default);
var db = manager.GetDatabase("foo");
if (db == null)
{
throw new Exception("Cannot create database.");
}


 ここで保存するアルバム情報のデータを考える。とりあえずアルバムタイトル、アーティスト名、収録曲名、リリース年あたりで構成。収録曲名をListにしたい、Listにするとリレーショナルデータベースでそのまま保存できないので今回のようにドキュメント指向データベース使用を考えようかとなってくる。
class Album
{
public string AlbumTitle { get; set; }
public string Artist { get; set; }
public List<string> TrackTitles { get; set; }
public int? Year { get; set; }

public static Album FromJson(string jsonstr)
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<Album>(jsonstr);
}

public Dictionary<string, Object> GetDict()
{
var dict = new Dictionary<string, dynamic>() {
{"AlbumTitle", AlbumTitle},
{"Artist", Artist},
{"TrackTitles", TrackTitles},
{"Year", Year},
};
return dict;
}
}

 オブジェクトをDictionary化するメソッドも加えておいた。あとJSONからこのオブジェクトを作るメソッドも。

 適当なアルバム名やアーティスト名を入れてAlbumのインスタンスを準備。
var album1 = new Album()
{
AlbumTitle = "album1",
Artist = "artist1",
TrackTitles = new List<string> {"t1", "t2", "t3"},
Year = 2010
};

var album2 = new Album()
{
AlbumTitle = "album2",
Artist = "artist2",
TrackTitles = new List<string> { "t1", "t2", "t3", "t4", "t5" },
Year = 2005
};

var album3 = new Album()
{
AlbumTitle = "album3",
Artist = "artist1",
TrackTitles = new List<string> { "r1" },
Year = null
};

var albums = new List<Album> { album1, album2, album3 };


 データベースへそれぞれのアルバムデータを保存。
foreach (var album in albums)
{
var document = db.CreateDocument();
document.Id = album.Artist + " " + album.AlbumTitle;
var albumDict = album.GetDict();
albumDict["updated_at"] = DateTime.Now;
var properties = albumDict;
var rev = document.PutProperties(properties);
Console.WriteLine(rev);
}


 保存データの全件読み出し。
var view = db.GetView("all");
if (view != null)
{
view.SetMap((doc, emit) =>
{
emit(doc["AlbumTitle"], doc);
}, "ver1");
}

var vQuery = db.GetView("all").CreateQuery();
docs = vQuery.Run();
Console.WriteLine("no filter: " + docs.Count);


 読みだしたドキュメントをAlbumオブジェクトへ。
foreach (var doc in docs)
{
var album = Album.FromJson(doc.Value.ToString());
Console.WriteLine(album.AlbumTitle);
}


 t1というタイトルの曲が入ったアルバムを探す。
var view3 = db.GetView("TrackTitleFilter");
if (view3 != null)
{
view3.SetMap((doc, emit) =>
{
var titles = ((JArray)doc["TrackTitles"]).ToArray();
if (titles.Contains("t1"))
{
emit(doc["AlbumTitle"], doc);
}
}, "ver1");
}

var vQuery = db.GetView("TrackTitleFilter").CreateQuery();
docs = vQuery.Run();
Console.WriteLine("TrackTitle filter: " + docs.Count);


 データソートはemitというデリゲートに渡す第一引数で行われる。データのオーダーを気にする場合はその辺も気にかけて。
 CRUDで考えればドキュメント作成はした。ドキュメントの引き出しからオブジェクトへの変換も行ったのでデータも読める。更新や削除は引き出したドキュメントからメソッドを実行するだけである。
http://developer.couchbase.com/mobile/develop/guides/couchbase-lite/native-api/document/index.html

 デスクトップアプリにドキュメント指向データベースを使いたくなったのでCouchbase Liteの使い方を学んだ。サービスとしてAzureでもドキュメント指向データベースの提供は始まっており、それをローカルでも使えるようにしてくれという投票も行われている。ドキュメント指向データベースも場合によってはかなり使い物になるということだろうから使える箇所を考えていきたい。

Windows 10: 自分のために作ったユニバーサルアプリをインストール

                
tags: .NET
 Windows 10のユニバーサルアプリはストアアプリと同様、基本的にストアからインストールをしてくださいという形になっている。そのためアプリ自体をビルドして出てきたファイルを実行しようとしてもAppContainerから実行されてないというようなエラーが出て実行できない。これを回避し自作ユニバーサルアプリを自分の環境で使いたい場合、アプリをインストールしてから実行する必要がある。というわけで自作ユニバーサルアプリのインストール方法のメモ。表示言語が英語での操作でやっているのでそこらは適宜読み換え。
 まず注意点。ユニバーサルアプリをストアを介さずにインストールできるようにするのはリスクを抱えることになる。基本審査を行うストアを介してインストールされるべきアプリが、ストア以外の入手先もOKということになってしまうので。というわけでインストールして使うのは自作アプリに絞ること。どっかから拾ってきたアプリでこの方法を実行しないこと。

 Windows10のSettingsメニューにデベロッパーモードへ切り替えるスイッチがある。これをオンにする。先にもあるとおり、これはセキュリティリスクを増す行為である。これをやるなら以降はファイル実行、スクリプト実行などで注意を増す必要がある。

 ユニバーサルアプリを作成したVisualStudioプロジェクトを開き、「Project」- 「Store」 - 「Create App Packages」とたどる。
1507191315283.jpg

 ストアへはアップしない。
 1507191315536.jpg

 CPU構成を自分の環境に合わせる。パッケージ作成は数分かかるようなので余計な設定はしないでおいたほうがいいかも。
1507191316143.jpg

 パッケージ作成が終わったら認証が課される。
1507191313275.jpg

 実行するテストの選択。
 1507191314034.jpg

 以上が終了したら作成したアプリのプロジェクトフォルダにAppPackagesというディレクトリがあり、そのさらに下にそれらしきプロジェクト名とバージョン名のディレクトリができているのでそこへ下りていく。.ps1ファイルがあるのでそれを右クリックしてPowerShellで走らせる。これでインストールが始まる。
 1507191325235.jpg

Windows 10: ユニバーサルアプリを作ってみた その2

                
1507152230430.jpg

 Windows 10にはGroove Musicというオーディオファイル再生のためのアプリが入っているが、個人的には機能をそぎ落としたシンプルなものが使いたい。アルバムをクリックするたびにそのアルバムの詳細を表示する画面への遷移がいらない。遷移があると次のアルバムを選ぶために一覧へもどるという手間が増えて面倒。各曲の評価や時間の表示もいらない。聴きたい曲を流すだけなのでそんな情報は読まない。選んだアルバムのタイトル、アーティスト、収録曲がわかれば十分。というわけでユニバーサルアプリで自作してみる。機能をそぎ落としたものを作るので、標準搭載のアプリであるGroove Musicよりすごいものができるわけではない。簡単なものを作りつつ、ユニバーサルアプリ作成への理解を深めたかった。

 ユニバーサルアプリのパフォーマンスに関しては悪くないものになるようだ。.NET Nativeによってストアアプリのリリース設定版は中間言語ではなくネイティブコードにコンパイルされるとのこと。ユニバーサルアプリは公開時にMSのサーバにソリューションをアップロードして、ARM、x86、x64のそれぞれにコンパイルされて、ユーザがアプリをダウンロードするときに構成にあったものを落とさせるんだろう。

・オーディオファイル一覧とそのメタ情報の取得、各ファイルのアルバム単位への分割
 オーディオアプリということでまずはオーディオファイルとそのメタデータ収集。.NET Framework使用のアプリではDirectoryInfoなどからGetFilesで拡張子指定をかけてオーディオファイルを取ってこれた。
var files = new DirectoryInfo(uri)).GetFiles(".mp3", SearchOption.AllDirectories);
 これで集めたファイルをCOMのWMPLibにあるクラスに渡せばオーディオファイルのメタ情報を得られた。
var media = mediaInfo.wmpLib.newMedia(filePath);
var groupID = media.getItemInfo("WM/WMCollectionGroupID");
 このファイルアクセスやCOMの使用などのあたりは.NET Frameworkでやるのとユニバーサルアプリでは勝手が違う。そもそもユニバーサルアプリではファイルアクセスに制限がかかっているのもあるし。ただオーディオファイルのメタ情報を得たければ標準でFileStorageというオブジェクトから得る方法が準備されているところは助かった。
await KnownFolders.MusicLibrary.GetFoldersAsync(Windows.Storage.Search.CommonFolderQuery.GroupByAlbum);
上記のメソッドに渡しているクエリオプションによってどうフォルダを得るかを変えられる。GroupByAlbum以外にGroupuByArtist、GroupByAlbumArtistをはじめとしてジャンル別などわりといろいろ条件は準備されいる。アルバム一覧を表示するパネルにアーティストの名前順で表示したかったのでGroupByArtist、GroupByAlbumArtistなどを試してみたが、オーディオファイルがアルバム分けされずにアーティストの曲がごっちゃにまとまって返ってきた。なのでメタ情報取得後に改めてLINQなどでグルーピングしなおしたり。

・取得したオーディオファイルメタデータをデータベースへ
 オーディオファイルのメタデータを取得したら以降でその読み込みをとっとと行えるようにデータベースへつっこむ。簡単な構造でデータを保存するので柔軟性のあるドキュメント指向のデータベースが使いたかった。だがまだ対応したものはないらしいのでSQLiteを使用した。
http://www.codeproject.com/Articles/826602/Using-SQLite-as-local-database-with-Universal-Apps
 メタデータはアルバムごとにアルバムタイトル(string)、アーティスト名(string)、トラックタイトル(List)、ファイルパス(List)という具合にまとめたい。なるべく簡単にまとめたいので中間テーブルとか作りたくない(だからドキュメント指向データベースを使いたかった)。Listであるトラックタイトルとファイルパスがこのままじゃデータベースに保存できないけどどうするかなーと考えてみて、ListをJSONシリアライズすることで解決した。JSONのシリアライズ、デシリアライズもユニバーサルアプリでは新しいクラスが用意されていた。
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh770289.aspx
[Table("Album")]
class Album
{
[PrimaryKey]
public string AlbumID { get; set; }
public string Title { get; set; }
public string Artist { get; set; }
public int Length { get; set; }
public string _TrackPaths { get; private set; }
public string _Titles { get; private set; }
public DateTime Added { get; set; }

[Ignore]
public List<string> TrackPaths
{
get
{
var ja = JsonArray.Parse(_TrackPaths);
return (from a in ja.GetArray()
select a.GetString()).ToList();
}
set
{
var ja = new JsonArray();
foreach (var a in value)
{
ja.Add(JsonValue.CreateStringValue(a));
}
_TrackPaths = ja.Stringify();
}
}

[Ignore]
public List<string> Titles
{
get
{
var ja = JsonArray.Parse(_Titles);
return (from a in ja.GetArray()
select a.GetString()).ToList();
}
set
{
var ja = new JsonArray();
foreach (var a in value)
{
ja.Add(JsonValue.CreateStringValue(a));
}
_Titles = ja.Stringify();
}
}
}


 完成物イメージはこの記事のトップにスクショで置いてある。もしストアで公開するならもうちょい、コントロールがなにと連動してるかなどをわかりやすくせねばならない。だがとりあえず自分で使うぐらいには困らないかつ快適なものができた。
https://github.com/hMatoba/PlaneAudioU/tree/master/PlaneAudioU
プロフィール

h

Author:h

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon