Виктор обнови решението на 21.12.2015 11:57 (преди около 9 години)
+module LazyMode
+ attr_accessor :name, :notes
+
+ class Date
+ attr_accessor :year, :month, :day
+
+ def initialize(date = '')
+ date_as_array = date.split('-')
+ @year = date_as_array[0].to_i
+ @month = date_as_array[1].to_i
+ @day = date_as_array[2].to_i
+ end
+
+ def to_s
+ [year.to_s.rjust(4, '0'), month.to_s.rjust(2, '0'),
+ day.to_s.rjust(2, '0')].join('-')
+ end
+
+ def to_days
+ year * 360 + (month - 1) * 30 + day - 1
+ end
+
+ def +(integer)
+ result = Date.new
+ days = to_days + integer
+ result.year = days / 360
+ result.month = (days % 360) / 30 + 1
+ result.day = (days % 30) + 1
+ result
+ end
+ end
+
+ class Note
+ attr_reader :header, :tags, :file_name, :repetition
+
+ def initialize(header, file_name, *tags)
+ @header = header
+ @tags = tags
+ @body = ''
+ @status = :topostpone
+ @file_name = file_name
+ end
+
+ def body(information = nil)
+ @body = information unless information.nil?
+ @body
+ end
+
+ def status(new_status = nil)
+ @status = new_status unless new_status.nil?
+ @status
+ end
+
+ def string_to_days(string)
+ period = string.to_i
+ preriod += 1 if period == 0
+ type = string.chars.last
+ type_to_days = { 'd' => 1, 'w' => 7, 'm' => 30 }
+ type_to_days[type] * period
+ end
+
+ def scheduled(date)
+ array_for_repetition = date.split(' +')
+ @scheduled = Date.new(array_for_repetition.first)
+ if array_for_repetition.size > 1
+ @repetition = string_to_days(array_for_repetition.last)
+ else @repetition = 0
+ end
+ end
+
+ def note(header, *tags, &block)
+ LazyMode::note(header, *tags, &block)
+ end
+
+ def date
+ @scheduled
+ end
+
+ def date=(new_date)
+ @scheduled = new_date
+ end
+ end
+
+ class File
+ attr_accessor :name, :notes
+
+ def initialize(name)
+ @name = name
+ @notes = []
+ end
+
+ def check_for_date(note, date)
+ differ, repeat = note.date.to_days - date.to_days, note.repetition
+ return note if differ == 0
+ new_note = note.dup
+ new_note.date = date
+ return new_note if differ < 0 and repeat > 0 and differ % repeat == 0
+ nil
+ end
+
+ def daily_agenda(date)
+ result = AgendaFile.new
+ notes.each do |note|
+ result.notes << check_for_date(note, date)
+ end
+ result.notes.select! { |note| note != nil }
+ result
+ end
+
+ def up_to_date(note, date)
+ new_note = note.dup
+ differ = note.date.to_days - date.to_days
+ while differ < 0
+ differ += note.repetition
+ new_note.date = new_note.date + note.repetition
+ end
+ new_note
+ end
+
+ def check_for_week(note, date)
+ differ, repeat = note.date.to_days - date.to_days, note.repetition
+ return note if differ >= 0 and differ < 7 and repeat == 0
+ return nil if repeat == 0
+ new_note = up_to_date(note, date)
+ return new_note if new_note.date.to_days - date.to_days < 7
+ nil
+ end
+
+ def weekly_agenda(date)
+ result = AgendaFile.new
+ notes.each do |note|
+ result.notes << check_for_week(note, date)
+ end
+ result.notes.select! { |note| note != nil }
+ result
+ end
+ end
+
+ class AgendaFile
+ attr_accessor :notes
+
+ def initialize
+ @notes = []
+ end
+
+ def appropriate_tag(note, tag)
+ return true if tag.nil?
+ note.tags.include? tag
+ end
+
+ def appropriate_text(note, text)
+ return true if text.nil?
+ text.match note.header or text.match note.body
+ end
+
+ def appropriate_status(note, status)
+ return true if status.nil?
+ note.status == tag
+ end
+
+ def where(hash)
+ result = self.dup
+ result.notes.select! { |note| appropriate_tag(note, hash[:tag]) }
+ result.notes.select! { |note| appropriate_text(note, hash[:text]) }
+ result.notes.select! { |note| appropriate_status(note, hash[:status]) }
+ result
+ end
+ end
+
+ def self.create_file(name, &block)
+ @name = name
+ @notes = []
+ file = File.new(name)
+ self.instance_exec(&block)
+ file.notes = @notes
+ file
+ end
+
+ def self.note(header, *tags, &block)
+ result = Note.new(header, @name, *tags)
+ result.instance_exec(&block)
+ @notes << result
+ end
+end