diff --git a/vendor/gems/icalendar-1.0.2/COPYING b/vendor/gems/icalendar-1.0.2/COPYING new file mode 100644 index 0000000..870a5f2 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/COPYING @@ -0,0 +1,56 @@ +Ruby is copyrighted free software by Yukihiro Matsumoto . +You can redistribute it and/or modify it under either the terms of the GPL +(see the file GPL), or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/gems/icalendar-1.0.2/GPL b/vendor/gems/icalendar-1.0.2/GPL new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/vendor/gems/icalendar-1.0.2/README b/vendor/gems/icalendar-1.0.2/README new file mode 100644 index 0000000..90091e5 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/README @@ -0,0 +1,141 @@ += iCalendar -- Internet calendaring, Ruby style + +This is a Ruby library for dealing with iCalendar files. Rather than +explaining myself, here is the introduction from RFC-2445, which +defines the format: + +The use of calendaring and scheduling has grown considerably in the +last decade. Enterprise and inter-enterprise business has become +dependent on rapid scheduling of events and actions using this +information technology. However, the longer term growth of calendaring +and scheduling, is currently limited by the lack of Internet standards +for the message content types that are central to these knowledgeware +applications. This memo is intended to progress the level of +interoperability possible between dissimilar calendaring and +scheduling applications. This memo defines a MIME content type for +exchanging electronic calendaring and scheduling information. The +Internet Calendaring and Scheduling Core Object Specification, or +iCalendar, allows for the capture and exchange of information normally +stored within a calendaring and scheduling application; such as a +Personal Information Manager (PIM) or a Group Scheduling product. + +The iCalendar format is suitable as an exchange format between +applications or systems. The format is defined in terms of a MIME +content type. This will enable the object to be exchanged using +several transports, including but not limited to SMTP, HTTP, a file +system, desktop interactive protocols such as the use of a memory- +based clipboard or drag/drop interactions, point-to-point asynchronous +communication, wired-network transport, or some form of unwired +transport such as infrared might also be used. + +Now for some examples: + +## Probably want to start with this + + require 'rubygems' # Unless you install from the tarball or zip. + require 'icalendar' + require 'date' + + include Icalendar # Probably do this in your class to limit namespace overlap + +## Creating calendars and events is easy. + + # Create a calendar with an event (standard method) + cal = Calendar.new + cal.event do + dtstart Date.new(2005, 04, 29) + dtend Date.new(2005, 04, 28) + summary "Meeting with the man." + description "Have a long lunch meeting and decide nothing..." + klass "PRIVATE" + end + + cal.publish + +## Or you can make events like this + event = Event.new + event.start = DateTime.civil(2006, 6, 23, 8, 30) + event.summary = "A great event!" + cal.add_event(event) + + event2 = cal.event # This automatically adds the event to the calendar + event2.start = DateTime.civil(2006, 6, 24, 8, 30) + event2.summary = "Another great event!" + + # Now with support for property parameters + params = {"ALTREP" =>['"http://my.language.net"'], "LANGUAGE" => ["SPANISH"]} + + cal.event do + dtstart Date.new(2005, 04, 29) + dtend Date.new(2005, 04, 28) + summary "This is a summary with params.", params + end + + # We can output the calendar as a string to write to a file, + # network port, database etc. + cal_string = cal.to_ical + puts cal_string + +== Parsing iCalendars: + + # Open a file or pass a string to the parser + cal_file = File.open("single_event.ics") + + # Parser returns an array of calendars because a single file + # can have multiple calendars. + cals = Icalendar.parse(cal_file) + cal = cals.first + + # Now you can access the cal object in just the same way I created it + event = cal.events.first + + puts "start date-time: " + event.dtstart + puts "summary: " + event.summary + +== Finders: + +Often times in web apps and other interactive applications you'll need to +lookup items in a calendar to make changes or get details. Now you can find +everything by the unique id automatically associated with all components. + + cal = Calendar.new + 10.times { cal.event } # Create 10 events with only default data. + some_event = cal.events[5] # Grab it from the array of events + + # Use the uid as the key in your app + key = some_event.uid + + # so later you can find it. + same_event = cal.find_event(key) + +== Examples: + +Check the unit tests for examples of most things you'll want to do, but please +send me example code or let me know what's missing. + +== Download + +The latest release version of this library can be found at + +* http://rubyforge.org/projects/icalendar/ + +Documentation can be found at + +* http://icalendar.rubyforge.org/ + +== Installation + +It's all about rubygems: + +$ sudo gem install icalendar + +== License + +This library is released under the same license as Ruby itself. + +== Support & Contributions + +The iCalendar library homepage is http://icalendar.rubyforge.org/ + +There is an icalendar-devel@rubyforge.org mailing list that can be +used for asking questions, making comments or submitting patches. diff --git a/vendor/gems/icalendar-1.0.2/Rakefile b/vendor/gems/icalendar-1.0.2/Rakefile new file mode 100644 index 0000000..8bdef02 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/Rakefile @@ -0,0 +1,110 @@ +require 'rubygems' +require 'rake' +require 'rake/testtask' +require 'rake/rdoctask' +require 'rake/clean' +require 'rake/contrib/sshpublisher' + +PKG_VERSION = "1.0.2" + +$VERBOSE = nil +TEST_CHANGES_SINCE = Time.now - 600 # Recent tests = changed in last 10 minutes + +desc "Run all the unit tests" +task :default => [ :test, :lines ] + +desc "Run the unit tests in test" +Rake::TestTask.new(:test) { |t| + t.libs << "test" + t.test_files = FileList['test/*_test.rb', 'test/component/*_test.rb'] + t.verbose = true +} + +# rcov code coverage +rcov_path = '/usr/local/bin/rcov' +rcov_test_output = "./test/coverage" +rcov_exclude = "interactive.rb,read_write.rb,fixtures" + +# Add our created paths to the 'rake clobber' list +CLOBBER.include(rcov_test_output) + +desc 'Removes all previous unit test coverage information' +task (:reset_unit_test_coverage) do |t| + rm_rf rcov_unit_test_output + mkdir rcov_unit_test_output +end + +desc 'Run all unit tests with Rcov to measure coverage' +Rake::TestTask.new(:rcov) do |t| + t.libs << "test" + t.pattern = 'test/**/*_test.rb' + t.ruby_opts << rcov_path + t.ruby_opts << "-o #{rcov_test_output}" + t.ruby_opts << "-x #{rcov_exclude}" + t.verbose = true +end + +# Generate the RDoc documentation +Rake::RDocTask.new(:doc) { |rdoc| + rdoc.main = 'README' + rdoc.rdoc_files.include('lib/**/*.rb', 'README') + rdoc.rdoc_files.include('GPL', 'COPYING') + rdoc.rdoc_dir = 'docs/api' + rdoc.title = "iCalendar -- Internet Calendaring for Ruby" + rdoc.options << "--include=examples --line-numbers --inline-source" + rdoc.options << "--accessor=ical_component,ical_property,ical_multi_property" +} + +Gem::manage_gems +require 'rake/gempackagetask' + +spec = Gem::Specification.new do |s| + s.name = "icalendar" + s.version = PKG_VERSION + s.homepage = "http://icalendar.rubyforge.org/" + s.platform = Gem::Platform::RUBY + s.summary = "A ruby implementation of the iCalendar specification (RFC-2445)." + s.description = "Implements the iCalendar specification (RFC-2445) in Ruby. This allows for the generation and parsing of .ics files, which are used by a variety of calendaring applications." + + s.files = FileList["{test,lib,docs,examples}/**/*"].to_a + s.files += ["Rakefile", "README", "COPYING", "GPL" ] + s.require_path = "lib" + s.autorequire = "icalendar" + s.has_rdoc = true + s.extra_rdoc_files = ["README", "COPYING", "GPL"] + s.rdoc_options.concat ['--main', 'README'] + + s.author = "Jeff Rose" + s.email = "rosejn@gmail.com" +end + +Rake::GemPackageTask.new(spec) do |pkg| + pkg.gem_spec = spec + pkg.need_tar = true + pkg.need_zip = true +end + +desc 'Install the gem globally (requires sudo)' +task :install => :package do |t| + `sudo gem install pkg/icalendar-#{PKG_VERSION}.gem` +end + +task :lines do + lines = 0 + codelines = 0 + Dir.foreach("lib/icalendar") { |file_name| + next unless file_name =~ /.*rb/ + + f = File.open("lib/icalendar/" + file_name) + + while line = f.gets + lines += 1 + next if line =~ /^\s*$/ + next if line =~ /^\s*#/ + codelines += 1 + end + } + puts "\n------------------------------\n" + puts "Total Lines: #{lines}" + puts "Lines of Code: #{codelines}" +end diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/itip_notes.txt b/vendor/gems/icalendar-1.0.2/docs/rfcs/itip_notes.txt new file mode 100644 index 0000000..492fb39 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/docs/rfcs/itip_notes.txt @@ -0,0 +1,69 @@ +Set of methods used for transactions: + +PUBLISH: +- Publish a calendar entry to one or more users. + +REQUEST: +- Used to schedule a calendar entry with other users. +- Require REPLY messages from others. +- Used by Organizers to update status of entries. + +REPLY: +- Attendees use this to send information back to Organizers who have sent a + REQUEST message. + +ADD: +- Add one or more instances to an existing entry. + +CANCEL: +- Cancel a calendar item. + +REFRESH: +- Attendee's use this to get the latest version of an item. + +COUNTER: +- Used by an attendee to negotiate a change in a calendar entry. + +DECLINE-COUNTER: +- Used by an organizer to decline a COUNTER message. + + +Transports: + +Real-time vs. Store-and-forward? + +Entry Status: +- Only the organizer can set the STATUS property +- Attendee's use the "partstat" parameter of the ATTENDEE property to convey + their personal status. +- Initial value of "partstat" is set to "NEEDS-ACTION" by organizer +- Modifying this state is part of an attendee's REPLY message. + +Sequence Property: +- Used to tell manage different versions of an entry +- Has specific rules so look at these + +Handling messages should be done in this manner: + +1. The primary key for referencing a particular iCalendar component + is the "UID" property value. To reference an instance of a + recurring component, the primary key is composed of the "UID" and + the "RECURRENCE-ID" properties. +2. The secondary key for referencing a component is the "SEQUENCE" + property value. For components where the "UID" is the same, the + component with the highest numeric value for the "SEQUENCE" + property obsoletes all other revisions of the component with + lower values. +3. "Attendees" send "REPLY" messages to the "Organizer". For + replies where the "UID" property value is the same, the value of + the "SEQUENCE" property indicates the revision of the component + to which the "Attendee" is replying. The reply with the highest + numeric value for the "SEQUENCE" property obsoletes all other + replies with lower values. +4. In situations where the "UID" and "SEQUENCE" properties match, + the "DTSTAMP" property is used as the tie-breaker. The component + with the latest "DTSTAMP" overrides all others. Similarly, for + "Attendee" responses where the "UID" property values match and + the "SEQUENCE" property values match, the response with the + latest "DTSTAMP" overrides all others. + diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2425.pdf b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2425.pdf new file mode 100644 index 0000000..b87c34c Binary files /dev/null and b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2425.pdf differ diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2426.pdf b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2426.pdf new file mode 100644 index 0000000..c1a75cb Binary files /dev/null and b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2426.pdf differ diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2445.pdf b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2445.pdf new file mode 100644 index 0000000..ede6cb5 Binary files /dev/null and b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2445.pdf differ diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2446.pdf b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2446.pdf new file mode 100644 index 0000000..0dad4f8 Binary files /dev/null and b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2446.pdf differ diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2447.pdf b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2447.pdf new file mode 100644 index 0000000..17c2f90 Binary files /dev/null and b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc2447.pdf differ diff --git a/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc3283.txt b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc3283.txt new file mode 100644 index 0000000..a1b4aca --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/docs/rfcs/rfc3283.txt @@ -0,0 +1,738 @@ + + + +RFC 3283 (rfc3283) - Guide to Internet Calendaring + + + + +

