add geo info and do refractor on workers

This commit is contained in:
2021-04-29 20:44:21 +02:00
parent f7799bb514
commit c5190b48f8
32 changed files with 241 additions and 205 deletions

View File

@@ -9,6 +9,8 @@ class WowCharacter < ApplicationRecord
belongs_to :wow_class
belongs_to :wow_race
belongs_to :wow_character_title, optional: true
belongs_to :last_position, class_name: 'WowGeoPosition', optional: true
belongs_to :bind_position, class_name: 'WowGeoPosition', optional: true
has_one :wow_character_medium, dependent: :nullify
validates :name, presence: true

11
app/models/wow_geo_map.rb Normal file
View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
class WowGeoMap < ApplicationRecord
extend Mobility
translates :name
has_many :wow_geo_positions, dependent: :destroy
validates :name, presence: true
validates :map_id, presence: true, uniqueness: true
end

View File

@@ -0,0 +1,21 @@
# frozen_string_literal: true
class WowGeoPosition < ApplicationRecord
belongs_to :wow_geo_map
belongs_to :wow_geo_zone
has_one(
:last_position_character,
class_name: 'WowCharacter',
foreign_key: 'last_position_id',
inverse_of: :last_position,
dependent: :destroy
)
has_one(
:bind_position_character,
class_name: 'WowCharacter',
foreign_key: 'bind_position_id',
inverse_of: :bind_position,
dependent: :destroy
)
end

View File

@@ -0,0 +1,11 @@
# frozen_string_literal: true
class WowGeoZone < ApplicationRecord
extend Mobility
translates :name
has_many :wow_geo_positions, dependent: :destroy
validates :name, presence: true
validates :zone_id, presence: true, uniqueness: true
end

View File

@@ -9,6 +9,8 @@
<p class="card-text"><%= @wow_character.gender_race_name %></p>
<p class="card-text"><%= @wow_character.gender_class_name %></p>
<p class="card-text"><%= @wow_character.last_login_timestamp %></p>
<p class="card-text">Last position: Map: <%= @wow_character.last_position.wow_geo_map.name %> Zone: <%= @wow_character.last_position.wow_geo_zone.name %></p>
<p class="card-text">Bind position: Map: <%= @wow_character.bind_position.wow_geo_map.name %> Zone: <%= @wow_character.bind_position.wow_geo_zone.name %></p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>

View File

@@ -1,13 +1,13 @@
# frozen_string_literal: true
class WowCharacterDetailWorker
include Sidekiq::Worker
class WowCharacterDetailWorker < WowSidekiqWorker
def perform(wow_character_id)
return unless (wow_character = WowCharacter.where(character_id: wow_character_id).first)
return unless (wow_character = WowCharacter.find_by(character_id: wow_character_id))
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'en_GB')
# Public data
result = RBattlenet::Wow::Character.find({ name: wow_character.name.downcase, realm: wow_character.wow_realm.slug })
return unless result.status_code == 200
@@ -16,7 +16,7 @@ class WowCharacterDetailWorker
wow_character.last_login_timestamp = Time.at(result.last_login_timestamp.to_s[0..-4].to_i).utc
wow_character.average_item_level = result.average_item_level
wow_character.equipped_item_level = result.equipped_item_level
wow_character.wow_character_title = WowCharacterTitle.where(title_id: result.active_title.id).first if result.active_title
wow_character.wow_character_title = WowCharacterTitle.find_by(title_id: result.active_title.id) if result.active_title
wow_character.save
end

View File

@@ -1,8 +1,6 @@
# frozen_string_literal: true
class WowCharacterMediaWorker
include Sidekiq::Worker
class WowCharacterMediaWorker < WowSidekiqWorker
def perform(wow_character_id)
return unless (wow_character = WowCharacter.where(character_id: wow_character_id).first)

View File

