fox 0.4.0 → 0.6.2

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: 958a7a559e25d833355bdf0fffd38dac5a54d6d6
4
- data.tar.gz: af8ee1fde1f1f28701dce0549736b9e6f536f15d
3
+ metadata.gz: 857965e1b8fd0f5c481aa1675971cb6e6479cec3
4
+ data.tar.gz: 0e1b11db7c1a364d0ee09eea0a2bbdfcf092d8d5
5
5
  SHA512:
6
- metadata.gz: 587e812e9e989e5e936a3503af624fe4d4848b7243c679d23034076cbb9807a9b5f82f9b9e27f140c651f47bf50cbcc6a878949378826d4c038966c41498d2fd
7
- data.tar.gz: de4e187eb5304bac91fffd4475ed344af4f05ea7305fa31eb0ea564d528d4baaa4136959f748db5e265ec5772750b00b60626e542fd435f0338acae6a6670328
6
+ metadata.gz: 31e854ae25a1280da10618176c53d4edba426e9b2e3b6f598bb1d5dbbeb671bd2e265ff0e6e150ae4c7b5aad630e7c69f2f9118ca16781c5258f692c925d7b4f
7
+ data.tar.gz: 8174e3766090b9d87a1649a1f4a08bd305829dcea65b4c8b10773eedac3c0fb0522c93b7b901cb50ec74cce5be625abc747b0d9489e4f6875a4da121476e8695
@@ -58,7 +58,8 @@ Gem::Specification.new do |spec|
58
58
 
59
59
  spec.files += Dir.glob( 'spec/**/*' )
60
60
 
61
- spec.files += Dir.glob( 'data/**/*' )
61
+ # Exclude data folder (too big)
62
+ # spec.files += Dir.glob( 'data/**/*' )
62
63
 
63
64
  spec.files += Dir.glob( 'documentation/**/*' )
64
65
 
@@ -88,6 +89,8 @@ Gem::Specification.new do |spec|
88
89
  # Shell
89
90
  spec.add_runtime_dependency 'ptools'
90
91
  spec.add_runtime_dependency 'os'
92
+ spec.add_runtime_dependency 'progressbar'
93
+
91
94
 
92
95
  # Database ORM (Persistent)
93
96
  spec.add_runtime_dependency 'datamapper'
@@ -127,6 +130,9 @@ Gem::Specification.new do |spec|
127
130
  spec.add_runtime_dependency 'andand'
128
131
  # spec.add_runtime_dependency 'ick'
129
132
 
133
+ # Audio
134
+ spec.add_runtime_dependency 'taglib-ruby'
135
+
130
136
  # Misc System
131
137
  # spec.add_runtime_dependency 'awesome_print'
132
138
  # spec.add_runtime_dependency 'uuid'
@@ -5,7 +5,6 @@
5
5
  # @brief Fox module namespace
6
6
  module Fox
7
7
 
8
-
9
8
  class FoxError < StandardError
10
9
 