+

RFC 3283 (RFC3283)

+

Internet RFC/STD/FYI/BCP Archives

+ +
[ RFC Index | RFC Search | Usenet FAQs | Web FAQs | Documents | Cities ] +

+Alternate Formats: + rfc3283.txt

+

+

RFC 3283 - Guide to Internet Calendaring

+
+
+
+Network Working Group                                         B. Mahoney
+Request for Comments: 3283                                           MIT
+Category: Informational                                        G. Babics
+                                                                 Steltor
+                                                                A. Taler
+                                                               June 2002
+
+                     Guide to Internet Calendaring
+
+Status of this Memo
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+Abstract
+
+   This document describes the various Internet calendaring and
+   scheduling standards and works in progress, and the relationships
+   between them.  Its intent is to provide a context for these
+   documents, assist in their understanding, and potentially aid in the
+   design of standards-based calendaring and scheduling systems.  The
+   standards addressed are RFC 2445 (iCalendar), RFC 2446 (iTIP), and
+   RFC 2447 (iMIP).  The work in progress addressed is "Calendar Access
+   Protocol" (CAP).  This document also describes issues and problems
+   that are not solved by these protocols, and that could be targets for
+   future work.
+
+Table of Contents
+
+   1.    Introduction . . . . . . . . . . . . . . . . . . . . . . . .  2
+   1.1   Terminology  . . . . . . . . . . . . . . . . . . . . . . . .  2
+   1.2   Concepts and Relationships . . . . . . . . . . . . . . . . .  4
+   2.    Requirements . . . . . . . . . . . . . . . . . . . . . . . .  4
+   2.1   Fundamental Needs  . . . . . . . . . . . . . . . . . . . . .  4
+   2.2   Protocol Requirements  . . . . . . . . . . . . . . . . . . .  5
+   3.    Solutions  . . . . . . . . . . . . . . . . . . . . . . . . .  7
+   3.1   Examples . . . . . . . . . . . . . . . . . . . . . . . . . .  7
+   3.2   Systems  . . . . . . . . . . . . . . . . . . . . . . . . . .  8
+   3.2.1 Standalone Single-user System  . . . . . . . . . . . . . . .  8
+   3.2.2 Single-user Systems Communicating  . . . . . . . . . . . . .  8
+   3.2.3 Single-user with Multiple CUAs . . . . . . . . . . . . . . .  9
+   3.2.4 Single-user with Multiple Calendars  . . . . . . . . . . . .  9
+
+   3.2.5 Users Communicating on a Multi-user System . . . . . . . . . 10
+   3.2.6 Users Communicating through Different Multi-user Systems . . 10
+   4.    Important Aspects  . . . . . . . . . . . . . . . . . . . . . 10
+   4.1   Timezones  . . . . . . . . . . . . . . . . . . . . . . . . . 10
+   4.2   Choice of Transport  . . . . . . . . . . . . . . . . . . . . 11
+   4.3   Security . . . . . . . . . . . . . . . . . . . . . . . . . . 11
+   4.4   Amount of data . . . . . . . . . . . . . . . . . . . . . . . 11
+   4.5   Recurring Components . . . . . . . . . . . . . . . . . . . . 11
+   5.    Open Issues  . . . . . . . . . . . . . . . . . . . . . . . . 11
+   5.1   Scheduling People, not Calendars . . . . . . . . . . . . . . 12
+   5.2   Administration . . . . . . . . . . . . . . . . . . . . . . . 12
+   5.3   Notification . . . . . . . . . . . . . . . . . . . . . . . . 12
+   6.    Security Considerations  . . . . . . . . . . . . . . . . . . 12
+   6.1   Access Control . . . . . . . . . . . . . . . . . . . . . . . 12
+   6.2   Authentication . . . . . . . . . . . . . . . . . . . . . . . 12
+   6.3   Using E-mail . . . . . . . . . . . . . . . . . . . . . . . . 13
+   6.4   Other Issues . . . . . . . . . . . . . . . . . . . . . . . . 13
+         Acknowledgments  . . . . . . . . . . . . . . . . . . . . . . 13
+         References . . . . . . . . . . . . . . . . . . . . . . . . . 14
+         Authors' Addresses . . . . . . . . . . . . . . . . . . . . . 15
+         Full Copyright Statement . . . . . . . . . . . . . . . . . . 16
+
+1. Introduction
+
+   Calendaring and scheduling protocols are intended to aid individuals
+   in obtaining calendaring information and scheduling meetings across
+   the Internet, to aid organizations in providing calendaring
+   information on the Internet, and to provide for organizations looking
+   for a calendaring and scheduling solution to deploy internally.
+
+   It is the intent of this document to provide a context for these
+   documents, assist in their understanding, and potentially help in the
+   design of standards-based calendaring and scheduling systems.
+
+   Problems not solved by these protocols, as well as security issues to
+   be kept in mind, are discussed at the end of the document.
+
+1.1 Terminology
+
+   This memo uses much of the same terminology as iCalendar [RFC-2445],
+   iTIP [RFC-2446], iMIP [RFC-2447], and [CAP].  The following
+   definitions are provided as an introduction; the definitions in the
+   protocol specifications themselves should be considered canonical.
+
+   Calendar
+
+      A collection of events, to-dos, journal entries, etc.  A calendar
+      could be the content of a person or resource's agenda; it could
+      also be a collection of data serving a more specialized need.
+      Calendars are the basic storage containers for calendaring
+      information.
+
+   Calendar Access Rights
+
+      A set of rules defining who may perform what operations, such as
+      reading or writing information, on a given calendar.
+
+   Calendar Service
+
+      A running server application that provides access to a number of
+      calendar stores.
+
+   Calendar Store (CS)
+
+      A data store of a calendar service.  A calendar service may have
+      several calendar stores, and each store may contain several
+      calendars, as well as properties and components outside of those
+      calendars.
+
+   Calendar User (CU)
+
+      An entity (often a human) that accesses calendar information.
+
+   Calendar User Agent (CUA)
+
+      Software with which the calendar user communicates with a calendar
+      service or local calendar store to access calendar information.
+
+   Component
+
+      A piece of calendar data such as an event, a to-do or an alarm.
+      Information about components is stored as properties of those
+      components.
+
+   Delegator
+
+      A calendar user who has assigned his or her participation in a
+      scheduled calendar component (e.g.  a VEVENT) to another calendar
+      user (sometimes called the delegate or delegatee).  An example of
+      a delegator is a busy executive sending an employee to a meeting
+      in his or her place.
+
+   Delegate
+
+      A calendar user (sometimes called the delegatee) who has been
+      assigned to participate in a scheduled calendar component (e.g. a
+      VEVENT) in place of one of the attendees in that component
+      (sometimes called the delegator).  An example of a delegate is a
+      team member sent to a particular meeting.
+
+   Designate
+
+      A calendar user authorized to act on behalf of another calendar
+      user.  An example of a designate is an assistant scheduling
+      meetings for his or her superior.
+
+   Local Store
+
+      A CS that is on the same device as the CUA.
+
+   Property
+
+      A description of some element of a component, such as a start
+      time, title or location.
+
+   Remote Store
+
+      A CS that is not on the same device as the CUA.
+
+1.2 Concepts and Relationships
+
+   iCalendar is the language used to describe calendar objects.  iTIP
+   describes a way to use the iCalendar language to do scheduling.  iMIP
+   describes how to do iTIP scheduling via e-mail.  CAP describes a way
+   to use the iCalendar language to access a calendar store in real-
+   time.
+
+   The relationship between calendaring protocols is similar to that
+   between e-mail protocols.  In those terms, iCalendar is analogous to
+   RFC 2822, iTIP and iMIP are analogous to the Simple Mail Transfer
+   Protocol (SMTP), and CAP is analogous to the Post Office Protocol
+   (POP) or Internet Message Access Protocol (IMAP).
+
+2. Requirements
+
+2.1 Fundamental Needs
+
+   The following scenarios illustrate people and organizations' basic
+   calendaring and scheduling needs:
+
+      a] A doctor wishes to keep track of all her appointments.
+
+      Need: To read and manipulate one's own calendar with only one CUA.
+
+      b] A busy musician wants to maintain her schedule with multiple
+      devices, such as through an Internet-based agenda and with a PDA.
+
+      Need: To read and manipulate one's own calendar, possibly with
+      solutions from different vendors.
+
+      c] A software development team wishes to more effectively schedule
+      their time through viewing each other's calendar information.
+
+      Need: To share calendar information between users of the same
+      calendar service.
+
+      d] A teacher wants his students to schedule appointments during
+      his office hours.
+
+      Need: To schedule calendar events, to-dos and journals with other
+      users of the same calendar service.
+
+      e] A movie theater wants to publish its schedule for prospective
+      customers.
+
+      Need: To share calendar information with users of other calendar
+      services, possibly from a number of different vendors.
+
+      f] A social club wants to schedule calendar entries effectively
+      with its members.
+
+      Need: To schedule calendar events and to-dos with users of other
+      calendar services, possibly from a number of different vendors.
+
+2.2 Protocol Requirements
+
+   Some of these needs can be met by proprietary solutions (a, c, d),
+   but others can not (b, e, f).  These latter scenarios show that
+   standard protocols are required for accessing information in a
+   calendar store and scheduling calendar entries.  In addition, these
+   protocols require a common data format for representing calendar
+   information.
+
+   These requirements are met by the following protocol specifications.
+
+      - Data format: iCalendar [RFC-2445]
+
+      iCalendar [RFC-2445] provides a data format for representing
+      calendar information, to be used and exchanged by other protocols.
+      iCalendar [RFC-2445] can also be used in other contexts, such as a
+      drag-and-drop interface, or an export/import feature.  All the
+      other calendaring protocols depend on iCalendar [RFC-2445], so all
+      elements of a standards-based calendaring and scheduling systems
+      will have to be able to interpret iCalendar [RFC-2445].
+
+      - Scheduling protocol: iTIP [RFC-2446]
+
+      iTIP [RFC-2446] describes the messages used to schedule calendar
+      events.  Within iTIP messages, events are represented in iCalendar
+      [RFC-2445] format, and have semantics that identify the message as
+      being an invitation to a meeting, an acceptance of an invitation,
+      or the assignment of a task.
+
+      iTIP [RFC-2446] messages are used in the scheduling workflow,
+      where users exchange messages in order to organize things such as
+      events and to-dos.  CUAs generate and interpret iTIP [RFC-2446]
+      messages at the direction of the calendar user.  With iTIP [RFC-
+      2446] users can create, modify, delete, reply to, counter, and
+      decline counters to the various iCalendar [RFC-2445] components.
+      Furthermore, users can also request the free/busy time of other
+      people.
+
+      iTIP [RFC-2446] is transport-independent, and has one specified
+      transport binding: iMIP [RFC-2447] binds iTIP to e-mail.  In
+      addition [CAP] will provide a real-time binding of iTIP [RFC-
+      2446], allowing CUAs to perform calendar management and scheduling
+      over a single connection.
+
+      - Calendar management protocol: [CAP]
+
+      [CAP] describes the messages used to manage calendars on a
+      calendar store.  These messages use iCalendar [RFC-2445] to
+      describe various components such as events and to-dos.  These
+      messages make it possible to perform iTIP [RFC-2446] operations,
+      as well as other operations relating to a calendar store such as
+      searching, creating calendars, specifying calendar properties, and
+      specifying calendar access rights.
+
+3. Solutions
+
+3.1 Examples
+
+   Returning to the scenarios presented in section 2.1, the calendaring
+   protocols can be used in the following ways:
+
+      a] The doctor can use a proprietary CUA with a local store, and
+      perhaps use iCalendar [RFC-2445] as a storage mechanism.  This
+      would allow her to easily import her data store into another
+      application that supports iCalendar [RFC-2445].
+
+      b] The musician who wishes to access her agenda from anywhere can
+      use a [CAP]-enabled calendar service accessible over the Internet.
+      She can then use any available [CAP] clients to access the data.
+
+      A proprietary system that provides access through a Web-based
+      interface could also be employed, but the use of [CAP] would be
+      superior in that it would allow the use of third party
+      applications, such as PDA synchronization tools.
+
+      c] The development team can use a calendar service which supports
+      [CAP], and each member can use a [CAP]-enabled CUA of their
+      choice.
+
+      Alternatively, each member could use an iMIP [RFC-2447]-enabled
+      CUA, and they could book meetings over e-mail.  This solution has
+      the drawback that it is difficult to examine other users' agendas,
+      making the organization of meetings more difficult.
+
+      Proprietary solutions are also available, but they require that
+      all members use clients by the same vendor, and disallow the use
+      of third party applications.
+
+      d] The teacher can set up a calendar service, and have students
+      book time through any of the iTIP [RFC-2446] bindings.  [CAP]
+      provides real-time access, but could require additional
+      configuration.  iMIP [RFC-2447] would be the easiest to configure,
+      but may require more e-mail processing.
+
+      If [CAP] access is provided then determining the state of the
+      teacher's schedule is straightforward.  If not, this can be
+      determined through iTIP [RFC-2446] free/busy requests.  Non-
+      standard methods could also be employed, such as serving up
+      iCalendar [RFC-2445], HTML, or XML over HTTP.
+
+      A proprietary system could also be used, but would require that
+      all students be able to use software from a specific vendor.
+
+      e] [CAP] would be preferred for publishing a movie theater's
+      schedule, since it provides advanced access and search
+      capabilities.  It also allows easy integration with customers'
+      calendar systems.
+
+      Non-standard methods such as serving data over HTTP could also be
+      employed, but would be harder to integrate with customers'
+      systems.
+
+      Using a completely proprietary solution would be very difficult,
+      if not impossible, since it would require every user to install
+      and use the proprietary software.
+
+      f] The social club could distribute meeting information in the
+      form of iTIP [RFC-2446] messages, sent via e-mail using iMIP
+      [RFC-2447].  The club could distribute meeting invitations, as
+      well as a full published agenda.
+
+      Alternatively, the club could provide access to a [CAP]-enabled
+      calendar service.  However, this solution would be more expensive
+      since it requires the maintenance of a server.
+
+3.2 Systems
+
+   The following diagrams illustrate possible systems and their usage of
+   the various protocols.
+
+3.2.1 Standalone Single-user System
+
+   A single user system that does not communicate with other systems
+   need not employ any of the protocols.  However, it may use iCalendar
+   [RFC-2445] as a data format in some places.
+
+          -----------       O
+         | CUA w/    |     -+- user
+         |local store|      A
+          -----------      / \
+
+3.2.2 Single-user Systems Communicating
+
+   Users with single-user systems may schedule meetings with each others
+   using iTIP [RFC-2446].  The easiest binding of iTIP [RFC-2446] to use
+   would be iMIP [RFC-2447], since messages can be held in the users'
+   mail queues, which we assume to already exist.  [CAP] could also be
+   used.
+
+          O   -----------                    -----------   O
+         -+- | CUA w/    | -----[iMIP]----- | CUA w/    | -+- user
+          A  |local store|     Internet     |local store|  A
+         / \  -----------                    -----------  / \
+
+3.2.3 Single-user with Multiple CUAs
+
+   A single user may use more than one CUA to access his or her
+   calendar.  The user may use a PDA, a Web client, a PC, or some other
+   device, depending on accessibility.  Some of these clients may have
+   local stores and others may not.  Those with local stores need to
+   synchronize the data on the CUA with the data on the CS.
+
+                -----------
+               |   CUA w   | -----[CAP]----------+
+               |local store|                     |
+          O     -----------                    ----------
+         -+-                                  |   CS     |
+          A                                   |          |
+         / \                                   ----------
+                -----------                      |
+               |  CUA w/o  | -----[CAP]----------+
+               |local store|
+                -----------
+
+3.2.4 Single-user with Multiple Calendars
+
+   A single user may have many independent calendars; for example, one
+   may contain work-related information and another personal
+   information.  The CUA may or may not have a local store.  If it does,
+   then it needs to synchronize the data of the CUA with the data on
+   both of the CS.
+
+                                               ----------
+                     +------------[CAP]------ |   CS     |
+                     |                        |          |
+          O     -----------                    ----------
+         -+-   |  CUA      |
+          A    |           |
+         / \    -----------
+                     |                         ----------
+                     +------------[CAP]------ |   CS     |
+                                              |          |
+                                               ----------
+
+3.2.5 Users Communicating on a Multi-user System
+
+   Users on a multi-user system may schedule meetings with each other
+   using [CAP]-enabled CUAs and services.  The CUAs may or may not have
+   local stores.  Those with local stores need to synchronize the data
+   on the CUAs with the data on the CS.
+
+          O     -----------
+         -+-   |   CUA w   | -----[CAP]----------+
+          A    |local store|                     |
+         / \    -----------                    ----------
+                                              |   CS     |
+                                              |          |
+                                               ----------
+          O     -----------                      |
+         -+-   |  CUA w/o  | -----[CAP]----------+
+          A    |local store|
+         / \    -----------
+
+3.2.6 Users Communicating through Different Multi-user Systems
+
+   Users on a multi-user system may need to schedule meetings with users
+   on a different multi-user system.  The services can communicate using
+   [CAP] or iMIP [RFC-2447].
+
+          O     -----------                    ----------
+         -+-   |   CUA w   | -----[CAP]-------|   CS     |
+          A    |local store|                  |          |
+         / \    -----------                    ----------
+                                                   |
+                                             [CAP] or [iMIP]
+                                                   |
+          O     -----------                    ----------
+         -+-   |  CUA w/o  | -----[CAP]-------|   CS     |
+          A    |local store|                  |          |
+         / \    -----------                    ----------
+
+4. Important Aspects
+
+   There are a number of important aspects of these calendaring
+   standards of which people, especially implementers, should be aware.
+
+4.1 Timezones
+
+   The dates and times in components can refer to a specific time zone.
+   Time zones can be defined in a central store, or they may be defined
+   by a user to fit his or her needs.  All users and applications should
+   be aware of time zones and time zone differences.  New time zones may
+
+   need to be added, and others removed.  Two different vendors may
+   describe the same time zone differently (such as by using a different
+   name).
+
+4.2 Choice of Transport
+
+   There are issues to be aware of in choosing between a network
+   protocol such as [CAP], or a store and forward protocol, such as iMIP
+   [RFC-2447].
+
+   The use of a network ("on-the-wire") mechanism may require some
+   organizations to make provisions to allow calendaring traffic to
+   traverse a corporate firewall on the required ports.  Depending on
+   the organizational culture, this may be a challenging social
+   exercise.
+
+   The use of an email-based mechanism exposes time-sensitive data to
+   unbounded latency.  Large or heavily utilized mail systems may
+   experience an unacceptable delay in message receipt.
+
+4.3 Security
+
+   See the "Security Considerations" (Section 6) section below.
+
+4.4 Amount of data
+
+   In some cases, a component may be very large, for instance, a
+   component with a very large attachment.  Some applications may be
+   low-bandwidth or may be limited in the amount of data they can store.
+   Maximum component size may be set in [CAP].  It can also be
+   controlled in iMIP [RFC-2447] by restricting the maximum size of the
+   e-mail that the application can download.
+
+4.5 Recurring Components
+
+   In iCAL [RFC-2445], one can specify complex recurrence rules for
+   VEVENTs, VTODOs, and VJOURNALs.  One must be careful to correctly
+   interpret these recurrence rules and pay extra attention to being
+   able to interoperate using them.
+
+5. Open Issues
+
+   Many issues are not currently resolved by these protocols, and many
+   desirable features are not yet provided.  Some of the more prominent
+   ones are outlined below.
+
+5.1 Scheduling People, not Calendars
+
+   Meetings are scheduled with people; however, people may have many
+   calendars, and may store these calendars in many places.  There may
+   also be many routes to contact them.  The calendaring protocols do
+   not attempt to provide unique access for contacting a given person.
+   Instead, 'calendar addresses' are booked, which may be e-mail
+   addresses or individual calendars.  It is up to the users themselves
+   to orchestrate mechanisms to ensure that the bookings go to the right
+   place.
+
+5.2 Administration
+
+   The calendaring protocols do not address the issues of administering
+   users and calendars on a calendar service.  This must be handled by
+   proprietary mechanisms for each implementation.
+
+5.3 Notification
+
+   People often wish to be notified of upcoming events, new events, or
+   changes to existing events.  The calendaring protocols do not attempt
+   to address these needs in a real-time system.  Instead, the ability
+   to store alarm information on events is provided, which can be used
+   to provide client-side notification of upcoming events.  To organize
+   notification of new or changed events, clients have to poll the data
+   store.
+
+6. Security Considerations
+
+6.1 Access Control
+
+   There has to be reasonable granularity in the configuration options
+   for access to data through [CAP], so that what should be released to
+   requesters is released, and what shouldn't is not.  Details of
+   handling this are described in [CAP].
+
+6.2 Authentication
+
+   Access control must be coupled with a good authentication system, so
+   that the right people get the right information.  For [CAP], this
+   means requiring authentication before any database access can be
+   performed, and checking access rights and authentication credentials
+   before releasing information.  [CAP] uses the Simple Authentication
+   Security Layer (SASL) for this authentication.  In iMIP [RFC-2447],
+   this may present some challenges, as authentication is often not a
+   consideration in store-and-forward protocols.
+
+   Authentication is also important for scheduling, in that receivers of
+   scheduling messages should be able to validate the apparent sender.
+   Since scheduling messages are wrapped in MIME [RFC-2045], signing and
+   encryption are freely available.  For messages transmitted over mail,
+   this is the only available alternative.  It is suggested that
+   developers take care in implementing the security features in iMIP
+   [RFC-2447], bearing in mind that the concept and need may be foreign
+   or non-obvious to users, yet essential for the system to function as
+   they might expect.
+
+   The real-time protocols provide for the authentication of users, and
+   the preservation of that authentication information, allowing for
+   validation by the receiving end-user or server.
+
+6.3 Using E-mail
+
+   Because scheduling information can be transmitted over mail without
+   any authentication information, e-mail spoofing is extremely easy if
+   the receiver is not checking for authentication.  It is suggested
+   that implementers consider requiring authentication as a default,
+   using mechanisms such as are described in Section 3 of iMIP [RFC-
+   2447].  The use of e-mail, and the potential for anonymous
+   connections, means that 'calendar spam' is possible.  Developers
+   should consider this threat when designing systems, particularly
+   those that allow for automated request processing.
+
+6.4 Other Issues
+
+   The current security context should be obvious to users.  Because the
+   underlying mechanisms may not be clear to users, efforts to make
+   clear the current state in the UI should be made.  One example of
+   this is the 'lock' icon used in some Web browsers during secure
+   connections.
+
+   With both iMIP [RFC-2447] and [CAP], the possibilities of Denial of
+   Service attacks must be considered.  The ability to flood a calendar
+   system with bogus requests is likely to be exploited once these
+   systems become widely deployed, and detection and recovery methods
+   will need to be considered.
+
+Acknowledgments
+
+   Thanks to the following, who have participated in the development of
+   this document:
+
+      Eric Busboom, Pat Egen, David Madeo, Shawn Packwood, Bruce Kahn,
+      Alan Davies, Robb Surridge.
+
+References
+
+   [RFC-2445] Dawson, F. and D. Stenerson, "Internet Calendaring and
+              Scheduling Core Object Specification - iCalendar", RFC
+              2445, November 1998.
+
+   [RFC-2446] Silverberg, S., Mansour, S., Dawson, F. and R. Hopson,
+              "iCalendar Transport-Independent Interoperability Protocol
+              (iTIP):  Scheduling Events, Busy Time, To-dos and Journal
+              Entries", RFC 2446, November 1998.
+
+   [RFC-2447] Dawson, F., Mansour, S. and S. Silverberg, "iCalendar
+              Message-Based Interoperability Protocol - iMIP", RFC 2447,
+              November 1998.
+
+   [RFC-2045] Freed, N. and N. Borenstein, "Multipurpose Internet Mail
+              Extensions (MIME) - Part One: Format of Internet Message
+              Bodies", RFC 2045, November 1996.
+
+   [CAP]      Mansour, S., Royer, D., Babics, G., and Hill, P.,
+              "Calendar Access Protocol (CAP)", Work in Progress.
+
+Authors' Addresses
+
+   Bob Mahoney
+   MIT
+   E40-327
+   77 Massachusetts Avenue
+   Cambridge, MA  02139
+   US
+
+   Phone: (617) 253-0774
+   EMail: bobmah@mit.edu
+
+   George Babics
+   Steltor
+   2000 Peel Street
+   Montreal, Quebec  H3A 2W5
+   CA
+
+   Phone: (514) 733-8500 x4201
+   EMail: georgeb@steltor.com
+
+   Alexander Taler
+
+   EMail: alex@0--0.org
+
+Full Copyright Statement
+
+   Copyright (C) The Internet Society (2002).  All Rights Reserved.
+
+   This document and translations of it may be copied and furnished to
+   others, and derivative works that comment on or otherwise explain it
+   or assist in its implementation may be prepared, copied, published
+   and distributed, in whole or in part, without restriction of any
+   kind, provided that the above copyright notice and this paragraph are
+   included on all such copies and derivative works.  However, this
+   document itself may not be modified in any way, such as by removing
+   the copyright notice or references to the Internet Society or other
+   Internet organizations, except as needed for the purpose of
+   developing Internet standards in which case the procedures for
+   copyrights defined in the Internet Standards process must be
+   followed, or as required to translate it into languages other than
+   English.
+
+   The limited permissions granted above are perpetual and will not be
+   revoked by the Internet Society or its successors or assigns.
+
+   This document and the information contained herein is provided on an
+   "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
+   TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
+   BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
+   HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Acknowledgement
+
+   Funding for the RFC Editor function is currently provided by the
+   Internet Society.
+
+
+


