F1大好きな、インチキ技術者の日記

F1大好きなインチキ技術者が情報を発信して、自分を変えようとしている日記です

Firefox for iOSを実機で動かす

2015/11/13 AppStoreにて正式にFirefoxが公開されました ですので、普通はもう自分でビルドしなくてもいいです。



Chromeも使いますが、Firefoxにとっても愛着を感じております。iOS版の開発も伝えられていましたが ソースが公開されているので、待ちきれずに自分でビルドしてみることにしました。

xcodeを使って実機デバッグできる環境が必要です。iOS Developer Programとかですね。 (円安でさりげなく値上がりしていますね)

手順は、 https://github.com/mozilla/firefox-ios に掲載されていますので その通り実行しました。

実は、「2. Install Carthage.」 を見逃していて5分ほど途方に暮れました

Cloneの中にある、 Client.xcodeproj を起動して、何も考えずにビルド。 エミュレーターでは上手く動きました!この調子で実機でもとんとん拍子に・・・と 甘い考えをしていたのですが、ダメでした(T-T)

失敗1 SendTo にてエラー

スクリーンショット 2015-04-30 15.22.22.png

SendToのプロパティを見るとTeamが「Unknow name」になっていたので自分のアカウントに修正

スクリーンショット 2015-04-30 15.25.45.png

アカウントを変更して、Fix Issueをクリックするも以下のエラーが出るのでBundle Identifier を適切な値に変更した。(jp.qiita.hanamiche.*にしました) 「An App ID with Identifier 'org.mozilla.ios.Fennec.SendTo' is not available. Please enter a different string.」

スクリーンショット 2015-04-30 15.30.14.png

失敗2 ShareTo にてエラー

SendToと同じように、ShareToもBundle Identifier を適切な値に変更した。

失敗3 とにかく Bundle Identifierを変更しまくる

とにかく、org.mozilla. や group.org.mozilla. の記載があると実機で実行できないので変更する

Client, SendTo, ShareToの「Keychain Sharing」「Add Groups」を適度に修正

ちなみに、swiftファイルに記載してある「org.mozilla.*」は修正不要

そしてついに動いた

IDの衝突で動かないだけなのでBundle Identifier周りを調整してあげれば後はビルドするだけで簡単に動きました!

やった!

IRCのログを日々Redmineに登録する

思い立った理由

IRCRedmineを業務で使っています。 IRCはログインしていない時のログが追えなかったり、基本的に各自のクライアントにログが残るためみんなで共有できないかな。と考えました。

Redmineに日々のIRCのログが残っていけばきっと良いこともあるはずと考えました。

開発環境

いろいろ迷いましたが、Windows版のLimeChatでログをテキストに保存してたのでそれをPowerShellRest API(Invoke-RestMethod)を使ってRedmineに登録することにしました。

前提条件

  • LimeChatのログファイル命名規則は: %c\%y%m%d-%s.log
  • ログを保存するにはずっとろIRCにログインしておかないといけない
  • Redmine REST APIが有効になっていること

ソースはこちら。 これをタスクスケジューラーで日々実行しています。

######################################################################
##                                                                  ##
## IRCのログをRedmineに登録するよ!                                 ##
##                                                                  ##
## このPowerShellをタスクスケジューラで1日1回実行中!               ##
##                                                                  ##
######################################################################
#本番用
$url = "【RedmineのURL】/issues.json"
$api_key = "【APIキー】"
$project_id = "irclog"

#HTTPヘッダ (認証ありだとBASIC認証用のヘッダも必要)
$headers = @{"X-Redmine-API-Key" = $api_key;
             "Authorization" = "【BASIC認証用のヘッダ (Basic : xxxxxxxxxxxxxxxxxxx)】"
}

#ログファイルのパス
$logfilepath = "【ログファイルのディレクトリパスを指定】"

#タイトルを作成
$subject = Get-Date (Get-Date).AddDays(-1) -Format "yyyy/MM/dd(ddd)のIRCログ"

