Решение на Седма задача от Николай Коцев

Обратно към всички решения

Към профила на Николай Коцев

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 25 успешни тест(а)
  • 6 неуспешни тест(а)

Код

## src/lazy_mode/agenda.rb
module LazyMode
class Agenda
attr_accessor :notes, :date
def initialize (notes, date = nil)
@notes = notes.map {|note| NoteProxy.new(date, note)}
@date = date
end
def where(options = {})
Agenda.new(Filter.new(@notes, options).filter)
end
class Filter
def initialize(notes, options)
@notes = notes.dup
@options = options
end
def filter
filter_status if @options[:status]
filter_tag if @options[:tag]
filter_text if @options[:text]
@notes
end
def filter_status
@notes.select! { |note| note.status == @options[:status] }
end
def filter_tag
@notes.select! { |note| note.tags.include?(@options[:tag]) }
end
def filter_text
@notes.select! do |note|
note.header =~ @options[:text] || note.body =~ @options[:text]
end
end
end
class NoteProxy
attr_reader :date, :note
def initialize(date = nil, note)
@date = date || note.date
@note = note
end
def method_missing(name, *args, &block)
@note.send(name, *args, &block)
end
end
end
end
# src/lazy_mode/date.rb
module LazyMode
class Date
@@repeater_values = {
"d" => 1,
"w" => 7,
"m" => 30,
}
attr_reader :day, :month, :year
def self.date_hash(number)
hash = {}
{year: 360, month: 30, day: 1}.each_pair do |type, value|
hash[type] = number / value
number -= hash[type] * value
end
hash
end
def self.build_from_number(number)
raise "No negative dates" if number < 0
hash = date_hash(number)
date_string = "#{hash[:year].to_s.rjust(4, '0')}-"
date_string += "#{hash[:month].to_s.rjust(2, '0')}-"
date_string += "#{hash[:day].to_s.rjust(2, '0')}"
new(date_string)
end
def initialize(date)
match_object = date.match(/(\d{4,4})-(\d\d)-(\d\d)\s?\+?(\d+[dwm])?/)
if match_object
@year = match_object[1].to_i
@month = match_object[2].to_i
@day = match_object[3].to_i
@repeater = match_object[4]
end
end
def to_s
year_string = @year.to_s.rjust(4, '0')
month_string = @month.to_s.rjust(2, '0')
day_string = @day.to_s.rjust(2, '0')
"#{year_string}-#{month_string}-#{day_string}"
end
def to_i
30 * 12 * @year + 30 * @month + @day
end
def ==(other)
check_equality(other) || other.check_equality(self)
end
def check_equality(other_date)
own_number, other_number = to_i, other_date.to_i
return own_number == other_number unless @repeater
return false if own_number > other_number
number = @repeater.match(/(\d+)/)[0].to_i
number * @@repeater_values[@repeater.match(/\d+(\w)/)[1]]
(other_number - own_number) % number == 0
end
def successor
self.class.build_from_number(to_i + 1)
end
end
end
# src/lazy_mode/file.rb
module LazyMode
class File
attr_reader :name, :notes
def initialize(name, notes)
@name = name
@notes = notes
end
def daily_agenda(date)
agenda_notes = notes_recursively.select {|note| note.date == date}
LazyMode::Agenda.new(agenda_notes, date)
end
def weekly_agenda(date)
agenda_notes = []
new_date = date.dup
7.times do
#current_day_comparator = -> (note) { note.date == new_date }
#agenda_notes << notes_recursively.select(&current_day_comparator)
agenda_notes << current_date_notes(new_date)
new_date = new_date.successor
end
LazyMode::Agenda.new(agenda_notes.flatten.uniq)
end
def current_date_notes(date)
notes_recursively.select { |note| note.date == date }
end
def notes_recursively
@notes.map { |note| note.notes_recursively }.flatten
end
end
end
# src/lazy_mode/notable.rb
module LazyMode
module Notable
attr_accessor :notes
# Don't forget to change NoteBuilder#note, too
# Had to do the terrible thing with the splat *, because of skeptic
def note(header, * tags, &block)
note_builder = LazyMode::NoteBuilder.new(header, tags, @file_name)
note_builder.instance_eval(&block)
@notes << note_builder.build
end
end
end
# src/lazy_mode/lazy_mode.rb
module LazyMode
class << self
def create_file(name, &block)
file_builder = FileBuilder.new(name)
file_builder.instance_eval(&block)
file_builder.build
end
end
class FileBuilder
attr_accessor :file_name
include Notable
def initialize(file_name)
@file_name = file_name
@notes = []
end
def build
File.new(@file_name, @notes)
end
end
end
# src/lazy_mode/note.rb
module LazyMode
class Note
attr_accessor :header, :file_name, :body, :status, :tags, :date, :notes
def initialize(options = {})
@header = options[:header]
@file_name = options[:file_name]
@date, @body = options[:date], options[:body]
@status = options[:status] || :topostpone
@tags = options[:tags] || []
@notes = options[:notes] || []
end
def notes_recursively
@notes.map { |note| note.notes_recursively } + [self]
end
end
end
# src/lazy_mode/note_builder.rb
module LazyMode
class NoteBuilder
# include LazyMode::Notable
def initialize(header, tags, file_name)
@header = header
@tags = tags
@file_name = file_name
@notes = []
end
def build
Note.new({header: @header, file_name: @file_name, tags: @tags,
date: @date, status: @status, body: @body, notes: @notes})
end
# Don't forget to change Notable#note too
def note(header, *tags, &block)
note_builder = NoteBuilder.new(header,tags, @file_name)
note_builder.instance_eval(&block)
@notes << note_builder.build
end
def scheduled(date_string)
@date = Date.new(date_string)
end
def status(status)
@status = status
end
def body(body)
@body = body
end
end
end

