2018年1月2日火曜日

連続画像から動画作成

環境

  • Ubuntu 16.04.3 LTS

こんな感じでできました。

$ sudo apt install mencoder
$ mencoder "mf://images/jma3/*.png" -mf fps=25 -ovc lavc -lavcopts vcodec=mpeg4 -o test.avi

MTP で接続したスマホをファイルシステムとしてマウント

環境: Ubuntu 16.04


jmtpfs インストール

$ sudo apt install jmtpfs
MTP 接続されたスマホを確認 (PC に接続したスマホは 1台のみの場合)
$ jmtpfs -l
Device 0 (VID=04dd and PID=9a8b) is UNKNOWN in libmtp v1.1.10.
Please report this VID/PID and the device model to the libmtp development team
Available devices (busLocation, devNum, productId, vendorId, product, vendor):
1, 22, 0x9a8b, 0x04dd, UNKNOWN, UNKNOWN
busLocation devNum productId vendorId product vendor
1 22 0x9a8b 0x04dd UNKNOWN UNKNOWN

スマホ 2台接続した場合はなぜか以下のようになった
$ jmtpfs -l
Device 0 (VID=04dd and PID=9a8b) is UNKNOWN in libmtp v1.1.10.
Please report this VID/PID and the device model to the libmtp development team
Device 1 (VID=0e8d and PID=2008) is a MediaTek Inc MT65xx.
Available devices (busLocation, devNum, productId, vendorId, product, vendor):
1, 22, 0x9a8b, 0x04dd, UNKNOWN, UNKNOWN
1, 23, 0x2008, 0x0e8d, MT65xx, MediaTek Inc
1, 22, 0x9a8b, 0x04dd, UNKNOWN, UNKNOWN
1, 23, 0x2008, 0x0e8d, MT65xx, MediaTek Inc
busLocation devNum productId vendorId product vendor
1 22 0x9a8b 0x04dd UNKNOWN UNKNOWN
1 23 0x2008 0x0e8d MT65xx MediaTek Inc

マウント

マウントポイント作成

$ mkdir test

マウント

$ jmtpfs test/
Device 0 (VID=04dd and PID=9a8b) is UNKNOWN in libmtp v1.1.10.
Please report this VID/PID and the device model to the libmtp development team
Device 1 (VID=0e8d and PID=2008) is a MediaTek Inc MT65xx.
Android device detected, assigning default bug flags

マウントした中身を確認

$ ls -la test/
合計 4
drwxr-xr-x  4 worker worker    0  1月  1  1970 .
drwxrwxr-x  3 worker worker 4096  1月  2 16:14 ..
drwxr-xr-x 22 worker worker    0  1月 30  4438088 Internal storage
drwxr-xr-x  8 worker worker    0  3月 17  4438090 microSD
  • 中身を確認すると、busLocation=1, devNum=22 のスマホがマウントされた
  • 最初の有効な MTP デバイスを自動選択してマウントされるとのこと

MTP デバイスを指定してマウントする場合

$ jmtpfs -device=1,22 test/
Device 0 (VID=04dd and PID=9a8b) is UNKNOWN in libmtp v1.1.10.
Please report this VID/PID and the device model to the libmtp development team
Device 1 (VID=0e8d and PID=2008) is a MediaTek Inc MT65xx.
Android device detected, assigning default bug flags
  • busLocation=1, devNum=22 を指定

アンマウント

$ fusermount -u test/

Windows10 で Ctrl と Caps キーを入れ替え

環境: Windows10 Home

やってることは「 Windows8.1 で Ctrl と Caps キーを入れ替え 」と同じですが、レジストリエディタで値を手打ちするのが面倒なので DOS 窓でやってみました。


レジストリエディタで対象の値が無いことを確認

管理者としてコマンドプロンプトを実行

コマンドプロンプトで以下を実行

REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Keyboard Layout" /v "Scancode Map" /t REG_BINARY /d 0000000000000000030000001d003a003a001d0000000000 /f

レジストリエディタで対象の値ができたことを確認

Windows を再起動


2017年9月20日水曜日

Android の FolderSync アプリ設定

Android スマホのバックアップに FolderSync を使っているのですが、新しいスマホに FolderSync をインストールする度に設定値どうするんだっけ?と悩むのでまとめときます。


環境

  • Android: 6.0.1
  • FolderSync: 2.9.12

バックアップ概要

FolderSync から Ubuntu サーバーに sftp で接続し、バックアップの度に名前が時刻のフォルダを作成し、そこにスマホのファイルをバックアップします。