#本文をログファイルから取得
$filename = $logfilepath + (Get-Date (Get-Date).AddDays(-1) -Format "yyyyMMdd") + ".log"
$files = Get-Content $filename
$description = ""

Foreach ($name in $files)
{
    #ここで、関係のないログは排除するようにする。正規表現で排除したいぞ!
    if( $name -match "^[0-9]{2}:[0-9]{2}:[0-9]{2} .*> " -eq $true ) {

        #投稿者の名前先頭4文字をclass指定する
        $span_class = $name.Substring(9,4)

        #きれいに見せるための苦肉の策
        $name = $name.Replace("  ", "  ");
        $name = $name.Replace(" #", " #");
        $name = $name.Replace("http://", " http://");
        $name = $name.Replace("https://", " https://");

        $name = "%(" + $span_class + " irclog)" + $name + "  %`r`n"

        $description = $description + $name
    }
}

if( $description.Length -gt 0) {

    # 絵文字エスケープ・・・これは無念だけど・・・
    $description = $description.Replace("^^;","<notextile>^^;</notextile>")
    $description = $description.Replace("(__)","<notextile>(__)</notextile>")
    $description = $description.Replace("(^_^)","<notextile>(^_^)</notextile>")
    $description = $description.Replace("(-_★)","<notextile>(-_★)</notextile>")
    $description = $description.Replace("<(_ _)>","<notextile><(_ _)></notextile>")
    $description = $description.Replace("T-T","<notextile>T-T</notextile>")
    $description = $description.Replace("(^-^)/","<notextile>(^-^)/</notextile>")


    # JSONを組み立てる
    $issue_json = @{"project_id" = $project_id; "subject" = $subject; "description" = $description; "tracker_id" = $tracker_id}

    #このissueに気がつくまで2時間はかかった・・・
    $parent = @{"issue" = $issue_json}

    #JSONに変換する
    $parent = $parent | ConvertTo-Json -Compress

    # WindowsのファイルがShift-JISで保存されているので、UTF-8に変換
    $parent = ([System.Text.Encoding]::UTF8.GetBytes($parent))

    try 
    {
        # Redmineへ登録
        Invoke-RestMethod -Uri $url -Method POST -Body $parent -Headers $headers -ContentType "application/json;"
    }
    catch { 
        # がっかり。エラー(手抜き)
        echo $_.Exception.Response 
    }
}

Redmineに無事に登録できました! Redmineに無事に登録できました

参考サイト

最後に

Redmine REST APIを使う事で、いろいろと自動化できそうと気がつくことができました。 例えば、特定のSubjectを含んだメールが来たらRedmineのチケットをつくるとか、IRCで特定の発言をしたらRedmineに登録するなど、夢が膨らみます。

あ、IRCRedmine操作するのは、Redmine-Chan ( https://github.com/onishi/Redmine-Chan )がすでにありますね!

CentOS 5.11 で SPDYを使いたい(その2 - GCCバージョンアップからの目的達成編)

前回の続き・・・

この投稿は、2014年11月06日にQiitaに投稿した物です。 前回無事にApacheのバージョンアップができたので喜び勇んでmod_spdyをインストールした。 でも、ここでもつまずいたのでログを残しておきます。

mod_spdyのインストール

rpm持ってきてインストールするだけ簡単簡単!

$ wget https://dl-ssl.google.com/dl/linux/direct/mod-spdy-beta_current_x86_64.rpm
$ sudo rpm -U mod-spdy-beta_current_x86_64.rpm
$ sudo service httpd restart

と思って速攻導入してみたら・・・Apacheが起動しない・・・ 以下がエラーの内容

Starting httpd: httpd: Syntax error on line 214 of /etc/httpd/conf/httpd.conf: Syntax error on line 1 of /etc/httpd/conf.d/spdy.conf: Cannot load /usr/lib64/httpd/modules/mod_spdy.so into server: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by /usr/lib64/httpd/modules/mod_spdy.so)
[FAILED]