11
10
  class << self
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # System
5
+ require 'taglib'
6
+ require 'progressbar'
7
+
8
+
9
+ # @module module Mixin
10
+ # @brief Mixin module contains various functions to be used in other components
11
+ module Mixin
12
+
13
+ # @module Audio Module
14
+ # @brief Module wrapper around audio tasks
15
+ module Audio
16
+
17
+ # @fn def initialize *args {{{
18
+ # @brief Default constructor
19
+ #
20
+ # @param [Array] args Argument array
21
+ def initialize *args
22
+ super
23
+ end # }}}
24
+
25
+ # @fn def play_remote url {{{
26
+ # @brief Play audio content from remote URL
27
+ #
28
+ # @param [String] url Remote URL
29
+ def play_remote url
30
+ play( url, :url )
31
+ end # }}}
32
+
33
+ # @fn def play_local file {{{
34
+ # @brief Play audio content file
35
+ #
36
+ # @param [String] file Filename incl. path
37
+ def play_local file
38
+
39
+ duration = get_duration( file ) # in sec
40
+
41
+ if( duration.nil? )
42
+ play( file, :file )
43
+ else
44
+
45
+ threads = []
46
+
47
+ threads << Thread.new { play( file, :file ) }
48
+ threads << Thread.new do
49
+ ProgressBar.new( "Pomodoro", duration.to_i ) do |bar|
50
+ duration.to_i.times { sleep(1); bar.inc }
51
+ end
52
+ end
53
+
54
+ threads.each { |thread| thread.join }
55
+
56
+ end # if( duration.nil? )
57
+
58
+ end # }}}
59
+
60
+
61
+ private
62
+
63
+ # in sec
64
+ def get_duration file
65
+
66
+ duration = nil
67
+
68
+ begin
69
+ TagLib::FileRef.open( file ) do |fileref|
70
+
71
+ unless fileref.null?
72
+ tag = fileref.tag
73
+ properties = fileref.audio_properties
74
+
75
+ duration = properties.length
76
+ end
77
+
78
+ end # of TagLib
79
+ rescue
80
+ end
81
+
82
+ return duration
83
+ end
84
+
85
+
86
+ def play identifier, type
87
+
88
+ # Check if we are able to playback
89
+ sanity_check
90
+
91
+ if( type == :url )
92
+ # FIXME: Caching!
93
+ `wget #{identifier} -O - | mplayer -really-quiet -cache 8192 -`
94
+ end
95
+
96
+ if( type == :file )
97
+ `mplayer -really-quiet #{identifier}`
98
+ end
99
+
100
+ end
101
+
102
+ def sanity_check
103
+ players = detect_available_players
104
+ # FIXME
105
+ end
106
+
107
+ # sorted after user preference
108
+ def detect_available_players
109
+ # FIXME
110
+ [ "mplayer" ]
111
+ end
112
+
113
+ end # of module Audio
114
+
115
+ end # of module Mixin
116
+
117
+
118
+ # vim:ts=2:tw=100:wm=100:syntax=ruby
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # System
5
+ require 'fileutils'
6
+ require 'ostruct'
7
+
8
+
9
+ # @module module Mixin
10
+ # @brief Mixin module contains various functions to be used in other components
11
+ module Mixin
12
+
13
+ # @module Config Module
14
+ # @brief Module wrapper around tasks which demands config file
15
+ module Config
16
+
17
+ # @fn def initialize *args {{{
18
+ # @brief Default constructor
19
+ #
20
+ # @param [Array] args Argument array
21
+ def initialize *args
22
+
23
+ super
24
+
25
+ # Store all config paths and relevant filenames (global)
26
+ @paths = OpenStruct.new
27
+
28
+ # Level 1
29
+ @paths.user_home = Dir.home
30
+ @paths.fox_home = options[:'config-path']
31
+
32
+ # Level 2
33
+ @paths.assets = File.join( @paths.fox_home, 'assets' )
34
+ @paths.databases = File.join( @paths.fox_home, 'databases' )
35
+
36
+ # Level 3
37
+ @paths.pomodoro_assets = File.join( @paths.assets, 'pomodoro' )
38
+ @paths.coffeeshop_assets = File.join( @paths.assets, 'coffeeshop' )
39
+
40
+ # Sanity check, create if doesn't exist in $HOME
41
+ @paths.to_h.each do |tag, uri|
42
+ FileUtils.mkdir_p( uri ) unless( File.exists?( uri ) )
43
+ end
44
+
45
+
46
+ # Remote Assets URLs
47
+ @urls = OpenStruct.new
48
+
49
+ @urls.pomodoro = OpenStruct.new
50
+ @urls.pomodoro.short = 'https://github.com/rennhak/fox/raw/master/data/pomodoro/pomodoro_5.mp3'
51
+ @urls.pomodoro.normal = 'https://github.com/rennhak/fox/raw/master/data/pomodoro/pomodoro_25.mp3'
52
+
53
+ @urls.coffeeshop = OpenStruct.new
54
+ @urls.coffeeshop.morning_murmur = 'https://github.com/rennhak/fox/raw/master/data/coffeeshop/morning_murmur.mp3'
55
+
56
+
57
+ # Assets
58
+ @assets = OpenStruct.new
59
+
60
+ @assets.pomodoro = OpenStruct.new
61
+ @assets.pomodoro.short = File.join( @paths.pomodoro_assets, File.basename( @urls.pomodoro.short ) )
62
+ @assets.pomodoro.normal = File.join( @paths.pomodoro_assets, File.basename( @urls.pomodoro.normal ) )
63
+
64
+ # Config
65
+ @config = OpenStruct.new
66
+
67
+ @config.pomodoro = OpenStruct.new
68
+ @config.pomodoro.default = :normal
69
+
70
+ end # }}}
71
+
72
+ Thor::class_option :'config-path', :type => :string, :required => false, :default => "#{Dir.home}/.fox", :desc => 'Change default config path'
73
+
74
+ end # of module Configuration
75
+
76
+ end # of module Mixin
77
+
78
+
79
+ # vim:ts=2:tw=100:wm=100:syntax=ruby
@@ -15,6 +15,7 @@ module Mixin
15
15
  # @param [Array] args Argument array
16
16
  def initialize *args
17
17
  super
18
+
18
19
  unless File.exist?("~/.fox/config.yaml")
19
20
  abort("Could not find configuration file in ~/.fox/config.yaml. Please run 'fox config:generate' to generate it.")
20
21
  end
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'fox/error/errors'
3
+ # require 'fox/error/errors'
4
4
 
5
5
  module Mixin
6
6
 
@@ -0,0 +1,117 @@
1
+ #!/usr/bin/env ruby
2
+
3
+
4
+ # System
5
+ require 'open-uri'
6
+ require 'net/http'
7
+ require 'net/ftp'
8
+ require 'uri'
9
+ require 'progressbar'
10
+ require 'date'
11
+ require 'tempfile'
12
+ require 'timeout'
13
+
14
+
15
+
16
+ # @module module Mixin
17
+ # @brief Mixin module contains various functions to be used in other components
18
+ module Mixin
19
+
20
+ # @module Network Module
21
+ # @brief Module wrapper around network tasks
22
+ module Network
23
+
24
+ # @fn def initialize *args {{{
25
+ # @brief Default constructor
26
+ #
27
+ # @param [Array] args Argument array
28
+ def initialize *args
29
+ super
30
+ end # }}}
31
+
32
+ # @fn def online? {{{
33
+ # @brief Checks if user is online so we can download assets
34
+ #
35
+ # @return [boolean] True if online, otherwise false
36
+ def online?
37
+
38
+ begin
39
+ true if open( "http://www.google.com/", { read_timeout: 5 } )
40
+ rescue
41
+ false
42
+ end
43
+
44
+ end # }}}
45
+
46
+ # @fn def download url, target_filename # {{{
47
+ # @brief The function get retrieves the given URL content and returns it to the caller
48
+ #
49
+ # @param [String] url Requires a string containing a uri which will be downloaded.
50
+ #
51
+ # @return [OpenStruct] Returns an OpenStruct containing content and many other meta information
52
+ def download url, target_filename, progress_indicator = true
53
+
54
+ # Pre-condition
55
+ raise ArgumentError, "The function expects a string, but got a (#{url.class.to_s})" unless( url.is_a?(String) )
56
+
57
+ # Main
58
+ content = OpenStruct.new
59
+ request = nil
60
+
61
+ begin
62
+ # wait 900s or 15min before timeout
63
+ status = Timeout::timeout( 900 ) {
64
+
65
+ if( progress_indicator )
66
+
67
+ # Inspired by http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open-uri/rdoc/OpenURI/OpenRead.html
68
+ pbar = nil
69
+ request = open( url,
70
+ "r",
71
+ :read_timeout => nil,
72
+ :content_length_proc => lambda {|t|
73
+ if( t && 0 < t )
74
+ pbar = ProgressBar.new("...", t)
75
+ pbar.file_transfer_mode
76
+ end
77
+ },
78
+ :progress_proc => lambda {|s|
79
+ pbar.set s if pbar
80
+ }
81
+ )
82
+
83
+ else
84
+ request = open( url, "r", :read_timeout => nil )
85
+ end
86
+
87
+ STDOUT.puts ""
88
+
89
+ } # end of Timeout::timeout
90
+ rescue Timeout::Error
91
+ puts 'Time out error - That took too long (>=15min) - fatal abort'
92
+ exit
93
+ end
94
+
95
+ content.url = url
96
+ content.content = request.read
97
+ content.content_type = request.content_type
98
+ content.charset = request.charset
99
+ content.content_encoding = request.content_encoding
100
+ content.last_modified = request.last_modified
101
+ content.date = DateTime.now
102
+
103
+ @logger.message :debug, "Writing content to (file, #{target_filename.to_s})"
104
+ File.open( target_filename, "w+" ) { |f| f.write( content.content ) }
105
+
106
+ # Post-condition
107
+ raise ArgumentError, "Result should be of type OpenStruct, but is (#{content.class.to_s})" unless( content.is_a?(OpenStruct) )
108
+
109
+ [ content, target_filename ]
110
+ end # }}}
111
+
112
+ end # of module Network
113
+
114
+ end # of module Mixin
115
+
116
+
117
+ # vim:ts=2:tw=100:wm=100:syntax=ruby
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # System
4
+ require 'open-uri'
5
+
6
+ # Custom includes
7
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/logger' )
8
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/config' )
9
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/network' )
10
+ require File.expand_path( File.dirname( __FILE__ ) + '/mixin/audio' )
11
+
12
+
13
+ # @class Pomodoro command class
14
+ # @brief Allows you to get more productivity with a ticking egg timer
15
+ class Pomodoro < Thor
16
+
17
+ # Include various traits
18
+ include Thor::Actions
19
+ include ::Mixin::Logger
20
+ include ::Mixin::Config
21
+ include ::Mixin::Network
22
+ include ::Mixin::Audio
23
+
24
+ class_option :stream, :type => :boolean, :desc => 'Stream from github.com remote', :default => false
25
+ class_option :download, :type => :boolean, :desc => 'Download from github.com remote', :default => true
26
+
27
+ # @fn def default {{{
28
+ # @brief Plays default Pomodoro clock (25 min)
29
+ desc 'default', 'Plays default Pomodoro clock (25 min) so that you can concentrate'
30
+ def default
31
+
32
+ @logger.message :debug, 'Running sanity check for Pomodoro task'
33
+ sanity_check
34
+
35
+ if( options[:stream] )
36
+ @logger.message :info, 'Streaming from Remote via github.com raw (use CTRL+C to abort)'
37
+ @logger.message :warning, 'Please do not hammer github.com, download if possible instead'
38
+
39
+ play_remote( @urls.pomodoro.send( @config.pomodoro.default ) )
40
+ else
41
+ @logger.message :info, 'Playing local file (use CTRL+C to abort)'
42
+
43
+ play_local( @assets.pomodoro.send( @config.pomodoro.default ) )
44
+ end
45
+
46
+ end # }}}
47
+
48
+ # @fn def short {{{
49
+ # @brief Plays short Pomodoro clock (5 min)
50
+ desc 'short', 'Plays short Pomodoro clock (5 min) so that you can concentrate'
51
+ def short
52
+
53
+ @logger.message :debug, 'Running sanity check for Pomodoro task'
54
+ sanity_check
55
+
56
+ if( options[:stream] )
57
+ @logger.message :info, 'Streaming from Remote via github.com raw (use CTRL+C to abort)'
58
+ @logger.message :warning, 'Please do not hammer github.com, download if possible instead'
59
+
60
+ play_remote( @urls.pomodoro.short )
61
+ else
62
+ @logger.message :info, 'Playing local file (use CTRL+C to abort)'
63
+
64
+ play_local( @assets.pomodoro.short )
65
+ end
66
+
67
+ end # }}}
68
+
69
+
70
+ private
71
+
72
+ no_tasks do
73
+
74
+ # @fn def sanity_check {{{
75
+ # @brief Performs sanity check on online status and required assets
76
+ def sanity_check
77
+
78
+ # Either we stream or we use download / cached version
79
+ if( options[:stream] )
80
+ raise ArgumentError, 'Need to have access to Internet to be able to stream' unless( online? )
81
+ else
82
+ # Download needed?
83
+ broken = check_assets
84
+
85
+ unless( broken.empty? )
86
+ raise ArgumentError, "Need to have access to Internet to be able to download missing assets" unless( online? )
87
+
88
+ # Download!
89
+ broken.each do |type|
90
+ @logger.message :trace, "Downloading missing pomodoro asset (#{type})"
91
+ download @urls.pomodoro.send( type ), @assets.pomodoro.send( type )
92
+ end # of broken.each
93
+
94
+ end # of unless broken.empty?
95
+ end # of if( options[:stream] )
96
+
97
+ end # of def sanity_check }}}
98
+
99
+ # @fn def check_assets {{{
100
+ # @brief Checks local assets for pomodoro task, and if missing returns array with missing keyword
101
+ #
102
+ # @return [Array] Returns array with missing keywords, e.g. "short", "normal"
103
+ def check_assets
104
+ broken = []
105
+
106
+ %w[short normal].each do |type|
107
+ broken << type unless( File.exist?( @assets.pomodoro.send( type ) ) )
108
+ end # of %w[]
109
+
110
+ broken
111
+ end # def check_assets }}}
112
+
113
+ end # of no_tasks do
114
+
115
+ end # of Class New
116
+
117
+
118
+ # vim:ts=2:tw=100:wm=100:syntax=ruby
@@ -7,30 +7,10 @@ require 'andand'
7
7
  require 'fileutils'