Ubuntu サーバー側設定

  • IP: 192.168.0.1
  • スマホの IP アドレスからの sftp 接続 (22番ポート) を ufw で許可しておきます。
  • sftp アカウント: worker (sftp でネットワークから接続できるようにこのアカウントを作成しておきます)
  • バックアップ先ディレクトリ: /some/where/

FolderSync アカウント設定

FolderSync トップ画面で [Accounts] をタップ

[+] アイコンをタップ

[SFTP] をタップして以下を設定値を入力

Main

項目 設定値
Unique_name 適当な名前を設定

Server address

項目 設定値
Server_address sftp://192.168.0.1/

Login

項目 設定値
Use_anonymous_login OFF
Login_name worker
Password worker ユーザーの sftp パスワード
Known_hosts_file 空白
Private_key-file 空白
Key-file_password 空白

Advanced

項目 設定値
Disable_Compression OFF
Legacy_library OFF
Charset Default

Ubuntu サーバーが起動して sftp できる状態で [TEST] をタップ

  • Login succeeded となることを確認

[SAVE] をタップして保存


FolderSync Folderpairs 設定

FolderSync トップ画面で [Folderpairs] をタップ

[+] アイコンをタップして以下を設定

Main

項目 設定値
Unique_name 適当な名前を設定
Account 先ほど作成した sftp アカウントを選択
Sync_type To remote folder
Remote_folder /some/where
Local_folder /storage/emulated/0/DCIM/

Scheduling

項目 設定値
Use_scheduled_sync OFF
Sync_Interval Daily (グレーアウト)
Sync_days 空白 (グレーアウト)
Sync_times 空白 (グレーアウト)

Sync options

項目 設定値
Copy_files_to_time-stamped_folder ON
Naming_Pattern 空白
Instant_sync OFF (グレーアウト)
Exclude_from_force_sync OFF
Sync_subfolders ON
Sync_hidden_files ON
Delete_source_files_after_sync OFF
Retry_sync_if_failed OFF
Only_resync_source_files_if_modified_(ignore_target_deletion) OFF
Sync_deletions OFF (グレーアウト)
Overwrite_old_files Always (グレーアウト)
If_conflicting_modifications Skip file (グレーアウト)

Connection

項目 設定値
Use_WiFi ON
Turn_on_Wifi OFF
Allowed_WiFi_SSID’s_(_separate_with_,_) 空白
Disallowed_WiFi_SSID’s_(_separate_with_,_) 空白
Use_3G/4G OFF
Use_Edge/2G OFF
Sync_when_roaming OFF
Use_other_connections OFF
Ignore_network_state OFF

Notifications

項目 設定値
Show_notification_when_syncing OFF
Show_notification_on_sync_success ON
Show_notification_when_changes_occur OFF
Show_notification_on_sync_error ON

Advanced

項目 設定値
Only_sync_if_charging OFF
Rescan_media_library OFF
Use_MD5_checksums OFF
Use_temp-file_scheme ON
Disable_file-size_check OFF

[SAVE] をタップして保存


バックアップ

FolderSync トップ画面で [Folderpairs] をタップ

作成した Folderpair の [SYNC] をクリック

バックアップが完了すると、Ubuntu 側の /some/where 配下に名前が時刻のフォルダが作成され、スマホのファイルがバックアップされています。


2017年8月20日日曜日

VMware ゲストのディスクイメージを圧縮してみました

VMware ホストの空きディスク容量が少なくなってきたので VMware ゲスト内の不要ファイルを削除してみたのですが、ホストの空きディスク容量は増えませんでした。

ググってみると、ゲストイメージを圧縮する必要があるようです。 以下、 http://qiita.com/gogonosmarty/items/f13fd3f20c2fffd531d3 に書いてある通りやってみました。


環境

  • ホスト OS: Windows10 Home
  • VMware: VMware Player 6.0.7 build-2844087
  • ゲスト OS: Ubuntu 16.04.2 LTS

条件は以下の通りとのことです。

  • ゲストに VMware Tools がインストールされていること
  • ゲストが起動していること
  • スナップショットがあるとうまくいかないことがあるとのこと

disk コマンドのサブコマンドを確認

$ sudo vmware-toolbox-cmd help disk
disk: perform disk shrink operations
Usage: vmware-toolbox-cmd disk <subcommand> [args]

Subcommands:
   list: list available locations
   shrink <location>: wipes and shrinks a file system at the given location
   shrinkonly: shrinks all disks
   wipe <location>: wipes a file system at the given location
  • list サブコマンドで仮想ディスクファイルシステムを確認できるようです。
  • shrink サブコマンドで仮想ディスクファイルシステムを圧縮できるようです。
  • shrinkonly サブコマンドで全ての仮想ディスクファイルシステムを圧縮できるようです。

