diff --git a/app/api/v1/entities/manifestation_index.rb b/app/api/v1/entities/manifestation_index.rb index b0b971d9..31685b1f 100644 --- a/app/api/v1/entities/manifestation_index.rb +++ b/app/api/v1/entities/manifestation_index.rb @@ -20,7 +20,8 @@ class ManifestationIndex < Grape::Entity expose :orig_publication_date expose :author_gender, as: :author_genders, documentation: { values: ::Person.genders.keys, is_array: true } expose :translator_gender, as: :translator_genders, documentation: { values: ::Person.genders.keys, is_array: true } - expose :copyright_status, documentation: { type: 'Boolean' } + expose :intellectual_property, + documentation: { values: ::Expression.intellectual_properties.keys, is_array: true } expose :period, documentation: { values: Expression.periods.keys } expose :raw_creation_date expose :creation_date @@ -45,4 +46,4 @@ class ManifestationIndex < Grape::Entity end end end -end \ No newline at end of file +end diff --git a/app/api/v1/texts_api.rb b/app/api/v1/texts_api.rb index 5c5aa24b..dc3f316e 100644 --- a/app/api/v1/texts_api.rb +++ b/app/api/v1/texts_api.rb @@ -103,9 +103,10 @@ class V1::TextsAPI < V1::ApplicationApi type: [String], values: Expression.periods.keys, desc: 'specifies what section of the rough timeline of Hebrew literature an object belongs to.' - optional :is_copyrighted, - type: Boolean, - desc: 'limit search to copyrighted works or to non-copyrighted works' + optional :intellectual_property_types, + type: [String], + values: Expression.intellectual_properties.keys, + desc: 'limit search to works with selected intellectual property types' optional :author_genders, type: [String], values: Person.genders.keys optional :translator_genders, type: [String], values: Person.genders.keys optional :title, type: String, desc: "a substring to match against a text's title" @@ -140,7 +141,20 @@ class V1::TextsAPI < V1::ApplicationApi success V1::Entities::ManifestationsPage end post do - filters = params.slice(*%w(genres periods is_copyrighted author_genders translator_genders title author fulltext author_ids uploaded_between created_between published_between)) + filters = params.slice(*%w( + genres + periods + intellectual_property_types + author_genders + translator_genders + title + author + fulltext + author_ids + uploaded_between + created_between + published_between + )) orig_lang = params['original_language'] if orig_lang.present? diff --git a/app/chewy/manifestations_index.rb b/app/chewy/manifestations_index.rb index a541d152..94ad79e6 100644 --- a/app/chewy/manifestations_index.rb +++ b/app/chewy/manifestations_index.rb @@ -26,7 +26,7 @@ class ManifestationsIndex < Chewy::Index field :tags, type: 'keyword', value: ->{ approved_tags.map(&:name) } field :author_gender, value: ->(manifestation) {manifestation.author_gender }, type: 'keyword' field :translator_gender, value: ->(manifestation) {manifestation.translator_gender}, type: 'keyword' - field :copyright_status, value: ->(manifestation) {manifestation.copyright?}, type: 'keyword' # TODO: make non boolean + field :intellectual_property, value: ->(manifestation) {manifestation.expression.intellectual_property}, type: 'keyword' field :period, value: ->(manifestation) {manifestation.expression.period}, type: 'keyword' field :raw_creation_date, value: ->(manifestation) {manifestation.expression.work.date} field :creation_date, type: 'date', value: ->(manifestation) {normalize_date(manifestation.expression.work.date)} diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index c1c546e9..a6cd9d3d 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -77,7 +77,7 @@ def missing_images def missing_copyright @authors = Person.where(public_domain: nil) - records = Manifestation.joins(:expression).where(expressions: {copyrighted: nil}) + records = Manifestation.joins(:expression).merge(Expression.intellectual_property_unknown) @total = records.count @mans = records.page(params[:page]).per(50) @page_title = t(:missing_copyright_report) diff --git a/app/controllers/manifestation_controller.rb b/app/controllers/manifestation_controller.rb index fbf7e50f..bbbf1ed8 100644 --- a/app/controllers/manifestation_controller.rb +++ b/app/controllers/manifestation_controller.rb @@ -489,7 +489,7 @@ def update @e.title = params[:etitle] @e.date = params[:edate] @e.comment = params[:ecomment] - @e.copyrighted = (params[:public_domain] == 'false' ? true : false) # field name semantics are flipped from param name, yeah + @e.intellectual_property = params[:intellectual_property] unless params[:add_person_e].blank? r = Realizer.new(expression_id: @e.id, person_id: params[:add_person_e], role: params[:role_e].to_i) r.save! diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a4761709..a0fc4628 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -61,6 +61,11 @@ def textify_genre(genre) return I18n.t(genre) end + def textify_intellectual_property(value) + t(value, scope: 'intellectual_property') + end + + # TODO: remove def textify_copyright_status(copyrighted) copyrighted ? t(:by_permission) : t(:public_domain) end @@ -154,8 +159,17 @@ def translators_linked_string(m) return m.expression.translators.map{|x| "#{x.name}"}.join(', ') end - def copyright_glyph(is_copyright) - return is_copyright ? 'x' : 'm' # per /BY icons font/ben-yehuda/icons-reference.html + def intellectual_property_glyph(intellectual_property) + # per /BY icons font/ben-yehuda/icons-reference.html + case intellectual_property + when 'public_domain' + return 'm' + when 'copyrighted' + when 'by_permission' + return 'x' + else + return nil + end end def newsitem_glyph(item) # per icons-reference.html diff --git a/app/models/expression.rb b/app/models/expression.rb index c2dfbfab..3f056ad3 100644 --- a/app/models/expression.rb +++ b/app/models/expression.rb @@ -12,6 +12,11 @@ class Expression < ApplicationRecord has_many :tags, through: :taggings, class_name: 'Tag' has_paper_trail # for monitoring crowdsourced inputs + enum intellectual_property: { public_domain: 0, by_permission: 1, copyrighted: 2, orphan: 3, unknown: 100 }, + _prefix: true + + validates_presence_of :intellectual_property + def editors return realizers.includes(:person).where(role: Realizer.roles[:editor]).map{|x| x.person} end diff --git a/app/services/search_manifestations.rb b/app/services/search_manifestations.rb index 4bdd149a..5c3e6b94 100644 --- a/app/services/search_manifestations.rb +++ b/app/services/search_manifestations.rb @@ -19,12 +19,7 @@ def call(sort_by, sort_dir, filters) add_simple_filter(filter, :genre, filters['genres']) add_simple_filter(filter, :period, filters['periods']) - is_copyrighted = filters['is_copyrighted'] - - unless is_copyrighted.nil? - filter << { terms: { copyright_status: [is_copyrighted] } } - end - + add_simple_filter(filter, :intellectual_property, filters['intellectual_property_types']) add_simple_filter(filter, :author_gender, filters['author_genders']) add_simple_filter(filter, :translator_gender, filters['translator_genders']) add_simple_filter(filter, :author_ids, filters['author_ids']) diff --git a/app/views/authors/_author_top.html.haml b/app/views/authors/_author_top.html.haml index a2cb3a4b..67dda6a6 100644 --- a/app/views/authors/_author_top.html.haml +++ b/app/views/authors/_author_top.html.haml @@ -8,14 +8,8 @@ .author-page-top-years!= "(#{@author.life_years})" .author-top-second-line .author-page-top-rights - - if @author.public_domain - %span.by-icon-v02.copyright-icon> m - = textify_copyright_status(false) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_public_domain), 'data-content' => t(:public_domain_popover) - - else - %span.by-icon-v02.copyright-icon> x - = textify_copyright_status(true) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_permission), 'data-content' => t(:permission_popover) + = render partial: 'shared/intellectual_property', + locals: { intellectual_property: @author.public_domain ? :public_domain : :by_permission } .author-sort-area .author-page-top-sort-desktop.notyet = t(:sort_and_filter) @@ -73,4 +67,4 @@ $('.printbutton').click(function() { window.open("#{@print_url}",'_blank'); }); - }); \ No newline at end of file + }); diff --git a/app/views/manifestation/_dict_entry_top.haml b/app/views/manifestation/_dict_entry_top.haml index 5e6a50ef..38b51f3b 100644 --- a/app/views/manifestation/_dict_entry_top.haml +++ b/app/views/manifestation/_dict_entry_top.haml @@ -20,14 +20,8 @@ - else = '?' .BYD-rights - - if @m.copyright? - %span.by-icon-v02.copyright-icon> x - = textify_copyright_status(true) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_permission), 'data-content' => t(:permission_popover) - - else - %span.by-icon-v02.copyright-icon> m - = textify_copyright_status(false) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_public_domain), 'data-content' => t(:public_domain_popover) + = render partial: 'shared/intellectual_property', + locals: { intellectual_property: @e.intellectual_property } .topNavEntryArea.topNavEntryAreaDesktop - unless @prev_entry.nil? .topNavEntry diff --git a/app/views/manifestation/_dict_top.haml b/app/views/manifestation/_dict_top.haml index 56816305..3bcfec1a 100644 --- a/app/views/manifestation/_dict_top.haml +++ b/app/views/manifestation/_dict_top.haml @@ -17,14 +17,8 @@ - else = '?' .BYD-rights - - if @m.copyright? - %span.by-icon-v02.copyright-icon> x - = textify_copyright_status(true) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_permission), 'data-content' => t(:permission_popover) - - else - %span.by-icon-v02.copyright-icon> m - = textify_copyright_status(false) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_public_domain), 'data-content' => t(:public_domain_popover) + = render partial: 'shared/intellectual_property', + locals: { intellectual_property: @e.intellectual_property } .author-sort-area.notyet#sort_filter_toggle{title: t(:toggle_filters_tt)} .author-page-top-sort-desktop %span.help= t(:filter)+' [?]' @@ -119,4 +113,4 @@ $('.toggle-button-no').toggle(); $('.toggle-button-yes').toggle(); }); - }); \ No newline at end of file + }); diff --git a/app/views/manifestation/_metadata.html.haml b/app/views/manifestation/_metadata.html.haml index dc40dd44..3d980f30 100644 --- a/app/views/manifestation/_metadata.html.haml +++ b/app/views/manifestation/_metadata.html.haml @@ -27,14 +27,7 @@ %div .metadata - - if @m.copyright? - %span.by-icon-v02> x - = textify_copyright_status(true) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_permission), 'data-content' => t(:permission_popover) - - else - %span.by-icon-v02> m - = textify_copyright_status(false) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_public_domain), 'data-content' => t(:public_domain_popover) + = render partial: 'shared/intellectual_property', locals: { intellectual_property: @e.intellectual_property } .metadata %span.by-icon-v02.internal-genre-icon>= glyph_for_genre(@w.genre) = textify_genre(@w.genre) diff --git a/app/views/manifestation/edit_metadata.html.haml b/app/views/manifestation/edit_metadata.html.haml index 697d770e..738e63c8 100644 --- a/app/views/manifestation/edit_metadata.html.haml +++ b/app/views/manifestation/edit_metadata.html.haml @@ -49,12 +49,9 @@ %b= t(:comments)+': ' = text_area_tag :ecomment, @e.comment, rows: 4, cols: 40 %p - %h3= t(:copyright_status) - = radio_button_tag :public_domain, true, @e.copyrighted.nil? ? false : (not @e.copyrighted) - = label_tag t(:public_domain) - = radio_button_tag(:public_domain, false, @e.copyrighted.nil? ? false : @e.copyrighted) - = label_tag t(:by_permission) - / = textify_copyright_status(@e.copyrighted) # TODO: make editable + %h3= Expression.human_attribute_name(:intellectual_property) + - options = Expression.intellectual_properties.keys.map{ |code| [textify_intellectual_property(code), code] } + = select_tag :intellectual_property, options_for_select(options, @e.intellectual_property) = render partial: 'shared/associated_people', locals: { which: :expression, expression: @e, edit: true} %h2= t(:manifestation_details) @@ -95,4 +92,4 @@ = text_field_tag :link_description %p = submit_tag t(:save) -= link_to t(:back), action: :show, id: @m.id \ No newline at end of file += link_to t(:back), action: :show, id: @m.id diff --git a/app/views/manifestation/show.html.haml b/app/views/manifestation/show.html.haml index a34db014..19111e44 100644 --- a/app/views/manifestation/show.html.haml +++ b/app/views/manifestation/show.html.haml @@ -48,8 +48,8 @@ %b= t(:period) + ': ' = t(@e.period) %p - %b= t(:copyright_status) - = textify_copyright_status(@e.copyrighted) + %b #{Expression.human_attribute_name(:intellectual_property)}: + = textify_intellectual_property(@e.intellectual_property) %p %b= t(:language) + ': ' = textify_lang(@e.language) diff --git a/app/views/shared/_anth_panel.html.haml b/app/views/shared/_anth_panel.html.haml index dc5b6419..ab36569f 100644 --- a/app/views/shared/_anth_panel.html.haml +++ b/app/views/shared/_anth_panel.html.haml @@ -93,14 +93,9 @@ %span{:style => "font-weight:bold"}= t(:page_count)+': ' %span= text.page_count %div - - if text.manifestation.copyright? - %span.by-icon-v02.copyright-icon> x - = textify_copyright_status(true) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_permission), 'data-content' => t(:permission_popover) - - else - %span.by-icon-v02.copyright-icon> m - = textify_copyright_status(false) - = link_to '[?]', '#', 'class' => 'help', 'data-toggle' => 'popover', 'data-trigger' => 'focus', title: t(:about_public_domain), 'data-content' => t(:public_domain_popover) + - intellectual_property = text.manifestation.expression.intellectual_property + = render partial: 'shared/intellectual_property', + locals: { intellectual_property: intellectual_property } .bottom-right-buttons #add_work_block{style: 'display: none'} .by-button-v02.by-button-secondary-v02#add_work_btn{title: t(:anth_add_work_tt)} @@ -285,4 +280,4 @@ // enable multi-select mode } }); - }); \ No newline at end of file + }); diff --git a/app/views/shared/_intellectual_property.html.haml b/app/views/shared/_intellectual_property.html.haml new file mode 100644 index 00000000..6ebbfa99 --- /dev/null +++ b/app/views/shared/_intellectual_property.html.haml @@ -0,0 +1,6 @@ +%span.by-icon-v02= intellectual_property_glyph(intellectual_property) += textify_intellectual_property(intellectual_property) += link_to '[?]', '#', + class: :help, + data: { toggle: :popover, trigger: :focus, content: t(".popover.#{intellectual_property}") }, + title: t(".about.#{intellectual_property}") diff --git a/app/views/shared/_surprise_work.html.haml b/app/views/shared/_surprise_work.html.haml index 146a8e76..6e893871 100644 --- a/app/views/shared/_surprise_work.html.haml +++ b/app/views/shared/_surprise_work.html.haml @@ -23,9 +23,9 @@ .row .col-md-6.col-sm-12 .metadata - .by-icon-v02.copyright-icon= copyright_glyph(manifestation.copyright?) - = textify_copyright_status(manifestation.copyright?) - %span.help{ 'data-toggle' => 'tooltip', title: manifestation.copyright? ? t(:permission_explain) : t(:pd_explain)}= '[?]' + .by-icon-v02.copyright-icon= intellectual_property_glyph(e.intellectual_property) + = textify_intellectual_property(e.intellectual_property) + %span.help{ data: { toggle: :tooltip }, title: t(".explanations.#{e.intellectual_property}")}= '[?]' - if e.translation .metadata %b= t(:orig_lang)+': ' diff --git a/config/locales/active_record.en.yml b/config/locales/active_record.en.yml new file mode 100644 index 00000000..82bb6585 --- /dev/null +++ b/config/locales/active_record.en.yml @@ -0,0 +1,5 @@ +en: + activerecord: + attributes: + expression: + intellectual_property: Type of intellectual property diff --git a/config/locales/active_record.he.yml b/config/locales/active_record.he.yml new file mode 100644 index 00000000..cbce6672 --- /dev/null +++ b/config/locales/active_record.he.yml @@ -0,0 +1,5 @@ +he: + activerecord: + attributes: + expression: + intellectual_property: Type of intellectual property diff --git a/config/locales/en.yml b/config/locales/en.yml index 56f1de28..fa2cf173 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -8,6 +8,26 @@ en: next_page: Next page previous_page: Previous page first_page: First page + surprise_work: + explanations: + public_domain: not protected by intellectual property laws + by_permission: there is an explicit permission for publication from the owner + copyrighted: copyrighted + orphan: orphan + unknown: unknown + intellectual_property: + about: + public_domain: what does it means 'public domain'? + by_permission: what does it means 'by permission'? + copyrighted: what does it means 'copyrighted'? + orphan: what does it means 'orphan'? + unknown: what does it means 'unknown'? + popover: + public_domain: Copyright Law protects against unauthorized use of works for the duration of its validity (in Israel, seventy years from the end of the year of the creator's death). With the expiry of the rights, the creation becomes 'public domain', that is, the property of the public. This means that the work belongs to all of us, and we are all entitled to make any use of it, including commercial use, without the need to ask permission of anyone. + by_permission: Although the work is still copyrighted, the Ben־Yehuda Project has received *explicit permission to publish* The work in the Ben־Yehuda Project database, for the general public to read and research. Other uses (such as play, composition, or commercial performance) still *require express approval* from the rights holders. + copyrighted: TBD description for 'copyrighted' + orphan: TBD description for 'orphan' + unknown: TBD description for 'unknown' welcome: submit_contact: ziburit_failed: Control question failed @@ -24,3 +44,9 @@ en: ziburit_failed: Control question failed email_missing: Please provide an email address manifestation: + intellectual_property: + public_domain: public domain + by_permission: by permission + copyrighted: copyrighted + orphan: orphan + unknown: unknown diff --git a/config/locales/he.yml b/config/locales/he.yml index 044d06bf..63d56f12 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -414,7 +414,6 @@ he: ready: מוכן photo: תמונה last_update: עדכון אחרון - copyright_status: מצב זכויות יוצרים basic_details: פרטים בסיסיים submit: שליחה logo: לוגו @@ -936,12 +935,6 @@ he: anth_text_deletion_p3: מתוך המקראה הנוכחית confirm_anth_text_deletion: אישור מחיקת הפריט מהמקראה maintenance: תחזוקה - public_domain: נחלת הכלל - about_public_domain: 'מה פירוש נחלת הכלל?' - public_domain_popover: "חוק זכויות יוצרים מגן מפני שימוש בלתי-מורשה ביצירות למשך תקופת תוקפו (בישראל, שבעים שנה מסוף שנת מות היוצר). עם פקוע הזכויות, הופכת היצירה 'נחלת הכלל', כלומר רכוש הציבור. פירוש הדבר שהיצירה שייכת לכולנו, וכולנו רשאים לעשות בה כל שימוש, לרבות שימוש מסחרי, מבלי צורך לבקש רשות מאיש." - about_permission: 'מה פירוש ברשות פרסום?' - permission_popover: "על אף שהיצירה עדיין מוגנת בזכויות יוצרים, פרויקט בן־יהודה קיבל *רשות מפורשת לפרסם* את היצירה במאגר היצירה של פרויקט בן־יהודה, לשימוש הקהל הרחב לקריאה ומחקר. שימושים אחרים (כגון המחזה, הלחנה, או ביצוע מסחרי) עדיין *טעונים אישור מפורש* מאת בעלי הזכויות." - by_permission: מוגש ברשות פרסום uploaded_images: נקלטו %{images_added} קבצים נוספים, ועכשיו יש ליצירה %{total} בסך הכל. add_image: הוספת תמונה add_all_images: הדבקת כל התמונות @@ -1235,8 +1228,6 @@ he: translator: מתרגם translator_f: מתרגמת translated_by: בתרגום - pd_explain: פגו זכויות היוצרים על יצירות אלו - permission_explain: התקבלה רשות מפורשת מבעלי הזכויות לפרסום היצירות about_the_author_on_the_blog: רשומות ביומן הרשת donate_title: תמיכה כספית בפרויקט donate_p1_html: כל עבודת ההקלדה, ההגהה והעריכה בפרויקט נעשית בהתנדבות וללא קבלת תמורה. עם זאת, אנו מזמינים שירותי פיתוח תוכנה, אפיון, ועיצוב מנשק משתמש מקבלנים, ולשם כך אנו מגייסים תרומות. @@ -1349,6 +1340,26 @@ he: next_page: לדף הבא previous_page: לדף הקודם first_page: לדף הראשון + surprise_work: + explanations: + public_domain: פגו זכויות היוצרים על יצירות אלו + by_permission: התקבלה רשות מפורשת מבעלי הזכויות לפרסום היצירות + copyrighted: copyrighted + orphan: orphan + unknown: unknown + intellectual_property: + about: + public_domain: מה פירוש נחלת הכלל? + by_permission: מה פירוש ברשות פרסום? + copyrighted: what does it means 'copyrighted'? + orphan: what does it means 'orphan'? + unknown: what does it means 'unknown'? + popover: + public_domain: חוק זכויות יוצרים מגן מפני שימוש בלתי-מורשה ביצירות למשך תקופת תוקפו (בישראל, שבעים שנה מסוף שנת מות היוצר). עם פקוע הזכויות, הופכת היצירה 'נחלת הכלל', כלומר רכוש הציבור. פירוש הדבר שהיצירה שייכת לכולנו, וכולנו רשאים לעשות בה כל שימוש, לרבות שימוש מסחרי, מבלי צורך לבקש רשות מאיש. + by_permission: על אף שהיצירה עדיין מוגנת בזכויות יוצרים, פרויקט בן־יהודה קיבל *רשות מפורשת לפרסם* את היצירה במאגר היצירה של פרויקט בן־יהודה, לשימוש הקהל הרחב לקריאה ומחקר. שימושים אחרים (כגון המחזה, הלחנה, או ביצוע מסחרי) עדיין *טעונים אישור מפורש* מאת בעלי הזכויות. + copyrighted: TBD description for 'copyrighted' + orphan: TBD description for 'orphan' + unknown: TBD description for 'unknown' welcome: submit_contact: ziburit_failed: לא השתכנענו שאינך רובוט. @@ -1365,3 +1376,16 @@ he: ziburit_failed: לא השתכנענו שאינך רובוט. email_missing: נא לציין כתובת דואל, כדי שנוכל להשיב לך. manifestation: + intellectual_property: + public_domain: נחלת הכלל + by_permission: מוגש ברשות פרסום + copyrighted: copyrighted + orphan: orphan + unknown: unknown + + copyright_status: מצב זכויות יוצרים + public_domain: נחלת הכלל + by_permission: מוגש ברשות פרסום + pd_explain: פגו זכויות היוצרים על יצירות אלו + permission_explain: התקבלה רשות מפורשת מבעלי הזכויות לפרסום היצירות + diff --git a/db/migrate/20240424145657_change_copyrighted.rb b/db/migrate/20240424145657_change_copyrighted.rb new file mode 100644 index 00000000..c74da6a9 --- /dev/null +++ b/db/migrate/20240424145657_change_copyrighted.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class ChangeCopyrighted < ActiveRecord::Migration[6.1] + def change + add_column :expressions, :intellectual_property, :integer + + execute <<~sql + update expressions set intellectual_property = case copyrighted when true then 1 when false then 0 else 100 end + sql + + change_column_null :expressions, :intellectual_property, false + + remove_column :expressions, :copyrighted + + add_index :expressions, :intellectual_property + end +end diff --git a/db/schema.rb b/db/schema.rb index 426861d1..70f4007a 100755 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2024_02_06_222123) do +ActiveRecord::Schema.define(version: 2024_04_24_145657) do create_table "aboutnesses", id: :integer, charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t| t.integer "work_id" @@ -356,7 +356,6 @@ t.text "comment", size: :medium t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.boolean "copyrighted" t.date "copyright_expiration" t.boolean "translation" t.string "source_edition" @@ -364,6 +363,8 @@ t.string "normalized_pub_date" t.string "normalized_creation_date" t.integer "work_id", null: false + t.integer "intellectual_property", null: false + t.index ["intellectual_property"], name: "index_expressions_on_intellectual_property" t.index ["normalized_creation_date"], name: "index_expressions_on_normalized_creation_date" t.index ["normalized_pub_date"], name: "index_expressions_on_normalized_pub_date" t.index ["period"], name: "index_expressions_on_period" diff --git a/spec/api/v1/text_api_spec.rb b/spec/api/v1/text_api_spec.rb index 62f7fba3..f00c362a 100644 --- a/spec/api/v1/text_api_spec.rb +++ b/spec/api/v1/text_api_spec.rb @@ -227,11 +227,12 @@ end end - context 'when filter by copyright is provided' do + context 'when filter by intellectual property types is provided' do let(:manifestations) { result = [] (1..60).each do |index| - e = create(:expression, copyrighted: index%10 == 0) + intellectual_property = %w(public_domain by_permission copyrighted unknown)[index%4] + e = create(:expression, intellectual_property: intellectual_property) result << create(:manifestation, impressions_count: Random.rand(100), expression: e) end result @@ -243,13 +244,21 @@ end end - let(:additional_params) { { is_copyrighted: true, sort_by: :popularity, sort_dir: :asc } } + let(:additional_params) do + { intellectual_property_types: %w(public_domain unknown), sort_by: :popularity, sort_dir: :asc } + end it 'returns only copyrighted works' do expect(subject).to eq 201 - expect(total_count).to eq 6 - expect(data.size).to eq 6 - expect(data_ids).to eq manifestations.select(&:copyright?).sort_by(&:impressions_count).map(&:id) + expect(total_count).to eq 30 + expect(data.size).to eq 25 + + matched = manifestations.select do |m| + m.expression.intellectual_property_public_domain? || m.expression.intellectual_property_unknown? + end + + expect(data_ids).to eq matched.sort_by(&:impressions_count).map(&:id)[0..24] + end end @@ -258,7 +267,7 @@ { 'genres' => %w(poetry), 'periods' => %w(revival), - 'is_copyrighted' => true, + 'intellectual_property_types' => %w(public_domain), 'author_genders' => %w(male), 'translator_genders' => %w(female), 'title' => 'Title', @@ -384,7 +393,7 @@ def assert_manifestation(json, manifestation, view, file_format, snippet) expect(md['orig_publication_date']).to eq normalize_date(expression.date).to_s expect(md['author_genders']).to eq manifestation.author_gender expect(md['translator_genders']).to eq manifestation.translator_gender - expect(md['copyright_status']).to eq manifestation.copyright? + expect(md['intellectual_property']).to eq manifestation.expression.intellectual_property expect(md['period']).to eq expression.period expect(md['raw_creation_date']).to eq work.date expect(md['creation_date']).to eq normalize_date(work.date).to_s diff --git a/spec/controllers/admin_controller_spec.rb b/spec/controllers/admin_controller_spec.rb index ead5df4f..20c90dd0 100644 --- a/spec/controllers/admin_controller_spec.rb +++ b/spec/controllers/admin_controller_spec.rb @@ -56,24 +56,35 @@ describe '#incongruous_copyright' do include_context 'Admin user logged in' subject(:request) { get :incongruous_copyright } - let(:copyrighted_person) { create(:person, public_domain: false) } - let!(:public_domain_manifestation) { create(:manifestation, copyrighted: false) } - let!(:copyrighted_manifestation) { create(:manifestation, author: copyrighted_person, copyrighted: true) } - let!(:wrong_public_domain_manifestation_1) { create(:manifestation, author: copyrighted_person, copyrighted: false) } - let!(:wrong_public_domain_manifestation_2) { create(:manifestation, orig_lang: 'ru', translator: copyrighted_person, copyrighted: false) } - let!(:wrong_copyrighted_manifestation_1) { create(:manifestation, copyrighted: true) } - let!(:wrong_copyrighted_manifestation_2) { create(:manifestation, orig_lang: 'ru', copyrighted: true) } + let!(:public_domain_manifestation) do + create(:manifestation, intellectual_property: :public_domain) + end + let!(:by_permission_manifestation) do + create(:manifestation, author: copyrighted_person, intellectual_property: :by_permission) + end + let!(:wrong_public_domain_manifestation_1) do + create(:manifestation, author: copyrighted_person, intellectual_property: :public_domain) + end + let!(:wrong_public_domain_manifestation_2) do + create(:manifestation, orig_lang: 'ru', translator: copyrighted_person, intellectual_property: :public_domain) + end + let!(:wrong_by_permission_manifestation) do + create(:manifestation, intellectual_property: :by_permission) + end + let!(:wrong_copyrighted_manifestation) do + create(:manifestation, orig_lang: 'ru', intellectual_property: :copyrighted) + end - let(:wrong_manifestation_ids) { + let(:wrong_manifestation_ids) do [ wrong_public_domain_manifestation_1.id, wrong_public_domain_manifestation_2.id, - wrong_copyrighted_manifestation_1.id, - wrong_copyrighted_manifestation_2.id + wrong_by_permission_manifestation.id, + wrong_copyrighted_manifestation.id ] - } + end it 'renders successfully' do expect(request).to be_successful @@ -122,13 +133,13 @@ include_context 'Admin user logged in' subject(:request) { get :missing_copyright } - let!(:copyrighted_manifestation) { create(:manifestation, copyrighted: true) } - let!(:public_domain_manifestation) { create(:manifestation, copyrighted: false) } - let!(:missing_copyright_manifestation) { create(:manifestation, copyrighted: nil) } + let!(:by_permission_manifestation) { create(:manifestation, intellectual_property: :by_permission) } + let!(:public_domain_manifestation) { create(:manifestation, intellectual_property: :public_domain) } + let!(:unknown_manifestation) { create(:manifestation, intellectual_property: :unknown) } it 'shows records where copyright is nil' do expect(request).to be_successful - expect(assigns(:mans)).to eq [missing_copyright_manifestation] + expect(assigns(:mans)).to eq [unknown_manifestation] end end diff --git a/spec/controllers/manifestations_controller_spec.rb b/spec/controllers/manifestations_controller_spec.rb index 502aa0b5..f6a5da56 100644 --- a/spec/controllers/manifestations_controller_spec.rb +++ b/spec/controllers/manifestations_controller_spec.rb @@ -350,7 +350,8 @@ etitle: 'New Expression Title', genre: 'fables', wlang: 'ru', - primary: 'false' + primary: 'false', + intellectual_property: 'by_permission' } end @@ -359,7 +360,7 @@ expect(flash.notice).to eq I18n.t(:updated_successfully) manifestation.reload expect(manifestation).to have_attributes(title: 'New Manifestation Title') - expect(expression).to have_attributes(title: 'New Expression Title') + expect(expression).to have_attributes(title: 'New Expression Title', intellectual_property: 'by_permission') expect(work).to have_attributes(title: 'New Work Title', orig_lang: 'ru', genre: 'fables', primary: false) end end diff --git a/spec/factories/expressions.rb b/spec/factories/expressions.rb index 67474576..53fa8dfc 100644 --- a/spec/factories/expressions.rb +++ b/spec/factories/expressions.rb @@ -16,7 +16,7 @@ date { '2 ביוני 1960' } language { 'he' } comment { "Comment for #{expression_name}" } - copyrighted { false } + intellectual_property { :public_domain } copyright_expiration { nil } translation { orig_lang != language } source_edition {} diff --git a/spec/factories/manifestations.rb b/spec/factories/manifestations.rb index 18ff0140..1ddfb133 100644 --- a/spec/factories/manifestations.rb +++ b/spec/factories/manifestations.rb @@ -10,7 +10,7 @@ translator { orig_lang != language ? create(:person) : nil } editor { nil } illustrator { nil } - copyrighted { false } + intellectual_property { :public_domain } expression_title { title } work_title { title } primary { true } @@ -38,7 +38,7 @@ orig_lang: orig_lang, genre: genre, period: period, - copyrighted: copyrighted, + intellectual_property: intellectual_property, primary: primary ) end diff --git a/spec/services/search_manifestations_spec.rb b/spec/services/search_manifestations_spec.rb index 2d4e31ee..44bc5cf2 100644 --- a/spec/services/search_manifestations_spec.rb +++ b/spec/services/search_manifestations_spec.rb @@ -38,7 +38,7 @@ genre = %w(poetry prose drama fables article)[index % 5] period = %w(ancient medieval enlightenment revival modern)[index % 5] - copyrighted = index % 10 == 0 + intellectual_property = %w(public_domain copyrighted by_permission unknown)[index % 4] realizers = [] @@ -58,7 +58,7 @@ :expression, period: period, genre: genre, - copyrighted: copyrighted, + intellectual_property: intellectual_property, realizers: realizers, date: published_at.strftime('%d.%m.%Y'), work: work @@ -136,26 +136,14 @@ end end - describe 'by copyright' do - let(:filter) { { 'is_copyrighted' => is_copyrighted } } + describe 'by intellectual property types' do + let(:types) { %w(public_domain unknown) } + let(:filter) { { 'intellectual_property_types' => types } } - context 'when copyrighted texts requested' do - let(:is_copyrighted) { true } - it 'returns all copyrighted texts' do - expect(subject.count).to eq 20 - subject.limit(REC_COUNT).each do |rec| - expect(rec.copyright_status).to be_truthy - end - end - end - - context 'when not copyrighted texts requested' do - let(:is_copyrighted) { false } - it 'returns all not copyrighted texts' do - expect(subject.count).to eq 180 - subject.limit(REC_COUNT).each do |rec| - expect(rec.copyright_status).to be_falsey - end + it 'returns all works with given intellectual property types' do + expect(subject.count).to eq 100 + subject.limit(REC_COUNT).each do |rec| + expect(types).to include(rec.intellectual_property) end end end