どうやら、/usr/lib64/libstdc++.so.6が古いためGLIBCXX_3.4.11が無いというエラーのようだ・・・困った。 確認したら確かにない・・・

$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_FORCE_NEW

調査の結果GCCを新しくすれば良いようだが、ここはCentOS 5。yumで簡単にとはいかない・・・ 渋々ソースからコンパイルした 手順は、以下のページをそのままそっくり実行した。唯一の違いはバージョンが4.6.3って事くらい。

https://gcc.gnu.org/wiki/InstallingGCC

あと、makeに2時間くらい掛かりました・・・

GCCのビルド&インストールが完了したところで、インストールディレクトリをみると新しいlibstdc++.so.6.0.16ができてた。 念のため、中身も確認

$ strings $HOME/gcc-4.6.3/lib64/libstdc++.so.6.0.16 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.11
GLIBCXX_3.4.12
GLIBCXX_3.4.13
GLIBCXX_3.4.14
GLIBCXX_3.4.15
GLIBCXX_3.4.16
GLIBCXX_FORCE_NEW
GLIBCXX_DEBUG_MESSAGE_LENGTH

できてる! あとは、/usr/lib64にコピーしてシンボリックリンク作れば!

$ cp $HOME/gcc-4.6.3/lib64/libstdc++.so.6.0.16 /usr/lib64
$ ln -s libstdc++.so.6.0.16 libstdc++.so.6

ここまでやって、Apacheを再起動したら無事にSPDYが利用可能となりました!

CentOS 6を使えば本当に簡単に導入できるSPDYですがCentOS 5だとちょっと面倒でした。

CentOS 5.11 で SPDYを使いたい(その1 - Apacheバージョンアップ編)

はじめに

この投稿は、2014年11月05日にQiitaに投稿した物です。 お仕事の都合でCentOS 5.11(x64)のApacheでWebサーバを立てているのですが、どうしてもmod_spdyを利用したかったのでいろいろと作業しまました。そのログです。

mod_spdyのシステム要件

mod_spdyのrpmパッケージをダウンロードできるサイトmod_spdy — Google Developersで確認したところ要件は以下の2つのみ

System Requirements ・Apache 2.2 (≥2.2.4) ・mod_ssl enabled

mod_sslはすでに有効なので、Apacheのバージョンを確認した

# httpd -v
Server version: Apache/2.2.3
Server built:   Sep 16 2014 11:05:09

要件満たさず・・・ というわけで早速、Apacheのバージョンアップから!

Apacheのバージョンアップ

普通にyumしても最新版なので、CentALTリポジトリを有効にしてApacheをバージョンアップすることにした

まずは、リポジトリを使えるように・・・っと

# rpm -Uvh http://mirror.sysadminguide.net/centalt/repository/centos/5/x86_64/centalt-release-5-3.noarch.rpm

これで、CentALTリポジトリからApacheインストールできると思いきや、なんと403になる。。。

# yum --enablerepo=CentALT update httpd
Loaded plugins: fastestmirror
http://centos.alt.ru/repository/centos/5/x86_64/repodata/repomd.xml: [Errno 14] HTTP Error 403: Forbidden
Trying other mirror.
Error: Cannot retrieve repository metadata (repomd.xml) for repository: CentALT. Please verify its path and try again

調査したところ、ミラーサイトを指定しなければいけないようなので速攻対応

# vi /etc/yum.repos.d/centalt.repo
[CentALT]
name=CentALT Packages for Enterprise Linux 5 - $basearch
#baseurl=http://centos.alt.ru/repository/centos/5/$basearch/
baseurl=http://mirror.sysadminguide.net/centalt/repository/centos/5/$basearch/
enabled=0
gpgcheck=0

baseurlのみ変更し、いざ再実行!

# # yum --enablerepo=CentALT update httpd
Dependencies Resolved

========================================================================================
 Package                              Arch         Version           Repository    Size
========================================================================================
Updating:
 httpd                                x86_64       2.2.27-1.el5      CentALT      1.3 M
