2019/09/06

Windows10 1903 アップデートで Cortanaが暴走でスタートから検索不能 → レジストリとファイヤウォール設定

Windows10 1903 アップデートで Cortanaが暴走+スタートメニューの検索からアプリが検索できなくなった

bingSearchを停止してると Cortanaが暴走するので、有効に戻す。さらに検索されたくなければファイヤウォールでブロックしてちょ な事が書いてあったので実行したらフツーに戻ったメモ

レジストリの変更
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Search の
BingSearchEnabled を 1 (有効)へ変更

PCを再起動するか、タスクマネージャから Cortanaを強制終了して、スタートメニューの検索から検索ができるようになる

ファイヤウォールの設定(Cortanaをブロック)
ファイヤウォールの詳細設定から、「送信の規則」にある Cortana(複数ある場合は全て) の接続をブロック


Delphi 最大化MDI子フォームを切り替えると呼び出される OnResizeイベント

Delphi の古いソースコードの修正中に気づいた(最新では変わっているかも)
MDI子フォームを最大化した状態で、子フォームを切り替えると OnResizeイベントが2回呼び出される

最大化したMDI子フォームをAからBへ切り替えると
  1. フォームAが wsMaximized から wsNormal へ切り替わり OnResizeイベント発生
  2. フォームBが wsNormal から wsMaximized へ切り替わり OnResizeイベント発生
と2回呼び出される
つまり、背後に回ったフォームは、ノーマルサイズへ戻されているという事になる

今回、背後に回ったフォームのリサイズイベントは無視したいという条件があったので
MDIに wsMaximized が存在するかをチェックして、1. のイベントをスキップさせるという方法で対応

procedure TMdiChildForm.FormResize(Sender: TObject);
var I: Integer;
    MaxFormExists: Boolean;
begin
    // MDI Form に MAXが存在するかどうかを確認
    MaxFormExists := False;
    for I := MdiMainForm.MDIChildCount - 1 downto 0 do begin
        MaxFormExists := MaxFormExists or (MdiMainForm.MDIChildren[I].WindowState = wsMaximized);
    end;

    if (not MaxFormExists) or (WindowState = wsMaximized) then begin
        // resize func;
    end;
end;
上記の場合、最大化を解除した時のリサイズイベントがアクティブな子フォーム以外発生しないので注意が必要となる(アクティブな子フォーム以外は、すでに最大化ではないため)

2019/08/27

Evernote Developer で API Key 取得時の Usernameとは

久々に API Key を取得しようとして、Evernote Username へ何を入れるか迷ったのでメモ


Evernote Username は、生成される Consumer Key となるようです

2019/08/22

Evernote OAuth の Access Token 取得で 401

Evernote の OAuth にて Access Token 取得時にコード401でハマったのでメモ
基本的に Evernote の OAuth手順 どおりの key=value をポストするが oauth_token_secret の扱いについて


1. Generate a Temporary Token のレスポンスで得られる oauth_token_secret の値を保存しておく
上記のリクエスト時は、token_secret は未定義なので oauth_signature の生成時のキーは "consumer_secret&"

3. Retrieve Access Token のリクエスト時
1で保存しておいた oauth_token_secret の値を用いて oauth_signature を生成するので、キーは、"consumer_secret&token_secret" である


つまり、アクセストークンを生成するために保存が必要なレスポンス項目は
1. Generate a Temporary Token  === oauth_token, oauth_token_secret
2. Request User Authorization === oauth_verifier
となる

2019/08/21

Visual Studio 2019 + Npgsql4.09 で配布が必要だったDLL

PostgreSQLへ接続が必要な事案があり、昔使用した Npgsql3.0x系から、現行の Npgsql4.09 へ変更したら、配布するDLLファイルの数が増えた

Npgsql4.09 の Visual Studio 2019 への追加は、こちらが参考になりました

NuGet のパッケージマネージャコンソールから、ここで記載されている Install-Package コマンドを入力
(VSアップデート後にインストールすると、エラーなくインストールできた)

んで、配布に必要だったDLLの一覧
(フツーにビルドすると実行ファイルの場所にコピーされます)

Npgsql.dll
System.Buffers.dll
System.Memory.dll
System.Numerics.Vectors.dll
System.Runtime.CompilerServices.Unsafe.dll
System.Threading.Tasks.Extensions.dll
System.ValueTuple.dll


2019/07/31

ソフトポーズ(自動ポーズ)のないガラホでソフトポーズを利用する方法

一定時間経過後にプッシュ信号を自動出力するソフトポーズ(,)
一部のガラホでは、電話帳登録時にメニューにポーズ(;)しか表示されず、登録ができない

現在のガラホの多くは、Androidなためソフトポーズ自体は標準で搭載しているらしく、リンクやQRコードから取り込んだソフトポーズは動作する機種がある - 京セラ KYF34 で確認

KYF34 後継機種の KYF37, KYF39 には電話帳登録時にメニューからソフトポーズ(自動ポーズ)を選択可能

表計算でカレンダーの開始日を取得

表計算でカレンダーの開始日を取得して、容易にカレンダーを作成

ExcelやGoogleスプレッドシートの場合 Weekday関数を利用して、第1日目の曜日を取得(日0~土6)して、差分を求めれば、カレンダー先頭の日付が確定

