diff --git a/.perltidyrc b/.perltidyrc index 7c2cf62..f2ac20c 100644 --- a/.perltidyrc +++ b/.perltidyrc @@ -2,7 +2,7 @@ -w # Show all warnings -iob # Ignore old breakpoints -l=80 # 80 characters per line --mbl=2 # No more than 2 blank lines +-mbl=1 # No more than 2 blank lines -i=2 # Indentation is 2 columns -ci=2 # Continuation indentation is 2 columns -vt=0 # Less vertical tightness diff --git a/.travis.yml b/.travis.yml index 5147752..13a5212 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,15 +33,14 @@ before_script: - mojo version - coverage-setup notifications: - slack: - secure: hwihdXrKIOilNPyIunNh5yqBwtgwj4SnheF8DlsmQI2TqpcyFWgjvspnvquiV7+OEBb5mFUSZeEUj5cgIgJ3VaBFIbcij0nq3TTHAvSmx+oTboAxUkg62zdPaaFV+iK9BpCNm6eGsjE1Wfp6LXzBHOZetCXJ1IgQ02mOknkW2ysztNhF4G/MMUXvDe5ApgTHshGYvkaD+StHcLt2c6Quy4DUkKeU6Djun6Dyp3foSBibBRsQK9q0yXo5ooYkoVllEaSvu94FpxBjsF+lBQJveM2Wc090EgM1An/Oc/ptMVvMmSE0mmM8RR9vM5dUZwmZHd/kECo1cvGQG1nVJZ9qWnrCeWcnJS7M9FkFucEBjFJTzh1FL3tgYKnXkS04uQLaj84byQr7f+l4l8ExsJPUriQia9829+OeiRblOdB3mEEMgHleMhE0trfre7iz5Beob5sPwTq9z7ywrRVGX8vKeDXPEmwDi+5gdYXRw3QwNP7sWAePOdpZPzUBc5fUYZh8kJB22b8zoF1T81gxME0MQOc4nCgSCETtLWih3R8sngooAXXo9kYM3zb38ijoLpPwlOmE0BR9rvcSz8BBp1bVhWZ4k4ploe5uTtb+Mg31Amj6d5I5z9/KwYJQ6Mcy3y8Ijozm7+FpDLfjz70ZjAYguurmHFZsDQJQp4fJUcOFabc= + # slack: + # secure: hwihdXrKIOilNPyIunNh5yqBwtgwj4SnheF8DlsmQI2TqpcyFWgjvspnvquiV7+OEBb5mFUSZeEUj5cgIgJ3VaBFIbcij0nq3TTHAvSmx+oTboAxUkg62zdPaaFV+iK9BpCNm6eGsjE1Wfp6LXzBHOZetCXJ1IgQ02mOknkW2ysztNhF4G/MMUXvDe5ApgTHshGYvkaD+StHcLt2c6Quy4DUkKeU6Djun6Dyp3foSBibBRsQK9q0yXo5ooYkoVllEaSvu94FpxBjsF+lBQJveM2Wc090EgM1An/Oc/ptMVvMmSE0mmM8RR9vM5dUZwmZHd/kECo1cvGQG1nVJZ9qWnrCeWcnJS7M9FkFucEBjFJTzh1FL3tgYKnXkS04uQLaj84byQr7f+l4l8ExsJPUriQia9829+OeiRblOdB3mEEMgHleMhE0trfre7iz5Beob5sPwTq9z7ywrRVGX8vKeDXPEmwDi+5gdYXRw3QwNP7sWAePOdpZPzUBc5fUYZh8kJB22b8zoF1T81gxME0MQOc4nCgSCETtLWih3R8sngooAXXo9kYM3zb38ijoLpPwlOmE0BR9rvcSz8BBp1bVhWZ4k4ploe5uTtb+Mg31Amj6d5I5z9/KwYJQ6Mcy3y8Ijozm7+FpDLfjz70ZjAYguurmHFZsDQJQp4fJUcOFabc= email: on_success: always on_failure: always script: - export BIBSPACE_CONFIG=lib/BibSpace/files/config/default.conf - export BIBSPACE_USE_DUMP=1 -# - PERL5OPT=-MDevel::Cover=-coverage,statement,branch,condition,path,subroutine bin/bibspace test - PERL5OPT=-MDevel::Cover=-coverage,statement,branch,condition,path,subroutine prove -lr after_success: - cover -report coveralls diff --git a/Changelog.md b/Changelog.md index ddbc318..bb6582d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,9 @@ ### Changelog ### +#### v0.5.1 08.2017 #### +* Add support for docekrizing +* Move json files to json_data directory + #### v0.5.0 05.2016 #### * remove Redis-based caching * Big refactoring diff --git a/cpanfile b/cpanfile index b5664fe..30d30bd 100644 --- a/cpanfile +++ b/cpanfile @@ -1,7 +1,7 @@ requires 'Array::Utils' , '>= 0.0'; requires 'Apache::DBI' , '>= 0.0'; requires 'Crypt::Eksblowfish::Bcrypt' , '>= 0.0'; -requires 'Crypt::Random' , '>= 0.0'; +requires 'Bytes::Random' , '>= 0.0'; requires 'Cwd' , '>= 0.0'; requires 'DBD::mysql' , '>= 0.0'; requires 'DBI', '>= 1.619'; diff --git a/lib/BibSpace.pm b/lib/BibSpace.pm index 960e0da..62c307f 100644 --- a/lib/BibSpace.pm +++ b/lib/BibSpace.pm @@ -1,4 +1,4 @@ -package BibSpace v0.5.0; +package BibSpace v0.5.1; # ABSTRACT: BibSpace is a system to manage Bibtex references for authors and research groups web page. @@ -8,7 +8,7 @@ use BibSpace::Functions::MySqlBackupFunctions; use BibSpace::Functions::FDB; use BibSpace::Functions::FPublications; -# on test server: +# on test server: # BIBSPACE_CONFIG=/etc/bibspace_test.conf BIBSPACE_USE_DUMP=0 MOJO_MODE=development hypnotoad bin/bibspace use Mojo::Base 'Mojolicious'; @@ -16,6 +16,7 @@ use Mojo::Base 'Mojolicious::Plugin::Config'; use Data::Dumper; + # use File::Slurp; use POSIX qw/strftime/; use Try::Tiny; @@ -49,40 +50,48 @@ use BibSpace::Util::Preferences; use BibSpace::Util::EntityFactory; # STATE keyword -# state declares a lexically scoped variable, just like my. -# However, those variables will never be reinitialized, -# contrary to lexical variables that are reinitialized each time their enclosing block is entered. +# state declares a lexically scoped variable, just like my. +# However, those variables will never be reinitialized, +# contrary to lexical variables that are reinitialized each time their enclosing block is entered. # See Persistent Private Variables in perlsub for details. use feature qw( state say ); - ## OBJECTS CREATED AND CONTAINED IN HAS METHODS CANNOT BE CHANGED AT RUNTIME! + has preferences => sub { - return state $prefs = Preferences->new->load_maybe; + my $self = shift; + my $file + = $self->app->home->rel_file("bibspace_preferences.json"); + return state $prefs + = Preferences->new( filename => "" . $file )->load_maybe; }; has statistics => sub { - return state $stats = Statistics->new; + my $self = shift; + my $file = $self->app->home->rel_file("bibspace_stats.json"); + say $file; + return state $stats = Statistics->new( filename => "" . $file )->load_maybe; }; has config_file => sub { - my $self = shift; - my $candidate; - $candidate = $ENV{BIBSPACE_CONFIG}; - return $candidate if defined $candidate and -e $candidate; + my $self = shift; + my $candidate; + $candidate = $ENV{BIBSPACE_CONFIG}; + return $candidate if defined $candidate and -e $candidate; - $candidate = $self->app->home->rel_file('/etc/bibspace.conf'); - return $candidate if -e $candidate; + $candidate = $self->app->home->rel_file('/etc/bibspace.conf'); + return $candidate if -e $candidate; - $candidate = $self->app->home->rel_file('lib/BibSpace/files/config/default.conf'); - return $candidate if -e $candidate; + $candidate + = $self->app->home->rel_file('lib/BibSpace/files/config/default.conf'); + return $candidate if -e $candidate; - $candidate = $self->app->home->rel_file('config/default.conf'); # for travis - return $candidate if -e $candidate; + $candidate = $self->app->home->rel_file('config/default.conf'); # for travis + return $candidate if -e $candidate; - die "Cannot find Bibspace config!"; - return; + die "Cannot find Bibspace config!"; + return; }; has get_backups_dir => sub { @@ -107,7 +116,7 @@ has get_log_dir => sub { }; # do not use this - if MySQL server dies during operation, you will be not able to reconnect! -# use helper +# use helper ## OBJECTS CREATED AND CONTAINED IN HAS METHODS CANNOT BE CHANGED AT RUNTIME! # has db => sub { # my $self = shift; @@ -118,679 +127,658 @@ has get_log_dir => sub { # }; has version => sub { - return $BibSpace::VERSION // "0.5.0"; + return $BibSpace::VERSION // "0.5.0"; }; has quick_load_fixture_filename => sub { - return 'bibspace.dat'; + my $self = shift; + return $self->app->home->rel_file('bibspace.dat'); }; # don't want to read data form DB and wait to link them every reload? # use quick_load_fixture! Useful for development and testing. # better disable it for production has use_quick_load_fixture => sub { - my $self = shift; - return if $self->mode eq 'production'; + my $self = shift; + return if $self->mode eq 'production'; - return 1 - if defined $ENV{BIBSPACE_USE_DUMP} and $ENV{BIBSPACE_USE_DUMP} == 1; - return; + return 1 + if defined $ENV{BIBSPACE_USE_DUMP} and $ENV{BIBSPACE_USE_DUMP} == 1; + return; }; -# please use only a single type of logger at once. +# please use only a single type of logger at once. # Using multiple may not be supported currently # if you really want to use multiple different loggers or state-full loggers (please don't), # then you need to move the object construction INTO the LayeredReposity and provide a helper to access it for everywhere. has logger => sub { state $logger = SimpleLogger->new() }; - has smartArrayBackend => sub { - my $self = shift; - return SmartArray->new( logger => $self->logger ); + my $self = shift; + return SmartArray->new( logger => $self->logger ); }; ## I moved this to helpers as app->attr for a while has layeredRepository => sub { - my $self = shift; - $self->app->logger->info("Building layeredRepository"); - - - my $LR = LayeredRepository->new( - logger => $self->logger, - preferences => $self->preferences, - # id_provider_class => 'DummyUidProvider', - id_provider_class => 'IntegerUidProvider', - ); + my $self = shift; + $self->app->logger->info("Building layeredRepository"); - my $smartArrayLayer = RepositoryLayer->new( - name => 'smart', - priority => 1, - creates_on_read => undef, - backendFactoryName => "SmartArrayDAOFactory", - logger => $self->logger, - handle => $self->smartArrayBackend, + + my $LR = LayeredRepository->new( + logger => $self->logger, + preferences => $self->preferences, + + # id_provider_class => 'DummyUidProvider', + id_provider_class => 'IntegerUidProvider', + ); + + my $smartArrayLayer = RepositoryLayer->new( + name => 'smart', + priority => 1, + creates_on_read => undef, + backendFactoryName => "SmartArrayDAOFactory", + logger => $self->logger, + handle => $self->smartArrayBackend, # reset_data_callback must be undef if you want to create and restore backups using Storable. - reset_data_callback => undef, - is_read => 1 + reset_data_callback => undef, + is_read => 1 + ); + $LR->add_layer($smartArrayLayer); + + if ( !$self->db ) { + $self->logger->error( + "You add SQL layer, but there is no connection to the database! Skipping this layer." + . " You need to start MySQL server and restart BibSpace to use this layer" ); - $LR->add_layer($smartArrayLayer); - - if ( !$self->db ) { - $self->logger->error( - "You add SQL layer, but there is no connection to the database! Skipping this layer." - . " You need to start MySQL server and restart BibSpace to use this layer" - ); - } - else { - my $mySQLLayer = RepositoryLayer->new( - name => 'mysql', - priority => 99, - creates_on_read => 1, - backendFactoryName => "MySQLDAOFactory", - logger => $self->logger, - handle => $self->db, - reset_data_callback => \&reset_db_data, - reset_data_callback_arguments => [ $self->db ], - ); - $LR->add_layer($mySQLLayer); - } - return $LR; + } + else { + my $mySQLLayer = RepositoryLayer->new( + name => 'mysql', + priority => 99, + creates_on_read => 1, + backendFactoryName => "MySQLDAOFactory", + logger => $self->logger, + handle => $self->db, + reset_data_callback => \&reset_db_data, + reset_data_callback_arguments => [ $self->db ], + ); + $LR->add_layer($mySQLLayer); + } + return $LR; }; # layeredRepository will not change at runtime => repo neither. has repo => sub { - my $self = shift; - return RepositoryFacade->new( lr => $self->layeredRepository ); + my $self = shift; + return RepositoryFacade->new( lr => $self->layeredRepository ); }; ################################################################ sub startup { - my $self = shift; - $self->app->logger->info("*** Starting BibSpace ***"); - + my $self = shift; + $self->app->logger->info("*** Starting BibSpace ***"); - $self->setup_config; - $self->setup_plugins; - $self->app->preferences->local_time_zone( DateTime::TimeZone->new( name => 'local' )->name ); + $self->setup_config; + $self->setup_plugins; - $self->setup_routes; - $self->setup_hooks; - $self->setup_repositories; - $self->insert_admin; + $self->app->preferences->local_time_zone( + DateTime::TimeZone->new( name => 'local' )->name ); + $self->setup_routes; + $self->setup_hooks; + $self->setup_repositories; + $self->insert_admin; - - $self->app->logger->info("Setup done."); + $self->app->logger->info("Setup done."); - $self->app->logger->info( "Using CONFIG: " . $self->app->config_file ); - $self->app->logger->info( "App home is: " . $self->app->home ); - $self->app->logger->info( "Active bst file is: " . $self->app->bst ); + $self->app->logger->info( "Using CONFIG: " . $self->app->config_file ); + $self->app->logger->info( "App home is: " . $self->app->home ); + $self->app->logger->info( "Active bst file is: " . $self->app->bst ); - ############################### - ########### SANDBOX ########### - ############################### - - # # cool! - # my $author = $self->app->entityFactory->new_Author( uid => "AabakusAston" ); - # say $author->uid; - # say $author->id; - # # say $author->preferences; + ############################### + ########### SANDBOX ########### + ############################### - # say Dumper $author; - # $self->app->repo->authors_save($author); +# # cool! +# my $author = $self->app->entityFactory->new_Author( uid => "AabakusAston" ); +# say $author->uid; +# say $author->id; +# # say $author->preferences; + # say Dumper $author; + # $self->app->repo->authors_save($author); - # my @users = $self->app->repo->users_all; - # $self->logger->warn("All users: ".@users); - # map {say $_->toString } @users; + # my @users = $self->app->repo->users_all; + # $self->logger->warn("All users: ".@users); + # map {say $_->toString } @users; - # my @users_to_delete = $self->app->repo->users_filter(sub{$_->email =~ /\@example.com/}); - # $self->logger->warn("To delete: ".@users_to_delete); - # map {say $_->toString } @users_to_delete; - # $self->app->repo->users_delete(@users_to_delete); +# my @users_to_delete = $self->app->repo->users_filter(sub{$_->email =~ /\@example.com/}); +# $self->logger->warn("To delete: ".@users_to_delete); +# map {say $_->toString } @users_to_delete; +# $self->app->repo->users_delete(@users_to_delete); - # $self->logger->info("this is info"); - # $self->logger->warn("this is warning"); - # $self->logger->error("this is error"); + # $self->logger->info("this is info"); + # $self->logger->warn("this is warning"); + # $self->logger->error("this is error"); } ################################################################ sub insert_admin { - my $self = shift; - $self->app->logger->info("Add startup admin user..."); - - my $admin_exists - = $self->app->repo->users_find( sub { $_->login eq 'pub_admin' } ); - if ( !$admin_exists ) { - my $salt = salt(); - my $hash = encrypt_password( 'asdf', $salt ); - my $new_user = $self->app->entityFactory->new_User( - login => 'pub_admin', - email => 'pub_admin@example.com', - real_name => 'Admin', - rank => 99, - pass => $hash, - pass2 => $salt - ); - $self->app->repo->users_save($new_user); - } - else { - # this email is used in tests! - $admin_exists->email('pub_admin@example.com'); - $admin_exists->make_admin; - $self->app->repo->users_update($admin_exists); - } + my $self = shift; + $self->app->logger->info("Add startup admin user..."); + + my $admin_exists + = $self->app->repo->users_find( sub { $_->login eq 'pub_admin' } ); + if ( !$admin_exists ) { + my $salt = salt(); + my $hash = encrypt_password( 'asdf', $salt ); + my $new_user = $self->app->entityFactory->new_User( + login => 'pub_admin', + email => 'pub_admin@example.com', + real_name => 'Admin', + rank => 99, + pass => $hash, + pass2 => $salt + ); + $self->app->repo->users_save($new_user); + } + else { + # this email is used in tests! + $admin_exists->email('pub_admin@example.com'); + $admin_exists->make_admin; + $self->app->repo->users_update($admin_exists); + } } ################################################################ sub setup_repositories { - my $self = shift; + my $self = shift; - $self->app->logger->info("Setup repositories..."); + $self->app->logger->info("Setup repositories..."); - if ( -e $self->quick_load_fixture_filename - and $self->use_quick_load_fixture ) - { + if ( -e $self->quick_load_fixture_filename + and $self->use_quick_load_fixture ) + { # $self->app->logger->info("Retrieving dump from '".$self->quick_load_fixture_filename."'."); - my $layer = retrieve( $self->quick_load_fixture_filename ); + my $layer = retrieve( $self->quick_load_fixture_filename ); - # reser read layer = not needed, layer empty by start of the app - # $self->app->logger->info("Replacing layer 'smart' with the dump."); - $self->repo->lr->replace_layer( 'smart', $layer ); + # reser read layer = not needed, layer empty by start of the app + # $self->app->logger->info("Replacing layer 'smart' with the dump."); + $self->repo->lr->replace_layer( 'smart', $layer ); # $self->app->logger->debug("State after replacement:".$self->repo->lr->get_summary_table); - } - else { - $self->app->logger->info( "We do not use dump file '" - . $self->quick_load_fixture_filename - . "'." ); - } + } + else { + $self->app->logger->info( "We do not use dump file '" + . $self->quick_load_fixture_filename + . "'." ); + } - # no data, no fun = no need to copy, link, and store - if ( $self->repo->entries_empty ) { - $self->app->logger->info("Repo has no entries. Reseting read_layer."); + # no data, no fun = no need to copy, link, and store + if ( $self->repo->entries_empty ) { + $self->app->logger->info("Repo has no entries. Reseting read_layer."); - $self->repo->lr->copy_data( { from => 'mysql', to => 'smart' } ); + $self->repo->lr->copy_data( { from => 'mysql', to => 'smart' } ); - # Entities and Relations in the smart layer must be linked! - $self->link_data; - - $self->app->logger->info( "Storing current state to dump file '" - . $self->quick_load_fixture_filename - . "'." ); + # Entities and Relations in the smart layer must be linked! + $self->link_data; - # store current state to file - store $self->repo->lr->get_read_layer, - $self->quick_load_fixture_filename; - } + $self->app->logger->info( "Storing current state to dump file '" + . $self->quick_load_fixture_filename + . "'." ); + + # store current state to file + store $self->repo->lr->get_read_layer, $self->quick_load_fixture_filename; + } } ################################################################ sub link_data { - my $self = shift; - $self->app->logger->info("Linking data..."); - - $self->app->logger->info("Linking Authors (N) to (1) Authors."); - foreach my $author ( - $self->repo->authors_filter( sub { $_->id != $_->master_id } ) ) - { - my $master - = $self->repo->authors_find( sub { $_->id == $author->master_id } - ); - if ( $master and $author ) { - $author->set_master($master); - } + my $self = shift; + $self->app->logger->info("Linking data..."); + + $self->app->logger->info("Linking Authors (N) to (1) Authors."); + foreach my $author ( + $self->repo->authors_filter( sub { $_->id != $_->master_id } ) ) + { + my $master + = $self->repo->authors_find( sub { $_->id == $author->master_id } ); + if ( $master and $author ) { + $author->set_master($master); } - - - $self->app->logger->info("Linking Authors (N) to (M) Entries."); - foreach my $auth ( $self->repo->authorships_all ) { - my $entry - = $self->repo->entries_find( sub { $_->id == $auth->entry_id } ); - my $author - = $self->repo->authors_find( sub { $_->id == $auth->author_id } ); - if ( $entry and $author ) { - $auth->entry($entry); - $auth->author($author); - $entry->authorships_add($auth); - $author->authorships_add($auth); - } + } + + + $self->app->logger->info("Linking Authors (N) to (M) Entries."); + foreach my $auth ( $self->repo->authorships_all ) { + my $entry + = $self->repo->entries_find( sub { $_->id == $auth->entry_id } ); + my $author + = $self->repo->authors_find( sub { $_->id == $auth->author_id } ); + if ( $entry and $author ) { + $auth->entry($entry); + $auth->author($author); + $entry->authorships_add($auth); + $author->authorships_add($auth); } - - $self->app->logger->info("Linking Tags (N) to (M) Entries."); - foreach my $labeling ( $self->repo->labelings_all ) { - my $entry - = $self->repo->entries_find( sub { $_->id == $labeling->entry_id } - ); - my $tag - = $self->repo->tags_find( sub { $_->id == $labeling->tag_id } ); - if ( $entry and $tag ) { - $labeling->entry($entry); - $labeling->tag($tag); - $entry->labelings_add($labeling); - $tag->labelings_add($labeling); - } + } + + $self->app->logger->info("Linking Tags (N) to (M) Entries."); + foreach my $labeling ( $self->repo->labelings_all ) { + my $entry + = $self->repo->entries_find( sub { $_->id == $labeling->entry_id } ); + my $tag = $self->repo->tags_find( sub { $_->id == $labeling->tag_id } ); + if ( $entry and $tag ) { + $labeling->entry($entry); + $labeling->tag($tag); + $entry->labelings_add($labeling); + $tag->labelings_add($labeling); } - - $self->app->logger->info( - "Linking Teams (Exceptions) (N) to (M) Entries."); - foreach my $exception ( $self->repo->exceptions_all ) { - my $entry = $self->repo->entries_find( - sub { $_->id == $exception->entry_id } ); - my $team - = $self->repo->teams_find( sub { $_->id == $exception->team_id } - ); - if ( $entry and $team ) { - $exception->entry($entry); - $exception->team($team); - $entry->exceptions_add($exception); - $team->exceptions_add($exception); - } + } + + $self->app->logger->info("Linking Teams (Exceptions) (N) to (M) Entries."); + foreach my $exception ( $self->repo->exceptions_all ) { + my $entry + = $self->repo->entries_find( sub { $_->id == $exception->entry_id } ); + my $team + = $self->repo->teams_find( sub { $_->id == $exception->team_id } ); + if ( $entry and $team ) { + $exception->entry($entry); + $exception->team($team); + $entry->exceptions_add($exception); + $team->exceptions_add($exception); } + } - $self->app->logger->info("Linking Teams (N) to (M) Authors."); - foreach my $membership ( $self->repo->memberships_all ) { - my $author = $self->repo->authors_find( - sub { $_->id == $membership->author_id } ); - my $team - = $self->repo->teams_find( sub { $_->id == $membership->team_id } - ); - if ( defined $author and defined $team ) { - $membership->author($author); - $membership->team($team); - $author->memberships_add($membership); - $team->memberships_add($membership); - } + $self->app->logger->info("Linking Teams (N) to (M) Authors."); + foreach my $membership ( $self->repo->memberships_all ) { + my $author + = $self->repo->authors_find( sub { $_->id == $membership->author_id } + ); + my $team + = $self->repo->teams_find( sub { $_->id == $membership->team_id } ); + if ( defined $author and defined $team ) { + $membership->author($author); + $membership->team($team); + $author->memberships_add($membership); + $team->memberships_add($membership); } + } - $self->app->logger->info("Linking TagTypes (N) to (1) Tags."); - foreach my $tag ( $self->repo->tags_all ) { - my $tagtype - = $self->repo->tagTypes_find( sub { $_->id == $tag->type } ); - if ( $tag and $tagtype ) { - $tag->tagtype($tagtype); - } + $self->app->logger->info("Linking TagTypes (N) to (1) Tags."); + foreach my $tag ( $self->repo->tags_all ) { + my $tagtype = $self->repo->tagTypes_find( sub { $_->id == $tag->type } ); + if ( $tag and $tagtype ) { + $tag->tagtype($tagtype); } + } - $self->app->logger->info("TODO: Linking OurTypes (N) to (1) Entries."); + $self->app->logger->info("TODO: Linking OurTypes (N) to (1) Entries."); - $self->app->logger->info("Linking Finished."); + $self->app->logger->info("Linking Finished."); } ################################################################ sub setup_config { - my $self = shift; - my $app = $self; - $self->app->logger->info("Setup config..."); - $self->plugin( 'Config' => { file => $self->app->config_file } ); - - $ENV{MOJO_MAX_MESSAGE_SIZE} = 40 * 1024 * 1024; - $self->app->logger->info( "Setting max upload size to " - . $ENV{MOJO_MAX_MESSAGE_SIZE} - . " Bytes." ); + my $self = shift; + my $app = $self; + $self->app->logger->info("Setup config..."); + $self->plugin( 'Config' => { file => $self->app->config_file } ); + + $ENV{MOJO_MAX_MESSAGE_SIZE} = 40 * 1024 * 1024; + $self->app->logger->info( + "Setting max upload size to " . $ENV{MOJO_MAX_MESSAGE_SIZE} . " Bytes." ); } ################################################################ sub setup_plugins { - my $self = shift; - $self->app->logger->info("Setup plugins..."); - - $ENV{MOJO_REVERSE_PROXY} = 1; - - $self->app->plugin('InstallablePaths'); - $self->app->plugin('RenderFile'); - $self->plugin('BibSpace::Controller::Helpers'); - - push @{ $self->app->static->paths }, $self->app->home->rel_file('public'); - - # push @{$self->app->static->paths}, $self->config->{backups_dir}; - - $self->app->logger->info("App version: " . $self->app->version); - $self->app->logger->info("Creating directories..."); - for my $dir ( ( $self->app->get_backups_dir, - $self->app->get_upload_dir, - $self->app->get_upload_dir."papers", - $self->app->get_upload_dir."slides", - $self->app->get_log_dir) ) - { - $self->app->logger->debug("Creating directory: $dir"); - try { - Path::Tiny->new($dir)->mkpath; - } - catch { - $self->app->logger->error("Exception: cannot create directory $dir. Msg: $_"); - }; + my $self = shift; + $self->app->logger->info("Setup plugins..."); + + $ENV{MOJO_REVERSE_PROXY} = 1; + + $self->app->plugin('InstallablePaths'); + $self->app->plugin('RenderFile'); + $self->plugin('BibSpace::Controller::Helpers'); + + push @{ $self->app->static->paths }, $self->app->home->rel_file('public'); + + # push @{$self->app->static->paths}, $self->config->{backups_dir}; + + $self->app->logger->info( "App version: " . $self->app->version ); + $self->app->logger->info("Creating directories..."); + for my $dir ( + ( $self->app->get_backups_dir, + $self->app->get_upload_dir, + $self->app->get_upload_dir . "papers", + $self->app->get_upload_dir . "slides", + $self->app->get_log_dir + ) + ) + { + $self->app->logger->debug("Creating directory: $dir"); + try { + Path::Tiny->new($dir)->mkpath; } + catch { + $self->app->logger->error( + "Exception: cannot create directory $dir. Msg: $_"); + }; + } - # set logging dir in the logger - $self->app->logger->debug("Setting log dir to the logger"); - $self->logger->set_log_dir("".Path::Tiny->new($self->get_log_dir) ); + # set logging dir in the logger + $self->app->logger->debug("Setting log dir to the logger"); + $self->logger->set_log_dir( "" . Path::Tiny->new( $self->get_log_dir ) ); + # this is supposed to trigger connection to the DB + $self->app->db; - # this is supposed to trigger connection to the DB - $self->app->db; - - - $self->secrets( [ $self->config->{key_cookie} ] ); - - $self->helper( proxy_prefix => sub { $self->config->{proxy_prefix} } ); + $self->secrets( [ $self->config->{key_cookie} ] ); + $self->helper( proxy_prefix => sub { $self->config->{proxy_prefix} } ); } ################################################################ ################################################################ sub setup_routes { - my $self = shift; - $self->app->logger->info("Setup routes..."); - - my $anyone = $self->routes; - $anyone->get('/')->to('display#index')->name('start'); - - - $anyone->get('/forgot')->to('login#forgot'); - $anyone->post('/forgot/gen')->to('login#post_gen_forgot_token'); - $anyone->get('/forgot/reset/:token')->to('login#token_clicked') - ->name("token_clicked"); - $anyone->post('/forgot/store')->to('login#store_password'); - - $anyone->get('/login_form')->to('login#login_form')->name('login_form'); - $anyone->post('/do_login')->to('login#login')->name('do_login'); - $anyone->get('/youneedtologin')->to('login#not_logged_in') - ->name('youneedtologin'); - $anyone->get('/badpassword')->to('login#bad_password') - ->name('badpassword'); - - $anyone->get('/logout')->to('login#logout')->name('logout'); - - $anyone->any('/test/500')->to('display#test500')->name('error500'); - $anyone->any('/test/404')->to('display#test404')->name('error404'); - - $anyone->get('/register')->to('login#register')->name('register'); - $anyone->post('/register')->to('login#post_do_register') - ->name('post_do_register'); - $anyone->any('/noregister')->to('login#register_disabled'); - - my $logged_user = $anyone->under->to('login#check_is_logged_in'); - my $manager_user - = $logged_user->under->to('login#under_check_is_manager'); - my $admin_user = $logged_user->under->to('login#under_check_is_admin'); - - ################ PREFERENCES ################ - - $manager_user->get('/preferences')->to('preferences#index')->name('preferences'); - $admin_user->post('/preferences')->to('preferences#save')->name('save_preferences'); - - ################ EXPERIMENTAL / PERSISTENCE ################ - - $anyone->get('/system_status')->to('persistence#system_status') - ->name('system_status'); - $admin_user->get('/persistence/load')->to('persistence#load_fixture') - ->name('load_fixture'); - $admin_user->get('/persistence/save')->to('persistence#save_fixture') - ->name('save_fixture'); - $admin_user->get('/persistence/copy_mysql_to_smart') - ->to('persistence#copy_mysql_to_smart')->name('copy_mysql_to_smart'); - $admin_user->get('/persistence/copy_smart_to_mysql') - ->to('persistence#copy_smart_to_mysql')->name('copy_smart_to_mysql'); - - $admin_user->get('/persistence/persistence_status') - ->to('persistence#persistence_status')->name('persistence_status'); - $admin_user->get('/persistence/persistence_status_ajax') - ->to('persistence#persistence_status_ajax')->name('persistence_status_ajax'); - - - $admin_user->get('/persistence/reset_mysql') - ->to('persistence#reset_mysql')->name('reset_mysql'); - $admin_user->get('/persistence/reset_smart') - ->to('persistence#reset_smart')->name('reset_smart'); - $admin_user->get('/persistence/reset_all') - ->to('persistence#reset_all')->name('reset_all'); - - $admin_user->get('/persistence/insert_random_data') - ->to('persistence#insert_random_data')->name('insert_random_data'); - - - - ################ SETTINGS ################ - $logged_user->get('/profile')->to('login#profile'); - $admin_user->get('/manage_users')->to('login#manage_users') - ->name('manage_users'); - $admin_user->get('/profile/:id')->to('login#foreign_profile') - ->name('show_user_profile'); - $admin_user->get('/profile/delete/:id')->to('login#delete_user') - ->name('delete_user'); - - $admin_user->get('/profile/make_user/:id')->to('login#make_user') - ->name('make_user'); - $admin_user->get('/profile/make_manager/:id')->to('login#make_manager') - ->name('make_manager'); - $admin_user->get('/profile/make_admin/:id')->to('login#make_admin') - ->name('make_admin'); - - $manager_user->get('/log')->to('display#show_log')->name('show_log'); - # websocket for fun - $manager_user->websocket('/log_websocket/:num')->to('display#show_log_ws')->name('show_log_websocket'); - $manager_user->websocket('/statistics/:num')->to('display#show_stats_websocket')->name('show_stats_websocket'); - - - + my $self = shift; + $self->app->logger->info("Setup routes..."); + + my $anyone = $self->routes; + $anyone->get('/')->to('display#index')->name('start'); + + + $anyone->get('/forgot')->to('login#forgot'); + $anyone->post('/forgot/gen')->to('login#post_gen_forgot_token'); + $anyone->get('/forgot/reset/:token')->to('login#token_clicked') + ->name("token_clicked"); + $anyone->post('/forgot/store')->to('login#store_password'); + + $anyone->get('/login_form')->to('login#login_form')->name('login_form'); + $anyone->post('/do_login')->to('login#login')->name('do_login'); + $anyone->get('/youneedtologin')->to('login#not_logged_in') + ->name('youneedtologin'); + $anyone->get('/badpassword')->to('login#bad_password')->name('badpassword'); + + $anyone->get('/logout')->to('login#logout')->name('logout'); - $admin_user->get('/settings/fix_months') - ->to('publications#fixMonths') - ->name('fix_all_months'); - - $manager_user->get('/settings/clean_all') - ->to('publications#clean_ugly_bibtex') - ->name('clean_ugly_bibtex'); - - $manager_user->get('/settings/mark_all_to_regenerate') - ->to('publications#mark_all_to_regenerate') - ->name('mark_all_to_regenerate'); - - $manager_user->get('/settings/mark_author_to_regenerate/:author_id') - ->to('publications#mark_author_to_regenerate') - ->name('mark_author_to_regenerate'); - - $manager_user->get('/settings/regenerate_all') - ->to('publications#regenerate_html_for_all') - ->name('regenerate_html_for_all'); - - $logged_user->get('/settings/regenerate_html_in_chunk/:chunk_size') - ->to('publications#regenerate_html_in_chunk') - ->name('regenerate_html_in_chunk'); - - - - - - - $manager_user->get('/backups') - ->to('backup#index')->name('backup_index'); - $manager_user->put('/backups') - ->to('backup#save')->name('backup_do'); - $manager_user->put('/backups/mysql') - ->to('backup#save_mysql')->name('backup_do_mysql'); - $manager_user->get('/backups/:id') - ->to('backup#backup_download')->name('backup_download'); - - $admin_user->delete('/backups/:id') - ->to('backup#delete_backup')->name('backup_delete'); - $admin_user->put('/backups/:id') - ->to('backup#restore_backup')->name('backup_restore'); - $admin_user->delete('/backups') - ->to('backup#cleanup')->name('backup_cleanup'); - - - ################ TYPES ################ - $logged_user->get('/types')->to('types#all_our')->name('all_types'); - $manager_user->get('/types/add')->to('types#add_type') - ->name('add_type_get'); - $manager_user->post('/types/add')->to('types#post_add_type') - ->name('add_type_post'); - $manager_user->get('/types/manage/:name')->to('types#manage') - ->name('edit_type'); - $manager_user->get('/types/delete/:name')->to('types#delete_type') - ->name('delete_type'); - - $manager_user->post('/types/store_description') - ->to('types#post_store_description')->name('update_type_description'); - $manager_user->get('/types/toggle/:name')->to('types#toggle_landing') - ->name('toggle_landing_type'); - - $manager_user->get('/types/:our_type/map/:bibtex_type') - ->to('types#map_types'); - $manager_user->get('/types/:our_type/unmap/:bibtex_type') - ->to('types#unmap_types')->name('unmap_bibtex_type'); - - ################ AUTHORS ################ - - $logged_user->get('/authors/')->to('authors#all_authors') - ->name('all_authors'); - $manager_user->get('/authors/add')->to('authors#add_author') - ->name('add_author'); - $manager_user->post('/authors/add/')->to('authors#add_post'); - - $logged_user->get('/authors/edit/:id')->to('authors#edit_author') - ->name('edit_author'); - $manager_user->post('/authors/edit/')->to('authors#edit_post') - ->name('edit_author_post'); - $manager_user->get('/authors/delete/:id')->to('authors#delete_author') - ->name('delete_author'); - - - $admin_user->get('/authors/delete/:id/force') - ->to('authors#delete_author_force'); - - - - # for dev only!! - $admin_user->get('/authors/decimate') - ->to('authors#delete_invisible_authors'); - - - - - - $manager_user->post('/authors/edit_membership_dates') - ->to('authors#post_edit_membership_dates') - ->name('edit_author_membership_dates'); - - $manager_user->get('/authors/:id/add_to_team/:tid') - ->to('authors#add_to_team')->name('add_author_to_team'); - $manager_user->get('/authors/:id/remove_from_team/:tid') - ->to('authors#remove_from_team')->name('remove_author_from_team'); - $manager_user->get('/authors/:masterid/remove_uid/:uid') - ->to('authors#remove_uid')->name('remove_author_uid'); - - $manager_user->post('/authors/merge/')->to('authors#merge_authors') - ->name('merge_authors'); - - $admin_user->get('/authors/fix_masters') - ->to('authors#fix_masters')->name('fix_masters'); - - $manager_user->get('/authors/reassign') - ->to('authors#reassign_authors_to_entries'); - $admin_user->get('/authors/reassign_and_create') - ->to('authors#reassign_authors_to_entries_and_create_authors'); - - $manager_user->get('/authors/toggle_visibility/:id') - ->to('authors#toggle_visibility')->name('toggle_author_visibility'); - - # $logged_user->get('/authors/toggle_visibility') - # ->to('authors#toggle_visibility'); - - ################ TAG TYPES ################ - # $logged_user->get('/tags/')->to('tags#index')->name("tags_index"); - $logged_user->get('/tagtypes')->to('tagtypes#index') - ->name('all_tag_types'); - $admin_user->get('/tagtypes/add')->to('tagtypes#add') - ->name('add_tag_type'); - $admin_user->post('/tagtypes/add')->to('tagtypes#add_post') - ->name('add_tag_type_post'); - $admin_user->get('/tagtypes/delete/:id')->to('tagtypes#delete') - ->name('delete_tag_type'); - $manager_user->any('/tagtypes/edit/:id')->to('tagtypes#edit') - ->name('edit_tag_type'); - - ################ TAGS ################ - $logged_user->get('/tags/:type')->to( 'tags#index', type => 1 ) - ->name('all_tags'); - $admin_user->get('/tags/add/:type')->to( 'tags#add', type => 1 ) - ->name('add_tag_get'); - $admin_user->post('/tags/add/:type')->to( 'tags#add_post', type => 1 ) - ->name('add_tag_post'); - $logged_user->get('/tags/authors/:id/:type') - ->to( 'tags#get_authors_for_tag', type => 1 ) - ->name('get_authors_for_tag'); - $admin_user->get('/tags/delete/:id')->to('tags#delete') - ->name('delete_tag'); - - ### EDIT TAG FORM GOES WITH GET - WTF!?! - # FIXME: FIX THIS - $manager_user->get('/tags/edit/:id')->to('tags#edit')->name('edit_tag'); - - $anyone->get('/read/authors-for-tag/:tag_id/:team_id') - ->to('tags#get_authors_for_tag_and_team') - ->name('get_authors_for_tag_and_team'); - - #ALIAS - $anyone->get('/r/a4t/:tag_id/:team_id') - ->to('tags#get_authors_for_tag_and_team') - ->name('get_authors_for_tag_and_team'); - - $anyone->get('/read/authors-for-tag/:tag_id/:team_id') - ->to('tags#get_authors_for_tag_and_team') - ->name('get_authors_for_tag_and_team'); - - #ALIAS - $anyone->get('/r/a4t/:tag_id/:team_id') - ->to('tags#get_authors_for_tag_and_team') - ->name('get_authors_for_tag_and_team'); - - $anyone->get('/read/tags-for-author/:author_id') - ->to('tags#get_tags_for_author_read')->name('tags_for_author'); - - #ALIAS - $anyone->get('/r/t4a/:author_id')->to('tags#get_tags_for_author_read'); - - $anyone->get('/read/tags-for-team/:team_id') - ->to('tags#get_tags_for_team_read')->name('tags_for_team'); - - #ALIAS - $anyone->get('/r/t4t/:team_id')->to('tags#get_tags_for_team_read'); - - ################ TEAMS ################ - $logged_user->get('/teams')->to('teams#show')->name('all_teams'); - $logged_user->get('/teams/members/:teamid')->to('teams#team_members'); - - $manager_user->get('/teams/edit/:id')->to('teams#edit') - ->name('edit_team'); - $manager_user->get('/teams/delete/:id')->to('teams#delete_team') - ->name('delete_team'); - $manager_user->get('/teams/delete/:id/force') - ->to('teams#delete_team_force')->name('delete_team_force'); - $logged_user->get('/teams/unrealted_papers/:teamid') - ->to('publications#show_unrelated_to_team') - ->name('unrelated_papers_for_team'); - - $manager_user->get('/teams/add')->to('teams#add_team') - ->name('add_team_get'); - $manager_user->post('/teams/add/')->to('teams#add_team_post'); - - ################ EDITING PUBLICATIONS ################ + $anyone->any('/test/500')->to('display#test500')->name('error500'); + $anyone->any('/test/404')->to('display#test404')->name('error404'); + + $anyone->get('/register')->to('login#register')->name('register'); + $anyone->post('/register')->to('login#post_do_register') + ->name('post_do_register'); + $anyone->any('/noregister')->to('login#register_disabled'); + + my $logged_user = $anyone->under->to('login#check_is_logged_in'); + my $manager_user = $logged_user->under->to('login#under_check_is_manager'); + my $admin_user = $logged_user->under->to('login#under_check_is_admin'); + + ################ PREFERENCES ################ + + $manager_user->get('/preferences')->to('preferences#index') + ->name('preferences'); + $admin_user->post('/preferences')->to('preferences#save') + ->name('save_preferences'); + + ################ EXPERIMENTAL / PERSISTENCE ################ + + $anyone->get('/system_status')->to('persistence#system_status') + ->name('system_status'); + $admin_user->get('/persistence/load')->to('persistence#load_fixture') + ->name('load_fixture'); + $admin_user->get('/persistence/save')->to('persistence#save_fixture') + ->name('save_fixture'); + $admin_user->get('/persistence/copy_mysql_to_smart') + ->to('persistence#copy_mysql_to_smart')->name('copy_mysql_to_smart'); + $admin_user->get('/persistence/copy_smart_to_mysql') + ->to('persistence#copy_smart_to_mysql')->name('copy_smart_to_mysql'); + + $admin_user->get('/persistence/persistence_status') + ->to('persistence#persistence_status')->name('persistence_status'); + $admin_user->get('/persistence/persistence_status_ajax') + ->to('persistence#persistence_status_ajax') + ->name('persistence_status_ajax'); + + + $admin_user->get('/persistence/reset_mysql')->to('persistence#reset_mysql') + ->name('reset_mysql'); + $admin_user->get('/persistence/reset_smart')->to('persistence#reset_smart') + ->name('reset_smart'); + $admin_user->get('/persistence/reset_all')->to('persistence#reset_all') + ->name('reset_all'); + + $admin_user->get('/persistence/insert_random_data') + ->to('persistence#insert_random_data')->name('insert_random_data'); + + + ################ SETTINGS ################ + $logged_user->get('/profile')->to('login#profile'); + $admin_user->get('/manage_users')->to('login#manage_users') + ->name('manage_users'); + $admin_user->get('/profile/:id')->to('login#foreign_profile') + ->name('show_user_profile'); + $admin_user->get('/profile/delete/:id')->to('login#delete_user') + ->name('delete_user'); + + $admin_user->get('/profile/make_user/:id')->to('login#make_user') + ->name('make_user'); + $admin_user->get('/profile/make_manager/:id')->to('login#make_manager') + ->name('make_manager'); + $admin_user->get('/profile/make_admin/:id')->to('login#make_admin') + ->name('make_admin'); + + $manager_user->get('/log')->to('display#show_log')->name('show_log'); + $manager_user->get('/statistics')->to('display#show_stats') + ->name('show_stats'); + + # websocket for fun + $manager_user->websocket('/log_websocket/:num')->to('display#show_log_ws') + ->name('show_log_websocket'); + $manager_user->websocket('/statistics/:num') + ->to('display#show_stats_websocket')->name('show_stats_websocket'); + + + $admin_user->get('/settings/fix_months')->to('publications#fixMonths') + ->name('fix_all_months'); + + $manager_user->get('/settings/clean_all') + ->to('publications#clean_ugly_bibtex')->name('clean_ugly_bibtex'); + + $manager_user->get('/settings/mark_all_to_regenerate') + ->to('publications#mark_all_to_regenerate') + ->name('mark_all_to_regenerate'); + + $manager_user->get('/settings/mark_author_to_regenerate/:author_id') + ->to('publications#mark_author_to_regenerate') + ->name('mark_author_to_regenerate'); + + $manager_user->get('/settings/regenerate_all') + ->to('publications#regenerate_html_for_all') + ->name('regenerate_html_for_all'); + + $logged_user->get('/settings/regenerate_html_in_chunk/:chunk_size') + ->to('publications#regenerate_html_in_chunk') + ->name('regenerate_html_in_chunk'); + + + $manager_user->get('/backups')->to('backup#index')->name('backup_index'); + $manager_user->put('/backups')->to('backup#save')->name('backup_do'); + $manager_user->put('/backups/mysql')->to('backup#save_mysql') + ->name('backup_do_mysql'); + $manager_user->get('/backups/:id')->to('backup#backup_download') + ->name('backup_download'); + + $admin_user->delete('/backups/:id')->to('backup#delete_backup') + ->name('backup_delete'); + $admin_user->put('/backups/:id')->to('backup#restore_backup') + ->name('backup_restore'); + $admin_user->delete('/backups')->to('backup#cleanup') + ->name('backup_cleanup'); + + + ################ TYPES ################ + $logged_user->get('/types')->to('types#all_our')->name('all_types'); + $manager_user->get('/types/add')->to('types#add_type') + ->name('add_type_get'); + $manager_user->post('/types/add')->to('types#post_add_type') + ->name('add_type_post'); + $manager_user->get('/types/manage/:name')->to('types#manage') + ->name('edit_type'); + $manager_user->get('/types/delete/:name')->to('types#delete_type') + ->name('delete_type'); + + $manager_user->post('/types/store_description') + ->to('types#post_store_description')->name('update_type_description'); + $manager_user->get('/types/toggle/:name')->to('types#toggle_landing') + ->name('toggle_landing_type'); + + $manager_user->get('/types/:our_type/map/:bibtex_type') + ->to('types#map_types'); + $manager_user->get('/types/:our_type/unmap/:bibtex_type') + ->to('types#unmap_types')->name('unmap_bibtex_type'); + + ################ AUTHORS ################ + + $logged_user->get('/authors/')->to('authors#all_authors') + ->name('all_authors'); + $manager_user->get('/authors/add')->to('authors#add_author') + ->name('add_author'); + $manager_user->post('/authors/add/')->to('authors#add_post'); + + $logged_user->get('/authors/edit/:id')->to('authors#edit_author') + ->name('edit_author'); + $manager_user->post('/authors/edit/')->to('authors#edit_post') + ->name('edit_author_post'); + $manager_user->get('/authors/delete/:id')->to('authors#delete_author') + ->name('delete_author'); + + + $admin_user->get('/authors/delete/:id/force') + ->to('authors#delete_author_force'); + + + # for dev only!! + $admin_user->get('/authors/decimate') + ->to('authors#delete_invisible_authors'); + + + $manager_user->post('/authors/edit_membership_dates') + ->to('authors#post_edit_membership_dates') + ->name('edit_author_membership_dates'); + + $manager_user->get('/authors/:id/add_to_team/:tid') + ->to('authors#add_to_team')->name('add_author_to_team'); + $manager_user->get('/authors/:id/remove_from_team/:tid') + ->to('authors#remove_from_team')->name('remove_author_from_team'); + $manager_user->get('/authors/:masterid/remove_uid/:uid') + ->to('authors#remove_uid')->name('remove_author_uid'); + + $manager_user->post('/authors/merge/')->to('authors#merge_authors') + ->name('merge_authors'); + + $admin_user->get('/authors/fix_masters')->to('authors#fix_masters') + ->name('fix_masters'); + + $manager_user->get('/authors/reassign') + ->to('authors#reassign_authors_to_entries'); + $admin_user->get('/authors/reassign_and_create') + ->to('authors#reassign_authors_to_entries_and_create_authors'); + + $manager_user->get('/authors/toggle_visibility/:id') + ->to('authors#toggle_visibility')->name('toggle_author_visibility'); + + # $logged_user->get('/authors/toggle_visibility') + # ->to('authors#toggle_visibility'); + + ################ TAG TYPES ################ + # $logged_user->get('/tags/')->to('tags#index')->name("tags_index"); + $logged_user->get('/tagtypes')->to('tagtypes#index')->name('all_tag_types'); + $admin_user->get('/tagtypes/add')->to('tagtypes#add')->name('add_tag_type'); + $admin_user->post('/tagtypes/add')->to('tagtypes#add_post') + ->name('add_tag_type_post'); + $admin_user->get('/tagtypes/delete/:id')->to('tagtypes#delete') + ->name('delete_tag_type'); + $manager_user->any('/tagtypes/edit/:id')->to('tagtypes#edit') + ->name('edit_tag_type'); + + ################ TAGS ################ + $logged_user->get('/tags/:type')->to( 'tags#index', type => 1 ) + ->name('all_tags'); + $admin_user->get('/tags/add/:type')->to( 'tags#add', type => 1 ) + ->name('add_tag_get'); + $admin_user->post('/tags/add/:type')->to( 'tags#add_post', type => 1 ) + ->name('add_tag_post'); + $logged_user->get('/tags/authors/:id/:type') + ->to( 'tags#get_authors_for_tag', type => 1 ) + ->name('get_authors_for_tag'); + $admin_user->get('/tags/delete/:id')->to('tags#delete')->name('delete_tag'); + + ### EDIT TAG FORM GOES WITH GET - WTF!?! + # FIXME: FIX THIS + $manager_user->get('/tags/edit/:id')->to('tags#edit')->name('edit_tag'); + + $anyone->get('/read/authors-for-tag/:tag_id/:team_id') + ->to('tags#get_authors_for_tag_and_team') + ->name('get_authors_for_tag_and_team'); + + #ALIAS + $anyone->get('/r/a4t/:tag_id/:team_id') + ->to('tags#get_authors_for_tag_and_team') + ->name('get_authors_for_tag_and_team'); + + $anyone->get('/read/authors-for-tag/:tag_id/:team_id') + ->to('tags#get_authors_for_tag_and_team') + ->name('get_authors_for_tag_and_team'); + + #ALIAS + $anyone->get('/r/a4t/:tag_id/:team_id') + ->to('tags#get_authors_for_tag_and_team') + ->name('get_authors_for_tag_and_team'); + + $anyone->get('/read/tags-for-author/:author_id') + ->to('tags#get_tags_for_author_read')->name('tags_for_author'); + + #ALIAS + $anyone->get('/r/t4a/:author_id')->to('tags#get_tags_for_author_read'); + + $anyone->get('/read/tags-for-team/:team_id') + ->to('tags#get_tags_for_team_read')->name('tags_for_team'); + + #ALIAS + $anyone->get('/r/t4t/:team_id')->to('tags#get_tags_for_team_read'); + + ################ TEAMS ################ + $logged_user->get('/teams')->to('teams#show')->name('all_teams'); + $logged_user->get('/teams/members/:teamid')->to('teams#team_members'); + + $manager_user->get('/teams/edit/:id')->to('teams#edit')->name('edit_team'); + $manager_user->get('/teams/delete/:id')->to('teams#delete_team') + ->name('delete_team'); + $manager_user->get('/teams/delete/:id/force') + ->to('teams#delete_team_force')->name('delete_team_force'); + $logged_user->get('/teams/unrealted_papers/:teamid') + ->to('publications#show_unrelated_to_team') + ->name('unrelated_papers_for_team'); + + $manager_user->get('/teams/add')->to('teams#add_team') + ->name('add_team_get'); + $manager_user->post('/teams/add/')->to('teams#add_team_post'); + + ################ EDITING PUBLICATIONS ################ #<<< no perltidy here # EXPERIMENTAL @@ -1013,39 +1001,38 @@ sub setup_routes { ################################################################ sub setup_hooks { - my $self = shift; - $self->app->logger->info("Setup hooks..."); - - # $self->hook(after_render => sub { - # my ($c, $args) = @_; - # $c->push_url_history; - # # say "History of visisited URLS ".$c->get_url_history.":\n".join("\n", $c->get_url_history); - # }); - - $self->hook( - before_dispatch => sub { - my $c = shift; - - if( $c->req->headers->header('X-Forwarded-HTTPS') ){ - $c->req->url->base->scheme('https'); - } - $c->app->statistics->log_url($c->req->url); - - - # dirty fix for production deployment in a directory - # config->{proxy_prefix} stores the proxy prefix, e.g., /app - my $proxy_prefix = $self->config->{proxy_prefix}; - if ( $proxy_prefix ne "" ) { - - # we remove the leading slash - $proxy_prefix =~ s!^/!!; - - # and let Mojolicious add it again - push @{ $c->req->url->base->path->trailing_slash(1) }, - $proxy_prefix; - } - } - ); + my $self = shift; + $self->app->logger->info("Setup hooks..."); + +# $self->hook(after_render => sub { +# my ($c, $args) = @_; +# $c->push_url_history; +# # say "History of visisited URLS ".$c->get_url_history.":\n".join("\n", $c->get_url_history); +# }); + + $self->hook( + before_dispatch => sub { + my $c = shift; + + if ( $c->req->headers->header('X-Forwarded-HTTPS') ) { + $c->req->url->base->scheme('https'); + } + $c->app->statistics->log_url( $c->req->url ); + + + # dirty fix for production deployment in a directory + # config->{proxy_prefix} stores the proxy prefix, e.g., /app + my $proxy_prefix = $self->config->{proxy_prefix}; + if ( $proxy_prefix ne "" ) { + + # we remove the leading slash + $proxy_prefix =~ s!^/!!; + + # and let Mojolicious add it again + push @{ $c->req->url->base->path->trailing_slash(1) }, $proxy_prefix; + } + } + ); } 1; diff --git a/lib/BibSpace/Controller/Backup.pm b/lib/BibSpace/Controller/Backup.pm index 81abbeb..e8881d9 100644 --- a/lib/BibSpace/Controller/Backup.pm +++ b/lib/BibSpace/Controller/Backup.pm @@ -4,9 +4,10 @@ use Data::Dumper; use utf8; use Text::BibTeX; # parsing bib files use DateTime; + # use File::Slurp; -use v5.16; +use v5.16; use Try::Tiny; use strict; use warnings; @@ -18,6 +19,7 @@ use List::Util qw(first); use BibSpace::Functions::Core; use BibSpace::Functions::MySqlBackupFunctions; use BibSpace::Functions::BackupFunctions; + # use BibSpace::Functions::FDB; use BibSpace::Model::Backup; @@ -28,154 +30,189 @@ use Mojo::Base 'Mojolicious::Plugin::Config'; use Mojo::Log; - - #################################################################################### sub index { - my $self = shift; - my $dbh = $self->app->db; - - my $backup_dir = $self->app->get_backups_dir; - my $dir_size = get_dir_size($backup_dir); - $dir_size = $dir_size >> 20; - - my @backups_arr = sort {$b->date cmp $a->date} read_backups($backup_dir); - - foreach my $backup (@backups_arr){ - if( $backup->get_age->days >= $self->app->config->{allow_delete_backups_older_than}){ - $backup->allow_delete(1); - } - else{ - $backup->allow_delete(undef); - } + my $self = shift; + my $dbh = $self->app->db; + + my $backup_dir = $self->app->get_backups_dir; + my $dir_size = get_dir_size($backup_dir); + $dir_size = $dir_size >> 20; + + my @backups_arr = sort { $b->date cmp $a->date } read_backups($backup_dir); + + foreach my $backup (@backups_arr) { + if ( $backup->get_age->days + >= $self->app->config->{allow_delete_backups_older_than} ) + { + $backup->allow_delete(1); } + else { + $backup->allow_delete(undef); + } + } - $self->stash( - backups_arr => \@backups_arr, - dir_size => $dir_size - ); - $self->render( template => 'backup/backup' ); + $self->stash( backups_arr => \@backups_arr, dir_size => $dir_size ); + $self->render( template => 'backup/backup' ); } #################################################################################### sub save { - my $self = shift; + my $self = shift; - my $backup = do_storable_backup($self->app); + my $backup = do_storable_backup( $self->app ); - if ( $backup->is_healthy ) { - $self->flash( msg_type=>'success', msg => "Backup created successfully" ); - } - else { - $self->flash(msg_type=>'danger', msg => "Backup create failed!" ); - } - $self->redirect_to( 'backup_index' ); + if ( $backup->is_healthy ) { + $self->flash( + msg_type => 'success', + msg => "Backup created successfully" + ); + } + else { + $self->flash( msg_type => 'danger', msg => "Backup create failed!" ); + } + $self->redirect_to('backup_index'); } #################################################################################### sub save_mysql { - my $self = shift; + my $self = shift; - my $backup = do_mysql_backup($self->app); + my $backup = do_mysql_backup( $self->app ); - if ( $backup->is_healthy ) { - $self->flash( msg_type=>'success', msg => "Backup created successfully" ); - } - else { - $self->flash(msg_type=>'danger', msg => "Backup create failed!" ); - } - $self->redirect_to( 'backup_index' ); + if ( $backup->is_healthy ) { + $self->flash( + msg_type => 'success', + msg => "Backup created successfully" + ); + } + else { + $self->flash( msg_type => 'danger', msg => "Backup create failed!" ); + } + $self->redirect_to('backup_index'); } #################################################################################### sub cleanup { - my $self = shift; - my $age_treshold = $self->config->{backup_age_in_days_to_delete_automatically}; - - my $num_deleted = delete_old_backups($self->app, $age_treshold); - - $self->app->logger->info("Deleting old backups. $num_deleted backups have been cleaned."); - $self->flash( msg_type=>'success', msg => "$num_deleted backups have been cleaned." ); - - # redirecting to referrer here breaks the test if the test supports redirects! why? - # disabling redirects for test and putting here referrer allows test to pass - $self->redirect_to( 'backup_index' ); + my $self = shift; + my $age_treshold + = $self->config->{backup_age_in_days_to_delete_automatically}; + + my $num_deleted = delete_old_backups( $self->app, $age_treshold ); + + $self->app->logger->info( + "Deleting old backups. $num_deleted backups have been cleaned."); + $self->flash( + msg_type => 'success', + msg => "$num_deleted backups have been cleaned." + ); + +# redirecting to referrer here breaks the test if the test supports redirects! why? +# disabling redirects for test and putting here referrer allows test to pass + $self->redirect_to('backup_index'); } #################################################################################### sub backup_download { - my $self = shift; - my $uuid = $self->param('id'); + my $self = shift; + my $uuid = $self->param('id'); + + my $backup = find_backup( $uuid, $self->app->get_backups_dir ); + + if ( $backup and $backup->is_healthy ) { + $self->app->logger->info( "Downloading backup " . $backup->uuid ); + $self->render_file( 'filepath' => $backup->get_path ); + } + else { + $self->flash( + msg_type => 'danger', + msg => "Cannot download backup $uuid - backup not healthy." + ); + $self->redirect_to( $self->get_referrer ); + } +} - my $backup = find_backup($uuid, $self->app->get_backups_dir); +#################################################################################### +sub delete_backup { + my $self = shift; + my $uuid = $self->param('id'); + + my $backup = find_backup( $uuid, $self->app->get_backups_dir ); - if ( $backup and $backup->is_healthy ) { - $self->app->logger->info("Downloading backup ".$backup->uuid); - $self->render_file( 'filepath' => $backup->get_path ); + if ( $backup and $backup->is_healthy ) { + if ( $backup->get_age->days + >= $self->app->config->{allow_delete_backups_older_than} ) + { + $backup->allow_delete(1); } else { - $self->flash( msg_type=>'danger', msg => "Cannot download backup $uuid - backup not healthy." ); - $self->redirect_to( $self->get_referrer ); + $backup->allow_delete(undef); } -} - -#################################################################################### -sub delete_backup { - my $self = shift; - my $uuid = $self->param('id'); - - my $backup = find_backup($uuid, $self->app->get_backups_dir); - - if ( $backup and $backup->is_healthy ) { - if( $backup->get_age->days >= $self->app->config->{allow_delete_backups_older_than}){ - $backup->allow_delete(1); - } - else{ - $backup->allow_delete(undef); - } - if($backup->allow_delete){ - try{ - unlink $backup->get_path; - $self->app->logger->info("Deleting backup ".$backup->uuid); - $self->flash( msg_type=>'success', msg => "Backup id $uuid deleted!" ); - } - catch{ - $self->flash( msg_type=>'danger', msg => "Exception during deleting backup '$uuid': $_." ); - }; - } - else{ - $self->flash( msg_type=>'warning', msg => "Backup $uuid is too young to be deleted!" ); - } + if ( $backup->allow_delete ) { + try { + unlink $backup->get_path; + $self->app->logger->info( "Deleting backup " . $backup->uuid ); + $self->flash( + msg_type => 'success', + msg => "Backup id $uuid deleted!" + ); + } + catch { + $self->flash( + msg_type => 'danger', + msg => "Exception during deleting backup '$uuid': $_." + ); + }; } - else{ - $self->flash( msg_type=>'danger', msg => "Cannot delete backup $uuid - you need to do this manually." ); + else { + $self->flash( + msg_type => 'warning', + msg => "Backup $uuid is too young to be deleted!" + ); } + } + else { + $self->flash( + msg_type => 'danger', + msg => "Cannot delete backup $uuid - you need to do this manually." + ); + } - $self->res->code(303); - $self->redirect_to($self->url_for('backup_index')); + $self->res->code(303); + $self->redirect_to( $self->url_for('backup_index') ); } #################################################################################### sub restore_backup { - my $self = shift; - my $uuid = $self->param('id'); + my $self = shift; + my $uuid = $self->param('id'); - my $backup = find_backup($uuid, $self->app->get_backups_dir); + my $backup = find_backup( $uuid, $self->app->get_backups_dir ); - if($backup and $backup->is_healthy){ + if ( $backup and $backup->is_healthy ) { - restore_storable_backup($backup, $self->app); + restore_storable_backup( $backup, $self->app ); - $self->app->logger->info("Restoring backup ".$backup->uuid); + $self->app->logger->info( "Restoring backup " . $backup->uuid ); - my $status = "Status:
".$self->app->repo->lr->get_summary_table.""; + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; - $self->flash( msg_type=>'success', msg => "Backup restored successfully. Database recreated, persistence layers in sync. $status" ); - } - else { - $self->flash( msg_type=>'danger', msg => "Cannot restore - backup not healthy!" ); - } - $self->redirect_to('backup_index'); + $self->flash( + msg_type => 'success', + msg => + "Backup restored successfully. Database recreated, persistence layers in sync. $status" + ); + } + else { + $self->flash( + msg_type => 'danger', + msg => "Cannot restore - backup not healthy!" + ); + } + $self->redirect_to('backup_index'); } #################################################################################### diff --git a/lib/BibSpace/Controller/Cron.pm b/lib/BibSpace/Controller/Cron.pm index 8ec7f0e..2d08bc2 100644 --- a/lib/BibSpace/Controller/Cron.pm +++ b/lib/BibSpace/Controller/Cron.pm @@ -135,7 +135,6 @@ sub cron_run { } ############ Cron ACTIONS - $self->log_cron_usage($level); $self->app->logger->info("Cron level $level started"); if ( $level == 0 ) { @@ -156,6 +155,8 @@ sub cron_run { else { # do nothing } + # this may cause: [error] Unable to open file (bibspace_preferences.json) for storing : Permission denied at + $self->log_cron_usage($level); $self->app->logger->info("Cron level $level has finished"); return $text_to_render; diff --git a/lib/BibSpace/Controller/Display.pm b/lib/BibSpace/Controller/Display.pm index c19c0ce..ad7d7cd 100644 --- a/lib/BibSpace/Controller/Display.pm +++ b/lib/BibSpace/Controller/Display.pm @@ -105,9 +105,20 @@ sub show_log_ws { $self->on(finish => sub { my ($c, $code, $reason) = @_; - say "WS closed"; + say "show_log_ws WS closed"; }); } +################################################################################# +sub show_stats { + my $self = shift; + my $num = $self->param('num') // 20; + + my @lines = $self->app->statistics->toLines; + + $self->stash( lines => \@lines, num => $num); + $self->render( template => 'display/stats' ); +} + ################################################################################# sub show_stats_websocket { my $self = shift; @@ -124,7 +135,7 @@ sub show_stats_websocket { $self->on(finish => sub { my ($c, $code, $reason) = @_; - say "WS closed"; + say "show_stats_websocket WS closed"; }); } ################################################################################# diff --git a/lib/BibSpace/Controller/Helpers.pm b/lib/BibSpace/Controller/Helpers.pm index 262a067..df81f00 100644 --- a/lib/BibSpace/Controller/Helpers.pm +++ b/lib/BibSpace/Controller/Helpers.pm @@ -60,15 +60,20 @@ sub register { } ); - $app->helper( - db => sub { - my $self = shift; - return db_connect( - $self->app->config->{db_host}, $self->app->config->{db_user}, - $self->app->config->{db_database}, $self->app->config->{db_pass} - ); - } - ); + $app->helper( + db => sub { + my $self = shift; + my $db_host + = $ENV{BIBSPACE_DB_HOST} || $self->app->config->{db_host}; + my $db_user + = $ENV{BIBSPACE_DB_USER} || $self->app->config->{db_user}; + my $db_database + = $ENV{BIBSPACE_DB_DATABASE} || $self->app->config->{db_database}; + my $db_pass + = $ENV{BIBSPACE_DB_PASS} || $self->app->config->{db_pass}; + return db_connect( $db_host, $db_user, $db_database, $db_pass ); + } + ); $app->helper( bst => sub { diff --git a/lib/BibSpace/Controller/Persistence.pm b/lib/BibSpace/Controller/Persistence.pm index e6b1790..fdeae4e 100644 --- a/lib/BibSpace/Controller/Persistence.pm +++ b/lib/BibSpace/Controller/Persistence.pm @@ -21,9 +21,12 @@ use Mojo::Base 'Mojolicious::Controller'; ################################################################################# sub persistence_status { - my $self = shift; + my $self = shift; - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; $self->stash( msg_type => 'success', msg => $status ); $self->flash( msg_type => 'success', msg => $status ); $self->redirect_to( $self->get_referrer ); @@ -31,9 +34,12 @@ sub persistence_status { ################################################################################# sub persistence_status_ajax { - my $self = shift; + my $self = shift; - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; $self->render( text => $status ); } @@ -41,17 +47,27 @@ sub persistence_status_ajax { sub load_fixture { my $self = shift; - $self->app->logger->warn("PERSISTENCE CONTROLLER does: load_fixture"); + my $fixture_file + = $self->app->home->rel_file('fixture/bibspace_fixture.dat'); + $self->app->logger->info( + "Loading fixture from: " . $fixture_file->to_string ); - my $fixture_name = "bibspace_fixture.dat"; - my $fixture_dir = "./fixture/"; - my $fixture = Backup->new( dir => $fixture_dir, filename => $fixture_name ); + my $fixture = Backup->new( + dir => '' . $fixture_file->dirname, + filename => '' . $fixture_file->basename + ); restore_storable_backup( $fixture, $self->app ); - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; - $self->flash( msg_type => 'success', msg => "Fixture loaded into memory and mysql. $status" ); + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; + $self->flash( + msg_type => 'success', + msg => "Fixture loaded into memory and mysql. $status" + ); $self->redirect_to( $self->get_referrer ); } ################################################################################# @@ -60,36 +76,51 @@ sub save_fixture { $self->app->logger->warn("PERSISTENCE CONTROLLER does: save_fixture"); - my $fixture_name = "bibspace_fixture.dat"; - my $fixture_dir = "./fixture/"; - my $backup = Backup->create( 'dummy', "storable" ); - $backup->dir($fixture_dir); - $backup->filename($fixture_name); + my $fixture_file + = $self->app->home->rel_file('fixture/bibspace_fixture.dat'); + + my $backup = Backup->create( 'dummy', "storable" ); + $backup->dir( '' . $fixture_file->dirname ); + $backup->filename( '' . $fixture_file->basename ); my $layer = $self->app->repo->lr->get_read_layer; my $path = "" . $backup->get_path; - $Storable::forgive_me = "do store regexp please, we will not use them anyway"; + $Storable::forgive_me + = "do store regexp please, we will not use them anyway"; - # if you see any exceptions being thrown here, this might be due to REGEXP caused by DateTime pattern. - # this should not happen currently however - I think it is fixed now. +# if you see any exceptions being thrown here, this might be due to REGEXP caused by DateTime pattern. +# this should not happen currently however - I think it is fixed now. Storable::store $layer, $path; - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; - $self->flash( msg_type => 'success', msg => "Fixture stored to '" . $backup->get_path . "'. $status" ); + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; + $self->flash( + msg_type => 'success', + msg => "Fixture stored to '" . $backup->get_path . "'. $status" + ); $self->redirect_to( $self->get_referrer ); } ################################################################################# sub copy_mysql_to_smart { my $self = shift; - $self->app->logger->warn("PERSISTENCE CONTROLLER does: copy_mysql_to_smart"); + $self->app->logger->warn( + "PERSISTENCE CONTROLLER does: copy_mysql_to_smart"); $self->app->repo->lr->copy_data( { from => 'mysql', to => 'smart' } ); $self->app->link_data; - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; - $self->flash( msg_type => 'success', msg => "Copied mysql => smart. $status" ); + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; + $self->flash( + msg_type => 'success', + msg => "Copied mysql => smart. $status" + ); $self->redirect_to( $self->get_referrer ); } ################################################################################# @@ -99,8 +130,14 @@ sub copy_smart_to_mysql { $self->app->repo->lr->copy_data( { from => 'smart', to => 'mysql' } ); - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; - $self->flash( msg_type => 'success', msg => "Copied smart => mysql. $status" ); + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; + $self->flash( + msg_type => 'success', + msg => "Copied smart => mysql. $status" + ); $self->redirect_to( $self->get_referrer ); } @@ -111,49 +148,51 @@ sub insert_random_data { my $str_len = 60; - for (1..$num){ + for ( 1 .. $num ) { my $obj = $self->app->entityFactory->new_User( - login => random_string($str_len), - email => random_string($str_len).'@example.com', - real_name => random_string($str_len), - pass => random_string($str_len), - pass2 => random_string($str_len) + login => random_string($str_len), + email => random_string($str_len) . '@example.com', + real_name => random_string($str_len), + pass => random_string($str_len), + pass2 => random_string($str_len) ); $self->app->repo->users_save($obj); $obj = $self->app->entityFactory->new_Author( - uid => random_string($str_len), - ); + uid => random_string($str_len), ); $self->app->repo->authors_save($obj); $obj = $self->app->entityFactory->new_Entry( - bib => random_string($str_len), - ); + bib => random_string($str_len), ); $self->app->repo->entries_save($obj); $obj = $self->app->entityFactory->new_TagType( - name => random_string($str_len), - ); + name => random_string($str_len), ); $self->app->repo->tagTypes_save($obj); - my $tt = ($self->app->repo->tagTypes_all)[0]; + my $tt = ( $self->app->repo->tagTypes_all )[0]; $obj = $self->app->entityFactory->new_Tag( - name => random_string($str_len), - type => $tt->id + name => random_string($str_len), + type => $tt->id ); $self->app->repo->tags_save($obj); $obj = $self->app->entityFactory->new_Team( - name => random_string($str_len), - ); + name => random_string($str_len), ); $self->app->repo->teams_save($obj); } - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; - $self->flash( msg_type => 'success', msg => "Copied smart => mysql. $status" ); + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; + $self->flash( + msg_type => 'success', + msg => "Copied smart => mysql. $status" + ); $self->redirect_to( $self->get_referrer ); } ################################################################################# @@ -173,10 +212,14 @@ sub reset_smart { # instead, do not insert admin and set system in demo mode $self->app->preferences->run_in_demo_mode(1); - say "setting preferences->run_in_demo_mode to: '".$self->app->preferences->run_in_demo_mode."'"; + say "setting preferences->run_in_demo_mode to: '" + . $self->app->preferences->run_in_demo_mode . "'"; - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; $self->flash( msg_type => 'success', msg => $status ); $self->redirect_to( $self->get_referrer ); } @@ -189,12 +232,21 @@ sub reset_mysql { my $layer = $self->app->repo->lr->get_layer('mysql'); if ($layer) { $layer->reset_data; - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; $self->flash( msg_type => 'success', msg => $status ); } else { - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; - $self->flash( msg_type => 'danger', msg => "Reset failed - backend handle undefined. " . $status ); + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; + $self->flash( + msg_type => 'danger', + msg => "Reset failed - backend handle undefined. " . $status + ); } $self->redirect_to( $self->get_referrer ); @@ -206,10 +258,9 @@ sub reset_all { $self->app->logger->warn("PERSISTENCE CONTROLLER does: reset_all"); my @layers = $self->app->repo->lr->get_all_layers; - foreach (@layers){ $_->reset_data }; + foreach (@layers) { $_->reset_data } $self->app->repo->lr->reset_uid_providers; - - + # no pub_admin user would lock the whole system # if you insert it here, it may will cause clash of IDs @@ -218,7 +269,10 @@ sub reset_all { $self->app->preferences->run_in_demo_mode(1); - my $status = "Status:
" . $self->app->repo->lr->get_summary_table . ""; + my $status + = "Status:
" + . $self->app->repo->lr->get_summary_table + . ""; $self->flash( msg_type => 'success', msg => $status ); $self->redirect_to( $self->get_referrer ); } @@ -233,7 +287,8 @@ sub system_status { my $backup_dir_absolute = $self->config->{backups_dir}; - $backup_dir_absolute =~ s!/*$!/!; # makes sure that there is exactly one / at the end + $backup_dir_absolute + =~ s!/*$!/!; # makes sure that there is exactly one / at the end my $errored = 0; diff --git a/lib/BibSpace/Controller/Preferences.pm b/lib/BibSpace/Controller/Preferences.pm index d391505..35f738a 100644 --- a/lib/BibSpace/Controller/Preferences.pm +++ b/lib/BibSpace/Controller/Preferences.pm @@ -59,9 +59,6 @@ sub save { $self->app->preferences->output_time_format($output_time_format); - # # store to file - # my $json_str = $self->app->preferences->store('bibspace_preferences.json'); - $self->stash( preferences => $self->app->preferences, msg_type=>$msg_type, msg =>$msg ); # $self->render( template => 'display/preferences' ); $self->redirect_to( $self->get_referrer ); diff --git a/lib/BibSpace/Controller/Publications.pm b/lib/BibSpace/Controller/Publications.pm index 307fab3..1b60534 100644 --- a/lib/BibSpace/Controller/Publications.pm +++ b/lib/BibSpace/Controller/Publications.pm @@ -6,7 +6,6 @@ use Text::BibTeX; # parsing bib files use DateTime; use Mojo::IOLoop; -# use File::Slurp; # should be replaced in the future use Path::Tiny; # for creating directories use Try::Tiny; @@ -29,18 +28,18 @@ use Mojo::UserAgent; use Mojo::Log; our %mons = ( - 1 => 'January', - 2 => 'February', - 3 => 'March', - 4 => 'April', - 5 => 'May', - 6 => 'June', - 7 => 'July', - 8 => 'August', - 9 => 'September', - 10 => 'October', - 11 => 'November', - 12 => 'December' + 1 => 'January', + 2 => 'February', + 3 => 'March', + 4 => 'April', + 5 => 'May', + 6 => 'June', + 7 => 'July', + 8 => 'August', + 9 => 'September', + 10 => 'October', + 11 => 'November', + 12 => 'December' ); #################################################################################### # work, but not for now @@ -55,163 +54,174 @@ our %mons = ( # } #################################################################################### sub all { - my $self = shift; + my $self = shift; - my @all = Fget_publications_main_hashed_args( $self, {year=>undef}); - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@all); + my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + my @filtered = Fget_publications_main_hashed_args( $self, {}, \@all ); - $self->stash( entries => \@filtered, all_entries => \@all); - my $html = $self->render_to_string( template => 'publications/all' ); - $self->render( data => $html ); + $self->stash( entries => \@filtered, all_entries => \@all ); + my $html = $self->render_to_string( template => 'publications/all' ); + $self->render( data => $html ); } #################################################################################### sub all_recently_added { - my $self = shift; - my $num = $self->param('num') // 10; + my $self = shift; + my $num = $self->param('num') // 10; - $self->app->logger->info("Displaying recently added entries."); + $self->app->logger->info("Displaying recently added entries."); - my @all = Fget_publications_main_hashed_args( $self, {year=>undef}); - my @added_entries = sort { $b->creation_time cmp $a->creation_time } @all; - @added_entries = @added_entries[ 0 .. $num - 1 ]; + my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + my @added_entries = sort { $b->creation_time cmp $a->creation_time } @all; + @added_entries = @added_entries[ 0 .. $num - 1 ]; - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@added_entries); - # special sorting here - @filtered = sort { $b->creation_time cmp $a->creation_time } @filtered; + my @filtered + = Fget_publications_main_hashed_args( $self, {}, \@added_entries ); - $self->stash( entries => \@filtered, all_entries => \@added_entries ); - $self->render( template => 'publications/all' ); + # special sorting here + @filtered = sort { $b->creation_time cmp $a->creation_time } @filtered; + + $self->stash( entries => \@filtered, all_entries => \@added_entries ); + $self->render( template => 'publications/all' ); } #################################################################################### sub all_recently_modified { - my $self = shift; - my $num = $self->param('num') // 10; + my $self = shift; + my $num = $self->param('num') // 10; + + $self->app->logger->info("Displaying recently modified entries."); + - $self->app->logger->info("Displaying recently modified entries."); + my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + my @modified_entries + = sort { $b->modified_time cmp $a->modified_time } @all; + @modified_entries = @modified_entries[ 0 .. $num - 1 ]; - - my @all = Fget_publications_main_hashed_args( $self, {year=>undef}); - my @modified_entries = sort { $b->modified_time cmp $a->modified_time } @all; - @modified_entries = @modified_entries[ 0 .. $num - 1 ]; + my @filtered + = Fget_publications_main_hashed_args( $self, {}, \@modified_entries ); - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@modified_entries); - # special sorting here - @filtered = sort { $b->modified_time cmp $a->modified_time } @filtered; + # special sorting here + @filtered = sort { $b->modified_time cmp $a->modified_time } @filtered; - $self->stash( entries => \@filtered, all_entries => \@modified_entries ); - $self->render( template => 'publications/all' ); + $self->stash( entries => \@filtered, all_entries => \@modified_entries ); + $self->render( template => 'publications/all' ); } #################################################################################### sub all_without_tag { - my $self = shift; - my $tagtype = $self->param('tagtype') // 1; + my $self = shift; + my $tagtype = $self->param('tagtype') // 1; - # this will filter entries based on query - my @all = Fget_publications_main_hashed_args( $self, {year=>undef} ); - - my @untagged_entries = grep { scalar $_->get_tags($tagtype) == 0 } @all; - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@untagged_entries); + # this will filter entries based on query + my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + my @untagged_entries = grep { scalar $_->get_tags($tagtype) == 0 } @all; + my @filtered + = Fget_publications_main_hashed_args( $self, {}, \@untagged_entries ); - my $msg - = "This list contains papers that have no tags of type '$tagtype'. Use this list to tag the untagged papers! "; - $self->stash( msg_type => 'info', msg => $msg ); - $self->stash( entries => \@filtered, all_entries => \@untagged_entries ); - $self->render( template => 'publications/all' ); + + my $msg + = "This list contains papers that have no tags of type '$tagtype'. Use this list to tag the untagged papers! "; + $self->stash( msg_type => 'info', msg => $msg ); + $self->stash( entries => \@filtered, all_entries => \@untagged_entries ); + $self->render( template => 'publications/all' ); } #################################################################################### sub all_orphaned { - my $self = shift; + my $self = shift; - my @all = Fget_publications_main_hashed_args( $self, {year=>undef} ); + my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); - my @entries = grep { scalar( $_->get_authors ) == 0 } @all; - - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@entries); + my @entries = grep { scalar( $_->get_authors ) == 0 } @all; - my $msg - = "This list contains papers, that are currently not assigned to any of authors."; - $msg .= ' Click to delete '; + my @filtered = Fget_publications_main_hashed_args( $self, {}, \@entries ); + + my $msg + = "This list contains papers, that are currently not assigned to any of authors."; + $msg + .= ' Click to delete '; - $self->stash( msg_type => 'info', msg => $msg ); - $self->stash(entries => \@filtered, all_entries => \@entries); - $self->render( template => 'publications/all' ); + $self->stash( msg_type => 'info', msg => $msg ); + $self->stash( entries => \@filtered, all_entries => \@entries ); + $self->render( template => 'publications/all' ); } #################################################################################### sub show_unrelated_to_team { - my $self = shift; - my $team_id = $self->param('teamid'); + my $self = shift; + my $team_id = $self->param('teamid'); - $self->app->logger->info( - "Displaying entries unrelated to team '$team_id'."); + $self->app->logger->info( + "Displaying entries unrelated to team '$team_id'."); - my $team_name = ""; - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); - $team_name = $team->name if defined $team; + my $team_name = ""; + my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); + $team_name = $team->name if defined $team; - my @all = Fget_publications_main_hashed_args( $self, {year=>undef} ); - my @teamEntres = $team->get_entries; + my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + my @teamEntres = $team->get_entries; - my %inTeam = map { $_ => 1 } @teamEntres; - my @entriesUnrelated = grep { not $inTeam{$_} } @all; + my %inTeam = map { $_ => 1 } @teamEntres; + my @entriesUnrelated = grep { not $inTeam{$_} } @all; - # hash destroys order! - @entriesUnrelated = sort_publications(@entriesUnrelated); - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@entriesUnrelated); + # hash destroys order! + @entriesUnrelated = sort_publications(@entriesUnrelated); + my @filtered + = Fget_publications_main_hashed_args( $self, {}, \@entriesUnrelated ); - my $msg = "This list contains papers, that are: + my $msg = "This list contains papers, that are:
This list contains papers, that are:
+ my $msg = "This list contains papers, that are:
Such entries may wanted to be removed form the system or serve as a help with configuration.
"; - $self->stash( msg_type => 'info', msg => $msg ); - $self->stash( entries => \@filtered, all_entries => \@entries ); - $self->render( template => 'publications/all' ); + $self->stash( msg_type => 'info', msg => $msg ); + $self->stash( entries => \@filtered, all_entries => \@entries ); + $self->render( template => 'publications/all' ); } #################################################################################### #################################################################################### #################################################################################### sub all_bibtex { - my $self = shift; + my $self = shift; - my @objs = Fget_publications_main_hashed_args( $self, { hidden => 0 } ); + my @objs = Fget_publications_main_hashed_args( $self, { hidden => 0 } ); - my $big_str = "\n"; - foreach my $obj (@objs) { - $big_str .= $obj->{bib}; - $big_str .= "\n"; - } - $big_str .= "\n"; - $self->render( text => $big_str ); + my $big_str = "
\n"; + foreach my $obj (@objs) { + $big_str .= $obj->{bib}; + $big_str .= "\n"; + } + $big_str .= "\n"; + $self->render( text => $big_str ); } #################################################################################### sub all_read { - my $self = shift; + my $self = shift; - # this function does filtering ! - my @objs = Fget_publications_main_hashed_args( $self, { hidden => 0 } ); + # this function does filtering ! + my @objs = Fget_publications_main_hashed_args( $self, { hidden => 0 } ); - $self->stash( entries => \@objs ); - my $html = $self->render_to_string( template => 'publications/all_read' ); - $self->render( data => $html ); + $self->stash( entries => \@objs ); + my $html = $self->render_to_string( template => 'publications/all_read' ); + $self->render( data => $html ); } #################################################################################### sub single { - my $self = shift; - my $id = $self->param('id'); - - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - - my @objs; - if ( defined $entry ) { - push @objs, $entry; - } - else { - $self->stash( - msg_type => 'danger', - msg => "Entry $id does not exist." - ); - } - $self->stash( entries => \@objs ); - $self->render( template => 'publications/all' ); + my $self = shift; + my $id = $self->param('id'); + + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + + my @objs; + if ( defined $entry ) { + push @objs, $entry; + } + else { + $self->stash( msg_type => 'danger', msg => "Entry $id does not exist." ); + } + $self->stash( entries => \@objs ); + $self->render( template => 'publications/all' ); } #################################################################################### sub single_read { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - my @objs = (); + my @objs = (); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - if ( defined $entry and $entry->is_hidden == 0 ) { - push @objs, $entry; - } - $self->stash( entries => \@objs ); - $self->render( template => 'publications/all_read' ); + if ( defined $entry and $entry->is_hidden == 0 ) { + push @objs, $entry; + } + $self->stash( entries => \@objs ); + $self->render( template => 'publications/all_read' ); } #################################################################################### sub fixMonths { - my $self = shift; + my $self = shift; - $self->app->logger->info("Fix months in all entries."); + $self->app->logger->info("Fix months in all entries."); - my @entries = $self->app->repo->entries_all; + my @entries = $self->app->repo->entries_all; - foreach my $entry (@entries) { - $entry->fix_month(); - } - $self->app->repo->entries_save(@entries); + foreach my $entry (@entries) { + $entry->fix_month(); + } + $self->app->repo->entries_save(@entries); - $self->flash( - msg => 'Fixing entries month field finished.', - msg_type => 'info' - ); - $self->redirect_to( $self->get_referrer ); + $self->flash( + msg => 'Fixing entries month field finished.', + msg_type => 'info' + ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub toggle_hide { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - $self->app->logger->info("Toggle hide entry '$id'."); + $self->app->logger->info("Toggle hide entry '$id'."); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - if ( defined $entry ) { - $entry->toggle_hide; - $self->app->repo->entries_update($entry); - } - else { - $self->flash( msg => "There is no entry with id $id" ); - } + if ( defined $entry ) { + $entry->toggle_hide; + $self->app->repo->entries_update($entry); + } + else { + $self->flash( msg => "There is no entry with id $id" ); + } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub make_paper { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - $self->app->logger->info("Make entry '$id' 'paper'."); + $self->app->logger->info("Make entry '$id' 'paper'."); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - if ( defined $entry ) { - $entry->make_paper(); - $self->app->repo->entries_update($entry); - } - else { - $self->flash( msg => "There is no entry with id $id" ); - } + if ( defined $entry ) { + $entry->make_paper(); + $self->app->repo->entries_update($entry); + } + else { + $self->flash( msg => "There is no entry with id $id" ); + } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub make_talk { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - $self->app->logger->info("Make entry '$id' 'talk'."); + $self->app->logger->info("Make entry '$id' 'talk'."); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - if ( defined $entry ) { - $entry->make_talk(); - $self->app->repo->entries_update($entry); - } - else { - $self->flash( msg => "There is no entry with id $id" ); - } + if ( defined $entry ) { + $entry->make_talk(); + $self->app->repo->entries_update($entry); + } + else { + $self->flash( msg => "There is no entry with id $id" ); + } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub delete_orphaned { - my $self = shift; - - my @entries = $self->app->repo->entries_filter( - sub { scalar( $_->get_authors ) == 0 } ); - - foreach my $entry (@entries){ - my @au = $entry->authorships_all; - $self->app->repo->authorships_delete(@au); - my @ex = $entry->exceptions_all; - $self->app->repo->exceptions_delete(@ex); - my @la = $entry->labelings_all; - $self->app->repo->labelings_delete(@la); - } + my $self = shift; - my $num_deleted = $self->app->repo->entries_delete(@entries); + my @entries = $self->app->repo->entries_filter( + sub { scalar( $_->get_authors ) == 0 } ); + + foreach my $entry (@entries) { + my @au = $entry->authorships_all; + $self->app->repo->authorships_delete(@au); + my @ex = $entry->exceptions_all; + $self->app->repo->exceptions_delete(@ex); + my @la = $entry->labelings_all; + $self->app->repo->labelings_delete(@la); + } + + my $num_deleted = $self->app->repo->entries_delete(@entries); + + my $msg = "$num_deleted entries have been removed"; + $self->flash( msg => $msg, msg_type => 'info' ); + $self->redirect_to('all_orphaned'); - my $msg - = "$num_deleted entries have been removed"; - $self->flash( msg => $msg, msg_type => 'info' ); - $self->redirect_to( 'all_orphaned' ); - } #################################################################################### sub fix_file_urls { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); + + $self->app->logger->info("Fixing file urls for all entries."); - $self->app->logger->info("Fixing file urls for all entries."); + my @all_entries; - my @all_entries; + if ($id) { + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + push @all_entries, $entry if $entry; + } + else { + @all_entries = $self->app->repo->entries_all; + } + + my $big_str = ".\n"; + my $num_fixes = 0; + my $num_checks = 0; - if ($id) { - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - push @all_entries, $entry if $entry; + for my $entry (@all_entries) { + + ++$num_checks; + my $str; + $str .= "Entry " . $entry->id . ": "; + $entry->discover_attachments( $self->app->get_upload_dir ); + my @discovered_types = $entry->attachments_keys; + + + $str .= "has types: ("; + foreach (@discovered_types) { + $str .= " $_, "; } - else { - @all_entries = $self->app->repo->entries_all; + $str .= "). Fixed: "; + + # say $str; + my $fixed; + my $file = $entry->get_attachment('paper'); + my $file_url = $self->url_for( + 'download_publication_pdf', + filetype => "paper", + id => $entry->id + )->to_abs; + + if ( $file and $file->exists ) { + $entry->remove_bibtex_fields( ['pdf'] ); + $str .= "\n\t"; + $entry->add_bibtex_field( "pdf", "$file_url" ); + $fixed = 1; + $str .= "Added Bibtex filed PDF " . $file_url; } - my $big_str = ".\n"; - my $num_fixes = 0; - my $num_checks = 0; - - for my $entry (@all_entries) { - - ++$num_checks; - my $str; - $str .= "Entry " . $entry->id . ": "; - $entry->discover_attachments( $self->app->get_upload_dir ); - my @discovered_types = $entry->attachments_keys; - - - - $str .= "has types: ("; - foreach (@discovered_types) { - $str .= " $_, "; - } - $str .= "). Fixed: "; - - # say $str; - my $fixed; - my $file = $entry->get_attachment('paper'); - my $file_url = $self->url_for( - 'download_publication_pdf', - filetype => "paper", - id => $entry->id - )->to_abs; - - if ( $file and $file->exists ) { - $entry->remove_bibtex_fields( ['pdf'] ); - $str .= "\n\t"; - $entry->add_bibtex_field( "pdf", "$file_url" ); - $fixed = 1; - $str .= "Added Bibtex filed PDF " . $file_url; - } - - $file = $entry->get_attachment('slides'); - $file_url = $self->url_for( - 'download_publication', - filetype => "slides", - id => $entry->id - )->to_abs; - - if ( $file and $file->exists ) { - $entry->remove_bibtex_fields( ['slides'] ); - $str .= "\n\t"; - $entry->add_bibtex_field( "slides", "$file_url" ); - $fixed = 1; - $str .= "Added Bibtex filed SLIDES " . $file_url; - } - $str .= "\n"; - - if ($fixed) { - $big_str .= $str; - ++$num_fixes; - $entry->regenerate_html( 0, $self->app->bst, - $self->app->bibtexConverter ); - } + $file = $entry->get_attachment('slides'); + $file_url = $self->url_for( + 'download_publication', + filetype => "slides", + id => $entry->id + )->to_abs; + + if ( $file and $file->exists ) { + $entry->remove_bibtex_fields( ['slides'] ); + $str .= "\n\t"; + $entry->add_bibtex_field( "slides", "$file_url" ); + $fixed = 1; + $str .= "Added Bibtex filed SLIDES " . $file_url; } + $str .= "\n"; - $self->app->logger->info("Url fix results $big_str."); + if ($fixed) { + $big_str .= $str; + ++$num_fixes; + $entry->regenerate_html( 0, $self->app->bst, + $self->app->bibtexConverter ); + } + } - $self->flash( - msg_type => 'info', - msg => - "Checked $num_checks and regenerated $num_fixes entries. You may need to run regenerate HTML force now. Detailed fix results have been saved to log." - ); - $self->redirect_to( $self->get_referrer ); + $self->app->logger->info("Url fix results $big_str."); + + $self->flash( + msg_type => 'info', + msg => + "Checked $num_checks and regenerated $num_fixes entries. You may need to run regenerate HTML force now. Detailed fix results have been saved to log." + ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub remove_attachment { - my $self = shift; - my $id = $self->param('id'); # entry ID - my $filetype = $self->param('filetype') // 'paper'; # paper, slides - - $self->app->logger->info( - "Requested to remove attachment of type '$filetype'."); - - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - my ( $msg, $msg_type ); + my $self = shift; + my $id = $self->param('id'); # entry ID + my $filetype = $self->param('filetype') // 'paper'; # paper, slides - $entry->discover_attachments( $self->app->get_upload_dir ); + $self->app->logger->info( + "Requested to remove attachment of type '$filetype'."); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my ( $msg, $msg_type ); - if ( $entry->attachments_has($filetype) ) { - $self->app->logger->debug( - "Entry has attachment of type '$filetype'."); + $entry->discover_attachments( $self->app->get_upload_dir ); - if ( $filetype eq 'paper' ) { - $entry->remove_bibtex_fields( ['pdf'] ); - } - elsif ( $filetype eq 'slides' ) { - $entry->remove_bibtex_fields( ['slides'] ); - } - $entry->delete_attachment($filetype); - $entry->regenerate_html( 1, $self->app->bst, - $self->app->bibtexConverter ); - $self->app->repo->entries_save($entry); + if ( $entry->attachments_has($filetype) ) { + $self->app->logger->debug("Entry has attachment of type '$filetype'."); - $msg = "The attachment has been removed for entry '$id'."; - $msg_type = 'success'; - $self->app->logger->info($msg); + if ( $filetype eq 'paper' ) { + $entry->remove_bibtex_fields( ['pdf'] ); } - else { - $self->app->logger->debug( - "Entry has NO attachment of type '$filetype'."); - - $msg - = "File not found. Cannot remove attachment. Filetype '$filetype', entry '$id'."; - $msg_type = 'danger'; - $self->app->logger->error($msg); + elsif ( $filetype eq 'slides' ) { + $entry->remove_bibtex_fields( ['slides'] ); } + $entry->delete_attachment($filetype); - $self->flash( msg_type => $msg_type, msg => $msg ); - $self->redirect_to( $self->get_referrer ); + $entry->regenerate_html( 1, $self->app->bst, + $self->app->bibtexConverter ); + $self->app->repo->entries_save($entry); + + $msg = "The attachment has been removed for entry '$id'."; + $msg_type = 'success'; + $self->app->logger->info($msg); + } + else { + $self->app->logger->debug("Entry has NO attachment of type '$filetype'."); + + $msg + = "File not found. Cannot remove attachment. Filetype '$filetype', entry '$id'."; + $msg_type = 'danger'; + $self->app->logger->error($msg); + } + + $self->flash( msg_type => $msg_type, msg => $msg ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub discover_attachments { - my $self = shift; - my $id = $self->param('id'); - my $do = $self->param('do'); + my $self = shift; + my $id = $self->param('id'); + my $do = $self->param('do'); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - $self->app->logger->info("Discovery of attachments for entry ID '$id'." ); - - my $msg; - my $msg_type = 'info'; - if ( $entry and $do and $do == 1 ) { - $entry->discover_attachments( $self->app->get_upload_dir ); - $msg .= "Discovery was run for dir '" - . $self->app->get_upload_dir . "'."; - } - elsif( $entry ) { - $msg .= "Just displaying information. "; - $msg + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + $self->app->logger->info("Discovery of attachments for entry ID '$id'."); + + my $msg; + my $msg_type = 'info'; + if ( $entry and $do and $do == 1 ) { + $entry->discover_attachments( $self->app->get_upload_dir ); + $msg .= "Discovery was run for dir '" . $self->app->get_upload_dir . "'."; + } + elsif ($entry) { + $msg .= "Just displaying information. "; + $msg .= "Attachments debug:
" . $entry->get_attachments_debug_string . ""; - } - else{ - $msg = "Cannot discover, entry '$id' not found."; - $msg_type = 'danger'; - $self->app->logger->error( $msg ); - } - + } + else { + $msg = "Cannot discover, entry '$id' not found."; + $msg_type = 'danger'; + $self->app->logger->error($msg); + } - $self->flash( msg_type => $msg_type, msg => $msg ); - $self->redirect_to( $self->get_referrer ); + + $self->flash( msg_type => $msg_type, msg => $msg ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub download { - my $self = shift; - my $id = $self->param('id'); # entry ID - my $filetype = $self->param('filetype'); + my $self = shift; + my $id = $self->param('id'); # entry ID + my $filetype = $self->param('filetype'); - $self->app->logger->info( - "Requested to download attachment of type '$filetype' for entry ID '" - . $id - . "'." ); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - my $file; + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $file; - if ($entry) { - $entry->discover_attachments( $self->app->get_upload_dir ); - $file = $entry->get_attachment($filetype); - } - else { - $self->app->logger->error("Cannot download - entry '$id' not found."); - $self->render( status => 404, text => "File not found." ); - return; - } - - if ( $file and -e $file ) { - $self->app->logger->info( - "Downloading file download '$filetype' for entry '$id'."); - $self->render_file( 'filepath' => $file ); - return; - } - $self->app->logger->error( - "File not found. Requested download for entry '$id', filetype '$filetype'." - ); - $self->render( text => "File not found.", status => 404 ); + if ($entry) { + $entry->discover_attachments( $self->app->get_upload_dir ); + $file = $entry->get_attachment($filetype); + } + else { + $self->app->logger->error("Cannot download - entry '$id' not found."); + $self->render( status => 404, text => "File not found." ); + return; + } + + if ( $file and -e $file ) { + $self->render_file( 'filepath' => $file ); + return; + } + $self->app->logger->error( + "File not found. Requested download for entry '$id', filetype '$filetype'." + ); + $self->render( text => "File not found.", status => 404 ); } #################################################################################### sub add_pdf { - my $self = shift; - my $id = $self->param('id'); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $self = shift; + my $id = $self->param('id'); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - if ( !defined $entry ) { - $self->flash( msg_type => 'danger', msg => "Entry '$id' not found." ); - $self->redirect_to( $self->get_referrer ); - return; - } - $entry->populate_from_bib(); - $entry->generate_html( $self->app->bst, $self->app->bibtexConverter ); + if ( !defined $entry ) { + $self->flash( msg_type => 'danger', msg => "Entry '$id' not found." ); + $self->redirect_to( $self->get_referrer ); + return; + } + $entry->populate_from_bib(); + $entry->generate_html( $self->app->bst, $self->app->bibtexConverter ); - $self->stash( mentry => $entry ); - $self->render( template => 'publications/pdf_upload' ); + $self->stash( mentry => $entry ); + $self->render( template => 'publications/pdf_upload' ); } #################################################################################### sub add_pdf_post { - my $self = shift; - my $id = $self->param('id'); - my $filetype = $self->param('filetype'); - my $uploaded_file = $self->param('uploaded_file'); - - my $uploads_directory - = Path::Tiny->new( $self->app->get_upload_dir ); - - $self->app->logger->info("Saving attachment for entry '$id'"); - - # Check file size - if ( $self->req->is_limit_exceeded ) { - my $curr_limit_B = $ENV{MOJO_MAX_MESSAGE_SIZE}; - $curr_limit_B ||= 16777216; - my $curr_limit_MB = $curr_limit_B / 1024 / 1024; - $self->app->logger->info( - "Saving attachment for paper id '$id': limit exceeded. Current limit: $curr_limit_MB MB." - ); - $self->flash( - msg => "The File is too big and cannot be saved!", - msg_type => "danger" - ); - $self->redirect_to( $self->get_referrer ); - return; - } - - - if ( !$uploaded_file ) { - $self->flash( - msg => "File upload unsuccessful!", - msg_type => "danger" - ); - $self->app->logger->info( - "Saving attachment for paper id '$id' FAILED. Unknown reason"); - $self->redirect_to( $self->get_referrer ); - return; - } - - my $size = $uploaded_file->size; - my $sizeKB = int( $size / 1024 ); - if ( $size == 0 ) { - $self->flash( - msg => "No file was selected or file has 0 bytes! Not saving!", - msg_type => "danger" - ); - $self->app->logger->info( - "Saving attachment for paper id '$id' FAILED. File size is 0."); - $self->redirect_to( $self->get_referrer ); - return; - } + my $self = shift; + my $id = $self->param('id'); + my $filetype = $self->param('filetype'); + my $uploaded_file = $self->param('uploaded_file'); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - - if ( !defined $entry ) { - $self->flash( - msg_type => 'danger', - msg => "Entry '$id' does not exist." - ); - $self->redirect_to( $self->get_referrer ); - return; - } + my $uploads_directory = Path::Tiny->new( $self->app->get_upload_dir ); + $self->app->logger->info("Saving attachment for entry '$id'"); - my $name = $uploaded_file->filename; - my @dot_arr = split( /\./, $name ); - my $extension = $dot_arr[-1]; - + # Check file size + if ( $self->req->is_limit_exceeded ) { + my $curr_limit_B = $ENV{MOJO_MAX_MESSAGE_SIZE}; + $curr_limit_B ||= 16777216; + my $curr_limit_MB = $curr_limit_B / 1024 / 1024; + $self->app->logger->info( + "Saving attachment for paper id '$id': limit exceeded. Current limit: $curr_limit_MB MB." + ); + $self->flash( + msg => "The File is too big and cannot be saved!", + msg_type => "danger" + ); + $self->redirect_to( $self->get_referrer ); + return; + } - my $file_url; - my $destination; - if ( $filetype eq 'paper' ) { - $entry->delete_attachment('paper'); - $destination - = $uploads_directory->path( "papers", "paper-$id.$extension" ); - $uploaded_file->move_to($destination); - $self->app->logger->debug( - "Attachments file has been moved to: $destination."); - - $entry->add_attachment( 'paper', $destination ); - $file_url = $self->url_for( - 'download_publication_pdf', - filetype => "paper", - id => $entry->id - )->to_abs; - $entry->add_bibtex_field( 'pdf', "$file_url" ); - } - elsif ( $filetype eq 'slides' ) { - $entry->delete_attachment('slides'); - $destination = $uploads_directory->path( "slides", - "slides-paper-$id.$extension" ); - $uploaded_file->move_to($destination); - $self->app->logger->debug( - "Attachments file has been moved to: $destination."); - - $entry->add_attachment( 'slides', $destination ); - $file_url = $self->url_for( - 'download_publication', - filetype => "slides", - id => $entry->id - )->to_abs; - $entry->add_bibtex_field( 'slides', "$file_url" ); - } - else { - # ignore - we support only pdf and slides so far - } + if ( !$uploaded_file ) { + $self->flash( msg => "File upload unsuccessful!", msg_type => "danger" ); + $self->app->logger->info( + "Saving attachment for paper id '$id' FAILED. Unknown reason"); + $self->redirect_to( $self->get_referrer ); + return; + } + my $size = $uploaded_file->size; + my $sizeKB = int( $size / 1024 ); + if ( $size == 0 ) { + $self->flash( + msg => "No file was selected or file has 0 bytes! Not saving!", + msg_type => "danger" + ); $self->app->logger->info( - "Saving attachment for entry '$id' under: '$destination'."); + "Saving attachment for paper id '$id' FAILED. File size is 0."); + $self->redirect_to( $self->get_referrer ); + return; + } - my $msg - = "Successfully uploaded the $sizeKB KB file as $filetype. + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + + if ( !defined $entry ) { + $self->flash( + msg_type => 'danger', + msg => "Entry '$id' does not exist." + ); + $self->redirect_to( $self->get_referrer ); + return; + } + + + my $name = $uploaded_file->filename; + my @dot_arr = split( /\./, $name ); + my $extension = $dot_arr[-1]; + + + my $file_url; + my $destination; + + if ( $filetype eq 'paper' ) { + $entry->delete_attachment('paper'); + $destination + = $uploads_directory->path( "papers", "paper-$id.$extension" ); + $uploaded_file->move_to($destination); + $self->app->logger->debug( + "Attachments file has been moved to: $destination."); + + $entry->add_attachment( 'paper', $destination ); + $file_url = $self->url_for( + 'download_publication_pdf', + filetype => "paper", + id => $entry->id + )->to_abs; + $entry->add_bibtex_field( 'pdf', "$file_url" ); + } + elsif ( $filetype eq 'slides' ) { + $entry->delete_attachment('slides'); + $destination + = $uploads_directory->path( "slides", "slides-paper-$id.$extension" ); + $uploaded_file->move_to($destination); + $self->app->logger->debug( + "Attachments file has been moved to: $destination."); + + $entry->add_attachment( 'slides', $destination ); + $file_url = $self->url_for( + 'download_publication', + filetype => "slides", + id => $entry->id + )->to_abs; + $entry->add_bibtex_field( 'slides', "$file_url" ); + } + else { + # ignore - we support only pdf and slides so far + } + + $self->app->logger->info( + "Saving attachment for entry '$id' under: '$destination'."); + + my $msg + = "Successfully uploaded the $sizeKB KB file as $filetype. The file was renamed to: " - . $destination->basename . ""; + . $file_url . "\">" . $destination->basename . ""; - $entry->regenerate_html( 1, $self->app->bst, - $self->app->bibtexConverter ); - $self->app->repo->entries_save($entry); + $entry->regenerate_html( 1, $self->app->bst, $self->app->bibtexConverter ); + $self->app->repo->entries_save($entry); - $self->flash( msg_type => 'success', msg => $msg ); - $self->redirect_to( $self->get_referrer ); + $self->flash( msg_type => 'success', msg => $msg ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub mark_author_to_regenerate { - my $self = shift; - my $author_id = $self->param('author_id'); - my $converter = $self->app->bibtexConverter; + my $self = shift; + my $author_id = $self->param('author_id'); + my $converter = $self->app->bibtexConverter; - my $author = $self->app->repo->authors_find( sub{$_->id == $author_id} ); + my $author = $self->app->repo->authors_find( sub { $_->id == $author_id } ); - my @entries; + my @entries; - if($author){ - $self->app->logger->info("Marking entries of author '".$author->uid."' for HTML regeneration."); + if ($author) { + $self->app->logger->info( "Marking entries of author '" + . $author->uid + . "' for HTML regeneration." ); - @entries = $author->get_entries; - foreach my $entry (@entries){ - $entry->need_html_regen(1); - } - $self->app->repo->entries_save(@entries); + @entries = $author->get_entries; + foreach my $entry (@entries) { + $entry->need_html_regen(1); } - - my $msg = "".scalar(@entries). " entries have been MARKED for regeneration. "; - $msg .= "Now you may run 'regenerate all' or 'regenerate in chunks'. "; - $msg .= "Regenration in chunks is useful for large set of entries. "; - - $self->app->logger->info($msg); - $self->flash( msg_type => 'info', msg => $msg ); - $self->redirect_to( $self->get_referrer ); + $self->app->repo->entries_save(@entries); + } + + my $msg + = "" + . scalar(@entries) + . " entries have been MARKED for regeneration. "; + $msg .= "Now you may run 'regenerate all' or 'regenerate in chunks'. "; + $msg .= "Regenration in chunks is useful for large set of entries. "; + + $self->app->logger->info($msg); + $self->flash( msg_type => 'info', msg => $msg ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub regenerate_html_for_all { - my $self = shift; - my $converter = $self->app->bibtexConverter; + my $self = shift; + my $converter = $self->app->bibtexConverter; - $self->inactivity_timeout(3000); + $self->inactivity_timeout(3000); - $self->app->logger->info("regenerate_html_for_all is running"); + $self->app->logger->info("regenerate_html_for_all is running"); - my @entries = $self->app->repo->entries_filter( sub{$_->need_html_regen == 1} ); - my $num_regen = Fregenerate_html_for_array($self->app, 0, $converter, \@entries); - my $left_todo = scalar(@entries) - $num_regen; + my @entries + = $self->app->repo->entries_filter( sub { $_->need_html_regen == 1 } ); + my $num_regen + = Fregenerate_html_for_array( $self->app, 0, $converter, \@entries ); + my $left_todo = scalar(@entries) - $num_regen; - my $msg = "$num_regen entries have been regenerated. "; - $msg .= "$left_todo furter entries still require regeneration."; - $self->app->logger->info($msg); - $self->flash( msg_type => 'info', msg => $msg ); - $self->redirect_to( $self->get_referrer ); + my $msg = "$num_regen entries have been regenerated. "; + $msg .= "$left_todo furter entries still require regeneration."; + $self->app->logger->info($msg); + $self->flash( msg_type => 'info', msg => $msg ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub regenerate_html_in_chunk { - my $self = shift; - my $chunk_size = $self->param('chunk_size') // 30; + my $self = shift; + my $chunk_size = $self->param('chunk_size') // 30; - my $converter = $self->app->bibtexConverter; + my $converter = $self->app->bibtexConverter; - $self->inactivity_timeout(3000); + $self->inactivity_timeout(3000); - $self->app->logger->info("regenerate_html_in_chunk is running, chunk size $chunk_size "); + $self->app->logger->info( + "regenerate_html_in_chunk is running, chunk size $chunk_size "); - my @entries = $self->app->repo->entries_filter( sub{ $_->need_html_regen == 1} ); + my @entries + = $self->app->repo->entries_filter( sub { $_->need_html_regen == 1 } ); - my $last_entry_index = $chunk_size-1; - $last_entry_index = scalar(@entries)-1 if scalar(@entries) < $chunk_size; + my $last_entry_index = $chunk_size - 1; + $last_entry_index = scalar(@entries) - 1 if scalar(@entries) < $chunk_size; - my @portion_of_entries = @entries[ 0 .. $last_entry_index ]; - @portion_of_entries = grep {defined $_} @portion_of_entries; + my @portion_of_entries = @entries[ 0 .. $last_entry_index ]; + @portion_of_entries = grep { defined $_ } @portion_of_entries; - my $num_regen = Fregenerate_html_for_array($self->app, 1, $converter, \@portion_of_entries); - my $left_todo = scalar(@entries) - $num_regen; + my $num_regen = Fregenerate_html_for_array( $self->app, 1, $converter, + \@portion_of_entries ); + my $left_todo = scalar(@entries) - $num_regen; - my $msg = "$num_regen entries have been regenerated. "; - $msg .= "$left_todo furter entries still require regeneration."; - $self->app->logger->info($msg); - $self->flash( msg_type => 'info', msg => $msg ); - $self->redirect_to( $self->get_referrer() ); + my $msg = "$num_regen entries have been regenerated. "; + $msg .= "$left_todo furter entries still require regeneration."; + $self->app->logger->info($msg); + $self->flash( msg_type => 'info', msg => $msg ); + $self->redirect_to( $self->get_referrer() ); } #################################################################################### sub mark_all_to_regenerate { - my $self = shift; - my $converter = $self->app->bibtexConverter; + my $self = shift; + my $converter = $self->app->bibtexConverter; - $self->app->logger->info("Marking all entries for HTML regeneration."); + $self->app->logger->info("Marking all entries for HTML regeneration."); - my @entries = $self->app->repo->entries_all; - foreach my $entry (@entries){ - $entry->need_html_regen(1); - # $self->app->repo->entries_save($entry); - } - $self->app->repo->entries_save(@entries); + my @entries = $self->app->repo->entries_all; + foreach my $entry (@entries) { + $entry->need_html_regen(1); - my $msg = "".scalar(@entries). " entries have been MARKED for regeneration. "; - $msg .= "Now you may run 'regenerate all' or 'regenerate in chunks'. "; - $msg .= "Regenration in chunks is useful for large set of entries. "; - $self->app->logger->info($msg); - $self->flash( msg_type => 'info', msg => $msg ); - $self->redirect_to( $self->get_referrer() ); + # $self->app->repo->entries_save($entry); + } + $self->app->repo->entries_save(@entries); + + my $msg + = "" + . scalar(@entries) + . " entries have been MARKED for regeneration. "; + $msg .= "Now you may run 'regenerate all' or 'regenerate in chunks'. "; + $msg .= "Regenration in chunks is useful for large set of entries. "; + $self->app->logger->info($msg); + $self->flash( msg_type => 'info', msg => $msg ); + $self->redirect_to( $self->get_referrer() ); } #################################################################################### sub regenerate_html { - my $self = shift; - my $converter = $self->app->bibtexConverter; - my $id = $self->param('id'); - - - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $self = shift; + my $converter = $self->app->bibtexConverter; + my $id = $self->param('id'); - if ( !defined $entry ) { - $self->flash( - msg => "There is no entry with id $id", - msg_type => 'danger' - ); - $self->redirect_to( $self->get_referrer ); - return; - } - my @entries = ($entry); - my $num_regen = Fregenerate_html_for_array($self->app, 1, $converter, \@entries); - my $msg; - if($num_regen == 1){ - $msg = "$num_regen entry has been regenerated."; - } - else{ - $msg = "$num_regen entries have been regenerated."; - } - $self->app->logger->info($msg); - $self->flash( msg_type => 'info', msg => $msg ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + if ( !defined $entry ) { + $self->flash( + msg => "There is no entry with id $id", + msg_type => 'danger' + ); $self->redirect_to( $self->get_referrer ); + return; + } + my @entries = ($entry); + my $num_regen + = Fregenerate_html_for_array( $self->app, 1, $converter, \@entries ); + + my $msg; + if ( $num_regen == 1 ) { + $msg = "$num_regen entry has been regenerated."; + } + else { + $msg = "$num_regen entries have been regenerated."; + } + $self->app->logger->info($msg); + $self->flash( msg_type => 'info', msg => $msg ); + + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub delete_sure { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); - if ( !defined $entry ) { - $self->app->logger->warn( - "Entry '$id' does not exist and thus can't be deleted."); - $self->flash( - mgs_type => 'danger', - msg => "There is no entry with id $id" - ); - $self->redirect_to( $self->get_referrer ); - return; - } - - $entry->delete_all_attachments; - my @entry_authorships = $entry->authorships_all; - my @entry_labelings = $entry->labelings_all; - my @entry_exceptions = $entry->exceptions_all; - $self->app->repo->authorships_delete(@entry_authorships); - $self->app->repo->labelings_delete(@entry_labelings); - $self->app->repo->exceptions_delete(@entry_exceptions); - $self->app->repo->entries_delete($entry); - - $self->app->logger->info("Entry '$id' has been deleted."); + if ( !defined $entry ) { + $self->app->logger->warn( + "Entry '$id' does not exist and thus can't be deleted."); + $self->flash( + mgs_type => 'danger', + msg => "There is no entry with id $id" + ); $self->redirect_to( $self->get_referrer ); + return; + } + + $entry->delete_all_attachments; + my @entry_authorships = $entry->authorships_all; + my @entry_labelings = $entry->labelings_all; + my @entry_exceptions = $entry->exceptions_all; + $self->app->repo->authorships_delete(@entry_authorships); + $self->app->repo->labelings_delete(@entry_labelings); + $self->app->repo->exceptions_delete(@entry_exceptions); + $self->app->repo->entries_delete($entry); + + $self->app->logger->info("Entry '$id' has been deleted."); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub show_authors_of_entry { - my $self = shift; - my $id = $self->param('id'); - $self->app->logger->info("Showing authors of entry id $id"); + my $self = shift; + my $id = $self->param('id'); + $self->app->logger->info("Showing authors of entry id $id"); - my $entry = $self->app->repo->entries_find( sub { $_->{id} == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->{id} == $id } ); - if ( !defined $entry ) { - $self->flash( msg => "There is no entry with id $id" ); - $self->redirect_to( $self->get_referrer ); - return; - } + if ( !defined $entry ) { + $self->flash( msg => "There is no entry with id $id" ); + $self->redirect_to( $self->get_referrer ); + return; + } - my @authors = map { $_->author } $entry->authorships_all; - my @teams = $entry->get_teams; + my @authors = map { $_->author } $entry->authorships_all; + my @teams = $entry->get_teams; - $self->stash( entry => $entry, authors => \@authors, teams => \@teams ); - $self->render( template => 'publications/show_authors' ); + $self->stash( entry => $entry, authors => \@authors, teams => \@teams ); + $self->render( template => 'publications/show_authors' ); } #################################################################################### #################################################################################### #################################################################################### sub manage_tags { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - $self->app->logger->info("Manage tags of entry id $id"); + $self->app->logger->info("Manage tags of entry id $id"); - my $entry = $self->app->repo->entries_find( sub { $_->{id} == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->{id} == $id } ); - if ( !defined $entry ) { - $self->flash( msg => "There is no entry with id $id" ); - $self->redirect_to( $self->get_referrer ); - return; - } + if ( !defined $entry ) { + $self->flash( msg => "There is no entry with id $id" ); + $self->redirect_to( $self->get_referrer ); + return; + } - my @tags = $entry->get_tags; - my @tag_types = $self->app->repo->tagTypes_all; + my @tags = $entry->get_tags; + my @tag_types = $self->app->repo->tagTypes_all; - $self->stash( entry => $entry, tags => \@tags, tag_types => \@tag_types ); - $self->render( template => 'publications/manage_tags' ); + $self->stash( entry => $entry, tags => \@tags, tag_types => \@tag_types ); + $self->render( template => 'publications/manage_tags' ); } #################################################################################### sub remove_tag { - my $self = shift; - my $entry_id = $self->param('eid'); - my $tag_id = $self->param('tid'); + my $self = shift; + my $entry_id = $self->param('eid'); + my $tag_id = $self->param('tid'); - my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); - my $tag = $self->app->repo->tags_find( sub { $_->id == $tag_id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); + my $tag = $self->app->repo->tags_find( sub { $_->id == $tag_id } ); - if ( defined $entry and defined $tag ) { + if ( defined $entry and defined $tag ) { - my $search_label = Labeling->new( - entry => $entry, - tag => $tag, - entry_id => $entry->id, - tag_id => $tag->id + my $search_label = Labeling->new( + entry => $entry, + tag => $tag, + entry_id => $entry->id, + tag_id => $tag->id + ); + + my $label + = $self->app->repo->labelings_find( sub { $_->equals($search_label) } ); - my $label = $self->app->repo->labelings_find( - sub { $_->equals($search_label) } ); + if ($label) { - if ($label) { + ## you should always execute all those three commands together - smells like command pattern... + $entry->remove_labeling($label); + $tag->remove_labeling($label); + $self->app->repo->labelings_delete($label); - ## you should always execute all those three commands together - smells like command pattern... - $entry->remove_labeling($label); - $tag->remove_labeling($label); - $self->app->repo->labelings_delete($label); + $self->app->logger->info( + "Removed tag " . $tag->name . " from entry ID " . $entry->id . ". " ); + } + else { + # this paper does not have this tag - do nothing + $self->app->logger->warn( "Cannot remove tag " + . $tag->name + . " from entry ID " + . $entry->id + . " - reason: labeling not found. " ); + } - $self->app->logger->info( "Removed tag " - . $tag->name - . " from entry ID " - . $entry->id - . ". " ); - } - else { - # this paper does not have this tag - do nothing - $self->app->logger->warn( "Cannot remove tag " - . $tag->name - . " from entry ID " - . $entry->id - . " - reason: labeling not found. " ); - } + } - } - - $self->redirect_to( $self->get_referrer ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub add_tag { - my $self = shift; - my $entry_id = $self->param('eid'); - my $tag_id = $self->param('tid'); - - my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); - my $tag = $self->app->repo->tags_find( sub { $_->id == $tag_id } ); - - if ( defined $entry and defined $tag ) { - my $label = Labeling->new( - entry => $entry, - tag => $tag, - entry_id => $entry->id, - tag_id => $tag->id - ); - ## you should always execute all those three commands together - smells like command pattern... - - $self->app->repo->labelings_save($label); - $entry->add_labeling($label); - $tag->add_labeling($label); - } - else { - # this paper does not have this tag - do nothing - $self->app->logger->warn( - "Cannot add tag $tag_id to entry ID $entry_id - reason: tag or entry not found. " - ); - } + my $self = shift; + my $entry_id = $self->param('eid'); + my $tag_id = $self->param('tid'); + + my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); + my $tag = $self->app->repo->tags_find( sub { $_->id == $tag_id } ); + + if ( defined $entry and defined $tag ) { + my $label = Labeling->new( + entry => $entry, + tag => $tag, + entry_id => $entry->id, + tag_id => $tag->id + ); + ## you should always execute all those three commands together - smells like command pattern... + + $self->app->repo->labelings_save($label); + $entry->add_labeling($label); + $tag->add_labeling($label); + } + else { + # this paper does not have this tag - do nothing + $self->app->logger->warn( + "Cannot add tag $tag_id to entry ID $entry_id - reason: tag or entry not found. " + ); + } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### #################################################################################### #################################################################################### sub manage_exceptions { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - my $entry = $self->app->repo->entries_find( sub { $_->{id} == $id } ); + my $entry = $self->app->repo->entries_find( sub { $_->{id} == $id } ); - if ( !defined $entry ) { - $self->flash( msg => "There is no entry with id $id" ); - $self->redirect_to( $self->get_referrer ); - return; - } + if ( !defined $entry ) { + $self->flash( msg => "There is no entry with id $id" ); + $self->redirect_to( $self->get_referrer ); + return; + } - my @exceptions = $entry->exceptions_all; - my @all_teams = $self->app->repo->teams_all; - my @teams = $entry->get_teams; - my @authors = $entry->get_authors; + my @exceptions = $entry->exceptions_all; + my @all_teams = $self->app->repo->teams_all; + my @teams = $entry->get_teams; + my @authors = $entry->get_authors; - # cannot use objects as keysdue to stringification! - my %exceptions_hash = map { $_->team->id => 1 } @exceptions; - my @unassigned_teams = grep { not $exceptions_hash{ $_->id } } @all_teams; + # cannot use objects as keysdue to stringification! + my %exceptions_hash = map { $_->team->id => 1 } @exceptions; + my @unassigned_teams = grep { not $exceptions_hash{ $_->id } } @all_teams; - $self->stash( - entry => $entry, - exceptions => \@exceptions, - teams => \@teams, - all_teams => \@all_teams, - authors => \@authors, - unassigned_teams => \@unassigned_teams - ); - $self->render( template => 'publications/manage_exceptions' ); + $self->stash( + entry => $entry, + exceptions => \@exceptions, + teams => \@teams, + all_teams => \@all_teams, + authors => \@authors, + unassigned_teams => \@unassigned_teams + ); + $self->render( template => 'publications/manage_exceptions' ); } #################################################################################### sub add_exception { - my $self = shift; - my $entry_id = $self->param('eid'); - my $team_id = $self->param('tid'); + my $self = shift; + my $entry_id = $self->param('eid'); + my $team_id = $self->param('tid'); - my $msg; - my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); + my $msg; + my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); + my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); - if ( defined $entry and defined $team ) { + if ( defined $entry and defined $team ) { - my $exception = Exception->new( - entry => $entry, - team => $team, - entry_id => $entry->id, - team_id => $team->id - ); - - $entry->add_exception($exception); - $team->add_exception($exception); - $self->app->repo->exceptions_save($exception); - - $msg - = "Exception added! Entry ID " - . $entry->id - . " will be now listed under team '" - . $team->name . "'."; - } - else { - $msg - = "Cannot find entry or team to create exception. Searched team ID: " - . $team_id - . " entry ID: " - . $entry_id . "."; - } + my $exception = Exception->new( + entry => $entry, + team => $team, + entry_id => $entry->id, + team_id => $team->id + ); - $self->flash( msg => $msg ); - $self->app->logger->info($msg); - $self->redirect_to( $self->get_referrer ); + $entry->add_exception($exception); + $team->add_exception($exception); + $self->app->repo->exceptions_save($exception); + + $msg + = "Exception added! Entry ID " + . $entry->id + . " will be now listed under team '" + . $team->name . "'."; + } + else { + $msg + = "Cannot find entry or team to create exception. Searched team ID: " + . $team_id + . " entry ID: " + . $entry_id . "."; + } + + $self->flash( msg => $msg ); + $self->app->logger->info($msg); + $self->redirect_to( $self->get_referrer ); } #################################################################################### sub remove_exception { - my $self = shift; - my $entry_id = $self->param('eid'); - my $team_id = $self->param('tid'); + my $self = shift; + my $entry_id = $self->param('eid'); + my $team_id = $self->param('tid'); - my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); + my $entry = $self->app->repo->entries_find( sub { $_->id == $entry_id } ); + my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); - my $msg; + my $msg; - if ( defined $entry and defined $team ) { + if ( defined $entry and defined $team ) { - my $ex = Exception->new( - team_id => $team_id, - entry_id => $entry_id, - team => $team, - entry => $entry - ); + my $ex = Exception->new( + team_id => $team_id, + entry_id => $entry_id, + team => $team, + entry => $entry + ); - my $exception - = $self->app->repo->exceptions_find( sub { $_->equals($ex) } ); - - if ( defined $exception ) { - $entry->remove_exception($exception); - $team->remove_exception($exception); - $self->app->repo->exceptions_delete($exception); - - $msg - = "Removed exception team '" - . $team->name - . "' from entry ID " - . $entry->id . ". "; - } - else { - $msg - = "Cannot find exception to remove. Searched team '" - . $team->name - . "' entry ID: " - . $entry->id . "."; - } + my $exception + = $self->app->repo->exceptions_find( sub { $_->equals($ex) } ); + + if ( defined $exception ) { + $entry->remove_exception($exception); + $team->remove_exception($exception); + $self->app->repo->exceptions_delete($exception); + + $msg + = "Removed exception team '" + . $team->name + . "' from entry ID " + . $entry->id . ". "; } else { - $msg - = "Cannot find exception to remove. Searched team ID: " - . $team_id - . " entry ID: " - . $entry_id . "."; + $msg + = "Cannot find exception to remove. Searched team '" + . $team->name + . "' entry ID: " + . $entry->id . "."; } + } + else { + $msg + = "Cannot find exception to remove. Searched team ID: " + . $team_id + . " entry ID: " + . $entry_id . "."; + } - $self->flash( msg => $msg ); - $self->app->logger->info($msg); + $self->flash( msg => $msg ); + $self->app->logger->info($msg); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to( $self->get_referrer ); } #################################################################################### #################################################################################### #################################################################################### sub get_adding_editing_message_for_error_code { - my $self = shift; - my $exit_code = shift; - my $existing_id = shift || -1; - - # -1 You have bibtex errors! Not saving!"; - # -2 Displaying preview'; - # 0 Entry added successfully'; - # 1 Entry updated successfully'; - # 2 The proposed key is OK. - # 3 Proposed key exists already - HTML message - - if ( $exit_code eq 'ERR_BIBTEX' ) { - return - "You have bibtex errors! No changes were written to the database."; - } - elsif ( $exit_code eq 'PREVIEW' ) { - return 'Displaying preview. No changes were written to the database.'; - } - elsif ( $exit_code eq 'ADD_OK' ) { - return 'Entry added successfully. Switched to editing mode.'; - } - elsif ( $exit_code eq 'EDIT_OK' ) { - return 'Entry updated successfully.'; - } - elsif ( $exit_code eq 'KEY_OK' ) { - return - 'The proposed key is OK. You may continue with your edits. No changes were written to the database.'; - } - elsif ( $exit_code eq 'KEY_TAKEN' ) { - return - 'The proposed key exists already in DB under ID . + my $self = shift; + my $exit_code = shift; + my $existing_id = shift || -1; + + # -1 You have bibtex errors! Not saving!"; + # -2 Displaying preview'; + # 0 Entry added successfully'; + # 1 Entry updated successfully'; + # 2 The proposed key is OK. + # 3 Proposed key exists already - HTML message + + if ( $exit_code eq 'ERR_BIBTEX' ) { + return "You have bibtex errors! No changes were written to the database."; + } + elsif ( $exit_code eq 'PREVIEW' ) { + return 'Displaying preview. No changes were written to the database.'; + } + elsif ( $exit_code eq 'ADD_OK' ) { + return 'Entry added successfully. Switched to editing mode.'; + } + elsif ( $exit_code eq 'EDIT_OK' ) { + return 'Entry updated successfully.'; + } + elsif ( $exit_code eq 'KEY_OK' ) { + return + 'The proposed key is OK. You may continue with your edits. No changes were written to the database.'; + } + elsif ( $exit_code eq 'KEY_TAKEN' ) { + return + 'The proposed key exists already in DB under ID .
+% foreach my $line (@{$lines}){ +<%= $line %> +% } ++