pageflow-chart 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/CHANGELOG.md +8 -8
  4. data/app/assets/javascripts/pageflow/chart/editor.js +4 -3
  5. data/app/assets/javascripts/pageflow/chart/editor/config.js +7 -0
  6. data/app/assets/javascripts/pageflow/chart/editor/models/scraped_site.js +11 -50
  7. data/app/assets/javascripts/pageflow/chart/editor/views/configuration_editor.js +4 -1
  8. data/app/assets/javascripts/pageflow/chart/editor/views/embedded/iframe_embedded_view.js +8 -14
  9. data/app/assets/javascripts/pageflow/chart/editor/views/inputs/scraped_url_input_view.js +18 -39
  10. data/app/assets/stylesheets/pageflow/chart.scss +0 -1
  11. data/app/assets/stylesheets/pageflow/chart/editor.scss +2 -17
  12. data/app/assets/stylesheets/pageflow/chart/themes/default.scss +3 -0
  13. data/app/helpers/pageflow/chart/scraped_sites_helper.rb +1 -1
  14. data/app/jobs/pageflow/chart/scrape_site_job.rb +4 -1
  15. data/app/models/pageflow/chart/scraped_site.rb +35 -4
  16. data/app/views/pageflow/chart/editor/scraped_sites/_scraped_site.json.jbuilder +1 -0
  17. data/chart.gemspec +2 -2
  18. data/db/migrate/20190531141820_add_file_attributes_to_scraped_sites.rb +8 -0
  19. data/db/migrate/20190531145431_insert_file_usages_for_scraped_sites.rb +59 -0
  20. data/lib/pageflow/chart/downloader.rb +4 -1
  21. data/lib/pageflow/chart/page_type.rb +17 -0
  22. data/lib/pageflow/chart/refresh_tag_following_downloader.rb +3 -3
  23. data/lib/pageflow/chart/version.rb +1 -1
  24. data/spec/factories/scraped_sites.rb +16 -3
  25. data/spec/fixtures/all.css +3 -0
  26. data/spec/fixtures/all.js +1 -0
  27. data/spec/fixtures/data.csv +1 -0
  28. data/spec/fixtures/index.html +7 -0
  29. data/spec/integration/file_type_spec.rb +10 -0
  30. data/spec/jobs/pageflow/chart/scrape_site_job_spec.rb +14 -1
  31. data/spec/models/pageflow/chart/scraped_site_spec.rb +54 -0
  32. data/spec/pageflow/chart/downloader_spec.rb +13 -3
  33. data/spec/pageflow/chart/refresh_tag_following_downloader_spec.rb +23 -10
  34. metadata +20 -18
  35. data/app/assets/javascripts/pageflow/chart/editor/collections/scraped_sites_collection.js +0 -23
  36. data/app/assets/javascripts/pageflow/chart/editor/initializers/setup_collections.js +0 -1
  37. data/app/assets/javascripts/pageflow/chart/editor/templates/scraped_site_status.jst.ejs +0 -2
  38. data/app/assets/javascripts/pageflow/chart/editor/templates/url_input.jst.ejs +0 -7
  39. data/app/assets/javascripts/pageflow/chart/editor/views/scraped_site_status_view.js +0 -18
  40. data/app/controllers/pageflow/chart/application_controller.rb +0 -6
  41. data/app/controllers/pageflow/chart/scraped_sites_controller.rb +0 -25
  42. data/config/routes.rb +0 -3
  43. data/spec/controllers/pageflow/chart/scraped_sites_controller_spec.rb +0 -35
  44. data/spec/requests/scraping_site_spec.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69e58dc4cf527ebcc87f4fb761209cbc4c943f851dbbf317c34b1dc386b98b30
4
- data.tar.gz: d7e671cc45b645abe390dc01ba7db1a59b117dffc9ff873284d5864a9ec2cad7
3
+ metadata.gz: c3834ff2c73f8f33f70e43de722ed33e5a763ebe078ac4345074b8c7e49ebf3d
4
+ data.tar.gz: ab502c12ff710d698df3418fd572f3153d6981b0526cd9a635adc2ab1f8cbe64
5
5
  SHA512:
6
- metadata.gz: fe79c1727ae70e0184a93c568fc042edcbaddf86ab5d51fda3040dec8a037a57493233271cae64208735c9b3bbc9ece1d72dc5fe07a9e0feddf1d63dd421347d
7
- data.tar.gz: 29f7ecd19a0dbd9ed7c0f21db3be6bd1cb7a47d71282ea74e6b7077ce7fe28b16fc1453af7a6af3bb7dc78c53aa77c2cfc8be1c2b024b96eac9f94fc79403e68
6
+ metadata.gz: e326231888b882249d84824451b0449d598aca5b9c78f6842b20111ffe4c9c0b7079f3966cd0a654c4552cf59eb1c57442556c0cfe5370b194e46f1be1b12525
7
+ data.tar.gz: e14b7bacc6d778ca93764d48fc2f8fd5e484569cab89edf395848e478699fe0ab91ea6e0944315550aceae6e226428aa9bab678b0e9a9bb8887dfa5687b7c93d
@@ -8,6 +8,7 @@ cache: bundler
8
8
 
9
9
  services:
10
10
  - redis-server
11
+ - mysql
11
12
 
12
13
  script:
13
14
  - bin/rspec
@@ -1,16 +1,16 @@
1
1
  # CHANGELOG
2
2
 
3
- ### Version 2.1.0
3
+ ### Version 2.2.0
4
4
 
5
- 2019-04-08
5
+ 2019-11-04
6
6
 
7
- [Compare changes](https://github.com/codevise/pageflow-chart/compare/2-0-stable...v2.1.0)
7
+ [Compare changes](https://github.com/codevise/pageflow-chart/compare/2-1-stable...v2.2.0)
8
8
 
9
- - Adapt page dom for pageflow 14
10
- ([#51](https://github.com/codevise/pageflow-chart/pull/51))
11
- - Setup page type lint specs
12
- ([#50](https://github.com/codevise/pageflow-chart/pull/50))
9
+ #### Manual Update Step
10
+
11
+ - Turn scraped site into file type. Install migrations.
12
+ ([#55](https://github.com/codevise/pageflow-chart/pull/55))
13
13
 
14
14
  See
15
- [2-0-stable branch](https://github.com/codevise/pageflow-chart/blob/2-0-stable/CHANGELOG.md)
15
+ [2-1-stable branch](https://github.com/codevise/pageflow-chart/blob/2-1-stable/CHANGELOG.md)
16
16
  for previous changes.
@@ -1,9 +1,10 @@
1
1
  //= require_self
2
+
2
3
  //= require_tree ./editor/models
3
- //= require_tree ./editor/collections
4
4
  //= require_tree ./editor/views/inputs
5
5
  //= require_tree ./editor/templates
6
6
  //= require_tree ./editor/views
7
- //= require_tree ./editor/initializers
8
7
 
9
- pageflow.chart = pageflow.chart || {};
8
+ //= require ./editor/config
9
+
10
+ pageflow.chart = pageflow.chart || {};
@@ -0,0 +1,7 @@
1
+ pageflow.editor.fileTypes.register('pageflow_chart_scraped_sites', {
2
+ model: pageflow.chart.ScrapedSite,
3
+
4
+ matchUpload: function(upload) {
5
+ return false;
6
+ }
7
+ });
@@ -1,55 +1,16 @@
1
- pageflow.chart.ScrapedSite = Backbone.Model.extend({
2
- modelName: 'scraped_site',
3
- paramRoot: 'scraped_site',
4
-
5
- initialize: function() {
6
- this.listenTo(this, 'sync', function() {
7
- if (this.isProcessing() && !this.pollingInterval) {
8
- this.pollUntilScraped();
9
- }
10
- });
11
- },
12
-
13
- urlRoot: function() {
14
- return '/chart/scraped_sites';
15
- },
16
-
17
- isProcessed: function() {
18
- return this.get('state') === 'processed';
19
- },
20
-
21
- isProcessing: function() {
22
- return this.get('state') === 'processing';
23
- },
24
-
25
- isFailed: function() {
26
- return this.get('state') === 'processing_failed';
27
- },
28
-
29
- pollUntilScraped: function() {
30
- var model = this;
31
-
32
- if (model.isProcessed()) {
33
- return;
1
+ pageflow.chart.ScrapedSite = pageflow.ReusableFile.extend({
2
+ stages: [
3
+ {
4
+ name: 'processing',
5
+ activeStates: ['processing'],
6
+ finishedStates: ['processed'],
7
+ failedStates: ['processing_failed']
34
8
  }
9
+ ],
35
10
 
36
- model.pollingInterval = setInterval(poll, 1000);
11
+ readyState: 'processed',
37
12
 
38
- function stopPolling() {
39
- if (model.pollingInterval) {
40
- clearInterval(model.pollingInterval);
41
- model.pollingInterval = null;
42
- }
43
- }
44
-
45
- function poll() {
46
- model.fetch({
47
- success: function() {
48
- if (!model.isProcessing()) {
49
- stopPolling();
50
- }
51
- }
52
- });
53
- }
13
+ toJSON: function() {
14
+ return _.pick(this.attributes, 'url');
54
15
  }
55
16
  });
@@ -12,6 +12,9 @@ pageflow.ConfigurationEditorView.register('chart', {
12
12
  displayPropertyName: 'display_scraped_site_url',
13
13
  required: true
14
14
  });
15
+ this.input('scraped_site_id', pageflow.FileProcessingStateDisplayView, {
16
+ collection: 'pageflow_chart_scraped_sites'
17
+ });
15
18
  this.view(pageflow.chart.DatawrapperAdView);
16
19
  this.input('full_width', pageflow.CheckBoxInputView);
17
20
  this.group('background');
@@ -25,4 +28,4 @@ pageflow.ConfigurationEditorView.register('chart', {
25
28
  this.group('options');
26
29
  });
27
30
  }
28
- });
31
+ });
@@ -15,29 +15,23 @@ pageflow.chart.IframeEmbeddedView = Backbone.Marionette.View.extend({
15
15
  },
16
16
 
17
17
  updateScrapedSite: function() {
18
- var view = this;
19
-
20
18
  if (this.scrapedSite) {
21
19
  this.stopListening(this.scrapedSite);
22
20
  }
23
21
 
24
- var scrapedSiteId = this.model.get(this.options.propertyName);
25
-
26
- if (scrapedSiteId) {
27
- this.scrapedSite = pageflow.chart.scrapedSites.getOrFetch(scrapedSiteId, {
28
- success: function(scrapedSite) {
29
- view.updateAttributes(scrapedSite);
30
- }
31
- });
22
+ this.scrapedSite = this.model.getReference(this.options.propertyName,
23
+ 'pageflow_chart_scraped_sites');
24
+ this.updateAttributes();
32
25
 
26
+ if (this.scrapedSite) {
33
27
  this.listenTo(this.scrapedSite, 'change', this.updateAttributes);
34
28
  }
35
29
  },
36
30
 
37
- updateAttributes: function(scrapedSite) {
38
- scrapedSite = scrapedSite || this.scrapedSite;
31
+ updateAttributes: function() {
32
+ var scrapedSite = this.scrapedSite;
39
33
 
40
- if (scrapedSite && scrapedSite.isProcessed()) {
34
+ if (scrapedSite && scrapedSite.isReady()) {
41
35
  this.$el.attr('src', scrapedSite.get('html_file_url'));
42
36
 
43
37
  if (scrapedSite.get('use_custom_theme')) {
@@ -51,4 +45,4 @@ pageflow.chart.IframeEmbeddedView = Backbone.Marionette.View.extend({
51
45
  this.$el.attr('src', '');
52
46
  }
53
47
  }
54
- });
48
+ });
@@ -1,49 +1,28 @@
1
1
  pageflow.chart.ScrapedUrlInputView = pageflow.UrlInputView.extend({
2
- template: 'pageflow/chart/editor/templates/url_input',
2
+ className: 'chart_scraped_site_url_input_view',
3
3
 
4
- regions: {
5
- statusContainer: '.status_container'
6
- },
4
+ save: function() {
5
+ var url = this.ui.input.val();
7
6
 
8
- onLoad: function() {
9
- this.listenTo(this.model, 'change:' + this.options.propertyName, function() {
10
- this.updateScrapingStatus();
11
- });
7
+ if (url) {
8
+ var scrapedSite = pageflow
9
+ .entry
10
+ .getFileCollection('pageflow_chart_scraped_sites')
11
+ .findOrCreateBy({url: url});
12
12
 
13
- this.updateScrapingStatus();
14
- },
13
+ if (scrapedSite.isRetryable()) {
14
+ scrapedSite.retry();
15
+ }
15
16
 
16
- transformPropertyValue: function(url) {
17
- return $.Deferred(function(deferred) {
18
- pageflow.chart.scrapedSites.create(
19
- {
20
- url: url
21
- },
22
- {
23
- success: function(scrapedSite) {
24
- deferred.resolve(scrapedSite.id);
25
- }
26
- }
17
+ this.model.setReference(
18
+ this.options.propertyName,
19
+ scrapedSite
27
20
  );
28
- }).promise();
29
- },
30
-
31
- updateScrapingStatus: function() {
32
- var scrapedSite = this.getScrapedSite();
33
-
34
- if (scrapedSite) {
35
- this.statusContainer.show(new pageflow.chart.ScrapedSiteStatusView({
36
- model: scrapedSite
37
- }));
38
21
  }
39
22
  else {
40
- this.statusContainer.close();
41
- }
42
- },
43
-
44
- getScrapedSite: function() {
45
- if (this.model.has(this.options.propertyName)) {
46
- return pageflow.chart.scrapedSites.getOrFetch(this.model.get(this.options.propertyName));
23
+ this.model.unsetReference(
24
+ this.options.propertyName
25
+ );
47
26
  }
48
27
  }
49
- });
28
+ });
@@ -4,7 +4,6 @@
4
4
  .iframeWrapper {
5
5
  margin-bottom: 40px;
6
6
  pointer-events: all;
7
- height: 400px;
8
7
  position: relative;
9
8
 
10
9
  @media (min-width: 1500px) {
@@ -1,19 +1,5 @@
1
- .scraped_site_status {
2
- .state {
3
- display: none;
4
- }
5
-
6
- &.failed {
7
- .failed.state {
8
- display: block;
9
- }
10
- }
11
-
12
- &.processing {
13
- .processing.state {
14
- display: block;
15
- }
16
- }
1
+ .chart_scraped_site_url_input_view {
2
+ margin-bottom: 6px;
17
3
  }
18
4
 
19
5
  .datawrapper_ad {
@@ -23,6 +9,5 @@
23
9
  @include button('simple', #6AACF7);
24
10
  padding: 3px 10px;
25
11
  width: auto;
26
- float: right;
27
12
  }
28
13
  }
@@ -1,6 +1,7 @@
1
1
  @include pageflow-page-type-pictograms("chart");
2
2
 
3
3
  $chart-background: $basic-background-color;
4
+ $chart-iframe-base-height: 400px !default;
4
5
 
5
6
  .chart_page {
6
7
  .iframeWrapper {
@@ -8,5 +9,7 @@ $chart-background: $basic-background-color;
8
9
  opacity: 0.95;
9
10
  background-color: $chart-background;
10
11
  }
12
+
13
+ height: $chart-iframe-base-height;
11
14
  }
12
15
  }
@@ -12,7 +12,7 @@ module Pageflow
12
12
  }
13
13
 
14
14
  def scraped_site_iframe(scraped_site_id)
15
- scraped_site = ScrapedSite.find_by_id(scraped_site_id)
15
+ scraped_site = find_file_in_entry(ScrapedSite, scraped_site_id)
16
16
  data_attributes = {}
17
17
 
18
18
  if scraped_site
@@ -8,7 +8,8 @@ module Pageflow
8
8
  def perform_with_result(scraped_site,
9
9
  _options = {},
10
10
  downloader: downloader_for(scraped_site))
11
- downloader.load_following_refresh_tags(scraped_site.url) do |file|
11
+ downloader.load_following_refresh_tags(scraped_site.url,
12
+ raise_on_http_error: true) do |file|
12
13
  scraper = Scraper.new(file.read, Chart.config.scraper_options)
13
14
  scraped_site.html_file = StringIOWithContentType.new(
14
15
  scraper.html,
@@ -35,6 +36,8 @@ module Pageflow
35
36
  end
36
37
 
37
38
  :ok
39
+ rescue Downloader::HTTPError
40
+ :error
38
41
  end
39
42
 
40
43
  private
@@ -1,6 +1,8 @@
1
1
  module Pageflow
2
2
  module Chart
3
3
  class ScrapedSite < ActiveRecord::Base
4
+ include Pageflow::ReusableFile
5
+
4
6
  has_attached_file :javascript_file, Chart.config.paperclip_options(extension: 'js')
5
7
  has_attached_file :stylesheet_file, Chart.config.paperclip_options(extension: 'css')
6
8
  has_attached_file :html_file, Chart.config.paperclip_options(extension: 'html')
@@ -23,6 +25,10 @@ module Pageflow
23
25
  transition 'unprocessed' => 'processing'
24
26
  end
25
27
 
28
+ event :skip_reprocessing_imported_site do
29
+ transition 'unprocessed' => 'processed'
30
+ end
31
+
26
32
  event :reprocess do
27
33
  transition 'processed' => 'processing'
28
34
  transition 'processing_failed' => 'processing'
@@ -44,10 +50,6 @@ module Pageflow
44
50
  URI.join(url, 'data.csv').to_s
45
51
  end
46
52
 
47
- def as_json(*)
48
- super.merge(html_file_url: html_file_url)
49
- end
50
-
51
53
  def html_file_url
52
54
  return unless html_file.try(:path)
53
55
  if Chart.config.scraped_sites_root_url.present?
@@ -56,6 +58,35 @@ module Pageflow
56
58
  html_file.url
57
59
  end
58
60
  end
61
+
62
+ # ReusableFile-overrides:
63
+ def url
64
+ read_attribute(:url)
65
+ end
66
+
67
+ def retryable?
68
+ processing_failed?
69
+ end
70
+
71
+ def ready?
72
+ processed?
73
+ end
74
+
75
+ def publish!
76
+ if html_file.present?
77
+ skip_reprocessing_imported_site!
78
+ else
79
+ process!
80
+ end
81
+ end
82
+
83
+ def retry!
84
+ reprocess!
85
+ end
86
+
87
+ def attachments_for_export
88
+ [javascript_file, stylesheet_file, html_file, csv_file]
89
+ end
59
90
  end
60
91
  end
61
92
  end
@@ -0,0 +1 @@
1
+ json.call(scraped_site, :url, :html_file_url, :use_custom_theme)
@@ -18,11 +18,11 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.required_ruby_version = '~> 2.1'
20
20
 
21
- spec.add_runtime_dependency 'pageflow', '~> 14.x'
21
+ spec.add_runtime_dependency 'pageflow', '~> 15.x'
22
22
  spec.add_runtime_dependency 'nokogiri', '~> 1.0'
23
23
  spec.add_runtime_dependency 'pageflow-public-i18n', '~> 1.0'
24
24
 
25
- spec.add_development_dependency 'pageflow-support', '~> 14.x'
25
+ spec.add_development_dependency 'pageflow-support', '~> 15.x'
26
26
  spec.add_development_dependency 'bundler', ['>= 1.0', '< 3']
27
27
  spec.add_development_dependency 'rake', '~> 12.0'
28
28
  spec.add_development_dependency 'rspec-rails', '~> 3.0'
@@ -0,0 +1,8 @@
1
+ class AddFileAttributesToScrapedSites < ActiveRecord::Migration[5.2]
2
+ def change
3
+ add_reference :pageflow_chart_scraped_sites, :entry, index: true
4
+ add_column :pageflow_chart_scraped_sites, :rights, :string
5
+ add_column :pageflow_chart_scraped_sites, :parent_file_id, :integer
6
+ add_column :pageflow_chart_scraped_sites, :parent_file_model_type, :string
7
+ end
8
+ end
@@ -0,0 +1,59 @@
1
+ class InsertFileUsagesForScrapedSites < ActiveRecord::Migration[5.2]
2
+ # Pageflow models might have gotten out of sync with schema at this
3
+ # point. Use local models instead.
4
+ class MigratedPage < ActiveRecord::Base
5
+ self.table_name = 'pageflow_pages'
6
+
7
+ belongs_to :chapter, class_name: 'MigratedChapter'
8
+
9
+ serialize :configuration, JSON
10
+
11
+ def configuration
12
+ super || {}
13
+ end
14
+ end
15
+
16
+ class MigratedChapter < ActiveRecord::Base
17
+ self.table_name = 'pageflow_chapters'
18
+ belongs_to :storyline, class_name: 'MigratedStoryline'
19
+ end
20
+
21
+ class MigratedStoryline < ActiveRecord::Base
22
+ self.table_name = 'pageflow_storylines'
23
+ end
24
+
25
+ class MigratedFileUsage < ActiveRecord::Base
26
+ self.table_name = 'pageflow_file_usages'
27
+ end
28
+
29
+ def up
30
+ MigratedPage.where(template: 'chart').find_each do |page|
31
+ scraped_site_id = page.configuration['scraped_site_id']
32
+ next unless scraped_site_id
33
+
34
+ scraped_site = Pageflow::Chart::ScrapedSite.find_by_id(scraped_site_id)
35
+
36
+ unless scraped_site
37
+ puts "Scraped site #{scraped_site_id} not found"
38
+ next
39
+ end
40
+
41
+ revision_id = page&.chapter&.storyline&.revision_id
42
+
43
+ unless revision_id
44
+ puts "No revision_id for page #{page.id}"
45
+ next
46
+ end
47
+
48
+ MigratedFileUsage.create(file_id: scraped_site.id,
49
+ file_type: 'Pageflow::Chart::ScrapedSite',
50
+ revision_id: revision_id)
51
+ end
52
+ end
53
+
54
+ def down
55
+ MigratedFileUsage
56
+ .where(file_type: 'Pageflow::Chart::ScrapedSite')
57
+ .delete_all
58
+ end
59
+ end
@@ -6,15 +6,18 @@ module Pageflow
6
6
  class Downloader
7
7
  attr_reader :options
8
8
 
9
+ class HTTPError < StandardError; end
10
+
9
11
  def initialize(options = {})
10
12
  @options = options
11
13
  end
12
14
 
13
- def load(url)
15
+ def load(url, raise_on_http_error: false)
14
16
  file = open(make_absolute(url))
15
17
  yield(file)
16
18
  rescue OpenURI::HTTPError => exception
17
19
  Rails.logger.error "Exception loading url #{url}: #{exception.message}"
20
+ raise(HTTPError) if raise_on_http_error
18
21
  ensure
19
22
  file.close if file
20
23
  end
@@ -10,6 +10,23 @@ module Pageflow
10
10
  def json_seed_template
11
11
  'pageflow/chart/page_type.json.jbuilder'
12
12
  end
13
+
14
+ def file_types
15
+ [Chart.scraped_site_file_type]
16
+ end
17
+ end
18
+
19
+ def self.scraped_site_file_type
20
+ FileType.new(model: ScrapedSite,
21
+ editor_partial: 'pageflow/chart/editor/scraped_sites/scraped_site',
22
+ custom_attributes: {
23
+ url: {
24
+ permitted_create_param: true
25
+ },
26
+ use_custom_theme: {
27
+ permitted_create_param: false
28
+ }
29
+ })
13
30
  end
14
31
  end
15
32
  end
@@ -9,15 +9,15 @@ module Pageflow
9
9
  class TooManyRedirects < StandardError; end
10
10
  class NoUrlInRefreshMetaTag < StandardError; end
11
11
 
12
- def load_following_refresh_tags(url, redirect_count = 0, &block)
13
- load(url) do |file|
12
+ def load_following_refresh_tags(url, options = {}, redirect_count = 0, &block)
13
+ load(url, options) do |file|
14
14
  if (redirect_url = find_refresh_meta_tag_url(file.read))
15
15
  if redirect_count >= MAX_REDIRECT_COUNT
16
16
  raise TooManyRedirects, 'Too many redirects via refresh meta tags.'
17
17
  end
18
18
 
19
19
  redirect_url = ensure_absolute(redirect_url, url)
20
- return load_following_refresh_tags(redirect_url, redirect_count + 1, &block)
20
+ return load_following_refresh_tags(redirect_url, options, redirect_count + 1, &block)
21
21
  end
22
22
 
23
23
  file.rewind
@@ -1,5 +1,5 @@
1
1
  module Pageflow
2
2
  module Chart
3
- VERSION = '2.1.0'.freeze
3
+ VERSION = '2.2.0'.freeze
4
4
  end
5
5
  end
@@ -1,5 +1,18 @@
1
- FactoryBot.define do
2
- factory :scraped_site, class: 'Pageflow::Chart::ScrapedSite' do
3
- url 'MyString'
1
+ module Pageflow
2
+ module Chart
3
+ FactoryBot.define do
4
+ factory :scraped_site, class: 'Pageflow::Chart::ScrapedSite' do
5
+ url { 'MyString' }
6
+
7
+ trait :processed do
8
+ state { 'processed' }
9
+
10
+ javascript_file { File.open(Engine.root.join('spec', 'fixtures', 'all.js')) }
11
+ stylesheet_file { File.open(Engine.root.join('spec', 'fixtures', 'all.css')) }
12
+ html_file { File.open(Engine.root.join('spec', 'fixtures', 'index.html')) }
13
+ csv_file { File.open(Engine.root.join('spec', 'fixtures', 'data.csv')) }
14
+ end
15
+ end
16
+ end
4
17
  end
5
18
  end
@@ -0,0 +1,3 @@
1
+ .some {
2
+ color: #000
3
+ }
@@ -0,0 +1 @@
1
+ var chart = {};
@@ -0,0 +1 @@
1
+ some,values
@@ -0,0 +1,7 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Title</title>
5
+ </head>
6
+ <body></body>
7
+ </html>
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+ require 'pageflow/lint'
3
+
4
+ module Pageflow
5
+ module Chart
6
+ Pageflow::Lint.file_type(:scraped_site,
7
+ create_file_type: -> { Chart.scraped_site_file_type },
8
+ create_file: -> { create(:scraped_site, :processed) })
9
+ end
10
+ end
@@ -12,10 +12,23 @@ module Pageflow
12
12
 
13
13
  allow(Scraper).to receive(:new).and_return(scraper)
14
14
 
15
- expect(downloader).to receive(:load_following_refresh_tags).with('http://example.com')
15
+ expect(downloader).to receive(:load_following_refresh_tags)
16
+ .with('http://example.com',
17
+ raise_on_http_error: true)
16
18
 
17
19
  job.perform_with_result(scraped_site, {}, downloader: downloader)
18
20
  end
21
+
22
+ it 'returns :error on HTTP error' do
23
+ job = ScrapeSiteJob.new
24
+ scraped_site = create(:scraped_site, url: 'http://example.com/a')
25
+
26
+ stub_request(:get, 'http://example.com/a').to_return(status: 404, body: '')
27
+
28
+ result = job.perform_with_result(scraped_site)
29
+
30
+ expect(result).to eq(:error)
31
+ end
19
32
  end
20
33
  end
21
34
  end
@@ -26,5 +26,59 @@ module Pageflow::Chart
26
26
  expect(scraped_site_with_custom_theme.use_custom_theme).to eq(true)
27
27
  expect(scraped_site_without_custom_theme.use_custom_theme).to eq(false)
28
28
  end
29
+
30
+ it 'exposes all attachments for export' do
31
+ scraped_site = ScrapedSite.new(url: 'http://example.com/foo/index.html')
32
+
33
+ expect(scraped_site.attachments_for_export.map(&:name))
34
+ .to eq(%i[javascript_file stylesheet_file html_file csv_file])
35
+ end
36
+
37
+ describe '#publish!' do
38
+ it 'transitions state to processing for new site' do
39
+ scraped_site = ScrapedSite.new(url: 'http://example.com/foo/index.html')
40
+
41
+ scraped_site.publish!
42
+
43
+ expect(scraped_site.state).to eq('processing')
44
+ end
45
+
46
+ it 'transitions state to processed if html file is already set ' \
47
+ '(e.g. for sites that have been created via entry import)' do
48
+ scraped_site = ScrapedSite.new(url: 'http://example.com/foo/index.html',
49
+ html_file_file_name: 'index.html')
50
+
51
+ scraped_site.publish!
52
+
53
+ expect(scraped_site.state).to eq('processed')
54
+ end
55
+ end
56
+
57
+ describe '#retryable?' do
58
+ it 'is true if processing_failed' do
59
+ scraped_site = ScrapedSite.new(url: 'http://example.com/foo/index.html',
60
+ state: 'processing_failed')
61
+
62
+ expect(scraped_site).to be_retryable
63
+ end
64
+
65
+ it 'is false if processed' do
66
+ scraped_site = ScrapedSite.new(url: 'http://example.com/foo/index.html',
67
+ state: 'processed')
68
+
69
+ expect(scraped_site).not_to be_retryable
70
+ end
71
+ end
72
+
73
+ describe '#retry!' do
74
+ it 'transitions state to processing if processing_failed' do
75
+ scraped_site = ScrapedSite.new(url: 'http://example.com/foo/index.html',
76
+ state: 'processing_failed')
77
+
78
+ scraped_site.retry!
79
+
80
+ expect(scraped_site.state).to eq('processing')
81
+ end
82
+ end
29
83
  end
30
84
  end
@@ -17,17 +17,27 @@ module Pageflow
17
17
  expect(result).to eq("aaa")
18
18
  end
19
19
 
20
- it 'ignores HTTP response 404' do
20
+ it 'ignores HTTP response 404 by default' do
21
21
  downloader = Downloader.new
22
22
  result = ''
23
23
 
24
- stub_request(:get, "http://example.com/a").to_return(status: 404, body: 'aaa')
24
+ stub_request(:get, 'http://example.com/a').to_return(status: 404, body: 'aaa')
25
25
 
26
26
  downloader.load('http://example.com/a') do |io|
27
27
  result = io.read
28
28
  end
29
29
 
30
- expect(result).to eq("")
30
+ expect(result).to eq('')
31
+ end
32
+
33
+ it 'supports raising error on HTTP response 404 ' do
34
+ downloader = Downloader.new
35
+
36
+ stub_request(:get, 'http://example.com/a').to_return(status: 404, body: 'aaa')
37
+
38
+ expect {
39
+ downloader.load('http://example.com/a', raise_on_http_error: true)
40
+ }.to raise_error(Downloader::HTTPError)
31
41
  end
32
42
 
33
43
  it 'derives protocol from base_url' do
@@ -17,7 +17,7 @@ module Pageflow
17
17
  result = ''
18
18
 
19
19
  allow(downloader).to receive(:load)
20
- .with(original_url)
20
+ .with(original_url, {})
21
21
  .and_yield(StringIO.new(chart_html))
22
22
 
23
23
  refresh_tag_following_downloader.load_following_refresh_tags(original_url) do |file|
@@ -27,6 +27,19 @@ module Pageflow
27
27
  expect(result).to eq(chart_html)
28
28
  end
29
29
 
30
+ it 'passes raise_on_http_error to downloader' do
31
+ downloader = double(Downloader).as_null_object
32
+ refresh_tag_following_downloader = RefreshTagFollowingDownloader.new(downloader)
33
+
34
+ original_url = 'http://datawrapper.dwcdn.net/HPKfl/2/'
35
+
36
+ expect(downloader).to receive(:load)
37
+ .with(original_url, raise_on_http_error: true)
38
+
39
+ refresh_tag_following_downloader.load_following_refresh_tags(original_url,
40
+ raise_on_http_error: true)
41
+ end
42
+
30
43
  it 'looks for refresh meta tags and loads their url instead' do
31
44
  downloader = double(Downloader)
32
45
  refresh_tag_following_downloader = RefreshTagFollowingDownloader.new(downloader)
@@ -44,11 +57,11 @@ module Pageflow
44
57
  result = ''
45
58
 
46
59
  allow(downloader).to receive(:load)
47
- .with(original_url)
60
+ .with(original_url, {})
48
61
  .and_yield(StringIO.new(redirect_html))
49
62
 
50
63
  allow(downloader).to receive(:load)
51
- .with(target_url)
64
+ .with(target_url, {})
52
65
  .and_yield(StringIO.new(chart_html))
53
66
 
54
67
  refresh_tag_following_downloader.load_following_refresh_tags(original_url) do |file|
@@ -75,11 +88,11 @@ module Pageflow
75
88
  result = ''
76
89
 
77
90
  allow(downloader).to receive(:load)
78
- .with(original_url)
91
+ .with(original_url, {})
79
92
  .and_yield(StringIO.new(redirect_html))
80
93
 
81
94
  allow(downloader).to receive(:load)
82
- .with(target_url)
95
+ .with(target_url, {})
83
96
  .and_yield(StringIO.new(chart_html))
84
97
 
85
98
  refresh_tag_following_downloader.load_following_refresh_tags(original_url) do |file|
@@ -106,11 +119,11 @@ module Pageflow
106
119
  result = ''
107
120
 
108
121
  allow(downloader).to receive(:load)
109
- .with(original_url)
122
+ .with(original_url, {})
110
123
  .and_yield(StringIO.new(redirect_html))
111
124
 
112
125
  allow(downloader).to receive(:load)
113
- .with(target_url)
126
+ .with(target_url, {})
114
127
  .and_yield(StringIO.new(chart_html))
115
128
 
116
129
  refresh_tag_following_downloader.load_following_refresh_tags(original_url) do |file|
@@ -130,7 +143,7 @@ module Pageflow
130
143
  <html><head><meta http-equiv="REFRESH" content="0; url=#{original_url}"></head></html>
131
144
  HTML
132
145
 
133
- allow(downloader).to receive(:load).with(original_url) do |&block|
146
+ allow(downloader).to receive(:load).with(original_url, {}) do |&block|
134
147
  block.call(StringIO.new(redirect_html))
135
148
  end
136
149
 
@@ -149,7 +162,7 @@ module Pageflow
149
162
  <html><head><meta http-equiv="REFRESH" content="something strange"></head></html>
150
163
  HTML
151
164
 
152
- allow(downloader).to receive(:load).with(original_url).and_yield(StringIO.new(redirect_html))
165
+ allow(downloader).to receive(:load).with(original_url, {}).and_yield(StringIO.new(redirect_html))
153
166
 
154
167
  expect {
155
168
  refresh_tag_following_downloader.load_following_refresh_tags(original_url)
@@ -166,7 +179,7 @@ module Pageflow
166
179
  <html><head><meta http-equiv="REFRESH"></head></html>
167
180
  HTML
168
181
 
169
- allow(downloader).to receive(:load).with(original_url).and_yield(StringIO.new(redirect_html))
182
+ allow(downloader).to receive(:load).with(original_url, {}).and_yield(StringIO.new(redirect_html))
170
183
 
171
184
  expect {
172
185
  refresh_tag_following_downloader.load_following_refresh_tags(original_url)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pageflow-chart
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Codevise Solutions Ltd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-08 00:00:00.000000000 Z
11
+ date: 2019-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pageflow
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 14.x
19
+ version: 15.x
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 14.x
26
+ version: 15.x
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 14.x
61
+ version: 15.x
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 14.x
68
+ version: 15.x
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -180,28 +180,23 @@ files:
180
180
  - app/assets/javascripts/pageflow/chart.js
181
181
  - app/assets/javascripts/pageflow/chart/asset_urls.js.erb
182
182
  - app/assets/javascripts/pageflow/chart/editor.js
183
- - app/assets/javascripts/pageflow/chart/editor/collections/scraped_sites_collection.js
184
- - app/assets/javascripts/pageflow/chart/editor/initializers/setup_collections.js
183
+ - app/assets/javascripts/pageflow/chart/editor/config.js
185
184
  - app/assets/javascripts/pageflow/chart/editor/models/scraped_site.js
186
185
  - app/assets/javascripts/pageflow/chart/editor/templates/datawrapper_ad.jst.ejs
187
- - app/assets/javascripts/pageflow/chart/editor/templates/scraped_site_status.jst.ejs
188
- - app/assets/javascripts/pageflow/chart/editor/templates/url_input.jst.ejs
189
186
  - app/assets/javascripts/pageflow/chart/editor/views/configuration_editor.js
190
187
  - app/assets/javascripts/pageflow/chart/editor/views/datawrapper_ad_view.js
191
188
  - app/assets/javascripts/pageflow/chart/editor/views/embedded/iframe_embedded_view.js
192
189
  - app/assets/javascripts/pageflow/chart/editor/views/inputs/scraped_url_input_view.js
193
- - app/assets/javascripts/pageflow/chart/editor/views/scraped_site_status_view.js
194
190
  - app/assets/javascripts/pageflow/chart/page_type.js
195
191
  - app/assets/stylesheets/pageflow/chart.scss
196
192
  - app/assets/stylesheets/pageflow/chart/custom.scss
197
193
  - app/assets/stylesheets/pageflow/chart/editor.scss
198
194
  - app/assets/stylesheets/pageflow/chart/themes/default.scss
199
195
  - app/assets/stylesheets/pageflow/chart/transparent_background.css.erb
200
- - app/controllers/pageflow/chart/application_controller.rb
201
- - app/controllers/pageflow/chart/scraped_sites_controller.rb
202
196
  - app/helpers/pageflow/chart/scraped_sites_helper.rb
203
197
  - app/jobs/pageflow/chart/scrape_site_job.rb
204
198
  - app/models/pageflow/chart/scraped_site.rb
199
+ - app/views/pageflow/chart/editor/scraped_sites/_scraped_site.json.jbuilder
205
200
  - app/views/pageflow/chart/page.html.erb
206
201
  - app/views/pageflow/chart/page_type.json.jbuilder
207
202
  - bin/rails-cmd
@@ -210,9 +205,10 @@ files:
210
205
  - chart.gemspec
211
206
  - config/locales/de.yml
212
207
  - config/locales/en.yml
213
- - config/routes.rb
214
208
  - db/migrate/20140417112724_create_pageflow_chart_scraped_sites.rb
215
209
  - db/migrate/20160211085234_add_use_custom_theme_to_scraped_sites.rb
210
+ - db/migrate/20190531141820_add_file_attributes_to_scraped_sites.rb
211
+ - db/migrate/20190531145431_insert_file_usages_for_scraped_sites.rb
216
212
  - lib/generators/pageflow_chart/install/install_generator.rb
217
213
  - lib/pageflow/chart.rb
218
214
  - lib/pageflow/chart/configuration.rb
@@ -222,9 +218,13 @@ files:
222
218
  - lib/pageflow/chart/refresh_tag_following_downloader.rb
223
219
  - lib/pageflow/chart/scraper.rb
224
220
  - lib/pageflow/chart/version.rb
225
- - spec/controllers/pageflow/chart/scraped_sites_controller_spec.rb
226
221
  - spec/factories/scraped_sites.rb
222
+ - spec/fixtures/all.css
223
+ - spec/fixtures/all.js
224
+ - spec/fixtures/data.csv
227
225
  - spec/fixtures/datawrapper.html
226
+ - spec/fixtures/index.html
227
+ - spec/integration/file_type_spec.rb
228
228
  - spec/integration/page_type_spec.rb
229
229
  - spec/jobs/pageflow/chart/scrape_site_job_spec.rb
230
230
  - spec/models/pageflow/chart/scraped_site_spec.rb
@@ -232,7 +232,6 @@ files:
232
232
  - spec/pageflow/chart/downloader_spec.rb
233
233
  - spec/pageflow/chart/refresh_tag_following_downloader_spec.rb
234
234
  - spec/pageflow/chart/scraper_spec.rb
235
- - spec/requests/scraping_site_spec.rb
236
235
  - spec/spec_helper.rb
237
236
  - spec/support/active_job.rb
238
237
  - spec/support/factory_bot.rb
@@ -264,9 +263,13 @@ signing_key:
264
263
  specification_version: 4
265
264
  summary: Pagetype for Embedded Datawrapper Charts
266
265
  test_files:
267
- - spec/controllers/pageflow/chart/scraped_sites_controller_spec.rb
268
266
  - spec/factories/scraped_sites.rb
267
+ - spec/fixtures/all.css
268
+ - spec/fixtures/all.js
269
+ - spec/fixtures/data.csv
269
270
  - spec/fixtures/datawrapper.html
271
+ - spec/fixtures/index.html
272
+ - spec/integration/file_type_spec.rb
270
273
  - spec/integration/page_type_spec.rb
271
274
  - spec/jobs/pageflow/chart/scrape_site_job_spec.rb
272
275
  - spec/models/pageflow/chart/scraped_site_spec.rb
@@ -274,7 +277,6 @@ test_files:
274
277
  - spec/pageflow/chart/downloader_spec.rb
275
278
  - spec/pageflow/chart/refresh_tag_following_downloader_spec.rb
276
279
  - spec/pageflow/chart/scraper_spec.rb
277
- - spec/requests/scraping_site_spec.rb
278
280
  - spec/spec_helper.rb
279
281
  - spec/support/active_job.rb
280
282
  - spec/support/factory_bot.rb
@@ -1,23 +0,0 @@
1
- pageflow.chart.ScrapedSitesCollection = Backbone.Collection.extend({
2
- model: pageflow.chart.ScrapedSite,
3
-
4
- name: 'scraped_sites',
5
-
6
- getOrFetch: function(id, options) {
7
- options = options || {};
8
- var model = this.get(id);
9
-
10
- if (model) {
11
- if (options.success) {
12
- options.success(model);
13
- }
14
- }
15
- else {
16
- model = new pageflow.chart.ScrapedSite({id: id});
17
- this.add(model);
18
- model.fetch(options);
19
- }
20
-
21
- return model;
22
- }
23
- });
@@ -1 +0,0 @@
1
- pageflow.chart.scrapedSites = new pageflow.chart.ScrapedSitesCollection();
@@ -1,2 +0,0 @@
1
- <p class="processing state validation pending"><%= I18n.t('pageflow.chart.editor.templates.scraped_site_status.pending') %></p>
2
- <p class="failed state validation failed"><%= I18n.t('pageflow.chart.editor.templates.scraped_site_status.failed') %></p>
@@ -1,7 +0,0 @@
1
- <label>
2
- <span class="name"></span>
3
- <span class="inline_help"></span>
4
- </label>
5
- <input type="text" />
6
- <div class="validation"></div>
7
- <div class="status_container"></div>
@@ -1,18 +0,0 @@
1
- pageflow.chart.ScrapedSiteStatusView = Backbone.Marionette.ItemView.extend({
2
- template: 'pageflow/chart/editor/templates/scraped_site_status',
3
- className: 'scraped_site_status',
4
-
5
- modelEvents: {
6
- change: 'update'
7
- },
8
-
9
- onRender: function() {
10
- this.update();
11
- },
12
-
13
- update: function() {
14
- this.$el.toggleClass('processed', this.model.isProcessed());
15
- this.$el.toggleClass('failed', this.model.isFailed());
16
- this.$el.toggleClass('processing', this.model.isProcessing());
17
- }
18
- });
@@ -1,6 +0,0 @@
1
- module Pageflow
2
- module Chart
3
- class ApplicationController < ActionController::Base
4
- end
5
- end
6
- end
@@ -1,25 +0,0 @@
1
- module Pageflow
2
- module Chart
3
- class ScrapedSitesController < Chart::ApplicationController
4
- respond_to :json
5
-
6
- def create
7
- scraped_site = ScrapedSite.create!(scraped_site_params)
8
- scraped_site.process!
9
-
10
- respond_with(scraped_site)
11
- end
12
-
13
- def show
14
- scraped_site = ScrapedSite.find(params[:id])
15
- respond_with(scraped_site)
16
- end
17
-
18
- protected
19
-
20
- def scraped_site_params
21
- params.require(:scraped_site).permit(:url)
22
- end
23
- end
24
- end
25
- end
@@ -1,3 +0,0 @@
1
- Pageflow::Chart::Engine.routes.draw do
2
- resources :scraped_sites, only: [:create, :show]
3
- end
@@ -1,35 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Pageflow
4
- module Chart
5
- describe ScrapedSitesController do
6
- describe '#create' do
7
- routes { Pageflow::Chart::Engine.routes }
8
-
9
- it 'responds with success' do
10
- post(:create, params: {scraped_site: {url: "http://example.com/chart.html"}}, format: 'json')
11
-
12
- expect(response.status).to eq(201)
13
- end
14
-
15
- it 'creates scraped site' do
16
- expect {
17
- post(:create, params: {scraped_site: {url: "http://example.com/chart.html"}}, format: 'json')
18
- }.to change { ScrapedSite.count }
19
- end
20
- end
21
-
22
- describe '#show' do
23
- routes { Pageflow::Chart::Engine.routes }
24
-
25
- it 'responds with success' do
26
- scraped_site = create(:scraped_site, state: 'unprocessed')
27
-
28
- get(:show, params: { id: scraped_site.id }, format: 'json')
29
-
30
- expect(response.status).to eq(200)
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module Pageflow
4
- module Chart
5
- describe 'scraping site', perform_jobs: true do
6
- before do
7
- stub_request(:get, "http://example.com/chart.html")
8
- .to_return(:status => 200, :body => File.read('spec/fixtures/datawrapper.html'))
9
- stub_request(:get, /js$|css$|csv$/)
10
- .to_return(:status => 200, :body => 'file')
11
- end
12
-
13
- it 'downloads html and dependencies' do
14
- post('/charts/scraped_sites.json', params: {scraped_site: {url: 'http://example.com/chart.html'}})
15
-
16
- expect(ScrapedSite.first.html_file).to be_present
17
- expect(ScrapedSite.first.javascript_file).to be_present
18
- expect(ScrapedSite.first.stylesheet_file).to be_present
19
- expect(ScrapedSite.first.csv_file).to be_present
20
- end
21
- end
22
- end
23
- end