From fe2b85ae96b20eda5904cd64eded9ae5e2d9df35 Mon Sep 17 00:00:00 2001 From: Caio <117518+caiosba@users.noreply.github.com> Date: Fri, 23 Aug 2024 20:50:54 -0300 Subject: [PATCH] [WIP] Ticket CV2-5067: Implementing export for articles and feeds --- app/graph/mutations/export_mutations.rb | 4 +- app/models/explainer.rb | 8 +++ app/models/fact_check.rb | 8 +++ app/models/feed.rb | 8 +++ lib/list_export.rb | 17 ++++++- test/lib/list_export_test.rb | 66 ++++++++++++++++++++++--- 6 files changed, 102 insertions(+), 9 deletions(-) diff --git a/app/graph/mutations/export_mutations.rb b/app/graph/mutations/export_mutations.rb index 29cdcc150f..a3dde76a1b 100644 --- a/app/graph/mutations/export_mutations.rb +++ b/app/graph/mutations/export_mutations.rb @@ -1,7 +1,7 @@ module ExportMutations class ExportList < Mutations::BaseMutation - argument :query, GraphQL::Types::String, required: true - argument :type, GraphQL::Types::String, required: true # 'media', 'feed' or 'article' + argument :query, GraphQL::Types::String, required: true # JSON + argument :type, GraphQL::Types::String, required: true # 'media', 'feed', 'fact-check' or 'explainer' field :success, GraphQL::Types::Boolean, null: true diff --git a/app/models/explainer.rb b/app/models/explainer.rb index a4319e718a..5b55a57694 100644 --- a/app/models/explainer.rb +++ b/app/models/explainer.rb @@ -48,6 +48,14 @@ def update_paragraphs_in_alegre self.class.delay_for(5.seconds).update_paragraphs_in_alegre(self.id, previous_paragraphs_count, Time.now.to_f) end + def self.get_exported_data(query, team) + data = [['ID', 'Title', 'Description', 'URL', 'Language']] + team.filtered_explainers(query).find_each do |exp| + data << [exp.id, exp.title, exp.description, exp.url, exp.language] + end + data + end + def self.update_paragraphs_in_alegre(id, previous_paragraphs_count, timestamp) explainer = Explainer.find(id) diff --git a/app/models/fact_check.rb b/app/models/fact_check.rb index 5d42782496..5830494615 100644 --- a/app/models/fact_check.rb +++ b/app/models/fact_check.rb @@ -47,6 +47,14 @@ def update_item_status end end + def self.get_exported_data(query, team) + data = [['ID', 'Title', 'Summary', 'URL', 'Language', 'Report Status', 'Imported?']] + team.filtered_fact_checks(query).find_each do |fc| + data << [fc.id, fc.title, fc.summary, fc.url, fc.language, fc.report_status, fc.imported.to_s] + end + data + end + private def set_language diff --git a/app/models/feed.rb b/app/models/feed.rb index 05a652024f..e90c2c2d84 100755 --- a/app/models/feed.rb +++ b/app/models/feed.rb @@ -172,6 +172,14 @@ def saved_search_was SavedSearch.find_by_id(self.saved_search_id_before_last_save) end + def get_exported_data(filters) + data = [['Title', 'Number of media', 'Number of requests', 'Number of fact-checks']] + self.filtered_clusters(filters).find_each do |cluster| + data << [cluster.title, cluster.media_count, cluster.requests_count, cluster.fact_checks_count] + end + data + end + # This takes some time to run because it involves external HTTP requests and writes to the database: # 1) If the query contains a media URL, it will be downloaded... if it contains some other URL, it will be sent to Pender # 2) Requests will be made to Alegre in order to index the request media and to look for similar requests diff --git a/lib/list_export.rb b/lib/list_export.rb index cca7b50f06..51ec959d60 100644 --- a/lib/list_export.rb +++ b/lib/list_export.rb @@ -1,10 +1,13 @@ class ListExport - TYPES = [:article, :feed, :media] + TYPES = [:media, :feed, :fact_check, :explainer] def initialize(type, query, team_id) @type = type @query = query + @parsed_query = JSON.parse(@query) @team_id = team_id + @team = Team.find(team_id) + @feed = Feed.where(id: @parsed_query['feed_id'], team_id: @team_id).last if type == :feed raise "Invalid export type '#{type}'. Should be one of: #{TYPES}" unless TYPES.include?(type) end @@ -12,6 +15,12 @@ def number_of_rows case @type when :media CheckSearch.new(@query, nil, @team_id).number_of_results + when :feed + @feed.clusters_count(@parsed_query) + when :fact_check + @team.filtered_fact_checks(@parsed_query).count + when :explainer + @team.filtered_explainers(@parsed_query).count end end @@ -47,6 +56,12 @@ def export_data case @type when :media CheckSearch.get_exported_data(@query, @team_id) + when :feed + @feed.get_exported_data(@parsed_query) + when :fact_check + FactCheck.get_exported_data(@parsed_query, @team) + when :explainer + Explainer.get_exported_data(@parsed_query, @team) end end end diff --git a/test/lib/list_export_test.rb b/test/lib/list_export_test.rb index bea73e931b..668797d6e6 100644 --- a/test/lib/list_export_test.rb +++ b/test/lib/list_export_test.rb @@ -7,21 +7,17 @@ def setup def teardown end - test "should export media CSV and expire it" do + test "should expire the export" do t = create_team create_team_task team_id: t.id, fieldset: 'tasks' - pm1 = create_project_media team: t - pm2 = create_project_media team: t + pm = create_project_media team: t stub_configs({ 'export_csv_expire' => 2 }) do - # Generate a CSV with the two exported items export = ListExport.new(:media, '{}', t.id) csv_url = export.generate_csv_and_send_email(create_user) response = Net::HTTP.get_response(URI(csv_url)) assert_equal 200, response.code.to_i - csv_content = CSV.parse(response.body, headers: true) - assert_equal 2, csv_content.size # Make sure it expires after 2 seconds sleep 3 # Just to be safe @@ -29,4 +25,62 @@ def teardown assert_equal 403, response.code.to_i end end + + test "should export media CSV" do + t = create_team + create_team_task team_id: t.id, fieldset: 'tasks' + 2.times { create_project_media team: t } + + export = ListExport.new(:media, '{}', t.id) + csv_url = export.generate_csv_and_send_email(create_user) + response = Net::HTTP.get_response(URI(csv_url)) + assert_equal 200, response.code.to_i + csv_content = CSV.parse(response.body, headers: true) + assert_equal 2, csv_content.size + assert_equal 2, export.number_of_rows + end + + test "should export feed CSV" do + t = create_team + f = create_feed team: t + 2.times { f.clusters << create_cluster } + + export = ListExport.new(:feed, { feed_id: f.id }.to_json, t.id) + csv_url = export.generate_csv_and_send_email(create_user) + response = Net::HTTP.get_response(URI(csv_url)) + assert_equal 200, response.code.to_i + csv_content = CSV.parse(response.body, headers: true) + assert_equal 2, csv_content.size + assert_equal 2, export.number_of_rows + end + + test "should export fact-checks CSV" do + t = create_team + 2.times do + pm = create_project_media team: t + cd = create_claim_description project_media: pm + create_fact_check claim_description: cd + end + + export = ListExport.new(:fact_check, '{}', t.id) + csv_url = export.generate_csv_and_send_email(create_user) + response = Net::HTTP.get_response(URI(csv_url)) + assert_equal 200, response.code.to_i + csv_content = CSV.parse(response.body, headers: true) + assert_equal 2, csv_content.size + assert_equal 2, export.number_of_rows + end + + test "should export explainers CSV" do + t = create_team + 2.times { create_explainer team: t } + + export = ListExport.new(:explainer, '{}', t.id) + csv_url = export.generate_csv_and_send_email(create_user) + response = Net::HTTP.get_response(URI(csv_url)) + assert_equal 200, response.code.to_i + csv_content = CSV.parse(response.body, headers: true) + assert_equal 2, csv_content.size + assert_equal 2, export.number_of_rows + end end