diff --git a/Gemfile b/Gemfile index 759e2b5..de177ae 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,7 @@ gem "title" gem "uglifier" gem "telegram-bot-ruby" gem "leaflet-rails" +gem "paperclip", "~> 5.0.0.beta1" group :development do gem "quiet_assets" diff --git a/Gemfile.lock b/Gemfile.lock index 9c3799c..5ae7d8e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -66,6 +66,10 @@ GEM capybara-webkit (1.10.1) capybara (>= 2.3.0, < 2.8.0) json + climate_control (0.0.3) + activesupport (>= 3.0) + cocaine (0.5.8) + climate_control (>= 0.0.3, < 1.0) coderay (1.1.1) coercible (1.0.0) descendants_tracker (~> 0.0.1) @@ -131,6 +135,7 @@ GEM mime-types (3.0) mime-types-data (~> 3.2015) mime-types-data (3.2016.0221) + mimemagic (0.3.1) mini_portile2 (2.0.0) minitest (5.8.4) multipart-post (2.0.0) @@ -141,6 +146,12 @@ GEM nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) normalize-rails (3.0.3) + paperclip (5.0.0.beta2) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + cocaine (~> 0.5.5) + mime-types + mimemagic (~> 0.3.0) pg (0.18.4) pry (0.10.3) coderay (~> 1.1.0) @@ -290,6 +301,7 @@ DEPENDENCIES neat (~> 1.7.0) newrelic_rpm (>= 3.9.8) normalize-rails (~> 3.0.0) + paperclip (~> 5.0.0.beta1) pg pry-byebug pry-rails diff --git a/app/models/player.rb b/app/models/player.rb index 8933b1c..e38b966 100644 --- a/app/models/player.rb +++ b/app/models/player.rb @@ -2,13 +2,24 @@ # # Table name: players # -# id :integer not null, primary key -# first_name :string -# last_name :string -# username :string -# telegram_user_id :integer +# id :integer not null, primary key +# first_name :string +# last_name :string +# username :string +# telegram_user_id :integer +# avatar_file_name :string +# avatar_content_type :string +# avatar_file_size :integer +# avatar_updated_at :datetime # class Player < ActiveRecord::Base - has_many :attendances + has_many :attendances, dependent: :destroy + has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, + default_url: "/images/:style/missing.png" + validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\Z/ + + def avatar_url + avatar.url(:original) + end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 643e9d1..cc9fd8b 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -18,4 +18,5 @@ config.action_view.raise_on_missing_translations = true config.action_mailer.default_url_options = { host: "localhost:3000" } default_url_options[:host] = ENV['APPLICATION_HOST'] + Paperclip.options[:command_path] = "/usr/local/bin/" end diff --git a/db/migrate/20160513142219_add_attachment_avatar_to_players.rb b/db/migrate/20160513142219_add_attachment_avatar_to_players.rb new file mode 100644 index 0000000..c93a94f --- /dev/null +++ b/db/migrate/20160513142219_add_attachment_avatar_to_players.rb @@ -0,0 +1,11 @@ +class AddAttachmentAvatarToPlayers < ActiveRecord::Migration + def self.up + change_table :players do |t| + t.attachment :avatar + end + end + + def self.down + remove_attachment :players, :avatar + end +end diff --git a/db/schema.rb b/db/schema.rb index 2347e7a..7d314e3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160422153232) do +ActiveRecord::Schema.define(version: 20160513142219) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -55,10 +55,14 @@ end create_table "players", force: :cascade do |t| - t.string "first_name" - t.string "last_name" - t.string "username" - t.integer "telegram_user_id" + t.string "first_name" + t.string "last_name" + t.string "username" + t.integer "telegram_user_id" + t.string "avatar_file_name" + t.string "avatar_content_type" + t.integer "avatar_file_size" + t.datetime "avatar_updated_at" end add_foreign_key "attendances", "games" diff --git a/lib/pickup_bot/commands/join.rb b/lib/pickup_bot/commands/join.rb index 9b3d984..44dc671 100644 --- a/lib/pickup_bot/commands/join.rb +++ b/lib/pickup_bot/commands/join.rb @@ -12,6 +12,17 @@ def initialize(telegram_bot, message) def run if game_exists? current_player = Player.find_or_create_by(telegram_user_id: message.from.id) + pics = telegram_bot.api.get_user_profile_photos(user_id: message.from.id) + file_id = pics["result"]["photos"][0][2]["file_id"] + file = telegram_bot.api.get_file(file_id: file_id) + file_path = file["result"]["file_path"] + photo_url = "https://api.telegram.org/file/bot#{ENV["TELEGRAM_TOKEN"]}/#{file_path}" + current_player.avatar = URI.parse(photo_url) + current_player.first_name = message.from.first_name + current_player.last_name = message.from.last_name + current_player.username = message.from.username + current_player.save + attendence = Attendance.new(game: current_game, player: current_player) attendence.save telegram_bot.api.send_message( diff --git a/spec/factories/player.rb b/spec/factories/player.rb new file mode 100644 index 0000000..e914b76 --- /dev/null +++ b/spec/factories/player.rb @@ -0,0 +1,10 @@ +include ActionDispatch::TestProcess + +FactoryGirl.define do + factory :player do + first_name "Han" + last_name "Solo" + username "HSolo" + telegram_user_id "123" + end +end diff --git a/spec/fixtures/profile_picture.png b/spec/fixtures/profile_picture.png new file mode 100644 index 0000000..5ef335c Binary files /dev/null and b/spec/fixtures/profile_picture.png differ diff --git a/spec/lib/pickup_bot/commands/join_game_spec.rb b/spec/lib/pickup_bot/commands/join_game_spec.rb index 86252ac..41992a9 100644 --- a/spec/lib/pickup_bot/commands/join_game_spec.rb +++ b/spec/lib/pickup_bot/commands/join_game_spec.rb @@ -34,6 +34,10 @@ context "an active game exists" do scenario "new player joins game, a new player is created" do + stub_avatar_request + allow(bot.api).to receive(:get_user_profile_photos).and_return(stub_telegram_photos) + allow(bot.api).to receive(:get_file).and_return(stub_file_hash) + message = Telegram::Bot::Types::Message.new(message_params("/join")) game = Game.create(chat_id: fake_chat_id, required_players: 5) @@ -51,6 +55,8 @@ )).to have_been_made.times(1) expect(Player.count).to eq 1 expect(Game.last.attendances.count).to eq 1 + expect(Player.last.avatar_file_name).to_not eq nil + expect(Player.last.first_name).to eq message.from.first_name end scenario "existing player joins game" do @@ -74,4 +80,30 @@ expect(Game.last.attendances.count).to eq 1 end end + + + private + def stub_telegram_photos + {"ok"=>true, + "result"=> + {"total_count"=>1, + "photos"=> + [[{"file_id"=>"fake-file-id", "file_size"=>8786, "width"=>160, "height"=>160}, + {"file_id"=>"fake-file-id-2", "file_size"=>23897, "width"=>320, "height"=>320}, + {"file_id"=>"fake-file-id-3", "file_size"=>62566, "width"=>640, "height"=>640}]]}} + end + + def stub_file_hash + {"ok"=>true, "result"=>{"file_id"=> "fake-file-id", "file_size"=>8786, "file_path"=>"photo/file_0.jpg"}} + end + + + def stub_avatar_request + stub_request(:get, "https://api.telegram.org/file/bot143293395:AAHiPFb9qZYYRckQGRt5IJTlGG8KsHFh6X8/photo/file_0.jpg"). + with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}). + to_return( + :status => 200, + :body => File.open(File.join(Rails.root, '/spec/fixtures/profile_picture.png')), + :headers => { content_type: "image/png" }) + end end diff --git a/spec/models/player_spec.rb b/spec/models/player_spec.rb new file mode 100644 index 0000000..6880adc --- /dev/null +++ b/spec/models/player_spec.rb @@ -0,0 +1,37 @@ +# == Schema Information +# +# Table name: players +# +# id :integer not null, primary key +# first_name :string +# last_name :string +# username :string +# telegram_user_id :integer +# avatar_file_name :string +# avatar_content_type :string +# avatar_file_size :integer +# avatar_updated_at :datetime +# + +require "spec_helper" + +describe Player, type: :model do + describe "associations" do + it { is_expected.to have_many :attendances } + end + + describe "#avatar_url" do + context "when it is set" do + it "returns the uploaded image" do + fake_picture = "#{Rails.root}/spec/fixtures/profile_picture.png" + + player = build(:player, first_name: "Harisson", last_name: "Ford", + username: "Han Solo", telegram_user_id: "123", + avatar: fixture_file_upload(fake_picture) + ) + + expect(player.avatar_url).to eq(player.avatar.url(:original)) + end + end + end +end