@@ -0,0 +1,62 @@
# frozen_string_literal: true
class WowCharacterPositionsWorker < WowSidekiqWorker
def perform(wow_character_id)
return unless (wow_character = WowCharacter.find_by(character_id: wow_character_id))
# Protected data
RBattlenet.set_options(locale: 'all')
params = { character_id: wow_character_id, realm_id: wow_character.wow_realm.realm_id, token: wow_character.user.token }
result = RBattlenet::Wow::Profile::ProtectedSummary.find(params)
return unless result.status_code == 200
if (last_position = result.position)
wow_character_last_position = wow_character.last_position || WowGeoPosition.new(last_position_character: wow_character)
wow_character_last_position.wow_geo_zone = find_or_create_wow_geo_zone(last_position.zone)
wow_character_last_position.wow_geo_map = find_or_create_wow_geo_map(last_position.map)
wow_character_last_position.x = last_position.x
wow_character_last_position.y = last_position.y
wow_character_last_position.z = last_position.z
wow_character_last_position.facing = last_position.facing
wow_character_last_position.save
end
if (bind_position = result.bind_position)
wow_character_bind_position = wow_character.bind_position || WowGeoPosition.new(bind_position_character: wow_character)
wow_character_bind_position.wow_geo_zone = find_or_create_wow_geo_zone(bind_position.zone)
wow_character_bind_position.wow_geo_map = find_or_create_wow_geo_map(bind_position.map)
wow_character_bind_position.x = bind_position.x
wow_character_bind_position.y = bind_position.y
wow_character_bind_position.z = bind_position.z
wow_character_bind_position.facing = bind_position.facing
wow_character_bind_position.save
end
end
private
def find_or_create_wow_geo_zone(zone)
wow_geo_zone = WowGeoZone.find_or_initialize_by(zone_id: zone.id)
locales.each do |locale|
Mobility.with_locale(locale[0]) do
wow_geo_zone.name = zone.name[locale[1]]
end
end
wow_geo_zone.save
wow_geo_zone.persisted? ? wow_geo_zone : nil
end
def find_or_create_wow_geo_map(map)
wow_geo_map = WowGeoMap.find_or_initialize_by(map_id: map.id)
locales.each do |locale|
Mobility.with_locale(locale[0]) do
wow_geo_map.name = map.name[locale[1]]
end
end
wow_geo_map.save
wow_geo_map.persisted? ? wow_geo_map : nil
end
end

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowCharacterTitleDetailWorker
include Sidekiq::Worker
class WowCharacterTitleDetailWorker < WowSidekiqWorker
def perform(title_id)
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
return unless (title = WowCharacterTitle.where(title_id: title_id).first)
RBattlenet.set_options(locale: 'all')

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowCharacterTitlesWorker
include Sidekiq::Worker
class WowCharacterTitlesWorker < WowSidekiqWorker
def perform
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Title.all
@@ -26,9 +9,8 @@ class WowCharacterTitlesWorker
return unless result.status_code == 200
result.titles.each do |title|
wow_title = WowCharacterTitle.where(title_id: title.id).first_or_initialize
wow_title = WowCharacterTitle.find_or_initialize_by(title_id: title.id)
wow_title.title_id = title.id
wow_title.href = title.key.href
# Localisation data

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowCharactersWorker
include Sidekiq::Worker
class WowCharactersWorker < WowSidekiqWorker
def perform(user_id)
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
# Update the WoW character list
return unless (user = User.find(user_id))
@@ -29,7 +12,7 @@ class WowCharactersWorker
result.wow_accounts.each do |account|
account.characters.each do |character|
wow_char = user.wow_characters.where(character_id: character.id).first_or_initialize
wow_char = user.wow_characters.find_or_initialize_by(character_id: character.id)
wow_char.name = character.name
wow_char.gender = character.gender.type
@@ -40,8 +23,7 @@ class WowCharactersWorker
wow_char.wow_class = WowClass.where(class_id: character.playable_class.id).first
wow_char.wow_race = WowRace.where(race_id: character.playable_race.id).first
wow_char.user = user
wow_char.account_id = account.id
wow_char.character_id = character.id
wow_char.account_id = account.map_id
locales.each do |locale|
Mobility.with_locale(locale[0]) do
@@ -52,10 +34,11 @@ class WowCharactersWorker
wow_char.save
if wow_char.persisted?
WowCharacterMediaWorker.perform_async(wow_char.character_id)
WowCharacterDetailWorker.perform_async(wow_char.character_id)
end
next unless wow_char.persisted?
WowCharacterMediaWorker.perform_async(wow_char.character_id)
WowCharacterDetailWorker.perform_async(wow_char.character_id)
WowCharacterPositionsWorker.perform_async(wow_char.character_id)
end
end
end

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowClassDetailWorker
include Sidekiq::Worker
class WowClassDetailWorker < WowSidekiqWorker
def perform(class_id)
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
return unless (wow_class = WowClass.where(class_id: class_id).first)
RBattlenet.set_options(locale: 'all')

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowClassesWorker
include Sidekiq::Worker
class WowClassesWorker < WowSidekiqWorker
def perform
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::PlayableClass.all
@@ -26,9 +9,8 @@ class WowClassesWorker
return unless result.status_code == 200
result.classes.each do |playable_class|
wow_class = WowClass.where(class_id: playable_class.id).first_or_initialize
wow_class = WowClass.find_or_initialize_by(class_id: playable_class.id)
wow_class.class_id = playable_class.id
wow_class.href = playable_class.key.href
# Localisation data

