pagelapse 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3f8d6638ceb44da7aa0d6baaaf1c69e17da1cdfd
4
+ data.tar.gz: a0eec7989c94fb441e0605de10d224010703fe1a
5
+ SHA512:
6
+ metadata.gz: d1f965cab3bad214de6f0866b2a49a3833d99f763e48ca315e50cb3fcca6c68d2fcf7bc6a1d2ff6330de8e47c9ea9669f8be9347449bcd5d78b758eea9e7adfc
7
+ data.tar.gz: c14caa22ad972f86ec36b314fe1e2d4c22e5ce435e9b7a11c9be6cf57536992685ea2a7c1f4b15749e49e191426deec76a0de4451276da4db5aa360e12ee4d0f
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pagelapse.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Robert Lord
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Pagelapse
2
+
3
+ Generates time-lapses of websites, with ease. Inspirational background music not included.
4
+
5
+ ## Installation
6
+
7
+ Pagelapse needs phantomjs to take screenshots, so simply run:
8
+
9
+ $ brew install phantomjs
10
+
11
+ And then install pagelapse:
12
+
13
+ $ gem install pagelapse
14
+
15
+ ## Usage
16
+
17
+ Add a page to start capturing:
18
+
19
+ $ pagelapse record http://reddit.com
20
+
21
+ Pagelapse will check the website every 20 seconds for changes. There are some settings, too:
22
+
23
+ $ pagelapse record http://reddit.com --interval 60 --width 1200 --height 1000 --full-page false
24
+
25
+ To view the websites you've recorded in a nice web interface:
26
+
27
+ $ pagelapse view
28
+
29
+ To stop recording a page:
30
+
31
+ $ pagelapse stop http://reddit.com
32
+
33
+ To pause and resume the background server:
34
+
35
+ $ pagelapse pause
36
+ $ pagelapse resume
37
+
38
+ ## Contributing
39
+
40
+ 1. Fork it ( <http://github.com/lord/pagelapse/fork> )
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/pagelapse ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pagelapse'
3
+ Pagelapse.cli(ARGV)
@@ -0,0 +1,32 @@
1
+ # Parses lapsefiles
2
+
3
+ module Pagelapse
4
+ class Parser
5
+ def initialize(file)
6
+ puts "Starting Pagelapse #{Pagelapse::VERSION}"
7
+ @recorders = []
8
+ instance_eval File.read(file), file, 1
9
+ while @recorders.length > 0 do
10
+ @recorders.each do |r|
11
+ if r.ready?
12
+ print "Checking #{r.name}"
13
+ if r.capture
14
+ puts " - captured!"
15
+ else
16
+ puts ""
17
+ end
18
+ end
19
+ end
20
+ @recorders.reject! do |r|
21
+ r.expired?
22
+ end
23
+ end
24
+ end
25
+
26
+ def record(name, url, interval=20)
27
+ r = Pagelapse::Recorder.new(name, url)
28
+ yield r
29
+ @recorders << r
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,67 @@
1
+ require 'fileutils'
2
+ module Pagelapse
3
+ class Recorder
4
+ attr_accessor :interval, :duration, :timeout, :width, :height, :expiration
5
+ attr_reader :name, :url
6
+
7
+ def initialize(name, url)
8
+ @name = name
9
+ @url = url
10
+ @interval = 20
11
+ @duration = nil
12
+ @on_load = nil
13
+ @expiration = nil
14
+ @start = Time.now
15
+ @width = 1240
16
+ @height = 900
17
+ @timer = Time.new 0
18
+ @capture_if = nil
19
+ @save_if = nil
20
+ FileUtils.mkdir_p(File.join 'lapses', @name)
21
+ end
22
+
23
+ def before_capture(&block)
24
+ @on_load = block
25
+ end
26
+
27
+ def capture_if(&block)
28
+ @capture_if = block
29
+ end
30
+
31
+ def save_if(&block)
32
+ @save_if = block
33
+ end
34
+
35
+ def filename
36
+ File.join 'lapses', @name, "#{Time.now.to_i}.png"
37
+ end
38
+
39
+ # Returns true if timer is expired and ready to capture
40
+ def ready?
41
+ @timer < Time.now - @interval
42
+ end
43
+
44
+ # Returns true if recorder has expired
45
+ def expired?
46
+ Time.now > @start + @expiration if @expiration
47
+ end
48
+
49
+ def capture
50
+ @timer = Time.now
51
+ ws = Pagelapse::Screenshot.new
52
+ if @on_load
53
+ ws.start_session(&@on_load)
54
+ else
55
+ ws.start_session
56
+ end.capture(
57
+ @url,
58
+ filename,
59
+ width: @width,
60
+ height: @height,
61
+ timeout: @timeout,
62
+ capture_if: @capture_if,
63
+ save_if: @save_if
64
+ )
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,83 @@
1
+ require "capybara/dsl"
2
+ require "capybara/poltergeist"
3
+
4
+ module Pagelapse
5
+ # Thanks to http://www.cherpec.com/2013/04/30/capturing-web-page-screenshots-from-ruby/
6
+ # for the basis of this code
7
+ class Screenshot
8
+ include Capybara::DSL
9
+
10
+ # Captures a screenshot of +url+ saving it to +output_path+.
11
+ def capture(url, output_path, width: 1024, height: 768, full: false, timeout: false, capture_if: nil, save_if: nil)
12
+ # Browser settings
13
+ page.driver.resize(width, height)
14
+ page.driver.headers = {
15
+ "User-Agent" => "Pagelapse #{Pagelapse::VERSION}",
16
+ }
17
+
18
+ unless capture_if
19
+ capture_if = Proc.new do
20
+ page.driver.status_code == 200
21
+ end
22
+ end
23
+
24
+ unless save_if
25
+ save_if = Proc.new do |old_file, new_file|
26
+ Digest::MD5.file(old_file).hexdigest != Digest::MD5.file(new_file).hexdigest
27
+ end
28
+ end
29
+
30
+ # Open page
31
+ visit url
32
+
33
+ # Timeout
34
+ sleep timeout if timeout
35
+
36
+ if instance_eval(&capture_if)
37
+ old_file = last_file_next_to(output_path)
38
+
39
+ # Save screenshot
40
+ page.driver.save_screenshot(output_path, :full => full)
41
+
42
+ # If no old file, than always save
43
+ return true unless old_file
44
+
45
+ if save_if.call(old_file, output_path)
46
+ true
47
+ else
48
+ File.delete output_path
49
+ false
50
+ end
51
+ else
52
+ false
53
+ end
54
+ end
55
+
56
+ def start_session(&block)
57
+ Capybara.reset_sessions!
58
+ Capybara.current_session.instance_eval(&block) if block_given?
59
+ self
60
+ end
61
+
62
+ private
63
+ def last_file_next_to(file)
64
+ Dir[File.dirname(file) + "/*"].max_by {|f| File.mtime(f)}
65
+ end
66
+ end
67
+
68
+ # By default Capybara will try to boot a rack application
69
+ # automatically. You might want to switch off Capybara's
70
+ # rack server if you are running against a remote application
71
+ Capybara.run_server = false
72
+ Capybara.register_driver :poltergeist do |app|
73
+ Capybara::Poltergeist::Driver.new(app, {
74
+ # Raise JavaScript errors to Ruby
75
+ js_errors: false,
76
+ phantomjs_logger: File.open(File::NULL, "w"),
77
+ debug: false,
78
+ # Additional command line options for PhantomJS
79
+ phantomjs_options: ['--ignore-ssl-errors=yes'],
80
+ })
81
+ end
82
+ Capybara.current_driver = :poltergeist
83
+ end
@@ -0,0 +1,3 @@
1
+ module Pagelapse
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,79 @@
1
+ require 'sinatra'
2
+
3
+ module Pagelapse
4
+ class Viewer < Sinatra::Base
5
+ configure do
6
+ set :public_folder, 'lapses'
7
+ end
8
+ get '/' do
9
+ names = Dir['lapses/*']
10
+ names.map! do |filename|
11
+ filename.match(/^[^\/]+\/(.+)/)[1]
12
+ end
13
+ names.map! do |link|
14
+ "<p><a href='#{link}'>#{link}</a></p>"
15
+ end
16
+ names.join
17
+ end
18
+ get '/:name' do
19
+ files = Dir[File.join('lapses', params[:name], '*')]
20
+ files.map! do |filename|
21
+ filename.match(/^[^\/]+\/(.+)/)[1]
22
+ end
23
+ html = <<-HTML
24
+ <html>
25
+ <head>
26
+ <style>
27
+ body {
28
+ display: table;
29
+ width: 100%;
30
+ height: 100%;
31
+ }
32
+ #wrapper {
33
+ display: table-cell;
34
+ vertical-align: middle;
35
+ max-width: 100%;
36
+ max-height: 100%;
37
+ text-align: center;
38
+ }
39
+ </style>
40
+ <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
41
+ <script>
42
+ var imgs = [];
43
+ var urls = [];
44
+ function preloadImages(urls)
45
+ {
46
+ for(i in urls) {
47
+ var img = new Image();
48
+ img.src=urls[i];
49
+ imgs.push(img);
50
+ }
51
+ }
52
+ urls = <%= files.to_json %>;
53
+ preloadImages(urls);
54
+ function setImage(num) {
55
+ document.getElementById('image').src = urls[num];
56
+ }
57
+
58
+ $(function () {
59
+ $('body').mousemove(function (e) {
60
+ var pagewidth = $(window).width();
61
+ var mousex = event.pageX;
62
+ var num = Math.floor((mousex / pagewidth) * urls.length);
63
+ setImage(num);
64
+ });
65
+ });
66
+ </script>
67
+ </head>
68
+ <body>
69
+ <div id="wrapper">
70
+ <img id="image">
71
+ </div>
72
+ </body>
73
+ </html>
74
+ HTML
75
+
76
+ erb html, locals: {files: files}
77
+ end
78
+ end
79
+ end
data/lib/pagelapse.rb ADDED
@@ -0,0 +1,22 @@
1
+ require "pagelapse/version"
2
+ require "pagelapse/recorder"
3
+ require "pagelapse/screenshot"
4
+ require "pagelapse/parser"
5
+ require "pagelapse/viewer"
6
+
7
+ module Pagelapse
8
+
9
+ def self.cli(args)
10
+ case args[0]
11
+ when nil, 'start'
12
+ begin
13
+ Pagelapse::Parser.new "./Lapsefile"
14
+ rescue Interrupt
15
+ end
16
+ when 'view', 'viewer', 'server'
17
+ Pagelapse::Viewer.run!
18
+ else
19
+ puts "Unknown action #{args[0]}"
20
+ end
21
+ end
22
+ end
data/pagelapse.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pagelapse/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "pagelapse"
8
+ spec.version = Pagelapse::VERSION
9
+ spec.authors = ["Robert Lord"]
10
+ spec.email = ["robert@lord.io"]
11
+ spec.summary = %q{Generates time-lapses of websites, with ease.}
12
+ spec.description = %q{}
13
+ spec.homepage = "https://github.com/lord/pagelapse"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_dependency "capybara"
24
+ spec.add_dependency "poltergeist"
25
+ spec.add_dependency "sinatra"
26
+ end
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pagelapse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Robert Lord
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: capybara
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: poltergeist
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sinatra
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: ''
84
+ email:
85
+ - robert@lord.io
86
+ executables:
87
+ - pagelapse
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - Gemfile
93
+ - LICENSE.txt
94
+ - README.md
95
+ - Rakefile
96
+ - bin/pagelapse
97
+ - lib/pagelapse.rb
98
+ - lib/pagelapse/parser.rb
99
+ - lib/pagelapse/recorder.rb
100
+ - lib/pagelapse/screenshot.rb
101
+ - lib/pagelapse/version.rb
102
+ - lib/pagelapse/viewer.rb
103
+ - pagelapse.gemspec
104
+ homepage: https://github.com/lord/pagelapse
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.2.2
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: Generates time-lapses of websites, with ease.
128
+ test_files: []