Quantcast
Channel: 北風研究室
Viewing all 93 articles
Browse latest View live

python で database クラスを作ってみる (修正版)

$
0
0

python で database クラスを作ってみる (Part 5) で作ったクラスでは、python3.6 では動かなかったので、少し改修して python3.6 で動作するようにしました。

動作確認下環境:
1)
CentOS Linux release 7.5
mysql Ver 15.1 Distrib 5.5.56-MariaDB
Python 2.7.5
Python 3.6.5

2)
CentOS release 6.10
mysql Ver 14.14 Distrib 5.1.73
Python 2.6.6
Python 3.6.5

Python の MySQL インターフェースに mysqlclient を使用します。

# pip install mysqlclient
# pip3.6 install mysqlclient

以前の SimpleDB クラスは、Python 3.6 でエラーになってしまうので手直ししたものを再掲します。

SimpleDBクラスのソース: simpledb.py
(ファイル名を simpledb.py_.txt から “simpledb.py” に変更してください。)


CentOS7 をPHP7.0 インストール

$
0
0

CentOS7 の PHP を PHP7.0 にしてたら、結構ハマってしまった。

結局、思考錯誤の結果、一度全部 PHP を削除:
# yum remove php*

そして、PHP7.0 を REMI リポジトリからインストール:
# yum install –enablerepo=remi,remi-php70 php php-devel php-mbstring php-pdo php-gd php-mysqlnd php-intl php-pear

インストールされたパッケージ:
# rpm -qa | grep php
php-common-7.0.33-8.el7.remi.x86_64
php-xml-7.0.33-8.el7.remi.x86_64
php-7.0.33-8.el7.remi.x86_64
php-pear-1.10.9-2.el7.remi.noarch
php70-php-xml-7.0.33-8.el7.remi.x86_64
php70-php-pecl-mysql-1.0.0-0.9.20151007git294ce3b.el7.remi.x86_64
php-pdo-7.0.33-8.el7.remi.x86_64
php70-php-mysqlnd-7.0.33-8.el7.remi.x86_64
php-mysqlnd-7.0.33-8.el7.remi.x86_64
php-json-7.0.33-8.el7.remi.x86_64
php70-runtime-2.0-1.el7.remi.x86_64
php70-php-mbstring-7.0.33-8.el7.remi.x86_64
php-gd-7.0.33-8.el7.remi.x86_64
php70-php-gd-7.0.33-8.el7.remi.x86_64
php-cli-7.0.33-8.el7.remi.x86_64
php70-php-common-7.0.33-8.el7.remi.x86_64
php-fedora-autoloader-1.0.0-1.el7.remi.noarch
php70-php-json-7.0.33-8.el7.remi.x86_64
php70-php-pdo-7.0.33-8.el7.remi.x86_64
php-devel-7.0.33-8.el7.remi.x86_64
php-process-7.0.33-8.el7.remi.x86_64
php-mbstring-7.0.33-8.el7.remi.x86_64
php-intl-7.0.33-8.el7.remi.x86_64

ドメインが利用可能かチェックするPHPスクリプト

$
0
0

ドメイン名が利用可能かチェックするのに dns_get_record 関数を使います。
パラメータには url か domain.com のようなドメイン名
結果はテキストで OK か NG を返します。

<?php
$url = $_GET["url"];
$res = parse_url($url);
$name = "";

if (isset($res['host'])) {
    $name = $res['host'];
} else if (isset($res['path'])) {
    $name = $res['path'];
}

header('Content-type: plain/text');
if (!empty($name)) {
    $result = dns_get_record($name);
    if ($result === false || empty($result)) {
        echo 'NG';
    } else {
        echo 'OK';
    }
} else {
    echo 'ERR';
}
exit;
?>

このPHPスクリプトをエクセルVBAから呼び出す例:

'
' ドメインチェック WebAPI
'
'   URL: https://www.northwind.mydns.jp/samples/webservice/checkdomain.php
'   パラメータ: url
'   レスポンス:
'        OK: 利用可能
'        NG: 利用不可
'
' Ex.
'  IsDomainAvailable("northwind.mydns.jp")        = True
'
'
Function IsDomainAvailable(DomainUrl As String) As Boolean
    On Error GoTo ErrHandler

    Dim Request As Object
    Dim checkerUrl As String

    IsDomainAvailable = False
    checkerUrl = "https://www.northwind.mydns.jp/samples/webservice/checkdomain.php"

    Set Request = CreateObject("WinHttp.WinHttpRequest.5.1")

    With Request
      .Open "GET", checkerUrl & "?url=" & DomainUrl, False
      .send

        If .StatusText = "OK" And .ResponseText = "OK" Then
            IsDomainAvailable = True
        End If
    End With

    Set Request = Nothing
    
    Exit Function