仮想ディスクファイルシステムを確認

$ sudo vmware-toolbox-cmd disk list
/

/ を圧縮

$ sudo vmware-toolbox-cmd disk shrink /

2017年8月13日日曜日

使用されている CSS のみ抽出したり整形したり

環境: Ubuntu 16.04.2 LTS


Sphinx の html 文書を用意

使用されている CSS のみ抽出したり、整形したりする対象として、Sphinx の html 文書を用意します。

パッケージインストール

$ sudo apt install python3-sphinx
$ sudo apt install make

Sphinx 文書を作成

$ mkdir sphinx
$ cd sphinx/
$ sphinx-quickstart
$ make html

$ ls -la build/html/
total 40
drwxrwxr-x 4 ubuntu ubuntu 4096 Aug 13 16:47 .
drwxrwxr-x 4 ubuntu ubuntu 4096 Aug 13 16:47 ..
-rw-rw-r-- 1 ubuntu ubuntu  230 Aug 13 16:47 .buildinfo
-rw-rw-r-- 1 ubuntu ubuntu 2541 Aug 13 16:47 genindex.html
-rw-rw-r-- 1 ubuntu ubuntu 3770 Aug 13 16:47 index.html
-rw-rw-r-- 1 ubuntu ubuntu  197 Aug 13 16:47 objects.inv
-rw-rw-r-- 1 ubuntu ubuntu 2943 Aug 13 16:47 search.html
-rw-rw-r-- 1 ubuntu ubuntu  240 Aug 13 16:47 searchindex.js
drwxrwxr-x 2 ubuntu ubuntu 4096 Aug 13 16:47 _sources
drwxrwxr-x 2 ubuntu ubuntu 4096 Aug 13 16:47 _static

作成した Sphinx 文書の index.html ファイルで使用している CSS ファイルを確認

$ head -n 20 build/html/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">


<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>Welcome to aaa’s documentation! &mdash; aaa ccc documentation</title>

    <link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />

    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    './',
        VERSION:     'ccc',
        COLLAPSE_INDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true

以下の CSS ファイルを使っていました。

  • _static/alabaster.css
  • _static/pygments.css

CSS ファイルのサイズを確認

$ ls -l build/html/_static/alabaster.css build/html/_static/pygments.css
-rw-rw-r-- 1 ubuntu ubuntu 9220 Aug 13 16:47 build/html/_static/alabaster.css
-rw-rw-r-- 1 ubuntu ubuntu 4149 Aug 13 16:47 build/html/_static/pygments.css

2つの CSS ファイルをあわせて 13KBytes 程度です。

これらの CSS ファイルには実際には使用されていない CSS やコメントも含まれています。


使用されている CSS のみ抽出

UnCSS を使って、使用されている CSS のみ抽出します。

パッケージインストール

$ sudo apt install nodejs
$ sudo apt install npm

node という名前で nodejs を使えるようにします

$ sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10

$ ls -la /usr/bin/node
lrwxrwxrwx 1 root root 22 Aug 13 17:14 /usr/bin/node -> /etc/alternatives/node

$ ls -la /etc/alternatives/node
lrwxrwxrwx 1 root root 15 Aug 13 17:14 /etc/alternatives/node -> /usr/bin/nodejs

UnCSS インストール

$ sudo npm install -g uncss

使用されている CSS のみ抽出

$ uncss build/html/index.html > build/html/_static/res.css

使用されている CSS のみ抽出され、サイズが 13KBytes 程度から 6KBytes 程度に減りました。

$ ls -l build/html/_static/res.css
-rw-rw-r-- 1 ubuntu ubuntu 5943 Aug 13 18:05 build/html/_static/res.css

CSS ファイルを整形

res.css のファイルの最後は以下のようになっていました。

$ tail build/html/_static/res.css

/* misc. */

/* Make nested-list/multi-paragraph items look better in Releases changelog
 * pages. Without this, docutils' magical list fuckery causes inconsistent
 * formatting between different release sub-lists.
 */

