頭の中は異空間

ものづくり中心

Chrome拡張機能追加時に出る「アクセスしたウェブサイト上にある自分の全データの読み取りと変更」って何?

google extensionを追加するとき、ちょっと怖い警告が出てくることが多いです。今更ですが気になってちょっと調べてみたら以下の記事が見つかりました。
英語版だと「it can Read and change all your data~」と出るのでそっちでググってます。
www.howtogeek.com
これによると、

  1. google extension storeではその警告を出すことがレギュレーションになってる=>この警告自体を気にしても仕方ない
  2. ただし、一部警告が出ない滅茶苦茶シンプルなextensionもあるらしい(上記記事だとGoogle Hangouts)=>extensionがサイトの情報を閲覧しないことが明確な場合は警告を出す必要がない
  3. 警告が出るのはあくまで、特定のサイトのデータをextensionが閲覧する場合。例としてSave to Google Driveが挙げられている

このような解釈になると思われます。


ブラウザメーカーがすべてのextensionについて検証しているわけではないとあるので、おそらくメーカー側としては保険として出している、という意味合いもあるでしょう(問題の原因がextensionだったとしてもブラウザメーカーにケチをつける人が出てくる恐れがある)。


記事の下の方でextensionが契約番号等を収集できてしまう可能性がある点が危険という風なことを言っていますが、それを危惧するのであれば、拡張機能管理からサイトへのアクセス項目を、「クリックされた場合のみ」もしくは「特定のサイト」にしておけば不意にデータを取られる心配はなくなります。


評価基準としては

  1. Googleなど良く知られている会社が作っている場合=>まあ安全
  2. 全く知らない第三者が値作っている場合はちょっと危険
  3. 利用者が多くstoreで高評価されている場合(レビュー含む)、かつchrome extension store以外のブログで評価されている場合なんかは安全

とあります。私はレビューの中身もサクッと読んでみて明らかにこれは危険だと判断するに足る情報が見つかれば断念しますが、上記基準で何ら問題ないかなと考えます。また、できたばかりでなく長く使われているか、も選択基準としては大事だと思います。

【Django】ローカルでキャッシュバスティングをして、staticファイルを即時反映させよう

もうwebで開発をするのなら当たり前ですがjsやcssの修正を反映させるにはキャッシュをどうにかしないといけません。
Django初心者の私が軽く調べてみたところ、Djangoには最初からその機能が備わっているとのこと。
blog.xoxzo.com
Djangoでは本番にデプロイするときに一箇所にstaticファイルを集める仕様になっており、そのときに機能する機能(激寒ギャグ)ということだと思います。じゃあローカルではどうやるのと。

django-static-md5urlを使ってみたところローカルだとどうもうまく機能してくれないので、仕方なくキャッシュバスティングの部分は自作することにしました。
早速コードから。


views.py

import random, hashlib

これも同じくviews.pyに

def get(self, request, *args, **kwargs):
    ...
    hash = hashlib.sha256(str(random.random()).encode()).hexdigest()
    ...
    return render(request, 'myapp/index.html', {'form': form, 'hash': hash})

hash値を保存し、
sha256の部分はお好みで(sha224, sha512など。値の長さが違ったりするけど)。

{% block extrahead %}
    <link href="{% static 'myapp/css/app.css' %}?v={{ hash }}" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="{% static 'myapp/js/app.js' %}?v={{ hash }}"></script>
{% endblock %}

こんな感じで書けば?v=の先が毎回ランダムなhash値となり、十分なhashの長さならhashの衝突もまず起こらないので不自由なく修正直後に反映させることができます。

【Django】何もしてないのに急にコードが動かなくなったらバージョンを疑えという話

Djangoでログイン、ログアウトを実装中のあるとき、logoutを読み込もうとするともうないのでエラーが返されるようになりました。なんでじゃ。

    from django.contrib.auth.views import logout, LoginView
ImportError: cannot import name 'logout'

