Skip to content

各種イベント管理サービスのAPIで統計情報を集計したい #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yasulab opened this issue May 31, 2016 · 27 comments
Closed
Labels
急ぎじゃないよ Make something better but not rushed. 統計情報 Tracking event record function via APIs: https://coderdojo.jp/stats

Comments

@yasulab
Copy link
Member

yasulab commented May 31, 2016

やりたいこと

  • 全国のDojoの集計情報が欲しい
  • アンケートでもいいけど、イベント情報から集計するのが的確そう
  • TVや雑誌から取材されたときや、企業に協賛を求めるときに便利

数字の根拠を明確にし、かつ、その集計方法が誰でも検証可能である状況にしたい 📈 👀

数字の使用例

子ども向けプログラミング道場を推進する一般社団法人 CoderDojo Japanを さくらインターネットが支援、「さくらのクラウド」を無料提供
https://www.sakura.ad.jp/press/2017/0720_cloud-coderjapan/

CoderDojoは、7~17歳を対象に、日本全国88カ所以上で開催されている非営利のオープンソースコミュニティです。2011年にアイルランドで始まり、世界では69カ国・1,200の道場があります。日本でも、2012年から活動が始まり、これまでに1,000回以上のイベントが開催されています。

少なくとも2,000~3,000回ぐらいは達成していそうだったが、今回は主要な道場のみを指先確認して1,000以上あることを確認した。しかし、より正確な根拠があれば、もっと正確な数字が伝えられる。CoderDojo の参加者数についても同様で、計測方法が確立すれば、より正確な数字が伝えられる。

cf. 日本の CoderDojo (zen登録済) - Google Spreadsheet
https://docs.google.com/spreadsheets/d/17-M-qv5c0MdE_ZIFk566I2CGCIDHFkQwXWiunDXCGVw/edit#gid=354377216

欲しい情報

  1. Dojo毎の開催回数
    • 全Dojoの開催回数合計
  2. Dojo毎の参加者数
    • 全Dojoの参加者数合計
  3. 以下、あると嬉しいけど、今は考えない:
    • Dojo毎のメンター数
    • 全Dojoのメンター数合計
    • ☝️ これらの数字は、イベント情報からは分からない可能性が高い

対応する必要のあるイベント管理サービス

  • Doorkeeper API
  • Connpass API
  • Peatix (今は考えない) ※ 利用例@会津
  • Facebook Event API (今は考えない)
  • CoderDojo Zen (今は考えない)

あとでやる (今はやらない)

  • 統計情報をどう見せるか
  • 統計情報のビジュアライゼーション
@yasulab yasulab added the 急ぎじゃないよ Make something better but not rushed. label May 31, 2016
@nanophate nanophate self-assigned this Jun 1, 2016
@yasulab
Copy link
Member Author

yasulab commented Jun 30, 2016

API利用の参考事例: http://qiita.com/kiida/items/373446edd2fb09da82ca

@yasulab yasulab changed the title 全国のDojoのイベント情報APIを叩いて、各種情報を集計したい 各種イベント管理サービスのAPIを叩いて、統計情報を集計したい Dec 12, 2016
@yasulab
Copy link
Member Author

yasulab commented Jul 25, 2017

@nalabjp こちらが先ほど話していた Issue になります 🙏

次のアクション

  • 開発に関するAPIキーなどを @nalabjp さんと共有する (yasulab)
  • CoderDojo ごとに使っているイベントサービスをまとめる (yasulab)
  • DB設計
  • cron 回す (月に1回ぐらい)
  • 他、ドキュメント化されていない情報を都度具体化していく

今はやらない / 考えない

直近のイベント情報を見せる仕組みを考える #110

@yasulab
Copy link
Member Author

yasulab commented Jul 25, 2017

TIPS: ナラさんが2015年頃、似たようなイベント情報収集機能をRailsで実装していた 😮

Push notification of events - GitHub
https://github.com/nalabjp/pesca

@yasulab
Copy link
Member Author

