rubyshelltools 0.0.10 → 0.0.11

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.
data/README.md CHANGED
@@ -11,7 +11,16 @@ name wasn't available at rubygems anymore ;-)
11
11
 
12
12
  Since bash-history isn't always enough persistent for my daily work, I deal with the idea to create a kinda 'central toolbox' for my shell. RST represents the first steps in this direction. I'm not sure if the 'project' will survive, tho. I'll give it a try.
13
13
 
14
- The first pushed version features a very simple 'ls' and 'calendar'-command. The plan is to play around with the structure of the gem until I'm satisfied and feel comfortable to start implementing more features. There's a ton of ideas what RST could do, I'm just not sure what it shall do. Let's see ...
14
+ Current version features a very simple 'ls' and 'calendar'-command.
15
+ There is a command-line-version `bin/rst` and a Curses-version `bin/rst-ui`.
16
+ A Sinatra-version will be added later.
17
+
18
+ **Branches**
19
+
20
+ * _master_ - core and command-line version
21
+ * _curses_ - core, command-line, and Curses implementation
22
+
23
+ The plan is to play around with the structure of the gem until I'm satisfied and feel comfortable to start implementing more features. There's a ton of ideas what RST could do, I'm just not sure what it shall do. Let's see ...
15
24
 
16
25
 
17
26
  Install from rubygems.org
