pageflow-chart 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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