Skip to content

Instantly share code, notes, and snippets.

@mankind
Last active September 16, 2019 09:52
Show Gist options
  • Save mankind/4e9e41c58b6b2167af93241909949cf9 to your computer and use it in GitHub Desktop.
Save mankind/4e9e41c58b6b2167af93241909949cf9 to your computer and use it in GitHub Desktop.
ubiquity hyku-api
ActiveSupport::Inflector.inflections(:en) do |inflect|
# Here you can put the singular and plural form you expect
inflect.acronym 'API'
#inflect.irregular ' API', 'Api'
end
#/home/edward/dev-2/hyku/spec/fixtures/json/datacite.json
{
"data": {
"id": "https://doi.org/10.15123/pub.7627",
"type": "works",
"attributes": {
"doi": "10.15123/pub.7627",
"identifier": "https://doi.org/10.15123/pub.7627",
"url": "http://roar.uel.ac.uk/id/eprint/7627",
"author": [
{
"given": "Matthew",
"family": "Hawkins"
}
],
"title": "The Concept of Affective Tonality, and the Role of the Senses in Producing a Cinematic Narrative",
"container-title": "The University of East London",
"description": "The practice based research project presented in this thesis\r\ndraws upon theoretical research in affect studies and film-\u00adphilosophy.\r\nThe aim of the thesis is to reconsider the pre-\u00adproduction and production\r\nprocess of narrative cinema and involve the rich and varied research\r\ninto the area of affect and the body in the field of film studies that is\r\ncurrently being used to analyse the reception and meaning making\r\nprocess used as the foundation for producing a series of narrative films\r\nthat privilege affect over traditional storytelling structures.\r\nFour films were made as part of an investigation into affective\r\nfilm practice. These films accompany the written exegesis and serve as\r\na testing ground for concepts developed in the written component of the\r\nthesis. Each piece of practice is formally and conceptually more\r\ncomplex than the last. The fourth and final film serves as an example\r\nfor the cinema of affective tonality and as such constitutes the central,\r\nvisual argument.\r\nThe theoretical research and experimental moving-\u00adimage\r\npractice result in the outlining of five conditions for the production of a\r\ncinema of affective tonality, which are combined with a taxonomy of\r\naffect developed by the author of the thesis. The taxonomy and\r\nguidelines offer filmmakers and researchers -\u00ad engaged in moving-\u00adimage\r\npractice and visual methods -\u00ad a proposition to construct cinema through\r\naffect rather than linguistics and ideology of film grammar.",
"resource-type-subtype": "Thesis",
"data-center-id": "bl.uel",
"member-id": "bl",
"resource-type-id": "text",
"version": null,
"license": "http://creativecommons.org/licenses/by-nc-nd/3.0",
"schema-version": null,
"results": [],
"related-identifiers": [],
"published": "2016",
"registered": "2018-10-22T13:12:01.000Z",
"checked": null,
"updated": "2019-09-11T05:31:35.000Z",
"media": [],
"xml": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHJlc291cmNlIHhtbG5zPSJodHRwOi8vZGF0YWNpdGUub3JnL3NjaGVtYS9rZXJuZWwtNCIgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeHNpOnNjaGVtYUxvY2F0aW9uPSJodHRwOi8vZGF0YWNpdGUub3JnL3NjaGVtYS9rZXJuZWwtNCBodHRwOi8vc2NoZW1hLmRhdGFjaXRlLm9yZy9tZXRhL2tlcm5lbC00L21ldGFkYXRhLnhzZCI+CiAgPGlkZW50aWZpZXIgaWRlbnRpZmllclR5cGU9IkRPSSI+MTAuMTUxMjMvUFVCLjc2Mjc8L2lkZW50aWZpZXI+CiAgPHJlc291cmNlVHlwZSByZXNvdXJjZVR5cGVHZW5lcmFsPSJUZXh0Ij5UaGVzaXM8L3Jlc291cmNlVHlwZT4KICA8Y3JlYXRvcnM+CiAgICA8Y3JlYXRvcj4KICAgICAgPGNyZWF0b3JOYW1lPkhhd2tpbnMsIE1hdHRoZXc8L2NyZWF0b3JOYW1lPgogICAgICA8Z2l2ZW5OYW1lPk1hdHRoZXc8L2dpdmVuTmFtZT4KICAgICAgPGZhbWlseU5hbWU+SGF3a2luczwvZmFtaWx5TmFtZT4KICAgIDwvY3JlYXRvcj4KICA8L2NyZWF0b3JzPgogIDx0aXRsZXM+CiAgICA8dGl0bGUgeG1sOmxhbmc9ImVuIj5UaGUgQ29uY2VwdCBvZiBBZmZlY3RpdmUgVG9uYWxpdHksIGFuZCB0aGUgUm9sZSBvZiB0aGUgU2Vuc2VzIGluIFByb2R1Y2luZyBhIENpbmVtYXRpYyBOYXJyYXRpdmU8L3RpdGxlPgogIDwvdGl0bGVzPgogIDxkZXNjcmlwdGlvbnM+CiAgICA8ZGVzY3JpcHRpb24geG1sOmxhbmc9ImVuIiBkZXNjcmlwdGlvblR5cGU9IkFic3RyYWN0Ij5UaGUgcHJhY3RpY2UgYmFzZWQgcmVzZWFyY2ggcHJvamVjdCBwcmVzZW50ZWQgaW4gdGhpcyB0aGVzaXMmIzEzOwpkcmF3cyB1cG9uIHRoZW9yZXRpY2FsIHJlc2VhcmNoIGluIGFmZmVjdCBzdHVkaWVzIGFuZCBmaWxtLcKtcGhpbG9zb3BoeS4mIzEzOwpUaGUgYWltIG9mIHRoZSB0aGVzaXMgaXMgdG8gcmVjb25zaWRlciB0aGUgcHJlLcKtcHJvZHVjdGlvbiBhbmQgcHJvZHVjdGlvbiYjMTM7CnByb2Nlc3Mgb2YgbmFycmF0aXZlIGNpbmVtYSBhbmQgaW52b2x2ZSB0aGUgcmljaCBhbmQgdmFyaWVkIHJlc2VhcmNoJiMxMzsKaW50byB0aGUgYXJlYSBvZiBhZmZlY3QgYW5kIHRoZSBib2R5IGluIHRoZSBmaWVsZCBvZiBmaWxtIHN0dWRpZXMgdGhhdCBpcyYjMTM7CmN1cnJlbnRseSBiZWluZyB1c2VkIHRvIGFuYWx5c2UgdGhlIHJlY2VwdGlvbiBhbmQgbWVhbmluZyBtYWtpbmcmIzEzOwpwcm9jZXNzIHVzZWQgYXMgdGhlIGZvdW5kYXRpb24gZm9yIHByb2R1Y2luZyBhIHNlcmllcyBvZiBuYXJyYXRpdmUgZmlsbXMmIzEzOwp0aGF0IHByaXZpbGVnZSBhZmZlY3Qgb3ZlciB0cmFkaXRpb25hbCBzdG9yeXRlbGxpbmcgc3RydWN0dXJlcy4mIzEzOwpGb3VyIGZpbG1zIHdlcmUgbWFkZSBhcyBwYXJ0IG9mIGFuIGludmVzdGlnYXRpb24gaW50byBhZmZlY3RpdmUmIzEzOwpmaWxtIHByYWN0aWNlLiBUaGVzZSBmaWxtcyBhY2NvbXBhbnkgdGhlIHdyaXR0ZW4gZXhlZ2VzaXMgYW5kIHNlcnZlIGFzJiMxMzsKYSB0ZXN0aW5nIGdyb3VuZCBmb3IgY29uY2VwdHMgZGV2ZWxvcGVkIGluIHRoZSB3cml0dGVuIGNvbXBvbmVudCBvZiB0aGUmIzEzOwp0aGVzaXMuIEVhY2ggcGllY2Ugb2YgcHJhY3RpY2UgaXMgZm9ybWFsbHkgYW5kIGNvbmNlcHR1YWxseSBtb3JlJiMxMzsKY29tcGxleCB0aGFuIHRoZSBsYXN0LiBUaGUgZm91cnRoIGFuZCBmaW5hbCBmaWxtIHNlcnZlcyBhcyBhbiBleGFtcGxlJiMxMzsKZm9yIHRoZSBjaW5lbWEgb2YgYWZmZWN0aXZlIHRvbmFsaXR5IGFuZCBhcyBzdWNoIGNvbnN0aXR1dGVzIHRoZSBjZW50cmFsLCYjMTM7CnZpc3VhbCBhcmd1bWVudC4mIzEzOwpUaGUgdGhlb3JldGljYWwgcmVzZWFyY2ggYW5kIGV4cGVyaW1lbnRhbCBtb3Zpbmctwq1pbWFnZSYjMTM7CnByYWN0aWNlIHJlc3VsdCBpbiB0aGUgb3V0bGluaW5nIG9mIGZpdmUgY29uZGl0aW9ucyBmb3IgdGhlIHByb2R1Y3Rpb24gb2YgYSYjMTM7CmNpbmVtYSBvZiBhZmZlY3RpdmUgdG9uYWxpdHksIHdoaWNoIGFyZSBjb21iaW5lZCB3aXRoIGEgdGF4b25vbXkgb2YmIzEzOwphZmZlY3QgZGV2ZWxvcGVkIGJ5IHRoZSBhdXRob3Igb2YgdGhlIHRoZXNpcy4gVGhlIHRheG9ub215IGFuZCYjMTM7Cmd1aWRlbGluZXMgb2ZmZXIgZmlsbW1ha2VycyBhbmQgcmVzZWFyY2hlcnMgLcKtIGVuZ2FnZWQgaW4gbW92aW5nLcKtaW1hZ2UmIzEzOwpwcmFjdGljZSBhbmQgdmlzdWFsIG1ldGhvZHMgLcKtIGEgcHJvcG9zaXRpb24gdG8gY29uc3RydWN0IGNpbmVtYSB0aHJvdWdoJiMxMzsKYWZmZWN0IHJhdGhlciB0aGFuIGxpbmd1aXN0aWNzIGFuZCBpZGVvbG9neSBvZiBmaWxtIGdyYW1tYXIuPC9kZXNjcmlwdGlvbj4KICA8L2Rlc2NyaXB0aW9ucz4KICA8cHVibGljYXRpb25ZZWFyPjIwMTY8L3B1YmxpY2F0aW9uWWVhcj4KICA8cHVibGlzaGVyPlRoZSBVbml2ZXJzaXR5IG9mIEVhc3QgTG9uZG9uPC9wdWJsaXNoZXI+CiAgPHJpZ2h0c0xpc3Q+CiAgICA8cmlnaHRzIHJpZ2h0c1VSST0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktbmMtbmQvMy4wLyI+Q3JlYXRpdmUgQ29tbW9uczogQXR0cmlidXRpb24tTm9uY29tbWVyY2lhbC1ObyBEZXJpdmF0aXZlIFdvcmtzIDMuMDwvcmlnaHRzPgogIDwvcmlnaHRzTGlzdD4KPC9yZXNvdXJjZT4="
},
"relationships": {
"data-center": {
"data": {
"id": "bl.uel",
"type": "data-centers"
}
},
"member": {
"data": {
"id": "bl",
"type": "members"
}
},
"resource-type": {
"data": {
"id": "text",
"type": "resource-types"
}
}
}
}
}
#/home/edward/dev-2/hyku/spec/services/datacite_client_spec.rb
RSpec.describe Ubiquity::DataciteClient do
let (:json_data) {File.read(Rails.root.join("spec/fixtures/json/datacite.json")) }
let (:decoded_url) {CGI.unescape('https://dx.doi.org/10.15123%2FPUB.7627') }
let (:client) {described_class.new(decoded_url)}
before(:each) do
stub_request(:get, "https://api.datacite.org/works/#{client.path}").
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: json_data, headers: {'Content-Type'=>'application/json; charset=utf-8'})
end
context 'initialize datacite client with an HTTP GET to /api.datacite.org' do
#fetch_record_from_datacite
it 'returns a path ' do
expect(client.path).to eq "/works/10.15123/PUB.7627"
end
end
context 'fetch_record_from_datacite' do
it 'returns a HTTParty::Response' do
response_object = client.fetch_record_from_datacite
expect(response_object.class).to eq HTTParty::Response
expect(response_object.success?).to eq true
expect(response_object.headers['content-type']).to eq "application/json; charset=utf-8"
expect(response_object.parsed_response).to eq JSON.parse(json_data)
end
end
end
namespace :api do
namespace :v1 do
resources :work_endpoints, defaults: {format: :json}
end
end
class API::V1::WorkEndpointsController < ApplicationController
protect_from_forgery with: :null_session, if: Proc.new {|c| c.request.format.json? }
before_action :find_work, only: [:show]
#api/v1/work_endpoints/index?work_name=article&tenant_name=library.localhost
def index
puts "mala #{params.inspect}"
work_name = params['work_name']
tenant_name = params['tenant_name']
puts "peter #{work_name}"
#AccountElevator.switch!(tenant_name)
switch_tenant
puts "lara #{tenant_name}"
puts "workio #{work_class}"
work_class = work_name.classify.constantize #work_class
puts "sasa #{work_class.inspect}"
# Article.order('id asc').offset(1).limit(1)
records = work_class.order('id desc') #.limit(1)
puts "lami #{records.inspect}"
render json: records #{a: 1}.to_json
end
def show
render json: @work
end
def create
work_name = params['work_name']
work_class = work_name.classify.constantize
switch_tenant
work = work_class.new(JSON.parse(params['work_data']) )
attributes = work.attributes
depositor_ability = User.find_by(email: '[email protected]')
ability = ::Ability.new(depositor_ability)
env = Hyrax::Actors::Environment.new(work, ability, attributes)
Hyrax::CurationConcern.actor.create(env)
render json: env.curation_concern
end
private
def find_work
switch_tenant
#@work = work_class.find(params[:id])
@work = ActiveFedora::Base.find(params[:id])
end
def work_class
work_name = params['work_name']
work_name.classify.constantize
end
def switch_tenant
tenant_name = params['tenant_name']
AccountElevator.switch!(tenant_name)
end
end
def self.handle_json_fields(record)
clean_submitted_data ||= remove_hash_keys_with_empty_and_nil_values(record)
new_record = compare_hash_keys?(clean_submitted_data)
if clean_submitted_data.present? & new_record == false
[clean_submitted_data.to_json]
end
end
#Check if the hash keys are only those used for default values like position
def self.compare_hash_keys?(record)
if record.present? && record.first.present?
my_default_keys = get_default_hash_keys(record)
keys_in_hash = record.map {|hash| hash.keys}.flatten.uniq
(keys_in_hash == my_default_keys)
else
nil
end
end
#remove hash keys with value of nil, "", and "NaN"
def self.remove_hash_keys_with_empty_and_nil_values(data)
if (data.present? && data.class == Array)
new_data = data.map do |hash|
['contributor_orcid', 'contributor_isni', 'creator_orcid', 'creator_isni', 'editor_isni', 'editor_orcid'].each do|ele|
hash[ele] = hash[ele].strip.chomp('/').split('/').last.gsub(/[^a-z0-9X-]/, '') if hash[ele].present?
end
hash.reject { |_k, v| v.nil? || v.to_s.empty? || v == "NaN" }
end
# remove hash that contains only default keys and values.
remove_hash_with_default_keys(new_data)
end
end
# remove any hash that contains only default keys and values.
def self.remove_hash_with_default_keys(data)
my_default_keys = get_default_hash_keys(data)
new_data = data.reject do |hash|
hash.keys.uniq == my_default_keys
end
end
#data is an array of hash eg [{"contributor_organization_name"=>""}},{"contributor_name_type"=>"Personal"}]
def self.get_default_hash_keys(data)
if data.present? && data.first.present?
#we get the first hash in the array and then get the first hash key
record = data.first.keys.first || data
splitted_record = record.split('_')
#the value of record will be "contributor_organization_name" when using array of hash from the above comments
#This means field name after the record.split will be 'contributor' and will change depending on the hash keys
get_field_name ||= splitted_record.first
return ["#{get_field_name}_position"] if (data.length == 1 && splitted_record.last == "position")
["#{get_field_name}_name_type", "#{get_field_name}_position"]
end
end
def apply_save_data_to_curation_concern(env)
new_attributes = clean_attributes(env.attributes)
env.curation_concern.attributes.each do |key, val|
if new_attributes[key].present? && new_attributes[key].is_a?(Array)
new_attributes[key] = new_attributes[key].first if val.nil? || val.is_a?(String)
process_json_value(key, new_attributes) if ['creator', 'editor', 'contributor', 'alternate_identifier', 'related_identifier'].include? key
end
end
puts "nela #{new_attributes.inspect}"
#env.curation_concern.attributes = new_attributes
env.curation_concern.date_modified = TimeService.time_in_utc
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment