プログラムの記事一覧

2020/06/01

【覚書】VS2019でネットワーク系のプログラムを作成する時のおまじない

SSLが必要なサイトにアクセスする可能性があるプログラムでは、TLS1.2に対応させる必要がある。

もう面倒なので、テンプレートに入れ込もうかと思うくらいに必須な内容になっている。

            System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;

おまじないとして、Program.cs の先頭にでも記述しておけば問題はないだろう。

2020/05/28

【接触確認アプリ】政府仕様書を読んでみて(2)

【接触確認アプリ】政府仕様書を読んでみて

続きです。

Bluetoothの問題も出てきますが、待機状態でのバッテリーの消耗が激しいのが気になってしまう。それも、古い機種ほど顕著に表れる。政府仕様書には対応バージョンが

本仕様書の執筆時点では iOS 13.5 以上および Android 6 以上

と書かれている。

性能評価に関しても、

端末の応答は 3 秒以内とする。

接触の測定には Bluetooth を活用するが、電波干渉や障害物により正確に測定できないことがあるのでパラメータ設定に留意すること

と、謎の言葉が書かれている。

OSのバージョンは私が開発するのなら最新に近いバージョンに限定するだろう。古い機種でBluetoothを使えばトラブルに遭遇するのは目に見えている。何度も書いているが、バッテリーの持ちが悪くなるのは確実だ。

スマホで、3秒も動作が止まることを許容するのか?Bluetoothを活用と書かれているが、Bluetoothの通信障害の許容は行わないらしい。

仕様書の中で注意しなければならないのは二点。

端末での稼働率は 98%以上とし、サーバーの稼働率は 95%以上とする。

とあるが、停止時間ではなく稼働率なのがまたいやらしい。

一時的な停止により社会的に大きな社会的混乱を引き起こすものではない。障害時には 72 時間以内の復旧を目標とする。大規模災害におけるシステム停止時には、システム運用者と相談の上、1 週間以内の復旧を行う

となっている。矛盾する記述にも思える。

そもそも、3日間も放置を許すのならやる必要はない。その3日間の間にそれだけの人と接触するのかわかったものではない。

社会実験的な意味合いが強く、提案されて乗りました的な匂いがする。

いろいろ要求定義に書かれているが、これらを全部まとめると、”不可能”の言葉が頭に浮かんでくる。

そして、一番の問題は

スマートフォンの国民の個人保有率が 64.7%(令和元年版情報通信白書)であるので、最大で国民の6割以上が導入することを目指す想定で基盤等の拡張性を確保する。

この部分だ。国民と言っているが、渡航者でも利用できるように、英語での我慢を整備することと定義されている。

わかりやすいように、国民を1億人と定義すると、6、000万端末分のサーバが必要になってしまう。サーバに保存しているデータは4,200人分の14日分のデータだから、容量はそれほど多くはない。しかし、トラフィックが問題になる。仕様書を読むと、規定されているようには思えない。したがって、開発者の任意機能となる。

そのために、国の金だと思ってサーバの維持費を膨大な金額で設定することが考えられる。

さて、実際にアプリが無事リリースされたとして使うか?

私は使わない。

アプリを設定したら10万くれるとか言われない限りは使わないだろう。

まず、メリットが提示されていない。

感染者が近くに居たのがわかるだけだ。10万くれるという明確なメリットではないにしろ、感染者全員が承諾して、全員が追跡・追認できるようにならないと意味がない。強制できないのなら、意味がない。

また、バッテリーの持ちが悪くなる。Bluetoothを常時使う事で、スマホの熱対策が心配になる。もしかしたら、劣化の原因にもなるかもしれない。

この方式しか考えられなかったのだろうか?

Twitterでも書いたことがあるが、やった感を出すためだけにかなりの金額の”運営費”を払うのだろうか?

サーバはただじゃない。保守メンテもただではやらないだろう。使われないクズアプリの為に税金が使われるのだ、それも仕様を読んだ段階でかなり問題が見えてくる。今なら傷口は担当者の首を切るだけで幕引きができるが、セキュリティの問題が発生したり、最悪は乗っ取りまで考える必要がある。アプリなんて危険な方法を用いないで、もっと別な方法を考えればいいのに・・・。

 

2020/05/27

【接触確認アプリ】政府仕様書を読んでみて

接触確認アプリに関する仕様書等の公表

接触確認アプリの仕様書を読んでいると、昔作ったアプリを思い出す。

Bluetoothを待機状態にして、近くにいた同じアプリを使っている人と情報を交換する物だ。過去にさかのぼって、地図で接触場所を確認できるというものだ。

作っているうえで、Andoridは問題はなかった。正確には、問題はバッテリーの持ちが2割ほど悪くなるという問題だったが、Bluetoothの待機状態を常時待機から、数秒間のディレイを入れて対応した。それで、バッテリーの持ちが落ち込むのは5%未満に抑えた。

問題は、iOSの方だった。

iOSは、フォアグランドでBluetoothを待機状態にしてもバッテリーの持ちは2-3%の落ち込みだったが、問題は違うところにあった。

バックグラウンドでアプリを待機させると、待機状態の維持ができなくなるのだ。
Android にも似たような現象が発生するが回避方法があった。

記憶では、15分で待機状態が終了してしまった。再度待機状態に戻すのに、アプリの操作が必要になっていた。

ペアリングしている状態なら問題が発生しないBluetoothだが待機状態でのピア通信では問題が多発した。

この問題は解決できているのだろうか?
解決できていたとして、脆弱性に繋がらないのか?

仕様書を読むと、キーファイルを保存するように見える。DBを使ってくれるとは思うが、仕様書のまま作成すると接触した人の数だけファイルができる。14日間は保存するように書かれている。

スマホの容量はきにする必要がないくらいに肥大化しているが、保存すべき情報ではないのは間違いはない。

昔作ったソースがどこかに転がっていると思うから、公開しておこうかな?

政府が余計にことを考えないで、キャリアに丸投げした方がよかったと思うけどな。
キャリアが握っているSIMの情報と接続IPを元に接触確認アプリを作るのが良いと思う。

