diff --git a/app/controllers/concerns/script_listings.rb b/app/controllers/concerns/script_listings.rb index 42d1e4b0b3f..79469f723b3 100644 --- a/app/controllers/concerns/script_listings.rb +++ b/app/controllers/concerns/script_listings.rb @@ -147,8 +147,11 @@ def code_search return end - script_ids = ScriptCodeSearch.search(params[:c]) + limit_to_ids = User.find_by(id: params[:by])&.script_ids if params[:by].presence + + script_ids = ScriptCodeSearch.search(params[:c], limit_to_ids:) @scripts = Script.order(self.class.get_sort(params)).includes(:users, :localized_attributes).where(id: script_ids) + @scripts = @scripts.where(language: (params[:language] == 'css') ? 'css' : 'js') unless params[:language] == 'all' include_deleted = current_user&.moderator? && params[:include_deleted] == '1' @scripts = @scripts.listable(script_subset) unless include_deleted @scripts = @scripts.paginate(page: page_number, per_page:) @@ -157,14 +160,16 @@ def code_search format.html do @bots = 'noindex,nofollow' @title = t('scripts.listing_title_for_code_search', search_string: params[:c]) + @page_description = t('scripts.listing_description_for_code_search_html', search_string: params[:c]) @canonical_params = [:c, :sort] @include_script_sets = false if current_user&.moderator? - @page_description = if include_deleted - view_context.link_to('Exclude deleted scripts', { c: params[:c], include_deleted: nil }) - else - view_context.link_to('Include deleted scripts', { c: params[:c], include_deleted: '1' }) - end + @page_description += view_context.content_tag(:p, + if include_deleted + view_context.link_to('Exclude deleted scripts', { c: params[:c], include_deleted: nil }) + else + view_context.link_to('Include deleted scripts', { c: params[:c], include_deleted: '1' }) + end) end @link_alternates = [ @@ -201,6 +206,7 @@ def apply_filters(scripts, params, script_subset, default_sort: nil) scripts = scripts.where(id: set_script_ids) end scripts = scripts.where(language: (params[:language] == 'css') ? 'css' : 'js') unless params[:language] == 'all' + scripts = scripts.joins(:authors).where(authors: { user_id: params[:by] }) if params[:by].presence scripts = scripts.order(get_sort(params, set:, default_sort:)) return scripts end @@ -311,6 +317,8 @@ def load_scripts_for_index_with_es with[:available_as_js] = true end + with[:author_ids] = params[:by] if params[:by] + @scripts = Script.search( params[:q].presence || '*', fields: ['name^10', 'description^5', 'author^5', 'additional_info^1'], diff --git a/app/helpers/scripts_helper.rb b/app/helpers/scripts_helper.rb index 4fbe1642a42..1ae840b61da 100644 --- a/app/helpers/scripts_helper.rb +++ b/app/helpers/scripts_helper.rb @@ -3,7 +3,7 @@ module ScriptsHelper extend Memoist - def script_list_link(label, sort: nil, site: nil, set: nil, default_sort: nil, language: nil, filter_locale: nil, rel: nil, new: nil) + def script_list_link(label, sort: nil, site: nil, set: nil, default_sort: nil, language: nil, filter_locale: nil, rel: nil, by: nil) is_link = true is_minified = action_name == 'minified' is_code_search = action_name == 'code_search' @@ -11,7 +11,7 @@ def script_list_link(label, sort: nil, site: nil, set: nil, default_sort: nil, l # sets can have a different default sort_param_to_use = (sort == default_sort) ? nil : sort rel ||= (set.present? || filter_locale.present?) ? :nofollow : nil - if sort == params[:sort] && site == params[:site] && set == params[:set] && language == params[:language] + if sort == params[:sort] && site == params[:site] && set == params[:set] && language == params[:language] && by == params[:by] l = label is_link = false elsif is_libraries @@ -19,13 +19,13 @@ def script_list_link(label, sort: nil, site: nil, set: nil, default_sort: nil, l elsif is_minified l = link_to(label, minified_scripts_path(sort: sort_param_to_use), rel:) elsif is_code_search - l = link_to(label, code_search_scripts_path(sort: sort_param_to_use, c: params[:c]), rel:) + l = link_to(label, code_search_scripts_path(sort: sort_param_to_use, c: params[:c], language:, by:), rel:) elsif site.nil? - l = link_to(label, { sort: sort_param_to_use, site: nil, set:, q: params[:q], language:, filter_locale:, new: }, rel:) + l = link_to(label, { sort: sort_param_to_use, site: nil, set:, q: params[:q], language:, filter_locale:, by: }, rel:) elsif params[:controller] == 'users' l = link_to(label, { sort: sort_param_to_use, site:, set:, language:, filter_locale: }, rel:) else - l = link_to label, by_site_scripts_path(sort: sort_param_to_use, site:, set:, q: params[:q], language:, filter_locale:, new:), rel: + l = link_to label, by_site_scripts_path(sort: sort_param_to_use, site:, set:, q: params[:q], language:, filter_locale:, by:), rel: end tag.li(class: "list-option#{is_link ? '' : ' list-current'}") { l } end diff --git a/app/models/concerns/script_indexing.rb b/app/models/concerns/script_indexing.rb index 852ab9e06f9..cc2fd209a11 100644 --- a/app/models/concerns/script_indexing.rb +++ b/app/models/concerns/script_indexing.rb @@ -38,6 +38,9 @@ module ScriptIndexing author: { type: 'keyword', }, + author_ids: { + type: 'integer', + }, created_at: { type: 'date', }, @@ -88,6 +91,7 @@ def search_data description: search_value_from_localized_attributes('description'), additional_info: search_value_from_localized_attributes('additional_info'), author: users.map(&:name).join(' '), + author_ids: users.map(&:id), created_at:, code_updated_at:, total_installs:, diff --git a/app/services/script_code_search.rb b/app/services/script_code_search.rb index 172772ff6f1..117b4508945 100644 --- a/app/services/script_code_search.rb +++ b/app/services/script_code_search.rb @@ -30,8 +30,14 @@ def index_all end end - def search(text) - content, _stderr, _status = Open3.capture3('grep', '-R', '-F', '-l', text, BASE_PATH) + def search(text, limit_to_ids: nil) + content, _stderr, _status = if limit_to_ids.nil? + Open3.capture3('grep', '-R', '-F', '-l', text, BASE_PATH) + elsif limit_to_ids.none? + ['', nil, nil] + else + Open3.capture3('grep', '-R', '-F', '-l', text, *limit_to_ids.map { |id| "#{BASE_PATH}/#{id}" }) + end content.split("\n").map { |line| line.delete_prefix("#{BASE_PATH}/") }.map(&:to_i) end diff --git a/app/views/scripts/_list_options.html.erb b/app/views/scripts/_list_options.html.erb index 98c1d7dbf5a..086915d2fb9 100644 --- a/app/views/scripts/_list_options.html.erb +++ b/app/views/scripts/_list_options.html.erb @@ -7,7 +7,7 @@ libraries = false if !defined?(libraries) || libraries.nil? default_sort = @set&.default_sort || (params[:q].present? ? 'relevance' : (libraries ? 'created' : ScriptListings::DEFAULT_SORT)) rel = nil unless defined?(rel) -current_options = params.to_unsafe_h.slice(:sort, :site, :set, :language, :filter_locale,).map {|k, v| [k.to_sym, v] }.to_h.merge(default_sort: default_sort) +current_options = params.to_unsafe_h.slice(:sort, :site, :set, :language, :filter_locale, :by).map {|k, v| [k.to_sym, v] }.to_h.merge(default_sort: default_sort) current_options[:rel] = rel if rel skip_all_sites_link = false unless defined?(skip_all_sites_link) %> @@ -81,6 +81,23 @@ skip_all_sites_link = false unless defined?(skip_all_sites_link) <% end %> + <% if (current_user || params[:by].presence) && controller_name != 'users' %> +
Authorship: + +
+ <% end %> + <% # This doesn't work for search if include_script_sets && (action_name != 'index' || params[:q].blank?) && user_signed_in? && !current_user.script_sets.empty? %>
Script set: diff --git a/app/views/scripts/index.html.erb b/app/views/scripts/index.html.erb index 85932350ff1..1244600f7fa 100644 --- a/app/views/scripts/index.html.erb +++ b/app/views/scripts/index.html.erb @@ -63,7 +63,7 @@
- <%= render partial: 'list_options', locals: {by_sites: @by_sites, scripts: @scripts, sort_options: @sort_options, include_script_sets: @include_script_sets.nil? ? true : @include_script_sets, include_search: true} %> + <%= render partial: 'list_options', locals: {by_sites: @by_sites, scripts: @scripts, sort_options: @sort_options, include_script_sets: @include_script_sets.nil? ? true : @include_script_sets, include_search: action_name != 'code_search'} %> <% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index a849e2c1562..b39984ecdf2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -236,6 +236,7 @@ en: listing_title_for_search: "'%{search_string}' user scripts" # html title for script list page for code search results. listing_title_for_code_search: "'%{search_string}' user scripts" + listing_description_for_code_search_html: "Code search for %{search_string}" # html title for script list page when no other situation applies listing_title_generic: "User scripts" # html title for script list page for a user's favorites. set_name is script_sets.favorites_name @@ -283,6 +284,10 @@ en: listing_language_all: "All" listing_language_js: "JavaScript" listing_language_css: "CSS" + listing_author: + all: All authors + me: My scripts + user: Scripts by %{author_name} search_failed: Something went wrong loading your results. Some search functionality may not be working. We've been notified of the issue. # link to start the process of importing (creating from an external place) scripts import: "Import scripts"