ブログ

割とコンピュータよりの情報をお届けします。

コンピュータ

MongoDBの設定ファイルを作らされた

先週からMongoDBの設定ファイルを作らされていた。enableLocalhostAuthBypassってローカルなら認証いらないのでは?と思っていたら違うらしい。

作ったファイルの例(Windows用に直し)は以下のようなもの。

systemLog:
    destination: file
    path: "C:/mongodb/logs/log.txt"
net:
    bindIp: 127.0.0.1
    port: 27017
storage:
    dbPath: "C:/mongodb/data"
    journal:
        enabled: true
        commitIntervalMs: 500
    engine: wiredTiger
    wiredTiger:
      engineConfig:
         cacheSizeGB: 1.0
         journalCompressor: zlib
      collectionConfig:
         blockCompressor: zlib    
setParameter:
    enableLocalhostAuthBypass: true
#    enableLocalhostAuthBypass: false
security:
    authorization: enabled
#    authorization: disabled
   

設定の仕方何度も確認したが,enableLocalhostAuthBypass: trueをいれてもコマンド実行になると認証が省けない。
読んでみるとadminデータベースの最初のユーザが作成されるまでの限定的操作では有効だがその後は関係ないらしい…

基本的には,一度目のcreateUserが完了するまで一部コマンドのみ有効である(getUsersなどは使えない)。普通はadminデータベースにユーザを追加する。
ところが,いったんdropUserでこのユーザを削除してしまうとmongodbを再起動するまではこの設定は無効である。

また,createUserで複数のユーザを作成している場合(adminデータベース以外のデータベースに対するユーザもカウントされるようである)には,一つだけdropUserで削除したところでまだユーザが残っているのでmongodbを再起動してもこの設定は無効である。

≫ 続きを読む

2018/07/22 コンピュータ   TakeMe

普通のアプリをWindowsサービス化するnssmで32bitと64bit混ぜこぜ

普通のアプリをWindowsサービス化するnssmは便利なツールだが,32bit版になっていても実行するファイルが64bit版であっても構わないみたい。

nssmは64bitビルドでなければ64 bitアプリを動かせないのかと思っていたが,問題ないようだ。
Wix Toolsetでインストーラを作っていた時に気付いた。

例えば32 bitビルドのnssmでnodeが64 bit版の場合には,タスクマネージャーで確認するとnssmだけ「(32 ビット)」という表記がついているがnode.jsにはその表記がないので64 bitで動いているようだ。

Wix Toolsetでインストールする先のフォルダProgram FilesにするかProgram Files(x86)の違いには注意する必要があるようだが,単体の時は混ぜこぜが可能だ。

Wix Toolsetの場合にはインストール先ディレクトリのIDを標準のProgramFilesFolderにするか,意図的にProgramFiles64Folderにするかの差である。nssmファイルの選択を気を付けないといけない。

≫ 続きを読む

2018/07/15 コンピュータ   TakeMe

ntp-clientとsocket.ioでサービス作成を試してWix Toolsetでインストールしてみた

ntp-clientとsocket.ioでサービス作成を試してみる」で作成したファイルをnssmでWindowsサービスとして動かすアプリをWix Toolsetでインストールファイルを作成してみた。

nssmをダウンロードしてくることが最初。
本当はnode.jsのインストーラも同梱した方がよいような気がするが,ここでは前の記事でインストールしたようにnode.exeはzipで展開してcmdファイルに
[node.exeパス] serv.js
を記述したserve.cmdファイルを用意て同梱した。

wxsファイルの例は添付します。

<?xml version="1.0" encoding="utf-8"?>
<!−−
    # This comment is generated by WixEdit, the specific commandline
    # arguments for the WiX Toolset are stored here.

    candleArgs: 
    lightArgs: "<projectname>.wixobj" -out "<projectname>.msi" <extensions> -cultures:ja-JP
−−>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="E5C926F4-5511-480D-BDCE-0222B5C6A1A1" Name="SocketIO_TEST 作品" Language="1041" Version="0.0.0.1" Manufacturer="Take3's Web" UpgradeCode="F8DE7934-6B08-42E4-A0A0-2086A5612F23" Codepage="932">
        <Package Description="Test file in a Product" Comments="Simple test" InstallerVersion="200" Compressed="yes" />
        <Media Id="1" Cabinet="simple.cab" EmbedCab="yes" />
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder" Name="PFiles">
                <Directory Name="SocketIO_TEST" Id="SOCKETIO_TEST">
                    <Directory Id="NODE_MODULES" Name="node_modules">
... 容量制限のため省略 ...
                    <Component Id="Serv.js">
                        <File Id="SERV.JS" Name="serv.js" Source=".\serv.js" />
                    </Component>
                    <Component Id="GetNtp.js">
                        <File Id="GETNTP.JS" Name="GetNtp.js" Source=".\GetNtp.js" />
                    </Component>
                    <Component Id="SocketIOHandler.js">
                        <File Id="SOCKETIOHANDLER.JS" Name="SocketIOHandler.js" Source=".\SocketIOHandler.js" />
                    </Component>
                    <Component Id="nssm.exe">
                        <File Id="NSSM.EXE" Name="nssm.exe" Source=".\nssm.exe" />
                        <RegistryKey Key="SYSTEM\CurrentControlSet\Services\SocketIO_TEST" Root="HKLM" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
                            <RegistryValue Value="16" Type="integer" Name="Type" />
                            <RegistryValue Name="Start" Type="integer" Value="2" />
                            <RegistryValue Name="ErrorControl" Type="integer" Value="1" />
                            <RegistryValue Name="WOW64" Type="integer" Value="332" />
                            <RegistryValue Name="ObjectName" Type="string" Value="LocalSystem" />
                            <RegistryValue Name="DelayedAutostart" Type="integer" Value="0" />
                            <RegistryValue Name="FailureActionsOnNonCrashFailures" Type="integer" Value="1" />
                            <RegistryKey Id="Parameters" Key="Parameters" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
                                <RegistryValue Name="Application" Type="expandable" Value="[SOCKETIO_TEST]serve.cmd" />
                                <RegistryValue Name="AppParameters" Type="expandable" Value="" />
                                <RegistryValue Name="AppDirectory" Type="expandable" Value="[SOCKETIO_TEST]" />
                                <RegistryKey Id="AppExit" Key="AppExit" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
                                    <RegistryValue Action="write" Type="string" Value="Restart" />
                                </RegistryKey>
                            </RegistryKey>
                        </RegistryKey>
                        <ServiceInstall Name="SocketIO_TEST" Type="ownProcess" Start="auto" ErrorControl="normal" Description="SocketIO_TEST作品" DisplayName="SocketIO_TEST" />
                        <ServiceControl Id="StartService" Name="SocketIO_TEST" Start="install" Stop="both" Remove="uninstall" Wait="yes" />
                    </Component>
                    <Component Id="serve.cmd">
                        <File Id="SERVE.CMD" Name="serve.cmd" Source="serve.cmd" />
                    </Component>
                    <Component Id="index.html">
                        <File Id="INDEX.HTML_2" Name="index.html" Source="index.html" />
                    </Component>
                    <Component Id="package.json">
                        <File Id="PACKAGE.JSON_40" Name="package.json" Source="package.json" />
                    </Component>
                    <Component Id="package_lock.json">
                        <File Id="PACKAGE_LOCK.JSON" Name="package-lock.json" Source="package-lock.json" />
                    </Component>
                </Directory>
            </Directory>
        </Directory>
        <Feature Id="DefaultFeature" Title="Main Feature" Level="1">
            <ComponentRef Id="NODE_NTP_CLIENT" />
            <ComponentRef Id="NODE_NTP_CLIENT.CMD" />
            <ComponentRef Id="HISTORY.MD" />
... 容量制限のため省略...

≫ 続きを読む

2018/07/15 コンピュータ   TakeMe

ntp-clientとsocket.ioでサービス作成を試してみる

ntp-clientとsocket.ioを使ってみた。
学習を始めたJavaScriptのクラス使い方も試してみた。

以下に示す例はnode.jsでntp-clientを使用して自コンピュータ時刻(サーバ側)とntpサーバーの時刻の差を6分置きに取得する。
そして10秒置きに自コンピュータ時刻(サーバ側)を取得してオフセットを足して,socket.ioを通して送信する。
サンプルにしては長いものになっている。

まずアプリのスタートポイントの(本体)serv.js

const GetNtp = require('./GetNtp')

var getNtp = new GetNtp();
var ntpServer = 'ntp.nict.jp';

var task = new Promise(function(resolve, reject) {
  getNtp.getNetworkTime(ntpServer, 123, resolve, reject);
})

task.then(function(value) {
  // 6分置きにオフセットmsを更新
  setInterval(function () {
    getNtp.getNetworkTime(ntpServer, 123);
  }, 360000);
  
  // 10秒置きに時刻を送信 
  setInterval(function() {
    var value = new Date();
    value = new Date(value.valueOf() + getNtp.timeOffset);
    socketIOHandler.io.sockets.emit('date', {'date': value});
  }, 10000);
});

var SocketIOHandler = require('./SocketIOHandler');
var socketIOHandler = new SocketIOHandler(8081, getNtp);
socketIOHandler.start();

クラスの勉強中につきGetNtpというクラス風のオブジェクトを作成するGetNtp.js

var GetNtp = function() {
  this.ntpClient = require('ntp-client');
  this.last = null;
  this.timeOffset = 0;
}

GetNtp.prototype.getNetworkTime = function(uri, port, resolve, reject) {
  var before = new Date();
  this.ntpClient.getNetworkTime(uri, port, (err, date)=> {
    if(err) {
      console.error(err);
      if (typeof reject !== "undefined")
        reject();
      return;
    }
    var after = new Date();
    var computerDate = (before.valueOf() + after.valueOf()) / 2.0;
    this.timeOffset = date.valueOf() - computerDate.valueOf(); // コンピュータ時刻が進んでいたら負
    console.log('Time Offset Updated: ' + this.timeOffset.toFixed(1) + " ms");
    this.last = date;
    if (typeof resolve !== "undefined")
      resolve(date)
  });
}

module.exports = GetNtp

同様にクラス風オブジェクトを作成するSocketIOHandler.js

var SocketIOHandler = function(port, getNtp) {
  this.getNtp = getNtp;
  this.fs = require('fs');
  this.handler = function(req, res) {
    this.fs.readFile(__dirname + '/index.html',
    function (err, data) {
      if (err) {
        res.writeHead(500);
        return res.end('Error loading index.html');
      }
      res.writeHead(200);
      res.end(data);
    });
  }.bind(this);

  this.app = require('http').createServer(this.handler);
  this.io = require('socket.io')(this.app);
  
  this.start = () => {
    this.app.listen(port);
  }

  this.io.on('connection', (socket) => {
    socket.emit('connected', { hello: 'world' });
    {
      var value = new Date();
      value = new Date(value.valueOf() + this.getNtp.timeOffset);
      socket.emit('date', {'date': value});
    }
    socket.on('test', function (data) {
      console.log(data);
    });
  });
}

module.exports = SocketIOHandler;

クライアント側のコードindex.html。(httpでクライアントに読ませて使用する)

<html>
<head>
  <title>Sample App</title>
  <script
    src="https://code.jquery.com/jquery-3.3.1.min.js"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
</head>
<body>
<div id="test"></div>
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io('http://localhost:8081');
  socket.on('connected', function (data) {
    console.log(data);
    socket.emit('test', { value: 'data' });
  });
  socket.on('date', function(data) {
    console.log(data);
    $('#test').html(data.date);
  });
</script>
</body>
</html>

≫ 続きを読む

2018/07/15 コンピュータ   TakeMe

Visual Studio CodeでNode.jsのアプリをデバッグ

先の記事の続きでプログラム作成を続けていた。するとlaunch.jsonの設定にまだまだ深いところがあったので追加の内容を調べていた。
process.stdout.writeを使ったところでlaunch.jsonに新たな設定が必要になった。

今回デバッグするアプリケーションは
2つのファイルで構成

スクリプトの内容は後に回すとして
まずlaunch.jsonでconfigurationsに追加が必要なのは
"console": "integratedTerminal",
であった。

これを追加しておかないとprocess.stdout.writeで出力した内容がデバッグの表示に現れない。
なぜこうなるのかは いまひとつよくわかっていない。

一つ目はserv.js

const GetNtp = require('./GetNtp')

var getNtp = new GetNtp();

var before = new Date();
var task = new Promise(function(resolve, reject) {
  getNtp.getNetworkTime('ntp.nict.jp', 123, resolve, reject)
})

task.then(function(value) {
  var after = new Date()
  console.log('Computer tick: ' + (before.valueOf() + after.valueOf()) / 2 + ' ms')
  process.stdout.write('ntp.nict.jp tick: ' + value.valueOf() + ' ms\n')
  process.stdout.write('Difference: ' + ((before.valueOf() + after.valueOf()) / 2 - value.valueOf()) + ' ms')
  process.stdout.write(' ±: ' + (after.valueOf() - before.valueOf()) + ' ms\n')
})

2つ目のファイルGetNtp.jsは以下のようになっている


var GetNtp = function() {
  this.ntpClient = require('ntp-client');
}

GetNtp.prototype.getNetworkTime = function(uri, port, resolve, reject) {
  this.ntpClient.getNetworkTime(uri, port, function(err, date) {
    if(err) {
        console.error(err)
        if (typeof reject !== "undefined")
          reject()
        return
    }
    if (typeof resolve !== "undefined")
      resolve(date)
  });
}

module.exports = GetNtp

その前にこのサンプルではntp-clientを使って時刻を取得し自PCの時刻と差をms出力をしている。

作業フォルダでnpm init -yを実行してnpm install -D ntp-clientを実行しておく必要があることは言うまでもない。

≫ 続きを読む

2018/07/14 コンピュータ   TakeMe

CSS でtableの一部をsticky ... 使えないの続編

tableの中でスクロールさせる部分と固定させる部分を分けるときにCSSでposition: stickyを指定するというのを調べていたという記事の続き,

上を固定してみた。

どのHTML / CSSの参考サイトも指定のtdかth要素をstickyにするか,absoluteにするかでスクロールに対して止めていた。

参考を見ながら試してみたコードはセルだけが固定された。
また試しのコードを作ってみた。

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=yes">
<style>
html {
  height:100%;
}

body {
  height: 100%;
  margin: 0;
  padding:0;
  height: 100%;
}

#wrapper {
  overflow: scroll;
  width: 100%;
  height:100%;
}

#wrapper2 {
  position:absolute;
  top:0;
  left:0;
  overflow: hidden;
  width: 373px;
  height: 97.5vh;
  z-index:4;
}

#wrapper3 {
  position:absolute;
  top:0;
  left:0;
  overflow: hidden;
  width: 97.5vw;
  height: 34px;
  z-index:4;
}


table {
  table-layout;fixed;
  border-collapse: collapse;
}

thead th {
  background-color: #4a4aff;
  color: white;
  width: 300px;
  height: 10px;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 1;
  box-sizing: border-box;
  border:1px solid white;
}

thead {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
}

thead th.blank {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 3;
}

td {
  text-align: center;
  box-sizing: border-box;
  background-color: #efefff;
  width: 300px;
  height: 70px;
  border: 1px solid black;
}

tr:nth-of-type(2n+1) td {
  background-color: #ffffff;
}

td:nth-of-type(1) {
  position: sticky;
  left:0px;
}

th:nth-of-type(1) {
  position: sticky;
  left:0px;
  z-index:3;
}

td:nth-of-type(2) {
  position: sticky;
  left:122px;
}

th:nth-of-type(2) {
  position: sticky;
  left:122px;
  z-index:3;
}

td:nth-of-type(3) {
  position: sticky;
  left:244px;
}

th:nth-of-type(3) {
  position: sticky;
  left:244px;
  z-index:3;
}

tr {
  height:20px;
}

.fixed {
  position: fixed;
}

.header {
  width:120px;
  height:30px;
}

</style>
</head>
<body>
<div id="wrapper">
<table>
<colgroup span="3" style="border-right:2px solid black;">
<colgroup span="7">
<thead>
<tr><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th></tr>
</thead>
<tbody>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
</tbody>
</table>
</div>

<div id="wrapper2">
<table>
<colgroup span="3" style="border-right:2px solid black;">
<colgroup span="7">
<thead>
<tr><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th></tr>
</thead>
<tbody>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
</tbody>
</table>
</div>

<div id="wrapper3">
<table>
<colgroup span="3" style="border-right:2px solid black;">
<colgroup span="7">
<thead>
<tr><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th><th><div class="header">TEST</div></th></tr>
</thead>
<tbody>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
</tbody>
</table>
</div>

</body>
</html>

 

オーバーレイ表示をすることで確かにヘッダだけ固定された。

コラムが今度は固定を追加した。
そして,スクロールバーのサイズは固定とみなしている。100%いっぱいに広げてしまうとスクロールバーが隠れてしまう。

せっかくとあるJavaScriptフレームワークの学習を始めたのにjqueryでグリグリいじりまくるコーディングに逆戻り…

やっぱりjQueryが手放せない。
jqueryでスクロールイベントに合わせてコラムだけを表示している側をスクロールする対応が必要

≫ 続きを読む

2018/07/12 コンピュータ   TakeMe

CSS でtableの一部をsticky ... 使えない

tableの中でスクロールさせる部分と固定させる部分を分けるときにCSSでposition: stickyを指定するというのを調べていた
新しいposition: sticky;が便利という記事が多かったので試してみたら…

どのHTML / CSSの参考サイトも指定のtdかth要素をstickyにするか,absoluteにするかでスクロールに対して止めていた。

参考を見ながら試してみたコードは以下のようなものだが…

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, user-scalable=yes">
<style>
html {
  height: 100%;
}

body {
  height: 100%;
  margin: 0;
}

#wrapper {
  width: 400px;
  overflow:scroll;
  height:100%;
}

table {
  table-layoute: auto;
  border-collapse: collapse;
}

tbody th {
  background-color: #4a4aff;
  color: white;
  width: 300px;
  height: 70px;
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 1;
  border:1px solid white;
}

thead {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  z-index: 2;
}

thead th.blank {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
  left: 0;
  z-index: 3;
}

td {
  text-align: center;
  background-color: #efefff;
  width: 300px;
  height: 70px;
  border: 1px solid black;
}

tr:nth-of-type(2n+1) td {
  background-color: #ffffff;
}

/*td:nth-of-type(1) {
  position: sticky;
  left:0px;
}

th:nth-of-type(1) {
  position: sticky;
  left:0px;
  z-index:3;
}

colgroup:nth-of-type(1) {
  position: absolute;
  left:0px;
  z-index:3;
}*/

</style>
</head>
<body>
<div id="wrapper">
<table>
<colgroup span="3" style="border:2px solid black;">
<colgroup span="7">
<tr><th>TEST</th><th>TEST2</th><th>TEST3</th><th>TEST4</th><th>TEST5</th><th>TEST</th><th>TEST2</th><th>TEST3</th><th>TEST4</th><th>TEST5</th></tr>
<tbody>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
<tr><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td><td>0</td></tr>
</tbody>
</table>
</div>
</body>
</html>

 

確かに,簡単なコードでヘッダが固定されるのだが固定されるのはヘッダのセルだけで境界は固定されないのだ…

スクロースしてみると境界が透けて見える

これではデザインがうるさいと使えない。

せっかくとあるJavaScriptフレームワークの学習を始めたのにjqueryでグリグリいじりまくるコーディングに逆戻り…

結局jQueryが手放せない。

≫ 続きを読む

2018/07/11 コンピュータ   TakeMe