今の政府だとちょっとでもミスをすると政権が持たないのがわかっているから、慎重になっているのだろうけど、GPSと接続IPを使った接触確認アプリのほうが問題は少ないと思う。
Bluetoothは諸刃の刃だと思う。便利には違いないし、メートル単位での接触を考えれば仕様は満たすだろう。

しかし、それにはユーザの多大なる協力が必要になる。
開けたところで使った場合は?
フェスとかで大量に接触確認アプリが起動されていたら?
バックグラウンドで本当に取れる?ピア通信でも接続単位は1だよ?開けたところで、数百の端末情報を一度に処理できる?
店舗でも同じですよ。5人とかの密接状況を処理できるとは思えない。

あとは待機状態での、脆弱性は大丈夫?
わかりにくい文字列に接続しはなっている?
いろいろ考えると不安でしかない。
6月中旬って半月だよ?テストできるの?無理だよね?もうできている物を流用したとしても・・・。iOSの審査を考えると無理だよね?

広告

2020/05/22

【覚書】Amazon 検索ウィジェットの文字化け対策

【覚書】WordPressでAmazon商品を簡単に表示するショートコード

で解説しているAmazon商品を簡単に表示するショートコードなのですが、2020年05月07日くらいから文字化けされるようになってしまっています。差塩は、2020年04月10日にAmazon側の問題として修正されたのですが、再度表示がおかしくなってしまっています。

日本語でなければ問題はないので、最初はエンコードの問題かなぁPHPのバージョンを変えた影響がでていると考えて、調査を行いましたが、エンコードではなく、Amazon アソシエイトで検索ウィジェットを参照しても同じような現象になってしまいます。

いくつかのサイトでも同様の現象が発生していて、Amazonに問い合わせしてくれた人がいます。

Amazonアソシエイト側の不具合で現在対応中だという事です。

文字化け対策は、”Amazonが対応してくれるまで待つ”が対応方法になってしまいます。

2020/05/21

【VS2019】16.6.0

2020/05/13 に、VS2019の最新バージョン16.6.0がリリースされていた。

変更内容は、リリースノートを見た方が早いだろう。

地味にバージョンアップが行われているのだが、気が付いたときには更新を行っておいた方がいいだろう。

インテリセンスとかの修正が入っているのが地味に嬉しい。

複数で行う時には、バージョンを合わせた方がいいのだろうな。アセンブリまで更新されているし、通常使う物か検証していないからわからないけど、合わせないと何が発生するかわからないですからね。

開発プログラムのほうにも書いておいた方がいいかな?

VS2019のバージョン情報を埋め込んでおけば、ソースを展開した時に困らないからな。

2020/05/16

【覚書】WordPressのタグをC#から追加(WordPressPCL)

WordPressPCL を使って、C#から管理しているWordPress に記事を投稿する。
その時に、同時にタグを追加したい場合がある。っていうか、それができないと不便。