Лог от изпълнението

.....F.....F..F....FFF.........

Failures:

  1) LazyMode LazyMode::Note can have nested notes
     Failure/Error: expect(file.notes.first.body).to eq('')
       
       expected: ""
            got: nil
       
       (compared using ==)
     # /tmp/d20160107-5693-173j34s/spec.rb:114:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) LazyMode LazyMode::Note #body can have no body
     Failure/Error: expect(file.notes.first.body).to eq('')
       
       expected: ""
            got: nil
       
       (compared using ==)
     # /tmp/d20160107-5693-173j34s/spec.rb:94:in `block (4 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) LazyMode#daily_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.daily_agenda(LazyMode::Date.new('2012-12-12'))
     TypeError:
       nil can't be coerced into Fixnum
     # /tmp/d20160107-5693-173j34s/solution.rb:106:in `*'
     # /tmp/d20160107-5693-173j34s/solution.rb:106:in `to_i'
     # /tmp/d20160107-5693-173j34s/solution.rb:114:in `check_equality'
     # /tmp/d20160107-5693-173j34s/solution.rb:110:in `=='
     # /tmp/d20160107-5693-173j34s/solution.rb:139:in `block in daily_agenda'
     # /tmp/d20160107-5693-173j34s/solution.rb:139:in `select'
     # /tmp/d20160107-5693-173j34s/solution.rb:139:in `daily_agenda'
     # /tmp/d20160107-5693-173j34s/spec.rb:174:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
     Failure/Error: expect(agenda.notes.size).to eq(2)
       
       expected: 2
            got: 1
       
       (compared using ==)
     # /tmp/d20160107-5693-173j34s/spec.rb:271:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) LazyMode#weekly_agenda returns note scheduled with weekly repeater
     Failure/Error: agenda = file.weekly_agenda(LazyMode::Date.new('2012-12-10'))
     TypeError:
       nil can't be coerced into Fixnum
     # /tmp/d20160107-5693-173j34s/solution.rb:106:in `*'
     # /tmp/d20160107-5693-173j34s/solution.rb:106:in `to_i'
     # /tmp/d20160107-5693-173j34s/solution.rb:114:in `check_equality'
     # /tmp/d20160107-5693-173j34s/solution.rb:110:in `=='
     # /tmp/d20160107-5693-173j34s/solution.rb:156:in `block in current_date_notes'
     # /tmp/d20160107-5693-173j34s/solution.rb:156:in `select'
     # /tmp/d20160107-5693-173j34s/solution.rb:156:in `current_date_notes'
     # /tmp/d20160107-5693-173j34s/solution.rb:149:in `block in weekly_agenda'
     # /tmp/d20160107-5693-173j34s/solution.rb:146:in `times'
     # /tmp/d20160107-5693-173j34s/solution.rb:146:in `weekly_agenda'
     # /tmp/d20160107-5693-173j34s/spec.rb:294:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) LazyMode#weekly_agenda returns note scheduled with monthly repeater
     Failure/Error: expect(agenda.notes.size).to eq(1)
       
       expected: 1
            got: 2
       
       (compared using ==)
     # /tmp/d20160107-5693-173j34s/spec.rb:327:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01777 seconds
31 examples, 6 failures

Failed examples:

rspec /tmp/d20160107-5693-173j34s/spec.rb:98 # LazyMode LazyMode::Note can have nested notes
rspec /tmp/d20160107-5693-173j34s/spec.rb:88 # LazyMode LazyMode::Note #body can have no body
rspec /tmp/d20160107-5693-173j34s/spec.rb:163 # LazyMode#daily_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-173j34s/spec.rb:259 # LazyMode#weekly_agenda returns multiple notes with different dates when scheduled with daily repeater
rspec /tmp/d20160107-5693-173j34s/spec.rb:283 # LazyMode#weekly_agenda returns note scheduled with weekly repeater
rspec /tmp/d20160107-5693-173j34s/spec.rb:315 # LazyMode#weekly_agenda returns note scheduled with monthly repeater

История (3 версии и 0 коментара)

Николай обнови решението на 21.12.2015 12:32 (преди около 9 години)

+## src/lazy_mode/agenda.rb
+module LazyMode
+ class Agenda
+ attr_accessor :notes, :date
+
+ def initialize (notes, date = nil)
+ @notes = notes.map {|note| NoteProxy.new(date, note)}
+ @date = date
+ end
+
+ def where( * args)
+ raise NotImplementedError, "soon™"
+ end
+
+ class NoteProxy
+ attr_reader :date, :note
+
+ def initialize(date = nil, note)
+ @date = date || note.date
+ @note = note
+ end
+
+ def method_missing(name, *args, &block)
+ @note.send(name, *args, &block)
+ end
+ end
+ end
+end
+
+# src/lazy_mode/date.rb
+module LazyMode
+ class Date
+ @@repeater_values = {
+ "d" => 1,
+ "w" => 7,
+ "m" => 30,
+ }
+ attr_reader :day, :month, :year
+
+ def self.date_hash(number)
+ hash = {}
+ {year: 360, month: 30, day: 1}.each_pair do |type, value|
+ hash[type] = number / value
+ number -= hash[type] * value
+ end
+ hash
+ end
+
+ def self.build_from_number(number)
+ raise "No negative dates" if number < 0
+ hash = date_hash(number)
+ date_string = "#{hash[:year].to_s.rjust(4, '0')}-"
+ date_string += "#{hash[:month].to_s.rjust(2, '0')}-"
+ date_string += "#{hash[:day].to_s.rjust(2, '0')}"
+ new(date_string)
+ end
+
+
+ def initialize(date)
+ match_object = date.match(/(\d{4,4})-(\d\d)-(\d\d)\s?\+?(\d+[dwm])?/)
+ if match_object
+ @year = match_object[1].to_i
+ @month = match_object[2].to_i
+ @day = match_object[3].to_i
+ @repeater = match_object[4]
+ end
+ end
+
+ def to_s
+ year_string = @year.to_s.rjust(4, '0')
+ month_string = @month.to_s.rjust(2, '0')
+ day_string = @day.to_s.rjust(2, '0')
+ "#{year_string}-#{month_string}-#{day_string}"
+ end
+
+ def to_i
+ 30 * 12 * @year + 30 * @month + @day
+ end
+
+ def ==(other)
+ check_equality(other) || other.check_equality(self)
+ end
+
+ def check_equality(other_date)
+ own_number, other_number = to_i, other_date.to_i
+ return own_number == other_number unless @repeater
+ return false if own_number > other_number
+ number = @repeater.match(/(\d+)/)[0].to_i
+ number * @@repeater_values[@repeater.match(/\d+(\w)/)[1]]
+ (other_number - own_number) % number == 0
+ end
+
+ def successor
+ self.class.build_from_number(to_i + 1)
+ end
+ end
+end
+
+# src/lazy_mode/file.rb
+module LazyMode
+ class File
+ attr_reader :name, :notes
+
+ def initialize(name, notes)
+ @name = name
+ @notes = notes
+ end
+
+ def daily_agenda(date)
+ agenda_notes = notes_recursively.select {|note| note.date == date}
+ LazyMode::Agenda.new(agenda_notes, date)
+ end
+
+ # def weekly_agenda(date)
+ # agenda_notes = []
+ # parse_date = date.dup
+ # 7.times do
+ # agenda_notes << notes_recursively
+ # parse_date = parse_date.successor
+ # end
+ # LazyMode::Agenda.new(agenda_notes.flatten.uniq, date)
+ # end
+
+
+ def notes_recursively
+ @notes.map { |note| note.notes_recursively }.flatten
+ end
+ end
+end
+
+# src/lazy_mode/lazy_mode.rb
+module LazyMode
+ class << self
+ def create_file(name, &block)
+ file_builder = FileBuilder.new(name)
+ file_builder.instance_eval(&block)
+ file_builder.build
+ end
+ end
+
+
+ class FileBuilder
+ attr_accessor :file_name
+ include Notable
+
+ def initialize(file_name)
+ @file_name = file_name
+ @notes = []
+ end
+
+ def build
+ File.new(@file_name, @notes)
+ end
+ end
+end
+
+# src/lazy_mode/note.rb
+module LazyMode
+ class Note
+ attr_accessor :header, :file_name, :body, :status, :tags, :date, :notes
+
+ def initialize(options = {})
+ @header = options[:header]
+ @file_name = options[:file_name]
+ @date, @body = options[:date], options[:body]
+ @status = options[:status] || :topostpone
+ @tags = options[:tags] || []
+ @notes = options[:notes] || []
+ end
+
+ def notes_recursively
+ @notes.map { |note| note.notes_recursively } + [self]
+ end
+ end
+end
+
+# src/lazy_mode/note_builder.rb
+module LazyMode
+ class NoteBuilder
+ # include LazyMode::Notable
+
+ def initialize(header, tags, file_name)
+ @header = header
+ @tags = tags
+ @file_name = file_name
+ @notes = []
+ end
+
+ def build
+ Note.new({header: @header, file_name: @file_name, tags: @tags,
+ date: @date, status: @status, body: @body, notes: @notes})
+ end
+
+ # Don't forget to change Notable#note too
+ def note(header, *tags, &block)
+ note_builder = NoteBuilder.new(header,tags, @file_name)
+ note_builder.instance_eval(&block)
+ @notes << note_builder.build
+ end
+
+ def scheduled(date_string)
+ @date = Date.new(date_string)
+ end
+
+ def status(status)
+ @status = status
+ end
+
+ def body(body)
+ @body = body
+ end
+ end
+end
+
+# src/lazy_mode/notable.rb
+module LazyMode
+ module Notable
+ attr_accessor :notes
+
+ # Don't forget to change NoteBuilder#note, too
+ # Had to do the terrible thing with the splat *, because of skeptic
+ def note(header, * tags, &block)
+ note_builder = LazyMode::NoteBuilder.new(header, tags, @file_name)
+ note_builder.instance_eval(&block)
+ @notes << note_builder.build
+ end
+ end
+end

Николай обнови решението на 21.12.2015 16:57 (преди около 9 години)

## src/lazy_mode/agenda.rb
module LazyMode
class Agenda
attr_accessor :notes, :date
def initialize (notes, date = nil)
@notes = notes.map {|note| NoteProxy.new(date, note)}
@date = date
end
- def where( * args)
- raise NotImplementedError, "soon™"
- end
+ def where(options = {})
+ filter_status(filtered_notes, options)
+ end
+ class Filter
+ def initialize(notes, options)
+ @notes = notes
+ @options = options
+ end
+
+ def filter
+ filter_status if options[:status]
+ @notes
+ end
+
+ def filter_status
+ @notes.select! { |note| note.status == options[:status] }
+ end
+ end
+
+
class NoteProxy
attr_reader :date, :note
def initialize(date = nil, note)
@date = date || note.date
@note = note
end
def method_missing(name, *args, &block)
@note.send(name, *args, &block)
end
end
end
end
# src/lazy_mode/date.rb
module LazyMode
class Date
@@repeater_values = {
"d" => 1,
"w" => 7,
"m" => 30,
}
attr_reader :day, :month, :year
def self.date_hash(number)
hash = {}
{year: 360, month: 30, day: 1}.each_pair do |type, value|
hash[type] = number / value
number -= hash[type] * value
end
hash
end
def self.build_from_number(number)
raise "No negative dates" if number < 0
hash = date_hash(number)
date_string = "#{hash[:year].to_s.rjust(4, '0')}-"
date_string += "#{hash[:month].to_s.rjust(2, '0')}-"
date_string += "#{hash[:day].to_s.rjust(2, '0')}"
new(date_string)
end
def initialize(date)
match_object = date.match(/(\d{4,4})-(\d\d)-(\d\d)\s?\+?(\d+[dwm])?/)
if match_object
@year = match_object[1].to_i
@month = match_object[2].to_i
@day = match_object[3].to_i
@repeater = match_object[4]
end
end
def to_s
year_string = @year.to_s.rjust(4, '0')
month_string = @month.to_s.rjust(2, '0')
day_string = @day.to_s.rjust(2, '0')
"#{year_string}-#{month_string}-#{day_string}"
end
def to_i
30 * 12 * @year + 30 * @month + @day
end
def ==(other)
check_equality(other) || other.check_equality(self)
end
def check_equality(other_date)
own_number, other_number = to_i, other_date.to_i
return own_number == other_number unless @repeater
return false if own_number > other_number
number = @repeater.match(/(\d+)/)[0].to_i
number * @@repeater_values[@repeater.match(/\d+(\w)/)[1]]
(other_number - own_number) % number == 0
end
def successor
self.class.build_from_number(to_i + 1)
end
end
end
# src/lazy_mode/file.rb
module LazyMode
class File
attr_reader :name, :notes
def initialize(name, notes)
@name = name
@notes = notes
end
def daily_agenda(date)
agenda_notes = notes_recursively.select {|note| note.date == date}
LazyMode::Agenda.new(agenda_notes, date)
end
- # def weekly_agenda(date)
- # agenda_notes = []
- # parse_date = date.dup
- # 7.times do
- # agenda_notes << notes_recursively
- # parse_date = parse_date.successor
- # end
- # LazyMode::Agenda.new(agenda_notes.flatten.uniq, date)
- # end
+ def weekly_agenda(date)
+ agenda_notes = []
+ new_date = date.dup
+ 7.times do
+ #current_day_comparator = -> (note) { note.date == new_date }
+ #agenda_notes << notes_recursively.select(&current_day_comparator)
+ agenda_notes << current_date_notes(new_date)
+ new_date = new_date.successor
+ end
+ LazyMode::Agenda.new(agenda_notes.flatten.uniq)
+ end
+ def current_date_notes(date)
+ notes_recursively.select { |note| note.date == date }
+ end
+
def notes_recursively
@notes.map { |note| note.notes_recursively }.flatten
end
end
end
+# src/lazy_mode/notable.rb
+module LazyMode
+ module Notable
+ attr_accessor :notes
+
+ # Don't forget to change NoteBuilder#note, too
+ # Had to do the terrible thing with the splat *, because of skeptic
+ def note(header, * tags, &block)
+ note_builder = LazyMode::NoteBuilder.new(header, tags, @file_name)
+ note_builder.instance_eval(&block)
+ @notes << note_builder.build
+ end
+ end
+end
+
# src/lazy_mode/lazy_mode.rb
module LazyMode
class << self
def create_file(name, &block)
file_builder = FileBuilder.new(name)
file_builder.instance_eval(&block)
file_builder.build
end
end
class FileBuilder
attr_accessor :file_name
include Notable
def initialize(file_name)
@file_name = file_name
@notes = []
end
def build
File.new(@file_name, @notes)
end
end
end
# src/lazy_mode/note.rb
module LazyMode
class Note
attr_accessor :header, :file_name, :body, :status, :tags, :date, :notes
def initialize(options = {})
@header = options[:header]
@file_name = options[:file_name]
@date, @body = options[:date], options[:body]
@status = options[:status] || :topostpone
@tags = options[:tags] || []
@notes = options[:notes] || []
end
def notes_recursively
@notes.map { |note| note.notes_recursively } + [self]
end
end
end
# src/lazy_mode/note_builder.rb
module LazyMode
class NoteBuilder
# include LazyMode::Notable
def initialize(header, tags, file_name)
@header = header
@tags = tags
@file_name = file_name
@notes = []
end
def build
Note.new({header: @header, file_name: @file_name, tags: @tags,
date: @date, status: @status, body: @body, notes: @notes})
end
# Don't forget to change Notable#note too
def note(header, *tags, &block)
note_builder = NoteBuilder.new(header,tags, @file_name)
note_builder.instance_eval(&block)
@notes << note_builder.build
end
def scheduled(date_string)
@date = Date.new(date_string)
end
def status(status)
@status = status
end
def body(body)
@body = body
end
end
end
-
-# src/lazy_mode/notable.rb
-module LazyMode
- module Notable
- attr_accessor :notes
-
- # Don't forget to change NoteBuilder#note, too
- # Had to do the terrible thing with the splat *, because of skeptic
- def note(header, * tags, &block)
- note_builder = LazyMode::NoteBuilder.new(header, tags, @file_name)
- note_builder.instance_eval(&block)
- @notes << note_builder.build
- end
- end
-end

