pageflow-chart 0.1.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 (100) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +21 -0
  3. data/CHANGELOG.md +7 -0
  4. data/Gemfile +10 -0
  5. data/README.md +91 -0
  6. data/Rakefile +20 -0
  7. data/app/assets/images/pageflow/chart/fs_close_sprite.png +0 -0
  8. data/app/assets/images/pageflow/chart_pictogram.png +0 -0
  9. data/app/assets/images/pageflow/chart_pictogram_small.png +0 -0
  10. data/app/assets/images/pageflow/chart_sprite.png +0 -0
  11. data/app/assets/images/pageflow/ov-chart.png +0 -0
  12. data/app/assets/javascripts/pageflow/chart.js +5 -0
  13. data/app/assets/javascripts/pageflow/chart/asset_urls.js.erb +3 -0
  14. data/app/assets/javascripts/pageflow/chart/editor.js +9 -0
  15. data/app/assets/javascripts/pageflow/chart/editor/collections/scraped_sites_collection.js +23 -0
  16. data/app/assets/javascripts/pageflow/chart/editor/initializers/setup_collections.js +1 -0
  17. data/app/assets/javascripts/pageflow/chart/editor/models/scraped_site.js +55 -0
  18. data/app/assets/javascripts/pageflow/chart/editor/templates/scraped_site_status.jst.ejs +2 -0
  19. data/app/assets/javascripts/pageflow/chart/editor/templates/url_input.jst.ejs +7 -0
  20. data/app/assets/javascripts/pageflow/chart/editor/views/configuration_editor.js +26 -0
  21. data/app/assets/javascripts/pageflow/chart/editor/views/embedded/iframe_embedded_view.js +47 -0
  22. data/app/assets/javascripts/pageflow/chart/editor/views/inputs/scraped_url_input_view.js +49 -0
  23. data/app/assets/javascripts/pageflow/chart/editor/views/scraped_site_status_view.js +18 -0
  24. data/app/assets/javascripts/pageflow/chart/page_type.js +152 -0
  25. data/app/assets/stylesheets/pageflow/chart.css.scss +130 -0
  26. data/app/assets/stylesheets/pageflow/chart/custom.css.scss +209 -0
  27. data/app/assets/stylesheets/pageflow/chart/editor.css.scss +17 -0
  28. data/app/assets/stylesheets/pageflow/chart/themes/default.css.scss +10 -0
  29. data/app/controllers/pageflow/chart/application_controller.rb +6 -0
  30. data/app/controllers/pageflow/chart/scraped_sites_controller.rb +25 -0
  31. data/app/helpers/pageflow/chart/scraped_sites_helper.rb +13 -0
  32. data/app/jobs/pageflow/chart/scrape_site_job.rb +59 -0
  33. data/app/models/pageflow/chart/scraped_site.rb +51 -0
  34. data/app/views/pageflow/chart/page.html +41 -0
  35. data/app/views/pageflow/chart/page_type.json.jbuilder +2 -0
  36. data/bin/rails +8 -0
  37. data/chart.gemspec +30 -0
  38. data/config/locales/de.yml +40 -0
  39. data/config/locales/en.yml +22 -0
  40. data/config/routes.rb +3 -0
  41. data/db/migrate/20140417112724_create_pageflow_chart_scraped_sites.rb +14 -0
  42. data/lib/pageflow/chart.rb +21 -0
  43. data/lib/pageflow/chart/configuration.rb +63 -0
  44. data/lib/pageflow/chart/downloader.rb +53 -0
  45. data/lib/pageflow/chart/engine.rb +17 -0
  46. data/lib/pageflow/chart/page_type.rb +15 -0
  47. data/lib/pageflow/chart/scraper.rb +107 -0
  48. data/spec/controllers/pageflow/chart/scraped_sites_controller_spec.rb +35 -0
  49. data/spec/dummy/README.rdoc +28 -0
  50. data/spec/dummy/Rakefile +6 -0
  51. data/spec/dummy/app/assets/images/.keep +0 -0
  52. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  53. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  54. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  55. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  56. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  57. data/spec/dummy/app/mailers/.keep +0 -0
  58. data/spec/dummy/app/models/.keep +0 -0
  59. data/spec/dummy/app/models/concerns/.keep +0 -0
  60. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  61. data/spec/dummy/bin/bundle +3 -0
  62. data/spec/dummy/bin/rails +4 -0
  63. data/spec/dummy/bin/rake +4 -0
  64. data/spec/dummy/config.ru +4 -0
  65. data/spec/dummy/config/application.rb +22 -0
  66. data/spec/dummy/config/boot.rb +5 -0
  67. data/spec/dummy/config/database.yml +25 -0
  68. data/spec/dummy/config/environment.rb +5 -0
  69. data/spec/dummy/config/environments/development.rb +29 -0
  70. data/spec/dummy/config/environments/production.rb +80 -0
  71. data/spec/dummy/config/environments/test.rb +36 -0
  72. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  73. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  74. data/spec/dummy/config/initializers/inflections.rb +16 -0
  75. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  76. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  77. data/spec/dummy/config/initializers/session_store.rb +3 -0
  78. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  79. data/spec/dummy/config/locales/en.yml +23 -0
  80. data/spec/dummy/config/routes.rb +4 -0
  81. data/spec/dummy/db/schema.rb +39 -0
  82. data/spec/dummy/lib/assets/.keep +0 -0
  83. data/spec/dummy/public/404.html +58 -0
  84. data/spec/dummy/public/422.html +58 -0
  85. data/spec/dummy/public/500.html +57 -0
  86. data/spec/dummy/public/favicon.ico +0 -0
  87. data/spec/factories/scraped_sites.rb +5 -0
  88. data/spec/fixtures/datawrapper.html +121 -0
  89. data/spec/jobs/pageflow/chart/scrape_site_job_spec.rb +22 -0
  90. data/spec/models/pageflow/chart/scraped_site_spec.rb +19 -0
  91. data/spec/pageflow/chart/downloader_spec.rb +90 -0
  92. data/spec/pageflow/chart/scraper_spec.rb +179 -0
  93. data/spec/requests/scraping_site_spec.rb +23 -0
  94. data/spec/spec_helper.rb +20 -0
  95. data/spec/support/factory_girl.rb +5 -0
  96. data/spec/support/html_fragment.rb +13 -0
  97. data/spec/support/paperclip.rb +11 -0
  98. data/spec/support/resque.rb +20 -0
  99. data/spec/support/webmock.rb +11 -0
  100. metadata +363 -0