だから、作ってみた。

            string strUrl = wp.siteUrl;
            var client = new WordPressClient(strUrl + "wp-json");
            try
            {
                client.AuthMethod = AuthMethod.JWT;
                client.SetJWToken(wp.siteToken);
                //
                WordPressPCL.Models.Tag entry = new Tag();
                entry.Name = strTag;
                //
                var ctask = client.Tags.Create(entry);
                ctask.Wait();
                var tags = ctask.Result;
                //
                strRet = tags.Id.ToString();
            }
            catch (AggregateException ae)
            {
                ae.Handle((ex) =>
                {
                    if (ex is WPException)
                    {
                        errorMesseage(ex.Message);
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            }
            catch (Exception ex)
            {
                errorMesseage(ex.Message);
            }

最終的に登録したタグのIDを取得するのは、記事を投稿する時に、必要になるのはIDだからです。
広告

2020/05/04

【覚書】WordPressにC# WindowsForm から投稿

NuGet で WordPressPCL をインストール。

WordPress には、JWT Authentication for WP-API プラグインをインストール。ユーザー → 対象ユーザ → パスワードの設定。

認証

            CWPData wp = getSelectSite();
            if( wp != null )
            {
                string strUrl = wp.siteUrl;
                try
                {
                    var client = new WordPressClient(strUrl + "wp-json");
                    client.AuthMethod = AuthMethod.JWT;
                    client.RequestJWToken(txtUserName.Text, txtPasswd.Text).Wait();
                    //
                    var isValidToken = client.IsValidJWToken().Result;
                    //
                    if (isValidToken == true)
                    {
                        wp.siteToken = client.GetToken();
                        lblAuth.Visible = true;
                        //
                        int iPos = cbWPData.SelectedIndex;
                        _mWPData[iPos].siteToken = wp.siteToken;
                    }
                    else
                    {
                        lblAuth.Visible = false;
                    }
                }
                catch (AggregateException ae)
                {
                    ae.Handle((ex) =>
                    {
                        Console.WriteLine(ex.GetType().Name);
                        Console.WriteLine(" " + ex.Message);
                        if (ex is WPException)
                        {
                            lblAuth.Visible = false;
                            errorMesseage(ex.Message);
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    });
                }
                catch (Exception ex)
                {
                    lblAuth.Visible = false;
                    errorMesseage(ex.Message);
                }
            }

認証が成功したら、次は投稿

                string strUrl = wp.siteUrl;
                var client = new WordPressClient(strUrl + "wp-json");
                try
                {
                    client.AuthMethod = AuthMethod.JWT;
                    client.SetJWToken(wp.siteToken);
                    //
                    Post entry = new Post();
                    //
                    entry.Categories = getInts(txtCategory.Text);
                    entry.Tags = getInts(txtTag.Text);
                    entry.Title = new Title(txtTitle.Text);
                    entry.Content = new Content(txtBody.Text);
                    //
                    if (txtMedia.Text != "")
                    {
                        try
                        {
                            int iMedia = int.Parse(txtMedia.Text);
                            entry.FeaturedMedia = iMedia;
                        }
                        catch
                        {

                        }
                    }
                    //
                    var post = client.Posts.Create(entry);
                    post.Wait();
                    //
                    var result = post.Result;
                    //
                    txtWPUrl.Text = result.Link;
                    //
                    wp.lastCategory = txtCategory.Text;
                    wp.lastTag = txtTag.Text;
                    wp.lastMedia = txtMedia.Text;
                    saveWPData(wp);
                }
                catch (AggregateException ae)
                {
                    ae.Handle((ex) =>
                    {
                        if (ex is WPException)
                        {
                            errorMesseage(ex.Message);
                            return true;
                        }
                        else
                        {
                            return false;
                        }
                    });
                }
                catch (Exception ex)
                {
                    errorMesseage(ex.Message);
                }

いろいろ余計なソースがあるけど、こんな感じで任意のWordpressに投稿が可能。

認証のTokenは永続的に使える物ではないので、都度取得するくらいのUIが良いと思います。

2020/05/03

【覚書】権限を取得して実行

                    ProcessStartInfo psi = new ProcessStartInfo();
                    //起動するファイルのパスを指定する
                    psi.FileName = appFileName;
                    //コマンドライン引数を指定する
                    if (strArgs != "")
                    {
                        psi.Arguments = strArgs;
                    }
                    if( bRunAs == true )
                    {
                        psi.Verb = "runas";
                    }
                    //
                    hProcess = Process.Start(psi);

パラメータ部分は省略していますが、ProcessStartInfo をセットして実行すればいいだけ。

2020/04/30

【覚書】プラグイン機能を作る為の手段

最初にインターフェースを作る。

    public interface IStoryEditorPlugin
    {
        /// <summary>
        /// 初期化
        /// </summary>
        /// <returns></returns>
        bool init(string strDllFileName);
        /// <summary>
        /// バージョン情報プロパティ
        /// </summary>
        string Version { get; }
        /// <summary>
        /// コピーライト
        /// </summary>
        string Copyright { get; }
        /// <summary>
        /// ノードを選択された時に、実行される
        /// </summary>
        bool isNodeOpen { get; }
        /// <summary>
        /// 表示用メニュー
        /// </summary>
        /// <returns></returns>
        ToolStripMenuItem menu(string strDllFileName);
        /// <summary>
        /// 
        /// </summary>
        /// <param name="mPluginData"></param>
        /// <returns></returns>
        CStoryEditorPlugin run(CStoryEditorPlugin mPluginData);
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        DialogResult config(string strDllFileName);
        /// <summary>
        /// 設定項目がある場合に、True
        /// </summary>
        bool isConfig { get; }
        /// <summary>
        /// 設定用のメニューの項目
        /// </summary>
        /// <param name="strDllFileName"></param>
        /// <returns></returns>
        ToolStripMenuItem configMenu(string strDllFileName);
    }


肝になるのが、ToolStripMenuItem を返すところ。本体でロードした時に、メニュー項目に追加される ToolStripMenuItem  を作って返してあげる。これで、プラグインの下準備ができる。

DLLを作って、インタフェースを実装する。

public class CTextFile : IStoryEditorPlugin
{
        public CTextFile()
        {

        }


こんな感じで実装すればいいだけだ。

呼び込み部分は、

            IStoryEditorPlugin plugin = null;
            //
            string[] files = Directory.GetFiles(strBaseFolderName, "*.dll", SearchOption.AllDirectories);
            foreach (string dllFileName in files)
            {
                var asm = Assembly.LoadFrom(dllFileName);
                plugin = null;
                foreach (var tImpl in asm.GetTypes())
                {
                    if (tImpl.IsInterface) continue;
                    try
                    {
                        plugin = Activator.CreateInstance(tImpl) as IStoryEditorPlugin;
                        if (plugin != null)
                        {
                            break;
                        }
                    }
                    catch
                    {
                        //break;
                    }
                }

こんな感じで、DLLを収めているFolderを探して、インタフェースが実装されている場合にはプラグインだとして認識してあげればいいと思う。

後は、創意工夫で乗り切れば大丈夫!

広告

2020/04/21

【バージョンアップ】サイトの更新

各種ドメイン。

https://dotnet.jp/

https://hyperion.biz/

https://mnabe.net/

https://nfox.biz/

の、PHPのバージョンを設定できる最新版に変更しました。同時、MySQLを5.5から5.7に変更しました。

まさか、一日掛かりの作業になるとは思わなかった。

問題は、MySQL5.5 で作っていた一部のデータが5.7に移行すると文字化けしてしまったのだ。最初は、PHPのバージョンの問題だと思って、バージョンを元に戻しても改善しなかった。問題の切り分けを行っていたら、どうやら5.5の時に挿入していたプログラム側に問題があったようだ。VS2010で作っていたプログラムで、フォームの内容をPHPにPOSTで送って、PHPからデータを挿入するだけのものだった。

ここで、文字コードがEUCになっていたのだ。

しかし、DBはUTF8で作られていて、データも問題なく表示できていた。個人的に使っているデータなので、気にしないで使っていた。移行ツールが文字コードを厳密に判定していたようで、何をどうやっても文字化けしてしまったのだ。

解決策を考えること15分。

5.5のデータを一度HTMLに表示させれば、文字化けすることなく表示できる。MySQL5.5(文字化けデータ・・約12万件)→ 一件一件 CSVに変換するPHPのプログラムを作成 → VS2019でWeb情報を取得する → MySQL5.7に文字化けすることなく挿入できるPHPのプログラムを作成 → 挿入した元のMySQL5.5のデータに参照したフラグを付ける。

このプログラムを延々と回した。サーバに負荷がかからないようにしながら状況を注視しながら・・・。

先ほどやっと終わった。

”軽い気持ちで始めた”バージョンアップだったが、大変な目にあってしまった。

そのせいで今日アップ予定の”異世界の物流は俺に任せろ”の【第八章 リップル子爵とアデヴィト帝国】第十六話 ユーラットに寄り道 の公開が2時間遅れてしまった。

2020/03/28

【戯言】VS2015→VS2019

メインで利用する開発ツールを変更するのはいつも手間取るのだが、VS2015→VS2019は思った以上に簡単だった。

まず、.NET Framework が大きく変わっていないのが変更が少なくて済んだ理由だろう。

古い技術で作っている物は若干の手直しが必要になりそうだが、昔のソースは、昔のVSでメンテナンスを行うので問題にはならない。

新しい環境で動かす必要がある場合のみ開発環境を変更する方向性にした。

仕事で作った物は変更の必要がないのでそのままにして、趣味で作っている物やソフトライブラリに登録している物はVS2019でリビルドして提供する。

Story Editor関連はVS2019に変更する。まだ動作確認をしている最中だが問題はなさそうだ。.NET Framework のバージョンも変えていないので当然問題は出ないと思うが、今後を考えると変えたほうが良いかも知れない。町売りのWindows10が入ったパソコンの初期バージョンに合わせようと思っている。下位バージョンでも問題はないとは思う。選択肢はそれほど多くはないので、少し調べながらデフォルトバージョンを選んでいこうと思う。最新バージョンには間違ってもしない。

2020/02/08

【戯言】ウィルス開発

昨日になるがメインで使っていないアカウントに面白いメールが届いた。

ウィルスを作る事ができるか?

いろいろ書かれていたが要約するとそんな感じだ。今世間を騒がせている新型コロナウィルスではなく所謂コンピュータウィルスだ。

確かに持っている事は持っているしウィルス自体を作成する事は難しい事ではない。マクロが組める程度でも簡単に作る事ができる。

ウィルスに何をさせるのかとウィルスをどうやって感染させるのかが難しいのだ。

作り方はもちろん面倒な事になりそうだったので”やらない”とだけ書いた返事を出した。SPAMメールも増えない事から純粋にウィルスを作りたかったのだろうと判断した。

ウィルスを作ろうと思ったらプログラム言語が何かしら必要になってくると思うのだろう。事実正しいだろう。しかし、言語なら何でもよいというわけではない。

作るにあたっては定義が必要になる。

ウィルスは、自己増殖を兼ね備えたプログラムの一種だと思っている。自己増殖機能を持っていればウィルスと考えても問題ないだろう。

悪さをしなければ、ウィルスは有効な手段となってくる。

特に、自己増殖は最新版に入れ替える場合などに使えるからだ。自作のプログラムには必ず入れ込んでいる機能だ。

私はDLLを一つ作って自己増殖と自己入れ替えを実現している。

プログラムからDLLを呼び出すと、別の小さなプロセスが起動する。そのプロセスから親となるプログラムを殺す。自分自身ではなく親を先に入れ替えるのだ。入れ替えた親からDLLやほかのバージョンアップが必要なプログラムを入れ替えるようにしている。

自己増殖は自分自身をほかの場所にコピーするだけの機能なのでそれほど難しくない。

なので、私の作っているプログラムがウィルスかどうかを判断した時にウィルスとなってしまう。最近はひかからなくなったがこの機能を作った時には無料のウィルス対策ソフトにウィルス認定されたことがあった。自己増殖や自己入れ替えは問題ではなかったのでしばらくしたらウィルス認定されなくなった。

広告

2020/01/29

【覚書】WordPressでAmazon商品を簡単に表示するショートコード

WordPress にAmazonの商品を紹介できるプラグインはいろいろと存在しているのですが、どれもいまいち趣味に合わない。

問題なのは、このサイトを含めて作っているサイトでは商品を売れない事に起因している。

API の制限があります。

  • 利用開始から60日間は、一日あたり8640リクエスト可能
  • 過去30日間の発送済み商品売上約5円ごとに1リクエスト追加
  • 最大リクエスト可能数は864000
  • 過去30日以内に発送済の商品売上が必要

私のような場合には最後の制限にヒットします。毎月誰かが買ってくれるなんて事はありません。

それで何か方法はないかと考えたのですが、Amazonアソシエイトの画面でいい感じにできるウィジェットを発見しました。

ホーム>ウィジェット>商品検索ウィジェット

商品検索ウィジェットを使ってみます。

まずは、”あなたのWebサイトに追加”を選択して、ウィジェットのプレビューを表示します。好きにカスタマイズしてください。

<script type="text/javascript">amzn_assoc_ad_type ="responsive_search_widget"; amzn_assoc_tracking_id ="netlaborat-22"; amzn_assoc_marketplace ="amazon"; amzn_assoc_region ="JP"; amzn_assoc_placement =""; amzn_assoc_search_type = "search_widget";amzn_assoc_width ="auto"; amzn_assoc_height ="auto"; amzn_assoc_default_search_category =""; amzn_assoc_default_search_key ="";amzn_assoc_theme ="light"; amzn_assoc_bg_color ="FFFFFF"; </script><script src="//z-fe.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&Operation=GetScript&ID=OneJS&WS=1&Marketplace=JP"></script>

コードはこんな感じになります。
検索ワードを入力して表示を行うと、コードが下記のように変わります。

<script type="text/javascript">amzn_assoc_ad_type ="responsive_search_widget"; amzn_assoc_tracking_id ="netlaborat-22"; amzn_assoc_marketplace ="amazon"; amzn_assoc_region ="JP"; amzn_assoc_placement =""; amzn_assoc_search_type = "search_widget";amzn_assoc_width ="auto"; amzn_assoc_height ="auto"; amzn_assoc_default_search_category =""; amzn_assoc_default_search_key =".NET";amzn_assoc_theme ="light"; amzn_assoc_bg_color ="FFFFFF"; </script><script src="//z-fe.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&Operation=GetScript&ID=OneJS&WS=1&Marketplace=JP"></script>

見てみればわかると思いますが、”amzn_assoc_default_search_key”という引数に検索ワードを渡しているだけです。他にもカテゴリーやマーケットプレイスに関しての指定があります。

上記の例では”amzn_assoc_tracking_id”に私のトラッキングコードを渡していますので、ご自分のコードに切り替える必要があります。

ここまで来たらショートコードにすべき事はわかってきます。

amzn_assoc_default_search_key に関して表示したい商品名やコードを渡せるように変更してあげればいいだけです。Wordpress のショートコードに慣れた人なら簡単に作る事ができるでしょう。私は、function.php の最後に次のように追加しました。ISBN での検索を追加したかったからです。

function setAmazonAssociate($args)
{
	extract(shortcode_atts(array(
		'scode' => '',
		'isbn' => '',
	), $args));
	$sword = '';
	if( $scode === 'ISBN' )
	{
		$sword = 'ISBN '. $isbn;
	}
	else
	{
		$sword = $scode;
	}
	$tid = 'netlaborat-22';

	$strRet = '<script type="text/javascript">amzn_assoc_ad_type ="responsive_search_widget"; amzn_assoc_tracking_id ="'.$tid.'"; amzn_assoc_marketplace ="amazon"; amzn_assoc_region ="JP"; amzn_assoc_placement =""; amzn_assoc_search_type = "search_widget";amzn_assoc_width ="auto"; amzn_assoc_height ="auto"; amzn_assoc_default_search_category =""; amzn_assoc_default_search_key ="'.$sword.'";amzn_assoc_theme ="light"; amzn_assoc_bg_color ="FFFFFF"; </script><script src="//z-fe.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&Operation=GetScript&ID=OneJS&WS=1&Marketplace=JP"></script>';

	return $strRet;
}
add_shortcode('setAmazonCode', 'setAmazonAssociate');

解っていると思いますが上記のまま貼り付けないでください。
セキュリティをガン無視していますし、トラッキングIDも決め打ちしています。ご自分の環境にあったカスタマイズをお願いします。

ここまで来たらショートコードを使えば商品が表示されます。

[setAmazonCode scode=”ISBN” isbn=”9784065173817″]注)[と]は全角で表現しています。

創竜伝14巻が表示されたら成功です。

[setAmazonCode scode=”創竜伝”]注)[と]は全角で表現しています。

こちらは創竜伝に関する商品が検索されて表示されます。

 

2020/01/28

【戯言】Twitterの弊害

昨今のネット上の情報発信を見ると、簡単にアプリを作る事ができるTwitterでの発信が多くなってきている。

歓迎すべき事柄だと思っています。バッチをつける事ができれば偽物が出ても安心できます。それだけではなく、情報発信の容易さから第一報を告げるのにはちょうど良くなっている。

ただ便利な反面弊害も出始めているように思える。

情報収集の難しさだ。

通り一遍の情報を得る事は出来るのだが付属情報の入手が難しくなってきている。それと関連するのだが、RSSなどの副次的利用が可能なフォーマットになっていないのが問題になってくる。有益な情報が多いのはありがたいのだが、その情報を入手して使う難しさは依然よりも困難になってしまっている。

副次的な利用と書いているが、簡単に言えば趣味の予定を収集してスケジュールを作成するなどの事が難しくなってしまっているのだ。RSSと言わないがHTMLで記述されているスケジュールでは、プログラムでの加工が簡単にできた。入手もまとまっているので自動化ができたのだが、Twitterで雑多なつぶやきからスケジュールだけを引っ張り出すのは手動でも面倒に思えてしまうのだ。

例えば、大道芸を見に行く趣味があるとして、その大道芸のスケジュールを確認しようとしたときに、アカウントを一つ作ったとしても雑多な情報の中からスケジュールだけを探すのは困難極まりない。情報が少なければいいのだがRTされたりしてしまうと最終的なスケジュールがどれなのかをとっさに判断する事が難しい。人が難しいと思える事をプログラム化するのはもっと難しい。自分の為に決まったフォーマットで呟いてほしいと思っても無理だろう。

以前ドメインを一つ取得して”大度芸のスケジュール”を自動作成するプログラムを作ろうとした事があったのだが、ほとんどのスケジュールを手動で入力しなければならなかった為に挫折してしまった。

同じようにTwitterでの情報発信を行ってくれるのはうれしいのだが、それだけではスケジュールを合わせる事は難しい。

情報発信が容易に行えるようになってしまったために、情報をまとめるのが難しくなってしまっている。

なんとかならないかと調査はしているが、考えつく方法はどれもこれも大道芸人さんに負担を強いる形になってしまう。それでは本末転倒なのだ。

2020/01/16

【開発メモ】tweet.jsのJSON形式

多分2020年1月からだと思うが、Twitter のTwitterデータでダウンロードしたtweet.jsの形式が変わっている。

window.YTD.tweet.part0 = [ {
  "retweeted" : false,
  "source" : "サンプルソース",
  "entities" : {
    "hashtags" : [ ],
    "symbols" : [ ],
    "user_mentions" : [ ],
  },
  "display_text_range" : [ "0", "132" ],
  "favorite_count" : "0",
  "id_str" : "1014416775855783936",
  "truncated" : false,
  "retweet_count" : "0",
  "id" : "1014416775855783936",
  "possibly_sensitive" : true,
  "created_at" : "Wed Jul 04 07:53:00 +0000 2018",
  "favorited" : false,
  "full_text" : "【宣伝】",
  "lang" : "ja"
}

だったのだが

window.YTD.tweet.part0 = [ {
  "tweet" : {
    "retweeted" : false,

が挿入されるようになってしまった。

そこで、tweet.js を利用して投稿の全削除を行うようなプログラムは修正する必要が出てくる。

 

広告

2020/01/15

【戯言】専門職のプログラマー

送られてきた求人票を見ているのだけど、まだ言語での求人を行っているのですね。

業務知識での求人は、補足に”経験者優遇”や”業務経験車優遇”くらいしか存在しない。確かに特殊な業務では難しいというのは理解できるがもう少し考えてみてはどうだろうと思えてしまう。

どうせ業務経験と言っても自分の会社とはやり方が違うから新人に教えるのと大差ないという理由なら納得ができるが、それならば”即戦力”を募集しないほうがいい。矛盾が出てしまっている。

プログラマーが専門職だったのはもう10年以上前の話だと思っていたのだが、その時代から止まってしまっているのだろう。

前にも書いたが、八百屋のプログラマーとか魚屋のプログラマーだとか存在してもいいと思えてしまう。Webデザイナーがプログラムを書いてもいいと思っているし、プログラマーが初歩的なデザインができないようでは話にならないと思っている。それぞれの専門家がいるのだが最終的な調整や専門家に任せるのだろうけど、初期段階では全部ができる人物が居てもいいと思える。

 

2019/12/06

【SPAM】【楽天市場】お支払い方法を更新してください(自動配信メール)

久しぶりに面白いSPAMが来た。
内容はよくあるアカウントとパスワードを騙し取るサイトへの誘導だったけど、作りが面白かった。

メールで送られてきたSPAMだったのだが、メールの発信元が珍しく日本のサービス(sakura.ne.jp)を使っていた。
ヘッダーにつけられている経路を見ても自前で作って印象がある。Message-IDはもう少し工夫した方がいいと思うけど、そこまで厳密には見ないだろう。
X-Mailer を偽装しているようなのでそれなりの知識があるとは思うのだが、それならDate ヘッダの調整はしておいたほうが良いだろう。
送信部分のReceivedを読み込むとTLSv1.2 ESMTPS で送られている。sakura.ne.jp からなので報告(密告)だけは送っておいた。

さて面白いなっと思ったのは・・・。

HTMLメールになっているのだが、内容はすごく綺麗に表示されている。

しかし、タグを取り除いて表示するplain状態では、下記のような表示になる。

【楽天市場】お支払い方法を更新してください(自動配信メール)
かワソあゥぞ

楽天会員お客様

残念ながら、あなたのアカウント
ひどはなザエ
楽天会員個人情報 を更新できませんでした。
これは、カードが期限切れになったか。請求先住所が変更されたなど、さまざまな理由で発生する可能性があります。

ゕえぁヴ

アカウント情報の一部が誤っている故に、お客様のアカウントを維持するため
ヂォプヽてゑ゛ヒ

ゞそモゴや
楽天会員個人 情報を確認する必要・ェあります。今アカウントを確認できます。
ログイン

なお、24時間以内にご確認がない場合、誠に遺憾ながら、アカウントをロックさせていただくことを警告いたします。

ダよブ

ァんほ
どうぞよろしくお願いいたします。

ノヤヸせィ

これでは日本人は騙せないと思えてくる。
未だにHTMLがデフォルトになっているメーラーが多いのが問題なのだ。

確かに画像の表示や動画や音楽を添付して面白いメールを送ることができるのだが、必要なことですか?

メールに求められるのはそんなことではないと思う。

設定のデフォルトはプレーンテキストでの表示にして、ユーザが自分でHTML表記にしたいと思った場合に切り替えられるようにすべきではないのか?

 

2019/05/18

【NEWS】量子コンピューター小型・実用化へ前進 東大チーム、心臓部を開発

超高速で計算できる量子コンピューターの小型化に必要な心臓部の部品を東京大の古沢明教授らのチームが開発した。従来の手法と比べ計算回路を大幅に減らすことができ、量子コンピューターの実用化に一歩近づいた。米科学誌電子版に17日、論文が掲載された。

生きている間に実現できると嬉しいな。
使えるようになるまでは多分難しいだろうけど、動いているところを見てみたい気持ちにはなるな。

それに、夢が広がるからな。

広告

2018/10/13

【覚書】C#から、XServerで提供しているHTTPSサービスにアクセスする

                string strAccessURL = URLを入力;
                //
                System.Net.HttpWebRequest webreq = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strAccessURL);
                System.Net.HttpWebResponse webres = (System.Net.HttpWebResponse)webreq.GetResponse();
                System.IO.Stream st = webres.GetResponseStream();
                System.IO.StreamReader sr = new System.IO.StreamReader(st);
                //
                retData = sr.ReadToEnd();
                //
                sr.Close();
                st.Close();
&lt;br/>

で、アクセスしてデータを取得で来ていたが、最新サーバに切り替わって、速度が上がった関係かわからないが、エラーになってしまった。

要求は中止されました: SSL/TLS のセキュリティで保護されているチャネルを作成できませんでした

と、エラーが返されることが多発した。
私の環境下だと、ほぼ100%になってしまっていた。

回避策として

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

を、取得前に宣言することで、回避されている。

継続調査中だが、これで問題はなさそうだ。

2018/07/25

【開発メモ】DBの代わり

プログラムを作っていて、DBが使える状況になる方が多いが、時々DBが使えない場合がある。

そもそも、DBを使うほどではない場合が多いのだが、それでもDBを使えたら楽だなって思える事がある。

Access DBを使うほうがいい場合と、もう面倒だ、SQL Server を立ててしまえって場合がある。個人的に作っているアプリなら、どちらでもいいとは思うのだが、メンテナンス性を考慮すると、常に参照できる状態になっているDBが好ましい。個人で使うプログラムならなおさらだ。気分で、DB構造を変えたりする事が多い。エラー処理が甘くても、使うのが自分と少数なら困る事は少ないだろう。そういう場合には、XML形式にして保存する事が多い。これなら、最悪手作業で修正できてしまう。

Windowsでももう少し手軽にDBが使えればなっと思う事がある。
手軽にというのは、セットアップの必要がなく(SQL Server や MySQL はこの時点で弾かれる)無料で使えて、参照に特別なプログラムが必要ない(Access がここで消える)。

LocalDBが一番近いのだけど、配布を考えると、少しだけ手間が増えてしまう。

SQLite になってくるのかな?
配布先で、追加インストールなしで、DBがいじられたりできたら最高なんだけどな。

2018/07/16

【覚書】Auth認証を作る

Twitter から UserStream API の廃止が行われていますが、リアルタイムにツイートを取得する必要性が少ないのか、それほどの混乱にはなっていない。

代替えはいろいろ出ていますがどうにも使い勝手が悪い。

そこまでリアルタイムにこだわりがあるわけではない。実際に、ツイートが、”2分”遅れたとして、何か困る事象になるのだろうか?
もし、それほどリアルタイムにこだわる必要があるサービスの提供を考えるのなら、Twitter という選択肢を選ばないだろう。確かに、不特定多数に同時に情報を発信するという概念から言えば、Twitter は優秀なプラットフォームだと思う。

話が横道にそれてしまったが、利用規約やAPI仕様変更の多さから毛嫌いされることが多い Twitter ですが、当然の事だと受け入れて、できることを、できる範囲で楽しめばいいと割り切っています。

APIの仕様から、1分に一回程度は、タイムラインの取得ができるのですから、これを安全に行う方法で考えればよい。

前置きが長くなったが、C#を使って、タイムラインとDMを取得して、ユーザに通知するためだけのサービスを作る。

  • 複数アカウントに対応する
  • 5分未満で新着が把握できる
  • タイムラインの取得を行って、自分以外の投稿を知らせる
  • タイムラインを取得して、コメントが付いたら知らせる
  • DMが届いたら知らせる

ぐらいかな?

あと、画像や動画があれば認識するくらいで大丈夫かな?

ツイートもできるだろうけど、今は必要ないかな。BOTとか作るのなら必須だろうけど、Windowsフォームアプリではあまり意味がなさそうだからな。

まずは、認証部分を作ろう。
C#には、CoreTweet という強力なパッケージが用意されている。NuGet で取得しておく。

Twitterアプリのためのキーの取得は、https://apps.twitter.com/ で行っておく。電話番号認証されていないアカウントでは作成できない。

フォームアプリを作成して、メインとなる部分

        private CoreTweet.OAuth.OAuthSession session { get; set; }

を宣言する。

適当に、ボタンを二つと、テキストボックスを一つを配置して、一つのボタンを”認証”とした。そこに、

            session = CoreTweet.OAuth.Authorize(Properties.Resources.ConsumerKey, Properties.Resources.ConsumerSecret);
            var url = session.AuthorizeUri; // -> user open in browser
            frmPin mPin = new frmPin(url.ToString());
            mPin.Show();
とでも、書いておこう。
アプリキーの設定を行って、認証用のURLを取得した。

それをあらかじめ作っておいた、Webブラウザだけを張り付けたフォームに渡して起動する。単純に Shell に取得してきたURLを渡してもよいが、デフォルトブラウザで起動するのが美しくないので、別枠にした。デフォルトブラウザでは、Twitter を広げているのだろう。そうなると、ログイン状態を維持した状態にできなくなってします。

今回は、PIN の入力にしたが、ASP.NET や PHP が使えるサーバがあるのなら、認証をそっちに投げてしまって、キーだけ取得したり、コールバックを受け付ける仕組みにしてもよいとは思う。

個人的には、そのほうが美しいとは思うが、認証を行うという機能充足を考えると、PIN入力でも十分だと思われる。

PINの入力をテキストボックスに行わせた後(自分で作って、自分で使うので、エラーや細かい操作性を無視している。客に渡したり、不特定多数に使わせるのなら、PINではなく、コールバックのほうがいいのは当然である。そうなると、URLの取得から、サイト側で行う必要があり、面倒になってしまった)を、もう一つのボタンで処理を行う。

            string strPin = txtPin.Text;
            //
            var tokens = CoreTweet.OAuth.GetTokens(session, strPin);
            //
            txtAccessToken.Text = tokens.AccessToken.ToString();
            txtAccessSecret.Text = tokens.AccessTokenSecret.ToString();
別途フォームに張り付けていた、二つのテキストボックスに取得してきたトークンを張り付けているが、当然これからも永続的に使うのなら、DBに入れるなりする必要がある。
私は、今後の事も考えて、設定用のXMLでも作ろうかと思っている。
認証はこれで終わり。
あとは、取得したトークンを利用するのだが、続きはまた気になって作ったときにでも・・・
広告

2018/07/15

【覚書】PHPで、Agent判定

使いどころがそれほどあるとは思えませんが、機種判定を行って、分岐を作りたい時に必要になってきます。

JavaScript とかで判断するほうがスマートな気がしますが、あえて、PHP で判定を行っています。転送量を少しでも減らせればいいかなっと思ってみたりしています。

		public function checkMobile()
		{
			$bRet = false;
			$ua=$_SERVER['HTTP_USER_AGENT'];
			if( (strpos($ua,’iPhone’) !== false)
			 || (strpos($ua,’iPod’) !== false)
			 || (strpos($ua,’Android’) !== false))
			{
				$bRet = true;
			}
			//
			return $bRet;
		}

処理は簡単です。

HTTP_USER_AGENT を取得して、その中に、分岐させたい物を判断すればいいのです。
関数にして少しでも使い勝手を良くしようかと思っています。

多分、もっといい方法は山のようにあると思いますが、古いプログラマには、可読性をあげる事を優先してしまう癖があります。

2018/07/13

【開発メモ】WordPress で、Amazon 商品を入れ込む

いろいろなプラグインが出ていますが、いまいち使い勝手が悪い。使い勝手が悪いのではなく、ぴんと来ないが正解なのだろう。

検索で出てくる、AmazonJS は確かに便利ですが、ブラウザによっては、ブラック画面になるだけで、組み込みができない。古いブラウザで実行すれば、入力画面が出ることから、私の環境の責任なのだろうと利用をあきらめることにする。
バージョンアップがされれば使えるようにはなるとは思うが、それまで Amazon の商品紹介(アフィリエイト)をどうしようかと考えた。

Amazon のアソシエイトには、ウィジェットを作られるものが存在している。

この画面ですが、売り上げもなく、アソシエイトを確認していなかった自分が悪いのですが、これは使える!

中を見ると、それほど複雑なことをしているわけではない様です。

貼り付けるだけで、ウィジェットが表示されるようになります。
デザインに関しても、Amazon 由来のものですが、まぁ個人で使うには十分だと思う。

そこで、これを使って、ショートコードを作ってみることにした。

WordPress のショートコードは、それほど難しい物ではない。

function.php に、function を作成して、「add_shortcode」すればいいだけだ。
慣れないと、表示ができなくなったりするので、本当は、プラグインとかにしたほうがいいとは思うけど、そこまで大げさにはしたくない。気が向いたら、作り変えるかもしれないけど、ショートコードで実装しておけばいい。

php に慣れた人なら難しくはないと思う。

一癖あるのは、ショートコードに引数を渡すところだと思う。

function setAmazonAssociate($args)
{
	extract(shortcode_atts(array(
		'scode' => '',
		'isbn' => '',
	), $args));
	$sword = '';
	if( $scode === 'ISBN' )
	{
		$sword = 'ISBN '. $isbn;
	}
	else
	{
		$sword = $scode;
	}
	$tid = 'netlaborat-22';

	$strRet = '<script type="text/javascript">amzn_assoc_ad_type ="responsive_search_widget"; amzn_assoc_tracking_id ="'.$tid.'"; amzn_assoc_marketplace ="amazon"; amzn_assoc_region ="JP"; amzn_assoc_placement =""; amzn_assoc_search_type = "search_widget";amzn_assoc_width ="auto"; amzn_assoc_height ="auto"; amzn_assoc_default_search_category =""; amzn_assoc_default_search_key ="'.$sword.'";amzn_assoc_theme ="light"; amzn_assoc_bg_color ="FFFFFF"; </script><script src="//z-fe.amazon-adsystem.com/widgets/q?ServiceVersion=20070822&Operation=GetScript&ID=OneJS&WS=1&Marketplace=JP"></script>';

	return $strRet;
}
add_shortcode('AmazonAssociate', 'setAmazonAssociate');

これで、ショートコードの準備ができた。

万が一、ご自分で利用される場合には、$tid の値は、ご自分のトラッキングIDに変更してください。
このまま利用してもいいのですが、私のトラッキングIDになってしまい。売り上げがご自分のところに来なくなります。

あとは、商品を入れていくだけでよい。

[AmazonAssociate scode='ISBN' isbn='9784865543070']

とすれば、黒の召喚士6が表示される。

もう少しパラメータとかエラーチェックとか本来なら作ったほうがいいのはわかっているけど、自分が使うだけなら、これで十分だと思う。
思う事にしておく。

2018/07/10

【開発メモ】Windowsフォームアプリで、タスクリストを作成する

前回の「Windowsフォームで、タスクバーにプログレスを表示」を使って、タスクリストを作成してみます。

使い道としては、あまりないかもしれませんが、タスクバーに、アイコンを登録している時には、少しだけ便利になります。

準備として、プログラムを、ファイルを渡されたり/引数でプログラムが処理を行うように作成します(別記予定)。

面倒なので、クラスを作成します。


public class CJumpItem
{
// タスク以外のカテゴリ
public string CustomCategory { get; set; }
// タスクに乗せるタイトル
public string Title { get; set; }
// タスクにマウスを合わせた時のTip
public string Description { get; set; }
// アプリケーションに渡す引数
public string Arguments { get; set; }
// 起動パス(別アプリでもOK)
public string ApplicationPath { get; set; }
// 表示するアイコンが内封されているEXE/DLLのパス
public string IconResourcePath { get; set; }
// 起動時の実行フォルダ
public string WorkingDirectory { get; set; }
// アイコン番号
public int IconResourceIndex { get; set; }
//
public CJumpItem()
{
CustomCategory = "";
Title = "";
Description = "";
Arguments = "";
ApplicationPath = "";
IconResourcePath = "";
IconResourceIndex = 0;
WorkingDirectory = "";
}
}

クラスの内容は、コメントを見てください。
それ以上の説明はないです。
適当な場所に、このクラスを記述して、次のメソッドを実装します。


public static void setJumpList(bool bShowRecentCategory, bool bShowFrequentCategory, CJumpItem[] mJumpItems)
{
JumpList jumpList = new JumpList();
foreach (CJumpItem item in mJumpItems)
{
JumpTask task = new JumpTask();
//
task.Title = item.Title;
if (item.CustomCategory != "")
{
task.CustomCategory = item.CustomCategory;
}
if (item.ApplicationPath != "")
{
task.ApplicationPath = item.ApplicationPath;
}
if (item.Arguments != "")
{
task.Arguments = item.Arguments;
}
if (item.Description != "")
{
task.Description = item.Description;
}
if (item.IconResourcePath != "")
{
task.IconResourcePath = item.IconResourcePath;
task.IconResourceIndex = item.IconResourceIndex;
}
if (item.WorkingDirectory != "")
{
task.WorkingDirectory = item.WorkingDirectory;
}
//
jumpList.JumpItems.Add(task);
}
jumpList.ShowRecentCategory = bShowRecentCategory;
jumpList.ShowFrequentCategory = bShowFrequentCategory;
jumpList.Apply();
}

記述場所なんかを気にしてくれれば”多分”動作します。

あとは、これを呼び出すために必要な、CJumpItem[] mJumpItems を生成するだけです。

System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(strSearchPath);
IEnumerable<System.IO.FileInfo> files = di.EnumerateFiles(“*.*”, System.IO.SearchOption.AllDirectories);
foreach (System.IO.FileInfo f in files)
{
CJumpItem jump = new CJumpItem();
jump.Arguments = f.FullName;
jump.Title = f.FullName;
jump.Description = f.LastWriteTime.ToString(“yyyy/MM/dd HH:mm”) + ” 保存”;
int iPos;
if (jumpItems == null)
{
iPos = 0;
}
else
{
iPos = jumpItems.Length;
}
Array.Resize(ref jumpItems, iPos + 1);
jumpItems[iPos] = jump;
}

こんな感じで、strSearchPath に指定された、Folderにあるファイルを並べて表示するようにしています。この辺りは、好みで変更してください。

広告

2018/06/13

【開発メモ】 Windowsフォームで、タスクバーにプログレスを表示

元ネタ:WPF/Windowsフォーム:タスクバーのアイコンに進捗表示を出すには?[C#、VB]

VS2015で行った時に、NuGet での参照に差異が出てくる。

Windows API Code Packで検索を行うと、沢山出てくる

利用には、WindowsAPICodePack-ShellExtensions をインストールしたら、必要な物が全部セットアップされた。

後は、記事通りでうまく動かすことができる。

// プログレスインジケーターを緑色にする
TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.Normal);
// プログレスインジケーターの進捗割合を30%にする
TaskbarManager.Instance.SetProgressValue(30, 100);

を記述するだけだ。あとは、好きに料理すればいい。

終わらせるのは、

TaskbarManager.Instance.SetProgressState(TaskbarProgressBarState.NoProgress);

で、OKになる。

他にも、見ていると、面白そうなメソッドが用意されているので、使ってみるといいかもしれない。

1 2