Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Natural language parser for recurring events

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
test
.document
.gitignore
.rvmrc
LICENSE
README.rdoc
Rakefile
SCENARIOS.rdoc
VERSION
git-flow-version
tickle.gemspec

README.rdoc

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

Copyright © 2010 Joshua Lippiner. See LICENSE for details.

Something went wrong with that request. Please try again.