@@ -0,0 +1,17 @@
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
+ }
17
+ }
@@ -0,0 +1,10 @@
1
+ $chart-background: $basic-background-color;
2
+
3
+ .chart_page {
4
+ .iframeWrapper {
5
+ &:before {
6
+ opacity: 0.95;
7
+ background-color: $chart-background;
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ module Pageflow
2
+ module Chart
3
+ class ApplicationController < ActionController::Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,25 @@
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
@@ -0,0 +1,13 @@
1
+ module Pageflow
2
+ module Chart
3
+ module ScrapedSitesHelper
4
+ def scraped_site_url(scraped_site_id)
5
+ scraped_site = ScrapedSite.find_by_id(scraped_site_id)
6
+
7
+ if scraped_site
8
+ scraped_site.html_file_url
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,59 @@
1
+ module Pageflow
2
+ module Chart
3
+ class ScrapeSiteJob
4
+ extend StateMachineJob
5
+ @queue = :scraping
6
+
7
+ attr_reader :downloader
8
+
9
+ def initialize(downloader)
10
+ @downloader = downloader
11
+ end
12
+
13
+ def perform(scraped_site)
14
+ downloader.load(scraped_site.url) do |file|
15
+ scraper = Scraper.new(file.read, Chart.config.scraper_options)
16
+ scraped_site.html_file = StringIOWithContentType.new(
17
+ scraper.html,
18
+ file_name: 'file.html',
19
+ content_type: 'text/html'
20
+ )
21
+
22
+ downloader.load_all(scraper.javascript_urls, extension: '.js', separator: "\n;") do |file|
23
+ scraped_site.javascript_file = file
24
+ end
25
+
26
+ downloader.load_all(scraper.stylesheet_urls, extension: '.css', separator: "\n;") do |file|
27
+ scraped_site.stylesheet_file = file
28
+ end
29
+ end
30
+
31
+ downloader.load(scraped_site.csv_url) do |file|
32
+ scraped_site.csv_file = file
33
+ end
34
+
35
+ :ok
36
+ end
37
+
38
+ def self.perform_with_result(scraped_site, options = {})
39
+ # This is were the downloader passed to `initialize` is created.
40
+ new(Downloader.new(base_url: scraped_site.url)).perform(scraped_site)
41
+ end
42
+ end
43
+
44
+ class StringIOWithContentType < StringIO
45
+ def initialize(string, options)
46
+ super(string)
47
+ @options = options
48
+ end
49
+
50
+ def content_type
51
+ @options.fetch(:content_type)
52
+ end
53
+
54
+ def original_filename
55
+ @options.fetch(:file_name)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,51 @@
1
+ module Pageflow
2
+ module Chart
3
+ class ScrapedSite < ActiveRecord::Base
4
+ has_attached_file :javascript_file, Chart.config.paperclip_options(extension: 'js')
5
+ has_attached_file :stylesheet_file, Chart.config.paperclip_options(extension: 'css')
6
+ has_attached_file :html_file, Chart.config.paperclip_options(extension: 'html')
7
+ has_attached_file :csv_file, Chart.config.paperclip_options(basename: 'data', extension: 'csv')
8
+
9
+ state_machine initial: 'unprocessed' do
10
+ extend StateMachineJob::Macro
11
+
12
+ state 'unprocessed'
13
+ state 'processing'
14
+ state 'processing_failed'
15
+ state 'processed'
16
+
17
+ event :process do
18
+ transition 'unprocessed' => 'processing'
19
+ end
20
+
21
+ event :reprocess do
22
+ transition 'processed' => 'processing'
23
+ transition 'processing_failed' => 'processing'
24
+ end
25
+
26
+ job ScrapeSiteJob do
27
+ on_enter 'processing'
28
+ result ok: 'processed'
29
+ result error: 'processing_failed'
30
+ end
31
+ end
32
+
33
+ def csv_url
34
+ URI.join(url, 'data.csv').to_s
35
+ end
36
+
37
+ def as_json(*)
38
+ super.merge(html_file_url: html_file_url)
39
+ end
40
+
41
+ def html_file_url
42
+ return unless html_file.try(:path)
43
+ if Chart.config.scraped_sites_root_url.present?
44
+ File.join(Chart.config.scraped_sites_root_url, html_file.path)
45
+ else
46
+ html_file.url
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,41 @@
1
+ <div class="blackLayer"></div>
2
+ <div class="content_and_background chart_page">
3
+ <div class="backgroundArea">
4
+ <%= background_image_div(configuration, 'background_image') %>
5
+ <%= shadow_div :opacity => configuration['gradient_opacity'] %>
6
+ </div>
7
+
8
+ <div class="content">
9
+ <div class="iframeWrapper">
10
+ <iframe data-src="<%= scraped_site_url(configuration['scraped_site_id']) %>"
11
+ style="width: 100%; height: 100%"
12
+ name="°"
13
+ scrolling="auto"
14
+ frameborder="0"
15
+ align="aus"
16
+ marginheight="15"
17
+ marginwidth="15"
18
+ allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true">
19
+ </iframe>
20
+ <div class="iframe_overlay"></div>
21
+ <div class="bigscreen_toggler" tabindex="4" title="<%= t('.toggle_title') %>"><%= t('.toggle') %></div>
22
+ </div>
23
+ <div class="scroller">
24
+ <div>
25
+ <div class="contentWrapper">
26
+ <div class="page_header">
27
+ <h2>
28
+ <span class="tagline"><%= configuration['tagline'] %></span>
29
+ <span class="title"><%= configuration['title'] %></span>
30
+ <span class="subtitle"><%= configuration['subtitle'] %></span>
31
+ </h2>
32
+ <%= background_image_tag(configuration['background_image_id'], {"class" => "print_image"}) %>
33
+ </div>
34
+ <div class="contentText">
35
+ <p><%= raw configuration['text'] %></p>
36
+ </div>
37
+ </div>
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
@@ -0,0 +1,2 @@
1
+ json.key_format! camelize: :lower
2
+ json.supported_hosts Pageflow::Chart.config.supported_hosts
data/bin/rails ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/pageflow/chart/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
data/chart.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "pageflow-chart"
5
+ spec.version = "0.1.0"
6
+ spec.authors = ["Tim Fischbach"]
7
+ spec.email = ["tfischbach@codevise.de"]
8
+ spec.summary = "Pagetype for Embedded Datawrapper Charts"
9
+ spec.homepage = ""
10
+ spec.license = "MIT"
11
+
12
+ spec.files = `git ls-files`.split($/)
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.require_paths = ["lib"]
16
+
17
+ spec.add_runtime_dependency "pageflow", "~> 0.7"
18
+ spec.add_runtime_dependency "nokogiri"
19
+ spec.add_runtime_dependency "paperclip"
20
+ spec.add_runtime_dependency "state_machine"
21
+ spec.add_runtime_dependency "state_machine_job"
22
+ spec.add_runtime_dependency 'i18n-js'
23
+
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rspec-rails", "~> 2.0"
27
+ spec.add_development_dependency 'factory_girl_rails'
28
+ spec.add_development_dependency "sqlite3"
29
+ spec.add_development_dependency "webmock"
30
+ end
@@ -0,0 +1,40 @@
1
+ de:
2
+ activerecord:
3
+ attributes:
4
+ pageflow/page:
5
+ scraped_site_id: Diagramm URL
6
+ pageflow:
7
+ chart:
8
+ editor:
9
+ templates:
10
+ scraped_site_status:
11
+ failed: Beim Herunterladen des Diagramms ist ein Fehler aufgetreten.
12
+ pending: Diagramm wird heruntergeladen...
13
+ help_entries:
14
+ page_type:
15
+ menu_item: Diagramm
16
+ text: ! '# Diagramm
17
+
18
+
19
+ Einbindung von DataWrapper-Diagrammen
20
+
21
+
22
+ Hier kannst Du Deinen Pageflow um animierte Infografiken ergänzen. Eingebettet ist das
23
+
24
+ Diagramm in ein Hintergrund-Bild und Text. Die Infografik lässt sich durch Klicken
25
+
26
+ vergrössern.
27
+
28
+
29
+ Dein Diagramm musst Du allerdings zuvor extern erstellen und einen entsprechenden Link generieren. Unter www.datawrapper.de findest Du Beispiele und die Konditionen, um
30
+
31
+ diesen Dienst in Anspruch zu nehmen.
32
+
33
+
34
+ Typische Anwendungsbeispiele: Statistiken, Diagramme, Zahlen&Fakten'
35
+ page:
36
+ toggle: Ansicht vergrößern bzw. verkleinern
37
+ toggle_title: Ansicht vergrößern bzw. verkleinern
38
+ page_type_category_name: Daten und Diagramme
39
+ page_type_description: Einbindung von Diagrammen, die mit DataWrapper erstellt wurden
40
+ page_type_name: Diagramm
@@ -0,0 +1,22 @@
1
+ en:
2
+ activerecord:
3
+ attributes:
4
+ pageflow/page:
5
+ scraped_site_id: Chart URL
6
+ pageflow:
7
+ chart:
8
+ editor:
9
+ templates:
10
+ scraped_site_status:
11
+ failed: Chart download failed.
12
+ pending: Downloading chart...
13
+ help_entries:
14
+ page_type:
15
+ menu_item: Chart
16
+ text: ! "# Chart\n\nIntegration of a DataWrapper-Diagram\n\nHere you can add animated infographics to your Pageflow. The diagram is embedded into a background-picture and text. To enlarge the graphic you simply have to click on it. \n\nBut first of all you have to create your graphic externally and generate a link. You can find examples and requirements for this under www.datawrapper.de.\n\nExamples of application: statistics, diagrams, numbers & facts"
17
+ page:
18
+ toggle: Toggle
19
+ toggle_title: Toggle
20
+ page_type_category_name: Data and Charts
21
+ page_type_description: Embedded DataWrapper chart
22
+ page_type_name: Chart
data/config/routes.rb ADDED
@@ -0,0 +1,3 @@
1
+ Pageflow::Chart::Engine.routes.draw do
2
+ resources :scraped_sites, only: [:create, :show]
3
+ end
@@ -0,0 +1,14 @@
1
+ class CreatePageflowChartScrapedSites < ActiveRecord::Migration
2
+ def change
3
+ create_table :pageflow_chart_scraped_sites do |t|
4
+ t.string :url
5
+ t.string :state
6
+ t.attachment :html_file
7
+ t.attachment :javascript_file
8
+ t.attachment :stylesheet_file
9
+ t.attachment :csv_file
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ require 'paperclip'
2
+ require 'state_machine'
3
+ require 'state_machine_job'
4
+
5
+ require 'pageflow/chart/engine'
6
+
7
+ module Pageflow
8
+ module Chart
9
+ def self.config
10
+ @config ||= Chart::Configuration.new
11
+ end
12
+
13
+ def self.configure(&block)
14
+ block.call(config)
15
+ end
16
+
17
+ def self.page_type
18
+ Chart::PageType.new
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,63 @@
1
+ module Pageflow
2
+ module Chart
3
+ class Configuration
4
+ # Options to pass to Scraper when it is created in ScrapedSiteJob
5
+ attr_reader :scraper_options
6
+
7
+ # paperclip_base_path is a prefix for the paperclip options path
8
+ attr_accessor :paperclip_base_path
9
+
10
+ # If present scraped_sites_root_url replaces the host/domain-name of the
11
+ # URL paperclip returns for the scraped HTML file.
12
+ #
13
+ # This can be used to circumvent the same-domain policy by setting it
14
+ # to ie "/datawrapper" and redirecting from there to the S3 host alias that holds
15
+ # the files.
16
+ attr_accessor :scraped_sites_root_url
17
+
18
+ # Default options for paperclip attachments which are supposed to
19
+ # use s3 storage. All options allowed in paperclip has_attached_file
20
+ # calls are allowed.
21
+ # This defaults to the configuration in `config/initializers/pageflow.rb` by the same name.
22
+ #
23
+ # @param [Hash] opts
24
+ # @option opts [Array<Regexp>] :head_script_blacklist Script tags in page head are ignored if they match any of this list of regexes.
25
+ # @option opts [Array<Regexp>] :inline_script_blacklist Inline script tags are ignored if they match any of this list of regexes.
26
+ # @option opts [Array<String>] :selector_blacklist HTML-elements matched by selectors in this list will not be scraped.
27
+ # @return [Hash]
28
+ attr_accessor :paperclip_s3_default_options
29
+
30
+ # White list of URL prefixes (including protocol) of scraped
31
+ # sites.
32
+ # @return [Array<String>]
33
+ attr_reader :supported_hosts
34
+
35
+ def initialize
36
+ @scraper_options = {
37
+ head_script_blacklist: [/piwik/],
38
+ inline_script_blacklist: [/piwik/],
39
+ selector_blacklist: ['body .noscript']
40
+ }
41
+ @paperclip_s3_default_options = {}
42
+ @paperclip_base_path = ':host'
43
+ @scraped_sites_root_url = nil
44
+ @supported_hosts = ['http://cf.datawrapper.de']
45
+ end
46
+
47
+ # @api private
48
+ def paperclip_options(options = {})
49
+ Pageflow.config.paperclip_s3_default_options
50
+ .deep_merge(default_paperclip_path_options(options))
51
+ .deep_merge(paperclip_s3_default_options)
52
+ end
53
+
54
+ private
55
+
56
+ def default_paperclip_path_options(options)
57
+ {
58
+ path: File.join(paperclip_base_path, ":class/:id_partition/#{options.fetch(:basename, 'all')}.#{options.fetch(:extension)}")
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end