data/bin/rst-ui ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'curses'
4
+
5
+ require_relative '../lib/rst'
6
+ require_relative '../lib/load'
7
+ include RST
8
+
9
+ # ACTIONS CALLED BY MAIN-LOOP
10
+
11
+ def display_calendar screen,from,to
12
+ store = Persistent::DiskStore.new(CALENDAR_FILE)
13
+ screen.clear
14
+ screen.print_screen( _print_calendar(store, from,to ))
15
+ screen.status( _print_status_line(from,to))
16
+ end
17
+
18
+ def clear_screen(screen)
19
+ screen.clear
20
+ end
21
+
22
+ def print_year(screen)
23
+ clear_screen(screen)
24
+ screen.print_screen( _year_banner )
25
+ screen.status( "c=calender, q=quit" )
26
+ end
27
+
28
+ # HELPERS
29
+
30
+ def _year_banner
31
+ [ '', ' RubyShellTools'," #{VERSION}" ] +
32
+ `banner -w 32 #{Date.today.year}`.split(/\n/).map{|line|" #{line}"} +
33
+ ['']*3
34
+ end
35
+
36
+ def _print_status_line(from,to)
37
+ "#{(Time.now+from.weeks).strftime('%Y-%m-%d')} " +
38
+ "to #{(Time.now+to.weeks).strftime('%Y-%m-%d')} " +
39
+ "[<up> -5w, <down> +5w, <c> today, <enter> clear]"
40
+ end
41
+
42
+ def _print_calendar(store, from, to)
43
+ store.all.map { |calendar|
44
+ calendar.name + "\n" +
45
+ calendar.to_text("#{from}w","#{to}w").to_s
46
+ }.join("\n\n").split(/\n/)
47
+ end
48
+
49
+
50
+ # MAIN
51
+
52
+ # Initialize the controller
53
+ # Loop getch until 'q' is received
54
+ # Arrow-keys changes the range for from and to by months/years
55
+ # Enter clears the screen (shows the current year as banner)
56
+ # 'r' does nothing to demonstrate the noop function ;-)
57
+ # 'q' quits the loop and ends the program.
58
+ # Curses gets shut down when CoursesController gets dropped by the GC.
59
+ CursesController.new(ARGV).tap do |controller|
60
+
61
+ from = -1 # show calendar from today -1 week
62
+ to = 5 # show calendar to today + 5 weeks
63
+
64
+ loop do
65
+ case Curses.getch
66
+ when Curses::Key::UP then from -= 4; to -= 4; display_calendar(controller,from,to)
67
+ when Curses::Key::DOWN then from += 4; to += 4; display_calendar(controller,from,to)
68
+ when Curses::Key::LEFT then from -= 52; to -= 52; display_calendar(controller,from,to)
69
+ when Curses::Key::RIGHT then from += 52; to += 52; display_calendar(controller,from,to)
70
+ when ?c then from = -1; to = 5; display_calendar(controller,from,to)
71
+ when 10 then print_year(controller) #ENTER
72
+ when ?r then clear_screen(controller); controller.noop
73
+ when ?q then break
74
+ end
75
+ end
76
+
77
+ end
78
+
@@ -0,0 +1,124 @@
1
+ require 'curses'
2
+
3
+ module RST
4
+
5
+ # Controll the curses-lib
6
+ # @example
7
+ # cc = CursesController.new
8
+ # cc.print_scren( ['Line 1', 'Line 2', ...] )
9
+ # cc.clear
10
+ # cc.status 'It works'
11
+ #
12
+ class CursesController
13
+
14
+ include Curses
15
+
16
+ # Available colors provided by Curses
17
+ COLORS = [ COLOR_BLACK,COLOR_RED,COLOR_GREEN,COLOR_YELLOW,COLOR_BLUE,
18
+ COLOR_MAGENTA,COLOR_CYAN,COLOR_WHITE ]
19
+
20
+ # @group public api
21
+
22
+ # Initialize and register a finalizer to close curses
23
+ # whenever this object gets destroyed by the GC.
24
+ def initialize(*)
25
+ init_curses
26
+ ObjectSpace.define_finalizer( self, self.class.finalize )
27
+ clear
28
+ end
29
+
30
+ # Outputs array of lines from 0,0 to max-lines
31
+ # @param [Array] lines - lines to output
32
+ def print_screen(lines)
33
+ color_pair = 1
34
+ lines.each_with_index do |line,lno|
35
+ color_pair = color_pair == 1 ? 2 : 1
36
+ write(lno, 0, block_given? ? yield(line,lno) : line, color_pair)
37
+ break if lno > height-3
38
+ end
39
+ end
40
+
41
+
42
+ # update the status-line
43
+ # @param [String] message
44
+ def status(message)
45
+ message += '-' * (status_line_length - message.length)
46
+ write(status_line, 0, message, 1 )
47
+ end
48
+
49
+ # No operation - called when an unknown key is pressed
50
+ # to show any response
51
+ def noop
52
+ write(0,0,"NOOP #{Time.now.to_s}"+" "*5)
53
+ end
54
+
55
+ # Clear the screen and rewrite the status-bar
56
+ def clear
57
+ Curses.clear
58
+ status "q=Quit c=Calendar <enter>=Clear screen"
59
+ end
60
+
61
+ #@endgroup
62
+
63
+ private
64
+
65
+ # Output a line of text and clear to the end of line
66
+ # @param [Integer] line - the line to write to 0=top of screen
67
+ # @param [Integer] column - the column to start at 0=left most col.
68
+ # @param [String] text - the text to write
69
+ # @param [Integer] color_pair - which color to use (or random)
70
+ def write(line, column, text, color_pair=@color_pairs.sample)
71
+ Curses.setpos(line, column)
72
+ Curses.attron(color_pair(color_pair)|A_NORMAL) do
73
+ Curses.addstr(text+ ' '*(status_line_length-column-text.length))
74
+ end
75
+ end
76
+
77
+ # @return [Integer] - number of lines available at current screen
78
+ def height
79
+ Curses.lines
80
+ end
81
+
82
+ # Initialize the Curses-environment
83
+ def init_curses
84
+ Curses.noecho # do not show typed keys
85
+ Curses.init_screen
86
+ Curses.start_color
87
+ @screen=Curses.stdscr
88
+ @screen.keypad(true) # enable arrow keys
89
+ init_colors
90
+ end
91
+
92
+ # Create color-pairs fg/bg for each combination of
93
+ # given colors (see top of file)
94
+ def init_colors
95
+ @color_pairs = []
96
+ COLORS.each_with_index do |fg,fgi|
97
+ (COLORS-[fg]).each_with_index do |bg,bgi|
98
+ Curses.init_pair(fgi*10+bgi,fg,bg)
99
+ @color_pairs << fgi*10+bgi
100
+ end
101
+ end
102
+ end
103
+
104
+ # @return [Integer] - number of columns (width) of the screen
105
+ def status_line_length
106
+ Curses.cols
107
+ end
108
+
109
+ # @return [Integer] - bottom of screen
110
+ def status_line
111
+ Curses.lines-1
112
+ end
113
+
114
+
115
+ # Finalize get's called when the CG will free the object.
116
+ # The call to this function was registered in the constructor.
117
+ def self.finalize
118
+ proc do
119
+ Curses.close_screen
120
+ end
121
+ end
122
+
123
+ end
124
+ end
data/lib/load.rb CHANGED
@@ -27,6 +27,9 @@ unless defined? LIB_LOADED
27
27
  $LOAD_PATH.unshift(File.expand_path('../errors',__FILE__))