View File

@@ -1,10 +1,7 @@
# frozen_string_literal: true
class WowMountsCollectionWorker
include Sidekiq::Worker
class WowMountsCollectionWorker < WowSidekiqWorker
def perform(user_id)
# Update the WoW character list
return unless (user = User.find(user_id))
RBattlenet.set_options(locale: 'en_US')

View File

@@ -9,10 +9,9 @@ class WowMountsWorker < WowSidekiqWorker
return unless result.status_code == 200
result.mounts.each do |mount|
wow_mount = WowMount.where(mount_id: mount.id).first_or_initialize
wow_mount = WowMount.find_or_initialize_by(mount_id: mount.id)
# Global data
wow_mount.mount_id = mount.id
wow_mount.href = mount.key.href
# Localisation data

View File

@@ -9,10 +9,8 @@ class WowPetAbilitiesWorker < WowSidekiqWorker
return unless result.status_code == 200
result.abilities.each do |ability|
wow_pet_ability = WowPetAbility.where(ability_id: ability.id).first_or_initialize
wow_pet_ability = WowPetAbility.find_or_initialize_by(ability_id: ability.id)
# Global data
wow_pet_ability.ability_id = ability.id
wow_pet_ability.href = ability.key.href
# Localisation data

View File

@@ -2,7 +2,7 @@
class WowPetAbilityDetailWorker < WowSidekiqWorker
def perform(ability_id)
return unless (ability = WowPetAbility.where(ability_id: ability_id).first)
return unless (ability = WowPetAbility.find_by(ability_id: ability_id))
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::PetAbility.find(ability_id)

View File

@@ -2,7 +2,7 @@
class WowPetDetailWorker < WowSidekiqWorker
def perform(pet_id)
return unless (pet = WowPet.where(pet_id: pet_id).first)
return unless (pet = WowPet.find_by(pet_id: pet_id))
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Pet.find(pet_id)

View File

@@ -1,8 +1,6 @@
# frozen_string_literal: true
class WowPetsCollectionWorker
include Sidekiq::Worker
class WowPetsCollectionWorker < WowSidekiqWorker
def perform(user_id)
return unless (user = User.find(user_id))
@@ -12,7 +10,7 @@ class WowPetsCollectionWorker
return unless result.status_code == 200
result.pets.each do |pet|
next unless (local_pet = WowPet.where(pet_id: pet.species.id).first)
next unless (local_pet = WowPet.find_by(pet_id: pet.species.id))
UserObtainWowPet.where(user: user.id, wow_pet: local_pet.id).first_or_create
end

View File

@@ -9,10 +9,9 @@ class WowPetsWorker < WowSidekiqWorker
return unless result.status_code == 200
result.pets.each do |pet|
wow_pet = WowPet.where(pet_id: pet.id).first_or_initialize
wow_pet = WowPet.find_or_initialize_by(pet_id: pet.id)
# Global data
wow_pet.pet_id = pet.id
wow_pet.href = pet.key.href
# Localisation data

View File

@@ -1,25 +1,8 @@
# frozen_string_literal: true
class WowRaceDetailWorker
include Sidekiq::Worker
class WowRaceDetailWorker < WowSidekiqWorker
def perform(race_id)
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
return unless (race = WowRace.where(race_id: race_id).first)
return unless (race = WowRace.find_by(race_id: race_id))
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::PlayableRace.find(race_id)

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowRacesWorker
include Sidekiq::Worker
class WowRacesWorker < WowSidekiqWorker
def perform
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::PlayableRace.all
@@ -26,10 +9,9 @@ class WowRacesWorker
return unless result.status_code == 200
result.races.each do |playable_race|
wow_race = WowRace.where(race_id: playable_race.id).first_or_initialize
wow_race = WowRace.find_or_initialize_by(race_id: playable_race.id)
# Global data
wow_race.race_id = playable_race.id
wow_race.href = playable_race.key.href
# Localisation data

View File

@@ -1,25 +1,8 @@
# frozen_string_literal: true
class WowRealmDetailWorker
include Sidekiq::Worker
class WowRealmDetailWorker < WowSidekiqWorker
def perform(realm_id)
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
return unless (realm = WowRealm.where(realm_id: realm_id).first)
return unless (realm = WowRealm.find_by(realm_id: realm_id))
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Realm.find(realm_id)

View File