8
8
 
9
9
 
10
-
10
+ # @fn class ProjectBuilder
11
+ # @brief Handles project bootstrapping via convenient Fox DSL
11
12
  class ProjectBuilder
12
13
 
13
- attr_reader :name
14
-
15
- TEMPLATES = {
16
- :exe =>
17
- <<-EOT
18
- #!/usr/bin/ruby -w
19
-
20
- require 'rubygems'
21
- require 'commandline
22
- require '%name%'
23
-
24
- class %name.capitalize%App < CommandLine::Application
25
- def initialize
26
- end
27
-
28
- def main
29
- end
30
- end#class %name.capitalize%App
31
- EOT
32
- }
33
-
34
14
  def initialize name
35
15
  @name = name
36
16
  @top_level_dir = Dir.pwd
@@ -41,16 +21,17 @@ EOT
41
21
  @cwd = @project_dir
42
22
  end
43
23
 
44
- def create_project
45
- yield
46
- end # of def create_project }}}
47
-
48
24
  def self.load project_name, dsl
49
25
  proj = new( project_name )
50
26
  proj = proj.instance_eval( File.read(dsl), dsl )
51
27
  proj
52
28
  end # of def self.load }}}
53
29
 
30
+
31
+ def create_project
32
+ yield
33
+ end # of def create_project }}}
34
+
54
35
  def dir dir_name
