jsでbrowser情報を取得する

<script type="text/javascript">
    document.write(navigator.appCodeName + "<br>");
    document.write(navigator.appName + "<br>");
    document.write(navigator.appVersion + "<br>");
    document.write(navigator.platform + "<br>");
    document.write(navigator.userAgent + "<br>");
</script>

chromeで見てるから、chromeと出力させたいんだが、何故mozilla、Netscapeなんだ????
仕組みが分からん。

ipの地域をtableで表示する

getパラメーターの値で表示を切り替えます。

<table>
      <?php if($_GET&#91;"selectedDimension"&#93; == 'continent'): ?>
      <th>Continent</th><th>Users</th>
      <?php
        $i = 0;
        foreach($c1 as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php elseif($_GET&#91;"selectedDimension"&#93; == 'country'): ?>
      <th>Country</th><th>Users</th>
      <?php
        $i = 0;
        foreach($c2 as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php elseif($_GET&#91;"selectedDimension"&#93; == 'city'): ?>
      <th>City</th><th>Users</th>
      <?php
        $i = 0;
        foreach($c3 as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php else: ?>
      <th>Page</th><th>PageView</th>
      <?php
        $i = 0;
        foreach($data as $key => $value){
          if($i < 10){
            echo "<tr>";
            echo "<td>".$key."</td><td>".$value."</td>";
            echo "</tr>";
          }
          $i++;    
        }
      ?>
      </table>
      <?php endif; ?>

continent

country

city

一人デバックしてるなー
というか、これ、ページビュー単位ではなくて、cookie単位しないと駄目だ
うおおおおおおお、結構複雑だ

cookieに重複がない場合だけ、ipの地域を取得するに変更
foreachの前で$cookie=array();と宣言します。

$cookie = array();
foreach ($cursor as $document) {
  $pv[] = $document->date;
  if(!in_array($document->cookie, $cookie)){
    if(!is_null($document->continent)){
    $c1[] = $document->continent;
    }
    if(!is_null($document->contry)){
    $c2[] = $document->contry;
    }
    if(!is_null($document->city)){
    $c3[] = $document->city;
    }
  }
  $cookie[] = $document->cookie;
  $session[] = $document->session;
  if(!is_null($document->referrer)){
  $avgtime[] = $document->avgtime;
  }
  if(!is_null($document->referrer)){
  $referrer[] = $document->referrer;
  }
  $visit[] = $document->visit;
  $access[] = substr($document->date, 11, 2);
  $page[] = $document->page;    
}

continent, country, cityがuniqueになりました。
よっしゃ、ip周りはOKそう。

次は、browser, os, service provider
これ、js、phpでとれるんか?
取れなければ、スキップとしたい。が、GAでは必ず見る項目ではある。。

GETパラメーターをhiddenで送る

日付のパラメーターがついていた場合には、それに地域パラメータを加えてリンクさせる。

if(isset($_GET['_udate00'])&&isset($_GET['_udate01'])) {
  $date1 = $_GET['_udate00'];
  $date2 = $_GET['_udate01'] . " 23:59:59";
  $continent = "?_udate00".$_GET['_udate00']."&_udate01=".$_GET['_udate01']."&selectedDimension=continent";
  $contry = "?_udate00".$_GET['_udate00']."&_udate01=".$_GET['_udate01']."&selectedDimension=contry";
  $city = "?_udate00".$_GET['_udate00']."&_udate01=".$_GET['_udate01']."&selectedDimension=city";
} else {
  $date1 = date("Y-m-d", strtotime("-10 day"));
  $date2 = date("Y-m-d H:i:s");
  $continent = "?selectedDimension=continent";
  $contry = "?selectedDimension=contry";
  $city = "?selectedDimension=city";
}
if(isset($_GET['selectedDimension'])){
  $c = $_GET['selectedDimension'];
}

datepickerのformでは、hiddenでipの地域データをsubmitさせます。

<form method="GET" name="form" action="">
<input name="_udate00" type="text" id="datepicker" value="<?php echo $date1; ?>"> ~ <input name="_udate01" type="text" id="datepicker2" value="<?php echo $date2; ?>">
<input type="hidden" name="selectedDimension" value="<?php echo $c; ?>">
<input type="submit" class="submit" value="apply">
</form>

両方ついています。

ipアドレスの地理情報を取得してmongoDBに挿入する

192.168.33.1だとgeoliteがエラーになるので、198.7.31.23にします。

$data = array("date"=>date("Y-m-d H:i:s"));
$audience = $_POST['userdata']; 
$mongo = "app.na".$audience[0][1];
$audience = array_splice($audience, 1);

$ip_addr = $audience[0][1];
if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

foreach($audience as $value){
	$data += array($value[0]=>$value[1]); 
}

require_once '../geolite/vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('../geolite/GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$data = $data + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

var_dump($data);

$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert($data);
$mng->executeBulkWrite($mongo, $bulk);

echo "finished!!!";

取得できています。

mongoDBにもはいってます。

-geoliteがエラーの時の為に、try catch (Exception $e) に変えると、以下の分岐条件は削除できます。

if($ip_addr == "192.168.33.1"){
	$ip_addr = "198.7.31.23";
}

ipの地理情報はmongoDBには入りません。

因みに、Chrom extensionでBetternet Unlimited Free VPN ProxyやHotspot Shieldなどを使うとIPアドレスを偽造できるようです。

次は、表示側を作ります。
flexを入れ子にしたレイアウトにします。

iphoneのカメラとEOSは何が違うのか?

プロでなければ、普通に写真撮る分にはiphoneで十分、と誰かにお聞きしたんだが、
前から気になっていた、iphoneと一眼レフでどれ位性能違うの?

iphone
6s
-live photos(シャッターを切る前後1.5秒ずつの動画も含めて記録する)
-位相差AFセンサー
-手ぶれ補正
-動画画質 4K/30p(フルHDの4倍の情報量)
-有効画素数 1200万画素

X
-1200万画素
-連写速度 約10コマ/秒
-シャッター速度 1/8000~30秒
-4Kビデオ作成
-wifi bluetooth, gps 〇
-レンズF値 広角:1.8, 望遠:2.4
-レンズカバー距離 28-57mm
-174g

Cannon
EOS630(1989年129,700円)
-シャッター1/2000~30秒
-AF方式:TTL位相差検出方式(ズレ検出)、AFモードはワンショット式 /動体予測AIサーボAF、AF検出範囲はEV1~18(ISO100)
-ファインダー:ペンタ固定アイレベル式、倍率0.8倍、視野率94%、交換スクリーン7種完備
-測光・露出制御:複合型SPC素子使用、TTL開放測光シャッタースピード優先式AE/絞り優先式AE/インテリジェントプログラムAE、定点連動マニュアル、オートブラケティング(1/2段±5段階露光可能)、9回まで予約可能の多重露出可能、測光感度分布特性=画面6分割評価測光/中央部分(画面中央約6.5%部)測光(AEロック機能付き)、露出補正±5EV(1/2ステップ)可能、測光連動範囲はEV-1~ 20(ISO100:F1.4)、フィルム使用感度域はISO6~6400、イメージセレクト=AF、AE、巻き上げ、プログラムの組み合わせ7種、カスタムファンクション=7種設定可能

EOS-1D X Mark II(547,800円!?)
-CFカード(タイプI準拠、UDMAモード7対応)CFastカード(CFast 2.0対応)
-約35.9×23.9mm
-CMOSセンサー
-約2020万画素
-DCF2.0 PEG、RAW
-ピクチャースタイル:オート、スタンダード、ポートレート、風景、ディテール重視、ニュートラル、忠実設定、モノクロ、ユーザー設定1~3
-ホワイトバランス
-画像の明るさ自動補正,高輝度側・階調優先,レンズ光学補正
-ファインダー ペンタプリズム使用、アイレベル式 約0.76倍(50mmレンズ・∞・-1m-1)
-オートフォーカス 専用AFセンサーによるTTL二次結像位相差検出方式
-露出制御:約36万画素RGB+IR測光センサー使用、216分割TTL開放測光
-多重露出撮影
-シャッター 電子制御式、フォーカルプレーンシャッター 1/8000~30秒
-ドライブ関係 1枚撮影、高速連続撮影、低速連続撮影、1枚:ソフト動作、ソフト高速連続撮影、ソフト低速連続撮影、セルフタイマー:10秒、セルフタイマー:2秒 高速連続撮影
-外部ストロボ EXシリーズスピードライト E-TTL II 自動調光
-ライブビュー撮影機能
-動画撮影機能 MOV、MP4
-液晶モニター
-再生機能
-有線LAN機能
….

機能が想像以上にあるな。。1989年のEOS630ですら、まだキャッチアップでんぞ。。。

とりあえずシャッター速度は変わらんよう。
画素は2200万だからEOSは倍。1200万でも相当凄いんだろうけど。。よーわからんが。
明るさや、露出補正はなんとなく馴染みやすいが、手振れ補正のアルゴリズムが良くわかりませんね。
手振れ補正は、色々なアルゴリズムの研究が世界中であるようです。
https://library.naist.jp/mylimedio/dllimedio/showpdf2.cgi/DLPDFR008578_P1-93
光学式:カメラの動きをジャイロセンサで検出して、その動きがキャンセルされるようにレンズ、撮影素子を駆動する
電子式:画像処理
->光学式は、カメラそのもの動きを計算しているんですね。

自動運転は画像認識の技術が入っているので、当然カメラと連動した写真系のサービスつくらないと駄目ってことですね。(どれ位掘らないといけないのか、現段階では想像つきません)
呑気に「一眼レフ買って撮影会に行きたい」なんて言ってる場合ではないことは確か。

ipの大陸、国、地域を配列にpush

$audience = array("date"=>"2018-04-18 08:05:50", "ip"=>"198.7.31.23", "visit"=>"Returned User");

$ip_addr = $audience["ip"];

require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('GeoLite2-City.mmdb');
$record = json_decode(json_encode($reader->city($ip_addr)));

$continent = $record->continent->names->en;
$contry = $record->country->names->en;
$city = $record->city->names->en;

$audience = $audience + array('continent'=>$continent, 'contry'=>$contry, 'city'=>$city);

print_r("<pre>");
var_dump($audience);
print_r("</pre>");

きた!

cronでgunzipを実行する

crontabでgunzipと書くだけです。

20 * * * * root cd /home/vagrant/cookie/cron; gunzip GeoLite2-Country.mmdb.gz

ほお~

sudo cat /var/log/cron
Apr 26 22:20:02 localhost CROND[17108]: (root) CMD (cd /home/vagrant/cookie/cron; gunzip GeoLite2-Country.mmdb.gz)

無償版は毎月3日に更新されるそう(真偽は不明です)なので、日本との時差を考慮して、毎月5日の1時15分にwgetして、1時20分にgunzipするよう設定します。

15 1 5 * * root cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"
15 1 5 * * root cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz"
20 1 5 * * root cd /home/vagrant/cookie/cron; gunzip GeoLite2-Country.mmdb.gz
20 1 5 * * root cd /home/vagrant/cookie/cron; gunzip GeoLite2-City.mmdb.gz

geolite側はこれでOK
次はmongodbに入れる前に、phpでipから、continent, country, cityを取得して配列にpushするところをやりたいと思います。

cronでwgetを実行する

wget:ノンインタラクティブなダウンローダー

wgetがどこにあるか確認します。

/usr/bin/wget

bin:Binary codeのこと、実行可能プログラム置き場
/bin:FHSによって定められたシングルユーザを含めたどのユーザでも使えるコマンド
/usr/bin:ユーザーが一般的に使用するコマンド

続いて、crontabを編集します。

sudo vi /etc/crontab

任意のディレクトリ(ここでは/home/vagrant/cookie/cron)に、wgetでdownloadしたいとすると、まず、cdで移動する必要があります。そのため、以下のように書きます。
root cd で移動して、/usr/bin/wgetで、”http://hogehoge”をダウンロード
※ここでは、テスト用に毎時55分にwgetする

55 * * * * root cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz"
/etc/rc.d/init.d/crond start

編集後、crond start
/etc/rc.d/init.d/crond start

結果
->取れてる!!!

sudo cat /var/log/cron でログも確認

Apr 26 21:55:01 localhost CROND[17001]: (root) CMD (cd /home/vagrant/cookie/cron; /usr/bin/wget "http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz")

OK牧場!

ipから、continent, country, cityを取得

encodeしてdecodeします。

$reader = new Reader('GeoLite2-City.mmdb');
$ip_addr = '182.22.59.229';
$record = json_decode(json_encode($reader->city($ip_addr)));



echo $record->continent->names->en ."<br>";
echo $record->country->names->en ."<br>";
echo $record->city->names->en ."<br>";

首相官邸
https://www.kantei.go.jp/
202.214.216.10
Asia
Japan
Komagatani
大阪府羽曳野市駒ケ谷?

white house
https://www.whitehouse.gov/
North America
United States
Cambridge

おもろい!続けて..

ペニンシュラ
peninsula.com
North America
United States
cityがnullの場合もあるようです。
ってか、アメリカかい!

GeoIP2でipアドレスの住所判定

GeoLite2 CountryがIPアドレスから国を取得するデータベース、GeoLite2 CityがIPアドレスから地域を取得するデータベース

# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
# gunzip GeoLite2-Country.mmdb.gz
# wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
# gunzip GeoLite2-City.mmdb.gz

mmdbはインメモリデータベース
gunzip:圧縮された圧縮ファイルを解凍する

composerを入れてGeoIP2 PHP APIをインストール

$ curl -sS https://getcomposer.org/installer | php
composer require geoip2/geoip2:~2.0

<?php
require_once 'vendor/autoload.php';
use GeoIp2\Database\Reader;

$reader = new Reader('GeoLite2-City.mmdb');
$ip_addr = '182.22.59.229';
$record = $reader->city($ip_addr);

print_r("<pre>");
var_dump($record);
print_r("</pre>");
?>

ドイツ語、英語、スペイン語、フランス語、日本語、ポルトガル語、ロシア語、中国語で出力されます。
[“record”:”GeoIp2\Record\AbstractRecord”:private]=>
array(2) {
[“geoname_id”]=>
int(1850147)
[“names”]=>
array(8) {
[“de”]=>
string(5) “Tokio”
[“en”]=>
string(5) “Tokyo”
[“es”]=>
string(5) “Tokio”
[“fr”]=>
string(5) “Tokyo”
[“ja”]=>
string(6) “東京”
[“pt-BR”]=>
string(7) “Tóquio”
[“ru”]=>
string(10) “Токио”
[“zh-CN”]=>
string(6) “东京”
}
}

1.エリア、国、都市を取得
2.wget・gunzipをcronで実行できるか確認が必要
3.クライアントリクエストからの負担を軽くするため、都市の抽出はmongoDBに入れる前にphp側で実行したい