それまで正常動作していたのが急に落ちるなんてありません、が直近で何かしたかなと思い返すとselect2をpip installしただけなのですがそれによってDjangoのバージョンまで勝手にアップグレードされてました。
f:id:notwo:20190920083640p:plain
(Collecting django >= 2.0のあたり)
こんな感じのログが出てました。よく見ると、たしかに既存の古いDjangoがアンスコ&要件を満たす新バージョンのDjangoがインストールされているじゃあーりませんかー。この機能、便利っちゃ便利です、しかし結果的にDjango1系で動作していたコードが2系で動かなくなってしまいました。

私の手元の環境のDjangoのバージョンが1.11.1→2.2.5となっていたせいで、1系で使えたlogoutを読み込めなくなっていたのが原因だったわけですが、これpipの仕様を知らないと結構引っかかりやすい罠じゃないかなあと思います。知らないほうが悪い、となりそうですが。

Djangoは1系と2系で一部書き方が違うことがあるので、他のサイトを参考にするときも、Djangoのバージョンが何かを絶対に見るようにしよう、ということになります。まぁこれはDjangoに限った話ではないですね。

【Django】heroku local実行時にstaticファイルが必ず404になる件

今回からはてな記法に変えてみました。コードにシンタックスハイライトを楽につけるにはこうするしかなかったのです。

Djangoでstaticファイルをただ読み込ませるというだけの単純なはずの作業で数日間大苦戦したので、このような邪悪は処罰しようと思い、後学のために残しておきます。

環境(執筆時)

Djangoのファイル構成

f:id:notwo:20190907160308p:plain
白枠はプロジェクト名の箇所です。アプリ名をuser_authとしています。

python manage.py startapp user_auth

でアプリ作成しました。
staticディレクトリがアプリ直下と、project_staticディレクトリがプロジェクト直下にそれぞれ配置されているのがわかると思います。
project_staticディレクトリには本番にデプロイする際にstaticファイルを配置するために必要なので今のうちに作ってしまいます。ここではローカルでの動きについてのみ触れますので、実際には使いませんが。

コード

以下でuser_auth/css/bootstrap.min.cssを読み込もうとしています。

アプリ名/base.html

{% load static %}

...

<link href="{% static 'user_auth/css/bootstrap.min.css' %}" rel="stylesheet">

settings.py

PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
STATIC_ROOT = os.path.join(BASE_DIR, 'project_static')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

このように設定してpython manage.py runserverとすると、404が出ずstatic以下のファイルが読み込まれます。実際にChromeで開発者ツール(F12)→Sourceとするとそこに読み込んだファイルが有ることでしょう。
手元で普通にDjangoの開発をするだけならこれで十分です。
ここまでの構造やコードについての解説は以下記事が大変優秀でした。
hideharaaws.hatenablog.com


しかし問題は、herokuと組み合わせる場合。全く同じディレクトリ構成とコードでheroku local web実行後に結果を見て見ると…
f:id:notwo:20190907161514p:plain
なんでじゃ。
heroku local webだと参照している場所が違うのか…?Djangoでは思想?として開発中とデプロイ時では参照の仕方が違うことはわかりました。
↓ここでよく解説されています。
qiita.com

しかし同じローカルで実行しているのに同じことができないのは不思議です。散々探し回っても解決に至る情報にはたどり着きませんでした。というわけで、ローカル開発するならrunserverを実行するのが確実なのでそっちにします。何か変わるわけでもなさそうですしね。というわけでheroku localコマンドには永久にご退場願おうか。

本番にデプロイするときは以下公式サイトを見れば良さそうです。
devcenter.heroku.com
ここによればpython manage.py collectstaticしろと書いてあります。実際にやってみると、各アプリのcssとかjsがproject_static以下に集約されることがわかります。元あるファイルからコピーしただけなので、アプリ直下のstaticの中身はそのままですね。おそらく、static以下のファイルに修正が入ったらこのコマンドを毎回実行する必要がありそうです。



