Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor/cleanup #11

Merged
merged 7 commits into from
Apr 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ install:
- sudo apt-get install ffmpeg
- sudo apt-get install imagemagick
- bundle install
command: bundle exec rake
command: CODECLIMATE_REPO_TOKEN=8849fed07a5273771df2257c579724d8eef91699fa482cf212afd1d2607a85fa bundle exec rake
rvm:
- 2.1.0
- 2.0.0
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# WGif
[![Build Status](https://travis-ci.org/ecmendenhall/wgif.svg?branch=master)](https://travis-ci.org/ecmendenhall/wgif)
[![Code Climate](https://codeclimate.com/github/ecmendenhall/wgif.png)](https://codeclimate.com/github/ecmendenhall/wgif)

WGif is a command line tool for creating animated GIFs from YouTube videos.

Expand Down
4 changes: 2 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
require "bundler/gem_tasks"
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)
task :default => :spec
task default: :spec
20 changes: 10 additions & 10 deletions lib/wgif.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
require "wgif/cli"
require "wgif/download_bar"
require "wgif/downloader"
require "wgif/exceptions"
require "wgif/gif_maker"
require "wgif/installer"
require "wgif/uploader"
require "wgif/version"
require "wgif/video"
require "wgif/video_cache"
require 'wgif/cli'
require 'wgif/download_bar'
require 'wgif/downloader'
require 'wgif/exceptions'
require 'wgif/gif_maker'
require 'wgif/installer'
require 'wgif/uploader'
require 'wgif/version'
require 'wgif/video'
require 'wgif/video_cache'
78 changes: 78 additions & 0 deletions lib/wgif/argument_parser.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'optparse'
require 'wgif/exceptions'

module WGif
class ArgumentParser

URL = %r{\Ahttps?://.*\z}
TIMESTAMP = /\A\d{1,2}(?::\d{2})+(?:\.\d*)?\z/

def initialize
@options = {}
@defaults = {
trim_from: '00:00:00',
duration: 1.0,
dimensions: '480'
}
@parser = OptionParser.new do |opts|
opts.on('-f N',
'--frames N',
'Number of frames in the final gif. (Default 20)') {
|n| @options[:frames] = n.to_i
}
opts.on('-s HH:MM:SS',
'--start HH:MM:SS',
'Start creating gif from input video at this timestamp. (Default 00:00:00)') {
|ts| @options[:trim_from] = ts
}
opts.on('-d seconds',
'--duration seconds',
'Number of seconds of input video to capture. (Default 5)') {
|d| @options[:duration] = d.to_f
}
opts.on('-w pixels',
'--width pixels',
'Width of the gif in pixels. (Default 500px)') {
|gs| @options[:dimensions] = gs
}
opts.on('-u',
'--upload',
'Upload finished GIF to Imgur') {
|u| @options[:upload] = u
}
opts.on_tail('-h',
'--help',
'Print help information.') {
print_help
exit
}
end
end

def parse(args)
options = parse_args(args)
validate_args(options)
options
end

def argument_summary
@parser.summarize
end

def parse_args(args)
options = @defaults.merge(parse_options args)
options.merge(url: args[0], output: args[1])
end

def parse_options(args)
@parser.parse! args
@options
end

def validate_args(args)
fail WGif::InvalidUrlException unless args[:url] =~ URL
fail WGif::InvalidTimestampException unless args[:trim_from] =~ TIMESTAMP
fail WGif::MissingOutputFileException unless args[:output]
end
end
end
109 changes: 29 additions & 80 deletions lib/wgif/cli.rb
Original file line number Diff line number Diff line change
@@ -1,114 +1,65 @@
require 'optparse'
require 'wgif/argument_parser'
require 'wgif/exceptions'
require 'wgif/installer'

module WGif
class CLI

attr_accessor :parser
attr_accessor :argument_parser

def initialize
@options = {}
@defaults = {
trim_from: '00:00:00',
duration: 1.0,
dimensions: '480'
}
@parser = OptionParser.new do |opts|
opts.on('-f N',
'--frames N',
'Number of frames in the final gif. (Default 20)') {
|n| @options[:frames] = n.to_i
}
opts.on('-s HH:MM:SS',
'--start HH:MM:SS',
'Start creating gif from input video at this timestamp. (Default 00:00:00)') {
|ts| @options[:trim_from] = ts
}
opts.on('-d seconds',
'--duration seconds',
'Number of seconds of input video to capture. (Default 5)') {
|d| @options[:duration] = d.to_f
}
opts.on('-w pixels',
'--width pixels',
'Width of the gif in pixels. (Default 500px)') {
|gs| @options[:dimensions] = gs
}
opts.on('-u',
'--upload',
'Upload finished GIF to Imgur') {
|u| @options[:upload] = !!u
}

opts.on_tail('-h',
'--help',
'Print help information.') {
print_help
exit
}
end
@argument_parser = WGif::ArgumentParser.new
end

def parse_args(args)
options = @defaults.merge(parse_options args)
options.merge(url: args[0], output: args[1])
def make_gif(cli_args)
WGif::Installer.new.run if cli_args[0] == 'install'
load_dependencies
rescue_errors do
args = @argument_parser.parse(cli_args)
frames = convert_video(args)
GifMaker.new.make_gif(frames, args[:output], args[:dimensions])
upload(args) if args[:upload]
end
end

def parse_options(args)
@parser.parse! args
@options
private

def upload(args)
url = Uploader.new('d2321b02db7ba15').upload(args[:output])
puts "Finished. GIF uploaded to Imgur at #{url}"
end

def validate_args(parsed_args)
raise WGif::InvalidUrlException unless parsed_args[:url] =~ /\Ahttps?\:\/\/.*\z/
raise WGif::InvalidTimestampException unless parsed_args[:trim_from] =~ /\A\d{1,2}(?::\d{2})+(?:\.\d*)?\z/
raise WGif::MissingOutputFileException unless parsed_args[:output]
def convert_video(args)
video = Downloader.new.get_video(args[:url])
clip = video.trim(args[:trim_from], args[:duration])
clip.to_frames(frames: args[:frames])
end

def make_gif(cli_args)
WGif::Installer.new.run if cli_args[0] == 'install'
def load_dependencies
require 'wgif/downloader'
require 'wgif/gif_maker'
require 'wgif/uploader'
rescue_errors do
args = parse_args cli_args
validate_args(args)
video = Downloader.new.get_video(args[:url])
clip = video.trim(args[:trim_from], args[:duration])
frames = clip.to_frames(frames: args[:frames])
GifMaker.new.make_gif(frames, args[:output], args[:dimensions])
if args[:upload]
url = Uploader.new('d2321b02db7ba15').upload(args[:output])
puts "Finished. GIF uploaded to Imgur at #{url}"
end
end
end

private

def rescue_errors
begin
yield
yield
rescue WGif::InvalidUrlException
print_error "That looks like an invalid URL. Check the syntax."
print_error 'That looks like an invalid URL. Check the syntax.'
rescue WGif::InvalidTimestampException
print_error "That looks like an invalid timestamp. Check the syntax."
print_error 'That looks like an invalid timestamp. Check the syntax.'
rescue WGif::MissingOutputFileException
print_error 'Please specify an output file.'
rescue WGif::VideoNotFoundException
print_error "WGif can't find a valid YouTube video at that URL."
rescue WGif::ClipEncodingException
print_error "WGif encountered an error transcoding the video."
print_error 'WGif encountered an error transcoding the video.'
rescue WGif::ImgurException => e
print_error <<-error
WGif couldn't upload your GIF to Imgur. The Imgur error was:

#{e}
error
rescue SystemExit => e
raise e
rescue Exception => e
rescue StandardError => e
print_error <<-error
Something went wrong creating your GIF. The details:

Expand All @@ -117,7 +68,6 @@ def rescue_errors

Please open an issue at: https://github.com/ecmendenhall/wgif/issues/new
error
end
end

def print_error(message)
Expand All @@ -127,15 +77,14 @@ def print_error(message)
end

def print_help
puts "Usage: wgif [YouTube URL] [output file] [options]", "\n"
puts @parser.summarize, "\n"
puts 'Usage: wgif [YouTube URL] [output file] [options]', "\n"
puts @argument_parser.argument_summary, "\n"
puts <<-example
Example:

$ wgif https://www.youtube.com/watch?v=1A78yTvIY1k bjork.gif -s 00:03:30 -d 2 -w 400

example
end

end
end
1 change: 0 additions & 1 deletion lib/wgif/download_bar.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@ def update_total(size)
def increment_progress(size)
@progress_bar.progress += size
end

end
end
50 changes: 23 additions & 27 deletions lib/wgif/downloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,26 @@ def initialize
@cache = WGif::VideoCache.new
end

def video_url youtube_url
begin
urls = ViddlRb.get_urls(youtube_url)
urls.first
rescue
raise WGif::VideoNotFoundException
end
def video_url(youtube_url)
urls = ViddlRb.get_urls(youtube_url)
urls.first
rescue
raise WGif::VideoNotFoundException
end

def video_id youtube_url
begin
uri = URI(youtube_url)
params = CGI.parse(uri.query)
params['v'].first
rescue
raise WGif::InvalidUrlException
end
def video_id(youtube_url)
uri = URI(youtube_url)
params = CGI.parse(uri.query)
params['v'].first
rescue
raise WGif::InvalidUrlException
end

def get_video youtube_url
def get_video(youtube_url)
id = video_id youtube_url
if cached_clip = @cache.get(id)
return cached_clip
cached_clip = @cache.get(id)
if cached_clip
cached_clip
else
temp = load_clip(id, youtube_url)
video = WGif::Video.new(id, temp.path)
Expand All @@ -46,7 +43,7 @@ def get_video youtube_url

private

def create_progress_bar request, output_file
def create_progress_bar(request, output_file)
size = nil
download_bar = WGif::DownloadBar.new

Expand All @@ -56,29 +53,28 @@ def create_progress_bar request, output_file
end

request.on_body do |chunk|
output_file.write(chunk)
download_bar.increment_progress(chunk.size)
output_file.write(chunk)
download_bar.increment_progress(chunk.size)
end
end

def request_clip youtube_url, output_file
clip_url = self.video_url youtube_url
def request_clip(youtube_url, output_file)
clip_url = video_url(youtube_url)
request = Typhoeus::Request.new clip_url
create_progress_bar(request, output_file)
request.run
end

def load_clip id, youtube_url
FileUtils.mkdir_p "/tmp/wgif"
def load_clip(id, youtube_url)
FileUtils.mkdir_p '/tmp/wgif'
temp = File.open("/tmp/wgif/#{id}", 'wb')
begin
clip = request_clip(youtube_url, temp)
raise WGif::VideoNotFoundException unless clip.response_code == 200
fail WGif::VideoNotFoundException unless clip.response_code == 200
ensure
temp.close
end
temp
end

end
end