Веселин обнови решението на 15.12.2015 21:30 (преди около 9 години)
+module LazyMode
+ require 'date'
+
+ @notes = {}
+
+ class Date
+ attr :date
+ attr_reader :year, :month, :day
+
+ def initialize(date)
+ date = date.split('-')
+ @year, @month, @day = date[0].to_i, date[1].to_i, date[2].to_i
+
+ @date = "%04d" % @year << "-" << "%02d" % @month << "-" << "%02d" % @day
+ end
+
+ def to_s
+ @date
+ end
+ end
+
+ class Note
+ attr_reader :header, :file_name, :body, :status, :tags, :repeat
+
+ def initialize(header, tags = [], file_name, block)
+ @header, @tags, @status, @body = header, tags, :topostpone, ''
+ @file_name = file_name
+ @repeat_toggle = false
+ instance_eval &block
+ end
+
+ def scheduled(date = nil)
+ if date.nil? then return @scheduled end
+ date = date.split(' ')
+ @scheduled = Date.new(date[0]).to_s
+ @repeat = date[1] if date.size > 1
+ end
+
+ def status(value = nil)
+ if value.nil? then @status else @status = value end
+ end
+
+ def body(value = nil)
+ if value.nil? then @body else @body = value end
+ end
+
+ def note(header, *tags, &block)
+ new_note = LazyMode::Note.new(header, tags, @file_name, block)
+ LazyMode::notes[@file_name] << new_note
+ end
+
+ def date
+ if not @repeat.nil?
+ Date.new(repeat_date)
+ else
+ Date.new(scheduled)
+ end
+ end
+
+ def repeat_date
+ return if @repeat.nil?
+ first = @repeat[1, @repeat.length]
+ period = first.slice!(first.length - 1)
+ days = LazyMode.period_days(period)
+ new_date = ::DateTime.strptime(scheduled, '%Y-%m-%d')
+ (new_date + (first.to_i * days)).strftime('%Y-%m-%d')
+ end
+
+ def use_repeat(value)
+ @repeat_toggle = value
+ end
+ end
+
+ class File
+ def initialize(name)
+ @name = name
+ end
+
+ def name
+ @name
+ end
+
+ def notes
+ LazyMode::notes[@name]
+ end
+
+ def daily_agenda(date)
+ agenda = Filter.new
+ agenda.notes = notes.select do |note|
+ repeat_check(date, note)
+ date.to_s == note.scheduled or date.to_s == note.repeat_date
+ end
+ agenda
+ end
+
+ def weekly_agenda(date)
+ agenda = Filter.new
+ agenda.notes = notes.select do |note|
+ repeat_check(date, note)
+ week_date_check(date, note)
+ end
+ agenda
+ end
+
+ def repeat_check(date, note)
+ if date == note.repeat_date
+ note.use_repeat(true)
+ else
+ note.use_repeat(false)
+ end
+ end
+
+ def week_date_check(date, note)
+ new_date, dates = ::DateTime.strptime(date.to_s, '%Y-%m-%d'), []
+ (0..6).each { |i| dates << (new_date + i).strftime('%Y-%m-%d') }
+ dates.include?(note.scheduled) or dates.include?(note.repeat_date)
+ end
+ end
+
+ class Filter
+ attr_accessor :notes
+
+ def initialize
+ @notes = []
+ end
+
+ def where(tag: nil, text: nil, status: nil)
+ a = filter_tag(tag) if not tag.nil?
+ a.filter_text(text) if not text.nil?
+ a.filter_status(status) if not status.nil?
+ a
+ end
+
+ def filter_tag(tag)
+ @notes.select! { |note| note.tags.include?(tag) }
+ self
+ end
+
+ def filter_text(pattern)
+ @notes.select! do |note|
+ pattern.match(note.header) or pattern.match(note.body)
+ end
+ self
+ end
+
+ def filter_status(status)
+ @notes.select! { |note| note.status == status }
+ self
+ end
+ end
+
+ class << self
+ attr_accessor :notes
+
+ def create_file(name, &block)
+ @current_file = name
+ @notes[name] = [] if not @notes.has_key?(name)
+ class_eval &block
+ @current_file = nil
+
+ LazyMode::File.new(name)
+ end
+
+ def note(header, *tags, &block)
+ new_note = LazyMode::Note.new(header, tags, @current_file, block)
+ @notes[@current_file] << new_note
+ end
+
+ def scheduled(date)
+
+ end
+
+ def period_days(period)
+ case period
+ when 'd' then 1
+ when 'w' then 7
+ when 'm' then 30
+ end
+ end
+ end
+end