Skip to content

Instantly share code, notes, and snippets.

@afa
Created February 4, 2019 18:11
Show Gist options
  • Save afa/d82edf8f67621eb8e4ce33438bfa12c3 to your computer and use it in GitHub Desktop.
Save afa/d82edf8f67621eb8e4ce33438bfa12c3 to your computer and use it in GitHub Desktop.
примеры работы с внешним апи
module FileStorage
class BaseModel < Hashie::Trash
include Hashie::Extensions::Coercion
include Hashie::Extensions::MergeInitializer
include Hashie::Extensions::IndifferentAccess
include Hashie::Extensions::IgnoreUndeclared
end
end
module FileStorage
class FilePermission < BaseModel
property :file_id
property :permission
end
end
module Deal
class DocumentsFilter
include Dry::Transaction
include DryTransactionRunable
map :by_document_type
def by_document_type(documents:, document_type: Settings.deal.documents.document_type)
documents.select { |document| document.document_type_id == document_type }
end
end
end
module Deal
class LocateAssistantsDocuments
include Dry::Transaction
include DryTransactionRunable
SERVER_ERRORS = [
Domclick::Deal::Client::ConnectionError,
Domclick::Deal::HttpErrors::ServerError
].freeze
CLIENT_ERRORS = [
Domclick::Deal::HttpErrors::ClientError
].freeze
TEMPLATES = {
server: 'server connection error: %s',
client: 'data transfer error: %s'
}.freeze
step :select_deals
map :expand_documents
def select_deals(assistant:, assistance:)
ids = [assistance.client&.user&.cas_id].compact
return Failure('require client cas_id') if ids.blank?
Success(send_api_request(assistant.cas_id, ids))
rescue *SERVER_ERRORS => e
notify_errors(e, :server)
rescue *CLIENT_ERRORS => e
notify_errors(e, :client)
end
def expand_documents(deals)
{ documents: deals.flat_map(&:documents) }
end
private
def send_api_request(cas_id, person_cas_ids)
search = Domclick::Deal::Model::DealSearch.new(person_cas_ids: person_cas_ids)
Domclick::Deal.client(cas_id: cas_id).search_deals(search).expand(:documents).all
end
def notify_errors(exception, template_sym)
ErrorNotifier.notify(exception)
Failure(format(TEMPLATES[template_sym], exception.message))
end
end
end
module FileStorage
class GetFileRoles
include Dry::Transaction
include DryTransactionRunable
ACCEPTANCE_HEADERS = {
'Accept': 'application/json',
'Content-Type' => 'multipart/form-data'
}.freeze
step :get_file_roles
# @param options <Hash>
# :with_empty false - returns only set permissions
def get_file_roles(config:, documents:, options: {})
file_ids = docs_to_ids(documents)
begin
json = RestClient::Request.execute(
method: :get,
url: getter_url(config, file_ids),
headers: ACCEPTANCE_HEADERS,
user: config.basic_login, password: config.basic_pass
)
rescue RestClient::NotFound
return Failure([])
end
data = JSON.parse(json)
Success(docs_to_objs(data, options))
end
private
def getter_url(config, file_ids)
Addressable::Template.new(config.host + config.permissions.get).expand(fileIds: file_ids).to_s
end
def docs_to_objs(perms, options)
perms.flat_map do |perm|
if perm['permissionDTO'].blank? && options[:with_empty]
FileStorage::FilePermission.new(permission: nil, file_id: perm['fileId'])
elsif perm['permissionDTO'].blank?
[]
else
perm['permissionDTO'].map do |hsh|
FileStorage::FilePermission.new(
permission: hsh['userIdentityId'],
file_id: hsh['fileId']
)
end
end
end.compact
end
def docs_to_ids(docs)
docs.map { |obj| obj.respond_to?(:file_id) ? obj.file_id : obj }.join(',')
end
end
end
module FileStorage
class PrepareDealDocumentsRights
include Dry::Transaction
include DryTransactionRunable
step :setup_required_rights
def setup_required_rights(config:, documents:, roles:)
result = FileStorage::GetFileRoles.run(config: config, documents: documents, options: { with_empty: true })
return Failure(:error_getting_file_rights) if result.failure?
if FileStorage::SetFileRoles.run(config: config, documents: result.value!, required_roles: roles).failure?
return Failure(:error_setting_file_rights)
end
Success(:ok)
end
end
end
module FileStorage
class SetFileRoles
include Dry::Transaction
include DryTransactionRunable
ACCEPTANCE_HEADERS = {
'Accept' => 'application/json',
'Content-Type' => 'application/json'
}.freeze
step :set_file_roles
# @param documents <Array> array of FileStorage::FilePermission
# специальный случай. когда у файла нет ролей, в FilePermission поле permission устанавливается в nil
def set_file_roles(config:, documents:, required_roles:)
records = build_file_permission_list(documents, required_roles)
Success(
RestClient::Request.execute(
method: :post,
url: setter_url(config, records),
payload: records.to_json,
headers: ACCEPTANCE_HEADERS,
user: config.basic_login, password: config.basic_pass
)
)
end
private
def setter_url(config, records)
Addressable::Template.new(config.host + config.permissions.set)
.expand(fileIds: records[:fileIdList].uniq)
.to_s
end
def extract_files_from_permissions(file_permissions)
file_permissions.map(&:file_id).uniq
end
def select_available_file_permissions(files)
files.select(&:permission)
end
def build_file_perission(file_id, permission)
FileStorage::FilePermission.new(
file_id: file_id,
permission: permission
)
end
def build_file_permission_list(files, roles)
role = roles.first
file_list = files.map { |hash| hash[:file_id].to_s }
{
fileIdList: file_list,
permissionDTO: { role: true, userIdentityId: role }
}
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment