$time = $time_travel;
}
- my $path = '/tmp/changes/';
+ my $path = '/tmp/actions/';
mkdir $path unless -e $path;
$path .= sprintf '%.4f.%s', $time, join('.', @$parts);
--- /dev/null
+package MojoFacets::Actions;
+
+use strict;
+use warnings;
+
+use base 'Mojolicious::Controller';
+
+use Storable;
+use Data::Dump qw(dump);
+use MojoFacets::Data;
+
+sub index {
+ my $self = shift;
+
+ my $max = $self->param('max') || 50;
+ my $action_regex = join('|', $self->param('action_filter'));
+ warn "# action_regex $action_regex\n";
+
+ my $actions;
+
+ my $stats;
+ foreach my $path ( sort { $b cmp $a } glob '/tmp/actions/*' ) {
+ if ( $path =~ m{/((\d+\.\d+)\.data\.(.+))$} ) {
+ my ( $uid, $t, $action ) = ( $1, $2, $3 );
+ $stats->{$action}++;
+ next if $action_regex && $action !~ m/^($action_regex)$/;
+ push @$actions, { uid => $uid, t => $t, action => $action }
+ if $#$actions < $max;
+ } else {
+ warn "ignore: $path\n";
+ }
+ }
+
+ # Render template "actions/index.html.ep" with message
+ $self->render(actions => $actions, stats => $stats );
+}
+
+
+sub view {
+ my $self = shift;
+ my $uid = $self->param('uid');
+ $self->render( change => retrieve( "/tmp/actions/$uid" ), uid => $uid );
+}
+
+sub _edit_path {
+ my $self = shift;
+ my $path = $self->param('path') || $self->session('path');
+ $self->app->home->rel_dir('data') . '/' . $path . '.edits';
+}
+
+sub edits {
+ my ( $self ) = @_;
+ my $path = $self->param('path') || $self->session('path');
+ my $commit = $self->param('commit');
+ my ( $items, $unique2id );
+ if ( my $apply_on_path = $self->param('apply_on_path') ) {
+ $items = $MojoFacets::Data::loaded->{$apply_on_path}->{data}->{items};
+ die "no $apply_on_path" unless $items;
+ warn "using $items for $apply_on_path\n";
+ }
+ my $edits;
+ my $stats;
+ my $glob = $self->_edit_path . '/*';
+ foreach my $t ( sort { $b cmp $a } glob $glob ) {
+ my $e = retrieve($t);
+ if ( $items ) {
+ my ($pk,$id) = %{ $e->{unique} };
+ if ( ! defined $unique2id->{$pk} ) {
+ warn "unique2id $pk on ", $#$items + 1 ," items\n";
+ foreach my $i ( 0 .. $#$items ) {
+ $unique2id->{$pk}->{ $items->[$i]->{$pk}->[0] } = $i;
+ }
+ }
+ my $status = 'missing';
+ if ( my $i = $unique2id->{$pk}->{$id} ) {
+ $status = 'found';
+ $items->[$i]->{$pk} = $e->{new} if $commit;
+ }
+ $e->{_status} = $status;
+ $stats->{$status}++;
+ }
+ push @$edits, $e;
+ }
+
+ my @loaded = MojoFacets::Data::__loaded_paths();
+ warn "# loaded paths ",dump @loaded;
+
+ $self->render( edits => $edits, loaded => \@loaded, stats => $stats );
+}
+
+sub edit {
+ my $self = shift;
+
+ if ( my $t = $self->param('remove') ) {
+ unlink $self->_edit_path . '/' . $t;
+ }
+
+ $self->redirect_to('/actions/edits');
+}
+
+1;
+++ /dev/null
-package MojoFacets::Changes;
-
-use strict;
-use warnings;
-
-use base 'Mojolicious::Controller';
-
-use Storable;
-use Data::Dump qw(dump);
-use MojoFacets::Data;
-
-sub index {
- my $self = shift;
-
- my $max = $self->param('max') || 50;
- my $action_regex = join('|', $self->param('action_filter'));
- warn "# action_regex $action_regex\n";
-
- my $actions;
-
- my $changes;
- foreach my $path ( sort { $b cmp $a } glob '/tmp/changes/*' ) {
- if ( $path =~ m{/((\d+\.\d+)\.data\.(.+))$} ) {
- my ( $uid, $t, $action ) = ( $1, $2, $3 );
- $actions->{$action}++;
- next if $action_regex && $action !~ m/^($action_regex)$/;
- push @$changes, { uid => $uid, t => $t, action => $action }
- if $#$changes < $max;
- } else {
- warn "ignore: $path\n";
- }
- }
-
- # Render template "changes/index.html.ep" with message
- $self->render(message => 'Latest Changes', changes => $changes, actions => $actions );
-}
-
-
-sub view {
- my $self = shift;
- my $uid = $self->param('uid');
- $self->render( change => retrieve( "/tmp/changes/$uid" ), uid => $uid );
-}
-
-sub _edit_path {
- my $self = shift;
- my $path = $self->param('path') || $self->session('path');
- $self->app->home->rel_dir('data') . '/' . $path . '.edits';
-}
-
-sub edits {
- my ( $self ) = @_;
- my $path = $self->param('path') || $self->session('path');
- my $commit = $self->param('commit');
- my ( $items, $unique2id );
- if ( my $apply_on_path = $self->param('apply_on_path') ) {
- $items = $MojoFacets::Data::loaded->{$apply_on_path}->{data}->{items};
- die "no $apply_on_path" unless $items;
- warn "using $items for $apply_on_path\n";
- }
- my $edits;
- my $stats;
- my $glob = $self->_edit_path . '/*';
- foreach my $t ( sort { $b cmp $a } glob $glob ) {
- my $e = retrieve($t);
- if ( $items ) {
- my ($pk,$id) = %{ $e->{unique} };
- if ( ! defined $unique2id->{$pk} ) {
- warn "unique2id $pk on ", $#$items + 1 ," items\n";
- foreach my $i ( 0 .. $#$items ) {
- $unique2id->{$pk}->{ $items->[$i]->{$pk}->[0] } = $i;
- }
- }
- my $status = 'missing';
- if ( my $i = $unique2id->{$pk}->{$id} ) {
- $status = 'found';
- $items->[$i]->{$pk} = $e->{new} if $commit;
- }
- $e->{_status} = $status;
- $stats->{$status}++;
- }
- push @$edits, $e;
- }
-
- my @loaded = MojoFacets::Data::__loaded_paths();
- warn "# loaded paths ",dump @loaded;
-
- $self->render( edits => $edits, loaded => \@loaded, stats => $stats );
-}
-
-sub edit {
- my $self = shift;
-
- if ( my $t = $self->param('remove') ) {
- unlink $self->_edit_path . '/' . $t;
- }
-
- $self->redirect_to('/changes/edits');
-}
-
-1;
if ( ! data ) {
data = new_content; // fallback to submited data for 304
} else {
- if ( $('a.save_changes').length == 0 )
- $('a.changes').before('<a class=save_changes href="/data/save">save</a>')
+ if ( $('a.save_actions').length == 0 )
+ $('a.actions').before('<a class=save_actions href="/data/save">save</a>')
}
var vals = data.split('¶');
data = vals.join('<span class=d>¶</span>');
font-weight: bold;
}
-.admin .changes {
+.admin .actions {
float: right;
}
-.admin .save_changes {
+.admin .save_actions {
float: right;
color: #f00;
padding-left: 1em;
text-decoration: none;
}
-/* /changes */
+/* /actions */
.change_box {
border: 3px dashed #f84;
}
text-decoration: line-through;
}
-/* /changes/edits */
+/* /actions/edits */
tr.edit pre {
color: #000;
--- /dev/null
+% layout 'ui';
+
+
+% my $dump = param('dump');
+% my $apply_on_path = param('apply_on_path');
+
+<form method=post>
+<input type=submit value="Apply"> on
+<select name=apply_on_path>
+% foreach my $p ( @$loaded ) {
+<option<%= $p eq $apply_on_path ? ' selected' : '' %>><%= $p %></option>
+% }
+</select>
+<label><input type=checkbox name=dump <%= $dump ? 'checked' : '' %>>dump</label>
+
+% if ( $apply_on_path ) {
+<ul id=status>
+% foreach my $status ( keys %$stats ) {
+<li><label>
+<input name=show type=checkbox value="<%= $status %>" checked>
+<%= $status %>
+<span class=count><%= $stats->{$status} %></span>
+</label>
+% }
+</ul>
+
+<input type=submit name=commit value="Commit changes">
+
+% }
+
+</form>
+
+<table>
+<tr><th></th><th>old</th><th>new</th></tr>
+
+% foreach my $e ( @$edits ) {
+<tr class="edit <%= $e->{_status} || 'unknown' %>">
+<td>
+<%= $e->{time} %>
+<tt><%= $e->{column} %></tt>
+% if ( my $status = $e->{_status} ) {
+% my ( $pk, $id ) = %{ $e->{unique} };
+<a href="<%= url_for( controller => 'data', action => 'filter' )->query( filter_name => $pk, filter_vals => $id ) %>"><%= $id %></a>
+<%= $status %>
+% } else {
+<a href="<%= url_for( action => 'edit' )->query( remove => $e->{time} ) %>">remove</a>
+% }
+
+</td><td><%== defined $e->{old} && join('<span class=d>¶</span>', @{$e->{old}}) %>
+</td><td><%== defined $e->{new} && join('<span class=d>¶</span>', @{$e->{new}}) %>
+
+% if ( $dump ) {
+</td><td><pre class=debug><%= dumper $e %></pre>
+% }
+</tr>
+% }
+
+</table>
+
+<pre class=debug>
+<%= dumper( $stats ) %>
+</pre>
+
+<script type="text/javascript">
+
+$(document).ready( function(){
+ console.debug('ready');
+ $('ul#status > li input[type=checkbox]').click( function(){
+ var toggle = this.value;
+ console.debug('click',this,toggle);
+ $('tr.'+toggle).toggleClass('hidden');
+ });
+});
+
+</script>
--- /dev/null
+% layout 'ui';
+<h2>Latest actions</h2>
+
+<form class=action_filter>
+<input type=submit value="Filter">
+<ul>
+% foreach my $type ( sort keys %$stats ) {
+<li><label>
+<input type=checkbox name=action_filter value="<%= $type %>">
+<%= $type %><span class=count><%= $stats->{$type} %></span>
+</label>
+% }
+</ul>
+<input type=submit value="Filter">
+</form>
+
+<table>
+<tr><th>action</th><th>timestamp</th></tr>
+% foreach my $action ( @$actions ) {
+<tr><td>
+<a class="view" href="<%= url_for( controller => 'actions', action => 'view' )->query( uid => $action->{uid} ) %>"><%= $action->{action} %></a>
+</td><td>
+<tt class=ts><%= $action->{t} %></tt>
+</td></tr>
+% }
+</table>
+
+% my $more = ( $#$actions ) * 10;
+Show <a href="<%= url_for( controller => 'actions', action => 'index' )->query( max => $more ) %>"><%= $more %> actions</a>
+
+<script type="text/javascript" src="/js/date_pretty.js"></script>
+<script type="text/javascript">
+$(document).ready( function(){
+ console.debug('convert timestamps');
+ $('tt.ts').each( function(){
+ $(this).text( date_pretty( new Date(this.textContent * 1000) ) );
+ });
+
+ $('a.view').live( 'click', function() {
+ console.debug(this.href);
+ var e = $(this).parent();
+ var link_html = e.html();
+ $.ajax({
+ url: this.href,
+ success: function(data){
+ var form = $(data).filter('form');
+ console.debug('ajax',e,form);
+ e.html( form )
+ .addClass( 'action_box' )
+ .append(
+ $('<input type=button value=hide>').click( function() {
+console.debug(this,link_html);
+ e.html( link_html ).removeClass( 'action_box' ).addClass( 'action_viewed' );
+ })
+ )
+ ;
+ }
+ })
+ return false;
+ });
+
+ $('form input[name=_master]').live( 'click', function(){
+ var master = this.value;
+ console.debug('replication master', master);
+
+ $(this).closest('form').attr('action', function() {
+ return master + this.action;
+ }).css({ 'background': '#ffe' });
+ });
+
+});
+</script>
--- /dev/null
+% layout 'default';
+
+% my $action = $uid;
+% $action =~ s/^.+\.([^\.]+)$/$1/;
+% $action = url_for( controller => 'data', action => $action );
+<form method=post action=<%= $action %>>
+<input type=submit value="<%= $action %>">
+<tt><%= $uid %></tt>
+% my $t = $1 if $uid =~ m/^(\d+\.\d+)/;
+<input type=hidden name="time" value="<%= $t %>">
+% if ( my $master = $ENV{'MASTER'} ) {
+<input class=replication type=checkbox name="_master" value="<%= $master %>" title="replicate to <%= $master %>">
+% }
+% my $params = $change->{params};
+<ul>
+% while ( @$params ) {
+% my $n = shift @$params;
+% my $v = shift @$params;
+<li><label>
+<%= $n %>
+<input type=checkbox name="<%= $n %>" value="<%= $v %>" checked>
+<%= $v %>
+</label>
+% }
+</ul>
+</form>
+
+<pre class=debug><%= dumper $change %></pre>
<a href="<%= url_for( controller => 'data', action => 'items' )->query( show => $show ) %>" <%= $class %>><%= $show %></a>
% }
-<span class=changes>
+<span class=actions>
% if ( session('modified') ) {
% my $path = session('path');
-<a class=save_changes title="<%= $path %>" href="<%= url_for( controller => 'data', action => 'save', path => $path ) %>">save</a>
+<a class=save_actions title="<%= $path %>" href="<%= url_for( controller => 'data', action => 'save', path => $path ) %>">save</a>
% }
% if ( $self->can('_export_path') && glob $self->_export_path('*') ) {
<a href="<%= url_for( controller => 'data', action => 'export' ) %>">export</a>
% }
-<a href="<%= url_for( controller => 'changes', action => 'edits' ) %>">edits</a>
-<a href="<%= url_for( controller => 'changes', action => 'index' ) %>">changes</a>
+<a href="<%= url_for( controller => 'actions', action => 'edits' ) %>">edits</a>
+<a href="<%= url_for( controller => 'actions', action => 'index' ) %>">actions</a>
</span>
</div>
+++ /dev/null
-% layout 'ui';
-
-
-% my $dump = param('dump');
-% my $apply_on_path = param('apply_on_path');
-
-<form method=post>
-<input type=submit value="Apply"> on
-<select name=apply_on_path>
-% foreach my $p ( @$loaded ) {
-<option<%= $p eq $apply_on_path ? ' selected' : '' %>><%= $p %></option>
-% }
-</select>
-<label><input type=checkbox name=dump <%= $dump ? 'checked' : '' %>>dump</label>
-
-% if ( $apply_on_path ) {
-<ul id=status>
-% foreach my $status ( keys %$stats ) {
-<li><label>
-<input name=show type=checkbox value="<%= $status %>" checked>
-<%= $status %>
-<span class=count><%= $stats->{$status} %></span>
-</label>
-% }
-</ul>
-
-<input type=submit name=commit value="Commit changes">
-
-% }
-
-</form>
-
-<table>
-<tr><th></th><th>old</th><th>new</th></tr>
-
-% foreach my $e ( @$edits ) {
-<tr class="edit <%= $e->{_status} || 'unknown' %>">
-<td>
-<%= $e->{time} %>
-<tt><%= $e->{column} %></tt>
-% if ( my $status = $e->{_status} ) {
-% my ( $pk, $id ) = %{ $e->{unique} };
-<a href="<%= url_for( controller => 'data', action => 'filter' )->query( filter_name => $pk, filter_vals => $id ) %>"><%= $id %></a>
-<%= $status %>
-% } else {
-<a href="<%= url_for( action => 'edit' )->query( remove => $e->{time} ) %>">remove</a>
-% }
-
-</td><td><%== defined $e->{old} && join('<span class=d>¶</span>', @{$e->{old}}) %>
-</td><td><%== defined $e->{new} && join('<span class=d>¶</span>', @{$e->{new}}) %>
-
-% if ( $dump ) {
-</td><td><pre class=debug><%= dumper $e %></pre>
-% }
-</tr>
-% }
-
-</table>
-
-<pre class=debug>
-<%= dumper( $stats ) %>
-</pre>
-
-<script type="text/javascript">
-
-$(document).ready( function(){
- console.debug('ready');
- $('ul#status > li input[type=checkbox]').click( function(){
- var toggle = this.value;
- console.debug('click',this,toggle);
- $('tr.'+toggle).toggleClass('hidden');
- });
-});
-
-</script>
+++ /dev/null
-% layout 'ui';
-<h2><%= $message %></h2>
-
-<form class=action_filter>
-<input type=submit value="Filter changes">
-<ul>
-% foreach my $type ( sort keys %$actions ) {
-<li><label>
-<input type=checkbox name=action_filter value="<%= $type %>">
-<%= $type %><span class=count><%= $actions->{$type} %></span>
-</label>
-% }
-</ul>
-<input type=submit value="Filter changes">
-</form>
-
-<table>
-<tr><th>action</th><th>timestamp</th></tr>
-% foreach my $change ( @$changes ) {
-<tr><td>
-<a class="view" href="<%= url_for( controller => 'changes', action => 'view' )->query( uid => $change->{uid} ) %>"><%= $change->{action} %></a>
-</td><td>
-<tt class=ts><%= $change->{t} %></tt>
-</td></tr>
-% }
-</table>
-
-% my $more = ( $#$changes ) * 10;
-Show <a href="<%= url_for( controller => 'changes', action => 'index' )->query( max => $more ) %>"><%= $more %> changes</a>
-
-<script type="text/javascript" src="/js/date_pretty.js"></script>
-<script type="text/javascript">
-$(document).ready( function(){
- console.debug('convert timestamps');
- $('tt.ts').each( function(){
- $(this).text( date_pretty( new Date(this.textContent * 1000) ) );
- });
-
- $('a.view').live( 'click', function() {
- console.debug(this.href);
- var e = $(this).parent();
- var link_html = e.html();
- $.ajax({
- url: this.href,
- success: function(data){
- var form = $(data).filter('form');
- console.debug('ajax',e,form);
- e.html( form )
- .addClass( 'change_box' )
- .append(
- $('<input type=button value=hide>').click( function() {
-console.debug(this,link_html);
- e.html( link_html ).removeClass( 'change_box' ).addClass( 'change_viewed' );
- })
- )
- ;
- }
- })
- return false;
- });
-
- $('form input[name=_master]').live( 'click', function(){
- var master = this.value;
- console.debug('replication master', master);
-
- $(this).closest('form').attr('action', function() {
- return master + this.action;
- }).css({ 'background': '#ffe' });
- });
-
-});
-</script>
+++ /dev/null
-% layout 'default';
-
-% my $action = $uid;
-% $action =~ s/^.+\.([^\.]+)$/$1/;
-% $action = url_for( controller => 'data', action => $action );
-<form method=post action=<%= $action %>>
-<input type=submit value="<%= $action %>">
-<tt><%= $uid %></tt>
-% my $t = $1 if $uid =~ m/^(\d+\.\d+)/;
-<input type=hidden name="time" value="<%= $t %>">
-% if ( my $master = $ENV{'MASTER'} ) {
-<input class=replication type=checkbox name="_master" value="<%= $master %>" title="replicate to <%= $master %>">
-% }
-% my $params = $change->{params};
-<ul>
-% while ( @$params ) {
-% my $n = shift @$params;
-% my $v = shift @$params;
-<li><label>
-<%= $n %>
-<input type=checkbox name="<%= $n %>" value="<%= $v %>" checked>
-<%= $v %>
-</label>
-% }
-</ul>
-</form>
-
-<pre class=debug><%= dumper $change %></pre>