yasulab commented Jul 25, 2017

ナラさんが当時、実装していて気づいたこと:

  • わりと connpass の実装に似たサービスが多い
  • Doorkeeper API は他のイベント管理サービスと少し異なる
  • DBに何を格納するか、どう寄せるか、考えなくてはいけない

@nalabjp
Copy link
Member

nalabjp commented Jul 29, 2017

memo: connpassのAPI

ref: https://connpass.com/about/api/
series_idというキーが使えそう
例えばCoderDojo浜松の場合series_idは2431で1件取得すると以下のようなレスポンスが取れる

CoderDojo浜松の例
I, [2017-07-29T21:23:29.487805 #51862]  INFO -- : get https://connpass.com/api/v1/event/?count=1&format=json&series_id=2431&start=1
D, [2017-07-29T21:23:29.487897 #51862] DEBUG -- request: User-Agent: "Faraday v0.9.2"
I, [2017-07-29T21:23:31.688439 #51862]  INFO -- Status: 200
D, [2017-07-29T21:23:31.688603 #51862] DEBUG -- response: cache-control: "max-age=300"
content-language: "ja"
content-type: "text/json; charset=utf-8"
date: "Sat, 29 Jul 2017 12:23:31 GMT"
expires: "Sat, 29 Jul 2017 12:27:25 GMT"
last-modified: "Sat, 29 Jul 2017 12:22:25 GMT"
server: "nginx"
vary: "Accept-Language, Cookie"
x-frame-options: "DENY"
transfer-encoding: "chunked"
connection: "Close"
{"results_returned"=>1,
 "events"=>
  [{"event_url"=>"https://coderdojo-hamamatsu.connpass.com/event/62418/",
    "event_type"=>"participation",
    "owner_nickname"=>"DojoHamama",
    "series"=>
     {"url"=>"https://coderdojo-hamamatsu.connpass.com/",
      "id"=>2431,
      "title"=>"CoderDojo浜松"},
    "updated_at"=>"2017-07-17T10:49:15+09:00",
    "lat"=>"34.696983500000",
    "started_at"=>"2017-08-11T13:30:00+09:00",
    "hash_tag"=>"",
    "title"=>"第19回CoderDojo浜松",
    "event_id"=>62418,
    "lon"=>"137.733223100000",
    "waiting"=>0,
    "limit"=>nil,
    "owner_id"=>96922,
    "owner_display_name"=>"CoderDojo浜松",
    "description"=>
     "<h1>CoderDojo浜松とは</h1>\n" +
     "<p>CoderDojo浜松は、浜松市を中心に活動する、小中学生向けのプログラミング道場です。主な活動として</p>\n" +
     "<ul>\n" +
     "<li>\n" +
     "<p>Scratch (ブロックを組合わせて簡単プログラミング)</p>\n" +
     "</li>\n" +
     "<li>\n" +
     "<p>HTML / CSS / JavaScript などを活用したWEBサイト作成</p>\n" +
     "</li>\n" +
     "<li>\n" +
     "<p><a href=\"https://code.org/learn/" rel=\"nofollow\">Hour of Code</a>や<a href=\"https://studio.code.org//" rel=\"nofollow\">Code Studio</a>を利用してのプログラミング学習</p>\n" +
     "</li>\n" +
     "</ul>\n" +
     "<p>を行っています。</p>\n" +
     "<h1>内容</h1>\n" +
     "<p>各人にテキストやScratchカードを見てもらい、その内容を実装してもらいます。またHTMLやCSSを使ってホームページをつくってみたい人はテキストもしくはカードを用意いたします。</p>\n" +
     "<p>また、自分で取り組みたいプログラミングがある場合はそちらをしていただいてもかまいません。</p>\n" +
     "<p>また、プログラミングを始めてみたいが何をしていいか分からないという人でも、<a href=\"https://code.org/learn/" rel=\"nofollow\">Hour of Code</a>や<a href=\"https://studio.code.org//" rel=\"nofollow\">Code Studio</a>といった教材でプログラミングを学習することができます。</p>\n" +
     "<p>最後は全員で成果を発表しましょう。</p>\n" +
     "<h1>参加資格</h1>\n" +
     "<ul>\n" +
     "<li>\n" +
     "<p>7歳~17歳までのプログラミングに興味がある方ならどなたでも参加いただけます。</p>\n" +
     "</li>\n" +
     "<li>\n" +
     "<p>その他運営に支障をきたすと判断した場合は参加をお断りする場合がございます。</p>\n" +
     "</li>\n" +
     "</ul>\n" +
     "<h1>注意事項</h1>\n" +
     "<ul>\n" +
     "<li>\n" +
     "<p>無線LANに接続可能なノートPCの持参をお願いします(Wi-Fi環境はこちらで用意します)。</p>\n" +
     "</li>\n" +
     "<li>\n" +
     "<p>小学生以下のお子さんが参加される場合、保護者の方は会場までの送迎をお願いします。</p>\n" +
     "</li>\n" +
     "<li>\n" +
     "<p>Scratchは事前に<a href=\"https://scratch.mit.edu/scratch2download//" rel=\"nofollow\">ここ</a>を参照しオフラインエディタをインストールしていただけると当日スムーズに作業が開始できます。</p>\n" +
     "</li>\n" +
     "</ul>",
    "address"=>"静岡県浜松市中区海老塚二丁目25-17",
    "catch"=>"小中学生向けのプログラミング道場",
    "accepted"=>5,
    "ended_at"=>"2017-08-11T15:30:00+09:00",
    "place"=>"浜松市南部協働センター 第3講座室"}],
 "results_start"=>1,
 "results_available"=>12}

results_availableは12で過去分を含めた全てのイベントは12件存在している
https://coderdojo-hamamatsu.connpass.com/event/

ただし、series_idを引っ張ってくるためには一度apiを叩く必要があり、なにかしらのkey, valueが必要。
例に挙げたCoderDojo浜松のDBにあるデータは以下のとおりで、

- name: 浜松 (東海)
  logo: https://pbs.twimg.com/profile_images/679526979456991234/3ycBOGYG.png
  url: http://www.coderdojo-hamamatsu.org/
  description: 静岡県浜松市で毎月開催
  order: 180
  tags:
  - Scratch
  - Webサイト
  - Ruby

CoderDojo浜松のデータを取るためのキーワードがなさそうなので、
series_idを引くためのkey,valueを別途持つ必要がある。

ちなみに、下北沢の場合は以下のようなデータで、

- name: 下北沢 (関東)
  url: https://coderdojo-tokyo.connpass.com/
  logo: https://graph.facebook.com/346407898743580/picture?type=large
  description: 東京都世田谷区で毎週開催
  order: 0
  tags:
  - Scratch
  - Webサイト
  - ゲーム

dojosテーブルのurlがconnpassのサブドメインなのだが、
coderdojo-tokyo.connpass.comをkeywordにしてもヒットしないためseries_idは引けない。

@nalabjp
Copy link
Member

nalabjp commented Jul 29, 2017

memo: doorkeeperのapi

ref: https://www.doorkeeperhq.com/developer/api

connpassと同様にgroupというキーが使えそう。
ただ、こちらもgroupを引くためのvalueが必要。
doorkeeperはqというkeyで検索するしかなく、Keyword to search for from the title or description fields.という仕様の模様。

@yasulab
Copy link
Member Author

yasulab commented Jul 30, 2017

現状、dojos.yaml には公式サイトへのURLを入力する項目 (url) がありますが、これとは別に当該道場のイベント管理ページへのURLを入力する欄を設けても良いかもしれないですね🤔

@nalabjp
Copy link
Member

nalabjp commented Jul 30, 2017

当該道場のイベント管理ページへのURLを入力する欄を設けても良いかもしれないですね

これなんですが、

coderdojo-tokyo.connpass.comをkeywordにしてもヒットしないためseries_idは引けない。

という理由からイベントリストを束ねるseries_id(doorkeeperではgroup)を引くという観点からはあまり有効なcolumnになれなさそうなんですよね。
なので、もういっそのこと手運用(apiを叩く簡単なrake taskぐらいは用意)でseries_idを取ってきてから登録してしまおうかと思っています。

@yasulab
Copy link
Member Author

yasulab commented Jul 30, 2017

なるほど、手運用でも良さそうですね! その場合は yaml ではなく Dojo モデルに更新をかけるような形が良いかなと思いました! (yaml は各道場運営者に編集してもらうためのファイルで、なるべく簡潔で分かりやすい状態の方がよいので💦)

@nalabjp
Copy link
Member

nalabjp commented Jul 30, 2017

yaml は各道場運営者に編集してもらうためのファイルで、なるべく簡潔で分かりやすい状態の方がよいので

なるほど、貴重な情報ありがとうございます😁
yamlに追加するかちょうど検討していたので、きっぱり辞める決心がついて良かったですw

Dojo モデルに更新をかけるような形が良いかなと思いました!

そうですね、coderdojo管理者がなんか良しなにやる方法にします。
Dojo has_one DojoEventService(id, name, url, group_id) みたいな感じで。

@yasulab
Copy link
Member Author

yasulab commented Jul 30, 2017

ご参考になったようで何よりです! 😸 何か気になる箇所などあれば、お気軽にご連絡くださ〜い ;)

yasulab added a commit that referenced this issue Aug 21, 2017
Implementation to aggregate statistical information #12
@yasulab
Copy link
Member Author

yasulab commented Aug 21, 2017

@nalabjp PRありがとうございました! 😸 先ほどPRをマージしましたが、こちらの Issue については、トップページ ( https://coderdojo.jp/ ) に

これまでに xxx 回以上のイベントが開催されました。

といった文言を追加するところまでやろうかなと考えています 🤔 (インパクトの高い統計情報だと思うので、ぜひ載せたい)

なので上記の文言をトップページに表示できるようになったら、本 Issue を完了という形にさせていただけると嬉しいです! 🙏

@nalabjp
Copy link
Member

nalabjp commented Oct 31, 2017

#164 をマージしたあとのTODO

  • facebookのapp_id, app_secretを環境変数に登録
  • rails dojo_event_services:upsertを実行してdojo_event_servicesテーブルをmigrate (冪等)
  • rails statistics:aggregationを実行してイベント履歴の過去分全てを集計する(2012年12月ぐらいから?)
  • 件数表示部分の実装 => @yasulab

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

.oO(イベント統計情報、どう呼び出すのが正しいんだろう...? 聞くの忘れていました ><)

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

むむ、、、冪等ではないのかな...?

$ heroku run rails dojo_event_services:upsert
ActiveModel::RangeError: 542546935853207 is out of range for ActiveModel::Type::Integer with limit 4 bytes

エラー内容
``` rails aborted! ActiveModel::RangeError: 542546935853207 is out of range for ActiveModel::Type::Integer with limit 4 bytes /app/vendor/bundle/ruby/2.4.0/gems/activemodel-5.1.4/lib/active_model/type/integer.rb:51:in `ensure_in_range' /app/vendor/bundle/ruby/2.4.0/gems/activemodel-5.1.4/lib/active_model/type/integer.rb:27:in `serialize' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/attribute.rb:51:in `value_for_database' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/relation/query_attribute.rb:11:in `value_for_database' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/quoting.rb:166:in `block in type_casted_binds' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/quoting.rb:166:in `map' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/quoting.rb:166:in `type_casted_binds' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `exec_no_cache' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql_adapter.rb:601:in `execute_and_clear' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:79:in `exec_query' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:102:in `exec_insert' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:113:in `exec_insert' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:133:in `insert' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/query_cache.rb:17:in `insert' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/relation.rb:61:in `insert' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/persistence.rb:589:in `_create_record' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/counter_cache.rb:178:in `_create_record' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/locking/optimistic.rb:76:in `_create_record' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/attribute_methods/dirty.rb:296:in `_create_record' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/callbacks.rb:340:in `block in _create_record' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:131:in `run_callbacks' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:827:in `_run_create_callbacks' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/callbacks.rb:340:in `_create_record' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/timestamp.rb:95:in `_create_record' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/persistence.rb:563:in `create_or_update' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/callbacks.rb:336:in `block in create_or_update' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:131:in `run_callbacks' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/callbacks.rb:827:in `_run_save_callbacks' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/callbacks.rb:336:in `create_or_update' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/persistence.rb:162:in `save!' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/validations.rb:50:in `save!' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/attribute_methods/dirty.rb:43:in `save!' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:313:in `block in save!' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:384:in `block in with_transaction_returning_status' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in `block in transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:194:in `block in within_new_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:191:in `within_new_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in `transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:210:in `transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:381:in `with_transaction_returning_status' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:313:in `save!' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/suppressor.rb:46:in `save!' /app/lib/tasks/dojo_event_services.rake:31:in `block (3 levels) in ' /app/lib/tasks/dojo_event_services.rake:9:in `each' /app/lib/tasks/dojo_event_services.rake:9:in `block (2 levels) in ' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:21:in `block in perform' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:18:in `perform' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/command.rb:46:in `invoke' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands.rb:16:in `' /app/bin/rails:4:in `require' /app/bin/rails:4:in `' Tasks: TOP => dojo_event_services:upsert ```

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

$ heroku run rails statistics:aggregation は無事に動いたっぽい 🤔

@nalabjp
Copy link
Member

nalabjp commented Nov 3, 2017

@yasulab

ActiveModel::RangeError: 542546935853207 is out of range for ActiveModel::Type::Integer with limit 4 bytes

integer to stringに変更したmigrationが実行されてなさそうな気がします!

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

@nalabjp おぉ、失念してました 💦 コメントありがとうございます! 😸

@nalabjp
Copy link
Member

nalabjp commented Nov 3, 2017

herokuへのdeploy時ってmigration走らないんでしたっけ?🤔

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

あれ、でも heroku run rails db:migrate が失敗しているなぁ。メッセージ見ると、PostgreSQL独特の何かかな🤔 ちなみに手元の環境では問題なくマイグレーションスクリプトを実行できました ✅

Caused by:
ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR: column "name" cannot be cast automatically to type integer
HINT: You might need to specify "USING name::integer".
: ALTER TABLE "dojo_event_services" ALTER COLUMN "name" TYPE integer

``` ▸ heroku-cli: update available from 6.13.13 to 6.14.36-15f8a25 Running rails db:migrate on ⬢ coderdojo-japan... up, run.3368 (Hobby) D, [2017-11-03T15:17:37.436091 #4] DEBUG -- : (1.0ms) SELECT pg_try_advisory_lock(2721298366456587855) D, [2017-11-03T15:17:37.449559 #4] DEBUG -- : (1.4ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC I, [2017-11-03T15:17:37.450654 #4] INFO -- : Migrating to ChangeColumnTypeDojoEventServices (20170820090605) D, [2017-11-03T15:17:37.453089 #4] DEBUG -- : (1.0ms) BEGIN == 20170820090605 ChangeColumnTypeDojoEventServices: migrating ================ -- change_column(:dojo_event_services, :name, :integer, {:null=>false}) D, [2017-11-03T15:17:37.455033 #4] DEBUG -- : (1.6ms) ALTER TABLE "dojo_event_services" ALTER COLUMN "name" TYPE integer D, [2017-11-03T15:17:37.456232 #4] DEBUG -- : (1.0ms) ROLLBACK D, [2017-11-03T15:17:37.457506 #4] DEBUG -- : (1.1ms) SELECT pg_advisory_unlock(2721298366456587855) rails aborted! StandardError: An error has occurred, this and all later migrations canceled:

PG::DatatypeMismatch: ERROR: column "name" cannot be cast automatically to type integer
HINT: You might need to specify "USING name::integer".
: ALTER TABLE "dojo_event_services" ALTER COLUMN "name" TYPE integer
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:73:in async_exec' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:73:in block (2 levels) in execute'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:46:in block in permit_concurrent_loads' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/concurrency/share_lock.rb:185:in yield_shares'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:45:in permit_concurrent_loads' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:72:in block in execute'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:612:in block (2 levels) in log' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:611:in block in log'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/notifications/instrumenter.rb:21:in instrument' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:603:in log'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:71:in execute' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/schema_statements.rb:428:in change_column'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:849:in block in method_missing' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:818:in block in say_with_time'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:818:in say_with_time' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:838:in method_missing'
/app/db/migrate/20170820090605_change_column_type_dojo_event_services.rb:3:in up' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:795:in exec_migration'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:776:in block (2 levels) in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:775:in block in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:408:in with_connection' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:774:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:953:in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1230:in block in execute_migration_in_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1298:in block in ddl_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in block in transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:194:in block in within_new_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:191:in within_new_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:210:in transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1298:in ddl_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1229:in execute_migration_in_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1201:in block in migrate_without_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1200:in each'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1200:in migrate_without_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in block in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1317:in with_advisory_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1007:in up' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:985:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/tasks/database_tasks.rb:171:in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/railties/databases.rake:58:in block (2 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:21:in block in perform' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:18:in perform'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/command.rb:46:in invoke' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands.rb:16:in <top (required)>'
/app/bin/rails:4:in require' /app/bin/rails:4:in

'

Caused by:
ActiveRecord::StatementInvalid: PG::DatatypeMismatch: ERROR: column "name" cannot be cast automatically to type integer
HINT: You might need to specify "USING name::integer".
: ALTER TABLE "dojo_event_services" ALTER COLUMN "name" TYPE integer
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:73:in async_exec' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:73:in block (2 levels) in execute'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:46:in block in permit_concurrent_loads' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/concurrency/share_lock.rb:185:in yield_shares'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:45:in permit_concurrent_loads' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:72:in block in execute'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:612:in block (2 levels) in log' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:611:in block in log'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/notifications/instrumenter.rb:21:in instrument' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:603:in log'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:71:in execute' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/schema_statements.rb:428:in change_column'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:849:in block in method_missing' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:818:in block in say_with_time'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:818:in say_with_time' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:838:in method_missing'
/app/db/migrate/20170820090605_change_column_type_dojo_event_services.rb:3:in up' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:795:in exec_migration'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:776:in block (2 levels) in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:775:in block in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:408:in with_connection' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:774:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:953:in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1230:in block in execute_migration_in_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1298:in block in ddl_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in block in transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:194:in block in within_new_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:191:in within_new_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:210:in transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1298:in ddl_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1229:in execute_migration_in_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1201:in block in migrate_without_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1200:in each'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1200:in migrate_without_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in block in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1317:in with_advisory_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1007:in up' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:985:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/tasks/database_tasks.rb:171:in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/railties/databases.rake:58:in block (2 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:21:in block in perform' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:18:in perform'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/command.rb:46:in invoke' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands.rb:16:in <top (required)>'
/app/bin/rails:4:in require' /app/bin/rails:4:in

'

Caused by:
PG::DatatypeMismatch: ERROR: column "name" cannot be cast automatically to type integer
HINT: You might need to specify "USING name::integer".
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:73:in async_exec' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:73:in block (2 levels) in execute'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:46:in block in permit_concurrent_loads' /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/concurrency/share_lock.rb:185:in yield_shares'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies/interlock.rb:45:in permit_concurrent_loads' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:72:in block in execute'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:612:in block (2 levels) in log' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:611:in block in log'
/app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.4/lib/active_support/notifications/instrumenter.rb:21:in instrument' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract_adapter.rb:603:in log'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:71:in execute' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/postgresql/schema_statements.rb:428:in change_column'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:849:in block in method_missing' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:818:in block in say_with_time'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:818:in say_with_time' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:838:in method_missing'
/app/db/migrate/20170820090605_change_column_type_dojo_event_services.rb:3:in up' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:795:in exec_migration'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:776:in block (2 levels) in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:775:in block in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/connection_pool.rb:408:in with_connection' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:774:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:953:in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1230:in block in execute_migration_in_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1298:in block in ddl_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in block in transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:194:in block in within_new_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:191:in within_new_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:235:in transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/transactions.rb:210:in transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1298:in ddl_transaction' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1229:in execute_migration_in_transaction'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1201:in block in migrate_without_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1200:in each'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1200:in migrate_without_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in block in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1317:in with_advisory_lock' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1148:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:1007:in up' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/migration.rb:985:in migrate'
/app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/tasks/database_tasks.rb:171:in migrate' /app/vendor/bundle/ruby/2.4.0/gems/activerecord-5.1.4/lib/active_record/railties/databases.rake:58:in block (2 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:21:in block in perform' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands/rake/rake_command.rb:18:in perform'
/app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/command.rb:46:in invoke' /app/vendor/bundle/ruby/2.4.0/gems/railties-5.1.4/lib/rails/commands.rb:16:in <top (required)>'
/app/bin/rails:4:in require' /app/bin/rails:4:in

'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

</details>

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

herokuへのdeploy時ってmigration走らないんでしたっけ?🤔

@nalabjp 最近全くマイグレーションやって気にしてなかったので、確かに走らせてない可能性がありますね 😅

@nalabjp
Copy link
Member

nalabjp commented Nov 3, 2017

https://stackoverflow.com/questions/10343383/rails-migrations-tried-to-change-the-type-of-column-from-string-to-integer

むむっ、postgresさん、カラムのタイプ変更がちょっと一手間必要そう?

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

なるほど🤔 事前に気づけてよかったです! 😸 もし運用開始が間に合わなくても、スクリプトで取得した統計データさえ教えてもらえればとりあえず数字を表示することはできるので、最悪それで見せてしまうこともできそうです ;) 👍 ✨ (ポイントは運用が始まることではなく、スクリプトで取得した統計データ情報なので、それを見せられればとりあえずは問題なさそう 📈✨)

@nalabjp
Copy link
Member

nalabjp commented Nov 3, 2017

https://stackoverflow.com/a/36899371

rails wayだとこんな感じだと書かれてますね。
(sqliteのときは動かなさそうだなー😇)

@yasulab
Copy link
Member Author

yasulab commented Nov 3, 2017

CoderDojo 柏周辺は自前のイベント管理サービスを使っていて、その合計をさっき直接伺ったのでこちらにメモしておきますね ;)

  • 柏: 93
  • 柏の葉: 29
  • 南柏: 3
  • 柏湘南: 4

=> 129回

@nalabjp
Copy link
Member

nalabjp commented Nov 3, 2017

CoderDojo 柏周辺は自前のイベント管理サービスを使っていて

柏はfacebookイベントから計測済みでした〜

yasulab added a commit that referenced this issue Nov 4, 2017
- Stats of 69/109 dojos using Facebook/Doorkeeper/connpass (1,466)
- Manually add the number of 柏の葉, 南柏, 柏湘南, and 小平
- This stats will be dynamically updated in the near future
@yasulab
Copy link
Member Author

yasulab commented Nov 4, 2017

Fixed by dcdd172 ✅ Thx @nalabjp for the great work!! 🎉 ✨

@yasulab yasulab closed this as completed Nov 5, 2017
@yasulab yasulab changed the title 各種イベント管理サービスのAPIを叩いて、統計情報を集計したい 各種イベント管理サービスのAPIで統計情報を集計したい Nov 22, 2017
@yasulab yasulab added the 統計情報 Tracking event record function via APIs: https://coderdojo.jp/stats label Jan 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
急ぎじゃないよ Make something better but not rushed. 統計情報 Tracking event record function via APIs: https://coderdojo.jp/stats
Projects
None yet
Development

No branches or pull requests

3 participants