技術系の記事だと最近Qiitaに垢を作ったのでそっちに書こうか迷ったのですが、個人的にはこのブログを盛り上げて行きたい思いがあるので、基本的に今後もここに載せていくつもりです。そもそも更新頻度も高くないし。

【AWS】ACMに登録したSSL証明書の有効期限切れしてしまったときの対策

またまたやらかしてしまいました。

なぜかACMに登録済みのSSL証明書の自動更新がされておらず、前回のような期限切れ注意的なメールも届いていなかったため実際に期限切れになるまで気づきませんでした。

f:id:notwo:20190303085042p:plain
赤字で「期限切れ」というパワーワードが刻まれている...

しかもテストで作った未使用証明書が残存していたという...要らないものは消して整理すべき(戒め)

 

さて、期限が切れてしまったら更新するだけです。ただ、期限が切れる前に更新するのと比べてひと手間かかります。

 

※以下、証明書とそれを使うサービスのリージョンが一致してないと使えないので前もってリージョンを合わせること

 

やり方は、ACMの画面、証明書のリクエストボタンからドメイン情報を入力していきます。検証方法は、私はEメールにしました。 

f:id:notwo:20190303090123p:plain
こんな感じになるはず

メールを送ってからの細かなやり方は下記にあります。

notwodaily.hatenablog.com

approveまで終わったら、要らない証明書を削除したいのですが... 

f:id:notwo:20190303084623p:plain

当たり前ですが、期限切れ証明書とはいえなにかのサービスで使用しているわけで、そちらで利用する証明書を変更しないといけません。

例えば私はCloudFrontで利用しています。

notwodaily.hatenablog.com

証明書の変更方法として、CloudFront(おそらく他サービスも)の場合はarnを更新すれば良いです。

下画像のARN(いま発行した証明書の方を選ぶこと!)の部分を丸ごとコピー。

f:id:notwo:20190303084702p:plain

Custom SSL Certificate (example.com):直下のテキストエリアにコピったarnを貼り付け、更新。

これでさっきまで使用不可能だった発行済証明書が選択され、使用可能に変わっていることを確認できます。

f:id:notwo:20190303084506p:plain

そして期限切れの証明書を削除可能になっているので、アクション→削除。発行済みの証明書のみが残っていれば大丈夫です。

これで無事解決です。めでたしめでたし。

 

 

いやあ、久しぶりに記事を書くネタができて本当に良かったです(白目)

【STEINS;GATE】【ネタバレあり】シュタゲ(elite, 0)の感想書いてみる

シュタゲエリート(無印)およびゼロをクリアし、アニメも観終わったので、簡単に感想など書いてみようと思います。なお映画は見ていません。

 

それぞれの世界線と違い

世界線 未来(2036年) 紅莉栖 まゆり タイムマシン 岡部達が関わる相手
α SERNによるディストピア すぐには死なない※1 2010/8/13に死亡 SERNが完成させる。未来のダルがそれを真似て完成させる
過去への一方通行
SERN(のラウンダー)
β アメリカ、ロシアを巻き込んだ第三次世界大戦勃発、終戦後も各地で内戦
世界人口が10億人にまで減少

2010/7/28に死亡

記憶だけAmadeusに残存

すぐには死なない 未来のダルが完成させる
未来にも過去にも行けるがバッテリー残量わずか
ストラトフォー
DURPA
ロシア軍
SERN(のラウンダー)※2
SG 戦争も起きずディストピアもない すぐには死なない すぐには死なない 存在するのか不明 不明

※1 タイムマシン完成後に死亡だった気がする

※2 敵として出てくるのはほんの1世界線の出来事であり、ここでは影が薄い

 

時間、世界線変動

  Dメール、Dライン タイムリープ タイムマシン
世界線変動 できるが、結果は受け取った相手の行動に左右される できない※1 できない※1
時間旅行 できない できるが制限あり できる

 