Installing for dependencies:
 apr-util-ldap                        x86_64       1.4.1-1.el5       CentALT       14 k
 httpd-tools                          x86_64       2.2.27-1.el5      CentALT       68 k
Updating for dependencies:
 apr-util                             x86_64       1.4.1-1.el5       CentALT       80 k
 httpd-devel                          x86_64       2.2.27-1.el5      CentALT      146 k
 httpd-manual                         x86_64       2.2.27-1.el5      CentALT      1.1 M
 mod_ssl                              x86_64       1:2.2.27-1.el5    CentALT       91 k

Transaction Summary
========================================================================================
Install       2 Package(s)
Upgrade       5 Package(s)

Total download size: 2.7 M
Is this ok [y/N]: 

おおっ!無事にApache 2.2.27がリストアップされています! そのまま"y"を押すと無事にバージョンアップされました!

# httpd -v
Server version: Apache/2.2.27 (Unix)
Server built:   Apr  9 2014 23:20:37

やったね(^_^)v

長くなったのでmod_spdyのインストールは次の投稿で・・・

SwiftでWKWebViewを使ってみた

はじめに*1

iPhone6やiOS8の発表も目前に迫り、iPhoneユーザのみなさまにおかれましては胸躍る季節かと思います。 そういう僕もo(^-^)oワクワク・・・ こう言うときは勉強に意欲が出るものです。

今回はiOS8の新機能の一つとして、今までSafariに独占されていたWebkit Frameworkがアプリでも使えるようになったので本当に簡単ですがWebkit Framework呼び出してWebページを表示するまで試してみました。

ちなみに、初めてのSwiftです。…o(;-_-;)oドキドキ♪

とにかく動かしてみる

今回は、Xcode6-Beta7を用いました、スクリーンショットはだめみたいなのでテキストだけでお届けします

手順

  • Single View Applicationでプロジェクトを新規作成
  • プロジェクト名は適当に決め、Languageは「swift」を選択
  • ViewController.swiftにコードを書く

ソース

