Terasannのチラ裏

「それはTeraさんに聞け」を目指すブログ

無慈悲な進捗チェッカーを作ってみた。

研究、仕事、恋愛。そして筋トレ。

何事もコツコツやることが大事ですね。

コツコツとやっていればいずれ結果は出る。良かれ悪かれ。

最近サボリ気味なので そんな自分に活を入れてくれるようなそんな進捗チェッカーを作った。

仕様

  • ディレクトリ内のファイルの更新が24時間以内に行われてるか確認
  • 行われていたら何かしらの進捗あり -> ご褒美画像をTweet
  • 何にも進捗無い -> 追い詰める画像をTweet

なんというシンプル!

どんなことになるのかというとこんな感じ

f:id:kch-bone:20150301022130p:plain

最後の方よくわからない画像がありますけど気にしない。 実験用アカウントなのでツイート数がすごいことになってますが笑

プログラムはシェルスクリプトPythonで構築しています。

24:00になるとcronに登録しておいたシェルスクリプトが実行されます。

シェルスクリプトは監視対象のディレクトリ内のファイルの更新状況を確認します。 更新状況の確認には find コマンドを用います。

find ./* -mtime -1 -type f|wc -l

24時間以内に更新されているファイルの数をカウントします。

シェルスクリプトの結果を変数に格納する場合は``で括ります。 こんな感じ

var=`find ./* -mtime -1 -type f|wc -l`

これでvarに更新されたファイルの数が入ります。あとはif文で比較するだけ!

コードはGithubにあげておきます。

ちなみにただアップロードされるというわけではなく好きな画像をランダムで選択し、「頑張りました!」の文字を挿入します!

こんな感じ

f:id:kch-bone:20150301031625p:plain

篠崎愛

f:id:kch-bone:20150301031859p:plain

吉木りさ

画像は適当にクロールして持ってきました。

wgetでグーグル画像検索からね。

以下は画像に文字を挿入するプログラムです。 画像サイズはバラバラなので、ある程度統一させます。

# -*- coding: utf-8 -*-
from PIL import Image, ImageDraw, ImageFont, ImageFilter

import sys

param = sys.argv

# 背景画像を開く
if param[1] == None:
    print "srcfile none"
src = Image.open(param[1])

sx = src.size[0]
sy = src.size[1]

#resizeを行う
if sx > sy :
    length = src.size[0]
else:
    length = src.size[1]

if length > 600:
    while length > 600:
        length = int(length*0.9)
        sx = int(sx*0.9)
        sy = int(sy*0.9)

else:
    while length < 600:
        length = int(length*1.1)
        sx = int(sx*1.1)
        sy = int(sy*1.1)


    
src.show()
img = src.resize((sx, sy), Image.ANTIALIAS)

# フォントセット
textFont = ImageFont.truetype("/System/Library/Fonts/ヒラギノ角ゴ ProN W6.otf", 40)
# テキストを貼り付ける Image を生成
textImg = Image.new("RGBA", (300, 100), (0, 0, 0, 0))
tmpDraw = ImageDraw.Draw(textImg)
# 貼り付けるテキスト

if int(param[2]) == 1:
    text = u"頑張りました!"
else:
    text = u""
# 影分を先に貼り付ける
tmpDraw.text((12, 2), text, font=textFont, fill="rgb(176, 196, 222)")
# 本体文字を貼り付ける
tmpDraw.text((10, 0), text, font=textFont, fill="black")
# 5 度傾ける
textImg = textImg.rotate(5)
# 背景画像に貼り付ける
img.paste(textImg, (sx-300, sy-100), textImg)
# 画像保存
img.show()
img.save("./output.png")

MarkdownをPDFとして書き出す!(環境構築手順書とか)

研究室で毎年やることになるサーバ構築。

誰もが最初は失敗する開発環境設定。

作業手順書を作りたいけどWordだとコード見づらい!色分けされない!

ならMarkdownでやりましょう。

PDFにするとこんな感じ

f:id:kch-bone:20150219224132p:plain

ちゃんとタイトルで章分けされてます!

すごい!!!

これならプログラムのレポートも見た目が綺麗になっていいね!

MarkDownのままで送ればいいんじゃない?

と思う人もいますが

いろんな環境で見てもらったり長期で保存するときにはXMLだったりPDFだったりのほうがいいわけです。(個人的に)

MarkdownがPDFに変換できたらなぁ。。。

って思っていたら先駆者がいました。

参考 : PandocでMarkdownからPDF変換

こちらを参考にしています。

今回の環境はLubuntu14.04です。。

まずpandocをいれます。

pandoc --version
sudo apt-get install pandoc

pandoc target.md -o target.pdf

できない。 これでできたら苦労しないよね笑 pdflatexいれないとなのか...

sudo apt-get install texlive-lang-cjk

pandoc target.md -o target.pdf -V documentclass=ltjarticle --latex-engine=lualatex

だめです。足りないパッケージを検索してこなくてはなりません。

apt-get search で どのパッケージ入れればいいのか検索。

luaotfload.sty が無いらしいので

apt-cache search luaotfload

で検索!

aptの検索コマンドなんて初めて使った笑

どうやら texlive-luatex - TeX Live: LuaTeX packages ってパッケージが必要らしいです。

sudo apt-get install texlive-luatex
apt-get install texlive-xetex
 pandoc install-log.md -o install-log.pdf -V documentclass=ltjarticle --latex-engine=lualatex

途中eu2enc.defがないよっていわれるので eneucパッケージに入ってるらしいです。 apt-cacheで検索したらxetexパッケージにあるそうな。

そんでもって早速書き出し!

pandoc target.md -o target.pdf -V documentclass=ltjarticle --latex-engine=lualatex

できました。

ありがとうPandoc!

PythonでコマンドラインにGIFを表示させる(Python&乃木坂)

この前こんなのを書いた

コマンドラインで画像を表示させる(Python&乃木坂46) - Terasannのチラ裏

コンソール画面に画像を表示できるようになった!

ってことでこんどはGIFを表示できないか考えてみる。

で、実装してみた。

するとこんな感じで表示される。あらまぁ便利

f:id:kch-bone:20150222020026g:plain

読み込んだのはこれ 乃木坂46西野七瀬ちゃん

なーちゃんgif

かわいい。

アニメーションであるのでできればファイルダウンロードのプログレスバーのように標準出力を上書きしていきたいところ。

プログレスバーとかは標準出力のCR(キャリッジリターン)っていう先頭を指すポインタみたいのを使っているらしい。ってかキャリッジリターンていうの!? ちなみにLFはラインフィード!

pythonで実装した例が検索したら、ちらほら発見できた。

しかし複数行で行ってるという記事は見当たらなかった。

参考サイトからまずカウントダウンのコードを入手。

参考 : コンソールへの出力を上書きしてゆく方法

うむ。いい感じに動いている。

つづいて改行コードを忍ばせる。

失敗。

どうやら改行コードが入ってしまうとダメ。

CRで戻れるのはその行の先頭らしい。

これはスペースをコンソール目一杯に埋めて改行っぽくしてもダメだった。(試してみた)

どうしよう

ってことでclearコマンドを使うことにした。

python

   os.system("clear")

こんな感じでコンソールをクリアできる。 クリアって言っても消すわけではないみたい。 消したわけではないのでスクロールすると見えてきます笑

つづいてgifの見れるコードを。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
created by keiichi 
"""

from PIL import Image
from PIL import ImageOps
import os

import sys, time

def ascii(pmatrix, sx, sy, columns):

    tab = ""
    tablen = 0

    if columns <= sx:
        sx = columns
        columns = 0
    else:
        tablen = columns - sx*2
        for i in xrange(tablen):
            tab = tab + " "

    line = ""
    for y in xrange(sy):
        sentence = ""
        for x in xrange(sx*2):

            gray = pmatrix.getpixel((x,y))

            """            
            if gray > 250:
                character = " "
            elif gray > 230:
                character = "."
            elif gray > 200:
                character = ":"
            elif gray > 175:
                character = "+"
            elif gray > 150:
                character = "*"
            elif gray > 125:
                character = "#"
            elif gray > 50:
                character = "@"
            
           
            if gray > 250:
                character = " "
            elif gray > 230:
                character = "."
            elif gray > 210:
                character = ":"
            elif gray > 190:
                character = "|"
            elif gray > 170:
                character = "/"
            elif gray > 150:
                character = "+"
            elif gray > 130:
                character = "*"
            elif gray > 110:
                character = "¥"
            elif gray > 90:
                character = "&"
            elif gray > 70:
                character = "$"
            elif gray > 50:
                character = "@"
            """

            if gray > 250:
                character = "@"
            elif gray > 230:
                character = "$"
            elif gray > 210:
                character = "&"
            elif gray > 190:
                character = "¥"
            elif gray > 170:
                character = "*"
            elif gray > 150:
                character = "+"
            elif gray > 130:
                character = "/"
            elif gray > 110:
                character = "|"
            elif gray > 90:
                character = ":"
            elif gray > 70:
                character = "."
            elif gray > 50:
                character = " "


            sentence = sentence + character
        line = line + sentence + tab
        
    return line


if __name__ == '__main__':

    try:


        param = sys.argv

        filename = 'logo.gif'

        if param[1] != None:
            
            filename = param[1]
            
        try:
            src = Image.open(filename)
            
        except IOError:
            print "Cant load", filename
            sys.exit(1)

        rows, columns = os.popen('stty size', 'r').read().split()

        size = 60
        sx =  src.size[0]
        sy =  src.size[1]
    
        if param[2] != None:
            size  = int(param[2])

        gif = []

        if (src.format == 'GIF'):
            try:
                while 1:
                    
                    try :
                            image = src.resize((size*2, size), Image.ANTIALIAS)
                            output_image = ImageOps.grayscale(image)
                            gif.append(ascii(output_image, int(size) , int(size), int(columns)))
    
                    except ValueError,UnboundLocalError:
                        pass
                    src.seek(src.tell()+1)
                    # 各フレーム毎の処理をする
    
            except EOFError:
                pass

            print len(gif)
            count = 2
            for i in xrange(count):
                for tgif in gif:
                    #sys.stdout.write("\r"+tgif)
                    os.system("clear")
                    sys.stdout.write('\r%s' % str(tgif))
                    sys.stdout.flush()
                    time.sleep(0.1)
        else:

            image = src.resize((size*2, size), Image.ANTIALIAS)
            #image.show()
            output_image = ImageOps.grayscale(image)
            print ascii(output_image, int(size), int(size), int(columns))
        

    except Exception as e:
        print '=== エラー内容 ==='
        print 'type:' + str(type(e))
        print 'args:' + str(e.args)
        print 'message:' + e.message
        print 'e自身:' + str(e)

PILにはGIFを分解できる関数があるのでそれを使いました!

参考 : Pillow/PIL/GifImagePlugin.py

ところがぎっちょん!あまりに高速なgifだとうまく抽出できなかった! こういうGIFたち↓

mario

なんでかなーっておもってちょっと調べて見たんだけど、GIFってframeの速度の設定があるらしい。そりゃそうだ。

参考 : あなたは大丈夫?高速GIFアニメになってしまう症

Pillow/PIL/GifImagePlugin.pyの110行目のところで

if frame != self.__frame + 1:
        raise ValueError("cannot seek to frame %d" % frame)

が起こっているっぽい。よくわかんないけど! ついでにPILが今現在対応しているGIFはGIF87 and GIF89ってことなのでそれ以外のGIFは再生できない。

GIFってこんなに種類のあるものなのね。

ちなみにPNGが登場したことで静止画用途でのGIFはほぼ消滅したそうな。

なかなか勉強になりました!

Gifが表示できるようになったからTerminalの起動もかっこよくなるできるかも!

目指すはアイアンマン2のディスプレイにハッキングをするシーン 58秒辺りから!


Iron Man 2 Hacking Scene - YouTube

Arch Linuxだとこんなかんじの表示だよね。いいなぁ〜。

作ってみようかな〜なんて笑

今日も良いPythonライフを!