設定はこんな感じだったと思います。タイムマシンでさえ世界線を変えられないのは、世界線の収束のせいですね。ただ、収束と言っても「決まった結果」として出てきたのは人の生死ばっかりですが。

タイムリープマシンはタイムマシンよりはリスクが少ないものの、それが出来た時から最大48時間前(最終的にはもっと伸びるが)までという制限がついていました。

 

※1 厳密には、アトラクタフィールド理論により世界線の収束が起こるので、特定の過去の出来事を変えられない、という意味

 

感想

ダル、チート過ぎない?足跡の残らないハッキングを一発成功させる(それも国家機密が相手)というまさにスーパーハッカーが味方にいるのが頼もしい、と思いました。未来ではタイムマシンを作っちゃうしね。活躍度でMVPをあげるなら彼じゃないか。

無印→ゼロの順に話が進みますが、ゼロのトゥルーエンドが無印のトゥルーエンドにつながるのが衝撃的でした。未来の岡部が、αから戻ってきた現在の岡部にムービーメールを送って道を示すところで察しました。

 

f:id:notwo:20181125093645j:plain

シュタゲをやるとタイムマシンが意外とそこまで万能ではないなという印象が強くなります。β世界線に来た鈴羽が言っていたバッテリー問題が、過去では常に付きまとううえマシンの故障タイミングによっては時空の狭間に閉じ込められかねないという欠点。アトラクタフィールド理論により、決まった結果は覆せない。特にここが問題な気がします。過去を変えても結果が変わらないなら、過去に戻る意味があるのかわかりません。ところが、そこにDメールないしはDラインを組み合わせることで、本当の意味で時間や世界を自由に操ることが出来るようになります。

しかしそんなことをすればSERNにマークされるし(Dラインは監視されていないのでセーフ)、タイムマシンはその存在がバレればその世界では戦争が起こってしまうという諸刃の剣であり、活躍の場がほとんどなかったのが意外でした。ドラえもんの世界の未来人の持っているタイムマシンはそういう欠点をどうやって克服しているのか、なんて考えてしまいますw

 

アニメでなくゲームをプレイした人ならではの感想としては、各ルートどれもハズレにはなりえない点が素晴らしい(ゼロのレスキネンルート除く)。例えば無印のフェイリスルートはむちゃくちゃ切ないルートではあるけれど、まゆりも紅莉栖も死なない一つの解答だと思います。選択肢で何を選ぼうがFateと違って分岐によってDead endとならないのが特徴だと思います(だからといってFateが悪いわけではない)。それでも私は結局トゥルーエンドが一番納得が行きますが。

他には、専門用語がそこそこ出てくるのですがその解説をTIPSという用語辞典で補っています。トロコンしたい場合、そのTIPS集めのためにも全ルート回ることになります。

 

さて、主人公の岡部視点で物語が進みますが、岡部が世界線を移る理由はまゆりと紅莉栖を死なせたくないからです。舞台のどちらの世界線も20年後には地獄が待ち受けていますから、殆ど誰にとっても辛い世界線に変わりはないものの、岡部にとってはその世界のことなんてどうでも良い※3わけです。あくまで目の前の紅莉栖、まゆりの無事が確認できれば良い。つまり世界線を移りたいのは岡部のエゴでしかないのですが、「独善的だ」なんて紅莉栖に言われても、それを強がって否定したりしないあたりに好感が持てます※4。結局、世界線を変えないと地獄なので、独善的だろうが岡部が世界線を変えることに、他人にとっても意義が生まれています。この辺の設定がとてもうまくできています。

加えて、岡部はαからβに移るときは紅莉栖に背中を押してもらい、βからSG世界線に移るときはまゆりに背中を押してもらっている。どちらのヒロインが欠けてもSG世界線にはたどり着けていなかった。このことがどちらも岡部にとって無くてはならない、ということを表現しているように感じられる。そんなヒロインをどちらも守ろうとする、だからこそ、最後の最後まで岡部を応援したくなる、そう出来ているんだと自分で納得しています。