55
36
  old_cwd = @cwd
56
37
  @cwd = File.join(@cwd, dir_name)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.6.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bjoern Rennhak
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: progressbar
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'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: datamapper
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -346,6 +360,20 @@ dependencies:
346
360
  - - ">="
347
361
  - !ruby/object:Gem::Version
348
362
  version: '0'
363
+ - !ruby/object:Gem::Dependency
364
+ name: taglib-ruby
365
+ requirement: !ruby/object:Gem::Requirement
366
+ requirements:
367
+ - - ">="
368
+ - !ruby/object:Gem::Version
369
+ version: '0'
370
+ type: :runtime
371
+ prerelease: false
372
+ version_requirements: !ruby/object:Gem::Requirement
373
+ requirements:
374
+ - - ">="
375
+ - !ruby/object:Gem::Version
376
+ version: '0'
349
377
  description: Commandline interface and library to the Fox Scientific Paper Suite
350
378
  email:
351
379
  - bjoern@clothesnetwork.com
@@ -389,6 +417,8 @@ files:
389
417
  - lib/fox/interface/thor/default.rb
390
418
  - lib/fox/interface/thor/info.thor
391
419
  - lib/fox/interface/thor/init.rb
420
+ - lib/fox/interface/thor/mixin/audio.rb
421
+ - lib/fox/interface/thor/mixin/config.rb
392
422
  - lib/fox/interface/thor/mixin/config_choice.rb
393
423
  - lib/fox/interface/thor/mixin/configuration.rb
394
424
  - lib/fox/interface/thor/mixin/database.rb
@@ -402,8 +432,10 @@ files:
402
432
  - lib/fox/interface/thor/mixin/history.rb
403
433
  - lib/fox/interface/thor/mixin/logger.rb
404
434
  - lib/fox/interface/thor/mixin/model.rb
435
+ - lib/fox/interface/thor/mixin/network.rb
405
436
  - lib/fox/interface/thor/mixin/shell.rb
406
437
  - lib/fox/interface/thor/new.thor
438
+ - lib/fox/interface/thor/pomodoro.thor
407
439
  - lib/fox/interface/thor/version.rb
408
440
  - lib/fox/library/choice.rb
409
441
  - lib/fox/library/logger.rb