LYNCSブログ

慶應義塾大学公認学生団体 宇宙科学総合研究会(LYNCS)のブログです。

三田祭告知・会誌の発行について

慶應義塾大学三田キャンパスのお祭り、三田祭が近づいてきました。

Twitterの方でも順次告知しておりますが、今年もLYNCSは三田祭に参加致します。 出展内容は以下の通りです。

  • 自作ドームでのプラネタリウム展示・生解説
  • 天体写真ポストカードの販売
  • 会誌「Escape Velocity」無料頒布

Escape Velocity

LYNCS初の試みとして、各部門からの寄稿をまとめた会誌を発行します。 団体全体として印刷物を公開するのは初めてであり、混乱も多々ありましたが、会員の協力で三田祭合わせでの発行が実現しました。

以下、掲載した記事の一覧です。

  1. 代表挨拶
  2. 量子情報科学序論~IBM Qを動かして学ぶ量子コンピュータ
  3. LYNCS理学研究本部 線型代数ゼミノート
  4. 2017種子島ロケットコンテスト
  5. 天文研究本部活動紹介
  6. LYNCS会員の機材紹介
  7. 星景・天体写真の撮り方
  8. 望遠鏡の紹介・扱い方
  9. LYNCS会員入会理由語り

希望される方には無料でお配りしますので、お近くの会員にお声掛けください。

皆様のご来場心よりお待ちしています。

(広報・И)

第13回能代宇宙イベント ~結果と3年間の感想~

f:id:lyncs:20170901074813j:plain 皆様お久しぶりです.代表のあっきーです.
先月8月17日~21日で第13回能代宇宙イベントのCanSat部門に出場してきました.
Twitterで実況や感想ツイートを行ってきましたが,このブログで結果をご報告させていただきます.

続きを読む

mbed / Raspberry Pi 用のBSch3V用部品データ (Win/Mac対応)

回路図エディタ「BSch3V」を使用していると、意外と最近のマイコンボードの部品データがなかったり、あったとしてもリンクが消滅しているといった事態に悩まされます。ということで作りました。

最近のマイコンボードといっても無限にありますので、とりあえず弊団体で使用しているmbedの主要なボード(LPC1768など)やRaspberry PiのGPIOピンをデータ化しています。もしご要望などありましたらコメント頂けると対応できるかもしれません。

また、Mac版のQt-BSch3V Modifiedでも利用できることを確認しております。

ダウンロード

BSch3V_mbed_raspberrypi.zip - Google ドライブ

(ryo-a)

JSONファイルを定期的に取得・保存したい (Node.js)

個人タスクで発生した備忘録です。

JSONを採取したい

東京メトロのオープンデータでは、JSON形式で運行情報などを取得できます。 実際の運行情報の事例を収集して解析の対象とするために簡単なスクリプトを書きました。

使用するもの

  • Node.js
  • date-utils
  • cheerio-httpcli
    • DOM解析するわけではないですが、単にエンコードとかの取り扱いが楽になるので。

コード

require('date-utils');
const cheerio = require('cheerio-httpcli');
const fs = require('fs');

var datetime = new Date().toFormat('YYYY-MM-DD-HH24_MI_SS');
var filename = datetime + '.json';
var savepath = './saved_json/' + filename;

cheerio.fetch('***input URL here***', 'utf-8', function (err, $, res, body) {
    //今回はダイヤ乱れなどの情報がある場合のみJSONを保存したいので
    if ($.html().search(/のため/) != -1){ 
        fs.writeFileSync(savepath, $.html(), 'utf8');
    }   
});

定期実行

言わずもがな、cronに登録します。 筆者はラズパイで走らせています。ラズパイが1台あれば気軽にcron回せるのでおすすめです。

(ryo-a)

MediaWiki「サムネイルの作成エラー: 12.5 MPよりも大きな寸法のファイル」の表示を解決する

問題

MediaWikiはアップロードされた画像に対して自動でサムネイル画像を作成し、ページ内ではそのサムネイル画像を表示しています。