後は +1すれば一日加算されるのでカレンダーを埋めてやって、表示形式で日付だけを表示させる


Month関数でタイトルと同じ月かどうかを判断して、条件付き書式で背景色を変えることも可能

2019/07/30

Intel ネットワークドライバのインストールで、アップグレードをサポートしていません

オンボードもインテル製ネットワーク、PCIへ追加したネットワークカードもインテル製のマシンにて、オンボードのドライバをインストールさせて認識済み

ここで、PCIへ追加したネットワークカードのドライバをインストールしようとすると

インテル(R) ネットワーク・コネクション のInstaller 情報
インストールされているインテル(R) ネットワーク・コネクションはアップグレードをサポートしていません。このバージョンをインストールする前に、現在インストールされているバージョンをアンインストールしてください。
のメッセージが出て、インストールできない
先に入れたオンボード用のドライバを見つけて、アップグレードできないぜ、と言っているらしい

上記で OK を押して、インストールプログラムを終了させてしまうと、Tempディレクトリへ展開されたドライバが消されてしまうので、上記ウィンドウを閉じない(閉じたら、もう一度起動して)

Explorer でアドレスに %temp% と入力して、Tempディレクトリを開いて、ドライバの展開されたディレクトリを探す(今回は %temp%\1\RarSFX0\配下にあり)

デバイスマネージャーから、目的のネットワークカードのドライバ更新で、上のドライバが入ったディレクトリを指定してインストールすればよい
(インストール完了後、インテルのプログラムでOKを押せば、Temp内の一時ファイルは消されます)

2019/07/26

Delphi で String を HMAC-SHA1

Delphi で String を HMAC-SHA1 + Base64

uses へ IdCoderMIME, IdHMACSHA1 を追加して
function HMAC_SHA1_Str(S, Key: string): string;
var
    HmacSha: TIdHMACSHA1;
    Hash: TidBytes;
    Base64: TIdEncoderMIME;
begin
    HmacSha := TIdHMACSHA1.Create;
    Base64 := TIdEncoderMIME.Create;
    try
        HmacSha.Key := TIdBytes(TEncoding.UTF8.GetBytes(Key));
        Hash := HmacSha.HashValue(TIdBytes(TEncoding.UTF8.GetBytes(S)));

        Result := Base64.EncodeBytes(Hash);
    finally
        Base64.Free;
        HmacSha.Free;
    end;
end;

2019/07/25

Tasker 5.8 で HTTP Request の警告が通知される

Tasker 5.8 で HTTP(HTTPS) Get, Post, Head アクションを利用すると、警告の通知が表示される

HTTP Get, Post, Head アクションは、非推奨(廃止予定)になったので「HTTP Request」アクションを利用してください(HTTP Auth アクションも見てね)

との事
ひとまずは、STOP REMINDING で警告は停止でき、非推奨の HTTP(HTTPS) Get, Post, Head アクションも実行可能です

2019/07/19

phpでPEARを使わずに受信メールをデコード

php でメール内容を取得しようと思うと PEAR利用が一般的だが、ヘッダのみをフィルタにかけたり、テキストメールだけを処理したい場合の簡単デコード
  • マルチパートには対応してません
  • エンコードは、ISO-2022-JP(SJIS)とUTF-8メールのみ(必要なら追記して)
<?php

// データ取得
$data = file_get_contents('example.eml'); // ファイルから
// $data = file_get_contents("php://stdin"); // 標準入力から

// ヘッダと本文を分離(空行で)
if( ($i = strpos($data, "\n\n")) !== false ){ 
 $header = substr($data, 0, $i);
 $body = substr($data, $i + 2);
}else{
 $header = $data;
 $body = '';
}

// ヘッダデコード
if( ($headerArray = iconv_mime_decode_headers($header)) !== false ){
  print_r($headerArray);
}

// 本文デコード
if( array_key_exists('Content-Type', $headerArray) && (strpos($headerArray['Content-Type'], 'ISO-2022-JP') !== false) ){
 $body = mb_convert_encoding($body, 'SJIS', 'ISO-2022-JP');
 $body = mb_convert_encoding($body, 'UTF-8', 'SJIS');
}
print_r($body);

?>

2019/07/13

ドコモ ファミリー割引のグループ回線を確認

新規にファミ割グループを追加(子回線)した後、どこかで確認できないかと探し回ったメモ

マイドコモから

  • 主回線のマイドコモ料金確認から前月末時点での対象回線は確認可能
  • 設定後、料金確定までの対象回線は確認不可能 → 151 で確認しかなさそう

前月までの明細のお知らせ項目に記載されている

2019/07/03

PydioSync でログイン認証に失敗する

PydioSync で Authentication failed: please verify your login and password のメッセージが出てログイン認証に失敗してしまう


pydio 設置ディレクトリ(サーバ側)にある、 .htaccess を開いて
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
の行のコメントアウトを外して保存


#Following lines seem to be necessary if PHP is working
#with apache as CGI or FCGI. Just remove the #
#See http://doc.tiki.org/WebDAV#Note_about_Apache_with_PHP_as_fcgi_or_cgi
#RewriteCond %{HTTP:Authorization} ^(.*)
#RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
#Following lines may be necessary for a PHP-FPM setup
# to make sure that authorization is transmitted.
# Just remove the # at the beginning of the line
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1


