diff --git a/.gitignore b/.gitignore index 0d3c4db..7bd810d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,10 @@ *.mp4 *.part +/.bundle/ +/.yardoc +/_yardoc/ +/coverage/ +/doc/ +/pkg/ +/spec/reports/ +/tmp/ diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..0edcd6c --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,13 @@ +AllCops: + TargetRubyVersion: 2.4 + +Style/StringLiterals: + Enabled: true + EnforcedStyle: single_quotes + +Style/StringLiteralsInInterpolation: + Enabled: true + EnforcedStyle: single_quotes + +Layout/LineLength: + Max: 120 diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..2c0c270 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +ruby 3.0.0 diff --git a/Gemfile b/Gemfile index 3422c4a..c8aabc5 100644 --- a/Gemfile +++ b/Gemfile @@ -2,12 +2,8 @@ source "https://rubygems.org" -git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } +# git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } -# gem "rails" +# Specify your gem's dependencies in fosdem.gemspec +gemspec -gem "thor", "~> 1.1" - -gem "mechanize", "~> 2.7" - -gem "colorize", "~> 0.8.1" diff --git a/Gemfile.lock b/Gemfile.lock index 18768d5..9ba4d9f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,6 +1,15 @@ +PATH + remote: . + specs: + fosdem-recorder (0.1.0) + colorize (~> 0.8.1) + mechanize (~> 2.7) + thor (~> 1.1) + GEM remote: https://rubygems.org/ specs: + ast (2.4.2) colorize (0.8.1) connection_pool (2.2.3) domain_name (0.5.20190701) @@ -28,11 +37,31 @@ GEM mini_portile2 (~> 2.5.0) racc (~> 1.4) ntlm-http (0.1.1) + parallel (1.20.1) + parser (3.0.0.0) + ast (~> 2.4.1) racc (1.5.2) + rainbow (3.0.0) + rake (13.0.3) + regexp_parser (2.0.3) + rexml (3.2.4) + rubocop (1.9.1) + parallel (~> 1.10) + parser (>= 3.0.0.0) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 1.8, < 3.0) + rexml + rubocop-ast (>= 1.2.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.4.1) + parser (>= 2.7.1.5) + ruby-progressbar (1.11.0) thor (1.1.0) unf (0.1.4) unf_ext unf_ext (0.0.7.7) + unicode-display_width (2.0.0) webrick (1.7.0) webrobots (0.1.2) @@ -40,9 +69,9 @@ PLATFORMS ruby DEPENDENCIES - colorize (~> 0.8.1) - mechanize (~> 2.7) - thor (~> 1.1) + fosdem-recorder! + rake (~> 13.0) + rubocop (~> 1.7) BUNDLED WITH - 2.1.2 + 2.2.6 diff --git a/README.md b/README.md index f005944..44e3ee3 100644 --- a/README.md +++ b/README.md @@ -37,3 +37,38 @@ $ bundle exec fosdem-recorder info https://fosdem.org/2021/schedule/event/sca_we [... a MP4 file will be created once the video is downloaded ...] ``` +# Fosdem + +Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/fosdem`. To experiment with that code, run `bin/console` for an interactive prompt. + +TODO: Delete this and the text above, and describe your gem + +## Installation + +Add this line to your application's Gemfile: + +```ruby +gem 'fosdem' +``` + +And then execute: + + $ bundle install + +Or install it yourself as: + + $ gem install fosdem + +## Usage + +TODO: Write usage instructions here + +## Development + +After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment. + +To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). + +## Contributing + +Bug reports and pull requests are welcome on GitHub at https://github.com/glenux/fosdem. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..1924143 --- /dev/null +++ b/Rakefile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +require "bundler/gem_tasks" +require "rubocop/rake_task" + +RuboCop::RakeTask.new + +task default: :rubocop diff --git a/bin/console b/bin/console new file mode 100755 index 0000000..a7b5515 --- /dev/null +++ b/bin/console @@ -0,0 +1,15 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "bundler/setup" +require "fosdem" + +# You can add fixtures and/or initialization code here to make experimenting +# with your gem easier. You can also use a different console, if you like. + +# (If you use this, don't forget to add pry to your Gemfile!) +# require "pry" +# Pry.start + +require "irb" +IRB.start(__FILE__) diff --git a/bin/setup b/bin/setup new file mode 100755 index 0000000..dce67d8 --- /dev/null +++ b/bin/setup @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +set -vx + +bundle install + +# Do any other automated setup that you need to do here diff --git a/exe/fosdem_recorder b/exe/fosdem_recorder new file mode 100755 index 0000000..1172b97 --- /dev/null +++ b/exe/fosdem_recorder @@ -0,0 +1,11 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'mechanize' +require 'time' +require 'colorize' +require 'thor' + +require 'fosdem_recorder/cli' + +FosdemRecorder::Cli.start(ARGV) diff --git a/fosdem-recorder b/fosdem-recorder deleted file mode 100755 index 3016c8d..0000000 --- a/fosdem-recorder +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -require 'mechanize' -require 'time' -require 'colorize' - -require 'thor' - -# Fosdem Cli - Download and cut streams video -class FosdemCli < Thor - desc 'info URL', 'Get information about URL' - def info(url) - meta = _get_meta(url) - puts "* title = #{meta[:title]}" - puts "* start = #{meta[:start_str]}" - puts "* stop = #{meta[:stop_str]}" - puts "* diff = #{meta[:duration_str]}" - puts "* url = #{meta[:stream_url]}" - end - - desc 'download URL', 'Download conference described at URL' - def download(url) - meta = _get_meta(url) - cmd = "Command: echo ffmpeg -i #{meta[:stream_url]} -c copy -t #{meta[:duration_str]} \"#{meta[:title_sane]}.mp4\" | at #{meta[:start_str]}" - puts cmd.yellow - system cmd - end - - private - - def _get_meta(url) - mechanize = Mechanize.new - page = mechanize.get(url) - - title = page.title - title_sane = - title - .gsub(/[^a-zA-Z0-9]/, '-') - .gsub(/--*/, '-') - .gsub(/-$/, '') - .gsub(/^-/, '') - - play_start_str = - page - .at('.side-box .icon-play') - .parent - .at('.value-title') - .text - .strip - - play_start = Time.parse(play_start_str) - - play_stop_str = - page - .at('.side-box .icon-stop') - .parent - .at('.value-title') - .text.strip - - play_stop = Time.parse(play_stop_str) - - duration = (play_stop - play_start) / 3600 - duration_h = duration.to_i - duration_m = ((duration - duration_h) * 60).to_i - duration_str = '%02d:%02d:00' % [duration_h, duration_m] - - stream_page = - page - .links - .select { |link| link.href =~ /live.fosdem.org/ } - .first - .href - - stream_url = - stream_page - .gsub(%r{.*watch/}, 'https://stream.fosdem.org/') - .gsub(/$/, '.m3u8') - - { - title: title, - title_sane: title_sane, - stream_url: stream_url, - start_str: play_start_str, - stop_str: play_stop_str, - duration_str: duration_str - } - end -end - -FosdemCli.start(ARGV) - -# https://stream.fosdem.org/dpostgresql.m3u8 - diff --git a/fosdem_recorder.gemspec b/fosdem_recorder.gemspec new file mode 100644 index 0000000..ee3d8e3 --- /dev/null +++ b/fosdem_recorder.gemspec @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require_relative 'lib/fosdem_recorder/version' + +Gem::Specification.new do |spec| + spec.name = 'fosdem-recorder' + spec.version = FosdemRecorder::VERSION + spec.authors = ['Glenn Y. Rolland'] + spec.email = ['glenux@glenux.net'] + + spec.summary = 'Simple FOSDEM conferences recorder' + spec.description = 'Simple FOSDEM conferences recorder' + spec.homepage = 'https://github.com/glenux/fosdem-recorder' + spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0') + + # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'" + # spec.metadata["homepage_uri"] = spec.homepage + spec.metadata["source_code_uri"] = 'https://github.com/glenux/fosdem-recorder' + # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here." + + # Specify which files should be added to the gem when it is released. + # The `git ls-files -z` loads the files in the RubyGem that have been added into git. + spec.files = Dir.chdir(File.expand_path(__dir__)) do + `git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) } + end + spec.bindir = 'exe' + spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) } + spec.require_paths = ['lib'] + + # Uncomment to register a new dependency of your gem + spec.add_dependency 'thor', '~> 1.1' + spec.add_dependency 'mechanize', '~> 2.7' + spec.add_dependency 'colorize', '~> 0.8.1' + spec.add_development_dependency 'rake', '~> 13.0' + spec.add_development_dependency 'rubocop', '~> 1.7' + + # For more information and examples about making a new gem, checkout our + # guide at: https://bundler.io/guides/creating_gem.html +end + diff --git a/lib/fosdem_recorder.rb b/lib/fosdem_recorder.rb new file mode 100644 index 0000000..a441269 --- /dev/null +++ b/lib/fosdem_recorder.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require_relative 'fosdem_recorder/version' + +module Fosdem + class Error < StandardError; end +end diff --git a/lib/fosdem_recorder/cli.rb b/lib/fosdem_recorder/cli.rb new file mode 100755 index 0000000..b663686 --- /dev/null +++ b/lib/fosdem_recorder/cli.rb @@ -0,0 +1,91 @@ + +module FosdemRecorder + # Fosdem Cli - Download and cut streams video + class Cli < Thor + desc 'info URL', 'Get information about URL' + def info(url) + meta = _get_meta(url) + puts meta[:title] + puts "* start = #{meta[:start_str]}" + puts "* stop = #{meta[:stop_str]}" + puts "* length = #{meta[:duration_str]}" + puts "* stream url = #{meta[:stream_url]}" + end + + desc 'download URL', 'Download conference described at URL' + def download(url) + meta = _get_meta(url) + cmd = "echo ffmpeg -i #{meta[:stream_url]} -c copy -t #{meta[:duration_str]} \"#{meta[:title_sane]}.mp4\" | at #{meta[:start_str]}" + puts "Command: #{cmd}".yellow + system cmd + end + + private + + def _validate_url(url) + return if url =~ %r{^https://fosdem.org/\d+/schedule/event/.*} + + warn 'ERROR: not a fosdem stream. URL must start with https://fosdem.org/...' + exit 1 + end + + def _get_meta(url) + mechanize = Mechanize.new + page = mechanize.get(url) + + title = page.title + title_sane = + title + .gsub(/[^a-zA-Z0-9]/, '-') + .gsub(/--*/, '-') + .gsub(/-$/, '') + .gsub(/^-/, '') + + play_start_str = + page + .at('.side-box .icon-play') + .parent + .at('.value-title') + .text + .strip + + play_start = Time.parse(play_start_str) + + play_stop_str = + page + .at('.side-box .icon-stop') + .parent + .at('.value-title') + .text.strip + + play_stop = Time.parse(play_stop_str) + + duration = (play_stop - play_start) / 3600 + duration_h = duration.to_i + duration_m = ((duration - duration_h) * 60).to_i + duration_str = format('%02d:%02d:00', hours: duration_h, minutes: duration_m) + + stream_page = + page + .links + .select { |link| link.href =~ /live.fosdem.org/ } + .first + .href + + stream_url = + stream_page + .gsub(%r{.*watch/}, 'https://stream.fosdem.org/') + .gsub(/$/, '.m3u8') + + { + title: title, + title_sane: title_sane, + stream_url: stream_url, + start_str: play_start_str, + stop_str: play_stop_str, + duration_str: duration_str + } + end + end + +end diff --git a/lib/fosdem_recorder/version.rb b/lib/fosdem_recorder/version.rb new file mode 100644 index 0000000..067f4d2 --- /dev/null +++ b/lib/fosdem_recorder/version.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +module FosdemRecorder + VERSION = "0.1.0" +end