28
28
  require 'store_errors'
29
29
 
30
+ $LOAD_PATH.unshift(File.expand_path('../curses',__FILE__))
31
+ require 'curses_controller'
32
+
30
33
  $LOAD_PATH.unshift(File.expand_path('../modules/calendar',__FILE__))
31
34
  require 'calendar'
32
35
  require 'eventable'
@@ -40,8 +40,6 @@ module RST
40
40
  #
41
41
  module Calendar
42
42
 
43
- include CalendarHelper
44
-
45
43
  # Calendar has a name and will be stored in Persistent::DiskStore(CALENDAR_FILE)
46
44
  # with it's name as the id. Thus you can save different calendars in
47
45
  # the same file. If no name is given 'unnamed' will be the default.
@@ -55,7 +53,7 @@ module RST
55
53
 
56
54
  # @group public API
57
55
 
58
- attr_reader :name, :start_date, :end_date, :events
56
+ attr_reader :name, :start_date, :end_date
59
57
 
60
58
  # @param [String] _name Name and persistent-id of this calendar.
61
59
  # @param [Date|Time|String] _start The date when the calendar starts
@@ -66,7 +64,21 @@ module RST
66
64
  @name = _name
67
65
  @start_date = parse_date_param(_start)
68
66
  @end_date = parse_date_param(_end)
69
- @events = _events
67
+ @_events = _events
68
+ end
69
+
70
+ # Return sorted events
71
+ # @return [Array] of Event-objects
72
+ def events
73
+ (@_events||=[]).sort { |a,b| a.event_date <=> b.event_date }
74
+ end
75
+
76
+ # Remove events from calendar by event-ids
77
+ # @param [Array] ids - ids to remove
78
+ def reject_events_by_id!(*ids)
79
+ @_events.reject! do |e|
80
+ ids.include?(e.id)
81
+ end
70
82
  end
71
83
 
72
84
 
@@ -92,7 +104,7 @@ module RST
92
104
  # Add Eventables to the calendar
93
105
  # @param [Eventable] add - the Object to add
94
106
  def <<(add)
95
- events << add
107
+ @_events << add
96
108
  end
97
109
 
98
110
  # Calculate the span between start and end in seconds
data/lib/rst.rb CHANGED
@@ -338,7 +338,7 @@ module RST
338
338
  def delete_events
339
339
  store = Persistent::DiskStore.new(CALENDAR_FILE)
340
340
  calendar = store.find(@options[:name])
341
- calendar.events.reject!{|r| @options[:delete_events].include?(r.id)}
341
+ calendar.reject_events_by_id!(*@options[:delete_events])
342
342
  store << calendar
343
343
  end
344
344
 
data/rst.rb CHANGED
@@ -3,7 +3,7 @@ require 'logger'
3
3
  # # Ruby Shell Tools Top-level file
4
4
  module RST
5
5
  # Gem-version
6
- VERSION = '0.0.10'
6
+ VERSION = '0.0.11'
7
7
 
8
8
  # Path to the docs used by the software
9
9
  DOCS = File.expand_path('../assets/docs', __FILE__)
metadata CHANGED
@@ -1,18 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubyshelltools
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Andi Altendorfer
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-04-05 00:00:00.000000000 Z
12
+ date: 2013-04-21 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: redcarpet
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
19
  - - '>='
18
20
  - !ruby/object:Gem::Version
@@ -20,6 +22,7 @@ dependencies:
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
27
  - - '>='
25
28
  - !ruby/object:Gem::Version
@@ -27,6 +30,7 @@ dependencies:
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rspec
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
35
  - - '>='
32
36
  - !ruby/object:Gem::Version
@@ -34,6 +38,7 @@ dependencies:
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
43
  - - '>='
39
44
  - !ruby/object:Gem::Version
@@ -41,6 +46,7 @@ dependencies:
41
46
  - !ruby/object:Gem::Dependency
42
47
  name: yard
43
48
  requirement: !ruby/object:Gem::Requirement
49
+ none: false
44
50
  requirements:
45
51
  - - '>='
46
52
  - !ruby/object:Gem::Version
@@ -48,6 +54,7 @@ dependencies:
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
51
58
  requirements:
52
59
  - - '>='
53
60
  - !ruby/object:Gem::Version
@@ -56,6 +63,7 @@ description: Tools for the unix shell
56
63
  email: andreas@altendorfer.at
57
64
  executables:
58
65
  - rst
66
+ - rst-ui
59
67
  extensions: []
60
68
  extra_rdoc_files:
61
69
  - README.md
@@ -65,6 +73,7 @@ files:
65
73
  - lib/core_extensions/mutex.rb
66
74
  - lib/core_extensions/numeric.rb
67
75
  - lib/core_extensions/string.rb
76
+ - lib/curses/curses_controller.rb
68
77
  - lib/errors/store_errors.rb
69
78
  - lib/load.rb
70
79
  - lib/modules/calendar/calendar.rb
@@ -77,30 +86,36 @@ files:
77
86
  - lib/modules/persistent/store.rb
78
87
  - lib/rst.rb
79
88
  - bin/rst
89
+ - bin/rst-ui
80
90
  - README.md
81
91
  - assets/docs/examples.md
82
92
  homepage: http://rubygems.org/gems/rubyshelltools
83
- licenses: []
84
- metadata: {}
93
+ licenses:
94
+ - MIT
85
95
  post_install_message:
86
96
  rdoc_options: []
87
97
  require_paths:
88
98
  - lib
89
99
  required_ruby_version: !ruby/object:Gem::Requirement
100
+ none: false
90
101
  requirements:
91
102
  - - '>='
92
103
  - !ruby/object:Gem::Version
93
104
  version: '0'
105
+ segments:
106
+ - 0
107
+ hash: 991597406818373700
94
108
  required_rubygems_version: !ruby/object:Gem::Requirement
109
+ none: false
95
110
  requirements:
96
111
  - - '>='
97
112
  - !ruby/object:Gem::Version
98
113
  version: '0'
99
114
  requirements: []
100
115
  rubyforge_project:
101
- rubygems_version: 2.0.0
116
+ rubygems_version: 1.8.25
102
117
  signing_key:
103
- specification_version: 4
118
+ specification_version: 3
104
119
  summary: Ruby Shell Tools
105
120
  test_files: []
106
121
  has_rdoc:
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 641f55c4735fc80402667b74f37d8d6b2b91684f
4
- data.tar.gz: cce31a850e6ca5f17a5a5b63da41fdcaf3c0a144
5
- SHA512:
6
- metadata.gz: 12b4f4292524d658a3587aa3535b288b43b27dce16ffb5d68c585dfa90fa3d7b98713ae30add0e36a3517d1934cf3b774b47be099485768cd2c352e6b06c8717
7
- data.tar.gz: 7a2f0e78844f86bc2da5ad9d3c41b58daefc5b633cc11503fe17e538cf7db133ba57072adaf44e507292375d2c0ecfb73c9db5fcde55dbc970386f4fe9547c3a