Skip to content

bfeigin/tickle

 
 

Repository files navigation

tickle

http://github.com/noctivityinc/tickle
by Joshua Lippiner, Noctivity

– DESCRIPTION

Tickle is a natural language parser for recurring events.

Tickle is designed to be a compliment of Chronic and can interpret things such as “every 2 days, every Sunday, Sundays, Weekly, etc.”

Tickle has one main method, “Tickle.parse,” which returns the next time the event should occur, at which point you simply call Tickle.parse again.

– INSTALLATION

Tickle can be installed via RubyGems:

$ gem install tickle

– TINKERING

Everything’s at Github - github.com/noctivityinc/tickle

– DEPENDENCIES

chronic gem (gem install chronic)

thoughtbot’s shoulda (gem install shoulda)

USAGE

You can parse strings containing a natural language interval using the Tickle.parse method.

Tickle.parse returns the next occurrence of the event.

You can either pass a string prefixed with the word “every, each or ‘on the’” or simply the time frame. You can also pass a start date with the word “starting” (e.g. Tickle.parse(‘every 3 days starting next friday’))

Tickle returns nil if it cannot parse the string cannot be parsed.

Tickle HEAVILY uses chronic for parsing both the event and the start date.

– EXAMPLES

require 'rubygems'
require 'tickle'

Time.now
2010-04-24 12:05:51 -0400

Tickle.parse('each day')  #=> 2010-04-24 12:05:51 -0400
Tickle.parse('every day')  #=> 2010-04-24 12:05:51 -0400
Tickle.parse('every week')  #=> 2010-05-01 12:05:51 -0400
Tickle.parse('every Month')  #=> 2010-05-24 12:05:51 -0400
Tickle.parse('every year')  #=> 2011-04-24 12:05:51 -0400
Tickle.parse('daily')  #=> 2010-04-24 12:05:51 -0400
Tickle.parse('weekly')  #=> 2010-05-01 12:05:51 -0400
Tickle.parse('monthly')  #=> 2010-05-24 12:05:51 -0400
Tickle.parse('yearly')  #=> 2011-04-24 12:05:51 -0400
Tickle.parse('every 3 days')  #=> 2010-04-27 12:05:51 -0400
Tickle.parse('every 3 weeks')  #=> 2010-05-15 12:05:51 -0400
Tickle.parse('every 3 months')  #=> 2010-07-23 12:05:51 -0400
Tickle.parse('every 3 years')  #=> 2013-04-23 12:05:51 -0400
Tickle.parse('every other day')  #=> 2010-04-26 12:05:51 -0400
Tickle.parse('every other week')  #=> 2010-05-08 12:05:51 -0400
Tickle.parse('every other month')  #=> 2010-06-24 12:05:51 -0400
Tickle.parse('every other year')  #=> 2012-04-24 12:05:51 -0400
Tickle.parse('every other day starting May 1st')  #=> 2010-05-01 12:00:00 -0400
Tickle.parse('every other week starting this Sunday')  #=> 2010-04-25 12:00:00 -0400
Tickle.parse('every Monday')  #=> 2010-04-26 12:00:00 -0400
Tickle.parse('every Wednesday')  #=> 2010-04-28 12:00:00 -0400
Tickle.parse('every Friday')  #=> 2010-04-30 12:00:00 -0400
Tickle.parse('every May')  #=> 2010-05-01 12:00:00 -0400
Tickle.parse('every june')  #=> 2010-06-01 12:00:00 -0400
Tickle.parse('beginning of the week')  #=> 2010-04-25 12:00:00 -0400
Tickle.parse('middle of the week')  #=> 2010-04-28 12:00:00 -0400
Tickle.parse('end of the week')  #=> 2010-05-01 12:00:00 -0400
Tickle.parse('beginning of the month')  #=> 2010-05-01 12:00:00 -0400
Tickle.parse('middle of the month')  #=> 2010-05-15 12:00:00 -0400
Tickle.parse('end of the month')  #=> 2010-04-30 00:00:00 -0400
Tickle.parse('beginning of the year')  #=> 2011-01-01 12:00:00 -0500
Tickle.parse('middle of the year')  #=> 2010-06-15 00:00:00 -0400
Tickle.parse('end of the year')  #=> 2010-12-31 00:00:00 -0500
Tickle.parse('the 3rd of May')  #=> 2010-05-03 12:00:00 -0400
Tickle.parse('the 3rd of February')  #=> 2011-02-03 12:00:00 -0500
Tickle.parse('the 10th of the month')  #=> 2010-05-10 12:00:00 -0400
Tickle.parse('the tenth of the month')  #=> 2010-05-10 12:00:00 -0400
Tickle.parse('the first of the month')  #=> 2010-05-01 12:00:00 -0400
Tickle.parse('the thirtieth')  #=> 2010-04-30 12:00:00 -0400
Tickle.parse('the fifth')  #=> 2010-05-05 12:00:00 -0400
Tickle.parse('the 3rd Sunday of May')  #=> 2010-05-16 12:00:00 -0400
Tickle.parse('the 3rd Sunday of the month')  #=> 2010-05-16 12:00:00 -0400
Tickle.parse('the 23rd of June')  #=> 2010-06-23 12:00:00 -0400
Tickle.parse('the twenty third of June')  #=> 2010-06-23 12:00:00 -0400
Tickle.parse('the thirty first of August')  #=> 2010-08-31 12:00:00 -0400
Tickle.parse('the twenty first')  #=> 2010-05-21 12:00:00 -0400
Tickle.parse('the twenty first of the month')  #=> 2010-05-21 12:00:00 -0400

– USING IN APP

To use in your app, we recommend adding two attributes to your database model:

  • next_occurrence

  • tickle_query

Then call Tickle.parse(query) when you need to and save the results accordingly. In your code, each day, simply check to see if today is >= next_occurrence and, if so, run your block.

After it completes, call Tickle.parse(tickle_query) again to update the next occurrence of the event.

– LIMITATIONS

Currently, Tickle only works for day intervals but feel free to fork and add time-based interval support or send me a note if you really want me to add it.

CREDIT

HUGE shout-out to both the creator of Chronic, Tom Preston-Werner (chronic.rubyforge.org/) as well as Brian Brownling who maintains a github version at github.com/mojombo/chronic.

Without their work and code structure I’d be lost.

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don’t break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright © 2010 Joshua Lippiner. See LICENSE for details.

About

Natural language parser for recurring events

Resources

License

Stars

Watchers

Forks

Packages

No packages published