※3 β世界線2036年を見た時はさすがに変えないといけない!と使命感を持っていましたが。

※4 β世界線に移るとき、「紅莉栖を見捨てる」ことを覚悟し、受け入れたことも含め。ただし、途中までは世界線を変えることの影響を恐れてはいた模様。

 

f:id:notwo:20181125093353j:plain

後は、物語にはあまり関係ない部分ですが、ゼロの冒頭でレスキネン教授の講演中、アマデウスに批判的な意見を出した人に対して岡部が「最初は無理だと思われた技術なんていくらでもある、それを克服した研究者がいたから今があるんだろ」というセリフ、ここ個人的に名言と思ってます。全く新しい技術やサービスが生まれようとしている時、そこには必ず批判する輩がいますが、技術的な困難だけでなくそういう批判にも打ち勝った結果出来上がった作品が世の中を変えていく、そういう流れは歴史上でも起こっていることですから。

 

 

f:id:notwo:20181125093300j:plain

復ッ活ッ 鳳凰院凶真復活ッッ

そして最後に、やはり鳳凰院凶真が復活したことが嬉しいです。この厨二ネームなくして岡部はありえないでしょうw元々無理してつけてた設定とはいえ、無印の頃の印象が強いから普通の大学生をしている岡部って違和感バリバリ。でも最後にしっかりもとに戻ってよかった。こっちのほうがより困難に立ち向かっている雰囲気が出ていると思います。

 

原作とアニメの違いについて

無印・・・原作ではトゥルーエンドの他に紅莉栖/まゆり/ルカ子/フェイリス/鈴羽のそれぞれのルートが存在。アニメでは原作のまゆりルートに準ずる。

ゼロ・・・原作ではトゥルーエンドの他にレスキネン/まゆり/紅莉栖/かがり/真帆のそれぞれのルートが存在。アニメでは各ルートを部分的になぞりつつトゥルーエンドへ。

 

ゼロはアニメと原作にちょくちょく違いがあるというか、アニメ限定シーンがあったりします(最後に岡部がBC18000に漂流した鈴羽とまゆりを迎えに行くシーンだったりかがりの格闘シーンでかがりの素顔がバレてたりダルの告白シーンがあったりetc)。

細かい突っ込みどころを無視すれば十分アニメも楽しめると思います。

 

アニメも原作も良いと思いますが、やはり私は原作を推します。原作であれば、岡部はもちろんサブキャラの深掘りもよりされているので。ただ、無印の鈴羽ルートつまり無限サイクリングはちょっと怖いけどね・・・

 

【Python】【Tk】treeview(表)に横スクロールバーを付ける

treeviewで横スクロールが出来ないと不便なのでつけよう、というものです。表以外の形式でも出来ると思います(未検証)。

 

コードとしては

frame = ...(frame初期化)
tree = ...(treeview初期化)
tree.pack()
hscrollbar = ttk.Scrollbar(frame, orient = tk.HORIZONTAL, command=tree.xview)
tree.configure(xscrollcommand=lambda f, l: hscrollbar.set(f, l))
hscrollbar.pack(fill='x')

で出来ます。

先にtree.pack()しておくことで、スクロールバーを表の下部につけることが出来ます。見て分かる通り同じframe内にtreeviewおよびスクロールバーを収める必要があります。

hscrollbar.pack()するときfill='x'がないと、スクロールバーのサイズが最小化されてしまって使い物になりません。

 

余談ですが、下記リンクの

autoscroll

を使うことで、ウィジェットのサイズによってスクロールバーをつけたり消したり出来ます。

python 2.7 - Horizontal scrolling won't activate for ttk Treeview widget - Stack Overflow

 

なお、縦スクロールバーも同様につけることが出来るものの、デフォルトでホイールに縦スクロールが対応しているようなので、わざわざつける必要があるのかは疑問。デザイン面を考慮するなら、ですね。