Asynchroner Import
authorSven Schöling <s.schoeling@linet-services.de>
Fri, 11 Jan 2013 12:55:39 +0000 (13:55 +0100)
committerSven Schöling <s.schoeling@linet-services.de>
Fri, 11 Jan 2013 12:55:39 +0000 (13:55 +0100)
SL/BackgroundJob/CsvImport.pm [new file with mode: 0644]
SL/Controller/CsvImport.pm
SL/DB/CsvImportProfile.pm
SL/System/TaskServer.pm
templates/webpages/csv_import/_deferred_results.html [new file with mode: 0644]
templates/webpages/csv_import/_results.html [new file with mode: 0644]
templates/webpages/csv_import/form.html

diff --git a/SL/BackgroundJob/CsvImport.pm b/SL/BackgroundJob/CsvImport.pm
new file mode 100644 (file)
index 0000000..e34edc3
--- /dev/null
@@ -0,0 +1,106 @@
+package SL::BackgroundJob::CsvImport;
+
+use strict;
+
+use parent qw(SL::BackgroundJob::Base);
+
+use YAML ();
+use SL::DB::CsvImportProfile;
+use SL::SessionFile::Random;
+
+sub create_job {
+  my ($self_or_class, %params) = @_;
+
+  my $package       = ref($self_or_class) || $self_or_class;
+  $package          =~ s/SL::BackgroundJob:://;
+
+  my $profile = delete $params{profile} || SL::DB::CsvImportProfile->new;
+  my $result  = delete $params{result}  || SL::SessionFile::Random->new;
+
+  my %data = (
+    profile => { $profile->flatten },
+    result  => $result->file_name,
+    %params,
+  );
+
+  my $job = SL::DB::BackgroundJob->new(
+    type         => 'once',
+    active       => 1,
+    package_name => $package,
+    data         => YAML::Dump(\%data),
+  );
+
+  return $job;
+}
+
+sub profile {
+  my ($self, $db_obj) = @_;
+
+  if (!$self->{profile}) {
+    $self->{profile} = SL::DB::CsvImportProfile->new;
+    my $data = YAML::Load($db_obj->data);
+    for (keys %$data) {
+      $self->{profile}->set($_ => $data->{$_});
+    }
+  }
+
+  return $self->{profile};
+}
+
+sub run {
+  my $self        = shift;
+  $self->{db_obj} = shift;
+
+  $self->do_import;
+
+  $self->cleanup;
+}
+
+sub do_import {
+  my ($self) = @_;
+
+  my $c = SL::Controller::CsvImport->new;
+  $c->profile($self->{profile});
+  $c->test_and_import(test => $self->);
+
+
+}
+
+sub cleanup {
+
+}
+
+1;
+
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+SL::Background::CsvImport - backend for automatic imports of csv data
+
+=head1 SYNOPSIS
+
+
+use SL::BackgroundJob::CsvImport;
+
+
+From a controller or external source:
+
+  my $job = SL::BackgroundJob::CsvImport->create_job(
+    file => $file,
+    %import_options
+  );
+
+=head1 DESCRIPTION
+
+=head1 FUNCTIONS
+
+=head1 BUGS
+
+=head1 AUTHOR
+
+Sven Schoeling E<lt>s.schoeling@linet-services.deE<gt>
+
+=cut
index cb54de9..9e2c096 100644 (file)
@@ -13,6 +13,8 @@ use SL::Controller::CsvImport::CustomerVendor;
 use SL::Controller::CsvImport::Part;
 use SL::Controller::CsvImport::Shipto;
 use SL::Controller::CsvImport::Project;
+use SL::BackgroundJob::CsvImport;
+use SL::System::TaskServer;
 
 use List::MoreUtils qw(none);
 
