Gitでパスワードなどが入力されたファイルを履歴管理するとき
備忘録。
Gitを使って開発を進めている時に、なんらかのサービスのIDやパスワードなどの認証情報が記述されたファイルを扱いたいときがあります。
auth.conf
{ "ID": "foo", "PASS": "bar" }
開発中は自分のID/PASSを入力しますが、それをバージョン管理に乗せて公開したくはありません。
.gitignoreに記述すると、そもそも認証ファイル自体がバージョン管理に乗らないか、もしくは既にバージョン管理下にあるファイルに対しては.gitignore設定が効きません。
そんな時に使えるのがGitのskip-worktree。
既に git 管理しているファイルをあえて無視したい
最初にauth.confのサンプルファイルをadd/commitして、auth.confに対してskip-worktreeを設定すると、その後auth.confに自分のID/PASSを入力するなどの変更を加えてもステージングの対象とならないようになります。
MP3を結合してYouTubeにアップするものを作った
複数のMP3ファイルをくっつけてYouTubeにアップするものを作りました。
kaakaa/GroovyYouTubeUploader
バンドの練習で撮ったMP3群をYouTubeにアップする時に
とかやってて、不毛だと思ったので作りました。
mp3の結合とビデオ形式への変換はFFmpegを使ってます。
FFmpeg
YouTubeにアップする部分はYouTube Data APIのサンプルをちょっといじって。
youtube-api-samples - YouTube API Sample Applications - Google Project Hosting
詳しい説明はGithubに書いてるつもり…
-
-
- -
-
作ってる間に色々調べすぎてブラウザのタブ数がエラいことなっていたので吐き出しておきます。。
MP3ファイルに静止画を付けてビデオファイルに変換する
How to Encode Videos for YouTube and other Video Sharing Sites
Create a video with a still image (input.png) and an audio file (audio.ogg): ffmpeg -loop 1 -r 2 -i input.png -i audio.ogg -c:v libx264 -preset medium -tune stillimage -crf 18 -c:a copy -shortest -pix_fmt yuv420p output.mkv
ffmpegはオプションが多くて難しいけど、凄く便利そう。
Google Developer Consoleでアプリケーションを登録したのに、ファイルがアップロードできない
google api - Error: invalid_client no application name - Stack Overflow
"PRODUCT NAME"と"Email address"の設定も必要らしい。
YouTube Data APIでアップロードする動画の公開範囲を変更したい
VideoStatus (YouTube Data API v3 (Rev. 94) 1.17.0-rc)
VideoStatus#setPrivacyStatus(String privacyStatus)で設定可能。
設定出来るのは
- public(公開)
- unlisted(限定公開)
- private(非公開)
一応、今回作ったアプリではconfファイルで設定可能にしました。
MavenプロジェクトをGradleプロジェクトに変更する
PowerPoint資料のアップローダ的なもの
Linux上で動作するパワポアップローダを作ってる。
kaakaa/PPTGallery
パワポの資料共有にファイルの配布じゃなく、Web上で完結できるように出来ないかな〜というのが始まり。
ファイルダウンロードして開くのが面倒に感じたのと、Sinatraと諸々のツール使えば出来そうだったので。
ppt/pptxのファイルをアップロードすると、諸々変換かかって、PNGをスライド形式で閲覧できるHTMLのビューワが生成されます。
現状、CentOS6.3での動作を確認しています。
環境構築はChefのcookbook化しようとしてるけど、イマイチ上手く動かない…。
kaakaa/PPTGallery_vagrant
まぁ、とりあえず必要なツール一覧として残しています。
内部構造としては諸々の変換ツールのWebインタフェースをSinatraで作っただけな感じ。
GStringの評価タイミングを勘違いしてた
GStringヒアドキュメント?で記述したスクリプトをGroovyShell#evaluateで評価しようとした時に、GString内のプレースホルダーが評価される場所を勘違いしていてハマったという話。
GString内のプレースホルダーはevaluateの前で評価される。
GString interpolation not working with GroovyShell ?
以下、経緯。
GroovyDSLを作ろうとしてGStringでハマった。
あとから要素を追加しやすいよう、methodMissingを使って動的にプロパティを追加できるようにしました。
def dsl = """\ person { name('Foo') age('28') } """ def script = """\ def person(Closure closure) { def person = new Person() closure.delegate = person closure() println person.profile() } class Person { Person() { def mc = new ExpandoMetaClass( Person, false, true) mc.initialize() this.metaClass = mc } // ここで動的にプロパティを追加したい def methodMissing(String name, args) { this.metaClass."${name}" = args[0] } def profile(){ this.properties } } """ new GroovyShell().evaluate("""\ ${dsl} ${script} """)
実行するとエラー。
Exception thrown groovy.lang.MissingPropertyException: No such property: methodName for class: ConsoleScript30 at ConsoleScript30.run(ConsoleScript30:8)
methodMissingに引数methodNameが上手く渡って無いのが原因かと思い、
def methodMissing(String methodName, args) { def methodName = 'hello' this.metaClass."${methodName}" = args[0] }
とかしてみたけど変わらず。
エラーの原因は一番上に書いた通りなので、変数dsl,scriptの宣言をGStringでなくシングルクォートのヒアドキュメントにしたら動きました。
def dsl = '''\ person { name('Foo') age('28') } ''' def script = '''\ def person(Closure closure) { def person = new Person() closure.delegate = person closure() println person.profile() } class Person { Person() { def mc = new ExpandoMetaClass( Person, false, true) mc.initialize() this.metaClass = mc } // ここで動的にプロパティを追加したい def methodMissing(String methodName, args) { this.metaClass."${methodName}" = args[0] } def profile(){ this.properties } } ''' new GroovyShell().evaluate("""\ ${dsl} ${script} """)
[class:class Person, age:28, name:Foo]
TracWikiで投稿時間を表示するマクロについて考える
とりあえず調べたところまでを残しておく。
TracWikiに書き込んだ時間を残しておける機能が欲しくて色々調べてる。
Pukiwikiの"time?"みたいな記法。
TimestampMacroなんてのもあるけど、コレはページを更新した時間を表示するものなので、目的とは違う。
あくまでも表示したいのは書き込んだ時間。
TracDBのWikiテーブルを見ると、Wiki記法から生成されるHTMLは保存されておらず、TracWiki記法のテキスト保存されていないようなので、ページをレンダリングする時にparseなりしてHTMLを生成しているんだと思う。
(パーサを調べてみるのも面白そうだなぁ… TracのWikiパーサを読むAdd Star)
なので、DBに格納される前にちょろまかさないとレンダリングされる度に時刻が更新されてしまうことになる。
とりあえずTracのソースをちょろちょろ見てみると、${TRAC_HOME}\python-lib\trac\trac\wiki\model.pyのsaveメソッドでWikiに書き込んだ情報をDBに格納しているみたい。
def save(self, author, comment, remote_addr, t=None, db=None): if not validate_page_name(self.name): raise TracError(_("Invalid Wiki page name '%(name)s'", name=self.name)) new_text = self.text != self.old_text if not new_text and self.readonly == self.old_readonly: raise TracError(_('Page not modified')) t = t or datetime.now(utc) @self.env.with_transaction(db) def do_save(db): cursor = db.cursor() if new_text: cursor.execute(""" INSERT INTO wiki (name,version,time,author,ipnr,text, comment,readonly) VALUES (%s,%s,%s,%s,%s,%s,%s,%s) """, (self.name, self.version + 1, to_utimestamp(t), author, remote_addr, self.text, comment, self.readonly)) self.version += 1 self.resource = self.resource(version=self.version) else: cursor.execute("UPDATE wiki SET readonly=%s WHERE name=%s", (self.readonly, self.name)) if self.version == 1: # Invalidate page name cache del WikiSystem(self.env).pages self.author = author self.comment = comment self.time = t for listener in WikiSystem(self.env).change_listeners: if self.version == 1: listener.wiki_page_added(self) else: listener.wiki_page_changed(self, self.version, t, comment, author, remote_addr) self.old_readonly = self.readonly self.old_text = self.text
DBに格納する前にself.text内の「time?」だか何だかの正規表現でひっかけて置換かければ出来ないことはなさそうだけど、悪手な臭いがしてためらっている。
Tracが用意してる拡張ポイントでも無いし、{{{ 〜 }}}で囲んだ部分のも置換してしまうだろうし。
まぁ、とりあえず今日はここまで。
Middleman-blogとGithub Pagesを利用したブログ
勉強会用資料。
広く浅く。
質問
Webサービスの値段はどれぐらい?
GitHub · Build software better, together.
Travis CI: Continuous Integration and Deployment That Just Works
Coveralls - Test Coverage History & Statistics
Gemnasium
Pricing - Code Climate
TraviceCIとCode Climateは特段高価。
他は、まぁ恩恵あるなら払っても良いかぐらいな値段ですね。
払わないけど。
静的HTML生成ツールであるMiddlemanでコメント欄とかどうすんの?
Disqusというサービスと使ったりするらしいです。
Using Disqus
ただ、1ページに1枠しか設置できないみたいなので、ブログもそれに合わせたレイアウトになりそう。
各日ごとにコメントがそれぞれ保存できたりするんかな?ちょっと使ってみないと分からない。
TravisCIなどからGithubへのPushはどうやってフックする?
Step four - Trigger Your First Build With a Git Push
Once GitHub hook is set up, push your commit that adds .travis.yml to your repository. That should add a build into one of the queues on Travis CI and your build will start as soon as one worker for your language is available.
「リポジトリへのPushによってビルドキューに貯まる」という記述を見ると、Github側からビルドキューを投げてる感じでしょうか?
はてなダイアリーの記事をMarkdown形式に一括変換
はじめに
はてな記法があまり好きになれないのとフロントエンドを触るために、ブログをGithub Pagesに移行しようと思っている。
middleman-blogをgithubでホストする
middlemanを使えば好きなエディタで記事書けるし、記法も最近よく使うMarkdownを使えるので便利そうだな、と。
そのために今まではてなで書いてきた記事を、Markdown形式にして移行できないか調べてみた。
調査
とりあえずはてなの記事を取得するのはAtomPub使えば良さそう。
はてなダイアリーAtomPub - Hatena Developer Center
認証突破にはwsseを使う。
RubyでAtompubのWSSE認証 - Panty's
取得したAtomの解析にはREXMLを。
XML処理 REXMLの使い方 - プログラムメモ
記事HTMLをMarkdown形式に変更するにはPandocを使うと良さそう。
Pandoc - About pandoc
Rubyのラッパーもあるし。
alphabetum/pandoc-ruby
成果物
作ってみた。
kaakaa/hatena2md
とりあえず大まかには変換できてるけど、middleman-blogに読み込ませると表示がおかしな部分が多々…。まぁ、昔の記事へのリンク貼っておけば良いか。
あと、middleman-blog用のMarkdownなのでタイトルやタグなどのヘッダがついてます。