先のFTPクライアントをC#で作り直してみた

先ほどのPythonでFTPサーバを作ってみた件について一緒に書いていたクライアントの部分をC#で書き直してみた。

この程度の実装ならC#の方が簡単。

ただし,WebClientを使用するところが非常に特徴的である。
ちなみに,2つファイルを作ってしまっているが,一つ目はファイルを転送したもの,二つ目はメモリからバイト列をファイルへ転送したもの。

using System.Text;

namespace FTP
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Net.WebClient client = new System.Net.WebClient();
            client.Credentials = new System.Net.NetworkCredential("user", "password");

            // ファイルを転送する場合。
            client.UploadFile("ftp://localhost/test4.txt", "test2.txt");

            // メモリから直接文字列を転送する場合。
            string str = "これはテストの文字列です";
            byte[] bytes = Encoding.UTF8.GetBytes(str); 
            client.UploadData("ftp://localhost/test5.txt", bytes);
            client.Dispose();
        }
    }
}

当然Syste.Net.WebClientを使用しているのでftpに限らずhttpの利用も想定できると思うが…

≫ 続きを読む

2018/07/08 コンピュータ   TakeMe

PythonでFTPサーバーを立ててみる

Pythonで開発用のftpサーバを用意してみた。

Pythonで開発用のftpサーバを簡単に作る方法を探していると,以下のようなコードが上がった。

ユーザ名 user
パスワード password
でダミーのユーザを作成。

import pyftpdlib.authorizers
import pyftpdlib.handlers
import pyftpdlib.servers
import os

# スクリプトのファイルのあるフォルダのfolderフォルダを
# ユーザルートにする
srvRoot = os.path.dirname(__file__) + '\\folder';

auth = pyftpdlib.authorizers.DummyAuthorizer()
auth.add_user('user', 'password', srvRoot, perm='elradfmw')

hndler = pyftpdlib.handlers.FTPHandler
hndler.authorizer = auth

server = pyftpdlib.servers.FTPServer(("0.0.0.0", 21), hndler)

try:
    server.serve_forever();
except KeyboardInterrupt:
    print('interrupted!')

クライアントを作成してみる。といっても接続してファイルをアップロードしてみるだけのプログラムだけど…

from ftplib import FTP

ftp = FTP(
    "localhost",
    "user",
    passwd="password"
)

# ファイルのアップロード(テキスト).
with open("test2.txt", "rb") as f:
    ftp.storlines("STOR /test2.txt", f)

ftp.quit();

例えば,このプログラムを定期的にプログラムを実行すれば定期的にアップロードできる。

ただし,この例ではtest2.txtファイルを一度用意しないといけない。
そこでいwith open......の部分は以下のように変えておくと,文字列を直接ftpサーバのtest3.txtファイルに書き込むことができる。

from io import BytesIO
sample_bytes=bytes('これはテストのバイト列です','utf-8')
f = BytesIO(sample_bytes)
ftp.storlines("STOR /test3.txt", f)

≫ 続きを読む

2018/07/08 コンピュータ   TakeMe

System.Threading.Thread.Startは一度しか開始されない。

.NET FrameworkのSystem.Threading.Threadを使用していて使用方法を誤って,大きなバグを招いてしまった。

System.Threading.Threadの使い方を間違えてしまった。

例えば,以下のようなコードでは最初のthread.Start()では意図通りRun()の中身が実行されるが,2回目のStart()では実行されない。

一応ドキュメントには載っている。

例外が発生すると思うのだが,どういうコンテキストで実行したか,例外が出ないことがあって大きなバグになってしまった。
一回一回new Thread(Run)を呼んでおけばよい。

using System;
using System.Threading;

namespace TEST_THREAD
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread thread = new Thread(Run);

            thread.Start();
            Thread.Sleep(2000);

            thread.Start();
            Thread.Sleep(2000);
        }

        private static void Run()
        {
            Console.WriteLine("Started");
        }
    }
}

≫ 続きを読む

2018/07/04 コンピュータ   TakeMe