ErrHandler:
    Debug.Print Err.Number & ": " & Err.Description
End Function

Sub Test()

    Debug.Print IsDomainAvailable("northwind.mydns.jp")

End Sub

PHP コーディング規約

$
0
0

コーディング規約ってやっぱりあった方がいいですよね。できるだけ多くの人が馴染みやすいのがいいですよね。

PHPのコーディングで参考になるものはと見つけたのが PEAR (PHP Extension and Application Repository) の標準コーディング規約です。

https://pear.php.net/manual/en/standards.php

PEAR ライブラリを使ってなくても、このような標準コーディングが公開されていることは大変参考になります。

PHPAGI v.2.20

$
0
0

AGI (Asterisk Gateway Interface) プログラムを作るのに欠かせないクラスライブラリの v2.20 が GitHub より利用可能です。

最新の Asterisk バージョンおよび PHP バージョンで使えます。
※ 当方では Asterisk 20.03 LTS/PHP v8.1 で動作確認済み

https://github.com/welltime/phpagi

Windows ssh コマンド configファイルでSSH接続を管理

$
0
0

Windows から ssh で Linux サーバーへ接続するには Putty、RLogin や Tera Term などのアプリケーションを使用していましたが、Windows にも ssh コマンドでも複数のサーバー接続がコンフィグファイルで管理できるので、いちいちホスト名やポートなどを指定しなくても、覚えやすいホスト名で SSH 接続できるうです。

コンフィグファイルは、.ssh\config というファイルでユーザーのホームディレクトリ下に作成します。

例: C:\Users\<ユーザー名>\.ssh\config

コンフィグファイルの書き方は、以下のように記述します。

例:

# 1号機
Host MyServer1
    HostName www.myserver1.com
    User foo
    IdentityFile "C:\Users\foo\keys\myserver1\id_rsa"
    Port 12345
    TCPKeepAlive yes
    IdentitiesOnly yes

# 2号機
Host MyServer2
    HostName www.myserver2.com
    User foo
    IdentityFile "C:\Users\foo\keys\myserver2\id_rsa"
    Port 12345
    TCPKeepAlive yes
    IdentitiesOnly yes

# 3号機
Host MyServer3
    HostName 160.nnn.nnn.nnn
    User foo
    IdentityFile "C:\Users\foo\keys\myserver3\id_rsa"
    Port 12345
    TCPKeepAlive yes
    IdentitiesOnly yes

接続する時は以下のコマンドを入力して実行します。

例: MyServer1 (www.myserver1.com)へ接続する場合

C:\Users\foo>ssh MyServer1

便利ですね。

コンフィグファイルの書き方

Host: サーバーの名前や自分の好きな名前を付けられます。
HostName: 接続先ホスト名または IPアドレス
User: ユーザー名
IdentityFile: 秘密鍵ファイル
Port: ポート
TCPKeepAlive: TCP Keep Alive を使用するか?
IdentitiesOnly: IdentityFileで指定した秘密鍵のみを使用するか?


free-jqgrid について

$
0
0

以前に書いたプログラムをメンテナンスしようと思って jqGrid の最新版にアップデートしようと思っていましたtがライセンスが変わって有償になっていました。jqGrid をv4.7.1を使うか、free-jqgrid に移行するかということで少し商用版 jqGrid (Guriddo) と free-jqgrid について調べました。

jqGrid (Guriddo)について

  • Guriddoという名前に変わった現在のjqGridは、商用利用する場合は有料ライセンスが必要です。ライセンスの種類や価格は、こちらで確認できます。
  • 過去バージョンの4.7.1までは、MIT/GPL 2のデュアルライセンスで公開されていたので、商用利用が可能です。ただし、更新やサポートはありません。

free-jqgrid について

free-jqgridは、jqGrid のフォーク版です。jqGrid は2015年に商用利用が有料になりましたが、free-jqgridはMITライセンスで公開されているので、商用利用が可能です。free-jqgridは、jqGridの機能を引き継ぎつつ、一部改良されています。例えば、以下のような機能が追加されています。

  • フィルター機能の強化
  • カラムの自動サイズ調整
  • ツールバーのカスタマイズ
  • ページネーションの改善

free-jqgrid は現在は頻繁に更新が行われていませんので互換性やセキュリティなど利用の際には注意が必要です。

ご参考になれば幸いです。

参考サイト:

free-jqgrid · GitHub
free-jqgrid – npm (npmjs.com)

Asterisk の無料オンライン ブック

$
0
0

邦題で「Asterisk テレフォニーの未来」という Asterisk の本がオライリーからでています。

この元本(英語)が無料のオンラインブックとして公開されています。

