wgif 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c2b920dfa55567f79e781514cdbec115e06c044
4
- data.tar.gz: 9e8dea99fdfd3f316538be45f6f5508e77470aed
3
+ metadata.gz: eda7edccc313c6f58f2bb806200b69011f1904c1
4
+ data.tar.gz: a2197e273c936b595a8b498e0c43deb43527ef23
5
5
  SHA512:
6
- metadata.gz: 2eeab9f6ee176bf8b412f72a722dfd9dcc8156107f760591602465a63bbee4f86dc8ae0ad7ba3d7c9c1ddbd0d282b763015eb5ba060ed61d8116be542811b9a5
7
- data.tar.gz: e5c3125c238f0b92b25531371287170b87084ee7e80392521c32134f4c4e8082f03fd6a9bcee811f6bae6115b423310be3fd46fce64aacca6975d3b52310634a
6
+ metadata.gz: e08a6c50358d79233771a2202991d0ed46eeffdfe723911b95dc97880a8583a407c62e7d3a24a15cb8aa53b9e7eb91d824e7c94e4b8717bf5c935f645525c92e
7
+ data.tar.gz: d8af1629380d458440a01bd496310bffc597892ec3f68b0ebdec8cc7af2712241b9ffb833ac4f93577a232a06a99382bf36c0f1b3d39de32cf3e527f3676ba33
data/.travis.yml CHANGED
@@ -4,6 +4,7 @@ install:
4
4
  - sudo apt-get install ffmpeg
5
5
  - sudo apt-get install imagemagick
6
6
  - bundle install
7
+ env: 'CODECLIMATE_REPO_TOKEN=8849fed07a5273771df2257c579724d8eef91699fa482cf212afd1d2607a85fa'
7
8
  command: bundle exec rake
8
9
  rvm:
9
10
  - 2.1.0
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # WGif
2
2
  [![Build Status](https://travis-ci.org/ecmendenhall/wgif.svg?branch=master)](https://travis-ci.org/ecmendenhall/wgif)
3
+ [![Code Climate](https://codeclimate.com/github/ecmendenhall/wgif.png)](https://codeclimate.com/github/ecmendenhall/wgif)
3
4
 
4
5
  WGif is a command line tool for creating animated GIFs from YouTube videos.
5
6
 
@@ -7,11 +8,13 @@ WGif is a command line tool for creating animated GIFs from YouTube videos.
7
8
  ```
8
9
  Usage: wgif [YouTube URL] [output file] [options]
9
10
 
10
- -f, --frames N Number of frames in the final gif. (Default 20)
11
- -s, --start HH:MM:SS Start creating gif from input video at this timestamp. (Default 00:00:00)
12
- -d, --duration seconds Number of seconds of input video to capture. (Default 1)
13
- -u, --upload Upload finished GIF to Imgur
14
- -w, --width pixels Width of the gif in pixels. (Default 480px)
11
+ -f, --frames N Number of frames in the final gif. (Default 20)
12
+ -s, --start HH:MM:SS Start creating gif from input video at this timestamp. (Default 00:00:00)
13
+ -d, --duration seconds Number of seconds of input video to capture. (Default 1)
14
+ -w, --width pixels Width of the gif in pixels. (Default 480px)
15
+ -u, --upload Upload finished gif to Imgur
16
+ -p, --preview Preview finished gif with Quick Look
17
+ -h, --help Print help information.
15
18
 
16
19
  Example:
17
20
 
@@ -34,7 +37,7 @@ $ gem build wgif.gemspec
34
37
  and
35
38
 
36
39
  ```sh
37
- $ gem install wgif-0.2.0.gem
40
+ $ gem install wgif-0.3.0.gem
38
41
  ```
39
42
 
40
43
  to install the executable.
@@ -72,14 +75,24 @@ total number of frames in the finished GIF. This defaults to 20, so let's drop a
72
75
  $ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif --start 00:03:30 -d 2 -f 18
73
76
  ```
74
77
 
75
- Down to 2.2 megabytes, but still not small enough to post on my Sugarcubes fan-Tumblr. Let's scale it down a little
76
- with the `-w` or `--width` flag:
78
+ To preview the output in a Quick Look window, add the `--preview` flag:
79
+
80
+ ```sh
81
+ $ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif --start 00:03:30 -d 2 -f 18 --preview
82
+ ```
83
+
84
+ You'll see a preview pop up in a Quick Look window like this one:
85
+
86
+ ![Preview](http://i.imgur.com/cccOnpY.png)
87
+
88
+ Dropping frames shrunk the file to 2.2 megabytes, but it's still not small enough to post on my Sugarcubes fan-Tumblr.
89
+ Let's scale it down a little with the `-w` or `--width` flag:
77
90
 
78
91
  ```sh
79
92
  $ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif --start 00:03:30 -d 2 -f 18 --width 350
80
93
  ```
81
94
 
82
- And finally, now that everything's completed add the `--upload` flag to automatically post it to Imgur:
95
+ And finally, now that everything's completed, let's add the `--upload` flag to automatically post it to Imgur:
83
96
 
84
97
  ```sh
85
98
  $ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif --start 00:03:30 -d 2 -f 18 --width 350 --upload
@@ -88,12 +101,16 @@ Finished. GIF uploaded to Imgur at http://i.imgur.com/iA28DuR.gif
88
101
 
89
102
  And here it is:
90
103
 
91
- ![Bjork](http://i.imgur.com/iA28DUR.gif)
104
+ ![Bjork](http://i.imgur.com/iA28DuR.gif)
92
105
  ### "You shouldn't let poets lie to you."
93
106
 
94
107
  ## Changes
108
+ - v0.3.0, 2014/4/20: Add Quick Look preview with `--preview` flag.
95
109
  - v0.2.0, 2014/4/11: Add automatic upload to Imgur with `--upload` flag.
96
110
 
111
+ ## Contributors
112
+ Thanks to [arlandism](https://github.com/arlandism) and [ellie007](https://github.com/ellie007) for pairing on Imgur uploads.
113
+
97
114
  ## Contributions
98
115
  Are welcome via pull request.
99
116
 
data/Rakefile CHANGED
@@ -1,5 +1,10 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
3
 
4
- RSpec::Core::RakeTask.new(:spec)
5
- task :default => :spec
4
+ RSpec::Core::RakeTask.new(:spec, :tag) do |t, task_args|
5
+ unless task_args[:tag] == 'integration'
6
+ t.rspec_opts = "--tag ~integration"
7
+ end
8
+ end
9
+
10
+ task default: :spec
data/lib/wgif.rb CHANGED
@@ -1,10 +1,10 @@
1
- require "wgif/cli"
2
- require "wgif/download_bar"
3
- require "wgif/downloader"
4
- require "wgif/exceptions"
5
- require "wgif/gif_maker"
6
- require "wgif/installer"
7
- require "wgif/uploader"
8
- require "wgif/version"
9
- require "wgif/video"
10
- require "wgif/video_cache"
1
+ require 'wgif/cli'
2
+ require 'wgif/download_bar'
3
+ require 'wgif/downloader'
4
+ require 'wgif/exceptions'
5
+ require 'wgif/gif_maker'
6
+ require 'wgif/installer'
7
+ require 'wgif/uploader'
8
+ require 'wgif/version'
9
+ require 'wgif/video'
10
+ require 'wgif/video_cache'
@@ -0,0 +1,94 @@
1
+ require 'optparse'
2
+ require 'wgif/exceptions'
3
+
4
+ module WGif
5
+ class ArgumentParser
6
+
7
+ URL = %r{\Ahttps?://.*\z}
8
+ TIMESTAMP = /\A\d{1,2}(?::\d{2})+(?:\.\d*)?\z/
9
+
10
+ def initialize
11
+ @options = {}
12
+ @defaults = {
13
+ trim_from: '00:00:00',
14
+ duration: 1.0,
15
+ dimensions: '480'
16
+ }
17
+ @parser = OptionParser.new do |opts|
18
+ opts.on('-f N',
19
+ '--frames N',
20
+ 'Number of frames in the final gif. (Default 20)') {
21
+ |n| @options[:frames] = n.to_i
22
+ }
23
+ opts.on('-s HH:MM:SS',
24
+ '--start HH:MM:SS',
25
+ 'Start creating gif from input video at this timestamp. (Default 00:00:00)') {
26
+ |ts| @options[:trim_from] = ts
27
+ }
28
+ opts.on('-d seconds',
29
+ '--duration seconds',
30
+ 'Number of seconds of input video to capture. (Default 1)') {
31
+ |d| @options[:duration] = d.to_f
32
+ }
33
+ opts.on('-w pixels',
34
+ '--width pixels',
35
+ 'Width of the gif in pixels. (Default 480px)') {
36
+ |gs| @options[:dimensions] = gs
37
+ }
38
+ opts.on('-u',
39
+ '--upload',
40
+ 'Upload finished gif to Imgur') {
41
+ |u| @options[:upload] = u
42
+ }
43
+ opts.on('-p',
44
+ '--preview',
45
+ 'Preview finished gif with Quick Look') {
46
+ |p| @options[:preview] = p
47
+ }
48
+ opts.on_tail('-h',
49
+ '--help',
50
+ 'Print help information.') {
51
+ print_help
52
+ exit
53
+ }
54
+ end
55
+ end
56
+
57
+ def parse(args)
58
+ options = parse_args(args)
59
+ validate_args(options)
60
+ options
61
+ end
62
+
63
+ def argument_summary
64
+ @parser.summarize
65
+ end
66
+
67
+ def parse_args(args)
68
+ options = @defaults.merge(parse_options args)
69
+ options.merge(url: args[0], output: args[1])
70
+ end
71
+
72
+ def parse_options(args)
73
+ @parser.parse! args
74
+ @options
75
+ end
76
+
77
+ def validate_args(args)
78
+ fail WGif::InvalidUrlException unless args[:url] =~ URL
79
+ fail WGif::InvalidTimestampException unless args[:trim_from] =~ TIMESTAMP
80
+ fail WGif::MissingOutputFileException unless args[:output]
81
+ end
82
+
83
+ def print_help
84
+ puts 'Usage: wgif [YouTube URL] [output file] [options]', "\n"
85
+ puts argument_summary, "\n"
86
+ puts <<-example
87
+ Example:
88
+
89
+ $ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif -s 00:03:30 -d 2 -w 400 --upload
90
+
91
+ example
92
+ end
93
+ end
94
+ end
data/lib/wgif/cli.rb CHANGED
@@ -1,114 +1,70 @@
1
- require 'optparse'
1
+ require 'wgif/argument_parser'
2
2
  require 'wgif/exceptions'
3
3
  require 'wgif/installer'
4
4
 
5
5
  module WGif
6
6
  class CLI
7
7
 
8
- attr_accessor :parser
8
+ attr_accessor :argument_parser
9
9
 
10
10
  def initialize
11
- @options = {}
12
- @defaults = {
13
- trim_from: '00:00:00',
14
- duration: 1.0,
15
- dimensions: '480'
16
- }
17
- @parser = OptionParser.new do |opts|
18
- opts.on('-f N',
19
- '--frames N',
20
- 'Number of frames in the final gif. (Default 20)') {
21
- |n| @options[:frames] = n.to_i
22
- }
23
- opts.on('-s HH:MM:SS',
24
- '--start HH:MM:SS',
25
- 'Start creating gif from input video at this timestamp. (Default 00:00:00)') {
26
- |ts| @options[:trim_from] = ts
27
- }
28
- opts.on('-d seconds',
29
- '--duration seconds',
30
- 'Number of seconds of input video to capture. (Default 5)') {
31
- |d| @options[:duration] = d.to_f
32
- }
33
- opts.on('-w pixels',
34
- '--width pixels',
35
- 'Width of the gif in pixels. (Default 500px)') {
36
- |gs| @options[:dimensions] = gs
37
- }
38
- opts.on('-u',
39
- '--upload',
40
- 'Upload finished GIF to Imgur') {
41
- |u| @options[:upload] = !!u
42
- }
11
+ @argument_parser = WGif::ArgumentParser.new
12
+ end
43
13
 
44
- opts.on_tail('-h',
45
- '--help',
46
- 'Print help information.') {
47
- print_help
48
- exit
49
- }
14
+ def make_gif(cli_args)
15
+ WGif::Installer.new.run if cli_args[0] == 'install'
16
+ load_dependencies
17
+ rescue_errors do
18
+ args = @argument_parser.parse(cli_args)
19
+ frames = convert_video(args)
20
+ GifMaker.new.make_gif(frames, args[:output], args[:dimensions])
21
+ upload(args) if args[:upload]
22
+ preview(args) if args[:preview]
50
23
  end
51
24
  end
52
25
 
53
- def parse_args(args)
54
- options = @defaults.merge(parse_options args)
55
- options.merge(url: args[0], output: args[1])
26
+ private
27
+
28
+ def preview(args)
29
+ Kernel.system "qlmanage -p #{args[:output]} &>/dev/null"
56
30
  end
57
31
 
58
- def parse_options(args)
59
- @parser.parse! args
60
- @options
32
+ def upload(args)
33
+ url = Uploader.new('d2321b02db7ba15').upload(args[:output])
34
+ puts "Finished. GIF uploaded to Imgur at #{url}"
61
35
  end
62
36
 
63
- def validate_args(parsed_args)
64
- raise WGif::InvalidUrlException unless parsed_args[:url] =~ /\Ahttps?\:\/\/.*\z/
65
- raise WGif::InvalidTimestampException unless parsed_args[:trim_from] =~ /\A\d{1,2}(?::\d{2})+(?:\.\d*)?\z/
66
- raise WGif::MissingOutputFileException unless parsed_args[:output]
37
+ def convert_video(args)
38
+ video = Downloader.new.get_video(args[:url])
39
+ clip = video.trim(args[:trim_from], args[:duration])
40
+ clip.to_frames(frames: args[:frames])
67
41
  end
68
42
 
69
- def make_gif(cli_args)
70
- WGif::Installer.new.run if cli_args[0] == 'install'
43
+ def load_dependencies
71
44
  require 'wgif/downloader'
72
45
  require 'wgif/gif_maker'
73
46
  require 'wgif/uploader'
74
- rescue_errors do
75
- args = parse_args cli_args
76
- validate_args(args)
77
- video = Downloader.new.get_video(args[:url])
78
- clip = video.trim(args[:trim_from], args[:duration])
79
- frames = clip.to_frames(frames: args[:frames])
80
- GifMaker.new.make_gif(frames, args[:output], args[:dimensions])
81
- if args[:upload]
82
- url = Uploader.new('d2321b02db7ba15').upload(args[:output])
83
- puts "Finished. GIF uploaded to Imgur at #{url}"
84
- end
85
- end
86
47
  end
87
48
 
88
- private
89
-
90
49
  def rescue_errors
91
- begin
92
- yield
50
+ yield
93
51
  rescue WGif::InvalidUrlException
94
- print_error "That looks like an invalid URL. Check the syntax."
52
+ print_error 'That looks like an invalid URL. Check the syntax.'
95
53
  rescue WGif::InvalidTimestampException
96
- print_error "That looks like an invalid timestamp. Check the syntax."
54
+ print_error 'That looks like an invalid timestamp. Check the syntax.'
97
55
  rescue WGif::MissingOutputFileException
98
56
  print_error 'Please specify an output file.'
99
57
  rescue WGif::VideoNotFoundException
100
58
  print_error "WGif can't find a valid YouTube video at that URL."
101
59
  rescue WGif::ClipEncodingException
102
- print_error "WGif encountered an error transcoding the video."
60
+ print_error 'WGif encountered an error transcoding the video.'
103
61
  rescue WGif::ImgurException => e
104
62
  print_error <<-error
105
63
  WGif couldn't upload your GIF to Imgur. The Imgur error was:
106
64
 
107
65
  #{e}
108
66
  error
109
- rescue SystemExit => e
110
- raise e
111
- rescue Exception => e
67
+ rescue StandardError => e
112
68
  print_error <<-error
113
69
  Something went wrong creating your GIF. The details:
114
70
 
@@ -117,25 +73,13 @@ Something went wrong creating your GIF. The details:
117
73
 
118
74
  Please open an issue at: https://github.com/ecmendenhall/wgif/issues/new
119
75
  error
120
- end
121
76
  end
122
77
 
123
78
  def print_error(message)
124
79
  puts message, "\n"
125
- print_help
80
+ @argument_parser.print_help
126
81
  exit 1
127
82
  end
128
83
 
129
- def print_help
130
- puts "Usage: wgif [YouTube URL] [output file] [options]", "\n"
131
- puts @parser.summarize, "\n"
132
- puts <<-example
133
- Example:
134
-
135
- $ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif -s 00:03:30 -d 2 -w 400
136
-
137
- example
138
- end
139
-
140
84
  end
141
85
  end
@@ -23,6 +23,5 @@ module WGif
23
23
  def increment_progress(size)
24
24
  @progress_bar.progress += size
25
25
  end
26
-
27
26
  end
28
27
  end
@@ -14,29 +14,26 @@ module WGif
14
14
  @cache = WGif::VideoCache.new
15
15
  end
16
16
 
17
- def video_url youtube_url
18
- begin
19
- urls = ViddlRb.get_urls(youtube_url)
20
- urls.first
21
- rescue
22
- raise WGif::VideoNotFoundException
23
- end
17
+ def video_url(youtube_url)
18
+ urls = ViddlRb.get_urls(youtube_url)
19
+ urls.first
20
+ rescue
21
+ raise WGif::VideoNotFoundException
24
22
  end
25
23
 
26
- def video_id youtube_url
27
- begin
28
- uri = URI(youtube_url)
29
- params = CGI.parse(uri.query)
30
- params['v'].first
31
- rescue
32
- raise WGif::InvalidUrlException
33
- end
24
+ def video_id(youtube_url)
25
+ uri = URI(youtube_url)
26
+ params = CGI.parse(uri.query)
27
+ params['v'].first
28
+ rescue
29
+ raise WGif::InvalidUrlException
34
30
  end
35
31
 
36
- def get_video youtube_url
32
+ def get_video(youtube_url)
37
33
  id = video_id youtube_url
38
- if cached_clip = @cache.get(id)
39
- return cached_clip
34
+ cached_clip = @cache.get(id)
35
+ if cached_clip
36
+ cached_clip
40
37
  else
41
38
  temp = load_clip(id, youtube_url)
42
39
  video = WGif::Video.new(id, temp.path)
@@ -46,7 +43,7 @@ module WGif
46
43
 
47
44
  private
48
45
 
49
- def create_progress_bar request, output_file
46
+ def create_progress_bar(request, output_file)
50
47
  size = nil
51
48
  download_bar = WGif::DownloadBar.new
52
49
 
@@ -56,29 +53,28 @@ module WGif
56
53
  end
57
54
 
58
55
  request.on_body do |chunk|
59
- output_file.write(chunk)
60
- download_bar.increment_progress(chunk.size)
56
+ output_file.write(chunk)
57
+ download_bar.increment_progress(chunk.size)
61
58
  end
62
59
  end
63
60
 
64
- def request_clip youtube_url, output_file
65
- clip_url = self.video_url youtube_url
61
+ def request_clip(youtube_url, output_file)
62
+ clip_url = video_url(youtube_url)
66
63
  request = Typhoeus::Request.new clip_url
67
64
  create_progress_bar(request, output_file)
68
65
  request.run
69
66
  end
70
67
 
71
- def load_clip id, youtube_url
72
- FileUtils.mkdir_p "/tmp/wgif"
68
+ def load_clip(id, youtube_url)
69
+ FileUtils.mkdir_p '/tmp/wgif'
73
70
  temp = File.open("/tmp/wgif/#{id}", 'wb')
74
71
  begin
75
72
  clip = request_clip(youtube_url, temp)
76
- raise WGif::VideoNotFoundException unless clip.response_code == 200
73
+ fail WGif::VideoNotFoundException unless clip.response_code == 200
77
74
  ensure
78
75
  temp.close
79
76
  end
80
77
  temp
81
78
  end
82
-
83
79
  end
84
80
  end