[Jifty-commit] r2805 - in jifty: . branches/virtual-models
branches/virtual-models/lib branches/virtual-models/lib/Jifty
branches/virtual-models/lib/Jifty/Manual
branches/virtual-models/lib/Jifty/Script
branches/virtual-models/share/web/templates/__jifty/css
branches/virtual-models/share/web/templates/__jifty/js
jifty-commit at lists.jifty.org
jifty-commit at lists.jifty.org
Tue Feb 20 06:51:59 EST 2007
Author: sterling
Date: Tue Feb 20 06:51:56 2007
New Revision: 2805
Added:
jifty/branches/virtual-models/lib/Jifty/Manual/TutorialRest.pod
Modified:
jifty/ (props changed)
jifty/branches/virtual-models/ (props changed)
jifty/branches/virtual-models/Makefile.PL
jifty/branches/virtual-models/lib/Jifty.pm
jifty/branches/virtual-models/lib/Jifty/API.pm
jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm
jifty/branches/virtual-models/lib/Jifty/Manual/Tutorial.pod
jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm
jifty/branches/virtual-models/lib/Jifty/Test.pm
jifty/branches/virtual-models/lib/Jifty/Web.pm
jifty/branches/virtual-models/share/web/templates/__jifty/css/dhandler
jifty/branches/virtual-models/share/web/templates/__jifty/js/dhandler
Log:
Merging latest trunk into virtual-models
Modified: jifty/branches/virtual-models/Makefile.PL
==============================================================================
--- jifty/branches/virtual-models/Makefile.PL (original)
+++ jifty/branches/virtual-models/Makefile.PL Tue Feb 20 06:51:56 2007
@@ -41,7 +41,7 @@
requires('HTTP::Server::Simple::Recorder');
requires('Hash::Merge');
requires('Hook::LexWrap');
-requires('IPC::PubSub' => '0.22' );
+requires('IPC::PubSub' => '0.23' );
requires('Jifty::DBI' => '0.31' ); # Jifty::DBI::Collection Jifty::DBI::Handle Jifty::DBI::Record::Cachable Jifty::DBI::SchemaGenerator
requires('Locale::Maketext::Extract' => '0.20');
requires('Locale::Maketext::Lexicon' => '0.60');
Modified: jifty/branches/virtual-models/lib/Jifty.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty.pm Tue Feb 20 06:51:56 2007
@@ -13,6 +13,37 @@
Jifty - an application framework
+=head1 SYNOPSIS
+
+ # Object containing lots of web related goodies...
+ my $web = Jifty->web;
+ my $request = Jifty->web->request;
+ my $response = Jifty->web->response;
+ my $link = Jifty->web->link( label => _('W00t'), url => '/whatsit' );
+
+ # Retrieve information from your application's etc/config.yml file.
+ my $config = Jifty->config;
+
+ # Retrieve the Jifty::DBI handle
+ my $handle = Jifty->handle;
+
+ # Load an application class, very handy in plugins
+ my $class = Jifty->app_class('Model', 'Foo');
+ my $foo = $class->new;
+ $foo->create( frobnicate => 42 );
+
+ # Configure information related to your application's actions
+ my $api = Jifty->api;
+
+ # Make parts of your page "subscribe" to information in a fragment
+ my $subs = Jifty->subs;
+
+ # Share information via IPC::PubSub in your application
+ my $bus = Jifty->bus;
+
+ # Retrieve general information about Mason
+ my $handler = Jifty->handler;
+
=head1 DESCRIPTION
Yet another web framework.
@@ -160,6 +191,13 @@
$app->start() if $app->can('start');
}
+# Explicitly destroy the classloader; if this happens during global
+# destruction, there's a period of time where there's a bogus entry in
+# @INC
+END {
+ Jifty->class_loader->DESTROY if Jifty->class_loader;
+}
+
=head2 config
An accessor for the L<Jifty::Config> object that stores the
@@ -177,6 +215,9 @@
An accessor for our L<Jifty::Logger> object for the application.
+You probably aren't interested in this. See L</log> for information on how to
+make log messages.
+
=cut
sub logger {
@@ -189,6 +230,9 @@
An accessor for our L<Jifty::Handler> object.
+This is another method that you usually don't want to mess with too much.
+Most of the interesting web bits are handled by L</web>.
+
=cut
sub handler {
@@ -392,7 +436,7 @@
=head1 SEE ALSO
-L<http://jifty.org>
+L<http://jifty.org>, L<Jifty::Manual::Tutorial>, L<Jifty::Everything>, L<Jifty::Config>, L<Jifty::Handle>, L<Jifty::Logger>, L<Jifty::Handler>, L<Jifty::Web>, L<Jifty::API>, L<Jifty::Subs>, L<IPC::PubSub>, L<Jifty::Plugin>, L<Jifty::ClassLoader>
=head1 AUTHORS
Modified: jifty/branches/virtual-models/lib/Jifty/API.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/API.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty/API.pm Tue Feb 20 06:51:56 2007
@@ -8,6 +8,42 @@
Jifty::API - Manages and allow reflection on the Jifty::Actions that
make up a Jifty application's API
+=head1 SYNOPSIS
+
+ # A nice way to run actions in your application
+ my $class = Jifty->api->qualify('SomeAction');
+ $class->require;
+ $action = $class->new(
+ moniker => 'my_action',
+ argument => {
+ foo => 1,
+ bar => 'baz',
+ },
+ );
+ $action->run;
+
+ # Logged users with an ID greater than 10 have restrictions
+ if (Jifty->web->current_user->id > 10) {
+ Jifty->api->deny('Foo');
+ Jifty->api->allow('FooBar');
+ Jifty->api->deny('FooBarDeleteTheWorld');
+ }
+
+ # Fetch the class names of all the allowed actions
+ my @actions = Jifty->api->actions;
+
+ # Check to see if an action is allowed
+ if (Jifty->api->is_allow('TrueFooBar')) {
+ # do something...
+ }
+
+ # Undo all allow/deny/restrict calls
+ Jifty->api->reset;
+
+=head1 DESCRIPTION
+
+You can fetch an instance of this class by calling L<Jifty/api> in your application. This object can be used to examine the actions available within your application and manage access to those actions.
+
=cut
@@ -20,7 +56,9 @@
=head2 new
-Creates a new C<Jifty::API> object
+Creates a new C<Jifty::API> object.
+
+Don't use this, see L<Jifty/api> to access a reference to C<Jifty::API> in your application.
=cut
@@ -47,8 +85,8 @@
Returns the fully qualified package name for the given provided
action. If the C<ACTIONNAME> starts with C<Jifty::> or
-C<ApplicationClass>::Action, simply returns the given name; otherwise,
-it prefixes it with the C<ApplicationClass>::Action.
+C<ApplicationClass::Action>, simply returns the given name; otherwise,
+it prefixes it with the C<ApplicationClass::Action>.
=cut
@@ -222,4 +260,15 @@
return sort grep { $self->is_allowed($_) } $self->_actions;
}
+=head1 SEE ALSO
+
+L<Jifty>, L<Jifty::Web>, L<Jifty::Action>
+
+=head1 LICENSE
+
+Jifty is Copyright 2005-2006 Best Practical Solutions, LLC.
+Jifty is distributed under the same terms as Perl itself.
+
+=cut
+
1;
Modified: jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty/ClassLoader.pm Tue Feb 20 06:51:56 2007
@@ -30,8 +30,12 @@
sub new {
my $class = shift;
- my $self = bless {@_}, $class;
+ my %args = @_;
+ my @exist = grep {ref $_ eq $class and $_->{base} eq $args{base}} @INC;
+ return $exist[0] if @exist;
+
+ my $self = bless {%args}, $class;
push @INC, $self;
return $self;
}
@@ -285,6 +289,30 @@
wantarray ? @{ $self->{models} } : $self->{models};
}
+=head2 DESTROY
+
+When the ClassLoader gets garbage-collected, its entry in @INC needs
+to be removed.
+
+=cut
+
+# The entries in @INC end up having SvTYPE == SVt_RV, but SvRV(sv) ==
+# 0x0 and !SvROK(sv) (!?) This may be something that perl should cope
+# with more cleanly.
+#
+# We call this explictly in an END block in Jifty.pm, because
+# otherwise the DESTROY block gets called *after* there's already a
+# bogus entry in @INC
+
+# This bug manifests itself as warnings that look like this:
+
+# Use of uninitialized value in require at /tmp/7730 line 9 during global destruction.
+
+
+sub DESTROY {
+ my $self = shift;
+ @INC = grep {defined $_ and $_ ne $self} @INC;
+}
=head1 Writing your own classes
Modified: jifty/branches/virtual-models/lib/Jifty/Manual/Tutorial.pod
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Manual/Tutorial.pod (original)
+++ jifty/branches/virtual-models/lib/Jifty/Manual/Tutorial.pod Tue Feb 20 06:51:56 2007
@@ -487,6 +487,8 @@
=item * Web Services
+See L<Jifty::Manual::TutorialRest> for a quick overview.
+
=item * Continuations in depth
=item * Customized view (user-defined wrappers and css)
Added: jifty/branches/virtual-models/lib/Jifty/Manual/TutorialRest.pod
==============================================================================
--- (empty file)
+++ jifty/branches/virtual-models/lib/Jifty/Manual/TutorialRest.pod Tue Feb 20 06:51:56 2007
@@ -0,0 +1,124 @@
+=head1 NAME
+
+Jifty::Manual::TutorialRest - Web Services
+
+=head1 DESCRIPTION
+
+This builds on L<Jifty::Manual::Tutorial>, so make sure you have a
+running jifty that roughly resembles the step-by-step from there.
+
+=head1 SETUP
+
+You must add this to your site_config.yml
+
+ framework:
+ Plugins:
+ - REST: {}
+
+See L<Jifty::Plugin::REST>.
+
+The commands assume that you have LWP installed with the GET alias. If
+not, you'll need to use the longhand lwp-request -m GET, or curl, or
+your browser.
+
+=head1 help
+
+Make sure it is working:
+
+ $ GET http://localhost:8888/=/help
+
+ Accessing resources:
+ ...
+
+You should see some text describing the services, not html (that's
+longhand for 404.) Check the config and restart the server.
+
+=head1 GET
+
+Just list the models.
+
+ $ GET http://localhost:8888/=/model.yml
+ ---
+ - MyWeblog.Model.Post
+
+List the Post schema.
+
+ $ GET http://localhost:8888/=/model/Post.yml
+ ---
+ body:
+ label: Content
+ name: body
+ readable: 1
+ sort_order: 1
+ type: text
+ writable: 1
+ id:
+ mandatory: 1
+ name: id
+ readable: 1
+ type: serial
+ writable: 0
+ title:
+ default: Untitled post
+ label: Title
+ name: title
+ readable: 1
+ sort_order: 0
+ type: text
+ writable: 1
+
+You did make some posts, right?
+
+ $ GET http://localhost:8888/=/model/Post/id.yml
+ ---
+ - 1
+ - 2
+
+Dump the data:
+
+ $ GET http://localhost:8888/=/model/Post/id/1.yml
+ ---
+ body: 'This is my post, the content of which is this, which is mine.'
+ id: 1
+ title: my first post
+
+ $ GET http://localhost:8888/=/model/Post/id/2.yml
+ ---
+ body: "Content of another post. Got to go, the cat's on fire."
+ id: 2
+ title: post deux
+
+=head1 POST
+
+TODO not working
+
+Actually, it looks like it is not supposed to work this way. Why not?
+
+ $ echo '---
+ body: "A post via web services"
+ id: 3
+ title: "posting from the command-line"
+ ' | lwp-request -m POST http://localhost:8888/=/model/Post.yml
+ POST http://localhost:8888/=/model/Post/id/3.yml --> 404 Not Found
+
+=head1 PUT
+
+TODO not working
+
+ $ echo '---
+ title: "posting from the cli"
+ ' | lwp-request -m PUT http://localhost:8888/=/model/Post/3.yml
+ 500 Can't read entity body: Connection reset by peer
+
+=head1 DELETE
+
+ $ lwp-request -m DELETE http://localhost:8888/=/model/Post/id/3.yml
+ ---
+ content: {}
+ error: ~
+ field_errors: {}
+ field_warnings: {}
+ message: Deleted
+ success: 1
+
+=cut
Modified: jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty/Plugin/REST/Dispatcher.pm Tue Feb 20 06:51:56 2007
@@ -28,6 +28,7 @@
on GET '/=/model/*' => \&list_model_columns;
on GET '/=/model' => \&list_models;
+on POST '/=/model/*' => \&create_item;
on PUT '/=/model/*/*/*' => \&replace_item;
on DELETE '/=/model/*/*/*' => \&delete_item;
@@ -58,7 +59,8 @@
on GET /=/model/<model>/<column>/<key> show item
on GET /=/model/<model>/<column>/<key>/<field> show item field
-on PUT /=/model/<model>/<column>/<key> replace item
+on POST /=/model/<model> create item
+on PUT /=/model/<model>/<column>/<key> update item
on DELETE /=/model/<model>/<column>/<key> delete item
on GET /=/action list actions
@@ -467,10 +469,17 @@
outs( ['model', $model, $column, $key], { map {$_ => stringify($rec->$_())} map {$_->name} $rec->columns});
}
+=head2 create_item
+
+Implemented by redispatching to a CreateModel action.
+
+=cut
+
+sub create_item { _dispatch_to_action('Create') }
=head2 replace_item
-Implemented by redispatching to a CreateModel or UpdateModel action
+Implemented by redispatching to a CreateModel or UpdateModel action.
=cut
@@ -488,7 +497,8 @@
my $prefix = shift;
my ($model, $class, $column, $key) = (model($1), $1, $2, $3);
my $rec = $model->new;
- $rec->load_by_cols( $column => $key );
+ $rec->load_by_cols( $column => $key )
+ if defined $column and defined $key;
if ( not $rec->id ) {
abort(404) if $prefix eq 'Delete';
@@ -497,16 +507,18 @@
$class =~ s/^[\w\.]+\.//;
- $ENV{REQUEST_METHOD} = 'POST';
- Jifty->web->request->argument( $column => $key );
- Jifty->web->request->argument( 'id' => $rec->id )
- if defined $rec->id;
+ if ( defined $column and defined $key ) {
+ Jifty->web->request->argument( $column => $key );
+ Jifty->web->request->argument( 'id' => $rec->id )
+ if defined $rec->id;
+ }
# CGI.pm doesn't handle form encoded data in PUT requests (in fact,
# it doesn't really handle PUT requests properly at all), so we have
# to read the request body ourselves and have CGI.pm parse it
- if ( $ENV{'CONTENT_TYPE'} =~ m|^application/x-www-form-urlencoded$|
- or $ENV{'CONTENT_TYPE'} =~ m|^multipart/form-data$| )
+ if ( $ENV{'REQUEST_METHOD'} eq 'PUT'
+ and ( $ENV{'CONTENT_TYPE'} =~ m|^application/x-www-form-urlencoded$|
+ or $ENV{'CONTENT_TYPE'} =~ m|^multipart/form-data$| ) )
{
my $cgi = Jifty->handler->cgi;
my $length = defined $ENV{'CONTENT_LENGTH'} ? $ENV{'CONTENT_LENGTH'} : 0;
@@ -529,6 +541,7 @@
}
}
+ $ENV{REQUEST_METHOD} = 'POST';
dispatch '/=/action/' . action( $prefix . $class );
}
Modified: jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty/Script/Schema.pm Tue Feb 20 06:51:56 2007
@@ -422,6 +422,7 @@
}
sub _print_upgrades {
+ my $self = shift;
my %UPGRADES = (@_);
for (
map { @{ $UPGRADES{$_} } }
Modified: jifty/branches/virtual-models/lib/Jifty/Test.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Test.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty/Test.pm Tue Feb 20 06:51:56 2007
@@ -141,11 +141,13 @@
rmtree([ File::Spec->canonpath("$root/var/mason") ], 0, 1);
Jifty->new( no_handle => 1 );
+
my $schema = Jifty::Script::Schema->new;
$schema->{drop_database} =
$schema->{create_database} =
$schema->{create_all_tables} = 1;
$schema->run;
+
Jifty->new();
$class->setup_mailbox;
}
@@ -398,6 +400,11 @@
# Clean up mailbox
Jifty::Test->teardown_mailbox;
+ # Disconnect the PubSub bus, if need be; otherwise we may not
+ # be able to drop the testing database
+ Jifty->bus->disconnect
+ if Jifty->bus;
+
# Remove testing db
if (Jifty->handle) {
Jifty->handle->disconnect();
Modified: jifty/branches/virtual-models/lib/Jifty/Web.pm
==============================================================================
--- jifty/branches/virtual-models/lib/Jifty/Web.pm (original)
+++ jifty/branches/virtual-models/lib/Jifty/Web.pm Tue Feb 20 06:51:56 2007
@@ -26,8 +26,8 @@
);
__PACKAGE__->mk_classdata($_)
- for qw(cached_css cached_css_digest
- cached_javascript cached_javascript_digest javascript_libs);
+ for qw(cached_css cached_css_digest cached_css_time
+ cached_javascript cached_javascript_digest cached_javascript_time javascript_libs);
__PACKAGE__->javascript_libs([qw(
jsan/JSAN.js
@@ -1011,6 +1011,7 @@
__PACKAGE__->cached_css( $css );
__PACKAGE__->cached_css_digest( md5_hex( $css ) );
+ __PACKAGE__->cached_css_time( time );
}
}
@@ -1132,6 +1133,7 @@
__PACKAGE__->cached_javascript( $js );
__PACKAGE__->cached_javascript_digest( md5_hex( $js ) );
+ __PACKAGE__->cached_javascript_time( time );
}
}
Modified: jifty/branches/virtual-models/share/web/templates/__jifty/css/dhandler
==============================================================================
--- jifty/branches/virtual-models/share/web/templates/__jifty/css/dhandler (original)
+++ jifty/branches/virtual-models/share/web/templates/__jifty/css/dhandler Tue Feb 20 06:51:56 2007
@@ -9,7 +9,7 @@
use HTTP::Date ();
-if ( Jifty->handler->cgi->http('If-Modified-Since')
+if ( ( Jifty->handler->cgi->http('If-Modified-Since') or Jifty->handler->cgi->http('If-None-Match') )
and $m->dhandler_arg eq Jifty->web->cached_css_digest . '.css' )
{
Jifty->log->debug("Returning 304 for cached css");
@@ -19,6 +19,9 @@
$r->content_type("text/css");
$r->header_out( 'Expires' => HTTP::Date::time2str(time + 31536000) );
+$r->header_out( 'Last-Modified' => HTTP::Date::time2str( Jifty->web->cached_css_time ) );
+$r->header_out( 'Age' => time - Jifty->web->cached_css_time );
+$r->header_out( 'Etag' => Jifty->web->cached_css_digest );
# XXX TODO: If we start caching the squished CSS in a file somewhere, we
# can have the static handler serve it, which would take care of gzipping
Modified: jifty/branches/virtual-models/share/web/templates/__jifty/js/dhandler
==============================================================================
--- jifty/branches/virtual-models/share/web/templates/__jifty/js/dhandler (original)
+++ jifty/branches/virtual-models/share/web/templates/__jifty/js/dhandler Tue Feb 20 06:51:56 2007
@@ -9,7 +9,7 @@
use HTTP::Date ();
-if ( Jifty->handler->cgi->http('If-Modified-Since')
+if ( ( Jifty->handler->cgi->http('If-Modified-Since') or Jifty->handler->cgi->http('If-None-Match') )
and $m->dhandler_arg eq Jifty->web->cached_javascript_digest . '.js' )
{
Jifty->log->debug("Returning 304 for cached javascript");
@@ -19,6 +19,9 @@
$r->content_type("application/x-javascript");
$r->header_out( 'Expires' => HTTP::Date::time2str(time + 31536000) );
+$r->header_out( 'Last-Modified' => HTTP::Date::time2str( Jifty->web->cached_javascript_time ) );
+$r->header_out( 'Age' => time - Jifty->web->cached_javascript_time );
+$r->header_out( 'Etag' => Jifty->web->cached_javascript_digest );
# XXX TODO: If we start caching the squished JS in a file somewhere, we
# can have the static handler serve it, which would take care of gzipping
More information about the Jifty-commit
mailing list