僕が書いたコードは、番号が振ってあるコメント(「//1.WebKit Frameworkをimportする」など)部分のほんの数行です。というか・・・たったの7行ですね。。

import UIKit

//1.WebKit Frameworkをimportする
import WebKit 

class ViewController: UIViewController {

    //2.WKWebviewの宣言!
    var _webkitview: WKWebView? 
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //3.WebKitのインスタンス作成!
        self._webkitview = WKWebView()
        
        //4.ここでWebKitをviewに紐付け
        self.view = self._webkitview!

        //5.URL作って、表示させる!
        var url = NSURL(string:"http://www.yahoo.co.jp/")
        var req = NSURLRequest(URL:url)
        self._webkitview!.loadRequest(req)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

これで、ビルドして実行すると何もできませんがWebKitでWebページが表示されます! 変数宣言の"?"や、メソッド実行時の"!"などは、こちらのページで勉強させていただきました!

最後に

もちろんこのコードだけではアプリになりませんが、swift+Webkitでなんか楽しかったです。 iOS8が正式にリリースされたらベンチマークが公開されると思いますので楽しみにしています。 (個人的にはATOK for iOSが楽しみでなりません!)

*1:2014年09月06日にQiitaに投稿した記事です。

LinuxからWindowsにバッチでファイルを定期的に移動する方法(逆もできるよ!)

やりたいこと*1

ファイルをバックアップするときなど、LinuxからWindowsへ、WindowsからLinuxへファイルをコピーや 移動したい場合があります。

いろいろ方法はあると思うのですが、WinSCPでは.NET Assemblyが公開されているので使ってみることにしました。

必要なもの

説明

C#で作ろうかと思ったのですが、簡単にかけるPowerShellで作りました。 こちらの例では、Linuxのサーバ(sessionOptions.HostNameに指定)にあるファイルをWindowsのPC(PowerShellが動いているPC)に移動してます。

なお、パスワード(sessionOptions.Password)がコメントアウトしてあるのはpagentを用いてSSH鍵認証を行っているためです。必要であればパスワードを書いてください。

ほぼWinSCPのサイトにあるサンプルのままですけど(^_^)

try
{
    # Load Windows Form
    [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    
    # Load WinSCP .NET assembly (パスは環境によって変更してください)
    [Reflection.Assembly]::LoadFrom("C:\Program Files\WinSCP\WinSCPnet.dll") | Out-Null
 
    # Setup session options
    $sessionOptions = New-Object WinSCP.SessionOptions
    $sessionOptions.Protocol = [WinSCP.Protocol]::Sftp
    $sessionOptions.HostName = "【接続先ホスト名】"
    $sessionOptions.UserName = "【ユーザ名】"
    #$sessionOptions.Password = "【パスワード】"
    $sessionOptions.SshHostKeyFingerprint = "【フィンガープリント 例: ssh-rsa 2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx】"
 
    $session = New-Object WinSCP.Session
 
    try
    {
        # Connect
        $session.Open($sessionOptions)
 
        # Upload files バイナリモードを設定
        $transferOptions = New-Object WinSCP.TransferOptions
        $transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
        
        #リモートマシンの"/tmp/backup/*"を"C:\tmp\backup\"に「移動」。 3つめの引数を$FALSEにするとコピー
        $transferResult = $session.GetFiles("/tmp/backup/*","C:\tmp\backup\", $TRUE, $transferOptions)
 
        # Throw on any error
        $transferResult.Check()
 
        # Print results
        foreach ($transfer in $transferResult.Transfers)
        {
            Write-Host ("Download of {0} succeeded" -f $transfer.FileName)
        }
    }
    finally
    {
        # Disconnect, clean up
        $session.Dispose()
    }
    
    exit 0
}
catch [Exception]
{
    #エラーが出たらダイアログを出して気がついてもらう
    [System.Windows.Forms.MessageBox]::Show($_.Exception.Message, "バックアップエラー!",[Windows.Forms.MessageBoxButtons]::OK,[Windows.Forms.MessageBoxIcon]::Error);
    exit 1
}

後日追記

PowerShellをVersion3にしたところ、[Reflection.Assembly]::LoadFrom("C:\Program Files\WinSCP\WinSCPnet.dll") でエラーが出るようになった。

ファイルまたはアセンブリ 'file:///C:\Program Files\WinSCP\WinSCPnet.dll'、またはその依存関係の 1 つが読み込 めませんでした。操作はサポートされません。 (HRESULT からの例外:0x80131515)

さっぱり原因がわかりませんでしたが、WinSCPのフォーラムで意外な解決策が提示されてました。 Topic "Powershell : Could not load file or assembly winscp.dll"

[Reflection.Assembly]::LoadFrom("C:\Program Files\WinSCP\WinSCPnet.dll")

[Reflection.Assembly]::LoadFrom("\\C:\Program Files\WinSCP\WinSCPnet.dll")

に・・・ファイルパスの前に"\\"追加したら動きました。

もっと後日追記(2018/07/20)

久々にPCを入れ替えたら実行されなくなっていた。いろいろ調べた結果、dllファイルの「ブロック解除」が必要でした。

*1:2018年07月20日にQiitaに投稿した記事です。

Chrome37(x64)でMacTypeが無効になったときの対応

本日Chrome37が公開され64bit版も公開されました。*1 早速x64版をインストールしたらMacTypeが有効になっていない・・・

そんなときの対応方法です!

chrome://flags/ で設定画面をOpen!

スクリーンショット 2014-08-27 10.12.56.png

「DirectWrite を無効にする」を有効にする

否定の否定で難しい。。。

Chromeを再起動!

再起動したらMacTypeが有効になってる!ぱっと見わかりますねー。一安心。 スクリーンショット 2014-08-27 10.13.14.png

IEではDirectWriteを無効にするオプションがないのでぜひつけてほしいな。。。 いや、もっと言えば。。。 もっときれいにフォントをレンダリングしてほしいな。。。

*1:2014年08月27日にQiitaに投稿した記事です。