上記変更でログインできるようになったものの、サーバ側の変更がローカルに反映されないんだけど...
ローカル→サーバはOK

2019/07/02

古いphpバージョンに固定した、さくらレンタルサーバへ pydio8 を php7.3 で動作させる

古いphpバージョンに固定された、さくらレンタルサーバで pydio8 をインストールして php7.3 で動作させた時のメモ

フツーにインストールするのはこちら

pydio8 をダウンロード(php7.2の修正を含む版)および設置
ここからは /home/USER/www/pydio8 をインストールディレクトリとして話を進めます

インストールディレクトリへ
session 保存ディレクトリを作成
ssh 等から $ mkdir _sessions とか

.user.ini を作成
post_max_size = 1024M
upload_max_filesize = 1024M
session.save_path="/home/USER/www/pydio8/_sessions" ←上で作成したディレクトリ

php.cgi を作成(利用したい php バージョンを指定)
#!/bin/sh
exec /usr/local/php/7.3/bin/php-cgi

.htaccess へ下記を追記
Action myphp-script /pydio8/php.cgi
AddHandler myphp-script .php .html
※ここで指定する php.cgi のパスはフルパスではなく Webで開くURLのパス部分になります

言語指定(日本語環境で利用する場合)
/home/USER/www/pydio8/conf/bootstrap_conf.php に
define("AJXP_LOCALE", "ja_JP.UTF-8");
を記述
//define("AJXP_LOCALE", ""); の下辺りへ

DBの作成
さくらのコントロールパネルから、新規作成(host, user, pass をメモっておく)

index ファイル設定変更
さくらのコントロールパネル → ファイルマネージャーから
/pydio8/ の アクセス設定で index.php を開くようにする

ここまでで下準備完了

Web から /pydio8/ へ接続して、admin ユーザーやDBを設定

完了したところで Permission エラーが出る → .htaccess が書き換えられているので
書きをもう一度行う

.htaccess へ下記を追記
Action myphp-script /pydio8/php.cgi
AddHandler myphp-script .php .html

index ファイル設定変更
さくらのコントロールパネル → ファイルマネージャーから
/pydio8/ の アクセス設定で index.php を開くようにする

2019/06/28

samba で別ユーザーのホームディレクトリへアクセス

smb で別ユーザーのホームディレクトリへアクセス

userA のホームディレクトリへ、userB や userC でも smbでアクセスする例

/etc/samba/smb.conf
[FolderName]
        path = /home/userA
        browsable = No
        read only = No
        writable = Yes
        valid users = userB, userC
        force user = userA

2019/06/18

ZTE blade e01 / freetel priori3 でシステムアップデートが暴走してデータ通信過多

ZTE blade e01 / freetel priori3 でシステムアップデートが暴走してデータ通信異常に行われているとか

ココココに対応方法が書いてあるけど、ホンマかいな、って内容

  1. 電源オフ
  2. SIMカードを抜いて、再度差し込む
  3. 電源オン
  4. 機内モードにする
  5. Wi-FiをONにする
  6. 機内モード解除

「開発者向けオプション」から「自動システムアップデート」をオフや
「アプリ」から更新プログラムを無効にする
ではダメなんだろうか

2019/06/13

RTV700 で ISDNの発信者番号を設定

ヤマハ RTV700 で ISDN の発信者番号を設定
isdn local address コマンドを使うが、この時のインターフェイス名は nt-bri1 等

isdn local address nt-bri1 03xxxxxxxx

2019/05/31

Adhell で利用可能な Knox キーが発行できなくなった

2019年4月頃から、Adhell で利用可能なキーが発行できない状態

キーがまだ有効な方は、Adhell から KLMS Agent (com.samsung.klmsagent) を無効にしておくことで、キーの有効期限が切れた後も、初期化等を行わなければ引き続き Adhell が利用可能

有効期限が切れた状態で Adhell を起動してしまうと Adhellの機能が無効となってしまいます



同様の機能がある Package Disabler Pro には一覧に上記が表示されませんので、KLMS Agent を無効化できません
adb から com.samsung.klmsagent の無効化が成功するかどうかは不明です

2019/05/22

Python の引数デフォルト値に計算式入れて失敗

引数に時間を入れなければ現在の時間、と思って下記のような関数を書いて失敗

def addFile(s, nowTime = datetime.datetime.now()):
この場合、最初の関数生成時にデフォルト値が生成されるそうで、ずっと最初に呼び出した値(時刻)が使われ続けた

None等で対応するそうです
def addFile(s, nowTime = None): if nowTime is None: nowTime = datetime.datetime.now()


samba で認証なしのディレクトリを作成

sambaで認証なしのディレクトリ作成メモ

[global]セクションで security = user となっているとユーザー認証ありき、しかし認証かけてるディレクトリはいじりたくないので、 map to guest = bad user を追加して、登録されてないユーザは guest扱いとする

今回対象の [test] セクションで guest ok = Yes として、書き込み可能等それ以外の項目を設定する(下の例では、書き込みは禁止)

/etc/samba/smb.conf
[global]
        workgroup = WORKGROUP
        netbios name = TestSrv
        server string = Samba server version %v

        security = user
        passdb backend = tdbsam

        printing = cups
        printcap name = cups
        load printers = yes
        cups options = raw

        map to guest = bad user

#       map untrusted to domain = Yes