@@ -43,12 +45,12 @@ sub action_new {
 
 sub action_test {
   my ($self) = @_;
-  $self->test_and_import(test => 1);
+  $self->test_and_import_deferred(test => 1);
 }
 
 sub action_import {
   my $self = shift;
-  $self->test_and_import(test => 0);
+  $self->test_and_import_deferred(test => 0);
 }
 
 sub action_save {
@@ -71,6 +73,29 @@ sub action_destroy {
   $self->redirect_to(action => 'new', 'profile.type' => $self->type);
 }
 
+sub action_result {
+  my $self = shift;
+
+  # load resultobject
+  $self->{background_job} = SL::DB::Manager::BackgroundJob->find_by(id => $::form->{job});
+
+  my $data = $self->{background_job}->data_as_hash;
+
+  my $profile = SL::DB::CsvImportProfile->new(type => $data->{type});
+  my $profile_data = $data->{profile};
+  for (keys %$profile_data) {
+    $profile->set($_ => $profile_data->{$_});
+  }
+
+  $self->profile($profile);
+
+  if ($data->{progress} < 100) {
+    $self->render('csv_import/_deferred_results', { no_layout => 1 });
+  } else {
+   die 'what? done? panic, no idea what to do';
+  }
+}
+
 sub action_download_sample {
   my $self = shift;
 
@@ -157,6 +182,33 @@ sub render_inputs {
   $self->render('csv_import/form', title => $title);
 }
 
+sub test_and_import_deferred {
+  my ($self, %params) = @_;
+
+  $self->profile_from_form;
+
+  if ($::form->{file}) {
+    my $file = SL::SessionFile->new($self->csv_file_name, mode => '>');
+    $file->fh->print($::form->{file});
+    $file->fh->close;
+  }
+
+  $self->{background_job} = SL::BackgroundJob::CsvImport->create_job(
+    file    => $self->csv_file_name,
+    profile => $self->profile,
+    type    => $self->profile->type,
+  )->save;
+
+  SL::System::TaskServer->start_if_not_running;
+  SL::System::TaskServer->wake_up;
+
+  flash('info', $::locale->text('Your import is beig processed.'));
+
+  $self->{deferred} = 1;
+
+  $self->render_inputs;
+}
+
 sub test_and_import {
   my ($self, %params) = @_;
 
@@ -189,8 +241,6 @@ sub test_and_import {
   $self->import_status($params{test} ? 'tested' : 'imported');
 
   flash('info', $::locale->text('Objects have been imported.')) if !$params{test};
-
-  $self->action_new;
 }
 
 sub load_default_profile {
index a0e1fa7..21dd484 100644 (file)
@@ -105,6 +105,14 @@ sub clone_and_reset_deep {
   return $clone;
 }
 
+sub flatten {
+  my ($self) = @_;
+
+  return map {
+    $_->key => $_->value
+  } $self->settings;
+}
+
 #
 # hooks
 #
index 57d0ba8..f5b4122 100644 (file)
@@ -43,6 +43,12 @@ sub start {
   return $self->_run_script_command('start');
 }
 
+sub start_if_not_running {
+  my ($self) = @_;
+
+  $self->start unless $self->is_running;
+}
+
 sub stop {
   my ($self) = @_;
 
diff --git a/templates/webpages/csv_import/_deferred_results.html b/templates/webpages/csv_import/_deferred_results.html
new file mode 100644 (file)
index 0000000..e422347
--- /dev/null
@@ -0,0 +1,21 @@
+<div id='progressbar'></div>
+[% IF progress < 100 %]
+<script type='text/javascript'>
+  function reload_results () {
+    $.ajax({
+      url: 'controller.pl',
+      data: {
+        action: 'CsvImport/result',
+        'profile.type': '[% SELF.profile.type %]',
+        job: '[% SELF.background_job.id %]'
+      },
+      success: function(data) { $('#results').html(data) },
+      error: function(e) { alert(e) },
+    });
+  }
+  $(document).ready(function(){
+    $('#progressbar').progressbar({ value: [% progress * 1 %] });
+    window.setTimeout(reload_results, 2000);
+  })
+</script>
+[% END %]
diff --git a/templates/webpages/csv_import/_results.html b/templates/webpages/csv_import/_results.html
new file mode 100644 (file)
index 0000000..56ec933
--- /dev/null
@@ -0,0 +1,12 @@
+  [%- IF SELF.errors %]
+   [%- PROCESS 'csv_import/_errors.html' %]
+  [%- END %]
+
+  [%- PROCESS 'csv_import/_result.html' %]
+  [%- PROCESS 'csv_import/_preview.html' %]
+
+[% IF progress == 100 %]
+<script type='text/javascript'>
+  $(function(){ $('#action_import').show() })
+</script>
+[% END %]
index c14fba7..2998de8 100644 (file)
 
  </form>
 
- [%- IF SELF.import_status %]
-  [%- IF SELF.errors %]
-   [%- PROCESS 'csv_import/_errors.html' %]
-  [%- END %]
-
-  [%- PROCESS 'csv_import/_result.html' %]
-  [%- PROCESS 'csv_import/_preview.html' %]
+ <div id='results'>
+ [%- IF SELF.deferred %]
+   [%- PROCESS 'csv_import/_deferred_results.html' %]
+ [%- ELSIF SELF.import_status %]
+   [%- PROCESS 'csv_import/_results.html' %]
  [%- END %]
+ </div>
+
 
  <script type="text/javascript">
   <!--