https://www.asteriskdocs.org/

上記のページの中ほどに、

For Asterisk 1.8

複数のHTML版か単一ページのHTML版をクリックするとコンテンツを見ることができます。


PHP error_log 関数でファイルへログ出力

$
0
0

error_log 関数でファイルへログ出力ができるので、クラスとして作成してみました。

<?php
#
# Logger
#
class MyLogger
{
    private $log_dir;
    private $log_fname;

    public function __construct($baseDir, $fname) {
        $this->log_dir = $baseDir;
        $this->log_fname = $fname;
    }

    public function Error($msg)
    {
        $log = "Error: ";
        $this->Output($log, $msg);
    }

    public function Info($msg)
    {
        $log = "Info: ";
        $this->Output($log, $msg);
    }

    protected function GetFileName()
    {
        $today = date("Ymd");
        return $this->log_dir."/".$today."_".$this->log_fname;
    }

    protected function Output($str, $msg)
    {
        $date = date("Y-m-d H:i:s");

        if (is_array($msg) || is_object($msg))
        {
            $log = "[".$date."]".$str.PHP_EOL;
            $log .= print_r($msg, true);
            $log .= PHP_EOL;
        }
        else
        {
            $log = "[".$date."]".$str.$msg.PHP_EOL;
        }
        error_log($log, 3, $this->GetFileName());
    }
}
// 実行
$log = new MyLogger('/tmp', 'test.log');
$log->Info('参考までに。');
$log->Error('大変だ。');
$arr = array('123','abc','xyz');
$log->Info($arr);
?>

出力例:

ログファイル名:/tmp/20140702_test.log
[2014-07-02 11:21:11]Info: 参考までに。
[2014-07-02 11:21:11]Error: 大変だ。
[2014-07-02 11:21:11]Info: 
Array
(
    [0] => 123
    [1] => abc
    [2] => xyz
)

PHP 配列を任意順で並べ替え

$
0
0

配列の並べ替えで比較キーを任意順で並べ替えたい場合の参考に。。。
この例では配列の ‘kind’ という値を 3 < 4 < 1 < 2 という順番で並べ替えます。

<?php
// 配列
$operators = array ();
$operators[] = array('name' => 'foo1', 'kind' => '1');
$operators[] = array('name' => 'foo2', 'kind' => '2');
$operators[] = array('name' => 'foo3', 'kind' => '3');
$operators[] = array('name' => 'foo4', 'kind' => '4');
$operators[] = array('name' => 'foo5', 'kind' => '3');
$operators[] = array('name' => 'foo6', 'kind' => '3');
$operators[] = array('name' => 'foo7', 'kind' => '2');
$operators[] = array('name' => 'foo8', 'kind' => '4');
$operators[] = array('name' => 'foo9', 'kind' => '1');

// 並べ替え(kind が 3,4,1,2) の順
usort($operators, function($a, $b) {
    if ($a['kind'] == 3)
    {
        if ($b['kind'] == 3)
        {
            return 0;
        }
        return -1;
    }
    else if ($a['kind'] == 4)
    {
        if ($b['kind'] == 4)
        {
            return 0;
        }
        else if ($b['kind'] == 3)
        {
            return 1;
        }
        return -1;
    }
    else if ($a['kind'] == 1)
    {
        if ($b['kind'] == 1)
        {
            return 0;
        }
        else if ($b['kind'] == 2)
        {
            return -1;
        }
        return 1;
    }
    else if ($a['kind'] == 2)
    {
        if ($b['kind'] == 2)
        {
            return 0;
        }
        return 1;
    }
    return 0;
});

// ソート結果
foreach($operators as $ope)
{
    echo 'Name: '.$ope['name'].' (Kind: '.$ope['kind'].')'.PHP_EOL;
}
?>

実行結果:

Name: foo6 (Kind: 3)
Name: foo3 (Kind: 3)
Name: foo5 (Kind: 3)
Name: foo4 (Kind: 4)
Name: foo8 (Kind: 4)
Name: foo9 (Kind: 1)
Name: foo1 (Kind: 1)
Name: foo2 (Kind: 2)
Name: foo7 (Kind: 2)

python で database クラスを作ってみる (Part 1)

$
0
0

python で Webクローラーをつくっているとどうしてもデータベースを参照、登録、更新が必要になります。MySQLにアクセスする方法少し楽して行えるように簡単なラッパークラスを作ってみたいと思います。

まずは、環境構築から。OS は CentOS7 です。データベースは mariadb をインストール済みです。
python は標準でインストールされている場合もありますが、念のため。

1. python 関連のインストール

# yum install python
# yum install python-devel
# yum install epel-release
# yum install python-pip
# yum install libxslt-devel libxml2-devel
# pip install beautifulsoup4
# pip install lxml

