diff --git a/Gemfile b/Gemfile index 211a4a7..93e3b88 100644 --- a/Gemfile +++ b/Gemfile @@ -3,8 +3,6 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.7.0' -# gem 'nokogiri', require: false - # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '6.0.2.1' # Use sqlite3 as the database for Active Record @@ -39,6 +37,9 @@ gem 'devise-encryptable', '0.2.0' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.4.2', require: false +# for composite primary keys +gem 'composite_primary_keys' + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] diff --git a/Gemfile.lock b/Gemfile.lock index 17ac9f4..3f376de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -73,6 +73,8 @@ GEM regexp_parser (~> 1.5) xpath (~> 3.2) childprocess (3.0.0) + composite_primary_keys (12.0.2) + activerecord (~> 6.0.0) concurrent-ruby (1.1.6) crass (1.0.6) devise (4.7.1) @@ -84,7 +86,7 @@ GEM devise-encryptable (0.2.0) devise (>= 2.1.0) erubi (1.9.0) - ffi (1.12.2) + ffi (1.12.2-x64-mingw32) globalid (0.4.2) activesupport (>= 4.2.0) httparty (0.18.0) @@ -105,11 +107,11 @@ GEM mime-types (3.3.1) mime-types-data (~> 3.2015) mime-types-data (3.2019.1009) - mimemagic (0.3.4) + mimemagic (0.3.5) mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.14.0) - msgpack (1.3.3) + msgpack (1.3.3-x64-mingw32) multi_xml (0.6.0) nio4r (2.5.2) nokogiri (1.10.9) @@ -157,7 +159,7 @@ GEM rubyzip (2.3.0) sass-rails (6.0.0) sassc-rails (~> 2.1, >= 2.1.1) - sassc (2.2.1) + sassc (2.2.1-x64-mingw32) ffi (~> 1.9) sassc-rails (2.1.2) railties (>= 4.0.0) @@ -184,6 +186,8 @@ GEM turbolinks-source (5.2.0) tzinfo (1.2.7) thread_safe (~> 0.1) + tzinfo-data (1.2019.3) + tzinfo (>= 1.0.0) warden (1.2.8) rack (>= 2.0.6) web-console (4.0.1) @@ -199,20 +203,21 @@ GEM activesupport (>= 4.2) rack-proxy (>= 0.6.1) railties (>= 4.2) - websocket-driver (0.7.1) + websocket-driver (0.7.2) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.4) + websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.3.0) PLATFORMS - ruby + x64-mingw32 DEPENDENCIES bootsnap (>= 1.4.2) byebug capybara (>= 2.15) + composite_primary_keys devise (= 4.7.1) devise-encryptable (= 0.2.0) httparty (= 0.18.0) @@ -232,4 +237,4 @@ RUBY VERSION ruby 2.7.0p0 BUNDLED WITH - 2.1.2 + 2.1.4 diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index b8595d5..cd97425 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -118,4 +118,19 @@ input[type=text], input[type=url], input[type=email], input[type=password], inpu line-height: 25px; font-size: 16px; border: 1px solid #bbb; +} + +input { + background-color: white; + border: solid #3F51B5; + border-width: 1px; + color: #3F51B5; + padding: 3px 3px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin-right: 0.1em; + font-weight: bolder; + border-radius: 4px; } \ No newline at end of file diff --git a/app/assets/stylesheets/favorites.scss b/app/assets/stylesheets/favorites.scss index a780c04..2197538 100644 --- a/app/assets/stylesheets/favorites.scss +++ b/app/assets/stylesheets/favorites.scss @@ -40,7 +40,10 @@ display: flex; :nth-child(2) { - color: darkred; + -webkit-text-fill-color: #ffffff; + background-color: #ff1919; + border-radius: 4px; + border-color: #ff1919; } } diff --git a/app/assets/stylesheets/print.css b/app/assets/stylesheets/print.css new file mode 100644 index 0000000..7fada74 --- /dev/null +++ b/app/assets/stylesheets/print.css @@ -0,0 +1,17 @@ +@media print { + nav, input, button, .favNav { + display: none; + } + + @page { + size: A4; + } + + body { + counter-reset: chapternum figurenum; + font-family: "Trebuchet MS", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Tahoma, sans-serif; + line-height: 1.5; + font-size: 11pt; + } +} + diff --git a/app/assets/stylesheets/tiss_crawler.scss b/app/assets/stylesheets/tiss_crawler.scss index 00b82ff..dfc467c 100644 --- a/app/assets/stylesheets/tiss_crawler.scss +++ b/app/assets/stylesheets/tiss_crawler.scss @@ -1,3 +1,8 @@ // Place all the styles related to the tiss_crawler controller here. // They will automatically be included in application.css. // You can use Sass (SCSS) here: https://sass-lang.com/ + +.annotationField { + width: 99.5%; + height: 8em; +} \ No newline at end of file diff --git a/app/controllers/crawlers/courses_crawler_controller.rb b/app/controllers/crawlers/courses_crawler_controller.rb index dc41553..e000079 100644 --- a/app/controllers/crawlers/courses_crawler_controller.rb +++ b/app/controllers/crawlers/courses_crawler_controller.rb @@ -26,6 +26,8 @@ class Crawlers::CoursesCrawlerController < Crawlers::TissCrawlerController params[:semester] = regex[:semester] end + @personal_annotation = get_stored_annotation FavoriteCourse, {number: params[:number]} + puts params # TissCrawler fetches the course's detail information @@ -82,4 +84,8 @@ class Crawlers::CoursesCrawlerController < Crawlers::TissCrawlerController redirect_back(fallback_location: search) end + def add_annotation + store_annotation FavoriteCourse, 'Course', {number: params[:id]} + end + end diff --git a/app/controllers/crawlers/people_crawler_controller.rb b/app/controllers/crawlers/people_crawler_controller.rb index ffb605d..beed2ee 100644 --- a/app/controllers/crawlers/people_crawler_controller.rb +++ b/app/controllers/crawlers/people_crawler_controller.rb @@ -22,6 +22,8 @@ class Crawlers::PeopleCrawlerController < Crawlers::TissCrawlerController params[:api] = '/api/person/v22/id/' params[:tiss_id] = params[:tiss_id] + @personal_annotation = get_stored_annotation FavoritePerson, {tiss_id: params[:tiss_id]} + puts params # TissCrawler fetches the person's detail information @person = TissCrawler.get_details(params) @@ -35,12 +37,12 @@ class Crawlers::PeopleCrawlerController < Crawlers::TissCrawlerController @person = TissCrawler.get_details(params) # create stores the object to the db after creation - favorite_hash = { tiss_id: @person['tiss_id'], - # the user who is currently active - user_id: current_user.id, - first_name: @person['first_name'], - last_name: @person['last_name'], - picture_uri: @person['picture_uri'] } + favorite_hash = {tiss_id: @person['tiss_id'], + # the user who is currently active + user_id: current_user.id, + first_name: @person['first_name'], + last_name: @person['last_name'], + picture_uri: @person['picture_uri']} if FavoritePerson.create(favorite_hash).valid? FavoritePerson.create(favorite_hash) flash[:alert] = 'Person added to your favorites!' @@ -50,4 +52,8 @@ class Crawlers::PeopleCrawlerController < Crawlers::TissCrawlerController redirect_back(fallback_location: crawlers_tiss_crawler_search_path) end + def add_annotation + store_annotation FavoritePerson, 'Person', {tiss_id: params[:id]} + end + end diff --git a/app/controllers/crawlers/projects_crawler_controller.rb b/app/controllers/crawlers/projects_crawler_controller.rb index 605efe2..c25cb31 100644 --- a/app/controllers/crawlers/projects_crawler_controller.rb +++ b/app/controllers/crawlers/projects_crawler_controller.rb @@ -21,6 +21,8 @@ class Crawlers::ProjectsCrawlerController < Crawlers::TissCrawlerController @id = params[:id] + @personal_annotation = get_stored_annotation FavoriteProject, {id: @id} + puts params # TissCrawler fetches the project's detail information @project = TissCrawler.get_project_details(params) @@ -34,9 +36,9 @@ class Crawlers::ProjectsCrawlerController < Crawlers::TissCrawlerController @project = TissCrawler.get_project_details(params) # create stores the object to the db after creation - favorite_hash = {id: params[:id], + favorite_hash = {id: [params[:id], current_user.id], # the user who is currently active - user_id: current_user.id, + # user_id: current_user.id, title: @project['titleDe']} if FavoriteProject.create(favorite_hash).valid? FavoriteProject.create(favorite_hash) @@ -46,4 +48,8 @@ class Crawlers::ProjectsCrawlerController < Crawlers::TissCrawlerController end redirect_back(fallback_location: search) end + + def add_annotation + store_annotation FavoriteProject, 'Project', {id: params[:id]} + end end diff --git a/app/controllers/crawlers/theses_crawler_controller.rb b/app/controllers/crawlers/theses_crawler_controller.rb index 711b1a0..97c8e65 100644 --- a/app/controllers/crawlers/theses_crawler_controller.rb +++ b/app/controllers/crawlers/theses_crawler_controller.rb @@ -21,6 +21,8 @@ class Crawlers::ThesesCrawlerController < Crawlers::TissCrawlerController @id = params[:id] + @personal_annotation = get_stored_annotation FavoriteThesis, {id: @id} + puts params # TissCrawler fetches the thesis' detail information @thesis = TissCrawler.get_thesis_details(params) @@ -34,9 +36,9 @@ class Crawlers::ThesesCrawlerController < Crawlers::TissCrawlerController @thesis = TissCrawler.get_thesis_details(params) # create stores the object to the db after creation - favorite_hash = {id: params[:id], + favorite_hash = {id: [params[:id], current_user.id], # the user who is currently active - user_id: current_user.id, + # user_id: current_user.id, title: @thesis['title']['de']} if FavoriteThesis.create(favorite_hash).valid? FavoriteThesis.create(favorite_hash) @@ -46,4 +48,8 @@ class Crawlers::ThesesCrawlerController < Crawlers::TissCrawlerController end redirect_back(fallback_location: search) end + + def add_annotation + store_annotation FavoriteThesis, 'Thesis', {id: params[:id]} + end end diff --git a/app/controllers/crawlers/tiss_crawler_controller.rb b/app/controllers/crawlers/tiss_crawler_controller.rb index aae78e3..0a9a39d 100644 --- a/app/controllers/crawlers/tiss_crawler_controller.rb +++ b/app/controllers/crawlers/tiss_crawler_controller.rb @@ -34,4 +34,31 @@ class Crawlers::TissCrawlerController < ApplicationController def add_to_fav end + def add_annotation + + end + + private + def get_stored_annotation(object, id_hash) + id_hash['user_id'] = current_user + if object.exists?(id_hash) + object.where(id_hash)[0]['personal_annotation'] + else + "" + end + end + + def store_annotation(object, object_name, id_hash) + id_hash['user_id'] = current_user + + # Allow storing empty strings as a way of "clearing" the stored val + if object.exists?(id_hash) + object.where(id_hash)[0].update(:personal_annotation => params[:body]) + flash[:alert] = 'Annotation stored!' + else + flash[:alert] = object_name + ' has to be favorited first!' + end + redirect_back(fallback_location: crawlers_tiss_crawler_search_path) + end + end diff --git a/app/helpers/crawlers/tiss_crawler_helper.rb b/app/helpers/crawlers/tiss_crawler_helper.rb index b730a09..ec3bcc2 100644 --- a/app/helpers/crawlers/tiss_crawler_helper.rb +++ b/app/helpers/crawlers/tiss_crawler_helper.rb @@ -1,2 +1,9 @@ module Crawlers::TissCrawlerHelper + def render_personal_annotations(id, personal_annotation) + render :partial => "crawlers/personal_annotations", + :locals => { + :cur_id => id, + :personal_annotation => personal_annotation + } + end end diff --git a/app/models/favorite_course.rb b/app/models/favorite_course.rb index 60d0d1f..7bac3e6 100644 --- a/app/models/favorite_course.rb +++ b/app/models/favorite_course.rb @@ -1,4 +1,6 @@ class FavoriteCourse < ApplicationRecord + self.primary_keys = :id, :user_id + validates :title, :semester, :number, presence: true - validates :semester, :number, uniqueness: {scope: [:semester, :number]} + validates :semester, :number, uniqueness: {scope: [:semester, :number, :user_id]} end diff --git a/app/models/favorite_person.rb b/app/models/favorite_person.rb index 9d1e8b8..e5d4186 100644 --- a/app/models/favorite_person.rb +++ b/app/models/favorite_person.rb @@ -1,5 +1,5 @@ class FavoritePerson < ApplicationRecord - self.primary_key = 'tiss_id' + self.primary_keys = :tiss_id, :user_id - validates :tiss_id, uniqueness: true + validates :tiss_id, uniqueness: { scope: [:user_id] } end diff --git a/app/models/favorite_project.rb b/app/models/favorite_project.rb index f7482c4..ca4e37e 100644 --- a/app/models/favorite_project.rb +++ b/app/models/favorite_project.rb @@ -1,5 +1,5 @@ class FavoriteProject < ApplicationRecord - self.primary_key = 'id' + self.primary_keys = :id, :user_id - validates :id, uniqueness: true + validates :id, :user_id, uniqueness: {scope: [:id, :user_id]} end diff --git a/app/models/favorite_thesis.rb b/app/models/favorite_thesis.rb index f1618f9..23f5238 100644 --- a/app/models/favorite_thesis.rb +++ b/app/models/favorite_thesis.rb @@ -1,5 +1,5 @@ class FavoriteThesis < ApplicationRecord - self.primary_key = 'id' + self.primary_keys = :id, :user_id - validates :id, uniqueness: true + validates :id, :user_id, uniqueness: {scope: [:id, :user_id]} end diff --git a/app/views/crawlers/_personal_annotations.html.erb b/app/views/crawlers/_personal_annotations.html.erb new file mode 100644 index 0000000..d28329b --- /dev/null +++ b/app/views/crawlers/_personal_annotations.html.erb @@ -0,0 +1,13 @@ +<%= form_tag "add_annotation", :id => "id" do -%> + <%= hidden_field_tag :authenticity_token, form_authenticity_token %> +
+ Add an annotation: +
++ <%= text_area_tag 'body', personal_annotation, class: 'annotationField' %> + <%= hidden_field_tag :id , cur_id %> +
++ <%= submit_tag "Save annotation" %> +
+<% end -%> \ No newline at end of file diff --git a/app/views/crawlers/courses_crawler/show_detail.html.erb b/app/views/crawlers/courses_crawler/show_detail.html.erb index 23c85ba..d8ad360 100644 --- a/app/views/crawlers/courses_crawler/show_detail.html.erb +++ b/app/views/crawlers/courses_crawler/show_detail.html.erb @@ -1,6 +1,8 @@ <% if @course != nil %> <%-# TODO parse more fields and style them appropriately -%> -Other E-Mails: <%= @person['other_emails'] %>
<% end %> <% if @person['main_addresses'] != nil %> -Address: <%= @person['main_addresses'][0]['street'] %>, <%= @person['main_addresses'][0]['zip_code'] %> <%= @person['main_addresses'][0]['city'] %>
+Address: <%= @person['main_addresses'][0]['street'] %> + , <%= @person['main_addresses'][0]['zip_code'] %> <%= @person['main_addresses'][0]['city'] %>
<% end %> - - <%= button_to 'Add to favorites', action: :add_to_fav, tiss_id: @person['tiss_id'] %> + + <%= button_to 'Add to favorites', action: :add_to_fav, tiss_id: @person['tiss_id'], class: 'button' %> + + <%= render_personal_annotations @person['tiss_id'], @personal_annotation %> + <% end %> \ No newline at end of file diff --git a/app/views/crawlers/projects_crawler/show_detail.html.erb b/app/views/crawlers/projects_crawler/show_detail.html.erb index 7321c2c..92be9e7 100644 --- a/app/views/crawlers/projects_crawler/show_detail.html.erb +++ b/app/views/crawlers/projects_crawler/show_detail.html.erb @@ -1,5 +1,7 @@ <% if @project != nil %> -<%= raw @project['abstractEn'] %>
<% end %> <% end %> + + <%= render_personal_annotations @id, @personal_annotation %> + <% end %> diff --git a/app/views/crawlers/theses_crawler/show_detail.html.erb b/app/views/crawlers/theses_crawler/show_detail.html.erb index 24f1a83..54cc904 100644 --- a/app/views/crawlers/theses_crawler/show_detail.html.erb +++ b/app/views/crawlers/theses_crawler/show_detail.html.erb @@ -1,5 +1,7 @@ <% if @thesis != nil %> -<%= @thesis['assistant']['familyName'] %> <%= @thesis['assistant']['givenName'] %>
<% end %> + + <%= render_personal_annotations @id, @personal_annotation %> <% end %> diff --git a/app/views/favorites/_nav.html.erb b/app/views/favorites/_nav.html.erb index 00728b8..4a9c8e7 100644 --- a/app/views/favorites/_nav.html.erb +++ b/app/views/favorites/_nav.html.erb @@ -3,4 +3,6 @@ <%= link_to 'Courses', favorites_courses_url %> <%= link_to 'Theses', favorites_theses_url %> <%= link_to 'Projects', favorites_projects_url %> -