Николай обнови решението на 21.12.2015 17:13 (преди около 9 години)

## src/lazy_mode/agenda.rb
module LazyMode
class Agenda
attr_accessor :notes, :date
def initialize (notes, date = nil)
@notes = notes.map {|note| NoteProxy.new(date, note)}
@date = date
end
- def where(options = {})
- filter_status(filtered_notes, options)
- end
+ def where(options = {})
+ Agenda.new(Filter.new(@notes, options).filter)
+ end
- class Filter
- def initialize(notes, options)
- @notes = notes
- @options = options
- end
+ class Filter
+ def initialize(notes, options)
+ @notes = notes.dup
+ @options = options
+ end
- def filter
- filter_status if options[:status]
- @notes
- end
+ def filter
+ filter_status if @options[:status]
+ filter_tag if @options[:tag]
+ filter_text if @options[:text]
+ @notes
+ end
- def filter_status
- @notes.select! { |note| note.status == options[:status] }
- end
- end
+ def filter_status
+ @notes.select! { |note| note.status == @options[:status] }
+ end
+
+ def filter_tag
+ @notes.select! { |note| note.tags.include?(@options[:tag]) }
+ end
+
+ def filter_text
+ @notes.select! do |note|
+ note.header =~ @options[:text] || note.body =~ @options[:text]
+ end
+ end
+ end
class NoteProxy
attr_reader :date, :note
def initialize(date = nil, note)
@date = date || note.date
@note = note
end
def method_missing(name, *args, &block)
@note.send(name, *args, &block)
end
end
end
end
# src/lazy_mode/date.rb
module LazyMode
class Date
@@repeater_values = {
"d" => 1,
"w" => 7,
"m" => 30,
}
attr_reader :day, :month, :year
def self.date_hash(number)
hash = {}
{year: 360, month: 30, day: 1}.each_pair do |type, value|
hash[type] = number / value
number -= hash[type] * value
end
hash
end
def self.build_from_number(number)
raise "No negative dates" if number < 0
hash = date_hash(number)
date_string = "#{hash[:year].to_s.rjust(4, '0')}-"
date_string += "#{hash[:month].to_s.rjust(2, '0')}-"
date_string += "#{hash[:day].to_s.rjust(2, '0')}"
new(date_string)
end
def initialize(date)
match_object = date.match(/(\d{4,4})-(\d\d)-(\d\d)\s?\+?(\d+[dwm])?/)
if match_object
@year = match_object[1].to_i
@month = match_object[2].to_i
@day = match_object[3].to_i
@repeater = match_object[4]
end
end
def to_s
year_string = @year.to_s.rjust(4, '0')
month_string = @month.to_s.rjust(2, '0')
day_string = @day.to_s.rjust(2, '0')
"#{year_string}-#{month_string}-#{day_string}"
end
def to_i
30 * 12 * @year + 30 * @month + @day
end
def ==(other)
check_equality(other) || other.check_equality(self)
end
def check_equality(other_date)
own_number, other_number = to_i, other_date.to_i
return own_number == other_number unless @repeater
return false if own_number > other_number
number = @repeater.match(/(\d+)/)[0].to_i
number * @@repeater_values[@repeater.match(/\d+(\w)/)[1]]
(other_number - own_number) % number == 0
end
def successor
self.class.build_from_number(to_i + 1)
end
end
end
# src/lazy_mode/file.rb
module LazyMode
class File
attr_reader :name, :notes
def initialize(name, notes)
@name = name
@notes = notes
end
def daily_agenda(date)
agenda_notes = notes_recursively.select {|note| note.date == date}
LazyMode::Agenda.new(agenda_notes, date)
end
def weekly_agenda(date)
agenda_notes = []
new_date = date.dup
7.times do
#current_day_comparator = -> (note) { note.date == new_date }
#agenda_notes << notes_recursively.select(&current_day_comparator)
agenda_notes << current_date_notes(new_date)
new_date = new_date.successor
end
LazyMode::Agenda.new(agenda_notes.flatten.uniq)
end
def current_date_notes(date)
notes_recursively.select { |note| note.date == date }
end
def notes_recursively
@notes.map { |note| note.notes_recursively }.flatten
end
end
end
# src/lazy_mode/notable.rb
module LazyMode
module Notable
attr_accessor :notes
# Don't forget to change NoteBuilder#note, too
# Had to do the terrible thing with the splat *, because of skeptic
def note(header, * tags, &block)
note_builder = LazyMode::NoteBuilder.new(header, tags, @file_name)
note_builder.instance_eval(&block)
@notes << note_builder.build
end
end
end
# src/lazy_mode/lazy_mode.rb
module LazyMode
class << self
def create_file(name, &block)
file_builder = FileBuilder.new(name)
file_builder.instance_eval(&block)
file_builder.build
end
end
class FileBuilder
attr_accessor :file_name
include Notable
def initialize(file_name)
@file_name = file_name
@notes = []
end
def build
File.new(@file_name, @notes)
end
end
end
# src/lazy_mode/note.rb
module LazyMode
class Note
attr_accessor :header, :file_name, :body, :status, :tags, :date, :notes
def initialize(options = {})
@header = options[:header]
@file_name = options[:file_name]
@date, @body = options[:date], options[:body]
@status = options[:status] || :topostpone
@tags = options[:tags] || []
@notes = options[:notes] || []
end
def notes_recursively
@notes.map { |note| note.notes_recursively } + [self]
end
end
end
# src/lazy_mode/note_builder.rb
module LazyMode
class NoteBuilder
# include LazyMode::Notable
def initialize(header, tags, file_name)
@header = header
@tags = tags
@file_name = file_name
@notes = []
end
def build
Note.new({header: @header, file_name: @file_name, tags: @tags,
date: @date, status: @status, body: @body, notes: @notes})
end
# Don't forget to change Notable#note too
def note(header, *tags, &block)
note_builder = NoteBuilder.new(header,tags, @file_name)
note_builder.instance_eval(&block)
@notes << note_builder.build
end
def scheduled(date_string)
@date = Date.new(date_string)
end
def status(status)
@status = status
end
def body(body)
@body = body
end
end
end