@@ -1,24 +1,7 @@
# frozen_string_literal: true
class WowRealmsWorker
include Sidekiq::Worker
class WowRealmsWorker < WowSidekiqWorker
def perform
locales = [
['en-us', 'en_US'],
['es-mx', 'es_MX'],
['pt-br', 'pt_BR'],
['de-de', 'de_DE'],
['en-gb', 'en_GB'],
['es-es', 'es_ES'],
['fr-fr', 'fr_FR'],
['it', 'it_IT'],
['ru-ru', 'ru_RU'],
['ko', 'ko_KR'],
['zh-tw', 'zh_TW'],
['zh-cn', 'zh_CN']
]
RBattlenet.authenticate(client_id: ENV['BLIZZARD_API_CLIENT_ID'], client_secret: ENV['BLIZZARD_API_CLIENT_SECRET'])
RBattlenet.set_options(locale: 'all')
result = RBattlenet::Wow::Realm.all
@@ -26,9 +9,8 @@ class WowRealmsWorker
return unless result.status_code == 200
result.realms.each do |realm|
wow_realm = WowRealm.where(realm_id: realm.id).first_or_initialize
wow_realm = WowRealm.find_or_initialize_by(realm_id: realm.id)
wow_realm.realm_id = realm.id
wow_realm.slug = realm.slug
wow_realm.href = realm.key.href

View File

@@ -0,0 +1,12 @@
class CreateWowGeoZones < ActiveRecord::Migration[6.1]
def change
create_table :wow_geo_zones do |t|
t.integer :zone_id
t.jsonb :name
t.timestamps
end
add_index :wow_geo_zones, :zone_id, unique: true
end
end

View File

@@ -0,0 +1,12 @@
class CreateWowGeoMaps < ActiveRecord::Migration[6.1]
def change
create_table :wow_geo_maps do |t|
t.integer :map_id
t.jsonb :name
t.timestamps
end
add_index :wow_geo_maps, :map_id, unique: true
end
end

View File

@@ -0,0 +1,14 @@
class CreateWowGeoPositions < ActiveRecord::Migration[6.1]
def change
create_table :wow_geo_positions do |t|
t.float :x
t.float :y
t.float :z
t.float :facing
t.belongs_to :wow_geo_zone
t.belongs_to :wow_geo_map
t.timestamps
end
end
end

View File

@@ -0,0 +1,9 @@
class AddWowGeoPositionToWowCharacter < ActiveRecord::Migration[6.1]
def change
add_column :wow_characters, :last_position_id, :bigint
add_column :wow_characters, :bind_position_id, :bigint
add_foreign_key :wow_characters, :wow_geo_positions, column: :last_position_id, primary_key: :id
add_foreign_key :wow_characters, :wow_geo_positions, column: :bind_position_id, primary_key: :id
end
end

35
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_04_29_132126) do
ActiveRecord::Schema.define(version: 2021_04_29_161239) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -127,6 +127,8 @@ ActiveRecord::Schema.define(version: 2021_04_29_132126) do
t.string "href"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.bigint "last_position_id"
t.bigint "bind_position_id"
t.index ["character_id"], name: "index_wow_characters_on_character_id", unique: true
t.index ["user_id"], name: "index_wow_characters_on_user_id"
t.index ["wow_character_title_id"], name: "index_wow_characters_on_wow_character_title_id"
@@ -147,6 +149,35 @@ ActiveRecord::Schema.define(version: 2021_04_29_132126) do
t.index ["class_id"], name: "index_wow_classes_on_class_id", unique: true
end
create_table "wow_geo_maps", force: :cascade do |t|
t.integer "map_id"
t.jsonb "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["map_id"], name: "index_wow_geo_maps_on_map_id", unique: true
end
create_table "wow_geo_positions", force: :cascade do |t|
t.float "x"
t.float "y"
t.float "z"
t.float "facing"
t.bigint "wow_geo_zone_id"
t.bigint "wow_geo_map_id"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["wow_geo_map_id"], name: "index_wow_geo_positions_on_wow_geo_map_id"
t.index ["wow_geo_zone_id"], name: "index_wow_geo_positions_on_wow_geo_zone_id"
end
create_table "wow_geo_zones", force: :cascade do |t|
t.integer "zone_id"
t.jsonb "name"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["zone_id"], name: "index_wow_geo_zones_on_zone_id", unique: true
end
create_table "wow_mounts", force: :cascade do |t|
t.jsonb "name"
t.string "source_type"
@@ -232,4 +263,6 @@ ActiveRecord::Schema.define(version: 2021_04_29_132126) do
t.index ["realm_id"], name: "index_wow_realms_on_realm_id", unique: true
end
add_foreign_key "wow_characters", "wow_geo_positions", column: "bind_position_id"
add_foreign_key "wow_characters", "wow_geo_positions", column: "last_position_id"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe WowGeoMap, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe WowGeoPosition, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe WowGeoZone, type: :model do
pending "add some examples to (or delete) #{__FILE__}"
end