/* Hide fugly table cell borders in ..bibliography:: directive output */
/*** uncss> filename: build/html/_static/pygments.css ***/ /* Comment */ /* Error */ /* Keyword */ /* Operator */ /* Comment.Hashbang */ /* Comment.Multiline */ /* Comment.Preproc */ /* Comment.PreprocFile */ /* Comment.Single */ /* Comment.Special */ /* Generic.Deleted */ /* Generic.Emph */ /* Generic.Error */ /* Generic.Heading */ /* Generic.Inserted */ /* Generic.Output */ /* Generic.Prompt */ /* Generic.Strong */ /* Generic.Subheading */ /* Generic.Traceback */ /* Keyword.Constant */ /* Keyword.Declaration */ /* Keyword.Namespace */ /* Keyword.Pseudo */ /* Keyword.Reserved */ /* Keyword.Type */ /* Literal.Number */ /* Literal.String */ /* Name.Attribute */ /* Name.Builtin */ /* Name.Class */ /* Name.Constant */ /* Name.Decorator */ /* Name.Entity */ /* Name.Exception */ /* Name.Function */ /* Name.Label */ /* Name.Namespace */ /* Name.Tag */ /* Name.Variable */ /* Operator.Word */ /* Text.Whitespace */ /* Literal.Number.Bin */ /* Literal.Number.Float */ /* Literal.Number.Hex */ /* Literal.Number.Integer */ /* Literal.Number.Oct */ /* Literal.String.Backtick */ /* Literal.String.Char */ /* Literal.String.Doc */ /* Literal.String.Double */ /* Literal.String.Escape */ /* Literal.String.Heredoc */ /* Literal.String.Interpol */ /* Literal.String.Other */ /* Literal.String.Regex */ /* Literal.String.Single */ /* Literal.String.Symbol */ /* Name.Builtin.Pseudo */ /* Name.Variable.Class */ /* Name.Variable.Global */ /* Name.Variable.Instance */ /* Literal.Number.Integer.Long */

改行されておらず、可読性が低いので整形します。

パッケージインストール

$ sudo apt install python3-cssutils

以下のように Python スクリプト作成

$ cat test.py
#!/usr/bin/env python3

import cssutils

sheet = cssutils.parseFile('build/html/_static/res.css')
print(sheet.cssText.decode())

CSS ファイルを整形

$ ./test.py > build/html/_static/res2.css

res2.css の中身を見ると、整形されていることを確認できます。



2017年8月12日土曜日

2段階認証プロセスを使用した Google アカウントを使って Python からメール送信

Google のメールサーバーを使って Python からメール送信する場合、スクリプト内部にて Google アカウントでメールサーバーにログインする必要があります。

しかし、ログインに使用する Google アカウントに 2段階認証プロセスが使われている場合は Google サービスへのログインパスワードではなく、アプリパスワードを Google のサイトで生成し、このアプリパスワードでメールサーバーにログインする必要があります。


Google アカウントのアプリパスワードを生成

このあたりを参考にしてアプリパスワードを生成します。

https://support.google.com/mail/answer/185833?hl=ja


Python スクリプトからメール送信

以下の内容でメールを送信するサンプルコードです。

サンプルコード

#!/usr/bin/env python3

from smtplib import SMTP
from email.mime.text import MIMEText
from email.header import Header

GOOGLE_ACCOUNT = 'example@gmail.com'
APP_PASSWORD = 'xxxxxxxxxxxxxxxx'

def send_mail(to_addrs, subject, mail_body, sub_type='plain'):
    smtp_server = 'smtp.gmail.com'
    port = 587
    from_addr = GOOGLE_ACCOUNT
    encoding = 'utf-8'

    msg = MIMEText(mail_body.encode(encoding), sub_type, encoding)
    msg['Subject'] = Header(subject, encoding)
    msg['From'] = from_addr
    msg['To'] = ', '.join(to_addrs)

    server = SMTP(smtp_server, port)
    server.starttls()
    server.login(GOOGLE_ACCOUNT, APP_PASSWORD)
    server.sendmail(from_addr, to_addrs, msg.as_string())
    server.quit()

body = '''
ほげほげ
ふがふが
ぴよぴよ
'''.strip()

send_mail(['addr1@xxx.example.net', 'addr2@yyy.example.net', 'addr3@zzz.example.net'], 'テストメール', body)

HTML メールを送信

HTML メールを送信する場合は send_mail() の引数 sub_type に ‘html’ を指定します。

html_body = '''
<table border=1>
    <tr><th></th><th>あああ</th><th>いいい</th></tr>
    <tr><td>ううう</td><td>えええ</td><td>おおお</td></tr>
    <tr><td>かかか</td><td>ききき</td><td>くくく</td></tr>
    <tr><td>けけけ</td><td>こここ</td><td>さささ</td></tr>
</table>
'''.strip()

send_mail(['addr1@xxx.example.net', 'addr2@yyy.example.net', 'addr3@zzz.example.net'], 'テスト HTML メール', html_body, 'html')