[test]
        path = /opt/test
        browsable = Yes
        read only = Yes
        writable = No
        guest ok = Yes


2019/05/16

Visual Studio 2019 で MFC アプリをビルドで afxwin.h が見つかりません

Visual Studio 2019 で MFC アプリをビルドで afxwin.h が見つかりません

Visual Studio Installer から Visual Studio 2019 に入り、C++によるデスクトップ...
「ビルドツール用 MFCほにゃほにゃ」にチェックを入れてインストールする(+1GB程度)

2019/05/09

Reply-To ヘッダ書き換えによるメール詐欺の仕組み

Reply-To ヘッダを偽ドメインへ書き換えたメールによる詐欺の仕組み
以下の手法で、メール内容を書き換えられ請求と共に振込先が変わったということで詐欺にあったという報告
互いに相手に返信していたと思われたが、似たドメインの犯人へ返信し、犯人はそれを書き換えて相手へ送っていた
最初の偽装がメール漏れによるものか、全くの新規から始まったものかは調査中

2019/04/26

Explorer でフォルダを開いてファイルを選択(既に開かれている場合は再利用) - Delphi

Windows Explorer でフォルダを開いてファイルを選択、これは通常の explorer.exe /select, オプションで実現可能ですが、既にフォルダが開かれている場合、そっちを再利用したい

参考文献

uses 節に FileCtrl, ShlObj, ActiveX が無ければ追加
function OpenFolderAndSelectFile(FileName: string): boolean;
var
    DidInitCOM: boolean;
    IIDL: PItemIDList;
    TheValue: HResult;
begin
    Result := False;
    DidInitCOM := False;
    try
        IIDL := ILCreateFromPath(PChar(FileName));
        if (IIDL <> nil) then
            try
                TheValue := SHOpenFolderAndSelectItems(IIDL, 0, Nil, 0);
                If TheValue <> S_OK then begin
                    If TheValue = $800401F0 then begin
                        DidInitCOM := Succeeded(CoInitialize(nil));
                        if DidInitCOM then
                            TheValue := SHOpenFolderAndSelectItems(IIDL, 0, nil, 0);
                    end;
                end;
                Result := (TheValue = S_OK);
            finally
                ILFree(IIDL);
            end;
    finally
        if DidInitCOM then
            CoUninitialize;
    end;
end;

VoIP GW - ODトランク接続の結線とメーカー別(NEC, 日立, ナカヨ)端子名称

専用線等で使われるODトランクの結線と共にメーカー(NEC, 日立, ナカヨ)ごとに名称がバラバラなのでまとめてみた

VoIP GWへRJ45(A結線)接続した場合のPBX側端子名称
PBX側VoIP GW側
日立ナカヨNECRJ45信号NECナカヨ日立
SSBBSB1(緑白)SGGSRB
SSASSM2(緑)ESRSRA
TBSL24WS(ring)3(橙白)4WR(ring)RL2RB
RBRL24WR(ring)4(青)4WS(ring)SL2TB
RARL14WR(tip)5(青白)4WS(tip)SL1TA
TASL14WS(tip)6(橙)4WS(tip)RL1RA
SRASRE7(茶白)MSSSSA
SRBGSG8(茶色)SBBSSB
※VoIP GW 側は、日立であれば NTシリーズ, NECであれば IP-Masterシリーズ等です
※アース起動の場合、PBXによってSSB-SRB間にジャンパーが必要です


一般的にPBX側はクイックコネクタですが、両端が RJ45の場合、SS ⇔ SR, R ⇔ S の上り下りが逆になるように接続

2019/04/19

Webフォームからの spam対策 - javascript

Webフォームからの広告入力対策