+

 

+
+ +
+

+ +

+
+ + + + diff --git a/vendor/gems/icalendar-1.0.2/examples/create_cal.rb b/vendor/gems/icalendar-1.0.2/examples/create_cal.rb new file mode 100644 index 0000000..b51d852 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/examples/create_cal.rb @@ -0,0 +1,45 @@ +#!/usr/bin/env ruby +## Need this so we can require the library from the samples directory +$:.unshift(File.dirname(__FILE__) + '/../lib') + +require 'rubygems' # Unless you install from the tarball or zip. +require 'icalendar' +require 'date' + +include Icalendar # Probably do this in your class to limit namespace overlap + +## Creating calendars and events is easy. + +# Create a calendar with an event (standard method) +cal = Calendar.new +cal.event do + dtstart Date.new(2005, 04, 29) + dtend Date.new(2005, 04, 28) + summary "Meeting with the man." + description "Have a long lunch meeting and decide nothing..." + klass "PRIVATE" +end + +## Or you can make events like this +event = Event.new +event.start = DateTime.civil(2006, 6, 23, 8, 30) +event.summary = "A great event!" +cal.add_event(event) + +event2 = cal.event # This automatically adds the event to the calendar +event2.start = DateTime.civil(2006, 6, 24, 8, 30) +event2.summary = "Another great event!" + +# Now with support for property parameters +params = {"ALTREP" =>['"http://my.language.net"'], "LANGUAGE" => ["SPANISH"]} + +cal.event do + dtstart Date.new(2005, 04, 29) + dtend Date.new(2005, 04, 28) + summary "This is a summary with params.", params +end + +# We can output the calendar as a string to write to a file, +# network port, database etc. +cal_string = cal.to_ical +puts cal_string diff --git a/vendor/gems/icalendar-1.0.2/examples/parse_cal.rb b/vendor/gems/icalendar-1.0.2/examples/parse_cal.rb new file mode 100644 index 0000000..91c6e21 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/examples/parse_cal.rb @@ -0,0 +1,20 @@ +#!/usr/bin/env ruby +## Need this so we can require the library from the samples directory +$:.unshift(File.dirname(__FILE__) + '/../lib') + +require 'icalendar' +require 'date' + +# Open a file or string to parse +cal_file = File.open("../test/life.ics") + +# Parser returns an array of calendars because a single file +# can have multiple calendar objects. +cals = Icalendar::parse(cal_file) +cal = cals.first + +# Now you can access the cal object in just the same way I created it +event = cal.events.first + +puts "start date-time: " + event.dtstart.to_s +puts "summary: " + event.summary diff --git a/vendor/gems/icalendar-1.0.2/examples/single_event.ics b/vendor/gems/icalendar-1.0.2/examples/single_event.ics new file mode 100644 index 0000000..2f039aa --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/examples/single_event.ics @@ -0,0 +1,18 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:bsprodidfortestabc123 +BEGIN:VEVENT +UID:bsuidfortestabc123 +SUMMARY:This is a really long summary + to test the method of unfolding lines + so I'm just going to ma + ke it + a whol + e + bunch of lines. +CLASS:PRIVATE +DTSTART;TZID=US-Mountain:20050120T170000 +DTEND:20050120T184500 +DTSTAMP:20050118T211523Z +END:VEVENT +END:VCALENDAR diff --git a/vendor/gems/icalendar-1.0.2/init.rb b/vendor/gems/icalendar-1.0.2/init.rb new file mode 100644 index 0000000..04c96ab --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/init.rb @@ -0,0 +1,3 @@ + + require File.join(File.dirname(__FILE__), 'lib', 'icalendar') + diff --git a/vendor/gems/icalendar-1.0.2/lib/hash_attrs.rb b/vendor/gems/icalendar-1.0.2/lib/hash_attrs.rb new file mode 100644 index 0000000..3ce71b7 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/hash_attrs.rb @@ -0,0 +1,34 @@ +# A module which adds some generators for hash based accessors. +module HashAttrs + + def hash_reader(hash_sym, syms) + syms.each do |id| + id = id.to_s.downcase + func = Proc.new do + hash = instance_variable_get(hash_sym) + hash[id.to_sym] + end + + self.send(:define_method, id, func) + end + end + + def hash_writer(hash_sym, syms) + syms.each do |id| + id = id.to_s.downcase + + func = Proc.new do |val| + hash = instance_variable_get(hash_sym) + hash[id.to_sym] = val + end + + self.send(:define_method, id+'=', func) + end + end + + def hash_accessor(hash, *syms) + hash_reader(hash, syms) + hash_writer(hash, syms) + end +end + diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar.rb new file mode 100644 index 0000000..7711ce8 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar.rb @@ -0,0 +1,36 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +$:.unshift(File.dirname(__FILE__)) + +### Base classes and mixin modules + +# to_ical methods for built-in classes +require 'icalendar/conversions' + +# Meta-programming helper methods +require 'meta' + +# Hash attributes mixin module +require 'hash_attrs' + +require 'icalendar/base' +require 'icalendar/component' + +# Calendar and components +require 'icalendar/calendar' +require 'icalendar/component/event' +require 'icalendar/component/journal' +require 'icalendar/component/todo' +require 'icalendar/component/freebusy' +require 'icalendar/component/timezone' +require 'icalendar/component/alarm' + +# Calendar parser +require 'icalendar/parser' + diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/base.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/base.rb new file mode 100644 index 0000000..f10bb81 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/base.rb @@ -0,0 +1,43 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end +require 'logger' + +module Icalendar #:nodoc: + + # A simple error class to differentiate iCalendar library exceptions + # from ruby language exceptions or others. + class IcalendarError < StandardError #:nodoc: + end + + # Exception used when the library encounters a bogus calendar component. + class UnknownComponentClass < IcalendarError + end + + # Exception used when the library encounters a bogus property type. + class UnknownPropertyMethod< IcalendarError + end + + # Exception used when the library encounters a bogus property value. + class InvalidPropertyValue < IcalendarError + end + + # This class serves as the base class for just about everything in + # the library so that the logging system can be configured in one place. + class Base + @@logger = Logger.new(STDERR) + @@logger.level = Logger::FATAL + + def self.debug + @@logger.level = Logger::DEBUG + end + + def self.quiet + @@logger.level = Logger::FATAL + end + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/calendar.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/calendar.rb new file mode 100644 index 0000000..a4e4c5b --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/calendar.rb @@ -0,0 +1,104 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +module Icalendar + + class Calendar < Component + ical_component :events, :todos, :journals, :freebusys, :timezones + + ical_property :calscale, :calendar_scale + ical_property :prodid, :product_id + ical_property :version + ical_property :ip_method + + def initialize() + super("VCALENDAR") + + # Set some defaults + self.calscale = "GREGORIAN" # Who knows, but this is the only one in the spec. + self.prodid = "iCalendar-Ruby" # Current product... Should be overwritten by apps that use the library + self.version = "2.0" # Version of the specification + end + + def event(&block) + e = Event.new + self.add_component e + + e.instance_eval &block if block + + e + end + + def find_event(uid) + self.events.find {|e| e.uid == uid} + end + + def todo(&block) + e = Todo.new + self.add_component e + + e.instance_eval &block if block + + e + end + + def find_todo(uid) + self.todos.find {|t| t.uid == uid} + end + + def journal(&block) + e = Journal.new + self.add_component e + + e.instance_eval &block if block + + e + end + + def find_journal(uid) + self.journals.find {|j| j.uid == uid} + end + + def freebusy(&block) + e = Freebusy.new + self.add_component e + + e.instance_eval &block if block + + e + end + + def find_freebusy(uid) + self.freebusys.find {|f| f.uid == uid} + end + + def timezone(&block) + e = Timezone.new + self.add_component e + + e.instance_eval &block if block + + e + end + + # The "PUBLISH" method in a "VEVENT" calendar component is an + # unsolicited posting of an iCalendar object. Any CU may add published + # components to their calendar. The "Organizer" MUST be present in a + # published iCalendar component. "Attendees" MUST NOT be present. Its + # expected usage is for encapsulating an arbitrary event as an + # iCalendar object. The "Organizer" may subsequently update (with + # another "PUBLISH" method), add instances to (with an "ADD" method), + # or cancel (with a "CANCEL" method) a previously published "VEVENT" + # calendar component. + def publish + self.ip_method = "PUBLISH" + end + + end # class Calendar + +end # module Icalendar diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component.rb new file mode 100644 index 0000000..a2d7bc3 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component.rb @@ -0,0 +1,438 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +module Icalendar + require 'socket' + + MAX_LINE_LENGTH = 75 + + class Geo < Icalendar::Base + attr_accessor :latitude, :longitude + alias :lat :latitude + alias :long :longitude + + def initialize(lat, long) + @lat = lat + @long = long + end + + def to_ical + "#{@lat.to_ical};#{@long.to_ical}" + end + end + + # The body of the iCalendar object consists of a sequence of calendar + # properties and one or more calendar components. The calendar + # properties are attributes that apply to the calendar as a whole. The + # calendar components are collections of properties that express a + # particular calendar semantic. For example, the calendar component can + # specify an Event, a Todo, a Journal entry, Timezone information, or + # Freebusy time information, or an Alarm. + class Component < Icalendar::Base + + meta_include HashAttrs + + attr_reader :name + attr_accessor :properties + + @@multi_properties = {} + @@multiline_properties = {} + + def initialize(name) + @name = name + @components = Hash.new([]) + @properties = {} + + @@logger.info("New #{@name[1,@name.size].capitalize}...") + end + + # Add a sub-component to the current component object. + def add_component(component) + key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym + + unless @components.has_key? key + @components[key] = [] + end + + @components[key] << component + end + + # Add a component to the calendar. + alias add add_component + + # Add an event to the calendar. + alias add_event add_component + + # Add a todo item to the calendar. + alias add_todo add_component + + # Add a journal item to the calendar. + alias add_journal add_component + + def remove_component(component) + key = (component.class.to_s.downcase + 's').gsub('icalendar::', '').to_sym + + if @components.has_key? key + @components[key].delete(component) + end + end + + # Remove a component from the calendar. + alias remove remove_component + + # Remove an event from the calendar. + alias remove_event remove_component + + # Remove a todo item from the calendar. + alias remove_todo remove_component + + # Remove a journal item from the calendar. + alias remove_journal remove_component + + # Used to generate unique component ids + def new_uid + "#{DateTime.now}_#{rand(999999999)}@#{Socket.gethostname}" + end + + # Output in the icalendar format + def to_ical + print_component do + s = "" + @components.each_value do |comps| + comps.each { |component| s << component.to_ical } + end + s + end + end + + # Print this icalendar component + def print_component + # Begin a new component + "BEGIN:#{@name.upcase}\r\n" + + + # Then the properties + print_properties + + + # sub components + yield + + + # End of this component + "END:#{@name.upcase}\r\n" + end + + # Print this components properties + def print_properties + s = "" + + @properties.each do |key,val| + # Take out underscore for property names that conflicted + # with built-in words. + if key =~ /ip_.*/ + key = key[3..-1] + end + + # Property name + unless multiline_property?(key) + prelude = "#{key.gsub(/_/, '-').upcase}" + + + # Possible parameters + print_parameters(val) + + # Property value + value = ":#{val.to_ical}" + escaped = prelude + value.gsub("\\", "\\\\").gsub("\n", "\\n").gsub(",", "\\,").gsub(";", "\\;") + s << escaped.slice!(0, MAX_LINE_LENGTH) << "\r\n " while escaped.size > MAX_LINE_LENGTH + s << escaped << "\r\n" + s.gsub!(/ *$/, '') + else + prelude = "#{key.gsub(/_/, '-').upcase}" + val.each do |v| + params = print_parameters(v) + value = ":#{v.to_ical}" + escaped = prelude + params + value.gsub("\\", "\\\\").gsub("\n", "\\n").gsub(",", "\\,").gsub(";", "\\;") + s << escaped.slice!(0, MAX_LINE_LENGTH) << "\r\n " while escaped.size > MAX_LINE_LENGTH + s << escaped << "\r\n" + s.gsub!(/ *$/, '') + end + end + end + s + end + + # Print the parameters for a specific property + def print_parameters(val) + s = "" + return s unless val.respond_to?(:ical_params) and not val.ical_params.nil? + + val.ical_params.each do |key,val| + s << ";#{key}" + val = [ val ] unless val.is_a?(Array) + + # Possible parameter values + unless val.empty? + s << "=" + sep = "" # First entry comes after = sign, but then we need commas + val.each do |pval| + if pval.respond_to? :to_ical + s << sep << pval.to_ical + sep = "," + end + end + end + end + s + end + + # TODO: Look into the x-property, x-param stuff... + # This would really only be needed for subclassing to add additional + # properties to an application using the API. + def custom_property(name, value) + @properties[name] = value + end + + def multi_property?(name) + @@multi_properties.has_key?(name.downcase) + end + + def multiline_property?(name) + @@multiline_properties.has_key?(name.downcase) + end + + # Make it protected so we can monitor usage... + protected + + def Component.ical_component(*syms) + hash_accessor :@components, *syms + end + + # Define a set of methods supporting a new property + def Component.ical_property(property, alias_name = nil, prop_name = nil) + property = "#{property}".strip.downcase + alias_name = "#{alias_name}".strip.downcase unless alias_name.nil? + # If a prop_name was given then we use that for the actual storage + property = "#{prop_name}".strip.downcase unless prop_name.nil? + + generate_getter(property, alias_name) + generate_setter(property, alias_name) + generate_query(property, alias_name) + end + + # Define a set of methods defining a new property, which + # supports multiple values for the same property name. + def Component.ical_multi_property(property, singular, plural) + property = "#{property}".strip.downcase.gsub(/-/, '_') + plural = "#{plural}".strip.downcase + + # Set this key so the parser knows to use an array for + # storing this property type. + @@multi_properties["#{property}"] = true + + generate_multi_getter(property, plural) + generate_multi_setter(property, plural) + generate_multi_query(property, plural) + generate_multi_adder(property, singular) + generate_multi_remover(property, singular) + end + + # Define a set of methods defining a new property, which + # supports multiple values in multiple lines with same property name + def Component.ical_multiline_property(property, singular, plural) + @@multiline_properties["#{property}"] = true + ical_multi_property(property, singular, plural) + end + + + private + + def Component.generate_getter(property, alias_name) + unless instance_methods.include? property + code = <<-code + def #{property}(val = nil, params = nil) + return @properties["#{property}"] if val.nil? + + unless val.respond_to?(:to_ical) + raise(NotImplementedError, "Value of type (" + val.class.to_s + ") does not support to_ical method!") + end + + unless params.nil? + # Extend with the parameter methods only if we have to... + unless val.respond_to?(:ical_params) + val.class.class_eval { attr_accessor :ical_params } + end + val.ical_params = params + end + + @properties["#{property}"] = val + end + code + + class_eval code, "component.rb", 219 + alias_method("#{alias_name}", "#{property}") unless alias_name.nil? + end + end + + def Component.generate_setter(property, alias_name) + setter = property + '=' + unless instance_methods.include? setter + code = <<-code + def #{setter}(val) + #{property}(val) + end + code + + class_eval code, "component.rb", 233 + alias_method("#{alias_name}=", "#{property+'='}") unless alias_name.nil? + end + end + + def Component.generate_query(property, alias_name) + query = "#{property}?" + unless instance_methods.include? query + code = <<-code + def #{query} + @properties.has_key?("#{property.downcase}") + end + code + + class_eval code, "component.rb", 226 + + alias_method("#{alias_name}\?", "#{query}") unless alias_name.nil? + end + end + + def Component.generate_multi_getter(property, plural) + # Getter for whole array + unless instance_methods.include? plural + code = <<-code + def #{plural}(a = nil) + if a.nil? + @properties["#{property}"] || [] + else + self.#{plural}=(a) + end + end + code + + class_eval code, "component.rb", 186 + end + end + + def Component.generate_multi_setter(property, plural) + # Setter for whole array + unless instance_methods.include? plural+'+' + code = <<-code + def #{plural}=(a) + if a.respond_to?(:to_ary) + a.to_ary.each do |val| + unless val.respond_to?(:to_ical) + raise(NotImplementedError, "Property values do not support to_ical method!") + end + end + + @properties["#{property}"] = a.to_ary + else + raise ArgumentError, "#{plural} is a multi-property that must be an array! Use the add_[property] method to add single entries." + end + end + code + + class_eval code, "component.rb", 198 + end + end + + def Component.generate_multi_query(property, plural) + # Query for any of these properties + unless instance_methods.include? plural+'?' + code = <<-code + def #{plural}? + @properties.has_key?("#{property}") + end + code + + class_eval code, "component.rb", 210 + end + end + + def Component.generate_multi_adder(property, singular) + adder = "add_"+singular.to_s + # Add another item to this properties array + unless instance_methods.include? adder + code = <<-code + def #{adder}(val, params = {}) + unless val.respond_to?(:to_ical) + raise(NotImplementedError, "Property value object does not support to_ical method!") + end + + unless params.nil? + # Extend with the parameter methods only if we have to... + unless val.respond_to?(:ical_params) + val.class.class_eval { attr_accessor :ical_params } + end + val.ical_params = params + end + + if @properties.has_key?("#{property}") + @properties["#{property}"] << val + else + @properties["#{property}"] = [val] + end + end + code + + class_eval code, "component.rb", 289 + alias_method("add_#{property.downcase}", "#{adder}") + end + end + + def Component.generate_multi_remover(property, singular) + # Remove an item from this properties array + unless instance_methods.include? "remove_#{singular}" + code = <<-code + def remove_#{singular}(a) + if @properties.has_key?("#{property}") + @properties["#{property}"].delete(a) + end + end + code + + class_eval code, "component.rb", 303 + alias_method("remove_#{property.downcase}", "remove_#{singular}") + end + end + + def method_missing(method_name, *args) + @@logger.debug("Inside method_missing...") + method_name = method_name.to_s.downcase + + unless method_name =~ /x_.*/ + raise NoMethodError, "Method Name: #{method_name}" + end + + # x-properties are accessed with underscore but stored with a dash so + # they output correctly and we don't have to special case the + # output code, which would require checking every property. + if args.size > 0 # Its a setter + # Pull off the possible equals + @properties[method_name[/x_[^=]*/].gsub('x_', 'x-')] = args.first + else # Or its a getter + return @properties[method_name.gsub('x_', 'x-')] + end + end + + public + + def respond_to?(method_name) + unless method_name.to_s.downcase =~ /x_.*/ + super + end + + true + end + + end # class Component +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component/alarm.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/alarm.rb new file mode 100644 index 0000000..b109fba --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/alarm.rb @@ -0,0 +1,44 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end +module Icalendar + # An Alarm calendar component is a grouping of component + # properties that is a reminder or alarm for an event or a + # to-do. For example, it may be used to define a reminder for a + # pending Event or an overdue Todo. + class Alarm < Component + + # Single properties + ical_property :action + ical_property :description + ical_property :trigger + ical_property :summary + + # Single but must appear together + ical_property :duration + ical_property :repeat + + # Single and only occurring once + + ical_property :created + ical_property :last_modified + ical_property :timestamp + ical_property :sequence + + # Multi properties + ical_multiline_property :attendee, :attendee, :attendees + ical_multi_property :attach, :attachment, :attachments + + def initialize() + super("VALARM") + + # Almost everyone just wants to display so I make it the + # default so it works for most people right away... + action "DISPLAY" + end + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component/event.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/event.rb new file mode 100644 index 0000000..9af938a --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/event.rb @@ -0,0 +1,123 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +module Icalendar + # A Event calendar component is a grouping of component + # properties, and possibly including Alarm calendar components, that + # represents a scheduled amount of time on a calendar. For example, it + # can be an activity; such as a one-hour long, department meeting from + # 8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time + # on an individual calendar. + class Event < Component + ical_component :alarms + + ## Single instance properties + + # Access classification (PUBLIC, PRIVATE, CONFIDENTIAL...) + ical_property :ip_class, :klass + + # Date & time of creation + ical_property :created + + # Complete description of the calendar component + ical_property :description + + # Specifies date-time when calendar component begins + ical_property :dtstart, :start + + # Latitude & longitude for specified activity + ical_property :geo, :geo_location + + # Date & time this item was last modified + ical_property :last_modified + + # Specifies the intended venue for this activity + ical_property :location + + # Defines organizer of this item + ical_property :organizer + + # Defines relative priority for this item (1-9... 1 = best) + ical_property :priority + + # Indicate date & time when this item was created + ical_property :dtstamp, :timestamp + + # Revision sequence number for this item + ical_property :sequence, :seq + + # Defines overall status or confirmation of this item + ical_property :status + ical_property :summary + ical_property :transp, :transparency + + # Defines a persistent, globally unique id for this item + ical_property :uid, :unique_id + + # Defines a URL associated with this item + ical_property :url + ical_property :recurid, :recurrence_id + + ## Single but mutually exclusive properties (Not testing though) + + # Specifies a date and time that this item ends + ical_property :dtend, :end + + # Specifies a positive duration time + ical_property :duration + + ## Multi-instance properties + + # Associates a URI or binary blob with this item + ical_multi_property :attach, :attachment, :attachments + + # Defines an attendee for this calendar item + ical_multiline_property :attendee, :attendee, :attendees + + # Defines the categories for a calendar component (school, work...) + ical_multi_property :categories, :category, :categories + + # Simple comment for the calendar user. + ical_multi_property :comment, :comment, :comments + + # Contact information associated with this item. + ical_multi_property :contact, :contact, :contacts + ical_multi_property :exdate, :exception_date, :exception_dates + ical_multi_property :exrule, :exception_rule, :exception_rules + ical_multi_property :rstatus, :request_status, :request_statuses + + # Used to represent a relationship between two calendar items + ical_multi_property :related_to, :related_to, :related_tos + ical_multi_property :resources, :resource, :resources + + # Used with the UID & SEQUENCE to identify a specific instance of a + # recurring calendar item. + ical_multi_property :rdate, :recurrence_date, :recurrence_dates + ical_multi_property :rrule, :recurrence_rule, :recurrence_rules + + def initialize() + super("VEVENT") + + # Now doing some basic initialization + sequence 0 + timestamp DateTime.now + uid new_uid + end + + def alarm(&block) + a = Alarm.new + self.add a + + a.instance_eval &block if block + + a + end + + + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component/freebusy.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/freebusy.rb new file mode 100644 index 0000000..5f24f5a --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/freebusy.rb @@ -0,0 +1,37 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end +module Icalendar + # A Freebusy calendar component is a grouping of + # component properties that represents either a request for, a reply to + # a request for free or busy time information or a published set of + # busy time information. + class Freebusy < Component + # Single properties + ical_property :contact + ical_property :dtstart, :start + ical_property :dtend, :end + ical_property :dtstamp, :timestamp + ical_property :duration + ical_property :organizer + ical_property :uid, :user_id + ical_property :url + + # Multi-properties + ical_multiline_property :attendee, :attendee, :attendees + ical_multi_property :comment, :comment, :comments + ical_multiline_property :freebusy, :freebusy, :freebusys + ical_multi_property :rstatus, :request_status, :request_statuses + + def initialize() + super("VFREEBUSY") + + timestamp DateTime.now + uid new_uid + end + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component/journal.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/journal.rb new file mode 100644 index 0000000..80e861b --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/journal.rb @@ -0,0 +1,61 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end +module Icalendar + # A Journal calendar component is a grouping of + # component properties that represent one or more descriptive text + # notes associated with a particular calendar date. The "DTSTART" + # property is used to specify the calendar date that the journal entry + # is associated with. Generally, it will have a DATE value data type, + # but it can also be used to specify a DATE-TIME value data type. + # Examples of a journal entry include a daily record of a legislative + # body or a journal entry of individual telephone contacts for the day + # or an ordered list of accomplishments for the day. The Journal + # calendar component can also be used to associate a document with a + # calendar date. + class Journal < Component + + # Single properties + ical_property :ip_class + ical_property :created + ical_property :description + ical_property :dtstart, :start + ical_property :last_modified + ical_property :organizer + ical_property :dtstamp, :timestamp + ical_property :sequence, :seq + ical_property :status + ical_property :summary + ical_property :uid, :user_id + ical_property :url + ical_property :recurid, :recurrence_id + + # Multi-properties + ical_multi_property :attach, :attachment, :attachments + ical_multiline_property :attendee, :attendee, :attendees + ical_multi_property :categories, :category, :categories + ical_multi_property :comment, :comment, :comments + ical_multi_property :contact, :contact, :contacts + ical_multi_property :exdate, :exception_date, :exception_dates + ical_multi_property :exrule, :exception_rule, :exception_rules + ical_multi_property :rstatus, :request_status, :request_statuses + ical_multi_property :related_to, :related_to, :related_tos + ical_multi_property :resources, :resource, :resources + ical_multi_property :rdate, :recurrence_date, :recurrence_dates + ical_multi_property :rrule, :recurrence_rule, :recurrence_rules + + def initialize() + super("VJOURNAL") + + sequence 0 + timestamp DateTime.now + uid new_uid + end + + end +end + diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component/timezone.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/timezone.rb new file mode 100644 index 0000000..baed983 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/timezone.rb @@ -0,0 +1,87 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end +module Icalendar + # A Timezone is unambiguously defined by the set of time + # measurement rules determined by the governing body for a given + # geographic area. These rules describe at a minimum the base offset + # from UTC for the time zone, often referred to as the Standard Time + # offset. Many locations adjust their Standard Time forward or backward + # by one hour, in order to accommodate seasonal changes in number of + # daylight hours, often referred to as Daylight Saving Time. Some + # locations adjust their time by a fraction of an hour. Standard Time + # is also known as Winter Time. Daylight Saving Time is also known as + # Advanced Time, Summer Time, or Legal Time in certain countries. The + # following table shows the changes in time zone rules in effect for + # New York City starting from 1967. Each line represents a description + # or rule for a particular observance. + class Timezone < Component + ical_component :standard, :daylight + + # Single properties + ical_property :dtstart, :start + ical_property :tzoffsetto, :timezone_offset_to + ical_property :tzoffsetfrom, :timezone_offset_from + ical_property :tzid, :timezone_id + ical_property :tzname, :timezone_name + + ical_property :created + ical_property :last_modified + ical_property :timestamp + ical_property :sequence + + # Multi-properties + ical_multi_property :comment, :comment, :comments + ical_multi_property :rdate, :recurrence_date, :recurrence_dates + ical_multi_property :rrule, :recurrence_rule, :recurrence_rules + + # Define a custom add component method because standard and daylight + # are the only components that can occur just once with their parent. + def add_component(component) + key = component.class.to_s.downcase.gsub('icalendar::','').to_sym + @components[key] = component + end + + # Also need a custom to_ical because typically it iterates over an array + # of components. + def to_ical + print_component do + s = "" + @components.each_value do |comp| + s << comp.to_ical + end + s + end + end + + + def initialize(name = "VTIMEZONE") + super(name) + end + + end + + # A Standard component is a sub-component of the Timezone component which + # is used to describe the standard time offset. + class Standard < Timezone + + def initialize() + super("STANDARD") + end + end + + # A Daylight component is a sub-component of the Timezone component which + # is used to describe the time offset for what is commonly known as + # daylight savings time. + class Daylight < Timezone + + def initialize() + super("DAYLIGHT") + end + end + +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/component/todo.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/todo.rb new file mode 100644 index 0000000..2021698 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/component/todo.rb @@ -0,0 +1,64 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end +module Icalendar + # A Todo calendar component is a grouping of component + # properties and possibly Alarm calendar components that represent + # an action-item or assignment. For example, it can be used to + # represent an item of work assigned to an individual; such as "turn in + # travel expense today". + class Todo < Component + ical_component :alarms + + # Single properties + ical_property :ip_class + ical_property :completed + ical_property :created + ical_property :description + ical_property :dtstamp, :timestamp + ical_property :dtstart, :start + ical_property :geo + ical_property :last_modified + ical_property :location + ical_property :organizer + ical_property :percent + ical_property :priority + ical_property :recurid, :recurrence_id + ical_property :seq, :sequence + ical_property :status + ical_property :summary + ical_property :uid, :user_id + ical_property :url + + # Single but mutually exclusive TODO: not testing anything yet + ical_property :due + ical_property :duration + + # Multi-properties + ical_multi_property :attach, :attachment, :attachments + ical_multiline_property :attendee, :attendee, :attendees + ical_multi_property :categories, :category, :categories + ical_multi_property :comment, :comment, :comments + ical_multi_property :contact, :contact, :contacts + ical_multi_property :exdate, :exception_date, :exception_dates + ical_multi_property :exrule, :exception_rule, :exception_rules + ical_multi_property :rstatus, :request_status, :request_statuses + ical_multi_property :related_to, :related_to, :related_tos + ical_multi_property :resources, :resource, :resources + ical_multi_property :rdate, :recurrence_date, :recurrence_dates + ical_multi_property :rrule, :recurrence_rule, :recurrence_rules + + def initialize() + super("VTODO") + + sequence 0 + timestamp DateTime.now + uid new_uid + end + + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/conversions.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/conversions.rb new file mode 100644 index 0000000..a00b776 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/conversions.rb @@ -0,0 +1,133 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +require 'date' + +### Add some to_ical methods to classes + +# class Object +# def to_ical +# raise(NotImplementedError, "This object does not implement the to_ical method!") +# end +# end + +require 'uri/generic' + +class String + def to_ical + self + end +end + +class Fixnum + def to_ical + "#{self}" + end +end + +class Float + def to_ical + "#{self}" + end +end + +# From the spec: "Values in a list of values MUST be separated by a COMMA +# character (US-ASCII decimal 44)." +class Array + def to_ical + map{|elem| elem.to_ical}.join ',' + end +end + +module URI + class Generic + def to_ical + "#{self}" + end + end +end + +class DateTime < Date + def to_ical(utc = false) + s = "" + + # 4 digit year + s << self.year.to_s + + # Double digit month + s << "0" unless self.month > 9 + s << self.month.to_s + + # Double digit day + s << "0" unless self.day > 9 + s << self.day.to_s + + s << "T" + + # Double digit hour + s << "0" unless self.hour > 9 + s << self.hour.to_s + + # Double digit minute + s << "0" unless self.min > 9 + s << self.min.to_s + + # Double digit second + s << "0" unless self.sec > 9 + s << self.sec.to_s + + # UTC time gets a Z suffix + if utc + s << "Z" + end + + s + end +end + +class Date + def to_ical(utc = false) + s = "" + + # 4 digit year + s << self.year.to_s + + # Double digit month + s << "0" unless self.month > 9 + s << self.month.to_s + + # Double digit day + s << "0" unless self.day > 9 + s << self.day.to_s + end +end + +class Time + def to_ical(utc = false) + s = "" + + # Double digit hour + s << "0" unless self.hour > 9 + s << self.hour.to_s + + # Double digit minute + s << "0" unless self.min > 9 + s << self.min.to_s + + # Double digit second + s << "0" unless self.sec > 9 + s << self.sec.to_s + + # UTC time gets a Z suffix + if utc + s << "Z" + end + + s + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/helpers.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/helpers.rb new file mode 100644 index 0000000..e4da970 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/helpers.rb @@ -0,0 +1,109 @@ +=begin + Copyright (C) 2005 Jeff Rose + Copyright (C) 2005 Sam Roberts + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +module Icalendar + module DateProp + # date = date-fullyear date-month date-mday + # date-fullyear = 4 DIGIT + # date-month = 2 DIGIT + # date-mday = 2 DIGIT + DATE = '(\d\d\d\d)(\d\d)(\d\d)' + + # time = time-hour [":"] time-minute [":"] time-second [time-secfrac] [time-zone] + # time-hour = 2 DIGIT + # time-minute = 2 DIGIT + # time-second = 2 DIGIT + # time-secfrac = "," 1*DIGIT + # time-zone = "Z" / time-numzone + # time-numzome = sign time-hour [":"] time-minute + # TIME = '(\d\d)(\d\d)(\d\d)(Z)?' + TIME = '(\d\d)(\d\d)(\d\d)' + + # This method is called automatically when the module is mixed in. + # I guess you have to do this to mixin class methods rather than instance methods. + def self.append_features(base) + super + klass.extend(ClassMethods) + end + + # This is made a sub-module just so it can be added as class + # methods rather than instance methods. + module ClassMethods + def date_property(dp, alias_name = nil) + dp = "#{dp}".strip.downcase + getter = dp + setter = "#{dp}=" + query = "#{dp}?" + + unless instance_methods.include? getter + code = <<-code + def #{getter}(*a) + if a.empty? + @properties[#{dp.upcase}] + else + self.#{dp} = a.first + end + end + code + + module_eval code + end + + unless instance_methods.include? setter + code = <<-code + def #{setter} a + @properties[#{dp.upcase}] = a + end + code + + module_eval code + end + + unless instance_methods.include? query + code = <<-code + def #{query} + @properties.has_key?(#{dp.upcase}) + end + code + + module_eval code + end + + # Define the getter + getter = "get#{property.to_s.capitalize}" + define_method(getter.to_sym) do + puts "inside getting..." + getDateProperty(property.to_s.upcase) + end + + # Define the setter + setter = "set#{property.to_s.capitalize}" + define_method(setter.to_sym) do |*params| + date = params[0] + utc = params[1] + puts "inside setting..." + setDateProperty(property.to_s.upcase, date, utc) + end + + # Create aliases if a name was specified +# if not aliasName.nil? +# gasym = "get#{aliasName.to_s.capitalize}".to_sym +# gsym = getter.to_sym +# alias gasym gsym + +# sasym = "set#{aliasName.to_s.capitalize}".to_sym +# ssym = setter.to_sym +# alias sasym ssym +# end + end + + end + + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/parameter.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/parameter.rb new file mode 100644 index 0000000..f456ff1 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/parameter.rb @@ -0,0 +1,33 @@ +=begin + Copyright (C) 2005 Jeff Rose + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +module Icalendar + + # A property can have attributes associated with it. These "property + # parameters" contain meta-information about the property or the + # property value. Property parameters are provided to specify such + # information as the location of an alternate text representation for a + # property value, the language of a text property value, the data type + # of the property value and other attributes. + class Parameter < Icalendar::Content + + def to_s + s = "" + + s << "#{@name}=" + if is_escapable? + s << escape(print_value()) + else + s << print_value + end + + s + end + + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/icalendar/parser.rb b/vendor/gems/icalendar-1.0.2/lib/icalendar/parser.rb new file mode 100644 index 0000000..19636b7 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/icalendar/parser.rb @@ -0,0 +1,375 @@ +=begin + Copyright (C) 2005 Jeff Rose + Copyright (C) 2005 Sam Roberts + + This library is free software; you can redistribute it and/or modify it + under the same terms as the ruby language itself, see the file COPYING for + details. +=end + +require 'date' +require 'uri' +require 'stringio' + +module Icalendar + def Icalendar.parse(src, single = false) + cals = Icalendar::Parser.new(src).parse + + if single + cals.first + else + cals + end + end + + class Parser < Icalendar::Base + # date = date-fullyear ["-"] date-month ["-"] date-mday + # date-fullyear = 4 DIGIT + # date-month = 2 DIGIT + # date-mday = 2 DIGIT + DATE = '(\d\d\d\d)-?(\d\d)-?(\d\d)' + + # time = time-hour [":"] time-minute [":"] time-second [time-secfrac] [time-zone] + # time-hour = 2 DIGIT + # time-minute = 2 DIGIT + # time-second = 2 DIGIT + # time-secfrac = "," 1*DIGIT + # time-zone = "Z" / time-numzone + # time-numzome = sign time-hour [":"] time-minute + TIME = '(\d\d):?(\d\d):?(\d\d)(\.\d+)?(Z|[-+]\d\d:?\d\d)?' + + def initialize(src) + # Setup the parser method hash table + setup_parsers() + + if src.respond_to?(:gets) + @file = src + elsif (not src.nil?) and src.respond_to?(:to_s) + @file = StringIO.new(src.to_s, 'r') + else + raise ArgumentError, "CalendarParser.new cannot be called with a #{src.class} type!" + end + + @prev_line = @file.gets + @prev_line.chomp! unless @prev_line.nil? + + @@logger.debug("New Calendar Parser: #{@file.inspect}") + end + + # Define next line for an IO object. + # Works for strings now with StringIO + def next_line + line = @prev_line + + if line.nil? + return nil + end + + # Loop through until we get to a non-continuation line... + loop do + nextLine = @file.gets + @@logger.debug "new_line: #{nextLine}" + + if !nextLine.nil? + nextLine.chomp! + end + + # If it's a continuation line, add it to the last. + # If it's an empty line, drop it from the input. + if( nextLine =~ /^[ \t]/ ) + line << nextLine[1, nextLine.size] + elsif( nextLine =~ /^$/ ) + else + @prev_line = nextLine + break + end + end + line + end + + # Parse the calendar into an object representation + def parse + calendars = [] + + @@logger.debug "parsing..." + # Outer loop for Calendar objects + while (line = next_line) + fields = parse_line(line) + + # Just iterate through until we find the beginning of a calendar object + if fields[:name] == "BEGIN" and fields[:value] == "VCALENDAR" + cal = parse_component + @@logger.debug "Added parsed calendar..." + calendars << cal + end + end + + calendars + end + + private + + # Parse a single VCALENDAR object + # -- This should consist of the PRODID, VERSION, option METHOD & CALSCALE, + # and then one or more calendar components: VEVENT, VTODO, VJOURNAL, + # VFREEBUSY, VTIMEZONE + def parse_component(component = Calendar.new) + @@logger.debug "parsing new component..." + + while (line = next_line) + fields = parse_line(line) + + name = fields[:name].upcase + + # Although properties are supposed to come before components, we should + # be able to handle them in any order... + if name == "END" + break + elsif name == "BEGIN" # New component + case(fields[:value]) + when "VEVENT" # Event + component.add_component parse_component(Event.new) + when "VTODO" # Todo entry + component.add_component parse_component(Todo.new) + when "VALARM" # Alarm sub-component for event and todo + component.add_component parse_component(Alarm.new) + when "VJOURNAL" # Journal entry + component.add_component parse_component(Journal.new) + when "VFREEBUSY" # Free/Busy section + component.add_component parse_component(Freebusy.new) + when "VTIMEZONE" # Timezone specification + component.add_component parse_component(Timezone.new) + when "STANDARD" # Standard time sub-component for timezone + component.add_component parse_component(Standard.new) + when "DAYLIGHT" # Daylight time sub-component for timezone + component.add_component parse_component(Daylight.new) + else # Uknown component type, skip to matching end + until ((line = next_line) == "END:#{fields[:value]}"); end + next + end + else # If its not a component then it should be a property + params = fields[:params] + value = fields[:value] + + # Lookup the property name to see if we have a string to + # object parser for this property type. + if @parsers.has_key?(name) + value = @parsers[name].call(name, params, value) + end + + name = name.downcase + + # TODO: check to see if there are any more conflicts. + if name == 'class' or name == 'method' + name = "ip_" + name + end + + # Replace dashes with underscores + name = name.gsub('-', '_') + + if component.multi_property?(name) + adder = "add_" + name + if component.respond_to?(adder) + component.send(adder, value, params) + else + raise(UnknownPropertyMethod, "Unknown property type: #{adder}") + end + else + if component.respond_to?(name) + component.send(name, value, params) + else + raise(UnknownPropertyMethod, "Unknown property type: #{name}") + end + end + end + end + + component + end + + # 1*(ALPHA / DIGIT / "=") + NAME = '[-a-z0-9]+' + + # <"> <"> + QSTR = '"[^"]*"' + + # Contentline + LINE = "(#{NAME})(.*(?:#{QSTR})|(?:[^:]*))\:(.*)" + + # * + PTEXT = '[^";:,]*' + + # param-value = ptext / quoted-string + PVALUE = "#{QSTR}|#{PTEXT}" + + # param = name "=" param-value *("," param-value) + PARAM = ";(#{NAME})(=?)((?:#{PVALUE})(?:,#{PVALUE})*)" + + def parse_line(line) + unless line =~ %r{#{LINE}}i # Case insensitive match for a valid line + raise "Invalid line in calendar string!" + end + + name = $1.upcase # The case insensitive part is upcased for easier comparison... + paramslist = $2 + value = $3.gsub("\\;", ";").gsub("\\,", ",").gsub("\\n", "\n").gsub("\\\\", "\\") + + # Parse the parameters + params = {} + if paramslist.size > 1 + paramslist.scan( %r{#{PARAM}}i ) do + + # parameter names are case-insensitive, and multi-valued + pname = $1 + pvals = $3 + + # If their isn't an '=' sign then we need to do some custom + # business. Defaults to 'type' + if $2 == "" + pvals = $1 + case $1 + when /quoted-printable/i + pname = 'encoding' + + when /base64/i + pname = 'encoding' + + else + pname = 'type' + end + end + + # Make entries into the params dictionary where the name + # is the key and the value is an array of values. + unless params.key? pname + params[pname] = [] + end + + # Save all the values into the array. + pvals.scan( %r{(#{PVALUE})} ) do + if $1.size > 0 + params[pname] << $1 + end + end + end + end + + {:name => name, :value => value, :params => params} + end + + ## Following is a collection of parsing functions for various + ## icalendar property value data types... First we setup + ## a hash with property names pointing to methods... + def setup_parsers + @parsers = {} + + # Integer properties + m = self.method(:parse_integer) + @parsers["PERCENT-COMPLETE"] = m + @parsers["PRIORITY"] = m + @parsers["REPEAT"] = m + @parsers["SEQUENCE"] = m + + # Dates and Times + m = self.method(:parse_datetime) + @parsers["COMPLETED"] = m + @parsers["DTEND"] = m + @parsers["DUE"] = m + @parsers["DTSTART"] = m + @parsers["RECURRENCE-ID"] = m + @parsers["EXDATE"] = m + @parsers["RDATE"] = m + @parsers["CREATED"] = m + @parsers["DTSTAMP"] = m + @parsers["LAST-MODIFIED"] = m + + # URI's + m = self.method(:parse_uri) + @parsers["TZURL"] = m + @parsers["ATTENDEE"] = m + @parsers["ORGANIZER"] = m + @parsers["URL"] = m + + # This is a URI by default, and if its not a valid URI + # it will be returned as a string which works for binary data + # the other possible type. + @parsers["ATTACH"] = m + + # GEO + m = self.method(:parse_geo) + @parsers["GEO"] = m + + end + + # Booleans + # NOTE: It appears that although this is a valid data type + # there aren't any properties that use it... Maybe get + # rid of this in the future. + def parse_boolean(name, params, value) + if value.upcase == "FALSE" + false + else + true + end + end + + # Dates, Date-Times & Times + # NOTE: invalid dates & times will be returned as strings... + def parse_datetime(name, params, value) + begin + DateTime.parse(value) + rescue Exception + value + end + + end + + # Durations + # TODO: Need to figure out the best way to represent durations + # so just returning string for now. + def parse_duration(name, params, value) + value + end + + # Floats + # NOTE: returns 0.0 if it can't parse the value + def parse_float(name, params, value) + value.to_f + end + + # Integers + # NOTE: returns 0 if it can't parse the value + def parse_integer(name, params, value) + value.to_i + end + + # Periods + # TODO: Got to figure out how to represent periods also... + def parse_period(name, params, value) + value + end + + # Calendar Address's & URI's + # NOTE: invalid URI's will be returned as strings... + def parse_uri(name, params, value) + begin + URI.parse(value) + rescue Exception + value + end + end + + # Geographical location (GEO) + # NOTE: returns an array with two floats (long & lat) + # if the parsing fails return the string + def parse_geo(name, params, value) + strloc = value.split(';') + if strloc.size != 2 + return value + end + + Geo.new(strloc[0].to_f, strloc[1].to_f) + end + + end +end diff --git a/vendor/gems/icalendar-1.0.2/lib/meta.rb b/vendor/gems/icalendar-1.0.2/lib/meta.rb new file mode 100644 index 0000000..9457fe3 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/lib/meta.rb @@ -0,0 +1,32 @@ +# A set of methods to help create meta-programming gizmos. +class Object + # The metaclass is the singleton behind every object. + def metaclass + class << self + self + end + end + + # Evaluates the block in the context of the metaclass + def meta_eval &blk + metaclass.instance_eval &blk + end + + # Acts like an include except it adds the module's methods + # to the metaclass so they act like class methods. + def meta_include mod + meta_eval do + include mod + end + end + + # Adds methods to a metaclass + def meta_def name, &blk + meta_eval { define_method name, &blk } + end + + # Defines an instance method within a class + def class_def name, &blk + class_eval { define_method name, &blk } + end +end diff --git a/vendor/gems/icalendar-1.0.2/test/calendar_test.rb b/vendor/gems/icalendar-1.0.2/test/calendar_test.rb new file mode 100644 index 0000000..dc546a3 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/test/calendar_test.rb @@ -0,0 +1,71 @@ +$:.unshift(File.dirname(__FILE__) + '/../lib') + +require 'test/unit' +require 'icalendar' + +require 'date' + +class TestCalendar < Test::Unit::TestCase + include Icalendar + # Generate a calendar using the raw api, and then spit it out + # as a string. Parse the string and make sure everything matches up. + def test_raw_generation + # Create a fresh calendar + cal = Calendar.new + + cal.calscale = "GREGORIAN" + cal.version = "3.2" + cal.prodid = "test-prodid" + + # Now generate the string and then parse it so we can verify + # that everything was set, generated and parsed correctly. + calString = cal.to_ical + + cals = Parser.new(calString).parse + + cal2 = cals.first + assert_equal("GREGORIAN", cal2.calscale) + assert_equal("3.2", cal2.version) + assert_equal("test-prodid", cal2.prodid) + end + + def test_block_creation + cal = Calendar.new + cal.event do + self.dtend = "19970903T190000Z" + self.summary = "This is my summary" + end + + event = cal.event + event.dtend "19970903T190000Z", {:TZID => "Europe/Copenhagen"} + event.summary "This is my summary" + + ev = cal.events.each do |ev| + assert_equal("19970903T190000Z", ev.dtend) + assert_equal("This is my summary", ev.summary) + end + end + + def test_find + cal = Calendar.new + + # add some events so we actually have to search + 10.times do + cal.event + cal.todo + cal.journal + cal.freebusy + end + event = cal.events[5] + assert_equal(event, cal.find_event(event.uid)) + + todo = cal.todos[5] + assert_equal(todo, cal.find_todo(todo.uid)) + + journal = cal.journals[5] + assert_equal(journal, cal.find_journal(journal.uid)) + + freebusy = cal.freebusys[5] + assert_equal(freebusy, cal.find_freebusy(freebusy.uid)) + end +end diff --git a/vendor/gems/icalendar-1.0.2/test/component/event_test.rb b/vendor/gems/icalendar-1.0.2/test/component/event_test.rb new file mode 100644 index 0000000..2ab1644 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/test/component/event_test.rb @@ -0,0 +1,44 @@ +$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib")) + +require 'test/unit' +require 'icalendar' + +# Define a test event +testEvent = <['"http://my.language.net"'], "LANGUAGE" => ["SPANISH"]} + @event.summary("This is a test summary.", params) + + assert_equal params, @event.summary.ical_params + + @cal.add_event @event + cal_str = @cal.to_ical + + cals = Icalendar::Parser.new(cal_str).parse + event = cals.first.events.first + assert_equal params, event.summary.ical_params + end +end diff --git a/vendor/gems/icalendar-1.0.2/test/parser_test.rb b/vendor/gems/icalendar-1.0.2/test/parser_test.rb new file mode 100644 index 0000000..c513986 --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/test/parser_test.rb @@ -0,0 +1,84 @@ +$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib') + +require 'test/unit' +require 'icalendar' + +# This is a test class for the calendar parser. +class TestIcalendarParser < Test::Unit::TestCase + + TEST_CAL = File.join(File.dirname(__FILE__), 'fixtures', 'single_event.ics') + + # First make sure that we can run the parser and get back objects. + def test_new + # Make sure we don't take invalid object types. + assert_raise(ArgumentError) { Icalendar::Parser.new(nil) } + + # Make sure we get an object back from parsing a file + calFile = File.open(TEST_CAL) + cals = Icalendar::Parser.new(calFile).parse + assert(cals) + calFile.close + + # Make sure we get an object back from parsing a string + calString = File.open(TEST_CAL).read + cals = Icalendar::Parser.new(calString).parse + assert(cals) + end + + # Now go through and make sure the object is correct using the + # dynamically generated raw interfaces. + def test_zzfile_parse + calFile = File.open(TEST_CAL) + cals = Icalendar.parse(calFile) + calFile.close + do_asserts(cals) + + Icalendar::Base.quiet + end + + def test_string_parse + # Make sure we get an object back from parsing a string + calString = File.open(TEST_CAL).read + cals = Icalendar::Parser.new(calString).parse + do_asserts(cals) + end + + # Just a helper method so we don't have to repeat the same tests. + def do_asserts(cals) + # Should just get one calendar back. + assert_equal(1, cals.size) + + cal = cals.first + + # Calendar properties + assert_equal("2.0", cal.version) + assert_equal("bsprodidfortestabc123", cal.prodid) + + # Now the event + assert_equal(1, cal.events.size) + + event = cal.events.first + assert_equal("bsuidfortestabc123", event.uid) + + summary = "This is a really long summary to test the method of unfolding lines, so I'm just going to make it a whole bunch of lines." + + assert_equal(summary, event.summary) + + start = DateTime.parse("20050120T170000") + daend = DateTime.parse("20050120T184500") + stamp = DateTime.parse("20050118T211523Z") + assert_equal(start, event.dtstart) + assert_equal(daend, event.dtend) + assert_equal(stamp, event.dtstamp) + + organizer = URI.parse("mailto:joebob@random.net") + assert_equal(organizer, event.organizer) + + ats = event.attachments + assert_equal(2, ats.size) + attachment = URI.parse("http://bush.sucks.org/impeach/him.rhtml") + assert_equal(attachment, ats[0]) + attachment = URI.parse("http://corporations-dominate.existence.net/why.rhtml") + assert_equal(attachment, ats[1]) + end +end diff --git a/vendor/gems/icalendar-1.0.2/test/read_write.rb b/vendor/gems/icalendar-1.0.2/test/read_write.rb new file mode 100644 index 0000000..fdf16ce --- /dev/null +++ b/vendor/gems/icalendar-1.0.2/test/read_write.rb @@ -0,0 +1,23 @@ +#!/usr/bin/ruby + +# NOTE: you must have installed ruby-breakpoint in order to use this script. +# Grab it using gem with "gem install ruby-breakpoint --remote" or download +# from the website (http://ruby-breakpoint.rubyforge.org/) then run setup.rb + +$:.unshift(File.dirname(__FILE__) + '/../lib') + +require 'breakpoint' +require 'icalendar' + +cals = Icalendar::Parser.new(File.new(ARGV[0])).parse +puts "Parsed #{cals.size} calendars" + +cal = cals.first +puts "First calendar has:" +puts "#{cal.events.size} events" +puts "#{cal.todos.size} todos" +puts "#{cal.journals.size} journals" + +test = File.new("rw.ics", "w") +test.write(cal.to_ical) +test.close