※ beautifulsoup4 はデータベースには必要はないですが、Webページを解析するのに必要なのでインストールしておきます。

2. MySql 関連のモジュールをインストール

# yum install gcc
# yum install mysql-devel
# pip install MySQL-python

python で database クラスを作ってみる (Part 2)

$
0
0

今回はクラスの定義とデータベースに接続、開く、閉じるところまでやっています。
クラス名は SimpleDB 、ファイルを simpledb.py とします。

コンストラクタで接続情報を渡し、open 関数で接続、カーソルを変数に格納しておきます。
close 関数でカーソルを閉じ、接続を閉じます。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import MySQLdb
from collections import OrderedDict

class SimpleDB(object):
    __host       = None
    __user       = None
    __password   = None
    __database   = None
    __cursor    = None
    __connection = None

    def __init__(self, host, database, user, password):
        self.__host = host
        self.__database = database
        self.__user = user
        self.__password = password
    ## End def __init

    def open(self):
        con = MySQLdb.connect(self.__host, self.__user, self.__password, self.__database)
        self.__connection = con
        self.__cursor = con.cursor()
    ## End def open

    def close(self):
        self.__cursor.close()
        self.__connection.close()
    ## End def close
## End class

if __name__ == '__main__':
    dbconfig = {
        "host": "localhost",
        "database": "<your database>",
        "user": "<your username>",
        "password": "<your secure password>",
        }

    try:
        db = SimpleDB(dbconfig['host'], dbconfig['database'], dbconfig['user'], dbconfig['password'])

        db.open()
        db.close()
    except Exception as e:
        print e.args

python で database クラスを作ってみる (Part 3)

$
0
0

今回はテーブルにデータを挿入して、選択するところまでやります。

テーブルにデータを挿入するため、SimpleDB クラスに insert 関数を定義します。
引数には table: テーブル名、data: 挿入するデータを辞書型で渡します。
関数内では、引数を基にして “INSERT table INTO (field, field…) VALUES (value, value…)” という SQL 文を組み立てます。
値はプリペアードステートメントで渡すので %s で組み立てておいて self.__cursor.execute(sql, bind) でバインドしています。
INSERT が成功すると、最後の行ID self.__cursor.lastrowid を返し、失敗した場合は、None を返します。

class SimpleDB(object):
... (省略)...

    def insert(self, table, data):
        sql = "INSERT INTO %s" % table
        bind = []

        if data is not None and len(data) > 0:
            # Build fields
            delim = ""
            sql += " ("
            for field, value in data.iteritems():
                sql += "%s `%s`" % (delim, field)
                delim = ","
            sql += ")"

            # Build values
            delim = ""
            sql += " VALUES ("
            for field, value in data.iteritems():
                sql += "%s " % (delim)
                sql += "%s"
                bind.append(value)
                delim = ","
            sql += ")"

        if self.__cursor is not None:
            self.__cursor.execute(sql, bind)
            self.__connection.commit()
            # Return last row ID.
            return self.__cursor.lastrowid
        return None
    ## End def insert

... (省略)...
## End class

次に、このテーブルからデータを取得するため、select 関数を定義します。
引数には table: テーブル名、conditions: 条件を指定する辞書型、sortby: ソートキー、sortdesc: ソート降順(True) を渡します。

関数内では、引数を基にして “SELECT * FROM table WHERE filed = value AND …” という SQL 文を組み立てます。
値はプリペアードステートメントで渡すので %s で組み立てておいて self.__cursor.execute(sql, bind) でバインドしています。
SELECT が成功すると、取得データを辞書型のリストで返し、失敗した場合は、None を返します。

class SimpleDB(object):
... (省略)...

    def select(self, table, conditions, sortby = None, sortdesc = False):
        result = None
        sql = "SELECT * FROM %s" % table
        bind = []

        if conditions is not None and len(conditions) > 0:
            sql += " WHERE "
            delim = ""

            for field, value in conditions.iteritems():
                if value is None:
                    sql += "%s `%s` IS NULL" % (delim, field)
                else:
                    sql += "%s `%s` = " % (delim, field)
                    sql += "%s"
                    bind.append(value)
                delim = " AND"

        if sortby is not None:
            sql += " ORDER BY %s %s" % (sortby, "DESC" if sortdesc else "ASC")

        if self.__cursor is not None:
            self.__cursor.execute(sql, bind)
            columns = self.__cursor.description
            result = []
            for row in self.__cursor.fetchall():
                item = {}
                for (index, value) in enumerate(row):
                    item[columns[index][0]] = value
                result.append(item)
        return result
    ## End def select

... (省略)...
## End class
Viewing all 93 articles
Browse latest View live