その1 - URL入力禁止
<script type="text/javascript">

 function checkUrl(form){
  for(var i=0; i < form.children.length; i++){
   if( form.children[i].nodeName.toUpperCase() === 'TEXTAREA' ){
    var urlCount = (form.children[i].value.match(/http(s)?:\/\//g)||[]).length;
    if( urlCount > 0 ){
     alert("テキストエリアにURLは記載できません");
     // form.children[i].value = '';
     return false;
    }
   }
  }
  return true;
 }

</script>
スクリプトを追加して、フォームのonsubmit へ checkUrl を記載
例) <form onsubmit="return checkUrl(this);">

その2 - コピペ禁止
<script type="text/javascript">

 window.onload = function(){
  document.body.onpaste = function(){
   alert("このページはペーストが禁止されています");
   return false;
  }
 }

</script>

2019/04/18

Google スプレッドシートの ImportXML関数に XPath をコピペしても #N/A になる原因

Google スプレッドシートで他サイトの情報を取得する(スクレイピングって言うの?)のに便利な ImportXML 関数

よくある解説には、
Chrome なら 右クリック→検証
取得したいエレメントで Copy → Copy XPath で得られた値の ダブルコーテーションをシングルに置き換えて、=ImportXML(url, xpath)
とやれば、ホラ簡単!
みたいなのがあるけど、ほとんど取得できねぇ~~~~~~~  #N/A

ということで原因と対策を調べてみた
ここでは、とあるサイトの値を取得するというよくあるパターン

最初に問題となるのは、取得するサイトの文字コードが UTF-8 ではない場合
これは、相手の問題なので今回はあきらめる

次に今回の本題 XPath の値がなぜ流用できないか、というか面倒なので流用したい
XPathは、主にソース固有の場所(id等は一意なので)からの相対パスとなる

該当部分のHTMLソース

ソースを見ると
div[id='cnt01']→div[の1番目]→table[の1番目]→tr[の2番目]→td
となっている

デベロッパーツールのエレメント構成

ここで得られる XPath の情報(コーテーションは変更済み)

//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]/td

このまま ImportXML へ貼り付けても そんなんありません(#N/A)となるが
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]/td
//*[@id='cnt01']/div[1]/table[1]/tbody/tr[2]
//*[@id='cnt01']/div[1]/table[1]/tbody
//*[@id='cnt01']/div[1]/table[1]
と上位へ変更してみると、突然表示されはじめるポイントがある
(もぅ、お気づきでしょう。というか画像に答え書いてあるけど)

デベロッパーツールで表示されるエレメントツリーは、ソースで省略されたタグを補完して正しい形にしたものです(こういうライブラリを用いて修正したりする)
したがって、上記例では tbody が補完されているため、そのまま XPath を利用しようとしても、そんなエレメントありませんとなるワケです

上記の例では tbody を取り去った下記の表記が答えとなります

//*[@id='cnt01']/div[1]/table[1]/tr[2]/td

つまり、ソースコードをベースに記述しなければならない ということです

2019/04/15

GOM Player 終了時のブラウザ広告を止める

GOM Player が終了時に既定のブラウザで広告を表示するようになった

レジストリを調べると広告を表示した時刻を Unixtime で記録して、この値が24時間以上(たぶん)古いと広告を出しているようなので、値を未来へ変更
※そのうち対策される可能性があります

レジストリの変更手順
  1. ファイル名を指定して実行(Win+R)で regedit を入力、レジストリエディタを起動
  2. \HKEY_CURRENT_USER\Software\GRETECH\GomPlayer を開く
  3. EndingBrowser の値を 10進数で 1735657200 (2025/1/1)等の未来に設定


2019/04/12

Python のキーワード引数へ変数を使う

Python のキーワード引数へ変数を使いたい
→ 辞書(dict)を利用して、連想配列のような形で渡す

def main(): option1 = 100 option2 = 200 options = {'opt1': option1, 'opt2': option1} test('Test', **options) # や test('Test', **{'opt1': option1, 'opt2': option2}) def test(s, *, opt1=1, opt2=2): print(s) print(opt1) print(opt2) print('')

Python3 でシリアルポートを使う

centos7 上で、Python3 でシリアルポートのモデム(実際はUSBポートに接続した Omron ME5614U2)へATコマンドを実行

デバイスの確認
/dev で ls
Omron ME5614U2 をUSBポートへ差し込んだら認識してました
/dev/ttyACM0 ←これ

pyserialのインストール
# pip install pyserial

python3コード
import serial ser = serial.Serial('/dev/ttyACM0', baudrate=9600, timeout=3) ser.write(b"AT\n") print(ser.read(16).decode(encoding='utf-8')) ser.close()
※python3からバイト列でやり取りするようになっているので、変換が必要です

引数の timeout は、read() で指定するサイズ(16byte)に到達しなくても、readが発生する時間(sec)です。read に貯まっているサイズを取得する inWaiting() を監視して、都度取得することも可能です。

2019/04/11

コンビニで貯められるポイントと還元率

コンビニで貯められるポイント(利用可能なポイントカード)と還元率 - 2019-04-11
楽天ポイントTポイントdポイントWAON
ポイント
WAON
POINT
Pontananaco
セブン-イレブン------1.00%
ファミリーマート0.5%0.5%0.5%----
ローソン--1.0%--1.0%-
ミニストップ---0.70%0.5%--
サークルKサンクス1.0%------
ポプラ1.0%------
スリーエイト1.0%------
色→要決済2019/11以降
※レシートポイント、クレジットカード一体型やポイントアップ制度によるポイントアップ等は反映してません

私は、ポイントが貯まったと実感するほどコンビニで買物しないのですが、いずれも切り捨てのため、0.5%は200円未満, 1.0%は100円未満では購買によるポイントがそもそも付与されなかったりします。
したがって、1%還元の店で 10万円使っても 1,000ポイント貯まる可能性は限りなく低くなります。
クレジットカード決済のポイントとあわせるとか、他で貯まったポイントを利用できるという意味ならあるかもしれませんが...

2019/04/09

Amazon Prime から Twitch Prime を有効にできない【解決】

大変申し訳ありませんが、お客様のアカウントで Twitch Primeを有効にできません。
Twitchプライムを有効にしている間にエラーが発生ししたようです。
一般的な問題には、クレジットカードが無効か拒否されている可能性がある場合に、プライムのサインアップに使用されるクレジットカードに関する問題などがあります。 クレジットカード情報の更新を含め、お客様のプライムメンバーシップを管理するには、ここをクリックしてください。 他の一般的な問題については、ここをクリックしてください。

紐づけの手順

  1. Amazon Prime 会員になる
  2. Twitch で会員登録する(この時点では無料会員)
  3. ブラウザをプライベートモードで起動
  4. Amazon へサインイン
  5. Twitch へサインイン Twitch Prime を試すから 日本を選択する
  6. 紐づけする Amazonアカウントの確認 → Twitch Prime へ

確認と試したこと

  • Amazon.com (米国の)のアカウントがあれば、Amazon.co.jp とメールアドレスを別にする(Amazon Echo で日本語に反応しないときも同じ)
  • ブラウザのプライベートモードを利用して紐づけを行う
  • Amazon Prime の支払い方法が登録されている
  • Amazon Prime の支払い方法に登録された手段で、少なくとも1度は決済を行っている ← 今回コレがひっかかっていた

私の場合、Amazon Prime 支払の後、クレジットカード更新があり、支払い方法を一旦削除して再登録していた(同じカードを延長すれば問題なかった)ので、Amazon Prime の支払い方法が登録されていない状態だった。そして、Amazon Prime の支払い方法を登録したものの、決済を一度も行っていなかったため、Twitch Prime との紐づけが有効にならなかったらしい。
Amazon Prime へ登録されている支払い方法で買い物をした翌日、紐づけて続きを行ったら、問題なく Twitch Prim へ登録が完了した。



コールバックから Delphi VCLのCaptionを変更すると文字列などが乱れる

コールバックから呼ばれる関数内で、VCL(今回は Label )のCaptionを変更すると、表示が乱れる(フォントサイズや幅がおかしくなる)

スレッド内と同様に Synchronize 内からVCLへアクセスする
    TThread.Synchronize(nil,
        procedure
        begin
                Label1.Caption := AFilename;
        end);

2019/03/26

cloudatcost IPアドレスの Update を行う(centos7編)

気がついたら cloudatcost のコンパネにIPアドレス変更(2019-2-22までにやっとけよ)のボタン
 
とっくに過ぎてるというか、接続不能になって気づいたわけですが...
ということで Update 手順

【注意】IPv4を変更すると、アドレスおよびゲートウェイ、アプリケーションが利用するリッスンIP/ポートを設定し直すまで、ネットワークが利用不能になります

コンパネから
  1. 対象サーバの  コンソール (右上の)が利用可能なのを確認
  2. IPv4:  Update ボタンを押して、確認画面で Continue を押す
    IPv4: Pending Migration... となる
  3. しばらくすると(3~15min)、新しいIPアドレスが IPv4: のところに表示される

コンパネのWebコンソールからログイン
Centos7 の場合、下記のように nmcli コマンドを利用して変更を行う

デバイスとコネクションを確認
# nmcli d

DEVICE  TYPE      STATE      CONNECTION
ens33   ethernet  connected  System eth0
lo      loopback  unmanaged  --     

新しいIPを設定
# nmcli c modify "System eth0" ipv4.addresses xxx.xxx.xxx.xxx/24

ここで コネクション名(System eth0)へデバイス名(ens33)を指定したりすると
Error: unknown connection 'ens33'
のようなエラーとなる


新しいGWを設定
# nmcli c modify "System eth0" ipv4.gateway xxx.xxx.xxx.1

DNSを設定(必要であれば)
# nmcli c modify "System eth0" ipv4.dns 1.1.1.1

ネットワークを再起動して反映
# systemctl restart network

確認(デバイスを指定)
#nmcli d show ens33

※アプリケーションでリッスンアドレスなどへグローバルIPを設定しているところがあれば、それらも変更する

2019/03/12

VB6, VBA でレジストリから元号を取得

VB6, VBA でレジストリから元号(和暦情報)を配列で取り出す関数をベタなAPIのみで構成
format関数って、ee年 のように eの直後に年が続くと 1年ではなく元年と表記されるんですね~

得られる配列は今の所、下記の形
第1引数→012345
01868/01/01明治_明_Meiji_M明治MeijiM
11912/07/30大正_大_Taisho_T大正TaishoT
21926/12/25昭和_昭_Showa_S昭和ShowaS
31989/01/08平成_平_Heisei_H平成HeiseiH
第2引数↑

※古い順である保証はありません
※2019/3/13頃のOSアップデートで、レジストリの値が全角合成文字(㍻)から先頭文字(平)に変更されています

配列から取得
    Dim Gengo()
    Dim I As Long
    Dim S As String

    Gengo = GetGengoDimFromReg()
    For I = UBound(Gengo, 2) To 0 Step -1
        S = S & Gengo(0, I) & " = " & Gengo(1, I) & Chr(13) & Chr(10)
    Next I

    ' S
FormatJ関数
s = FormatJ(Now, "g gg ggg e ee yyyy-mm-dd hh:nn")


モジュール本体
Option Compare Database
Option Explicit

Private Declare Function RegOpenKeyEx Lib "ADVAPI32" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegCloseKey Lib "ADVAPI32" (ByVal hKey As Long) As Long
Private Declare Function RegQueryValueExstr Lib "ADVAPI32" Alias "RegQueryValueExA" (ByVal hKey&, ByVal lpValueName$, ByVal lpReserved&, ByVal lpType&, ByVal lpData$, lpcbData&) As Long
Private Declare Function RegEnumValue Lib "ADVAPI32" Alias "RegEnumValueA" (ByVal hKey As Long, ByVal dwIndex As Long, ByVal lpValueName As String, lpcbValueName As Long, ByVal lpReserved As Long, lpType As Long, ByVal lpData As String, lpcbData As Long) As Long

Private Const HKEY_LOCAL_MACHINE = &H80000002

Private Const ERROR_SUCCESS = 0

Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_ENUMERATE_SUB_KEYS = &H8

Private GengoDimCache()



Function FormatJ(ByVal iDate As Date, ByVal FormatStr As String)
    Dim refGengo() As String
    Dim refWareki As Long

    If DateToWareki(iDate, refGengo, refWareki) Then
        FormatStr = Replace(FormatStr, "ggg", """" & refGengo(2) & """") ' 平成
        FormatStr = Replace(FormatStr, "gg", """" & refGengo(3) & """")  ' 平
        FormatStr = Replace(FormatStr, "g", """" & refGengo(5) & """")   ' H
        
        If refWareki = 1 Then
            ' Format関数は eの後に年があると「元年」表示となる
            FormatStr = Replace(FormatStr, "ee年", """元年""")
            FormatStr = Replace(FormatStr, "ee\年", """元年""")
            FormatStr = Replace(FormatStr, "e年", """元年""")
            FormatStr = Replace(FormatStr, "e\年", """元年""")
        End If
        
        FormatStr = Replace(FormatStr, "ee", """" & Right("0" & Trim(Str(refWareki)), 2) & """")
        FormatStr = Replace(FormatStr, "e", """" & Trim(Str(refWareki)) & """")
    End If
    
    FormatJ = Format(iDate, FormatStr)
End Function



Function DateToWareki(ByVal iDate As Date, ByRef refGengo() As String, ByRef refWareki As Long) As Boolean
    Dim Gengo()
    Dim I As Long
    Dim J As Long
    Dim S As String
    Dim TempDate As Date

    DateToWareki = False
    
    Gengo = GetGengoDim()
    If Sgn(Gengo) <> 0 Then
        TempDate = 0
        For I = 0 To UBound(Gengo, 2)
            If (Gengo(0, I) > TempDate) And (iDate >= Gengo(0, I)) Then
                TempDate = Gengo(0, I)
            
                ReDim refGengo(UBound(Gengo, 1))
                For J = UBound(Gengo, 1) To 0 Step -1
                    refGengo(J) = Gengo(J, I)
                Next J
                refWareki = Year(iDate) - Year(Gengo(0, I)) + 1
                
                DateToWareki = True
            End If
        Next I
    End If
End Function



' レジストリから元号を取得して配列で返す
Function GetGengoDimFromReg()
    If Sgn(GengoDimCache) <> 0 Then
        GetGengoDimFromReg = GengoDimCache ' キャッシュ
        Exit Function
    End If


    Dim hKey As Long
    
    Dim dwIndex As Long
    Dim lpName As String
    Dim lpcbName As Long
    
    Dim lpType As Long
    Dim lpData As String
    Dim lpcbData As Long
    
    Dim lpValue As String
    Dim lpcbValue As Long
    
    Dim DimLen As Long
    Dim YMD() As String
    Dim Gengo() As String
    Dim Result()
    
    If (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\CurrentControlSet\Control\Nls\Calendars\Japanese\Eras", 0, KEY_QUERY_VALUE + KEY_ENUMERATE_SUB_KEYS, hKey) = ERROR_SUCCESS) Then
        
        dwIndex = 0
        Do
            lpType = 0
            lpcbName = 256
            lpName = String(lpcbName, Chr(0))
            
            lpcbData = 256
            lpData = String(lpcbData, Chr(0))
            
            ' エントリ取得
            If (RegEnumValue(hKey, dwIndex, lpName, lpcbName, 0, lpType, lpData, lpcbData) = ERROR_SUCCESS) Then
                lpName = Left(lpName, InStr(1, lpName, Chr(0)) - 1) ' "1989 01 08"
                
                ' データ取得
                lpcbValue = 256
                lpValue = String(lpcbValue, Chr(0))
                
                If (RegQueryValueExstr(hKey, lpName, 0, 0, lpValue, lpcbValue) = ERROR_SUCCESS) Then
                    lpValue = Left(lpValue, InStr(1, lpValue, Chr(0)) - 1) ' "平成_㍻_Heisei_H" winUpdate→ "平成_平_Heisei_H"
                    
                    ' 配列へ
                    If Sgn(Result) = 0 Then
                        ReDim Preserve Result(5, 0)
                    Else
                        ReDim Preserve Result(5, UBound(Result, 2) + 1)
                    End If
                    DimLen = UBound(Result, 2)
                    
                    YMD = Split(lpName, " ", 3) ' "1989 01 08"
                    Result(0, DimLen) = DateSerial(Int(YMD(0)), Int(YMD(1)), Int(YMD(2)))
                    
                    Result(1, DimLen) = lpValue   ' 平成_平_Heisei_H
                    Gengo = Split(lpValue, "_", 4)
                    Result(2, DimLen) = Gengo(0) ' 平成
                    Result(3, DimLen) = Gengo(1) ' 平
                    Result(4, DimLen) = Gengo(2) ' Heisei
                    Result(5, DimLen) = Gengo(3) ' H
                End If
                
                dwIndex = dwIndex + 1
            Else
                Exit Do
            
            End If
        
        Loop
        
        Call RegCloseKey(hKey)
    End If
    
    GengoDimCache = Result
    GetGengoDimFromReg = Result
End Function

2019/03/11

ネットボランチDDNSで正しいIPを得られない

2019-03-08 あたりから 8.8.8.8 や 1.1.1.1 を含む複数の DNSサーバへ定期的に問い合わせると、一つ前の IP が返ったり、現在の IPが返ったり不安定な状況が続いている

試しに netvolante.jp で指定されている NS

secondary.netvolante.jp
sby-daemon.netvolante.jp
act-daemon.netvolante.jp

へ問い合わせを行うと act-daemon.netvolante.jp のみ古いアドレスを返してくるので、この辺りに問題があるのかもしれません

2019/03/08

javascript の json で単純な配列の個数やデータの取り出し

javascript の json で単純な配列の個数やデータの取り出し

key : value 形式ではなく、単純な配列を JSON.parse した時に得られる object は、key に配列の添字(0~)が入った状態なので

個数は Object.keys(jsonObject).length で求められ、データの取り出しは
var json_users = JSON.parse('["osomatsu","kadomatsu","iyami"]');
for(var key in json_users){
 alert(key + '=' + json_users[key]);
}

var json_users = JSON.parse('["osomatsu","kadomatsu","iyami"]');
for(var i = Object.keys(json_users).length -1; i >= 0; i--){
 alert(i + '=' + json_users[i]);
}
な感じ

2019/03/05

python の socket の udp 送信でブロードキャストしようとするとエラーが発生する

python の socket の udp 送信で、ユニキャストでは動作するがブロードキャストしようとすると
PermissionError: [Errno 13] Permission denied
のエラーが発生する
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) # ←コレ
sock.sendto(message.encode(), (host, port))
socket.SO_BROADCAST オプションを追加する

2019/03/04

adhell3.1.1.x を Android Studio でビルド

【重要】Adhell で利用可能な Knox キーが発行できなくなりました




adhell3.1.1.x 系をビルドしたときのメモ 【2018-03-04更新】

前提条件
  • Android Studio がセットアップ・アップデートされている
  • https://seap.samsung.com/ の登録を済ませている(ライブラリのダウンロードとキー取得に必要)

  1. gitlab からソースをダウンロード・解凍
  2. knox android サイト から Knox SDK 3.3.x と supportlib.jar をダウンロードして
    ※3.1.1.259 は Knox SDK 3.3 (API level 28) の knoxsdk.jar を利用

    各 libs の knoxsdk.jar と supportlib.jar を ソースの app/libs(なければ作成) へコピー

    上記ライブラリは、頻繁にアップデートされているのでその都度ダウンロードがオススメです。「エラー: シンボルを見つけられません」という表示は上記ライブラリのバージョンが古い可能性があります
  3. パッケージ名を変更 → ファイル app/app.properties (なければテキストファイルを作成)へ下記の形式で記述
    package.name=com.example.adhell3_1_x_x ←他の人とバッティングしないような文字列
    Package Disabler を利用する場合は下記も同じファイルへ記述
    enable.disableApps=true
    enable.appComponent=true

  4. Android Studio でソース(のディレクトリ)を開く
    build sync 等、画面下のほうが落ち着くまで、しばらく待ちます
  5. Android Studio の Settings で Configure on demand のチェックを外す → 2018-11-19 現在 Android Studio 3.2.1 ではこの設定は無くなっているので不要です
  6. ビルド

  7. ビルドが完了すると右下に下記のようなのが出てapkが作成されるので、実機へ移してインストールする
    app/build/outputs/apk/debug/app-debug.apk ←ココ

adhell3.1.1.x の実行には 各 knox ライセンスキーが必要です

現在利用可能なキーは  ELMキー で adhell 3.1.1.265 以降で対応しています
※複数キーは生成できないのでキー取得前に revoke 可能なキーはすべて revokeしてから ELMキーを取得してください

キーには有効期限があり、期限をすぎると再度取得するか、期限前に削除→再生成します
サイトからキー削除後に端末を再起動すると、adhellからキー入力を促されます

2019/02/25

Dialogflow から webhook される php を Google API v2 に対応させる

Dialogflow から google api v2 に対応しろとのお知らせが表示されるので、webhook される php を Google API v2 に対応させる

命令の流れをおさらい
まずは、どういう仕組だったかを忘れていたのでメモ
アプリに入って、命令を行うと、Intent にある Action and parameters の値を含む json が


Fulfillment に指定した url へポストされるので、応答メッセージを含む json を返す

という仕組み

API の切り替え
google api v2 対応への切り替え(Dialogflow側)は、スイッチを切り替えるだけ


api 切り替え後の web 側変更
API を切り替えると、送られてくる json の内容が変わります。また、応答メッセージを埋め込む json の形式も変わります。なので「そのままだと アプリから応答がありません」みたいな形になります

api v1 で post される json


api v2 で post される json


php の場合
$data = file_get_contents("php://input"); // 取得
$jsonArray = json_decode($data, true); // json -> 配列

// v1 action取得
$action = $jsonArray["result"]["action"];

// v2 action取得
$action = $jsonArray["queryResult"]["action"];
な感じに取得位置を変更します

送られてきたアクションに対する応答は、こちらのような形で speech と displayText で返していたものを fulfillmentText というキーに変更します
※面倒なので v1 の応答に fulfillmentText を追加して対応したらうまく動きませんでした

端的に書くと
 // api v1 応答
 echo json_encode(array(
  "speech" => '応答メッセージ',
  "displayText" => '応答メッセージ'
 ));

 // api v2 応答
 echo json_encode(array(
  "fulfillmentText" => '応答メッセージ'
 ));
です