diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c209ca6f7bfba28e0ba5703396f89d32bdd83ebd..1d8b132d1ec458207b1f6bdb62a4521081ee1762 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -32,7 +32,7 @@ test: stage: test script: - bundle exec rake db:migrate:reset RAILS_ENV=test - - rake spec:acceptance + - bundle exec rake spec:acceptance tags: - ruby - postgres diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..5bf56ef6371a7f8f856be574b69aed500f6aaefe --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,154 @@ +# v0.1.0 + +## Features + +* Activities + + * Show activities from a specific user + * Show all activities that logged user can see (feed) + * Show all users public activities + * Show logged user activities + +* Bookmarks + + * Create a bookmark + * Get a list of bookmarks + * Remove a bookmark + +* Collections + + * Add items to a collection + * Create a collection + * Destroy a collection + * Get a collection + * Get a list of collections + * Get all collection versions + * Like a collection + * Remove items from a collection + * Unlike a collection + * Update a collection + +* Complaints + + * Create a complaint + * Get a list of complaints + +* Contacts + + * Create contacts + * Destroy a contact + * Get a contact + * Get all contacts + * Update contacts + +* Downloads + + * Download the content (files) of a learning object or collection + +* Educational Stages + + * Create an educational stage + * Get a list of educational stages + * Remove an educational stage + +* Follows + + * Follow an user or collection + * Unfollow an user or collection + +* Institutions + + * Create an institution + * Destroy an institution + * Get a list of institutions + * Get an institution + * Update an institution + +* Languages + + * Create a language + * Destroy a language + * Get a language + * Get a list of languages + * Update languages + +* Learning Objects + + * Create a learning object draft + * Destroy an attachment (file) of a learning object + * Destroy a learning object + * Get a learning object + * Get a list of learning objects + * Get all learning object versions + * Like a learning object + * Publish a learning object + * Unlike a learning object + * Update a learning object + +* Mime Types + + * Create a mime type + * Destroy a mime type + * Get a mime type + * Get a list of mime types + * Update a mime type + +* Object Type + + * Create an object type + * Destroy an object type + * Get a list of object types + * Get an object type + * Update an object type + +* Reviews + + * Create a review + * Delete a review + * Get a list of reviews + * Rate a review + * Update a review + +* Statistics + + * Show statistics about the API usage + +* Subjects + + * Create a subject + * Get a list of subjects + * Remove a subject + +* Suggestions + + * Create suggestions + * Destroy suggestions + * Get a suggestion + * Get all suggestions + * Update suggestions + +* Tags + + * Create a tag + * Untag an object or collection + +* Users + + * Create an user + * Create an user by admin + * Login with an user account + * Logout of an user account + * Destroy an user + * Destroy an user by admin + * Get a list of users + * Get an user + * Get all user versions + * Show an user’s collections + * Show an user’s drafts + * Show an user’s learning objects + * Show an user’s liked collections + * Show an user’s liked learning objects + * Show an user’s own reviews + * Show an user’s received reviews + * Show what the user is following + * Update an user diff --git a/Gemfile b/Gemfile index cfcb968b1c9b7c34a1f224931644c280ebe7a814..e5e60aa5254284f3cf381721504cd78ab1e1d225 100644 --- a/Gemfile +++ b/Gemfile @@ -134,7 +134,7 @@ gem 'gitlab' gem 'pundit' # elasticsearch integration -gem 'searchkick', '~> 1.3.6' +gem 'searchkick' # enable/disable features by enviroments gem 'feature' diff --git a/Gemfile.lock b/Gemfile.lock index c88fdb0fac154c3c4c1c69f21ea0a0f8f55330a7..173c4cd951d54bccc257cfe0eb887dc348f045c8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,15 @@ +GIT + remote: git://github.com/mgiacomini/dspace-rest-client.git + revision: 7bc3a0a4fe8222663b9642d580de17acfdb76688 + branch: master + specs: + dspace_rest_client (2.2.8) + activesupport (>= 4.2.0) + faraday (~> 0.9.2) + json (~> 1.8, >= 1.8.3) + net-http-persistent (~> 2.9, >= 2.9.4) + resource_kit (>= 0.1.4) + GIT remote: git://github.com/rubysherpas/paranoia.git revision: bd3383729c790bf09e488f84221eaaea27c6597e @@ -32,11 +44,11 @@ GEM erubis (~> 2.7.0) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - active_model_serializers (0.10.2) + active_model_serializers (0.10.6) actionpack (>= 4.1, < 6) activemodel (>= 4.1, < 6) - jsonapi (~> 0.1.1.beta2) - railties (>= 4.1, < 6) + case_transform (>= 0.2) + jsonapi-renderer (>= 0.1.1.beta1, < 0.2) activejob (5.0.0.1) activesupport (= 5.0.0.1) globalid (>= 0.3.6) @@ -46,14 +58,17 @@ GEM activemodel (= 5.0.0.1) activesupport (= 5.0.0.1) arel (~> 7.0) - activerecord-import (0.16.1) + activerecord-import (0.18.2) activerecord (>= 3.2) activesupport (5.0.0.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.3.8) + acts_as_list (0.9.5) + activerecord (>= 3.0) + addressable (2.5.1) + public_suffix (~> 2.0, >= 2.0.2) annotate (2.7.1) activerecord (>= 3.2, < 6.0) rake (>= 10.4, < 12.0) @@ -74,16 +89,17 @@ GEM rack (>= 0.9.0) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) - brakeman (3.4.1) - builder (3.2.2) - bullet (5.4.2) + brakeman (3.6.1) + builder (3.2.3) + bullet (5.5.1) activesupport (>= 3.0.0) uniform_notifier (~> 1.10.0) byebug (9.0.6) + case_transform (0.2) + activesupport choice (0.2.0) chronic (0.10.2) - climate_control (0.0.3) - activesupport (>= 3.0) + climate_control (0.1.0) cocaine (0.5.8) climate_control (>= 0.0.3, < 1.0) codeclimate-engine-rb (0.4.0) @@ -91,8 +107,8 @@ GEM coderay (1.1.1) coercible (1.0.0) descendants_tracker (~> 0.0.1) - concurrent-ruby (1.0.2) - connection_pool (2.2.0) + concurrent-ruby (1.0.5) + connection_pool (2.2.1) curb (0.8.8) cvss (0.99.0) dalli (2.7.6) @@ -108,8 +124,8 @@ GEM dm-validations (~> 1.2.0) data_objects (0.10.17) addressable (~> 2.1) - database_cleaner (1.5.3) - dawnscanner (1.6.6) + database_cleaner (1.6.1) + dawnscanner (1.6.8) cvss data_mapper dm-sqlite-adapter @@ -121,14 +137,14 @@ GEM sqlite3 sys-uname terminal-table - debug_inspector (0.0.2) - derailed_benchmarks (1.3.1) + debug_inspector (0.0.3) + derailed_benchmarks (1.3.2) benchmark-ips (~> 2) get_process_mem (~> 0) heapy (~> 0) memory_profiler (~> 0) rack (>= 1) - rake (> 10, < 12) + rake (> 10, < 13) thor (~> 0.19) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) @@ -138,10 +154,10 @@ GEM railties (>= 4.1.0, < 5.1) responders warden (~> 1.2.3) - devise_token_auth (0.1.39) + devise_token_auth (0.1.40) devise (> 3.5.2, <= 4.2) rails (< 6) - diff-lcs (1.2.5) + diff-lcs (1.3) dm-aggregates (1.2.0) dm-core (~> 1.2.0) dm-constraints (1.2.0) @@ -178,69 +194,59 @@ GEM dm-core (~> 1.2.0) do_sqlite3 (0.10.17) data_objects (= 0.10.17) - dspace_rest_client (2.2.8) - activesupport (>= 4.2.0) - faraday (~> 0.9.2) - json (~> 1.8, >= 1.8.3) - net-http-persistent (~> 2.9, >= 2.9.4) - resource_kit (>= 0.1.4) - elasticsearch (2.0.0) - elasticsearch-api (= 2.0.0) - elasticsearch-transport (= 2.0.0) - elasticsearch-api (2.0.0) + elasticsearch (5.0.4) + elasticsearch-api (= 5.0.4) + elasticsearch-transport (= 5.0.4) + elasticsearch-api (5.0.4) multi_json - elasticsearch-transport (2.0.0) + elasticsearch-transport (5.0.4) faraday multi_json equalizer (0.0.11) erubis (2.7.0) execjs (2.7.0) - factory_girl (4.7.0) + factory_girl (4.8.0) activesupport (>= 3.0.0) - factory_girl_rails (4.7.0) - factory_girl (~> 4.7.0) + factory_girl_rails (4.8.0) + factory_girl (~> 4.8.0) railties (>= 3.0.0) - faker (1.6.6) + faker (1.7.3) i18n (~> 0.5) faraday (0.9.2) multipart-post (>= 1.2, < 3) fastercsv (1.5.5) feature (1.4.0) - ffi (1.9.14) + ffi (1.9.18) flamegraph (0.9.5) - flay (2.8.1) + flay (2.9.0) erubis (~> 2.7.0) path_expander (~> 1.0) ruby_parser (~> 3.0) sexp_processor (~> 4.0) - flog (4.4.0) + flog (4.6.1) path_expander (~> 1.0) ruby_parser (~> 3.1, > 3.1.0) - sexp_processor (~> 4.4) + sexp_processor (~> 4.8) get_process_mem (0.2.1) - gitlab (3.7.0) - httparty (~> 0.13.0) - terminal-table - globalid (0.3.7) - activesupport (>= 4.1.0) - haml (4.0.7) + gitlab (4.0.0) + httparty + terminal-table (= 1.7.1) + globalid (0.4.0) + activesupport (>= 4.2.0) + haml (5.0.1) + temple (>= 0.8.0) tilt - hashie (3.4.6) + hashie (3.5.5) heapy (0.1.2) - httparty (0.13.7) - json (~> 1.8) + httparty (0.14.0) multi_xml (>= 0.5.2) - i18n (0.7.0) + i18n (0.8.1) ice_nine (0.11.2) - immigrant (0.3.5) + immigrant (0.3.6) activerecord (>= 3.0) - json (1.8.3) - json_pure (1.8.3) - jsonapi (0.1.1.beta6) - jsonapi-parser (= 0.1.1.beta3) - jsonapi-renderer (= 0.1.1.beta1) - jsonapi-parser (0.1.1.beta3) - jsonapi-renderer (0.1.1.beta1) + json (1.8.6) + json_pure (1.8.6) + jsonapi-renderer (0.1.2) justify (1.0.2) jwt (1.5.6) launchy (2.4.3) @@ -249,42 +255,43 @@ GEM logger-colors (1.0.0) loofah (2.0.3) nokogiri (>= 1.5.9) - mail (2.6.4) + mail (2.6.5) mime-types (>= 1.16, < 4) - memory_profiler (0.9.6) + memory_profiler (0.9.8) method_source (0.8.2) mime-types (3.1) mime-types-data (~> 3.2015) mime-types-data (3.2016.0521) mimemagic (0.3.2) - mina (1.0.2) + mina (1.0.6) open4 (~> 1.3.4) rake mini_portile2 (2.1.0) - minitest (5.9.1) - minitest-reporters (1.1.12) + minitest (5.10.2) + minitest-reporters (1.1.14) ansi builder minitest (>= 5.0) ruby-progressbar multi_json (1.12.1) - multi_xml (0.5.5) + multi_xml (0.6.0) multipart-post (2.0.0) - mustache (1.0.3) + mustache (1.0.5) + mustermann (1.0.0) net-http-persistent (2.9.4) nio4r (1.2.1) - nokogiri (1.6.8.1) + nokogiri (1.7.2) mini_portile2 (~> 2.1.0) oauth (0.5.1) - oauth2 (1.2.0) - faraday (>= 0.8, < 0.10) + oauth2 (1.3.1) + faraday (>= 0.8, < 0.12) jwt (~> 1.0) multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - omniauth (1.3.1) - hashie (>= 1.2, < 4) - rack (>= 1.0, < 3) + omniauth (1.6.1) + hashie (>= 3.4.6, < 3.6.0) + rack (>= 1.6.2, < 3) omniauth-facebook (4.0.0) omniauth-oauth2 (~> 1.2) omniauth-google-oauth2 (0.4.1) @@ -298,13 +305,13 @@ GEM omniauth-oauth2 (1.4.0) oauth2 (~> 1.0) omniauth (~> 1.2) - omniauth-twitter (1.2.1) - json (~> 1.3) + omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) + rack open4 (1.3.4) orm_adapter (0.5.0) - paper_trail (5.2.2) - activerecord (>= 3.0, < 6.0) + paper_trail (7.0.2) + activerecord (>= 4.0, < 5.2) request_store (~> 1.1) paperclip (5.1.0) activemodel (>= 4.2.0) @@ -312,10 +319,10 @@ GEM cocaine (~> 0.5.5) mime-types mimemagic (~> 0.3.0) - parser (2.3.1.2) + parser (2.4.0.0) ast (~> 2.2) - path_expander (1.0.0) - pg (0.19.0) + path_expander (1.0.2) + pg (0.20.0) phantomjs (2.1.1.0) powerpack (0.1.1) ptools (1.3.3) @@ -324,16 +331,17 @@ GEM activerecord (>= 3.0) i18n (>= 0.5.0) railties (>= 3.0.0) - puma (3.6.0) + public_suffix (2.0.5) + puma (3.8.2) pundit (1.1.0) activesupport (>= 3.0.0) - rack (2.0.1) + rack (2.0.2) rack-attack (5.0.1) rack - rack-cors (0.4.0) - rack-mini-profiler (0.10.1) + rack-cors (0.4.1) + rack-mini-profiler (0.10.2) rack (>= 1.2.0) - rack-protection (1.5.3) + rack-protection (2.0.0) rack rack-test (0.6.3) rack (>= 1.0) @@ -349,9 +357,9 @@ GEM bundler (>= 1.3.0, < 2.0) railties (= 5.0.0.1) sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.1) + rails-dom-testing (2.0.2) activesupport (>= 4.2.0, < 6.0) - nokogiri (~> 1.6.0) + nokogiri (~> 1.6) rails-erd (1.5.0) activerecord (>= 3.2) activesupport (>= 3.2) @@ -365,116 +373,120 @@ GEM method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rainbow (2.1.0) + rainbow (2.2.2) + rake rake (11.3.0) - rdoc (4.2.2) - json (~> 1.4) - redis (3.3.1) - reek (4.5.1) + rdoc (4.3.0) + redis (3.3.3) + reek (4.6.2) codeclimate-engine-rb (~> 0.4.0) - parser (~> 2.3.1, >= 2.3.1.2) + parser (>= 2.4.0.0, < 2.5) rainbow (~> 2.0) - request_store (1.3.1) - resource_kit (0.1.5) - addressable (~> 2.3.6) - responders (2.3.0) - railties (>= 4.2.0, < 5.1) + request_store (1.3.2) + resource_kit (0.1.6) + addressable (>= 2.3.6, < 3.0.0) + responders (2.4.0) + actionpack (>= 4.2.0, < 5.3) + railties (>= 4.2.0, < 5.3) rmagick (2.16.0) - rspec (3.5.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-core (3.5.4) - rspec-support (~> 3.5.0) - rspec-expectations (3.5.0) + rspec (3.6.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-core (3.6.0) + rspec-support (~> 3.6.0) + rspec-expectations (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-mocks (3.5.0) + rspec-support (~> 3.6.0) + rspec-mocks (3.6.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.5.0) - rspec-rails (3.5.2) + rspec-support (~> 3.6.0) + rspec-rails (3.6.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.5.0) - rspec-expectations (~> 3.5.0) - rspec-mocks (~> 3.5.0) - rspec-support (~> 3.5.0) - rspec-support (3.5.0) - rspec_api_documentation (4.8.0) + rspec-core (~> 3.6.0) + rspec-expectations (~> 3.6.0) + rspec-mocks (~> 3.6.0) + rspec-support (~> 3.6.0) + rspec-support (3.6.0) + rspec_api_documentation (4.9.0) activesupport (>= 3.0.0) mustache (~> 1.0, >= 0.99.4) - rspec (~> 3.0, >= 3.0.0) - rubocop (0.45.0) - parser (>= 2.3.1.1, < 3.0) + rspec (~> 3.0) + rubocop (0.48.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - ruby-graphviz (1.2.2) + ruby-graphviz (1.2.3) ruby-progressbar (1.8.1) - ruby_parser (3.8.3) + ruby_parser (3.9.0) sexp_processor (~> 4.1) - rubycritic (3.0.0) + rubycritic (3.2.0) flay (~> 2.8) flog (~> 4.4) launchy (= 2.4.3) - parser (= 2.3.1.2) - rainbow + parser (= 2.4.0) + rainbow (~> 2.1) reek (~> 4.4) ruby_parser (~> 3.8) virtus (~> 1.0) - rubyzip (1.2.0) + rubyzip (1.2.1) screencap (0.1.4) phantomjs sdoc (0.4.2) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) - searchkick (1.3.6) - activemodel + searchkick (2.3.0) + activemodel (>= 4.1) elasticsearch (>= 1) hashie - sexp_processor (4.7.0) + sexp_processor (4.9.0) shoulda (3.5.0) shoulda-context (~> 1.0, >= 1.0.1) shoulda-matchers (>= 1.4.1, < 3.0) - shoulda-context (1.2.1) + shoulda-context (1.2.2) shoulda-matchers (2.8.0) activesupport (>= 3.0.0) - sidekiq (4.2.4) + sidekiq (5.0.0) concurrent-ruby (~> 1.0) connection_pool (~> 2.2, >= 2.2.0) rack-protection (>= 1.5.0) - redis (~> 3.2, >= 3.2.1) - sinatra (1.0) - rack (>= 1.0) - slim (3.0.7) - temple (~> 0.7.6) + redis (~> 3.3, >= 3.3.3) + sinatra (2.0.0) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.0) + tilt (~> 2.0) + slim (3.0.8) + temple (>= 0.7.6, < 0.9) tilt (>= 1.3.3, < 2.1) - spring (2.0.0) + spring (2.0.1) activesupport (>= 4.2) - sprockets (3.7.0) + sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.2.0) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sqlite3 (1.3.12) + sqlite3 (1.3.13) stackprof (0.2.10) streamio-ffmpeg (1.0.0) stringex (1.5.1) sys-uname (1.0.3) ffi (>= 1.0.0) - temple (0.7.7) - terminal-table (1.7.3) + temple (0.8.0) + terminal-table (1.7.1) unicode-display_width (~> 1.1.1) - thor (0.19.1) - thread_safe (0.3.5) - tilt (2.0.5) - tzinfo (1.2.2) + thor (0.19.4) + thread_safe (0.3.6) + tilt (2.0.7) + tzinfo (1.2.3) thread_safe (~> 0.1) - unicode-display_width (1.1.1) + unicode-display_width (1.1.3) uniform_notifier (1.10.0) uuidtools (2.1.5) virtus (1.0.5) @@ -482,14 +494,14 @@ GEM coercible (~> 1.0) descendants_tracker (~> 0.0, >= 0.0.3) equalizer (~> 0.0, >= 0.0.9) - warden (1.2.6) + warden (1.2.7) rack (>= 1.0) web-console (2.3.0) activemodel (>= 4.0) binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) - websocket-driver (0.6.4) + websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.2) whenever (0.9.7) @@ -501,12 +513,14 @@ PLATFORMS DEPENDENCIES active_model_serializers activerecord-import + acts_as_list annotate bcrypt (~> 3.1.7) better_errors brakeman bullet byebug + connection_pool curb (~> 0.8.8) dalli database_cleaner @@ -514,7 +528,7 @@ DEPENDENCIES derailed_benchmarks devise devise_token_auth - dspace_rest_client (= 2.2.8) + dspace_rest_client! execjs factory_girl_rails faker @@ -551,7 +565,7 @@ DEPENDENCIES rubyzip screencap sdoc (~> 0.4.0) - searchkick (~> 1.3.6) + searchkick shoulda sidekiq sinatra diff --git a/app/builders/learning_object_builder.rb b/app/builders/learning_object_builder.rb index 7f407e86f9eaee3d0e123786c00f192471442ca2..c986f3c70c1685e470c08ae7103c34870aa12634 100644 --- a/app/builders/learning_object_builder.rb +++ b/app/builders/learning_object_builder.rb @@ -7,6 +7,7 @@ class LearningObjectBuilder metadata: dspace_metadata_to_hash(item.metadata) ) + lo.curator = lo.get_metadata_value_of('dc.curator') institution = lo.get_metadata_value_of('dc.creator') institution = 'Desconhecido' if institution.blank? lo.publisher = Institution.where(name: institution).first_or_create diff --git a/app/controllers/concerns/followable_controller.rb b/app/controllers/concerns/followable_controller.rb index d703c163162c3a8bca651319c9d23ace9ac06303..d4d1cf569c518cd6fa3caf4e6aaf47478e6e12e9 100644 --- a/app/controllers/concerns/followable_controller.rb +++ b/app/controllers/concerns/followable_controller.rb @@ -28,4 +28,18 @@ module FollowableController render status: :forbidden end end + + # PUT /v1/users/1/follow + # PUT /v1/users/1/follow.json + def follow_toggle + if !current_user.following?(followable) + current_user.follow(followable) + render status: :created + elsif current_user.following?(followable) + current_user.unfollow(followable) + render status: :ok + else + render status: :forbidden + end + end end diff --git a/app/controllers/concerns/taggable_controller.rb b/app/controllers/concerns/taggable_controller.rb index 198ed5464ea428a5fc4308ce9c92a530967d4b1d..b451e2aa783d27ef0fd49d615f8f5c0ed4d29397 100644 --- a/app/controllers/concerns/taggable_controller.rb +++ b/app/controllers/concerns/taggable_controller.rb @@ -16,7 +16,7 @@ module TaggableController # DELETE /v1/learning_objects/1/untagging # DELETE /v1/learning_objects/1/untagging.json def untagging - @owner.untag(taggable, tag_params[:name]) + @owner.untag(taggable, with: [tag_params[:name]]) render json: taggable.tags, status: :ok end diff --git a/app/controllers/v1/collections_controller.rb b/app/controllers/v1/collections_controller.rb index 8faf84a832935c573de501cd7c2f964d33ec4276..f98194f415a493d02a97252fbfae90702ca218c2 100644 --- a/app/controllers/v1/collections_controller.rb +++ b/app/controllers/v1/collections_controller.rb @@ -9,7 +9,7 @@ class V1::CollectionsController < ApplicationController include ::SubjectableController include ::StageableController - before_action :authenticate_user!, only: [:create, :update, :destroy] + before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging] before_action :set_collection, only: [:show, :update, :destroy, :add_object, :delete_object, :subjecting, :unsubjecting, :add_stages, :remove_stages] before_action :set_new_collection, only: :index before_action :authorize!, except: [:create, :tagging, :untagging, :follow, :unfollow, :download] @@ -56,6 +56,10 @@ class V1::CollectionsController < ApplicationController # DELETE /v1/collections/1 # DELETE /v1/collections/1.json def destroy + items = @collection.collection_items.select(:id) + if !items.blank? + @collection.delete_items(items) + end @collection.destroy render status: :ok end @@ -63,8 +67,9 @@ class V1::CollectionsController < ApplicationController # POST /v1/collections/1/items def add_object return render nothing: true, status: :unprocessable_entity if extra_params.blank? || extra_params[:items].blank? - @collection.add_items(extra_params[:items]) - render json: @collection, status: :ok + errors = @collection.add_items(extra_params[:items]) + + render json: {collection: CollectionSerializer.new(@collection, {scope: current_user, scope_name: :current_user}).serializable_hash, errors: errors}, status: :ok end # DELETE /v1/collections/1/items @@ -98,7 +103,7 @@ class V1::CollectionsController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def collection_params - params.require(:collection).permit(:name, :description, :owner_id, :owner_type, :privacy, tags: []) + params.require(:collection).permit(:name, :curator, :description, :owner_id, :owner_type, :privacy, tags: []) end def extra_params @@ -107,7 +112,11 @@ class V1::CollectionsController < ApplicationController end def collection_associations(collection) - current_user.tag(collection, with: extra_params[:tags].map { |t| t['name'] }) unless extra_params[:tags].nil? + if extra_params[:tags] == [] + current_user.untag(collection, with: @collection.tags.map { |t| t['name'] }) + elsif !extra_params[:tags].nil? + current_user.tag(collection, with: extra_params[:tags].map { |t| t['name'] }) + end collection.add_subjects(ids: extra_params[:subjects]) unless extra_params[:subjects].nil? collection.add_educational_stages(ids: extra_params[:educational_stages]) unless extra_params[:educational_stages].nil? collection.add_items(extra_params[:items]) unless extra_params[:items].nil? diff --git a/app/controllers/v1/contacts_controller.rb b/app/controllers/v1/contacts_controller.rb index d1e589b425c6a77f931d9036f71b966822524c5d..37246084fa5b94dafe8f919c3f31d3d9e47952d2 100644 --- a/app/controllers/v1/contacts_controller.rb +++ b/app/controllers/v1/contacts_controller.rb @@ -18,6 +18,7 @@ class V1::ContactsController < ApplicationController def create @contact = Contact.new(contact_params) if @contact.save + ContactsMailer.new_contact_received(@contact).deliver_now render json: @contact, status: :created else render json: @contact.errors, status: :unprocessable_entity @@ -27,6 +28,7 @@ class V1::ContactsController < ApplicationController # PATCH/PUT v1/contacts/1 def update if @contact.update(contact_params) + ContactsMailer.contact_updated(@contact).deliver_now render json: @contact else render json: @contact.errors, status: :unprocessable_entity diff --git a/app/controllers/v1/educational_stages_controller.rb b/app/controllers/v1/educational_stages_controller.rb index 3518fabd954327e2023efaaf64118559b3807255..48fe33458fa72de0c949f238505fd778d2d1a0bd 100644 --- a/app/controllers/v1/educational_stages_controller.rb +++ b/app/controllers/v1/educational_stages_controller.rb @@ -6,7 +6,7 @@ class V1::EducationalStagesController < ApplicationController # GET /educational_stages # GET /educational_stages.json def index - educational_stages = paginate EducationalStage.all + educational_stages = EducationalStage.all render json: educational_stages end diff --git a/app/controllers/v1/learning_objects/attachment_controller.rb b/app/controllers/v1/learning_objects/attachment_controller.rb index 7309fc82b2790c02651bccaf064ce5b465387ed8..cc71c6d0f1cd146913c9fc0488eb9a5b003875e9 100644 --- a/app/controllers/v1/learning_objects/attachment_controller.rb +++ b/app/controllers/v1/learning_objects/attachment_controller.rb @@ -6,7 +6,7 @@ class V1::LearningObjects::AttachmentController < ApplicationController def destroy return render status: :not_found if @learning_object.nil? || @attachment.nil? - destroy_attachment_in_dspace(@attachment.id_dspace) + DeleteBitstreamWorker.perform_async(@attachment.id) @attachment.destroy render status: :ok @@ -28,9 +28,4 @@ class V1::LearningObjects::AttachmentController < ApplicationController authorize(@learning_object, :destroy?) end - - def destroy_attachment_in_dspace(id) - client = DspaceService.create_client - client.bitstreams.delete(id: id) - end end diff --git a/app/controllers/v1/learning_objects/chunks_controller.rb b/app/controllers/v1/learning_objects/chunks_controller.rb index b82de243c5fe91ad65b9d32d283dfd37e671eca1..a65e77f3d613c51e00a26e535ec677e0f9e651ff 100644 --- a/app/controllers/v1/learning_objects/chunks_controller.rb +++ b/app/controllers/v1/learning_objects/chunks_controller.rb @@ -13,12 +13,13 @@ class V1::LearningObjects::ChunksController < ApplicationController if last_chunk? combine_file! - post_file! + attachment = post_file! + render json: attachment, status: :ok + else + render status: :ok end - - render status: 200 rescue - render status: 500 + render status: :internal_server_error end private @@ -30,7 +31,7 @@ class V1::LearningObjects::ChunksController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def chunks_params - params.permit(:id, :file, :flowChunkNumber, :flowTotalChunks, :flowFilename, :flowIdentifier) + params.permit(:id, :file, :_chunkNumber, :_totalChunks, :_chunkFilename, :_chunkIdentifier, :_chunkSize, :_currentChunkSize, :_totalSize) end def post_file! @@ -68,37 +69,37 @@ class V1::LearningObjects::ChunksController < ApplicationController def valid_mime_type? mime_types = @learning_object.object_type.mime_types.map(&:extension) return true if mime_types.empty? - mime_types.include? chunks_params[:flowFilename].split('.').last + mime_types.include? chunks_params[:_chunkFilename].split('.').last end ## # Determine if this is the last chunk based in parts count. def last_chunk? - Dir["#{chunk_file_directory}/#{chunks_params[:flowFilename]}.part*"].count == chunks_params[:flowTotalChunks].to_i + Dir["#{chunk_file_directory}/#{chunks_params[:_chunkFilename]}.part*"].count == chunks_params[:_totalChunks].to_i end ## - # ./tmp/flow/abc-123/upload.txt.part1 + # ./tmp/file-chunks/abc-123/upload.txt.part1 def chunk_file_path - File.join(chunk_file_directory, "#{chunks_params[:flowFilename]}.part#{chunks_params[:flowChunkNumber]}") + File.join(chunk_file_directory, "#{chunks_params[:_chunkFilename]}.part#{chunks_params[:_chunkNumber]}") end ## - # ./tmp/flow/abc-123 + # ./tmp/file-chunks/abc-123 def chunk_file_directory - File.join('tmp', 'flow', chunks_params[:flowIdentifier]) + File.join('tmp', 'file-chunks', chunks_params[:_chunkIdentifier]) end ## - # /tmp/flow/upload.txt + # /tmp/file-chunks/upload.txt def final_file_path - File.join(final_file_directory, chunks_params[:flowFilename]) + File.join(final_file_directory, chunks_params[:_chunkFilename]) end ## - # /tmp/flow + # /tmp/file-chunks def final_file_directory - File.join('tmp', 'flow') + File.join('tmp', 'files', chunks_params[:_chunkIdentifier]) end ## diff --git a/app/controllers/v1/learning_objects_controller.rb b/app/controllers/v1/learning_objects_controller.rb index 31fcba21dc35e7c653b058e5968b27686f280a96..47809f9a5a0563862feb38b197cd386aed59d2bf 100644 --- a/app/controllers/v1/learning_objects_controller.rb +++ b/app/controllers/v1/learning_objects_controller.rb @@ -10,11 +10,11 @@ class V1::LearningObjectsController < ApplicationController include ::SubjectableController include ::StageableController - before_action :authenticate_user!, only: [:create, :update, :destroy] + before_action :authenticate_user!, only: [:create, :update, :destroy, :tagging, :untagging] before_action :set_learning_object, only: [:show, :update, :destroy, :subjecting, :unsubjecting, :add_stages, :remove_stages] before_action :set_new_learning_object, only: :index - before_action :authorize!, except: [:create, :tagging, :untagging, :download] - before_action :set_paper_trail_whodunnit + before_action :authorize!, except: [:create, :tagging, :untagging, :download, :magnetlink] + before_action :set_paper_trail_whodunnit, except: [:index, :show] def index learning_objects = paginate LearningObject.includes(:tags, :publisher, :language, :license, :subjects, :educational_stages, :reviews) @@ -67,6 +67,12 @@ class V1::LearningObjectsController < ApplicationController render status: :ok end + # GET /v1/learning_objects/magnetlink/:magnetlink + def magnetlink + render json: LearningObject.where(magnetlink: params[:magnetlink]) + end + + private def deleted_resource; LearningObject; end @@ -94,7 +100,7 @@ class V1::LearningObjectsController < ApplicationController # Never trust parameters from the scary internet, only allow the white list through. def learning_object_params return nil if params[:learning_object].nil? - params[:learning_object].permit(:author, :name, :object_type_id, :description, :license_id, :thumbnail, :software, :language_id, :link) + params[:learning_object].permit(:author, :name, :curator, :object_type_id, :description, :license_id, :thumbnail, :software, :language_id, :link, :magnetlink) end def extra_params @@ -103,7 +109,11 @@ class V1::LearningObjectsController < ApplicationController end def learning_object_associations(learning_object) - current_user.tag(learning_object, with: extra_params[:tags].map { |t| t['name'] }) unless extra_params[:tags].nil? + if extra_params[:tags] == [] + current_user.untag(learning_object, with: @learning_object.tags.map { |t| t['name'] }) + elsif !extra_params[:tags].nil? + current_user.tag(learning_object, with: extra_params[:tags].map { |t| t['name'] }) + end learning_object.add_subjects(ids: extra_params[:subjects]) unless extra_params[:subjects].nil? learning_object.add_educational_stages(ids: extra_params[:educational_stages]) unless extra_params[:educational_stages].nil? end diff --git a/app/controllers/v1/object_types_controller.rb b/app/controllers/v1/object_types_controller.rb index 742ca6885c452481acec2818e233bf23580190f5..cec8dbc49fb8674d73afdd581875fbb674be0e0f 100644 --- a/app/controllers/v1/object_types_controller.rb +++ b/app/controllers/v1/object_types_controller.rb @@ -8,7 +8,7 @@ class V1::ObjectTypesController < ApplicationController # GET /object_types # GET /object_types.json def index - object_types = paginate ObjectType.includes(:mime_types) + object_types = ObjectType.includes(:mime_types) render json: object_types end diff --git a/app/controllers/v1/omniauth_callbacks_controller.rb b/app/controllers/v1/omniauth_callbacks_controller.rb index 54854b7cfb3ece484680ee764259ea0d5d7e13cd..0ba43f3f669844c1bde3682f4c409143d2b3d71d 100644 --- a/app/controllers/v1/omniauth_callbacks_controller.rb +++ b/app/controllers/v1/omniauth_callbacks_controller.rb @@ -77,7 +77,8 @@ require 'open-uri' # break out provider attribute assignment for easy method extension def assign_provider_attrs(user, auth_hash) - avatar = auth_hash['provider']=='google_oauth2' ? open(auth_hash['info']['image']) : auth_hash['info']['image'] + + avatar = auth_hash['provider']=='google_oauth2' ? open(auth_hash['info']['image']) : auth_hash['info']['image'] user.assign_attributes({ nickname: auth_hash['info']['nickname'], diff --git a/app/controllers/v1/subjects_controller.rb b/app/controllers/v1/subjects_controller.rb index 6b4ed162edf426978dfdec919e95cfcfee6f73bf..0908c10a045c9956a9b136b88bef33927ac6972a 100644 --- a/app/controllers/v1/subjects_controller.rb +++ b/app/controllers/v1/subjects_controller.rb @@ -6,7 +6,7 @@ class V1::SubjectsController < ApplicationController # GET /subjects # GET /subjects.json def index - subjects = paginate Subject.all + subjects = Subject.all render json: subjects end diff --git a/app/controllers/v1/suggestions_controller.rb b/app/controllers/v1/suggestions_controller.rb index b12c6d7078f53dfdf68a69ea4b47a5a0c150cee8..79dfacdbd296937fde2dc193358e1c7d5d1df857 100644 --- a/app/controllers/v1/suggestions_controller.rb +++ b/app/controllers/v1/suggestions_controller.rb @@ -19,6 +19,7 @@ class V1::SuggestionsController < ApplicationController @suggestion = Suggestion.new(suggestion_params) if @suggestion.save + SuggestionsMailer.new_suggestion_received(@suggestion).deliver_now render json: @suggestion, status: :created else render json: @suggestion.errors, status: :unprocessable_entity @@ -28,6 +29,7 @@ class V1::SuggestionsController < ApplicationController # PATCH/PUT v1/suggestions/1 def update if @suggestion.update(suggestion_params) + SuggestionsMailer.suggestion_updated(@suggestion).deliver_now render json: @suggestion else render json: @suggestion.errors, status: :unprocessable_entity diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 286b2239d139960190594225e0134fe1a5c05370..4ff71b5d33e509b5d1b306eb2b6dae019b0c95fa 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,5 @@ class ApplicationMailer < ActionMailer::Base - default from: 'from@example.com' - layout 'mailer' + default to: 'portalmec_tec@inf.ufpr.br' + default from: 'portalmec@inf.ufpr.br' + #layout 'mailer' end diff --git a/app/mailers/contacts_mailer.rb b/app/mailers/contacts_mailer.rb new file mode 100644 index 0000000000000000000000000000000000000000..e485608d246cbacab6e5967df0c5ad1988bf3aea --- /dev/null +++ b/app/mailers/contacts_mailer.rb @@ -0,0 +1,14 @@ +class ContactsMailer < ApplicationMailer + + def new_contact_received(contact) + @contact = contact + @subject = "Contato de " + @contact.name + mail(subject: @subject) + end + + def contact_updated(contact) + @contact = contact + @subject = "O contato de " + @contact.name + " foi atualizado" + mail(subject: @subject) + end +end diff --git a/app/mailers/suggestions_mailer.rb b/app/mailers/suggestions_mailer.rb new file mode 100644 index 0000000000000000000000000000000000000000..b6545b69cfc64d6e9002f65f435916219e5e766a --- /dev/null +++ b/app/mailers/suggestions_mailer.rb @@ -0,0 +1,14 @@ +class SuggestionsMailer < ApplicationMailer + + def new_suggestion_received(suggestion) + @suggestion = suggestion + @subject = "Sugestão de " + @suggestion.name + mail(subject: @subject) + end + + def suggestion_updated(suggestion) + @suggestion = suggestion + @subject = "A sugestão de " + @suggestion.name + " foi atualizada" + mail(subject: @subject) + end +end diff --git a/app/models/collection.rb b/app/models/collection.rb index 9f42147f89f82c1e02f0dad4ef9f56f38c7a59fa..cecb90f16d4d75fd3d81ab94a9ad6a647a919c06 100644 --- a/app/models/collection.rb +++ b/app/models/collection.rb @@ -36,6 +36,8 @@ class Collection < ApplicationRecord include Highlights include Complainable + acts_as_paranoid + has_many :collection_items, -> { order("position ASC") }, as: :collectionable, dependent: :destroy has_many :collections, through: :collection_items, source: :collectionable, source_type: 'Collection' has_many :learning_objects, through: :collection_items, source: :collectionable, source_type: 'LearningObject' @@ -50,7 +52,6 @@ class Collection < ApplicationRecord searchkick language: 'brazilian', match: :word_start, searchable: [:name, :description, :author], callbacks: :async - acts_as_paranoid has_paper_trail def search_data @@ -86,10 +87,23 @@ class Collection < ApplicationRecord end def add_items(items) + errors = [] items.each do |item| - col_item = CollectionItem.where(collection: self, collectionable_id: item[:id], collectionable_type: item[:type]).first_or_create - col_item.set_list_position(item[:position]) unless item[:position].nil? + col_item = CollectionItem.where(collection: self, collectionable_id: item[:id], collectionable_type: item[:type]) + if col_item.blank? + i = item[:type].constantize.where(id: item[:id]).first + unless i.blank? + col_item = CollectionItem.create(collection: self, collectionable: i) + col_item.set_list_position(item[:position]) unless item[:position].nil? + else + errors << {error_type:"inexistent", id: item[:id], type: item[:type]} + end + else + errors << {error_type:"repeated", id: item[:id], type: item[:type]} + end end + + return errors end def delete_items(items) @@ -106,4 +120,8 @@ class Collection < ApplicationRecord def download_link '/'+PackageService.link(self) end + + def ignore_changes + super + %w(score views_count downloads_count likes_count shares_count follows_count) + end end diff --git a/app/models/collection_item.rb b/app/models/collection_item.rb index 4fc48636bdb07fefc3468a79dc6dce01bafcb704..101e61d5b41f8ed4479647b771bfeccd66ac31aa 100644 --- a/app/models/collection_item.rb +++ b/app/models/collection_item.rb @@ -21,10 +21,20 @@ class CollectionItem < ApplicationRecord validates :collection, :collectionable, presence: true acts_as_list scope: :collection + acts_as_paranoid + def recipient collection end + def public? + collectionable.privacy == 'public' + end + + def owner?(candidate) + collectionable.owner == candidate + end + def thumbnail collectionable_type == 'LearningObject' ? LearningObject.find(collectionable_id).default_thumbnail : Collection.find(collectionable_id).thumbnail end diff --git a/app/models/concerns/tagger.rb b/app/models/concerns/tagger.rb index f1815b29bcdc09dcad4d1d2dd2cff9419547a4f2..06798e532f2431e5c277f91ec54b2e6bd31bc235 100644 --- a/app/models/concerns/tagger.rb +++ b/app/models/concerns/tagger.rb @@ -20,8 +20,10 @@ module Tagger # Examples: # tagger.untag(LearningObject.find(1), "Tag") # tagger.untag(Collection.find(1), "Tag") - def untag(taggable, tag_name) - tag = Tag.find_by(name: tag_name) - Tagging.where(tagger: self, tag: tag, taggable: taggable).destroy_all + def untag(taggable, with: []) + with.each do |tag_name| + tag = Tag.find_by(name: tag_name) + Tagging.where(tagger: self, tag: tag, taggable: taggable).destroy_all + end end end diff --git a/app/models/concerns/trackable.rb b/app/models/concerns/trackable.rb index a8da93f4f48c87701517dfcfef7be35c2164abd5..f51750fa4569e81a7c66864dcc6c5c8a112aafce 100644 --- a/app/models/concerns/trackable.rb +++ b/app/models/concerns/trackable.rb @@ -1,12 +1,53 @@ module Trackable extend ActiveSupport::Concern - include PublicActivity::Model + include PublicActivity::Common include ActivitiesFilterService included do - tracked owner: proc { |controller, model| model.try(:user) || model.try(:owner) || controller.try(:current_user) } - tracked recipient: proc { |_controller, model| model.try(:recipient) || model } - tracked privacy: proc { |_controller, model| model.try(:privacy) || "public" } + after_create :new_create_activity + before_destroy :new_destroy_activity + after_update :new_update_activity + end + + private + + def new_update_activity + return nil if changed.blank? + return new_activity(:update) if ignore_changes == %w(updated_at) + filtered = changed.reject { |x| ignore_changes.include?(x) } + new_activity(:update) unless filtered.empty? + end + + def new_create_activity + new_activity(:create) + end + + def new_destroy_activity + new_activity(:destroy) + end + + def new_activity(action) + create_activity( + action, + owner: activity_owner, + recipient: activity_recipient, + privacy: activity_privacy + ) + end + + def ignore_changes + %w(updated_at) + end + + def activity_owner + proc { |controller, model| model.try(:user) || model.try(:owner) || controller.try(:current_user) } + end + + def activity_recipient + proc { |_controller, model| model.try(:recipient) || model } + end + def activity_privacy + proc { |_controller, model| model.try(:privacy) || 'public' } end end diff --git a/app/models/download.rb b/app/models/download.rb index 9812839a856ffcc25eebdacee249a507b5166125..8b5dae1ad57e293b98e225a5e74fb4168eb7934f 100644 --- a/app/models/download.rb +++ b/app/models/download.rb @@ -17,9 +17,15 @@ class Download < ApplicationRecord belongs_to :downloadable, polymorphic: true, counter_cache: true belongs_to :user, optional: true - validates_presence_of :ip, :downloadable + validates :ip, :downloadable, presence: true def recipient downloadable end + + private + + def new_create_activity + new_activity(:create) unless user.nil? + end end diff --git a/app/models/institution.rb b/app/models/institution.rb index 45a283350e02c5ba95fc64a7719a99d999954026..cd6d6909f302ebe89246ded0b07ee93e04c7922b 100644 --- a/app/models/institution.rb +++ b/app/models/institution.rb @@ -21,6 +21,9 @@ class Institution < ApplicationRecord #has_many :learning_objects, as: :publisher #has_many :collections, as: :owner + has_attached_file :avatar, styles: { medium: '300x300>', thumb: '60x60>' }, default_url: '' + validates_attachment_content_type :avatar, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'] + validates_presence_of :name acts_as_paranoid diff --git a/app/models/learning_object.rb b/app/models/learning_object.rb index fca93372bb6018ca9f4f50cae448bec9bd0dfc5d..dee6c17462c6d9b7a1ff8bfbe3529ccf0b69ac49 100644 --- a/app/models/learning_object.rb +++ b/app/models/learning_object.rb @@ -61,7 +61,7 @@ class LearningObject < ApplicationRecord belongs_to :object_type belongs_to :attachment, class_name: 'LearningObject::Attachment' - validates_presence_of :name, :publisher, :object_type, :language, :author, unless: :draft? + validates :name, :publisher, :object_type, :language, :author, unless: :draft?, presence: true validates :id_dspace, presence: true, uniqueness: true, unless: :published? default_scope { includes(:object_type, :attachment, :attachments) } @@ -109,6 +109,11 @@ class LearningObject < ApplicationRecord nil end + # If a LO has more than one object, this gives the location of the main one + def default_attachment_location + object_type.try(:name) == ('VÃdeo' || 'Ãudio') ? default_attachment.try(:retrieve_cache_link) : default_attachment.try(:retrieve_url) + end + def default_thumbnail return thumbnail unless thumbnail.blank? return nil if attachments.blank? @@ -125,8 +130,13 @@ class LearningObject < ApplicationRecord default_attachment.retrieve_cache_link end + # Download link with all relevant objects (currently only one) def download_link - object_type.try(:name) == ("VÃdeo" || "Ãudio") ? default_attachment.try(:retrieve_cache_link) : default_attachment.try(:retrieve_url) + default_attachment_location + end + + def ignore_changes + super + %w(score views_count downloads_count likes_count shares_count) end ## score methods diff --git a/app/models/search.rb b/app/models/search.rb index b74f038095c60c29b08fdcf1fa3dc36107ee4675..cb88cb4b1aa8a59bb0c8c7e3a680c3cfb2eeadaf 100644 --- a/app/models/search.rb +++ b/app/models/search.rb @@ -28,7 +28,7 @@ class Search { query: '*', order: 'score', - page: 1, + page: 0, results_per_page: 10 }.select { |key, _value| !params.key?(key) } end diff --git a/app/models/user.rb b/app/models/user.rb index 41cf256fb701fd2f6ff2b7c15b362e1399e3b484..a68598c89afae37d02363749e9d3cf099514464c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -41,12 +41,9 @@ class User < ApplicationRecord include Tagger include Complainable include Publisher - include PublicActivity::Common + include Trackable include ActivitiesFilterService - after_create -> { new_activity("create") } - after_update -> { new_activity("update") } - # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, @@ -79,7 +76,7 @@ class User < ApplicationRecord has_attached_file :cover, styles: { medium: '800x300>', thumb: '160x60>' }, default_url: '' validates_attachment_content_type :cover, content_type: ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'] - + validates :terms_of_service, acceptance: true searchkick language: 'brazilian', match: :word_start, searchable: [:name], callbacks: :async @@ -207,13 +204,11 @@ class User < ApplicationRecord ) end - def new_activity(type) - should_create = true - if type == "update" - ignore = ["tokens", "sign_in_count", "current_sign_in_at", "last_sign_in_at", "updated_at"] - filtered = changed.reject { |x| ignore.include?(x) } - should_create = !filtered.empty? - end - self.create_activity key: 'user.'+type, trackable: self, owner: self, recipient: self, privacy: "public" if should_create + def activity_owner + self + end + + def ignore_changes + super + %w(tokens sign_in_count current_sign_in_at last_sign_in_at current_sign_in_ip last_sign_in_ip score follows_count confirmation_token confirmed_at confirmation_sent_at) end end diff --git a/app/policies/collection_policy.rb b/app/policies/collection_policy.rb index 7ca595c7cd867bdbaf48d7f9c858c140a0fe1a21..b39a280f49d2ced6d8ecca66b31597661d2c42d5 100644 --- a/app/policies/collection_policy.rb +++ b/app/policies/collection_policy.rb @@ -7,8 +7,12 @@ class CollectionPolicy < ApplicationPolicy class Scope < Scope def resolve - if !user.nil? && user.is_admin? - scope.all + if !user.nil? + if user.is_admin? + scope.all + else + scope.includes(:collection_items).where.not(:collection_items => {:collection_id => nil}).where("privacy = ? OR owner_id = ?", 'public', user.id) + end else scope.includes(:collection_items).where.not(:collection_items => {:collection_id => nil}).where(privacy: 'public') end diff --git a/app/serializers/collection_item_serializer.rb b/app/serializers/collection_item_serializer.rb index e085d36a8ac68a814ded456d5fa347827b08cabc..60c59d539e02a9b728b34dfea947c9e46a819aa8 100644 --- a/app/serializers/collection_item_serializer.rb +++ b/app/serializers/collection_item_serializer.rb @@ -1,9 +1,18 @@ class CollectionItemSerializer < ActiveModel::Serializer cache key: 'collection_item', expires_in: 24.hours + def collectionable - serializer = object.collectionable_type == "LearningObject" ? ::LearningObjectSerializer : ::CollectionMinSerializer - serializer.new(object.collectionable, {scope: current_user, scope_name: :current_user}).serializable_hash + if ( object.collectionable_type == "LearningObject" ) + serializer = ::LearningObjectSerializer + elsif ( object.public? || (current_user && ( object.owner?(current_user) || current_user.is_admin? )) ) + serializer = ::CollectionMinSerializer + end + + if ( !serializer.blank? ) + serializer.new(object.collectionable, {scope: current_user, scope_name: :current_user}).serializable_hash + end end + belongs_to :collectionable, polymorphic: true attributes :id, :position, :collectionable, :collectionable_type end diff --git a/app/serializers/collection_serializer.rb b/app/serializers/collection_serializer.rb index 94f6bf6ce48c750ca922f5861f90359671b4ff15..a5f39efb52ecc4dc451d293efb9e9a2f24edfac4 100644 --- a/app/serializers/collection_serializer.rb +++ b/app/serializers/collection_serializer.rb @@ -28,7 +28,7 @@ class CollectionSerializer < ActiveModel::Serializer thumbs end - attributes :id, :name, :created_at, :updated_at, :description, :privacy, :score, :likes_count, :liked, :followed, :reviewed, :complained, :review_average, :thumbnail, :items_thumbnails + attributes :id, :name, :curator, :created_at, :updated_at, :description, :privacy, :score, :likes_count, :liked, :followed, :reviewed, :complained, :review_average, :thumbnail, :items_thumbnails belongs_to :owner has_many :tags diff --git a/app/serializers/follow_serializer.rb b/app/serializers/follow_serializer.rb index 5cf3d5147a7441062d416159021903f862ff01f8..ba5ee0682b26cf970310a272a257b52a2298c444 100644 --- a/app/serializers/follow_serializer.rb +++ b/app/serializers/follow_serializer.rb @@ -1,9 +1,12 @@ class FollowSerializer < ActiveModel::Serializer cache key: 'follow', expires_in: 24.hours + attributes :id + def follower object.user end - attributes :id, :follower, :followable + belongs_to :followable + belongs_to :follower end diff --git a/app/serializers/institution_serializer.rb b/app/serializers/institution_serializer.rb index 5de724635d138036ba37c13f2768f38b30266734..8b7d169d6c25a531061e9531bd4461e3f0634097 100644 --- a/app/serializers/institution_serializer.rb +++ b/app/serializers/institution_serializer.rb @@ -1,4 +1,4 @@ class InstitutionSerializer < ActiveModel::Serializer cache key: 'institution', expires_in: 4.hours - attributes :id, :name, :description, :address, :city, :country, :created_at, :updated_at + attributes :id, :name, :description, :address, :city, :country, :avatar, :created_at, :updated_at end diff --git a/app/serializers/learning_object_serializer.rb b/app/serializers/learning_object_serializer.rb index b1cdec145a3a0d84a079128a47c852b616e526e3..dbf2316da5ffef31800398cd2389208f4475a2bb 100644 --- a/app/serializers/learning_object_serializer.rb +++ b/app/serializers/learning_object_serializer.rb @@ -29,30 +29,34 @@ class LearningObjectSerializer < ActiveModel::Serializer object.complained? current_user end - attributes :id, - :name, - :description, - :author, - :thumbnail, - :publisher, - :object_type, - :language, - :default_attachment_id, - :default_mime_type, - :score, - :state, - :review_average, - :link, - :software, - :license, - :liked, - :likes_count, - :reviewed, - :complained, - :shares_count, - :created_at, - :updated_at + attributes \ + :id, + :name, + :description, + :author, + :curator, + :thumbnail, + :object_type, + :language, + :default_attachment_location, + :default_attachment_id, + :default_mime_type, + :score, + :state, + :review_average, + :link, + :software, + :license, + :liked, + :likes_count, + :reviewed, + :complained, + :shares_count, + :created_at, + :updated_at, + :magnetlink + belongs_to :publisher has_many :tags has_many :subjects has_many :educational_stages diff --git a/app/serializers/user_devise_serializer.rb b/app/serializers/user_devise_serializer.rb index dd97f8f52d489dd5fb5564055541d6022db427d3..c2547fc4439fcb49e506e61132764de9fe30b905 100644 --- a/app/serializers/user_devise_serializer.rb +++ b/app/serializers/user_devise_serializer.rb @@ -4,8 +4,12 @@ class UserDeviseSerializer < ActiveModel::Serializer object.avatar.url end + def cover_file_name + object.cover.url + end + attributes :id, :email, :provider, :avatar_file_name, :avatar_content_type, :uid, :name, :avatar_file_size, :avatar_updated_at, :bookmarks_count, :user_category_id, :score, :follows_count, :deleted_at, :description, :likes_count, - :learning_objects_count, :collections_count + :learning_objects_count, :collections_count, :cover_file_name, :cover_content_type, :cover_file_size, :cover_updated_at end diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index ed7bdcef0ae376d602ac84e9abec95068dcb67c5..e8d1f3e82dff625186ab5e63fd3c95cfd39edcec 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -9,6 +9,10 @@ class UserSerializer < ActiveModel::Serializer object.followed? current_user end + def email + object.email if (current_user != nil)&&(object.id == current_user.id || current_user.is_admin?) + end + attributes :id, :email, :provider, :name, :description, :education, :score, :cover, :role_ids, :institution_ids, :avatar, :likes_count, :followed, :complained, :follows_count, :learning_objects_count, :collections_count, :created_at, :updated_at has_many :subjects end diff --git a/app/services/dspace_service.rb b/app/services/dspace_service.rb index 207de2eeb2affb68115e70907bbeebd52428be8e..9943e36a1ecf29cc6da48e761043e9a75bc61ea2 100644 --- a/app/services/dspace_service.rb +++ b/app/services/dspace_service.rb @@ -5,6 +5,7 @@ class DspaceService # ID's of collections TEST_COLLECTION = 4 PORTALMEC_COLLECTION = 3 + PORTALMEC_BETA_COLLECTION = 6 BD_INT_OBJETOS_COLLECTION = 2 def self.create_client diff --git a/app/services/learning_object_publisher.rb b/app/services/learning_object_publisher.rb index a2ba1089ea51d7e405dafa32e0330e21e0727aa9..c646d533d02bff320b1eafd62ef93c0be62a960f 100644 --- a/app/services/learning_object_publisher.rb +++ b/app/services/learning_object_publisher.rb @@ -20,7 +20,9 @@ class LearningObjectPublisher # post *media_path* to *learning_object* on dspace def upload(learning_object, media_path) - DspaceUploadWorker.perform_async learning_object.id, media_path, learning_object.description + attachment = learning_object.attachments.create(name: File.basename(media_path)) + DspaceUploadWorker.perform_async(learning_object.id, media_path, attachment.id, learning_object.description) + attachment end ## publish *learning_object* @@ -29,7 +31,7 @@ class LearningObjectPublisher return true if learning_object.published? learning_object.state = LearningObject.states[:published] - learning_object.published_at = Time.now + learning_object.published_at = Time.current ThumbnailGenerateWorker.perform_async learning_object.id, learning_object.link if learning_object.link? learning_object.save end @@ -66,7 +68,8 @@ class LearningObjectPublisher 'dc.type' => object.object_type.try(:name), 'dc.rights.license' => object.license.try(:name), # 'dc.subject.category' => object.subjects, - 'dc.date.submitted' => object.created_at.to_s + 'dc.date.submitted' => object.created_at.to_s, + 'dc.curator' => object.curator } end end diff --git a/app/services/search_service/collection.rb b/app/services/search_service/collection.rb index 5bd29469709d51634c3d8489b27f653afed1edd1..a66407af69bdd841364fda3bacc41a781dce315b 100644 --- a/app/services/search_service/collection.rb +++ b/app/services/search_service/collection.rb @@ -1,7 +1,7 @@ module SearchService class Collection < Model def search - ::Collection.search(query: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) + ::Collection.search(body: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) end def autocomplete @@ -39,6 +39,7 @@ module SearchService when 'likes' then { likes: { order: :desc } } when 'downloads' then { downloads: { order: :desc } } when 'review_average' then { review_average: { order: :desc } } + else "_score" end end diff --git a/app/services/search_service/learning_object.rb b/app/services/search_service/learning_object.rb index bff63f89f5d272e4c242eab493cea34bac8e619f..6ae89d3edc218c5ca370797e83f8b418e93a1df7 100644 --- a/app/services/search_service/learning_object.rb +++ b/app/services/search_service/learning_object.rb @@ -2,7 +2,7 @@ module SearchService class LearningObject < Model def search fields = [:license, :tags, :subjects, :educational_stages, :taggings, :publisher, :language, :attachments, :reviews] - ::LearningObject.search(query: mount_query, includes: fields, order: order_hash, page: @search.page, per_page: @search.results_per_page) + ::LearningObject.search(body: mount_query, includes: fields, order: order_hash, page: @search.page, per_page: @search.results_per_page) end def autocomplete @@ -40,6 +40,7 @@ module SearchService when 'likes' then { likes: { order: :desc } } when 'downloads' then { downloads: { order: :desc } } when 'review_average' then { review_average: { order: :desc } } + else "_score" end end diff --git a/app/services/search_service/model.rb b/app/services/search_service/model.rb index eda8a5d6e734389b82930cd87790fab5ba1354f8..20ca0ad586e5db35ee5a5cd70104b7818403076c 100644 --- a/app/services/search_service/model.rb +++ b/app/services/search_service/model.rb @@ -38,22 +38,36 @@ module SearchService def mount_query match_all_query = { - filtered:{ - query: { match_all: {} }, - filter: mount_filter - } - } - return match_all_query if @search.query == "*" - - { - function_score: { - query: { bool: { - must: { dis_max: { queries: mount_queries } }, + query: { + bool: { + must: { + match_all: {} + }, filter: mount_filter - } }, - functions: [{ script_score: { script: { lang: 'groovy', file: 'calculate_score' } } }] - } + } + }, + size: @search.results_per_page, + from: ((@search.page.to_i) * (@search.results_per_page.to_i)).to_s, + sort: order_hash } + return match_all_query if @search.query == '*' + + { + query:{ + function_score: { + query: { bool: { + must: { dis_max: { queries: mount_queries } }, + filter: mount_filter + } }, + functions: [{ script_score: { script: { lang: 'groovy', file: 'calculate_score' } } }] + } + }, + # https://www.elastic.co/guide/en/elasticsearch/guide/current/pagination.html + # Comeca pagina 0 + size: @search.results_per_page, + from: ((@search.page.to_i) * (@search.results_per_page.to_i)).to_s, + sort: order_hash + } end def mount_queries diff --git a/app/services/search_service/user.rb b/app/services/search_service/user.rb index c9afd7790f52d404f93c74aa426155a4d24bcc0a..03898bdc3ac84c6c30bbc046843abb86b34deb45 100644 --- a/app/services/search_service/user.rb +++ b/app/services/search_service/user.rb @@ -1,7 +1,7 @@ module SearchService class User < Model def search - ::User.search(query: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) + ::User.search(body: mount_query, order: order_hash, page: @search.page, per_page: @search.results_per_page) end def autocomplete @@ -20,7 +20,7 @@ module SearchService def order_hash return { name: { order: :asc, unmapped_type: :string } } if @search.order == 'title' - nil + "_score" end end end diff --git a/app/views/contacts_mailer/contact_updated.html.erb b/app/views/contacts_mailer/contact_updated.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..fba5ea866e8990f0a1bf6b3a2f549cefef952986 --- /dev/null +++ b/app/views/contacts_mailer/contact_updated.html.erb @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <style>/* Email styles need to be inline */</style> + </head> + <body> + <h2>Nome do contato: <%= @contact.name %></h1> + <h2>Email do contato: <%= @contact.email %></h1> + <h2>Mensagem: <%= @contact.message %></h1> + </body> +</html> diff --git a/app/views/contacts_mailer/new_contact_received.html.erb b/app/views/contacts_mailer/new_contact_received.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..fba5ea866e8990f0a1bf6b3a2f549cefef952986 --- /dev/null +++ b/app/views/contacts_mailer/new_contact_received.html.erb @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <style>/* Email styles need to be inline */</style> + </head> + <body> + <h2>Nome do contato: <%= @contact.name %></h1> + <h2>Email do contato: <%= @contact.email %></h1> + <h2>Mensagem: <%= @contact.message %></h1> + </body> +</html> diff --git a/app/views/suggestions_mailer/new_suggestion_received.html.erb b/app/views/suggestions_mailer/new_suggestion_received.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..a0a08db307cc65caa4a8ddbabb192937113db04c --- /dev/null +++ b/app/views/suggestions_mailer/new_suggestion_received.html.erb @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <style>/* Email styles need to be inline */</style> + </head> + <body> + <h2>Nome: <%= @suggestion.name %></h1> + <h2>Link: <%= @suggestion.link %></h1> + <h2>Descrição: <%= @suggestion.description %></h1> + </body> +</html> diff --git a/app/views/suggestions_mailer/suggestion_updated.html.erb b/app/views/suggestions_mailer/suggestion_updated.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..a0a08db307cc65caa4a8ddbabb192937113db04c --- /dev/null +++ b/app/views/suggestions_mailer/suggestion_updated.html.erb @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <style>/* Email styles need to be inline */</style> + </head> + <body> + <h2>Nome: <%= @suggestion.name %></h1> + <h2>Link: <%= @suggestion.link %></h1> + <h2>Descrição: <%= @suggestion.description %></h1> + </body> +</html> diff --git a/app/workers/delete_bitstream_worker.rb b/app/workers/delete_bitstream_worker.rb new file mode 100644 index 0000000000000000000000000000000000000000..b19d59654894af46f56166bd95dfab936862808f --- /dev/null +++ b/app/workers/delete_bitstream_worker.rb @@ -0,0 +1,28 @@ +require_dependency 'dspace' + +class DeleteBitstreamWorker + include Sidekiq::Worker + + def perform(attachment_id = nil) + attachment = LearningObject::Attachment.find(attachment_id) + return false if attachment.blank? || !wait_bitstream(attachment) + + # Require dspace gem + Bundler.require(*Rails.groups) + + DspaceService.create_client.bitstreams.delete(id: attachment.id_dspace) + end + + private + + def wait_bitstream(attachment) + if attachment.id_dspace.blank? + Timeout.timeout(60) do + sleep(1.0) while attachment.id_dspace.blank? + end + end + true + rescue Timeout::Error + false + end +end diff --git a/app/workers/dspace_upload_worker.rb b/app/workers/dspace_upload_worker.rb index 5e27970055bfc9ff00e605bcc5b343ea5f47b53a..e7f64b155402897ef6ac04cdf5a293cbc03cefdf 100644 --- a/app/workers/dspace_upload_worker.rb +++ b/app/workers/dspace_upload_worker.rb @@ -1,24 +1,40 @@ +require_dependency 'dspace' + class DspaceUploadWorker include Sidekiq::Worker @@dspace = nil - def perform(learning_object_id, media_path, description = nil) + def perform(learning_object_id, media_path, attachment_id = nil, description = nil) # find learning object learning_object = LearningObject.find learning_object_id return false if learning_object.blank? + # Require dspace gem + Bundler.require(*Rails.groups) + # create attachment file = File.new(media_path, 'r') bitstream = dspace.items.add_bitstream(file, id: learning_object.id_dspace, name: File.basename(media_path), description: description) - attachment = learning_object.attachments.create map_bitstream2attachment(bitstream) + attachment = create_attachment(learning_object, bitstream, attachment_id) ThumbnailGenerateWorker.perform_async attachment.id, media_path end private + def create_attachment(learning_object, bitstream, attachment_id = nil) + unless attachment_id.nil? + attachment = learning_object.attachments.find(attachment_id) + unless attachment.nil? + attachment.update(map_bitstream2attachment(bitstream)) + return attachment + end + end + learning_object.attachments.create map_bitstream2attachment(bitstream) + end + def publisher @publisher ||= LearningObjectPublisher.new(dspace) end diff --git a/config/initializers/elasticsearch.rb b/config/initializers/elasticsearch.rb new file mode 100644 index 0000000000000000000000000000000000000000..e591a06b27196300668419e7f35019e6aef8f257 --- /dev/null +++ b/config/initializers/elasticsearch.rb @@ -0,0 +1,6 @@ +Searchkick.client = + Elasticsearch::Client.new( + url: 'localhost:9200', + transport_options: {request: {timeout: 550}} + ) + diff --git a/config/routes.rb b/config/routes.rb index c314a4533c81a8bfed191612d32c3f98c73169e8..2ef9a747bce42a72c79b623e5ba1d374077703ee 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,6 +13,7 @@ Rails.application.routes.draw do member do post 'follow', as: :follow, action: :follow delete 'follow', as: :unfollow, action: :unfollow + put 'follow', as: :follow_toggle, action: :follow_toggle end end @@ -154,5 +155,6 @@ Rails.application.routes.draw do get '/subjects', to: 'subjects#index' get '/educational_stages', to: 'educational_stages#index' get '/activities/me', to: 'activities#me' + get 'learning_objects/magnetlink/:magnetlink', to: 'learning_objects#magnetlink', as: 'magnetlink_learning_objects' end end diff --git a/db/migrate/20170503134230_add_attachment_avatar_to_institutions.rb b/db/migrate/20170503134230_add_attachment_avatar_to_institutions.rb new file mode 100644 index 0000000000000000000000000000000000000000..fee56386d833200d0c3faa7ff8a379d817bdbca7 --- /dev/null +++ b/db/migrate/20170503134230_add_attachment_avatar_to_institutions.rb @@ -0,0 +1,11 @@ +class AddAttachmentAvatarToInstitutions < ActiveRecord::Migration + def self.up + change_table :institutions do |t| + t.attachment :avatar + end + end + + def self.down + remove_attachment :institutions, :avatar + end +end diff --git a/db/migrate/20170511161146_add_curator_to_learning_object.rb b/db/migrate/20170511161146_add_curator_to_learning_object.rb new file mode 100644 index 0000000000000000000000000000000000000000..d722347d41c2a6de5bcc448e21740fe0e7d31b8e --- /dev/null +++ b/db/migrate/20170511161146_add_curator_to_learning_object.rb @@ -0,0 +1,5 @@ +class AddCuratorToLearningObject < ActiveRecord::Migration[5.0] + def change + add_column :learning_objects, :curator, :string + end +end diff --git a/db/migrate/20170512092359_add_magnetlink_to_learning_object.rb b/db/migrate/20170512092359_add_magnetlink_to_learning_object.rb new file mode 100644 index 0000000000000000000000000000000000000000..6ee102f5debee49368eaa5e8f2f9e0094393be85 --- /dev/null +++ b/db/migrate/20170512092359_add_magnetlink_to_learning_object.rb @@ -0,0 +1,5 @@ +class AddMagnetlinkToLearningObject < ActiveRecord::Migration[5.0] + def change + add_column :learning_objects, :magnetlink, :string + end +end \ No newline at end of file diff --git a/db/migrate/20170516111857_add_deleted_at_to_collection_items.rb b/db/migrate/20170516111857_add_deleted_at_to_collection_items.rb new file mode 100644 index 0000000000000000000000000000000000000000..abbe878fe27d87f74b19feeed88a854d25c1b020 --- /dev/null +++ b/db/migrate/20170516111857_add_deleted_at_to_collection_items.rb @@ -0,0 +1,6 @@ +class AddDeletedAtToCollectionItems < ActiveRecord::Migration[5.0] + def change + add_column :collection_items, :deleted_at, :datetime + add_index :collection_items, :deleted_at + end +end \ No newline at end of file diff --git a/db/migrate/20170518120936_add_curator_to_collection.rb b/db/migrate/20170518120936_add_curator_to_collection.rb new file mode 100644 index 0000000000000000000000000000000000000000..29f69c17c5c0c588d4eb3cf98152b367cb921a34 --- /dev/null +++ b/db/migrate/20170518120936_add_curator_to_collection.rb @@ -0,0 +1,5 @@ +class AddCuratorToCollection < ActiveRecord::Migration[5.0] + def change + add_column :collections, :curator, :string + end +end diff --git a/db/seeds/object_types.rb b/db/seeds/object_types.rb index ff52e24bf1d0c44b7e8073aea5fa4ab867211395..529b8a19ed0967b17b70eaa8c39bbca3742a8265 100644 --- a/db/seeds/object_types.rb +++ b/db/seeds/object_types.rb @@ -13,6 +13,7 @@ def types {name:'Jogo'}, {name:'Aplicativo móvel'}, {name:'Website externo'}, + {name:'Livro digital'}, {name:'Outros'} ] end diff --git a/db/seeds/subjects.rb b/db/seeds/subjects.rb index 447d277403e7051caba19784fcbe9341aef7a2de..53f8ea95dc8a6139577bc1c714a5661a37751354 100644 --- a/db/seeds/subjects.rb +++ b/db/seeds/subjects.rb @@ -13,7 +13,8 @@ def subjects {name:'QuÃmica'}, {name:'Sociologia'}, {name:'Outras LÃnguas'}, - {name:'Ensino Religioso'} + {name:'Ensino Religioso'}, + {name:'Outros'} ] end diff --git a/lib/tasks/import/learning_objects.rake b/lib/tasks/import/learning_objects.rake index 80da21d609fcbb6c058ae053827da66402dc5eff..1002ba94bc233722fc0b8f4b36445af7acc93025 100644 --- a/lib/tasks/import/learning_objects.rake +++ b/lib/tasks/import/learning_objects.rake @@ -1,12 +1,10 @@ -require 'rainbow' - namespace :import do - desc "import learning objects from dspace" + desc 'import learning objects from dspace' - task :learning_object, [:log] => [:environment] do |t, args| - desc "Importing Learning Objects from Dspace items" + task :learning_object, [:log] => [:environment] do |_t, args| + desc 'Importing Learning Objects from Dspace items' - args.with_defaults(:log => STDOUT) + args.with_defaults(log: STDOUT) logger = Log::DatabaseLogger.new(args.log) logger.level = Log::DatabaseLogger::CREATE @@ -17,14 +15,13 @@ namespace :import do offset = 0 loop do - - logger.info " --> importing items from #{offset} to #{offset+limit}" + logger.info " --> importing items from #{offset} to #{offset + limit}" begin # Get items from dspace (from offset to offset+limit) - dspace_items = get_items_from_dspace(limit, offset, ['metadata', 'bitstreams']) + dspace_items = get_col_items_from_dspace(limit, offset, ['metadata', 'bitstreams', 'parentCollection']) rescue => e - logger.warn "Database error, going to sleep" + logger.warn 'Database error, going to sleep' logger.error e # Sleeps for a while to wait database's recovery sleep(10.seconds) @@ -41,8 +38,12 @@ namespace :import do end # Increment offset, to get new items on next iteration - offset = offset + limit + offset += limit + dspace_items.select! do |i| + i.parent_collection.id == DspaceService::BD_INT_OBJETOS_COLLECTION + end + next if dspace_items.empty? # Iterates through items # Verifies if item is already on repository # Initializes new LearningObjects @@ -56,12 +57,15 @@ namespace :import do private - def get_items_from_dspace(limit, offset, expand=[]) - client = DspaceService.create_client - client.items.all( - expand: expand.join(','), - limit: limit, offset: offset - ) + def dspace_client + @client ||= DspaceService.create_client end + def get_col_items_from_dspace(limit, offset, expand = []) + dspace_client.items.all( + expand: expand.join(','), + limit: limit, + offset: offset + ) + end end diff --git a/lib/tasks/portalmec.rake b/lib/tasks/portalmec.rake index 0955340cdb6101f047cc6f651bd6aa4e7ac6ee0a..aa60378c635d288acda80e4005a00db13180e84b 100644 --- a/lib/tasks/portalmec.rake +++ b/lib/tasks/portalmec.rake @@ -7,8 +7,7 @@ namespace :portalmec do Rake::Task['import:learning_object'].invoke Rake::Task['import:tag'].invoke - # Rake::Task['tags:define_topics'].invoke - # Rake::Task['tags:define_school_levels'].invoke + Rake::Task['import:educational_stage'].invoke Rake::Task['object_type:restart'].invoke Rake::Task['language:restart'].invoke diff --git a/spec/acceptance/educational_stages_spec.rb b/spec/acceptance/educational_stages_spec.rb index 7c46f07ef19b1d73cc5c8b3d5898fa347a23493a..b7d7f85d952ffecc4cb5530d310fe1ea51483003 100644 --- a/spec/acceptance/educational_stages_spec.rb +++ b/spec/acceptance/educational_stages_spec.rb @@ -12,15 +12,9 @@ resource 'Educational Stages' do let(:learning_objects) { LearningObject.all } get '/v1/educational_stages' do - parameter :limit, 'Limit of educational stages' - parameter :offset, 'Offset of educational stages' - - let(:limit) { 12 } - let(:offset) { 0 } example_request 'Get a list of educational stages' do # active model serializer may render model associations in different order for collections (array of items), so we're verifing only returned ids - expect(JSON.parse(response_body).map { |o| o['id'] }.sort).to eq(EducationalStage.limit(limit).offset(offset).pluck(:id).sort) expect(status).to eq(200) end end diff --git a/spec/acceptance/object_types_spec.rb b/spec/acceptance/object_types_spec.rb index b6577ce9f4e6052a0ccd9e880b727d48f266a544..862bc56352f79998caf2e95e7ed53993ebdf2058 100644 --- a/spec/acceptance/object_types_spec.rb +++ b/spec/acceptance/object_types_spec.rb @@ -12,15 +12,9 @@ resource 'Object Type' do let(:mimetypes) { MimeType.all } get '/v1/object_types' do - parameter :limit, 'Limit of object types' - parameter :offset, 'Offset of object types' - - let(:limit) { 12 } - let(:offset) { 0 } example_request 'Get a list of object types' do # active model serializer may render model associations in different order for collections (array of items), so we're verifing only returned ids - expect(JSON.parse(response_body).map { |o| o['id'] }.sort).to eq(ObjectType.limit(limit).offset(offset).pluck(:id).sort) expect(status).to eq(200) end end diff --git a/spec/acceptance/subjects_spec.rb b/spec/acceptance/subjects_spec.rb index 40e257c01908bb4135b19611574e8375cf469135..4c118babd3f1496ebf408c65edabeb8d6cad7384 100644 --- a/spec/acceptance/subjects_spec.rb +++ b/spec/acceptance/subjects_spec.rb @@ -12,15 +12,9 @@ resource 'Subjects' do let(:learning_objects) { LearningObject.all } get '/v1/subjects' do - parameter :limit, 'Limit of subjects' - parameter :offset, 'Offset of subjects' - - let(:limit) { 12 } - let(:offset) { 0 } example_request 'Get a list of subjects' do # active model serializer may render model associations in different order for collections (array of items), so we're verifing only returned ids - expect(JSON.parse(response_body).map { |o| o['id'] }.sort).to eq(Subject.limit(limit).offset(offset).pluck(:id).sort) expect(status).to eq(200) end end