しかし、一定のサイズ(ファイルサイズではなく解像度)を超えた画像がアップロードされた場合、以下のようなエラーを返します。 f:id:lyncs:20170618125307p:plain なお、このエラーが出ても画像はしっかりとアップロードされています。サムネイルが生成されないだけです。

解決策

初期値では解像度の上限は12.5MP(3500 x 3500ピクセル)となっていますので、単にこの値を引き上げてやれば大丈夫です。
LocalSettings.php$wgMaxImageArea の値を設定しましょう。 Manual:$wgMaxImageArea - MediaWiki

4.9MP(7000x7000px)の場合こんな感じです。

$wgMaxImageArea = 4.9e7;

通常、LocalSettings.phpの初期値では$wgMaxImageAreaの項目がないはずなので、上記の内容を最終行に追加してあげればOKです。

多くの人が慣れ親しんだ◯x◯ピクセルという数値ではなく、ピクセル数で数値指定する必要があるので、参考のために上記MediaWikiマニュアルにはいくつかの例が記載さています。

  • 25 million pixels or 5000×5000: 2.5e7
  • 36 million pixels or 6000×6000: 3.6e7
  • 49 million pixels or 7000×7000: 4.9e7
  • 64 million pixels or 8000×8000: 6.4e7
  • 72 million pixels or 9000×9000: 7.2e7
  • 100 million pixels or 10000×10000: 10e7

その他

設定ファイルを変更すれば既存の画像もサムネイルが作成されるので、アップロードし直す必要はありません。

(LYNCSwiki運用担当 ゆん)

Slackの古くなったファイルを自動で削除してみた

概要

Slack(無料プラン)の容量制限をオーバーしないために、特定チャンネルの、ある日数より古いファイルを削除するbotを作成した記録です。 GAS(Google Apps Script)で毎日タイマー起動するように設定し、ファイル容量を管理するコストを大幅に抑えることができます。

対象読者

  • Slackを普段使っている方
  • JavaScriptを少し使ったことがある方

ねらい

LYNCSでは、2015年11月ごろからSlackをメインの連絡ツールとして利用しています。 Slackは企業向けのチャットサービスではありますが、無料プランでもかなり便利に使えるのが嬉しいですよね。

しかし、少人数で数ヶ月ほどの利用ならいざ知らず、人数が増え長く使い続けるとある問題にぶち当たります。 ファイルストレージの5GB容量制限です。

f:id:lyncs:20170604130347p:plain
LYNCS SlackチームのStatistics

画像は現在のLYNCSチームの統計ですが、数千のファイルが存在していることがわかります。 何も対策せずに使っていると、「5GB超えてるぞ金払えコラ(意訳)」と怒られることもしばしばでした。 しかし、Slack有料プランの価格設定は企業向けとなっており、学生団体にとってはおいそれと払える額ではありません。

従っていらないファイルを削除し、無料プランの制限内で使うしかないことになります。 でも、Slackにはファイルの一括削除機能がなく、ポチポチ手作業で消すことしかできません。 「ファイルを選ぶ→削除ボタンを押す→削除の確認ボタンを押す」を数百回も繰り返すのはさすがに耐えがたい。

f:id:lyncs:20170604130316p:plain
ファイル削除の確認メッセージ

そこで、SlackのWeb APIを利用して古いファイルを消す仕組みを作ることにしました。

実行環境

GASを知らない人のために簡単に説明すると、「GoogleのサーバーでJavaScriptを動かせる夢のようなサービス」です。 一応時間制限はあるものの、無料で24時間いつでもJavaScriptが動きます。 サーバーを持たなくても、Googleアカウントさえあれば簡単なBotが作れてしまうのです。

GASでSlack向けのBotを作った事例は既に多数あって、ライブラリも存在しています。 GASの具体的な操作などについてはあまり書かないので、以下の記事などをご覧ください。

Slack Web APIを使ってみる

Slackには、とても便利なWeb APIが存在します。 コマンド操作は敷居が高いと思うかもしれませんが、実はWeb上に素晴らしいテスト環境が用意されているので全く心配いりません。

API Methodsページに使えるメソッドの一覧があり、それぞれのページで詳細を閲覧できます。 実行するにはTokenを持っている必要があるので、発行ページで作っておきましょう。

例えば、files.listの動作を試してみます。 “Tester"と書かれたタブでオプション(token以外は空欄でも可)を入力してTest Methodをクリックすると、結果が下のテキストエリアに出てきます。

f:id:lyncs:20170604130311p:plain
APIテスター

親切にURLまで表示してくれています。 これにアクセスすれば自分のチームのファイル一覧が手に入るというわけです。 さて、リスト先頭の"image.png"を削除してみましょう。

f:id:lyncs:20170604130334p:plain
files.listの実行結果

ファイルの削除にはfiles.deleteを使います。 ファイルの"id"が必要になるので、files.listで出てきたものをコピペします。

f:id:lyncs:20170604130327p:plain
files.deleteの実行結果

"ok": trueとしか返ってきませんが、これで削除が完了しています。 とっても手軽ですね。

なお、削除に限らずSlackのデータを変更するメソッドをテストすると実際に変更されてしまうので、試す場合は十分気をつけてください!!!!!

削除を行うプログラムの流れ

APIの使い方が分かったので、一連の流れをプログラムにしていきます。 基本的には

  1. ファイル一覧を取得する(files.list)
  2. 見つけたファイルの数だけファイル削除を繰り返す(files.delete)

だけですが、いくつか問題があるので実際はもう少し複雑です。

不要なファイルを絞り込む

チームのファイルを全部消してしまっては、必要なものまで消えてしまい混乱が起こるので、不要なものだけに絞ります。

幸い、LYNCSのSlackは業務系のチャンネル(#generalなど)と雑談系のチャンネル(#randomなど)が分かれているので、雑談系にあがったファイルだけを削除すればよさそうです。 それでも、写真を貼った瞬間に消されては雑談にならないので、特定日数以前のファイルだけを対象にします。

チャンネルを指定する

特定チャンネルのファイル一覧を取り出すには、files.list"channel"を指定します。 チャンネルの指定はファイルと同様IDで行います。 チャンネルのIDなんて普通は覚えていないので、これもAPIで調べることにしますが、少し面倒です。

Slackのチャンネルには、公開(Public)のものと非公開(Private)のものがあります。 APIでは前者はchannel・後者はgroupという扱いで、メソッドを使い分けねばなりません。 そこで、チャンネルの名称からIDを得る方法はこうなります:

  1. チャンネル一覧を取得する(channels.list)
  2. 探している名称と一致するチャンネルがあるかどうか調べる
  3. 一致しなかったら、グループ一覧を取得する(groups.list)
  4. 探している名称と一致するグループがあるかどうか調べる

以下はchannelを探す関数です。 groupの方も流れは全く同じなので省略します。 UrlFetchApp.fetch()はGASの機能で、渡したURLにアクセスしてくれるものです。

結果がJSONで送られてくるので、パースしてsomeループで名称が一致するまで調べます。

/* チャンネル名を検索してIDを取得 */
function channelNameToId(name) {
  var res = UrlFetchApp.fetch('https://slack.com/api/channels.list?token=' + SLACK_ACCESS_TOKEN);
  var channelsList=JSON.parse(res.getContentText());
  var foundChannelsId = '';
  var isFound = channelsList.channels.some(function(channels){
    if (channels.name.match(name)){
      foundChannelsId = channels.id;
      return true;
    } 
  });
  return foundChannelsId;
}

経過日数を指定する

files.listts_toオプションを使うと、ある時刻までのファイルだけを取得できます。 この時刻はUNIX timeで指定しなければなりません。 そこで、経過日数からts_toに変換する関数を作りました。

JavaScriptではDate.getTime()で現在時刻をUNIX時間で取得できます。 これはミリ秒単位なので1000で割る必要があるのに注意です。 あとは、日数を秒数に換算して引き算するだけですね。

function elapsedDaysToUnixTime(days){  
  var date = new Date();
  var now = Math.floor(date.getTime()/ 1000); // unixtime[sec]
  return now - 8.64e4 * days + '' // 8.64e4[sec] = 1[day] 文字列じゃないと動かないので型変換している
}

ファイル削除プログラム

事前準備

スクリプトのプロパティ

APIのtokenは、流出するとチームに好き勝手されてしまうので扱いに注意が必要です。 外部の人に見せないものでも、コードに直接書くのは考えものです。 幸い、GASには「スクリプトのプロパティ」という任意の値を保存しておける機能があるので、そこにtokenなどを格納することにします。

取得は次のようにすれば可能です。

var SLACK_ACCESS_TOKEN = PropertiesService.getScriptProperties().getProperty("TOKEN");

また、削除するファイルを探すチャンネルもOLDFILEというプロパティにカンマ区切りで入力することにします。 これで、ソースコードを公開してもどんなチャンネルがあるかバレません。

f:id:lyncs:20170604130247p:plain
スクリプトのプロパティの入力例

APIを叩く

SlackのAPIを使うには、各種メソッドを叩く仕組みが必要です。 GASにはsoundTricker/SlackAppというライブラリがあり、これをインポートするだけでAPIが使えちゃいます。 ただ、最近これを使うより自前で書いたものの方がなぜか数倍速いのに気づいてしまったので、自前実装に切り替えました。

自分の環境で動けばいいので、かなり適当に書いてます。 他の環境でライブラリをお使いの方は、適宜読み替えてください。

例:

/* ファイルのリスト */
function filesList(data){
  var params = {
    'token': SLACK_ACCESS_TOKEN,
    'channel': data.channel,
    'ts_to': data.ts_to,
    'count': data.count
  }
  var options = {
    'method': 'POST',
    'payload': params
  }
  var res = UrlFetchApp.fetch('https://slack.com/api/files.list',options);
  return JSON.parse(res.getContentText());
}

ファイルを削除するスクリプト

まずはコードを。

/* 雑談チャンネル・グループの名称を検索して古いファイルを削除 */
function oldFileExecutioner(){
  const targetChannels = PropertiesService.getScriptProperties().getProperty("OLDFILE").split(",");    
  targetChannels.forEach(deleteOldFile);
}

/* 指定チャンネル内・特定日数より以前のファイルを削除 */
function deleteOldFile(channelName) {
  const days = 21;  // 遡る日数(ユーザが指定)
  
  var channelId = channelNameToId(channelName) || groupNameToId(channelName);
  if(!channelId){
    Logger.log('Not found "' + channelName + '". Skipping.');
    return -1; //見つからなければ終了
  }
  Logger.log('Found "' + channelName + '"(' + channelId + ')');
  var options = {
    channel: channelId,
    ts_to: elapsedDaysToUnixTime(days),
    count: 1000
  }
  filesList(options).files.forEach(function(val){
    data = filesDelete(val.id);
    if (data.error) Logger.log('  Failed to delete file ' + val.name + ' Error: ' + data.error);
    else Logger.log('  Deleted file "' + val.name + '"(' + val.id + ')');
  });
}

oldFileExecutioner()でプロパティから取得したチャンネル名それぞれについて、deleteOldFile(channelName)を実行しています。

チャンネルはchannels.listgroups.listの両方から探して、どちらでもなければログにエラーメッセージを残して終了します。 見つけたらchannelts_toを指定してfiles.listを叩くのですが、実はこれだけではファイル100件までしか取得できません。 そこで、countオプションに適当に大きめの値を入れておきます。

あとは各ファイルのIDをfiles.deleteに放り込むだけです。 実在するIDを入れるので普通は成功しますが、一応エラーが出たら内容をログに記録するようにしてあります。

トリガーの設定

GASには、指定したタイミングで関数を自動実行する「トリガー」という機能があります。 LYNCSでは、oldFileExecutioner()が毎日昼頃に実行されるように設定しています。 使い方はググればたくさん記事が出てくるので省略させてください。

実行例

チームのSlackでやると危ないので、テスト用の一人Slackにいろんなファイルをアップロードした上でoldFileExecutioner()を実行してみます。

f:id:lyncs:20170604130338p:plain
テスト用にアップロードしたファイルたち

スクリプトのプロパティにはtokenと、巡回してほしいチャンネルを指定しますが、わざと存在しないチャンネル名も混ぜておきます。

プロパティ
TOKEN {チームのtoken}
OLDFILE random,ch1,ch2

oldFileExecutioner()を実行して数秒待つとログを閲覧できます。

f:id:lyncs:20170604130306p:plain
実行後のログ

無事削除してくれたようです。 ch2というチャンネルは存在しないのでエラーになっています。 Slackの方を見てみるとファイルが減っていますが、#generalに上がっていたファイルは残っています。

f:id:lyncs:20170604130342p:plain
削除の対象外のファイル

展望

アーカイブ済みのチャンネルのファイルを削除する

channels.listis_archivedという項目があるので、アーカイブ済みなら中のファイルを消す、といったこともできます。

特定タイプのファイルだけを削除する

Slackでは、作成したスニペットやポストもファイル扱いです。 これらは文章データでストレージ容量にはほとんど影響ないのですが、自動削除の対象となってしまいます。

files.listで取得するファイルオブジェクトのプロパティにfiletypeという項目がある(一覧)ので、これを見て分類すれば、ファイルの種類によって動作を変えられそうです。

また、ファイルオブジェクトのsizeを見ればサイズがわかるので、一定サイズを超えていたら削除、という方針でもいいかもしれません。

(Webシステム担当 И)

LYNCSの新歓情報!(2017年)

皆さんこんにちは!新年度が始まりましたね!いよいよ始まる大学生生活に夢を膨らませる新入生や,新年度の授業に期待を寄せる上級生も全力でキャンパスライフを送ってください!

さて今日の更新では宇宙科学総合研究会LYNCSの新歓企画についてご紹介します!オリエンテーション期間は終了してしまいましたが,4月末までLYNCSでは新歓活動をしています!

  • 天文本部

捉えよ、宇宙を。(公式HPより)

いやぁかっこいいですね(自画自賛).天文本部では新歓期間中に観望会(月,木星)やプラネタリウム鑑賞会を予定しています.f:id:lyncs:20170120202928j:plain 写真は昨年の観望会の様子です.日吉キャンパスで行いますが,皆さんが思っている以上に星を見ることができます.ぜひご参加ください.(詳細日程は下記をご参照ください.)

  • 衛星ミッション本部

乗り出せ、宇宙に。(公式HPより)

いやぁこちらもかっこいいですね(2回目).衛星ミッション本部では新歓期間中に機械設計入門講座(3DCADの使用法)や回路設計入門講座を予定しています.また宇宙エレベータのクライマ実験の見学も予定しています.f:id:lyncs:20170310115809j:plainf:id:lyncs:20170406234656p:plain 画像は開発しているCanSatと宇宙エレベータの写真です.初心者の方でも1から教えますのでご安心ください!

  • 理学本部

3つ目は理学本部!こちらは今年度より設立した新規本部ですが内容は保証いたします!新歓期間中はチャンドラセカール限界やε-δ論法に関する講演会を予定しています.ぜひご参加ください!(写真は新規本部であることと会員の顔が写ってしまっているためありません.ご了承ください)

  • 全体予定

長々と書きましたが詳細は以下の画像をご参照ください!f:id:lyncs:20170406233715j:plain

そしてLINE@にご連絡いただければいつでも会員が対応いたします!f:id:lyncs:20170406235514j:plain

では新歓企画でお会いしましょう! 新代表あっきーでした!