wgif 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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