カレーのライスをtech忘れ

odmishienのtechメモ

git submodule foreach とかあるんだ

  • よくsubmoduleのあるリポジトリで Pull したり Push したりしていたら知らず知らずのうちにsubmodule内にdiffができてしまっていて、それを消さないとずっとvscodeの左のバーに通知バッチみたいなものが出てしまって鬱陶しい

  • これまでは素朴に cd /path/to/module/ としてから git reset --hard みたいなことをして差分を取り消していた

  • しかしこれが大規模なプロジェクトになればなるほどsubmoduleの数も増えるのでこの作業を繰り返すことが増える

  • つらい

  • 調べてみると、やはり便利コマンドが存在していた

blog.jubatus.tokyo

  • やはりこの世界は巨人の肩に乗っているという気持ちでいた方がよくて、自分がつらいと思ったことは先人の誰かもすでにつらいと思っていたことなのできちんと調べたほうがいい

eDEX-UIを導入してみた

SF大好きっ子なら、いつでも開発環境をかっちょ良くしたいと願っているはずですよね。ということでTwitterで見かけてかねてから気になっていた eDEX-UI を導入してみました。

github.com

インストール

> git clone https://github.com/GitSquared/edex-ui.git
> cd edex-ui
> npm run install-linux

これでMacOSX用に必要なモジュール類は入るはず。

起動

> npm start

aliasを仕込んでおいたら1コマンドで実行もできますね。

設定のカスタマイズ

グローバルな設定は全て ~/Library/Application\ Support/eDEX-UI/settings.json に書いてあります。

github.com

Wikiにもいじれるパラメータがまとめられています。

{
shell:zsh //zshも使える
cwd:/Users/{Username} //ホームディレクトリ指定
keyboard:en-US
theme:my-tron-fulltype //ここでテーマを指定できるので新しいテーマを作ってみた
termFontSize:15
audio:true //今はtrueにしているが結構うるさい
disableFeedbackAudio:false
pingAddr:1.1.1.1
port:3000
nointro:false
nocursor:false
allowWindowed:false
excludeSelfFromToplist:false
hideDotfiles:false
experimentalGlobeFeatures:false
experimentalFeatures:false
}

テーマのカスタマイズ

github.com

背景色や文字色、フォントなどいじれます。また injectCSScss形式で各ウインドウのレイアウトをいじれます。cssセレクタはメニューの View > Toggle Developer ToolsChromeのDeveloper Toolsと同じようなものが立ち上がるのでそれで確認できます。自分はこんな感じに設定。

動く、動くぞ!!!

youtu.be

SFだ〜〜。

SeleniumでChromeheadlessを使う際に要素がVisibleにならずTimeOutになってしまう

とあるaタグのhref要素を取得したい。Pythonで書いています。

button = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.ID, "id-of-element")))
detail_menu_url = detail_menu_button.get_attribute("href")

しかしChromeのheadlessモードを使う際、実際に手元のブラウザでは要素を取得できるのにheadlessモードにした途端、要素にアクセスできず以下のようなタイムアウトエラーが出ていました。

2019-04-08T09:40:08.451051+00:00 app[run.3736]: Traceback (most recent call last):
2019-04-08T09:40:08.451085+00:00 app[run.3736]: File "app.py", line 134, in <module>
2019-04-08T09:40:08.451471+00:00 app[run.3736]: main()
2019-04-08T09:40:08.451477+00:00 app[run.3736]: File "app.py", line 129, in main
2019-04-08T09:40:08.451753+00:00 app[run.3736]: pay_money, pay_amount, pay_day = confirm_card_payment()
2019-04-08T09:40:08.451760+00:00 app[run.3736]: File "app.py", line 93, in confirm_card_payment
2019-04-08T09:40:08.452013+00:00 app[run.3736]: detail_menu_button = WebDriverWait(driver, 30).until(EC.element_to_be_clickable((By.ID, "toDetailsDetailRelayFirst")))
2019-04-08T09:40:08.452038+00:00 app[run.3736]: File "/app/.heroku/python/lib/python3.6/site-packages/selenium/webdriver/support/wait.py", line 80, in until
2019-04-08T09:40:08.452257+00:00 app[run.3736]: raise TimeoutException(message, screen, stacktrace)
2019-04-08T09:40:08.452322+00:00 app[run.3736]: selenium.common.exceptions.TimeoutException: Message:

うーん。つまりどれだけ待ってもvisibleにならない=Chromeheadlessには見えていないということか。検索して解決策発見。

stackoverflow.com

I think the problem is, that the Element is really not visible in the default viewbox (600x800) of Headless Chrome.

なるほど。Windowサイズを指定しよう。

options.add_argument('window-size=1200,1100')

Flask + Tweepy でTwitterOAuth周りを触った

きっかけ

  • Twitterでバズるのって本当にTweetの中身が伴っているからバズってるのか、そのユーザの持つ特性とかがあって初めてバズってるのかよく分からないなあと思って完全に匿名のTwitterクライアントwebアプリを作ってみようと思い立ったのがきっかけ。

コード

from flask import Flask, render_template, request, redirect, session
import tweepy
import logging
import os

CONSUMER_KEY = 'YOUR CONSUMER_KEY'
CONSUMER_SECRET = 'YOUR CONSUMER_SECRET'
CALLBACK_URL = 'http://localhost:8000/'

app = Flask(__name__)
app.secret_key = 'なんでもいい'

@app.route('/')
def index():
    tweets = get_tweets()
    return render_template('index.html',tweets=tweets)

@app.route('/login',methods=['GET'])
def login():
    auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET, CALLBACK_URL)
    try:
        redirect_url = auth.get_authorization_url()
        session['request_token'] = auth.request_token
    except tweepy.TweepError as e:
        logging.error(str(e))
    return redirect(redirect_url)

def get_tweets():
    token = session.pop('request_token', None)
    verifier = request.args.get('oauth_verifier')
    if token is None or verifier is None:
        return False
    auth = tweepy.OAuthHandler(CONSUMER_KEY,CONSUMER_SECRET,CALLBACK_URL)

    auth.request_token = token
    try:
        auth.get_access_token(verifier)
    except tweepy.TweepError as e:
        logging.error(str(e))

    api = tweepy.API(auth)
    return api.home_timeline(count=100)

if __name__ == '__main__':
    app.run(debug=True,port=8000)

ハマったポイント

①そもそもTwitterOAuth認証の仕組みが分からん

コードはこちらを参考にしました

やってることは

1.twitterからリクエストークンを取得する

2.twitter.comにリダイレクトしてユーザーにアプリケーションを承認してもらう

3.コールバックを使用している場合、twitterはユーザーをアプリケーションにリダイレクトします。それ以外の場合、ユーザーは手動で検証コードを入力する必要があります。

4.承認されたリクエストークンとアクセストークンを交換します。

TwitterのDeveloper向けAppの仕様が若干変わっていた

OAuthがなかなかうまくいかず、KEYもSECRETも正しいはずなのに... ずっと出ていたエラーがこちら。

Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings.

なんだと?Callback URLをTwitterAppを作ったものと同じものにちゃんと設定しないといけないらしい。前触った時はCALLBACKURLとかテキトーに設定した記憶しかない。 http://localhost:8000 に設定すれば無事動きました。

認証周りだけでかなり躓いてしまって萎えました。

参考サイト

github.com

Perlの比較演算子でハマった

研修中に書いたコードでPerlでは文字列と数で比較演算子の書き方が違うというレビューをいただき、調べてみることに。Pythonでは全部==で Nullの評価だけisを使っていた記憶。

比較演算子(数値)

演算子 意味
== 等しい
!= 等しくない
>= 以上
<= 以下
> より大きい
< より小さい
<=> 比較1

比較演算子(文字列)

演算子 意味
eq 等しい
ne 等しくない
ge 以上
le 以下
gt より大きい
lt より小さい
cmp 比較1

文字列の方は覚えやすい。equall, not equal, greater or equal, less or equal, greater than, less than, compareてことかな?

参考サイト

比較演算子 - Perlリファレンス