プライバシーポリシー
広告の配信について
当サイトは第三者配信の広告サービス「Googleアドセンス」を利用しています。
広告配信事業者は、ユーザーの興味に応じた広告を表示するために「Cookie(クッキー)」を使用することがあります。Cookieを無効にする設定およびGoogleアドセンスに関して、詳しくはこちらをクリックしてください。
第三者がコンテンツおよび宣伝を提供し、訪問者から直接情報を収集し、訪問者のブラウザにCookie(クッキー)を設定したりこれを認識したりする場合があります。
アクセス解析ツールについて
当サイトでは、Googleによるアクセス解析ツール「Googleアナリティクス」を利用しています。このGoogleアナリティクスはトラフィックデータの収集のためにCookieを使用しています。このトラフィックデータは匿名で収集されており、個人を特定するものではありません。
この機能はCookieを無効にすることで収集を拒否することが出来ますので、お使いのブラウザの設定をご確認ください。この規約に関して、詳しくはこちらをクリックしてください。
当サイトへのコメントについて
当サイトでは、スパム・荒らしへの対応として、コメントの際に使用されたIPアドレスを記録しています。これはブログの標準機能としてサポートされている機能で、スパム・荒らしへの対応以外にこのIPアドレスを使用することはありません。
当サイトでは、次の各号に掲げる内容を含むコメントは管理人の裁量によって承認せず、削除する事があります。
- 特定の自然人または法人を誹謗し、中傷するもの。
- 極度にわいせつな内容を含むもの。
- 禁制品の取引に関するものや、他者を害する行為の依頼など、法律によって禁止されている物品、行為の依頼や斡旋などに関するもの。
- その他、公序良俗に反し、または管理人によって承認すべきでないと認められるもの。
免責事項
当サイトで掲載している画像の著作権・肖像権等は各権利所有者に帰属致します。権利を侵害する目的ではございません。記事の内容や掲載画像等に問題がございましたら、各権利所有者様本人が直接メールでご連絡下さい。確認後、対応させて頂きます。
当サイトからリンクやバナーなどによって他のサイトに移動された場合、移動先サイトで提供される情報、サービス等について一切の責任を負いません。
当サイトのコンテンツ・情報につきまして、可能な限り正確な情報を掲載するよう努めておりますが、誤情報が入り込んだり、情報が古くなっていることもございます。
当サイトに掲載された内容によって生じた損害等の一切の責任を負いかねますのでご了承ください。
運営者:waysaku
初出掲載:2020年8月30日
RSSの <content:encoded> の文字列が数値文字参照になっているので読める文字列に変換する
こんなやつ
大昔にRSSでシステム間連携を実装したときにハマった気がしたけど一切覚えてない。
content:encoded
にある メーガン妃
のような文字列はどうやら 符号化文字集合の一つである Unicode におけるその文字のCode Point を16進数で表示する 数値文字参照
という形式で出力されてるらしい。
- 数値文字参照
この数値文字参照を実際の文字に戻すには
文字符号化方式 vvvvvvvvvvvvvvvvvvvvv 文字 <-> Code Point <-> byte列 ^^^^^^^^^^^^^^^^^^^ 符号化文字集合
のうち Code Point > 文字
をすればよい。
Pythonでやる場合は unicodedata
モジュールを使って
def unicode_test(codepoint): import unicodedata #コードポイントを対応する文字の名前に変換 name = unicodedata.name(codepoint) #対応する名前に当てはまる文字を取得 letter = unicodedata.lookup(name) result = """ Unicode文字: {} 対応する文字の名前: {} """.format(letter, name) print(result)
とすると変換できる。
試してみる
>>> import re >>> pattern = '&#x([0-9A-F]{4});' >>> res = re.findall(pattern, 'メーガン妃') # 数値文字参照からCode Pointの16進数文字列部分だけ抜き出す >>> print(res) ['30E1', '30FC', '30AC', '30F3', '5983'] >>> m = map(lambda x: unicode_test(chr(int(x, 16))), res) #16進数文字列から16進数数値型に変換した上で、(Unicode)文字列に変換して上記の関数に渡してみる >>> print(list(m)) Unicode文字: メ 対応する文字の名前: KATAKANA LETTER ME Unicode文字: ー 対応する文字の名前: KATAKANA-HIRAGANA PROLONGED SOUND MARK Unicode文字: ガ 対応する文字の名前: KATAKANA LETTER GA Unicode文字: ン 対応する文字の名前: KATAKANA LETTER N Unicode文字: 妃 対応する文字の名前: CJK UNIFIED IDEOGRAPH-5983
できた。
Pythonの html.unescape()
を使うと 数値文字参照からコードポイント16進数文字列への変換
と コードポイント16進数文字列から文字に変換
を一気にやってくれるから便利。
Presto/HiveにはUTF-16を操作する関数が用意されてないっぽい
あるにはあったが、数値文字参照からコードポイント16進数文字列への変換
と コードポイント16進数文字列から文字に変換
をSQLでやるのは相当気合がいりそう(できるかどうかわからない)
Raspberry Piでmdadmを使ったraid1ディスクでTimeMachineサーバ構築のメモ
Raspberry Pi OSをインストールした後の作業メモ
GUIでの設定
ネットワーク設定
とりあえずwifiつなげる
その他
GUIから - sshの有効化 - CUIでのデフォルト起動に変更 - current user(piユーザー)でのデフォルトログインを無効化 - キーボード設定を日本語キーボードに変更
apt upgrade と vimインストール
pi@raspberrypi:~ $ sudo apt update pi@raspberrypi:~ $ sudo apt upgrade pi@raspberrypi:~ $ sudo apt install -y vim gnome-screenshot
ユーザーの追加とpiユーザのパスワード変更
FYI: https://qiita.com/R-STYLE/items/b481ba2d695ddf8bcee4
pi@raspberrypi:~ $ sudo adduser watanabe_yusaku pi@raspberrypi:~ $ sudo gpasswd -a watanabe_yusaku sudo pi@raspberrypi:~ $ sudo gpasswd -d pi sudo
piユーザーはデフォルトユーザとして何かしらOSのデフォルト設定に絡んでるかもしれないので削除せずにパスワード変更だけしておく
pi@raspberrypi:~ $ sudo passwd pi
固定IPの設定
pi@raspberrypi:~ $ sudo vim /etc/dhcpcd.conf interface eth0 static ip_address=192.168.11.203/24 static routers=192.168.11.1 static domain_name_servers=8.8.8.8 interface wlan0 static ip_address=192.168.11.204/24 static routers=192.168.11.1 static domain_name_servers=8.8.8.8
再起動後にCUIでログイン
再起動してIP確認
watanabe_yusaku@raspberrypi:~ $ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.11.203 netmask 255.255.255.0 broadcast 192.168.11.255 inet6 fe80::58d9:9e7:854:df74 prefixlen 64 scopeid 0x20<link> inet6 2400:4051:23c0:600:6c36:2388:c5:e8ab prefixlen 64 scopeid 0x0<global> ether dc:a6:32:91:39:36 txqueuelen 1000 (Ethernet) RX packets 543 bytes 131236 (128.1 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 149 bytes 22984 (22.4 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.11.204 netmask 255.255.255.0 broadcast 192.168.11.255 inet6 fe80::fd63:d724:db0d:fbd5 prefixlen 64 scopeid 0x20<link> inet6 2400:4051:23c0:600:225b:bdb7:cad3:d443 prefixlen 64 scopeid 0x0<global> ether dc:a6:32:91:39:37 txqueuelen 1000 (Ethernet) RX packets 386 bytes 106463 (103.9 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 35 bytes 4952 (4.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
時刻合わせ
watanabe_yusaku@raspberrypi:~ $ sudo vim /etc/systemd/timesyncd.conf [Time] NTP=ntp.jst.mfeed.ad.jp FallbackNTP=ntp.nict.jp time.google.com
を追記してrestart
sudo systemctl restart systemd-timesyncd
sudo systemctl status systemd-timesyncd
で確認するとSyncronizedになっていたが、TimezoneがUSになっていたのでraspi-configから 4 Localisation Options -> I2 Change Timezone
でTokyoに設定したら時間が正しくなった
mdadmインストールとraid1デバイスの復旧
/dev/sda1と/dev/sdb1は既にmdadmでraid1デバイスとして構築されているものを再度assembleする。 新たにmd0デバイスを構築する場合はこっちを参考に
watanabe_yusaku@raspberrypi:~ $ sudo apt install -y mdadm watanabe_yusaku@raspberrypi:~ $ sudo mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1 mdadm: /dev/md0 has been started with 2 drives. watanabe_yusaku@raspberrypi:~ $ cat /proc/mdstat Personalities : [raid1] md0 : active (auto-read-only) raid1 sda1[0] sdb1[1] 976629440 blocks super 1.2 [2/2] [UU] bitmap: 0/8 pages [0KB], 65536KB chunk unused devices: <none> watanabe_yusaku@raspberrypi:~ $ sudo mdadm --detail /dev/md0 /dev/md0: Version : 1.2 Creation Time : Tue May 19 05:30:38 2020 Raid Level : raid1 Array Size : 976629440 (931.39 GiB 1000.07 GB) Used Dev Size : 976629440 (931.39 GiB 1000.07 GB) Raid Devices : 2 Total Devices : 2 Persistence : Superblock is persistent Intent Bitmap : Internal Update Time : Fri May 22 18:45:33 2020 State : clean Active Devices : 2 Working Devices : 2 Failed Devices : 0 Spare Devices : 0 Consistency Policy : bitmap Name : raspberrypi:0 (local to host raspberrypi) UUID : 30e8a7d7:7fe4d381:3a337844:d762b48f Events : 10672 Number Major Minor RaidDevice State 0 8 1 0 active sync /dev/sda1 1 8 17 1 active sync /dev/sdb1
/dev/md0のマウント
watanabe_yusaku@raspberrypi:~ $ sudo mkdir /data watanabe_yusaku@raspberrypi:~ $ sudo chmod 777 /data watanabe_yusaku@raspberrypi:~ $ sudo mount -t ext4 /dev/md0 /data
TimeMachineサーバ設定
netatalkのインストール
watanabe_yusaku@raspberrypi:~ $ apt install -y netatalk watanabe_yusaku@raspberrypi:~ $ sudo vim /etc/netatalk/afp.conf ; ; Netatalk 3.x configuration file ; [Global] ; Global server settings mimic model = TimeCapsule6,106 mac charset = MAC_JAPANESE log file = /var/log/netatalk.log ; [Homes] ; basedir regex = /xxxx ; [My AFP Volume] ; path = /path/to/volume [TimeMachine] valid users = watanabe_yusaku path = /data/timemachine time machine = yes
time machine = yes
を書くの忘れててTimemachine設定の バックアップ用デスク選択の一覧に表示されなくてだいぶ時間とられた
再起動
watanabe_yusaku@raspberrypi:~ $ sudo service netatalk restart
確認
MacからTimeMachineの設定からディスク選択を確認すると表示されていることを確認
Google Cloud SpannerでFORMAT_TIMESTAMP関数使うと時間がずれる
SpannerにUTCでTIMESTAMP型で保存されてるデータをJSTに戻そうとしたときにはまった。
SELECT TIMESTAMP "2017-08-20 20:00:00 UTC" AS ORIGIN_UTC, TIMESTAMP_ADD(TIMESTAMP "2017-08-20 20:00:00 UTC", INTERVAL 9 HOUR) AS DateTime_9_Plus, FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_ADD(TIMESTAMP "2017-08-20 20:00:00 UTC", INTERVAL 9 HOUR)) AS DateTime_WITH_TIME_9_Plus_FORMATED, FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_ADD(TIMESTAMP "2017-08-20 20:00:00 UTC", INTERVAL (8 + 9) HOUR)) AS DateTime_8_Plus_9_FORMATED
ORIGIN_UTC | DateTime_9_Plus | DateTime_WITH_TIME_9_Plus_FORMATED | DateTime_8_Plus_9_FORMATED |
---|---|---|---|
2017-08-20T20:00:00Z | 2017-08-21T05:00:00Z | 2017-08-20 22:00:00 (なぜかずれる) | 2017-08-21 05:00:00 (8時間を補正分としていれてズレを戻す |
よくわからんが、内部で太平洋標準時(たいへいようひょうじゅんじ、Pacific Standard Time: 略称PST)+8:00が影響してるとかしてないとか? www.en.advertisercommunity.com
FORMAT_TIMESTAMP関数の第三引数で"+9:00"のように指定しないとだめだった。
FORMAT_TIMESTAMP(format_string, timestamp[, time_zone])
でも、Data Studio使ったときに期間指定すると
(FORMAT_TIMESTAMP('%Y%m%d', t0.DateTime) >= '20181201' AND FORMAT_TIMESTAMP('%Y%m%d', t0.DateTime) <= '20181231')
みたいなクエリになっちゃうので、上記のように手動で8を足しこんだカラムにしないとだめだった
さくらVPSにSoftEtherサーバ構築
基本的にはラズパイに構築したときと同じ
waysaku.hatenablog.com
ただ、すっかり忘れていたのでメモ
基本的にはここの通りにセットアップすればOKだが、vpnserverとvpnclientの両方セットアップが必要
linuxconfig.org
あと、さくらのVPSはiptableが /etc/iptables/iptables.rules で明示的にセットされてしまっているのでデフォだとudp/500とudp/4500がつながらないっぽい。
/etc/iptables/iptables.rules を削除してrebootして解決
golangでbyte配列から整数型への変換メモ
メモ
package main import ( "fmt" "golang.org/x/crypto/scrypt" "encoding/hex" "encoding/binary" "bytes" ) func main() { b := []byte{0x00, 0x00, 0x00, 0xFF} fmt.Println(b) fmt.Println(hex.EncodeToString(b)) var i int32 buf := bytes.NewReader(b) err := binary.Read(buf, binary.LittleEndian, &i) if err != nil { fmt.Println("binary.Read failded:", err) } fmt.Println(i) }
package.jsonのpeerDependenciesについての理解
依存の解決の違い(dependencies, devDependencies, peerDependencies)
「親アプリで利用されるためのnpmモジュールを開発している時に、このモジュールをインストールするときはmoduleA:0.5.0と一緒にインストールする必要がある」 というケースを考える
親アプリ | |- このモジュール | | | |- moduleA
1. このモジュールのpackage.jsonのdependenciesにmoduleA:0.5.0を書いた場合
親アプリにも自動的にmoduleA:0.5.0がインストールされるが、もし親アプリのpackage.jsonにmoduleA:1.5.0が設定されてた場合は上書きされて実行時エラーになる
2. このモジュールのpackage.jsonのdevDependenciesにmoduleA:0.5.0を書いた場合
親アプリでnpm installした時に、このモジュールのdevDependenciesは無視されるのでmoduleA:0.5.0はインストールされないため実行時エラーになる
対処: 親アプリ側でmoduleA:0.5.0をpackege.jsonに書く必要がある
3. (1.か2.に加えて) このモジュールのpackage.jsonのpeerDependenciesにmoduleA:0.5.0を書いた場合
npm-v3より前の場合は、親アプリのnode_modulesにmoduleA:0.5.0も一緒にインストールされる(WARNは出る)
npm-v3以降の場合は、 `このモジュール@1.0.0 requires a peer of moduleA@^0.5.0 but none was installed.` みたいなWARNが出るだけでmoduleA:0.5.0はインストールされない
それぞれの違い
2.のケースはそもそもとして、このモジュールの実行に必要なmoduleA:0.5.0をdevDependenciesに書くのは間違いである(開発用途に必要なモジュールではなく、実行に必要なモジュールのため)
1.のケースは親アプリ側がこのモジュールを利用するときにmoduleA:0.5.0が必須なことに気づけないため、なんらかの理由で親アプリのpackage.jsonにmoduleA:1.5.0を入れた場合に、このモジュールが動かなくなることを事前に気づくことができない
そのため、3.のpeerDependenciesをこのモジュールが使っていれば、警告として親アプリ側に通知することができるので、親アプリ側は明示的に(意図的に)moduleA:0.5.0を追加することができる。
はまったところ
この時注意が必要なのは、peerDependenciesはあくまで親アプリ側に警告を促すだけである。
親アプリは `このモジュールがmoduleA:0.5.0に依存しているからそれを利用しよう'と意図的に親アプリのpackage.jsonにmoduleA:0.5.0を追加することができるということが重要である。
もしも親アプリがmoduleA:1.5.0を利用したかったとしてもこのモジュールはmoduleA:0.5.0を使っているので、それぞれのモジュールの依存バージョンの互換性を解決してくれるものではない
どういうときに使うのか?
開発ではmoduleA:1.5.0を使っているが、このモジュールを利用するときは最低でもmoduleA:0.5.0を使ってほしいときとか?
結局、親アプリでmoduleA:1.5.0を参照して、このモジュールではmoduleA:0.5.0を参照するようにして依存性をよしなに解決して同時に使いたい
そのままではできないっぽい。
(なんかごにょごにょ工夫すればできるかもしれないけど)
疑問に対する推測
peerDependenciesって親アプリに設定するものじゃないのか?
親アプリのpeerDependenciesに指定することにより、このモジュールがどのバージョンのmoduleAに依存しているのかを指定する使い方なのもと思ったがどうやら違うっぽい
- 親アプリにpeerDependenciesを設定してもこのモジュールのバージョン依存を解決してくれるわけではないっぽい(WARN出るし)
- そもそも、peerDependenciesの書式的にどのモジュールがどのモジュールのどのバージョンに依存しているという書き方ができない
じゃぁ、devDependenciesとpeerDependenciesの両方に違うバージョンで書いてあるOSSモジュールをよく見るのはなんで?
これとか
リリースバージョンの依存はpeerDependenciesに書いて、開発中とか動作確認中のものはdevDependenciesに書いているのでは?
このモジュールのpeerDependenciesだけに書いた場合、このモジュールでnpm iinstallした場合はどうなるの?
peerDependenciesに書いただけでは、npm installしてもnode_modulesにインストールされない。
dependenciesかdevDependenciesと組み合わせて利用するみたい。
あんまり情報がなくて推測の部分が多い。
あんまりしっくり来てないけどこれ以上時間かけられないのでこんなもんの理解でとどめておく。
package.jsonのpeerDependenciesについて調べた
http://yukidarake.hateblo.jp/entry/2016/02/16/201614
Peer Dependencies
https://nodejs.org/en/blog/npm/peer-dependencies/