Data::ICal::RDF - Turn iCal files into an RDF graph
Version 0.03
use Data::ICal::RDF; # Instantiate a processing context with the appropriate handlers: my $context = Data::ICal::RDF->new( resolve_uid => sub { # returns an RDF node for the UID... }, resolve_binary => sub { # stores a binary object and resolves any relations # between it and its supplied file name; returns either an # identifier for the content or an identifier for the # relation between the name and the content. }, ); # Process a Data::ICal object... $context->process($ical); # Successive calls to 'process' against different iCal objects # will accumulate statements in the context's internal model. # Now you can do whatever you like with the model. my $result = $context->model;
This module is a processor context for turning Data::ICal objects into RDF data. By default it uses version 4 (i.e., random) UUIDs as subject nodes.
Initialize the processor context.
Supply a callback function to resolve the UID property of an iCal object. This function must return a RDF::Trine::Node::Resource or RDF::Trine::Node::Blank. The function is handed:
UID
The context object itself, meaning the function should be written as if it were a mixin of Data::ICal::RDF,
The UID of the iCal entry as a string literal.
This function is used in "subject_for", which is used by "process_events", which is used by "process". If the function is not reliable for any reason, such as a failure to access hardware or network resources, those methods may croak.
croak
By default the processor will automatically convert iCal UIDs which are V4 UUIDs into urn:uuid: URIs and use them as the subjects of the resulting RDF statements. Furthermore, this is checked before running this function to mitigate any database overhead (see "no_uuids"). A V4 UUID URN is also generated as the iCal data's subject if this function returns undef. If you do not want to use UUIDs, then this function must always return a valid value.
urn:uuid:
undef
Here is an example of a method in a fictitious class which generates a closure suitable to pass into the Data::ICal::RDF constructor:
sub generate_resolve_uid { my $self = shift; return sub { my ($data_ical_rdf, $uid) = @_; # magically look up a resource node from some other # data source return $self->lookup_uid($uid); }; }
This parameter is required.
Supply a callback function to handle inline BINARY attachments. This function must return a RDF::Trine::Node::Resource or RDF::Trine::Node::Blank. The function is handed:
BINARY
The binary data as a seekable IO object,
The declared Content-Type of the data (as in you might want to verify it using something like File::MMagic or File::MimeInfo::Magic),
The suggested file name, which will already be stripped of any erroneous path information. File names of zero length or containing only whitespace will not be passed into this function, so you need only check if it is defined.
defined
This function is used in the BINARY type handler in "process_events", which is used by "process". Once again, if this function is not completely reliable, those methods may croak.
sub generate_resolve_binary { my $self = shift; return sub { my ($data_ical_rdf, $io, $type, $name) = @_; # store the content somewhere and get back an identifier my $content_id = $self->store($io, $type); # return the content ID if there is no file name return $content_id unless defined $name; # turn the name into an RDF literal $name = RDF::Trine::Node::Literal->new($name); # now retrieve the subject node that binds the filename # to the content identifier my $subj = $self->get_subject_for($content_id, $name); # now perhaps write the relevant statements back into # the parser context's internal model map { $data_ical_rdf->model->add_statement($_) } for $self->statements_for($content_id, $name); # now we want to return the retrieved *subject*, which # will be passed into the upstream RDF statement # generation function. return $subj; }; }
Supply an RDF::Trine::Model object to use instead of an internal temporary model, for direct interface to some other RDF data store. Note that this is also accessible through the "model" accessor.
This parameter is optional.
Supply a HASH reference whose keys are known iCal TZID identifiers, and the values are DateTime::TimeZone objects. By default, these values are gleaned from the supplied Data::ICal objects themselves and will override any supplied values.
HASH
TZID
This is a flag to alter the short-circuiting behaviour of "subject_for". When set, it will not attempt to return the result of "uid_is_uuid" before running "resolve_uid".
Process a Data::ICal object and put it into the object's internal model. Note that any VTIMEZONE objects found will not be inserted into the model, but rather integrated into the appropriate date/time-like property values.
VTIMEZONE
Note as well that all non-standard properties are ignored, as well as all non-standard property parameters with the exception of X-FILENAME and X-APPLE-FILENAME since there is no standard way to suggest a file name for attachments.
X-FILENAME
X-APPLE-FILENAME
This method calls "subject_for" and therefore may croak if the "resolve_uid" callback fails for any reason.
Process a list of Data::ICal::Entry::Event objects. This is called by "process" and therefore also may croak.
Take an iCal UID property and return a suitable RDF node which can be used as a subject. This may call the "resolve_uid" callback and therefore may croak if it receives a bad value.
Returns a suitable urn:uuid: node if the iCal UID is also a valid (version 4) UUID. Used by "subject_for" and available in the resolve_uid and resolve_binary functions.
Retrieve the RDF::Trine::Model object embedded in the processor.
This module is prototype-grade, and may give you unexpected results. It does not have a test suite to speak of, at least not until I can come up with an adequate one. An exhaustive test suite to handle the vagaries of the iCal format would likely take an order of magnitude more effort than the module code itself. Nevertheless, I know it works because I'm using it, so my "test suite" is production. I repeat, this is not mature software. Patches welcome.
Furthermore, a number of iCal datatype handlers are not implemented in this early version. These are:
CAL-ADDRESS
DURATION
PERIOD
RECUR
TIME
UTC-OFFSET
In particular, a lack of a handler for the DURATION type means events that follow the DTSTART/DURATION form will be incomplete. In practice this should not be a problem, as iCal, Outlook, etc. use DTEND. This is also in part a design issue, as to whether the DURATION property should be normalized to DTEND.
DTSTART
DTEND
As well, the GEO, RESOURCES, and CLASS properties are yet to be implemented. Patches are welcome, as are work orders.
GEO
RESOURCES
CLASS
Dorian Taylor, <dorian at cpan.org>
<dorian at cpan.org>
Please report any bugs or feature requests to bug-data-ical-rdf at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-ICal-RDF. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
bug-data-ical-rdf at rt.cpan.org
You can find documentation for this module with the perldoc command.
perldoc Data::ICal::RDF
You can also look for information at:
RT: CPAN's request tracker (report bugs here)
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Data-ICal-RDF
AnnoCPAN: Annotated CPAN documentation
http://annocpan.org/dist/Data-ICal-RDF
CPAN Ratings
http://cpanratings.perl.org/d/Data-ICal-RDF
Search CPAN
http://search.cpan.org/dist/Data-ICal-RDF/
Data::ICal
RDF::Trine
DateTime::TimeZone::ICal
RFC 5545
Copyright 2015 Dorian Taylor.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
To install Data::ICal::RDF, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Data::ICal::RDF
CPAN shell
perl -MCPAN -e shell install Data::ICal::RDF
For more information on module installation, please visit the detailed CPAN module installation guide.