diff --git a/.perltidyrc b/.perltidyrc index f2ac20c..37c5f4a 100644 --- a/.perltidyrc +++ b/.perltidyrc @@ -10,3 +10,4 @@ -bt=2 # High brace tightness -sbt=2 # High square bracket tightness -isbc # Don't indent comments without leading space +-nst diff --git a/.tidyallrc b/.tidyallrc new file mode 100644 index 0000000..7a1ec14 --- /dev/null +++ b/.tidyallrc @@ -0,0 +1,8 @@ +[PerlTidy] +select = **/*.{pl,pm,t} +argv = --profile=$ROOT/.perltidyrc + +;[PerlCritic] +;select = lib/**/*.pm +;ignore = lib/BibStyle/**/*.pm +;argv = -severity 4 \ No newline at end of file diff --git a/Changelog.md b/Changelog.md index bb6582d..8d2d4de 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,7 +1,12 @@ ### Changelog ### +#### v0.5.2 08.2017 #### +* Code refactoring: perltidy +* Code refactoring: perlcritic severity 5 +* Partial code refactoring: perlcritic severity 4 + #### v0.5.1 08.2017 #### -* Add support for docekrizing +* Add support for dockerizing * Move json files to json_data directory #### v0.5.0 05.2016 #### diff --git a/README.md b/README.md index f932d4d..674bcfd 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,21 @@ Visit [hex64.com](http://www.hex64.com/) and click backend/frontend demo to have ## Installation ## * See [INSTALL.md](INSTALL.md) +## Using BibSpace with Docker ## + +BibSpace has no official docker image on dockerhub (yet), thus you need to build it manually. However, an image with prerequisites exists to ease the process of building. Here are the commands to build BibSpace using docker. + +``` +# build BibSpace image +docker-compose build +# run it with docker-compose +docker-compose up -d +# thats it! Point you browser to http://localhost:8083/ to open BibSpace +# you may stop the container with +docker-compose down +``` + +Your MySQL data is stored in `db_data`, whereas preferences and stats in `json_data`. ## TODOs ## BibSpace is currently undergoing serious refactoring. I try to keep current status up to date in [BibSpace Trelo Board](https://trello.com/b/yQ2VPiQ3/bibspace) diff --git a/cpanfile b/cpanfile index 30d30bd..1f5f6c4 100644 --- a/cpanfile +++ b/cpanfile @@ -43,6 +43,8 @@ on 'test' => sub { requires 'Test::Exception' , '>= 0.0'; requires 'Test::MockModule' , '>= 0.0'; requires 'Test::Pod::Coverage' , '>= 0.0'; + requires 'Test::Code::TidyAll' , '>= 0.0'; + requires 'Perl::Tidy' , '>= 0.0'; }; on 'develop' => sub { diff --git a/fixture/bibspace_fixture.dat b/fixture/bibspace_fixture.dat index 81d2988..174a429 100644 Binary files a/fixture/bibspace_fixture.dat and b/fixture/bibspace_fixture.dat differ diff --git a/lib/BibSpace.pm b/lib/BibSpace.pm index 62c307f..9da5df7 100644 --- a/lib/BibSpace.pm +++ b/lib/BibSpace.pm @@ -1,8 +1,7 @@ -package BibSpace v0.5.1; +package BibSpace v0.5.2; # ABSTRACT: BibSpace is a system to manage Bibtex references for authors and research groups web page. - use BibSpace::Functions::Core; use BibSpace::Functions::MySqlBackupFunctions; use BibSpace::Functions::FDB; @@ -14,7 +13,6 @@ use BibSpace::Functions::FPublications; use Mojo::Base 'Mojolicious'; use Mojo::Base 'Mojolicious::Plugin::Config'; - use Data::Dumper; # use File::Slurp; @@ -24,7 +22,6 @@ use Path::Tiny; # for creating directories use Mojo::Home; use File::Spec; - use BibSpace::Backend::SmartArray; use BibSpace::Backend::SmartHash; use BibSpace::Util::SimpleLogger; @@ -60,20 +57,17 @@ use feature qw( state say ); has preferences => sub { my $self = shift; - my $file - = $self->app->home->rel_file("bibspace_preferences.json"); - return state $prefs - = Preferences->new( filename => "" . $file )->load_maybe; + my $file = $self->app->home->rel_file("json_data/bibspace_preferences.json"); + return state $prefs = Preferences->new(filename => "" . $file)->load_maybe; }; has statistics => sub { my $self = shift; - my $file = $self->app->home->rel_file("bibspace_stats.json"); + my $file = $self->app->home->rel_file("json_data/bibspace_stats.json"); say $file; - return state $stats = Statistics->new( filename => "" . $file )->load_maybe; + return state $stats = Statistics->new(filename => "" . $file)->load_maybe; }; - has config_file => sub { my $self = shift; my $candidate; @@ -84,14 +78,13 @@ has config_file => sub { return $candidate if -e $candidate; $candidate - = $self->app->home->rel_file('lib/BibSpace/files/config/default.conf'); + = $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 + $candidate = $self->app->home->rel_file('config/default.conf'); # for travis return $candidate if -e $candidate; die "Cannot find Bibspace config!"; - return; }; has get_backups_dir => sub { @@ -142,8 +135,7 @@ has use_quick_load_fixture => sub { my $self = shift; return if $self->mode eq 'production'; - return 1 - if defined $ENV{BIBSPACE_USE_DUMP} and $ENV{BIBSPACE_USE_DUMP} == 1; + return 1 if defined $ENV{BIBSPACE_USE_DUMP} and $ENV{BIBSPACE_USE_DUMP} == 1; return; }; @@ -153,10 +145,9 @@ has use_quick_load_fixture => sub { # 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 ); + return SmartArray->new(logger => $self->logger); }; ## I moved this to helpers as app->attr for a while @@ -165,7 +156,6 @@ has layeredRepository => sub { my $self = shift; $self->app->logger->info("Building layeredRepository"); - my $LR = LayeredRepository->new( logger => $self->logger, preferences => $self->preferences, @@ -188,10 +178,10 @@ has layeredRepository => sub { ); $LR->add_layer($smartArrayLayer); - if ( !$self->db ) { + 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" + . " You need to start MySQL server and restart BibSpace to use this layer" ); } else { @@ -203,7 +193,7 @@ has layeredRepository => sub { logger => $self->logger, handle => $self->db, reset_data_callback => \&reset_db_data, - reset_data_callback_arguments => [ $self->db ], + reset_data_callback_arguments => [$self->db], ); $LR->add_layer($mySQLLayer); } @@ -213,7 +203,7 @@ has layeredRepository => sub { # layeredRepository will not change at runtime => repo neither. has repo => sub { my $self = shift; - return RepositoryFacade->new( lr => $self->layeredRepository ); + return RepositoryFacade->new(lr => $self->layeredRepository); }; @@ -222,55 +212,24 @@ sub startup { 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 ); + 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("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; - - # 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_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"); - + return; } ################################################################ sub insert_admin { @@ -278,10 +237,10 @@ sub insert_admin { $self->app->logger->info("Add startup admin user..."); my $admin_exists - = $self->app->repo->users_find( sub { $_->login eq 'pub_admin' } ); - if ( !$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 $hash = encrypt_password('asdf', $salt); my $new_user = $self->app->entityFactory->new_User( login => 'pub_admin', email => 'pub_admin@example.com', @@ -298,6 +257,7 @@ sub insert_admin { $admin_exists->make_admin; $self->app->repo->users_update($admin_exists); } + return; } ################################################################ @@ -306,42 +266,39 @@ sub 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 ); + $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 - . "'." ); + $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 ) { + 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 - . "'." ); + $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; } - - + return; } ################################################################ sub link_data { @@ -349,24 +306,21 @@ sub link_data { $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 } ) ) + 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 ) { + = $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 ) { + 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); @@ -375,11 +329,11 @@ sub link_data { } $self->app->logger->info("Linking Tags (N) to (M) Entries."); - foreach my $labeling ( $self->repo->labelings_all ) { + 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 ) { + = $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); @@ -388,12 +342,11 @@ sub link_data { } $self->app->logger->info("Linking Teams (Exceptions) (N) to (M) Entries."); - foreach my $exception ( $self->repo->exceptions_all ) { + 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 ) { + = $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); @@ -401,15 +354,12 @@ sub link_data { } } - $self->app->logger->info("Linking Teams (N) to (M) Authors."); - foreach my $membership ( $self->repo->memberships_all ) { + 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 ) { + = $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); @@ -418,27 +368,28 @@ sub link_data { } $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 ) { + 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("Linking Finished."); + return; } ################################################################ sub setup_config { my $self = shift; my $app = $self; $self->app->logger->info("Setup config..."); - $self->plugin( 'Config' => { file => $self->app->config_file } ); + $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." ); + "Setting max upload size to " . $ENV{MOJO_MAX_MESSAGE_SIZE} . " Bytes."); + return; } ################################################################ sub setup_plugins { @@ -451,20 +402,21 @@ sub setup_plugins { $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->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("App version: " . $self->app->version); $self->app->logger->info("Creating directories..."); for my $dir ( - ( $self->app->get_backups_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 { @@ -478,18 +430,13 @@ sub setup_plugins { # 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 ) ); - + $self->logger->set_log_dir("" . Path::Tiny->new($self->get_log_dir)); # 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} }); + return; } ################################################################ ################################################################ @@ -500,17 +447,16 @@ sub 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"); + ->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'); + ->name('youneedtologin'); $anyone->get('/badpassword')->to('login#bad_password')->name('badpassword'); $anyone->get('/logout')->to('login#logout')->name('logout'); @@ -520,7 +466,7 @@ sub setup_routes { $anyone->get('/register')->to('login#register')->name('register'); $anyone->post('/register')->to('login#post_do_register') - ->name('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'); @@ -530,176 +476,164 @@ sub setup_routes { ################ PREFERENCES ################ $manager_user->get('/preferences')->to('preferences#index') - ->name('preferences'); + ->name('preferences'); $admin_user->post('/preferences')->to('preferences#save') - ->name('save_preferences'); + ->name('save_preferences'); ################ EXPERIMENTAL / PERSISTENCE ################ $anyone->get('/system_status')->to('persistence#system_status') - ->name('system_status'); + ->name('system_status'); $admin_user->get('/persistence/load')->to('persistence#load_fixture') - ->name('load_fixture'); + ->name('load_fixture'); $admin_user->get('/persistence/save')->to('persistence#save_fixture') - ->name('save_fixture'); + ->name('save_fixture'); $admin_user->get('/persistence/copy_mysql_to_smart') - ->to('persistence#copy_mysql_to_smart')->name('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'); + ->to('persistence#copy_smart_to_mysql')->name('copy_smart_to_mysql'); $admin_user->get('/persistence/persistence_status') - ->to('persistence#persistence_status')->name('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'); - + ->to('persistence#persistence_status_ajax') + ->name('persistence_status_ajax'); $admin_user->get('/persistence/reset_mysql')->to('persistence#reset_mysql') - ->name('reset_mysql'); + ->name('reset_mysql'); $admin_user->get('/persistence/reset_smart')->to('persistence#reset_smart') - ->name('reset_smart'); + ->name('reset_smart'); $admin_user->get('/persistence/reset_all')->to('persistence#reset_all') - ->name('reset_all'); + ->name('reset_all'); $admin_user->get('/persistence/insert_random_data') - ->to('persistence#insert_random_data')->name('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'); + ->name('manage_users'); $admin_user->get('/profile/:id')->to('login#foreign_profile') - ->name('show_user_profile'); + ->name('show_user_profile'); $admin_user->get('/profile/delete/:id')->to('login#delete_user') - ->name('delete_user'); + ->name('delete_user'); $admin_user->get('/profile/make_user/:id')->to('login#make_user') - ->name('make_user'); + ->name('make_user'); $admin_user->get('/profile/make_manager/:id')->to('login#make_manager') - ->name('make_manager'); + ->name('make_manager'); $admin_user->get('/profile/make_admin/:id')->to('login#make_admin') - ->name('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'); + ->name('show_stats'); # websocket for fun $manager_user->websocket('/log_websocket/:num')->to('display#show_log_ws') - ->name('show_log_websocket'); + ->name('show_log_websocket'); $manager_user->websocket('/statistics/:num') - ->to('display#show_stats_websocket')->name('show_stats_websocket'); - + ->to('display#show_stats_websocket')->name('show_stats_websocket'); $admin_user->get('/settings/fix_months')->to('publications#fixMonths') - ->name('fix_all_months'); + ->name('fix_all_months'); $manager_user->get('/settings/clean_all') - ->to('publications#clean_ugly_bibtex')->name('clean_ugly_bibtex'); + ->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'); + ->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'); + ->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'); + ->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'); - + ->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'); + ->name('backup_do_mysql'); $manager_user->get('/backups/:id')->to('backup#backup_download') - ->name('backup_download'); + ->name('backup_download'); $admin_user->delete('/backups/:id')->to('backup#delete_backup') - ->name('backup_delete'); + ->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'); - + ->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->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'); + ->name('add_type_post'); $manager_user->get('/types/manage/:name')->to('types#manage') - ->name('edit_type'); + ->name('edit_type'); $manager_user->get('/types/delete/:name')->to('types#delete_type') - ->name('delete_type'); + ->name('delete_type'); $manager_user->post('/types/store_description') - ->to('types#post_store_description')->name('update_type_description'); + ->to('types#post_store_description')->name('update_type_description'); $manager_user->get('/types/toggle/:name')->to('types#toggle_landing') - ->name('toggle_landing_type'); + ->name('toggle_landing_type'); $manager_user->get('/types/:our_type/map/:bibtex_type') - ->to('types#map_types'); + ->to('types#map_types'); $manager_user->get('/types/:our_type/unmap/:bibtex_type') - ->to('types#unmap_types')->name('unmap_bibtex_type'); + ->to('types#unmap_types')->name('unmap_bibtex_type'); ################ AUTHORS ################ $logged_user->get('/authors/')->to('authors#all_authors') - ->name('all_authors'); + ->name('all_authors'); $manager_user->get('/authors/add')->to('authors#add_author') - ->name('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'); + ->name('edit_author'); $manager_user->post('/authors/edit/')->to('authors#edit_post') - ->name('edit_author_post'); + ->name('edit_author_post'); $manager_user->get('/authors/delete/:id')->to('authors#delete_author') - ->name('delete_author'); - + ->name('delete_author'); $admin_user->get('/authors/delete/:id/force') - ->to('authors#delete_author_force'); - + ->to('authors#delete_author_force'); # for dev only!! - $admin_user->get('/authors/decimate') - ->to('authors#delete_invisible_authors'); - + $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'); + ->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'); + ->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'); + ->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'); + ->to('authors#remove_uid')->name('remove_author_uid'); $manager_user->post('/authors/merge/')->to('authors#merge_authors') - ->name('merge_authors'); + ->name('merge_authors'); $admin_user->get('/authors/fix_masters')->to('authors#fix_masters') - ->name('fix_masters'); + ->name('fix_masters'); $manager_user->get('/authors/reassign') - ->to('authors#reassign_authors_to_entries'); + ->to('authors#reassign_authors_to_entries'); $admin_user->get('/authors/reassign_and_create') - ->to('authors#reassign_authors_to_entries_and_create_authors'); + ->to('authors#reassign_authors_to_entries_and_create_authors'); $manager_user->get('/authors/toggle_visibility/:id') - ->to('authors#toggle_visibility')->name('toggle_author_visibility'); + ->to('authors#toggle_visibility')->name('toggle_author_visibility'); # $logged_user->get('/authors/toggle_visibility') # ->to('authors#toggle_visibility'); @@ -709,22 +643,21 @@ sub setup_routes { $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'); + ->name('add_tag_type_post'); $admin_user->get('/tagtypes/delete/:id')->to('tagtypes#delete') - ->name('delete_tag_type'); + ->name('delete_tag_type'); $manager_user->any('/tagtypes/edit/:id')->to('tagtypes#edit') - ->name('edit_tag_type'); + ->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/: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'); + ->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!?! @@ -732,31 +665,31 @@ sub setup_routes { $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'); + ->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'); + ->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'); + ->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'); + ->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'); + ->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'); + ->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'); @@ -767,15 +700,14 @@ sub setup_routes { $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'); + ->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'); + ->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->get('/teams/add')->to('teams#add_team')->name('add_team_get'); $manager_user->post('/teams/add/')->to('teams#add_team_post'); ################ EDITING PUBLICATIONS ################ @@ -996,6 +928,7 @@ sub setup_routes { $anyone->get('/cron/(#level)')->to('cron#cron'); #>>> + return; } ################################################################ @@ -1004,35 +937,29 @@ 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') ) { + if ($c->req->headers->header('X-Forwarded-HTTPS')) { $c->req->url->base->scheme('https'); } - $c->app->statistics->log_url( $c->req->url ); - + $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 "" ) { + 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; + push @{$c->req->url->base->path->trailing_slash(1)}, $proxy_prefix; } } ); + return; } 1; diff --git a/lib/BibSpace/Backend/IBibSpaceBackend.pm b/lib/BibSpace/Backend/IBibSpaceBackend.pm index d09b088..7c18bea 100644 --- a/lib/BibSpace/Backend/IBibSpaceBackend.pm +++ b/lib/BibSpace/Backend/IBibSpaceBackend.pm @@ -1,5 +1,5 @@ package IBibSpaceBackend; -use v5.16; +use v5.16; use Try::Tiny; use Data::Dumper; use namespace::autoclean; @@ -16,6 +16,5 @@ requires 'delete'; requires 'filter'; requires 'find'; - 1; diff --git a/lib/BibSpace/Backend/SmartArray.pm b/lib/BibSpace/Backend/SmartArray.pm index 0a5ee7a..23a4d77 100644 --- a/lib/BibSpace/Backend/SmartArray.pm +++ b/lib/BibSpace/Backend/SmartArray.pm @@ -1,6 +1,6 @@ package SmartArray; -use v5.16; +use v5.16; use Try::Tiny; use Data::Dumper; use namespace::autoclean; @@ -19,8 +19,7 @@ use List::MoreUtils qw(first_index); use feature qw( say ); use MooseX::Storage; -with Storage( format => 'JSON', 'io' => 'File' ); - +with Storage(format => 'JSON', 'io' => 'File'); =item This is a in-memory data structure (hash) to hold all objects of BibSpace. @@ -30,159 +29,161 @@ with Storage( format => 'JSON', 'io' => 'File' ); String "TypeName" => { Integer UID => Object with type TypeName}. =cut -has 'logger' => ( is => 'ro', does => 'ILogger', required => 1, traits => ['DoNotSerialize']); +has 'logger' => + (is => 'ro', does => 'ILogger', required => 1, traits => ['DoNotSerialize']); has 'data' => ( - traits => ['Hash'], - is => 'ro', - isa => 'HashRef[ArrayRef[BibSpace::Model::IEntity]]', - default => sub { {} }, - handles => { - set => 'set', - get => 'get', - has => 'exists', - defined => 'defined', - keys => 'keys', - # values => 'values', - num => 'count', - pairs => 'kv', - _clear => 'clear', - }, + traits => ['Hash'], + is => 'ro', + isa => 'HashRef[ArrayRef[BibSpace::Model::IEntity]]', + default => sub { {} }, + handles => { + set => 'set', + get => 'get', + has => 'exists', + defined => 'defined', + keys => 'keys', + + # values => 'values', + num => 'count', + pairs => 'kv', + _clear => 'clear', + }, ); sub reset_data { - my $self = shift; - $self->logger->warn("Resetting SmartArray"); - $self->_clear; + my $self = shift; + $self->logger->warn("Resetting SmartArray"); + $self->_clear; } sub dump { - my $self = shift; - $self->logger->debug("SmartArray keys: ".join(', ', $self->keys)); + my $self = shift; + $self->logger->debug("SmartArray keys: " . join(', ', $self->keys)); } sub _init { - my ($self, $type) = @_; - die "_init requires a type!" unless $type; - if(!$self->defined($type)){ - $self->set($type, []); - } + my ($self, $type) = @_; + die "_init requires a type!" unless $type; + if (!$self->defined($type)) { + $self->set($type, []); + } } sub all { - my ($self, $type) = @_; + my ($self, $type) = @_; - $self->logger->error("SmartArray->all requires a type! Type: $type.") unless $type; - $self->_init($type); - my $aref = $self->get($type); - return @{ $aref }; + $self->logger->error("SmartArray->all requires a type! Type: $type.") + unless $type; + $self->_init($type); + my $aref = $self->get($type); + return @{$aref}; } sub _add { - my ($self, @objects) = @_; - my $type = ref($objects[0]); - $self->_init($type); - push @{$self->get($type)}, @objects; + my ($self, @objects) = @_; + my $type = ref($objects[0]); + $self->_init($type); + push @{$self->get($type)}, @objects; } sub save { - my ($self, @objects) = @_; - my $added = 0; - - # if there are multiple objects to add and the array is empty -> do it quicker! - if( @objects > 0 ){ - my $type = ref($objects[0]); - - if( $self->empty($type) ){ - $self->_add(@objects); - $added = scalar @objects; - return $added; - } + my ($self, @objects) = @_; + my $added = 0; + + # if there are multiple objects to add and the array is empty -> do it quicker! + if (@objects > 0) { + my $type = ref($objects[0]); + + if ($self->empty($type)) { + $self->_add(@objects); + $added = scalar @objects; + return $added; } - - - foreach my $obj(@objects){ - if( !$self->exists($obj)){ - ++$added; - $self->_add($obj); - } - else{ - $self->update($obj); - } + } + + foreach my $obj (@objects) { + if (!$self->exists($obj)) { + ++$added; + $self->_add($obj); + } + else { + $self->update($obj); } - - return $added; + } + + return $added; } -sub count { - my ($self, $type) = @_; - die "all requires a type!" unless $type; - return scalar $self->all($type); +sub count { + my ($self, $type) = @_; + die "all requires a type!" unless $type; + return scalar $self->all($type); } -sub empty { - my ($self, $type) = @_; - return $self->count($type) == 0; +sub empty { + my ($self, $type) = @_; + return $self->count($type) == 0; } ## this is mega slow for relations!!! -sub exists { - my ($self, $object) = @_; - my $type = ref($object); - $self->logger->error("SmartArray->exists requires a type! Object: '$object', type: '$type'.") unless $type; - my $found = first {$_->equals($object)} $self->all($type); - return defined $found; +sub exists { + my ($self, $object) = @_; + my $type = ref($object); + $self->logger->error( + "SmartArray->exists requires a type! Object: '$object', type: '$type'.") + unless $type; + my $found = first { $_->equals($object) } $self->all($type); + return defined $found; } -sub update { - my ($self, @objects) = @_; - # should happen automatically beacuse array keeps references to objects +sub update { + my ($self, @objects) = @_; + + # should happen automatically beacuse array keeps references to objects } -sub delete { - my ($self, @objects) = @_; - my $type = ref($objects[0]); - my $aref = $self->get($type); - my @removed; - foreach my $obj (@objects){ - my $idx = first_index { $_ == $obj } @{$aref}; - push @removed, splice( @{$aref}, $idx, 1) if $idx > -1; - } - return @removed; +sub delete { + my ($self, @objects) = @_; + my $type = ref($objects[0]); + my $aref = $self->get($type); + my @removed; + foreach my $obj (@objects) { + my $idx = first_index { $_ == $obj } @{$aref}; + push @removed, splice(@{$aref}, $idx, 1) if $idx > -1; + } + return @removed; } +sub filter { + my ($self, $type, $coderef) = @_; + + -sub filter { - my ($self, $type, $coderef) = @_; + return () if $self->empty($type); + my @arr = grep &{$coderef}, $self->all($type); - my $t0 = [gettimeofday]; - - return () if $self->empty($type); - my @arr = grep &{$coderef}, $self->all($type); - - my $dur = tv_interval ( $t0, [gettimeofday]); - say "Filtering in SArray '$type': $dur" if $dur > 0.01; - return @arr; + + + return @arr; } -sub find { +sub find { my ($self, $type, $coderef) = @_; - my $t0 = [gettimeofday]; - return undef if $self->empty($type); + + return if $self->empty($type); my $obj = first \&{$coderef}, $self->all($type); + - my $dur = tv_interval ( $t0, [gettimeofday]); - say "Finding in SArray '$type': $dur" if $dur > 0.01; + return $obj; } # Moose::Meta::Attribute::Native::Trait::Array - - __PACKAGE__->meta->make_immutable; no Moose; -1; \ No newline at end of file +1; diff --git a/lib/BibSpace/Backend/SmartHash.pm b/lib/BibSpace/Backend/SmartHash.pm index a9789aa..957249a 100644 --- a/lib/BibSpace/Backend/SmartHash.pm +++ b/lib/BibSpace/Backend/SmartHash.pm @@ -1,6 +1,6 @@ package SmartHash; -use v5.16; +use v5.16; use Try::Tiny; use Data::Dumper; use namespace::autoclean; @@ -27,157 +27,157 @@ use feature qw( say ); String "TypeName" => { Integer UID => Object with type TypeName}. =cut -has 'logger' => ( is => 'ro', does => 'ILogger', required => 1); +has 'logger' => (is => 'ro', does => 'ILogger', required => 1); has 'data' => ( - traits => ['Hash'], - is => 'ro', - isa => 'HashRef[HashRef[BibSpace::Model::IEntity]]', - default => sub { {} }, - handles => { - set => 'set', - get => 'get', - has => 'exists', - defined => 'defined', - keys => 'keys', - # values => 'values', - num => 'count', - pairs => 'kv', - _clear => 'clear', - }, + traits => ['Hash'], + is => 'ro', + isa => 'HashRef[HashRef[BibSpace::Model::IEntity]]', + default => sub { {} }, + handles => { + set => 'set', + get => 'get', + has => 'exists', + defined => 'defined', + keys => 'keys', + + # values => 'values', + num => 'count', + pairs => 'kv', + _clear => 'clear', + }, ); sub reset_data { - my $self = shift; - $self->logger->warn("Resetting SmartHash"); - $self->_clear; + my $self = shift; + $self->logger->warn("Resetting SmartHash"); + $self->_clear; } sub dump { - my $self = shift; - $self->logger->debug("SmartHash keys: ".join(', ', $self->keys)); + my $self = shift; + $self->logger->debug("SmartHash keys: " . join(', ', $self->keys)); } sub _init { - my ($self, $type) = @_; - die "_init requires a type!" unless $type; - if(!$self->defined($type)){ - $self->set($type, {}); - } + my ($self, $type) = @_; + die "_init requires a type!" unless $type; + if (!$self->defined($type)) { + $self->set($type, {}); + } } sub all { - my ($self, $type) = @_; - die "all requires a type!" unless $type; - $self->_init($type); - my $href = $self->get($type); - - my @result; - if($href){ - @result = values %$href; - } - return @result; + my ($self, $type) = @_; + die "all requires a type!" unless $type; + $self->_init($type); + my $href = $self->get($type); + + my @result; + if ($href) { + @result = values %$href; + } + return @result; } sub _add { - my ($self, @objects) = @_; - return if scalar(@objects) == 0; - - my $type = ref($objects[0]); - - $self->_init($type); - my $href = $self->get($type); - - my $num_added = 0; - foreach my $obj (@objects){ - $href->{$obj->id} = $obj; - $num_added++; - } - return $num_added; + my ($self, @objects) = @_; + return if scalar(@objects) == 0; + + my $type = ref($objects[0]); + + $self->_init($type); + my $href = $self->get($type); + + my $num_added = 0; + foreach my $obj (@objects) { + $href->{$obj->id} = $obj; + $num_added++; + } + return $num_added; } sub save { - my ($self, @objects) = @_; - return $self->_add(@objects); + my ($self, @objects) = @_; + return $self->_add(@objects); } -sub count { - my ($self, $type) = @_; - die "all requires a type!" unless $type; - return 0 if $self->empty($type); +sub count { + my ($self, $type) = @_; + die "all requires a type!" unless $type; + return 0 if $self->empty($type); - $self->_init($type); - my $href = $self->get($type); - return scalar keys %$href; + $self->_init($type); + my $href = $self->get($type); + return scalar keys %$href; } -sub empty { - my ($self, $type) = @_; - $self->_init($type); - my $href = $self->get($type); - return scalar(keys %$href) == 0; +sub empty { + my ($self, $type) = @_; + $self->_init($type); + my $href = $self->get($type); + return scalar(keys %$href) == 0; } -sub exists { - my ($self, $object) = @_; - my $type = ref($object); - $self->logger->error("SmartHash->exists requires a type! Object: '$object', type: '$type'.") unless $type; - my $href = $self->get($type); - return exists $href->{$object->id}; +sub exists { + my ($self, $object) = @_; + my $type = ref($object); + $self->logger->error( + "SmartHash->exists requires a type! Object: '$object', type: '$type'.") + unless $type; + my $href = $self->get($type); + return exists $href->{$object->id}; } -sub update { - my ($self, @objects) = @_; - return $self->_add(@objects); +sub update { + my ($self, @objects) = @_; + return $self->_add(@objects); } -sub delete { - my ($self, @objects) = @_; - my $type = ref($objects[0]); - my $href = $self->get($type); - - my @removed; - foreach my $obj (@objects){ - push @removed, delete $href->{$obj->id}; - } - - return @removed; +sub delete { + my ($self, @objects) = @_; + my $type = ref($objects[0]); + my $href = $self->get($type); + + my @removed; + foreach my $obj (@objects) { + push @removed, delete $href->{$obj->id}; + } + + return @removed; } - -sub filter { - my ($self, $type, $coderef) = @_; +sub filter { + my ($self, $type, $coderef) = @_; - my $t0 = [gettimeofday]; + - return () if $self->empty($type); - my @arr = grep &{$coderef}, $self->all($type); + return () if $self->empty($type); + my @arr = grep &{$coderef}, $self->all($type); - my $dur = tv_interval ( $t0, [gettimeofday]); - say "Filtering in SHash '$type': $dur" if $dur > 0.01; + + - return @arr; + return @arr; } -sub find { - my ($self, $type, $coderef) = @_; +sub find { + my ($self, $type, $coderef) = @_; - my $t0 = [gettimeofday]; + - return undef if $self->empty($type); - my $obj = first \&{$coderef}, $self->all($type); + return if $self->empty($type); + my $obj = first \&{$coderef}, $self->all($type); - my $dur = tv_interval ( $t0, [gettimeofday]); - say "Finding in SHash '$type': $dur" if $dur > 0.01; + + - return $obj; + return $obj; } # Moose::Meta::Attribute::Native::Trait::Array - - __PACKAGE__->meta->make_immutable; no Moose; -1; \ No newline at end of file +1; diff --git a/lib/BibSpace/Controller/Authors.pm b/lib/BibSpace/Controller/Authors.pm index 03ce101..7ef2696 100644 --- a/lib/BibSpace/Controller/Authors.pm +++ b/lib/BibSpace/Controller/Authors.pm @@ -1,18 +1,17 @@ package BibSpace::Controller::Authors; - use Data::Dumper; use utf8; use Text::BibTeX; # parsing bib files use DateTime; use Try::Tiny; + # use File::Slurp; use v5.16; #because of ~~ use strict; use warnings; - use List::MoreUtils qw(any uniq); use BibSpace::Functions::Core; @@ -23,49 +22,51 @@ use BibSpace::Functions::FPublications; use Mojo::Base 'Mojolicious::Controller'; use Mojo::Base 'Mojolicious::Plugin::Config'; - ############################################################################################################## sub all_authors { # refactored my $self = shift; my $visible = $self->param('visible'); my $search = $self->param('search'); my $letter = $self->param('letter'); - my @authors = $self->app->repo->authors_all; - if ( defined $visible ) { + if (defined $visible) { @authors = grep { $_->display == $visible } @authors; } - + @authors = grep { $_->is_master } @authors; - if ( $letter) { - @authors = grep { ( substr( $_->master, 0, 1 ) cmp $letter ) == 0 } @authors; + if ($letter) { + @authors = grep { (substr($_->master, 0, 1) cmp $letter) == 0 } @authors; } my @letters; - if( defined $visible){ - @letters = map { substr( $_->master, 0, 1 ) } $self->app->repo->authors_filter(sub{ $_->display == $visible }); + if (defined $visible) { + @letters = map { substr($_->master, 0, 1) } + $self->app->repo->authors_filter(sub { $_->display == $visible }); } - else{ - @letters = map { substr( $_->master, 0, 1 ) } $self->app->repo->authors_all; + else { + @letters = map { substr($_->master, 0, 1) } $self->app->repo->authors_all; } @letters = uniq @letters; @letters = sort @letters; + @authors = sort { $a->uid cmp $b->uid } @authors; + $self->stash( + authors => \@authors, + letters => \@letters, + selected_letter => $letter, + visible => $visible + ); - @authors = sort {$a->uid cmp $b->uid} @authors; - - $self->stash( authors => \@authors, letters => \@letters, selected_letter => $letter, visible => $visible ); - - $self->render( template => 'authors/authors' ); + $self->render(template => 'authors/authors'); } ############################################################################################################## sub add_author { my $self = shift; - $self->stash( master => '', id => '' ); - $self->render( template => 'authors/add_author' ); + $self->stash(master => '', id => ''); + $self->render(template => 'authors/add_author'); } ############################################################################################################## @@ -73,67 +74,74 @@ sub add_post { my $self = shift; my $new_master = $self->param('new_master'); - if ( defined $new_master and length($new_master) > 0 ) { + if (defined $new_master and length($new_master) > 0) { - my $author = $self->app->repo->authors_find( sub { $_->master eq $new_master } ); + my $author + = $self->app->repo->authors_find(sub { $_->master eq $new_master }); - if ( !defined $author ) { # no such user exists yet + if (!defined $author) { # no such user exists yet - $author = $self->app->entityFactory->new_Author( uid => $new_master ); + $author = $self->app->entityFactory->new_Author(uid => $new_master); $self->app->repo->authors_save($author); - if ( !defined $author->id ) { + if (!defined $author->id) { $self->flash( msg_type => 'danger', - msg => "Error saving author. Saving to the database returned no insert row id." + msg => + "Error saving author. Saving to the database returned no insert row id." ); - $self->redirect_to( $self->url_for('add_author') ); + $self->redirect_to($self->url_for('add_author')); return; } - $self->app->logger->info( "Added new author with master: $new_master. Author id is " . $author->{id} ); - $self->flash( msg_type => 'success', msg => "Author added successfully!" ); - $self->redirect_to( $self->url_for( 'edit_author', id => $author->{id} ) ); + $self->app->logger->info( + "Added new author with master: $new_master. Author id is " + . $author->{id}); + $self->flash(msg_type => 'success', msg => "Author added successfully!"); + $self->redirect_to($self->url_for('edit_author', id => $author->{id})); return; } else { # such user already exists! - $self->app->logger->info("Author with master: $new_master already exists!"); + $self->app->logger->info( + "Author with master: $new_master already exists!"); $self->flash( msg_type => 'warning', - msg => "Author with proposed master: $new_master already exists! Pick a different one." + msg => + "Author with proposed master: $new_master already exists! Pick a different one." ); - $self->redirect_to( $self->url_for('add_author') ); + $self->redirect_to($self->url_for('add_author')); return; } } - $self->flash( msg_type => 'warning', msg => "Bad input." ); - $self->redirect_to( $self->url_for('add_author') ); + $self->flash(msg_type => 'warning', msg => "Bad input."); + $self->redirect_to($self->url_for('add_author')); } ############################################################################################################## sub edit_author { my $self = shift; my $id = $self->param('id'); - my $author = $self->app->repo->authors_find( sub { $_->id == $id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $id }); - - if ( !defined $author ) { - $self->flash( msg => "Author with id $id does not exist!", msg_type => "danger" ); - $self->redirect_to( $self->url_for('all_authors') ); + if (!defined $author) { + $self->flash( + msg => "Author with id $id does not exist!", + msg_type => "danger" + ); + $self->redirect_to($self->url_for('all_authors')); } else { - my @all_teams = $self->app->repo->teams_all; my @author_teams = $author->get_teams; my @author_tags = $author->get_tags; # cannot use objects as keys due to hash stringification! my %author_teams_hash = map { $_->id => 1 } @author_teams; - my @unassigned_teams = grep { not $author_teams_hash{ $_->id } } @all_teams; - + my @unassigned_teams = grep { not $author_teams_hash{$_->id} } @all_teams; - my @minor_authors = $self->app->repo->authors_filter( sub { $_->is_minion_of($author) } ); + my @minor_authors + = $self->app->repo->authors_filter(sub { $_->is_minion_of($author) }); # $author->all_author_user_ids($dbh); @@ -145,7 +153,7 @@ sub edit_author { all_teams => \@all_teams, unassigned_teams => \@unassigned_teams ); - $self->render( template => 'authors/edit_author' ); + $self->render(template => 'authors/edit_author'); } } ############################################################################################################## @@ -154,10 +162,10 @@ sub add_to_team { my $master_id = $self->param('id'); my $team_id = $self->param('tid'); - my $author = $self->app->repo->authors_find( sub { $_->id == $master_id } ); - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $master_id }); + my $team = $self->app->repo->teams_find(sub { $_->id == $team_id }); - if ( defined $author and defined $team ) { + if (defined $author and defined $team) { my $membership = Membership->new( author => $author->get_master, team => $team, @@ -169,14 +177,20 @@ sub add_to_team { $author->add_membership($membership); $self->flash( - msg => "Author " . $author->uid . " has just joined team " . $team->name . "", + msg => "Author " + . $author->uid + . " has just joined team " + . $team->name . "", msg_type => "success" ); } else { - $self->flash( msg => "Author or team does does not exist!", msg_type => "danger" ); + $self->flash( + msg => "Author or team does does not exist!", + msg_type => "danger" + ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } ############################################################################################################## sub remove_from_team { @@ -184,73 +198,91 @@ sub remove_from_team { my $master_id = $self->param('id'); my $team_id = $self->param('tid'); - my $author = $self->app->repo->authors_find( sub { $_->id == $master_id } ); - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $master_id }); + my $team = $self->app->repo->teams_find(sub { $_->id == $team_id }); - if ( defined $author and defined $team ) { + if (defined $author and defined $team) { my $membership = $author->memberships_find(sub { $_->team->equals($team) }); $author->remove_membership($membership); $team->remove_membership($membership); $self->app->repo->memberships_delete($membership); $self->flash( - msg => "Author " . $author->uid . " has just left team " . $team->name . "", + msg => "Author " + . $author->uid + . " has just left team " + . $team->name . "", msg_type => "success" ); } else { - $self->flash( msg => "Author or team does does not exist!", msg_type => "danger" ); + $self->flash( + msg => "Author or team does does not exist!", + msg_type => "danger" + ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } ############################################################################################################## sub remove_uid { my $self = shift; my $master_id = $self->param('masterid'); my $minor_id = $self->param('uid'); - - my $author_master = $self->app->repo->authors_find( sub { $_->id == $master_id } ); - my $author_minor = $self->app->repo->authors_find( sub { $_->id == $minor_id } ); + my $author_master + = $self->app->repo->authors_find(sub { $_->id == $master_id }); + my $author_minor + = $self->app->repo->authors_find(sub { $_->id == $minor_id }); - if ( !defined $author_minor ) { - $self->flash( msg => "Cannot remove user_id $minor_id. Reason: such author deos not exist.", msg_type => "danger" ); + if (!defined $author_minor) { + $self->flash( + msg => + "Cannot remove user_id $minor_id. Reason: such author deos not exist.", + msg_type => "danger" + ); } - elsif ( $author_minor->is_master ) { - $self->flash( msg => "Cannot remove user_id $minor_id. Reason: it is a master_id.", msg_type => "warning" ); + elsif ($author_minor->is_master) { + $self->flash( + msg => "Cannot remove user_id $minor_id. Reason: it is a master_id.", + msg_type => "warning" + ); } else { my @master_entries = $author_master->get_entries; # remove master authorships from both authors - foreach my $master_authorship ( $author_master->authorships_all ){ - $author_master->remove_authorship($master_authorship); - $author_minor->remove_authorship($master_authorship); + foreach my $master_authorship ($author_master->authorships_all) { + $author_master->remove_authorship($master_authorship); + $author_minor->remove_authorship($master_authorship); - $master_authorship->entry->remove_authorship($master_authorship); - $self->app->repo->authorships_delete($master_authorship); + $master_authorship->entry->remove_authorship($master_authorship); + $self->app->repo->authorships_delete($master_authorship); } + # remove minion authorships from both authors - foreach my $minion_authorship ( $author_minor->authorships_all ){ - $author_minor->remove_authorship($minion_authorship); - $author_master->remove_authorship($minion_authorship); + foreach my $minion_authorship ($author_minor->authorships_all) { + $author_minor->remove_authorship($minion_authorship); + $author_master->remove_authorship($minion_authorship); - $minion_authorship->entry->remove_authorship($minion_authorship); - $self->app->repo->authorships_delete($minion_authorship); + $minion_authorship->entry->remove_authorship($minion_authorship); + $self->app->repo->authorships_delete($minion_authorship); } + # unlink authors $author_minor->remove_master; + # save changes (minor should be enough) $self->app->repo->authors_update($author_master); $self->app->repo->authors_update($author_minor); # calculate proper authorships automatically - Freassign_authors_to_entries_given_by_array($self->app, 0, \@master_entries); + Freassign_authors_to_entries_given_by_array($self->app, 0, + \@master_entries); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } ############################################################################################################## sub merge_authors { @@ -258,35 +290,44 @@ sub merge_authors { my $destination_id = $self->param('author_to'); my $source_id = $self->param('author_from'); - my $author_destination = $self->app->repo->authors_find( sub { $_->id == $destination_id } ); - $author_destination ||= $self->app->repo->authors_find( sub { $_->uid eq $destination_id } ); + my $author_destination + = $self->app->repo->authors_find(sub { $_->id == $destination_id }); + $author_destination + ||= $self->app->repo->authors_find(sub { $_->uid eq $destination_id }); - my $author_source = $self->app->repo->authors_find( sub { $_->id == $source_id } ); - $author_source ||= $self->app->repo->authors_find( sub { $_->uid eq $source_id } ); + my $author_source + = $self->app->repo->authors_find(sub { $_->id == $source_id }); + $author_source + ||= $self->app->repo->authors_find(sub { $_->uid eq $source_id }); my $copy_name = $author_source->uid; my $success = 0; - if ( defined $author_source and defined $author_destination ) { - if ( $author_destination->can_merge_authors($author_source) ) { + if (defined $author_source and defined $author_destination) { + if ($author_destination->can_merge_authors($author_source)) { my @src_authorships = $author_source->authorships_all; - foreach my $src_authorship ( @src_authorships ){ - # Removing the authorship from the source author - $src_authorship->author->remove_authorship($src_authorship); - # authorships cannot be updated, so we need to delete and add later - $self->app->repo->authorships_delete($src_authorship); - # Changing the authorship to point to a new author - $src_authorship->author($author_destination); - # store changes the authorship in the repo - $self->app->repo->authorships_save($src_authorship); - # Adding the authorship to the new author - $author_destination->add_authorship($src_authorship); + foreach my $src_authorship (@src_authorships) { + + # Removing the authorship from the source author + $src_authorship->author->remove_authorship($src_authorship); + + # authorships cannot be updated, so we need to delete and add later + $self->app->repo->authorships_delete($src_authorship); + + # Changing the authorship to point to a new author + $src_authorship->author($author_destination); + + # store changes the authorship in the repo + $self->app->repo->authorships_save($src_authorship); + + # Adding the authorship to the new author + $author_destination->add_authorship($src_authorship); } $author_source->memberships_clear; $author_source->set_master($author_destination); - + $self->app->repo->authors_save($author_destination); $self->app->repo->authors_save($author_source); @@ -300,18 +341,23 @@ sub merge_authors { ); } else { - $self->flash( msg => "An author cannot be merged with its self. ", msg_type => "danger" ); + $self->flash( + msg => "An author cannot be merged with its self. ", + msg_type => "danger" + ); } } else { - $self->flash( msg => "Authors cannot be merged. One or both authors do not exist.", msg_type => "danger" ); + $self->flash( + msg => "Authors cannot be merged. One or both authors do not exist.", + msg_type => "danger" + ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } - ############################################################################################################## sub edit_post { my $self = shift; @@ -320,55 +366,60 @@ sub edit_post { my $new_user_id = $self->param('new_user_id'); my $visibility = $self->param('visibility'); - my $author = $self->app->repo->authors_find( sub { $_->id == $id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $id }); - if ( defined $author ) { - if ( defined $new_master ) { + if (defined $author) { + if (defined $new_master) { - my $existing = $self->app->repo->authors_find( sub { ( $_->master cmp $new_master ) == 0 } ); + my $existing = $self->app->repo->authors_find( + sub { ($_->master cmp $new_master) == 0 }); - if ( !defined $existing ) { + if (!defined $existing) { $author->update_master_name($new_master); $self->app->repo->authors_save($author); - $self->flash( msg => "Master name has been updated successfully.", msg_type => "success" ); - $self->redirect_to( $self->url_for( 'edit_author', id => $author->id ) ); + $self->flash( + msg => "Master name has been updated successfully.", + msg_type => "success" + ); + $self->redirect_to($self->url_for('edit_author', id => $author->id)); } else { $self->flash( msg => "This master name is already taken by url_for( 'edit_author', id => $existing->id ) . "\">" + . $self->url_for('edit_author', id => $existing->id) . "\">" . $existing->master . ".", msg_type => "danger" ); - $self->redirect_to( $self->url_for( 'edit_author', id => $id ) ); + $self->redirect_to($self->url_for('edit_author', id => $id)); } - } - elsif ( defined $visibility ) { + elsif (defined $visibility) { $author->toggle_visibility; $self->app->repo->authors_save($author); } - elsif ( defined $new_user_id ) { + elsif (defined $new_user_id) { - my $existing_author = $self->app->repo->authors_find( sub { $_->uid eq $new_user_id } ); + my $existing_author + = $self->app->repo->authors_find(sub { $_->uid eq $new_user_id }); - if ( defined $existing_author ) { + if (defined $existing_author) { $self->flash( - msg => "Cannot add user ID $new_user_id. Such ID already exist. Maybe you wan to merge authors?", + msg => + "Cannot add user ID $new_user_id. Such ID already exist. Maybe you wan to merge authors?", msg_type => "warning" ); } else { - my $minion = $self->app->entityFactory->new_Author( uid => $new_user_id ); + my $minion = $self->app->entityFactory->new_Author(uid => $new_user_id); $author->add_minion($minion); $self->app->repo->authors_save($author); $self->app->repo->authors_save($minion); } } } - $self->redirect_to( $self->url_for( 'edit_author', id => $id ) ); + $self->redirect_to($self->url_for('edit_author', id => $id)); } ############################################################################################################## sub post_edit_membership_dates { @@ -378,34 +429,41 @@ sub post_edit_membership_dates { my $new_start = $self->param('new_start'); my $new_stop = $self->param('new_stop'); - my $author = $self->app->repo->authors_find( sub { $_->id == $master_id } ); - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $master_id }); + my $team = $self->app->repo->teams_find(sub { $_->id == $team_id }); - if ( $author and $team ) { + if ($author and $team) { my $search_mem = Membership->new( - author => $author->get_master, - team => $team, - author_id => $author->get_master->id, - team_id => $team->id - ); - my $membership = $self->app->repo->memberships_find( sub { $_->equals($search_mem) } ); + author => $author->get_master, + team => $team, + author_id => $author->get_master->id, + team_id => $team->id + ); + my $membership + = $self->app->repo->memberships_find(sub { $_->equals($search_mem) }); + + if ($membership) { - if( $membership ){ - $membership->start($new_start); $membership->stop($new_stop); - $self->app->repo->memberships_update($membership); - $self->flash( msg => "Membership updated successfully.", msg_type => "success" ); + $self->app->repo->memberships_update($membership); + $self->flash( + msg => "Membership updated successfully.", + msg_type => "success" + ); } - else{ - $self->flash( msg => "Cannot find membership.", msg_type => "danger" ); + else { + $self->flash(msg => "Cannot find membership.", msg_type => "danger"); } - $self->redirect_to( $self->url_for( 'edit_author', id => $author->id ) ); + $self->redirect_to($self->url_for('edit_author', id => $author->id)); return; } - - $self->flash( msg => "Cannot update membership: author or team not found.", msg_type => "danger" ); - $self->redirect_to( $self->get_referrer ); + + $self->flash( + msg => "Cannot update membership: author or team not found.", + msg_type => "danger" + ); + $self->redirect_to($self->get_referrer); } ############################################################################################################## @@ -413,16 +471,16 @@ sub delete_author { my $self = shift; my $id = $self->param('id'); - my $author = $self->app->repo->authors_find( sub { $_->{id} == $id } ); + my $author = $self->app->repo->authors_find(sub { $_->{id} == $id }); - if ( $author and $author->can_be_deleted() ) { + if ($author and $author->can_be_deleted()) { $self->delete_author_force(); } else { - $self->flash( msg => "Cannot delete author ID $id.", msg_type => "danger" ); + $self->flash(msg => "Cannot delete author ID $id.", msg_type => "danger"); } - $self->redirect_to( $self->url_for('all_authors') ); + $self->redirect_to($self->url_for('all_authors')); } ############################################################################################################## @@ -430,7 +488,7 @@ sub delete_author_force { my $self = shift; my $id = $self->param('id'); - my $author = $self->app->repo->authors_find( sub { $_->{id} == $id } ); + my $author = $self->app->repo->authors_find(sub { $_->{id} == $id }); if ($author) { @@ -438,45 +496,51 @@ sub delete_author_force { ## Deleting memberships my @memberships = $author->memberships_all; + # for each team, remove membership in this team - foreach my $membership ( @memberships ){ - $membership->team->remove_membership($membership); + foreach my $membership (@memberships) { + $membership->team->remove_membership($membership); } $self->app->repo->memberships_delete(@memberships); + # remove all memberships for this team $author->memberships_clear; ## Deleting authorships my @authorships = $author->authorships_all; + # for each team, remove authorship in this team - foreach my $authorship ( @authorships ){ - $authorship->entry->remove_authorship($authorship); + foreach my $authorship (@authorships) { + $authorship->entry->remove_authorship($authorship); } $self->app->repo->authorships_delete(@authorships); + # remove all authorships for this team $author->authorships_clear; # finally delete author $self->app->repo->authors_delete($author); - $self->app->logger->info( "Author " . $author->uid . " ID $id has been deleted." ); - $self->flash( msg => "Author " . $author->uid . " ID $id removed successfully.", msg_type => "success" ); + $self->app->logger->info( + "Author " . $author->uid . " ID $id has been deleted."); + $self->flash( + msg => "Author " . $author->uid . " ID $id removed successfully.", + msg_type => "success" + ); } else { - $self->flash( msg => "Cannot delete author ID $id.", msg_type => "danger" ); + $self->flash(msg => "Cannot delete author ID $id.", msg_type => "danger"); } - - $self->redirect_to( $self->url_for('all_authors') ); + $self->redirect_to($self->url_for('all_authors')); } - ############################################################################################################## ## do not use this on production! this is for making the tests faster!! sub delete_invisible_authors { my $self = shift; - my @authors = $self->app->repo->authors_filter( sub { !$_->is_visible } ); + my @authors = $self->app->repo->authors_filter(sub { !$_->is_visible }); foreach my $author (@authors) { @@ -484,34 +548,39 @@ sub delete_invisible_authors { ## Deleting memberships my @memberships = $author->memberships_all; + # for each team, remove membership in this team - foreach my $membership ( @memberships ){ - $membership->team->remove_membership($membership); + foreach my $membership (@memberships) { + $membership->team->remove_membership($membership); } $self->app->repo->memberships_delete(@memberships); + # remove all memberships for this team $author->memberships_clear; ## Deleting authorships my @authorships = $author->authorships_all; + # for each team, remove authorship in this team - foreach my $authorship ( @authorships ){ - # my $entry = $authorship->entry; - $authorship->entry->remove_authorship($authorship); - # $self->app->repo->entries_delete($entry); + foreach my $authorship (@authorships) { + + # my $entry = $authorship->entry; + $authorship->entry->remove_authorship($authorship); + + # $self->app->repo->entries_delete($entry); } $self->app->repo->authorships_delete(@authorships); + # remove all authorships for this team $author->authorships_clear; # finally delete author $self->app->repo->authors_delete($author); - $self->flash( msg => "Authors decimated! ", msg_type => "success" ); + $self->flash(msg => "Authors decimated! ", msg_type => "success"); } - - $self->redirect_to( $self->url_for('all_authors') ); + $self->redirect_to($self->url_for('all_authors')); } @@ -520,12 +589,15 @@ sub reassign_authors_to_entries { my $self = shift; my $create_new = shift // 0; - my @all_entries = $self->app->repo->entries_all; - my $num_authors_created = Freassign_authors_to_entries_given_by_array($self->app, $create_new, \@all_entries); + my @all_entries = $self->app->repo->entries_all; + my $num_authors_created + = Freassign_authors_to_entries_given_by_array($self->app, $create_new, + \@all_entries); - $self->flash( msg => - "Reassignment with author creation has finished. $num_authors_created authors have been created or assigned." ); - $self->redirect_to( $self->get_referrer ); + $self->flash(msg => + "Reassignment with author creation has finished. $num_authors_created authors have been created or assigned." + ); + $self->redirect_to($self->get_referrer); } ############################################################################################################## sub reassign_authors_to_entries_and_create_authors { @@ -536,57 +608,70 @@ sub reassign_authors_to_entries_and_create_authors { sub fix_masters { my $self = shift; - my @all_authors = $self->app->repo->authors_all; + my @all_authors = $self->app->repo->authors_all; + + my @broken_authors_0 + = grep { ($_->is_minion) and (!defined $_->masterObj) } @all_authors; - my @broken_authors_0 = grep { $_->is_minion and !defined $_->masterObj } @all_authors; # masterObj not set although it should be - my @broken_authors_1 = grep { !defined $_->masterObj and $_->master_id != $_->id } @all_authors; + my @broken_authors_1 + = grep { (!defined $_->masterObj) and ($_->master_id != $_->id) } @all_authors; + # masterObj set incorrectly - my @broken_authors_2 = grep { $_->masterObj and $_->master_id != $_->masterObj->id } @all_authors; + my @broken_authors_2 + = grep { $_->masterObj and $_->master_id != $_->masterObj->id } + @all_authors; my $num_fixes_0 = @broken_authors_0; my $num_fixes_1 = @broken_authors_1; my $num_fixes_2 = @broken_authors_2; - - my $msg_type = ($num_fixes_0 + $num_fixes_1 + $num_fixes_2) == 0 ? 'success' : 'danger'; + my $msg_type + = ($num_fixes_0 + $num_fixes_1 + $num_fixes_2) == 0 ? 'success' : 'danger'; my $msg = "Analysis is finished. Authors broken: "; # we cure all problems with the same medicine... - foreach my $author ( (@broken_authors_0, @broken_authors_1, @broken_authors_2) ){ - my $master = $self->app->repo->authors_find( sub { $_->id == $author->master_id } ); - if(defined $master){ + foreach my $author ((@broken_authors_0, @broken_authors_1, @broken_authors_2)) + { + my $master + = $self->app->repo->authors_find(sub { $_->id == $author->master_id }); + if (defined $master) { $author->masterObj($master); ++$num_fixes_0; ++$num_fixes_1; ++$num_fixes_2; } } - $msg .= "
Fixing is finished. Masters were re-added to the authors. Fixed: + $msg + .= "
Fixing is finished. Masters were re-added to the authors. Fixed: "; - - $self->flash( msg => $msg, msg_type => $msg_type ); - $self->redirect_to( $self->get_referrer ); + $self->flash(msg => $msg, msg_type => $msg_type); + $self->redirect_to($self->get_referrer); } ############################################################################################################## sub toggle_visibility { my $self = shift; my $id = $self->param('id'); - my $author = $self->app->repo->authors_find( sub { $_->id == $id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $id }); $author->toggle_visibility(); $self->app->repo->authors_update($author); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } ############################################################################################################## diff --git a/lib/BibSpace/Controller/Backup.pm b/lib/BibSpace/Controller/Backup.pm index e8881d9..10bc637 100644 --- a/lib/BibSpace/Controller/Backup.pm +++ b/lib/BibSpace/Controller/Backup.pm @@ -29,7 +29,6 @@ use Mojo::Base 'Mojolicious::Controller'; use Mojo::Base 'Mojolicious::Plugin::Config'; use Mojo::Log; - #################################################################################### sub index { my $self = shift; @@ -42,8 +41,8 @@ sub index { 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} ) + if ($backup->get_age->days + >= $self->app->config->{allow_delete_backups_older_than}) { $backup->allow_delete(1); } @@ -52,24 +51,21 @@ sub index { } } - $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 $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" - ); + if ($backup->is_healthy) { + $self->flash(msg_type => 'success', msg => "Backup created successfully"); } else { - $self->flash( msg_type => 'danger', msg => "Backup create failed!" ); + $self->flash(msg_type => 'danger', msg => "Backup create failed!"); } $self->redirect_to('backup_index'); } @@ -77,16 +73,13 @@ sub save { sub save_mysql { 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" - ); + if ($backup->is_healthy) { + $self->flash(msg_type => 'success', msg => "Backup created successfully"); } else { - $self->flash( msg_type => 'danger', msg => "Backup create failed!" ); + $self->flash(msg_type => 'danger', msg => "Backup create failed!"); } $self->redirect_to('backup_index'); } @@ -94,9 +87,9 @@ sub save_mysql { sub cleanup { my $self = shift; my $age_treshold - = $self->config->{backup_age_in_days_to_delete_automatically}; + = $self->config->{backup_age_in_days_to_delete_automatically}; - my $num_deleted = delete_old_backups( $self->app, $age_treshold ); + my $num_deleted = delete_old_backups($self->app, $age_treshold); $self->app->logger->info( "Deleting old backups. $num_deleted backups have been cleaned."); @@ -116,18 +109,18 @@ sub backup_download { 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 ) { - $self->app->logger->info( "Downloading backup " . $backup->uuid ); - $self->render_file( 'filepath' => $backup->get_path ); + 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 ); + $self->redirect_to($self->get_referrer); } } @@ -136,25 +129,22 @@ sub delete_backup { 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->get_age->days - >= $self->app->config->{allow_delete_backups_older_than} ) + 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 ) { + 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!" - ); + $self->app->logger->info("Deleting backup " . $backup->uuid); + $self->flash(msg_type => 'success', msg => "Backup id $uuid deleted!"); } catch { $self->flash( @@ -178,7 +168,7 @@ sub delete_backup { } $self->res->code(303); - $self->redirect_to( $self->url_for('backup_index') ); + $self->redirect_to($self->url_for('backup_index')); } #################################################################################### @@ -186,24 +176,23 @@ sub restore_backup { 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
-        . "
"; + = "Status:
"
+      . $self->app->repo->lr->get_summary_table
+      . "
"; $self->flash( msg_type => 'success', msg => - "Backup restored successfully. Database recreated, persistence layers in sync. $status" + "Backup restored successfully. Database recreated, persistence layers in sync. $status" ); } else { diff --git a/lib/BibSpace/Controller/Cron.pm b/lib/BibSpace/Controller/Cron.pm index 2d08bc2..f087ce6 100644 --- a/lib/BibSpace/Controller/Cron.pm +++ b/lib/BibSpace/Controller/Cron.pm @@ -13,11 +13,9 @@ use v5.16; #because of ~~ use strict; use warnings; - use BibSpace::Functions::FPublications; use BibSpace::Functions::BackupFunctions; - use Mojo::Base 'Mojolicious::Controller'; # use Mojo::UserAgent; @@ -34,7 +32,8 @@ sub index { use JSON -convert_blessed_universally; my $json_text - = JSON->new->allow_blessed(1)->convert_blessed(1)->utf8(1)->pretty(1)->encode( $self->app->preferences ); + = JSON->new->allow_blessed(1)->convert_blessed(1)->utf8(1)->pretty(1) + ->encode($self->app->preferences); say $json_text; $self->stash( @@ -43,7 +42,7 @@ sub index { lr_2 => $self->get_last_cron_run(2), lr_3 => $self->get_last_cron_run(3) ); - $self->render( template => 'display/cron' ); + $self->render(template => 'display/cron'); } ########################################################################################## sub cron { @@ -59,13 +58,16 @@ sub cron { $num_level = 2 if $level_param eq 'week' or $level_param eq '2'; $num_level = 3 if $level_param eq 'month' or $level_param eq '3'; - my $result = $self->cron_level($num_level); - if ( !$result ) { - $self->render( text => "Error 404. Incorrect cron job level: $level_param (numeric: $num_level)", status => 404 ); + if (!$result) { + $self->render( + text => + "Error 404. Incorrect cron job level: $level_param (numeric: $num_level)", + status => 404 + ); } else { - $self->render( text => $result, status => 200 ); + $self->render(text => $result, status => 200); } } @@ -74,30 +76,29 @@ sub cron_level { my $self = shift; my $level = shift; - - if ( !defined $level or $level < 0 or $level > 3 ) { + if ((!defined $level) or ($level < 0) or ($level > 3)) { return ""; } my $call_freq = 99999; - if ( $level == 0 ) { + if ($level == 0) { $call_freq = $self->config->{cron_day_freq_lock}; } - elsif ( $level == 1 ) { + elsif ($level == 1) { $call_freq = $self->config->{cron_night_freq_lock}; } - elsif ( $level == 2 ) { + elsif ($level == 2) { $call_freq = $self->config->{cron_week_freq_lock}; } - elsif ( $level == 3 ) { + elsif ($level == 3) { $call_freq = $self->config->{cron_month_freq_lock}; } else { # should never happen } - my $message_string = $self->cron_run( $level, $call_freq ); + my $message_string = $self->cron_run($level, $call_freq); # place to debug return $message_string; @@ -117,7 +118,7 @@ sub cron_run { my $last_call = $self->get_last_cron_run($level); # stupid library.... You need to convert units manually - if ( defined $last_call ) { + if (defined $last_call) { $last_call_hours = calc_hours($last_call); } my $left = $call_freq - $last_call_hours; @@ -125,7 +126,7 @@ sub cron_run { my $text_to_render; ############ Cron ACTIONS - if ( $last_call_hours < $call_freq ) { + if ($last_call_hours < $call_freq) { $text_to_render = "Cron level $level called too often. Last call $last_call_hours hours ago. Come back in $left hours\n"; return $text_to_render; @@ -137,25 +138,26 @@ sub cron_run { ############ Cron ACTIONS $self->app->logger->info("Cron level $level started"); - if ( $level == 0 ) { + if ($level == 0) { $self->do_cron_day(); } - elsif ( $level == 1 ) { - Mojo::IOLoop->stream( $self->tx->connection )->timeout(3600); + elsif ($level == 1) { + Mojo::IOLoop->stream($self->tx->connection)->timeout(3600); $self->do_cron_night(); } - elsif ( $level == 2 ) { - Mojo::IOLoop->stream( $self->tx->connection )->timeout(3600); + elsif ($level == 2) { + Mojo::IOLoop->stream($self->tx->connection)->timeout(3600); $self->do_cron_week(); } - elsif ( $level == 3 ) { - Mojo::IOLoop->stream( $self->tx->connection )->timeout(3600); + elsif ($level == 3) { + Mojo::IOLoop->stream($self->tx->connection)->timeout(3600); $self->do_cron_month(); } else { # do nothing } - # this may cause: [error] Unable to open file (bibspace_preferences.json) for storing : Permission denied at + +# 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"); @@ -165,7 +167,7 @@ sub cron_run { sub do_cron_day { my $self = shift; - my $backup1 = do_storable_backup( $self->app, "cron" ); + my $backup1 = do_storable_backup($self->app, "cron"); } ########################################################################################## @@ -175,16 +177,15 @@ sub do_cron_night { my @entries = $self->app->repo->entries_all; for my $e (@entries) { - $e->regenerate_html( 0, $self->app->bst, $self->app->bibtexConverter ); + $e->regenerate_html(0, $self->app->bst, $self->app->bibtexConverter); } } ########################################################################################## sub do_cron_week { my $self = shift; - - my $backup1 = do_mysql_backup( $self->app, "cron" ); - my $num_deleted = delete_old_backups( $self->app ); + my $backup1 = do_mysql_backup($self->app, "cron"); + my $num_deleted = delete_old_backups($self->app); } ########################################################################################## @@ -201,12 +202,13 @@ sub log_cron_usage { my $self = shift; my $level = shift; - my $now = DateTime->now->set_time_zone( $self->app->preferences->local_time_zone ); + my $now + = DateTime->now->set_time_zone($self->app->preferences->local_time_zone); my $fomatted_now = DateTime::Format::HTTP->format_datetime($now); say "Storing cron usage level '$level' as '$fomatted_now'."; - $self->app->preferences->cron_set( $level, $fomatted_now ); + $self->app->preferences->cron_set($level, $fomatted_now); } ########################################################################################## sub get_last_cron_run { @@ -214,20 +216,22 @@ sub get_last_cron_run { my $level = shift; # constant :P - my $long_time_ago = DateTime::Duration->new( years => 10 ); + my $long_time_ago = DateTime::Duration->new(years => 10); my $last_call_str = $self->app->preferences->cron_get($level); return $long_time_ago if !$last_call_str; - - my $now = DateTime->now->set_time_zone( $self->app->preferences->local_time_zone ); + my $now + = DateTime->now->set_time_zone($self->app->preferences->local_time_zone); my $last_call; try { $last_call = DateTime::Format::HTTP->parse_datetime($last_call_str); } catch { warn; - $self->app->logger->error("Cannot parse date of last cron usage. Parser got input: '$last_call_str', error: $_ "); + $self->app->logger->error( + "Cannot parse date of last cron usage. Parser got input: '$last_call_str', error: $_ " + ); }; return $long_time_ago if !$last_call; @@ -242,7 +246,6 @@ sub get_last_cron_run { # my $last_call_str = $self->app->preferences->cron_get($level); # return 0 if !$last_call_str; - # my $now = DateTime->now->set_time_zone($self->app->preferences->local_time_zone); # my $last_call; # try{ diff --git a/lib/BibSpace/Controller/Display.pm b/lib/BibSpace/Controller/Display.pm index ad7d7cd..c13f2f8 100644 --- a/lib/BibSpace/Controller/Display.pm +++ b/lib/BibSpace/Controller/Display.pm @@ -20,21 +20,21 @@ use BibSpace::Util::Statistics; ################################################################################# sub index { my $self = shift; - if ( $self->app->is_demo ) { - $self->session( user => 'demouser' ); - $self->session( user_name => 'demouser' ); + if ($self->app->is_demo) { + $self->session(user => 'demouser'); + $self->session(user_name => 'demouser'); } - $self->render( template => 'display/start' ); + $self->render(template => 'display/start'); } ################################################################################# sub test500 { my $self = shift; - $self->render( text => 'Oops 500.', status => 500 ); + $self->render(text => 'Oops 500.', status => 500); } ################################################################################# sub test404 { my $self = shift; - $self->render( text => 'Oops 404.', status => 404 ); + $self->render(text => 'Oops 404.', status => 404); } ################################################################################# sub get_log_lines { @@ -43,100 +43,115 @@ sub get_log_lines { my $type = shift; my $filter_re = shift; - - my $log_dir = Path::Tiny->new( $dir ); + my $log_dir = Path::Tiny->new($dir); my @file_list = $log_dir->children(qr/\.log$/); my @log_names = map { $_->basename('.log') } @file_list; my $log_2_read; - $log_2_read = $log_dir->child( $type . ".log" ) if defined $type; - $log_2_read = $file_list[0] if !$log_2_read or !$log_2_read->exists; + $log_2_read = $log_dir->child($type . ".log") if defined $type; + if ((!$log_2_read) or (!$log_2_read->exists)){ + $log_2_read = $file_list[0]; + } - die "No log file found " if !-e $log_2_read; # throw + die "No log file found " if (!-e $log_2_read); # throw - # my @lines = $log_2_read->lines( { count => -1 * $num } ); - # @lines = ( $num >= @lines ) ? reverse @lines : reverse @lines[ -$num .. -1 ]; + # my @lines = $log_2_read->lines( { count => -1 * $num } ); + # @lines = ( $num >= @lines ) ? reverse @lines : reverse @lines[ -$num .. -1 ]; my @lines = $log_2_read->lines(); + # @lines = reverse @lines; chomp(@lines); - if( $filter_re ){ - @lines = grep{ m/$filter_re/ } @lines; + if ($filter_re) { + @lines = grep {m/$filter_re/} @lines; } - return @lines[-$num..-1]; + return @lines[-$num .. -1]; } ################################################################################# sub show_log { - my $self = shift; - my $num = $self->param('num') // 100; - my $type = $self->param('type') // 'general'; # default + my $self = shift; + my $num = $self->param('num') // 100; + my $type = $self->param('type') // 'general'; # default my $filter = $self->param('filter'); - my @lines; - try{ - @lines = get_log_lines( $self->app->get_log_dir, $num, $type, $filter ); + try { + @lines = get_log_lines($self->app->get_log_dir, $num, $type, $filter); } - catch{ + catch { $self->app->logger->error("Cannot find log '$type'. Error: $_."); - $self->stash( msg_type => 'danger', msg => "Cannot find log '$type'." ); + $self->stash(msg_type => 'danger', msg => "Cannot find log '$type'."); }; - my @file_list = Path::Tiny->new( $self->app->get_log_dir )->children(qr/\.log$/); - my $curr_file = Path::Tiny->new( $self->app->get_log_dir )->child('general.log'); + my @file_list + = Path::Tiny->new($self->app->get_log_dir)->children(qr/\.log$/); + my $curr_file + = Path::Tiny->new($self->app->get_log_dir)->child('general.log'); - $self->stash( files => \@file_list, lines => \@lines, curr_file => $curr_file, num => $num); - $self->render( template => 'display/log' ); + $self->stash( + files => \@file_list, + lines => \@lines, + curr_file => $curr_file, + num => $num + ); + $self->render(template => 'display/log'); } ################################################################################# sub show_log_ws { my $self = shift; - my $num = $self->param('num') // 20; - - - $self->on(message => sub { - my ($self, $filter) = @_; - - my @lines = get_log_lines( $self->app->get_log_dir, $num, 'general', $filter ); - $self->send( Mojo::JSON::encode_json( \@lines ) ); - }); - - $self->on(finish => sub { - my ($c, $code, $reason) = @_; - say "show_log_ws WS closed"; - }); + my $num = $self->param('num') // 20; + + $self->on( + message => sub { + my ($self, $filter) = @_; + + my @lines + = get_log_lines($self->app->get_log_dir, $num, 'general', $filter); + $self->send(Mojo::JSON::encode_json(\@lines)); + } + ); + + $self->on( + finish => sub { + my ($c, $code, $reason) = @_; + say "show_log_ws WS closed"; + } + ); } ################################################################################# sub show_stats { my $self = shift; - my $num = $self->param('num') // 20; + my $num = $self->param('num') // 20; my @lines = $self->app->statistics->toLines; - $self->stash( lines => \@lines, num => $num); - $self->render( template => 'display/stats' ); + $self->stash(lines => \@lines, num => $num); + $self->render(template => 'display/stats'); } ################################################################################# sub show_stats_websocket { my $self = shift; - my $num = $self->param('num') // 20; - - - $self->on(message => sub { - my ($self, $filter) = @_; - - my @all_lines = $self->app->statistics->toLines; - my @lines = grep{ /$filter/} @all_lines; - $self->send( Mojo::JSON::encode_json( \@lines ) ); - }); - - $self->on(finish => sub { - my ($c, $code, $reason) = @_; - say "show_stats_websocket WS closed"; - }); + my $num = $self->param('num') // 20; + + $self->on( + message => sub { + my ($self, $filter) = @_; + + my @all_lines = $self->app->statistics->toLines; + my @lines = grep {/$filter/} @all_lines; + $self->send(Mojo::JSON::encode_json(\@lines)); + } + ); + + $self->on( + finish => sub { + my ($c, $code, $reason) = @_; + say "show_stats_websocket WS closed"; + } + ); } ################################################################################# diff --git a/lib/BibSpace/Controller/Helpers.pm b/lib/BibSpace/Controller/Helpers.pm index df81f00..4439fbe 100644 --- a/lib/BibSpace/Controller/Helpers.pm +++ b/lib/BibSpace/Controller/Helpers.pm @@ -4,13 +4,13 @@ use Data::Dumper; use utf8; use Text::BibTeX; # parsing bib files use DateTime; + # use File::Slurp; use v5.16; #because of ~~ use strict; use warnings; - use List::MoreUtils qw(any uniq); use BibSpace::Functions::Core; @@ -20,17 +20,16 @@ use BibSpace::Functions::FDB; use BibSpace::Functions::FPublications; - use base 'Mojolicious::Plugin'; sub register { - my ( $self, $app ) = @_; + my ($self, $app) = @_; - # this must be a helper, - # because smartIDprovider can be exchanged during system lifetime (e.g. restore backup), - # so the reference must always point to the currently valid id provider - # smartIDProvider must be instantiated INSIDE LayeredRepository +# this must be a helper, +# because smartIDprovider can be exchanged during system lifetime (e.g. restore backup), +# so the reference must always point to the currently valid id provider +# smartIDProvider must be instantiated INSIDE LayeredRepository $app->helper( smartIDProvider => sub { my $self = shift; @@ -38,10 +37,10 @@ sub register { } ); - # this must be a helper, - # because entityFactory can be exchanged during system lifetime (e.g. restore backup), - # so the reference must always point to the currently valid id provider - # entityFactory must be instantiated INSIDE LayeredRepository +# this must be a helper, +# because entityFactory can be exchanged during system lifetime (e.g. restore backup), +# so the reference must always point to the currently valid id provider +# entityFactory must be instantiated INSIDE LayeredRepository $app->helper( entityFactory => sub { my $self = shift; @@ -49,39 +48,36 @@ sub register { } ); - $app->helper( is_demo => sub { my $self = shift; return 1 if $self->config->{demo_mode}; - # say "helper->is_demo: run_in_demo_mode: ".$self->app->preferences->run_in_demo_mode; + +# say "helper->is_demo: run_in_demo_mode: ".$self->app->preferences->run_in_demo_mode; return 1 if $self->app->preferences->run_in_demo_mode == 1; return; } ); - $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( + 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 { - my $self = shift; + my $self = shift; my $bst_candidate_file = $self->app->home . '/lib/descartes2.bst'; - if ( defined $self->app->config->{bst_file} ) { + if (defined $self->app->config->{bst_file}) { $bst_candidate_file = $self->app->config->{bst_file}; return File::Spec->rel2abs($bst_candidate_file) if File::Spec->file_name_is_absolute($bst_candidate_file) @@ -96,7 +92,8 @@ sub register { $bst_candidate_file = $self->app->home . '/lib/descartes2.bst'; - return File::Spec->rel2abs($bst_candidate_file) if -e File::Spec->rel2abs($bst_candidate_file); + return File::Spec->rel2abs($bst_candidate_file) + if -e File::Spec->rel2abs($bst_candidate_file); $self->app->logger->error("Cannot find any valid bst file!"); return './bst-not-found.bst'; @@ -106,35 +103,39 @@ sub register { $app->helper( bibtexConverter => sub { my $self = shift; - try{ - my $class = $self->app->preferences->bibitex_html_converter; - Class::Load::load_class($class); - if($class->does('IHtmlBibtexConverter')){ - return $class->new( logger => $self->app->logger ); - } - die "Requested class '$class' does not implement interface 'IHtmlBibtexConverter'"; + try { + my $class = $self->app->preferences->bibitex_html_converter; + Class::Load::load_class($class); + if ($class->does('IHtmlBibtexConverter')) { + return $class->new(logger => $self->app->logger); + } + die + "Requested class '$class' does not implement interface 'IHtmlBibtexConverter'"; } - catch{ - $self->logger->error("Requested unknown type of bibitex_html_converter: '".$self->app->preferences->bibitex_html_converter."'. Error: $_."); + catch { + $self->logger->error( + "Requested unknown type of bibitex_html_converter: '" + . $self->app->preferences->bibitex_html_converter + . "'. Error: $_."); } - finally{ - return BibStyleConverter->new( logger => $self->app->logger ); + finally { + return BibStyleConverter->new(logger => $self->app->logger); }; } ); - $app->helper( - get_referrer => sub { - my $self = shift; - return $self->get_referrer_old; - } + get_referrer => sub { + my $self = shift; + return $self->get_referrer_old; + } ); $app->helper( get_referrer_new => sub { my $self = shift; my $ret = $self->req->headers->referrer; + # $ret //= $self->url_for('start'); return $ret; } @@ -144,38 +145,36 @@ sub register { my $s = shift; my $ret = $s->url_for('start'); $ret = $s->req->headers->referrer - if defined $s->req->headers->referrer - and $s->req->headers->referrer ne ''; + if defined $s->req->headers->referrer + and $s->req->headers->referrer ne ''; return $ret; } ); - $app->helper( - is_manager => sub { - my $self = shift; - return 1 if $self->app->is_demo; - return if !$self->session('user'); - my $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } ); - return if !$me; - return $me->is_manager; - } + is_manager => sub { + my $self = shift; + return 1 if $self->app->is_demo; + return if !$self->session('user'); + my $me = $self->app->repo->users_find( + sub { $_->login eq $self->session('user') }); + return if !$me; + return $me->is_manager; + } ); $app->helper( - is_admin => sub { - my $self = shift; - return 1 if $self->app->is_demo; - return if !$self->session('user'); - my $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } ); - return if !$me; - return $me->is_admin; - } + is_admin => sub { + my $self = shift; + return 1 if $self->app->is_demo; + return if !$self->session('user'); + my $me = $self->app->repo->users_find( + sub { $_->login eq $self->session('user') }); + return if !$me; + return $me->is_admin; + } ); - $app->helper( current_year => sub { return BibSpace::Functions::Core::get_current_year(); @@ -189,19 +188,21 @@ sub register { $app->helper( get_year_of_oldest_entry => sub { - my $self = shift; + my $self = shift; my $author = shift; my @entries = $self->app->repo->entries_all; - if(defined $author){ + if (defined $author) { - my $author_obj = $self->app->repo->authors_find( sub {$_->get_master->uid eq $author} ); - $author_obj ||= $self->app->repo->authors_find( sub {$_->get_master->id eq $author} ); - if ($author_obj){ - @entries = $author_obj->get_entries; + my $author_obj = $self->app->repo->authors_find( + sub { $_->get_master->uid eq $author }); + $author_obj ||= $self->app->repo->authors_find( + sub { $_->get_master->id eq $author }); + if ($author_obj) { + @entries = $author_obj->get_entries; } - + } my @entryYears = map { $_->year } grep { defined $_->year } @entries; @@ -211,37 +212,38 @@ sub register { } ); - $app->helper( num_pubs => sub { - my $self = shift; - my $type = shift; - my $year = shift; + my $self = shift; + my $type = shift; + my $year = shift; my $entries_arr_ref = shift; my @entries; - if($entries_arr_ref){ + if ($entries_arr_ref) { @entries = @$entries_arr_ref; } - else{ - @entries = $self->app->repo->entries_all; + else { + @entries = $self->app->repo->entries_all; } - - if($type){ - @entries = grep {$_->entry_type eq $type} @entries; + + if ($type) { + @entries = grep { $_->entry_type eq $type } @entries; } - if($year){ - @entries = grep { defined $_->year and $_->year == $year and $_->hidden == 0 } @entries; + if ($year) { + @entries + = grep { defined $_->year and $_->year == $year and $_->hidden == 0 } + @entries; } return scalar @entries; - + } ); $app->helper( get_important_tag_types => sub { my $self = shift; - return $self->app->repo->tagTypes_filter(sub{$_->id < 4}); + return $self->app->repo->tagTypes_filter(sub { $_->id < 4 }); } ); @@ -249,7 +251,7 @@ sub register { get_tag_type_obj => sub { my $self = shift; my $type = shift // 1; - return $self->app->repo->tagTypes_find( sub { $_->id == $type } ); + return $self->app->repo->tagTypes_find(sub { $_->id == $type }); } ); @@ -259,9 +261,9 @@ sub register { my $eid = shift; my $type = shift // 1; - my $paper = $self->app->repo->entries_find( sub { $_->id == $eid } ); + my $paper = $self->app->repo->entries_find(sub { $_->id == $eid }); my @tags = $paper->get_tags($type); - @tags = sort {$a->name cmp $b->name} @tags; + @tags = sort { $a->name cmp $b->name } @tags; return @tags; } ); @@ -272,11 +274,11 @@ sub register { my $eid = shift; my $type = shift // 1; - my $paper = $self->app->repo->entries_find( sub { $_->id == $eid } ); - my %has_tags = map {$_ => 1} $paper->get_tags($type); - my @all_tags = $self->app->repo->tags_filter( sub{$_->type == $type} ); + my $paper = $self->app->repo->entries_find(sub { $_->id == $eid }); + my %has_tags = map { $_ => 1 } $paper->get_tags($type); + my @all_tags = $self->app->repo->tags_filter(sub { $_->type == $type }); my @unassigned = grep { not $has_tags{$_} } @all_tags; - @unassigned = sort {$a->name cmp $b->name} @unassigned; + @unassigned = sort { $a->name cmp $b->name } @unassigned; return @unassigned; } ); @@ -294,7 +296,7 @@ sub register { $app->helper( get_visible_authors => sub { my $self = shift; - return $self->app->repo->authors_filter( sub { $_->is_visible } ); + return $self->app->repo->authors_filter(sub { $_->is_visible }); } ); @@ -305,7 +307,6 @@ sub register { } ); - $app->helper( get_num_teams => sub { my $self = shift; @@ -313,17 +314,14 @@ sub register { } ); - $app->helper( num_tags => sub { my $self = shift; my $type = shift // 1; - return scalar $self->app->repo->tags_filter( sub { $_->type == $type } ); + return scalar $self->app->repo->tags_filter(sub { $_->type == $type }); } ); - - $app->helper( num_pubs_for_author_and_tag => sub { my $self = shift; @@ -331,11 +329,11 @@ sub register { my $tag = shift; return - scalar $author->authorships_filter( sub { defined $_ and defined $_->entry and $_->entry->has_tag($tag) } ); + scalar $author->authorships_filter( + sub { defined $_ and defined $_->entry and $_->entry->has_tag($tag) }); } ); - $app->helper( num_pubs_for_tag => sub { my $self = shift; diff --git a/lib/BibSpace/Controller/Login.pm b/lib/BibSpace/Controller/Login.pm index 5577cde..6cc19d7 100644 --- a/lib/BibSpace/Controller/Login.pm +++ b/lib/BibSpace/Controller/Login.pm @@ -6,559 +6,525 @@ use Mojo::Base 'Mojolicious::Plugin::Config'; use BibSpace::Model::User; use BibSpace::Functions::Core - qw(send_email generate_token salt encrypt_password check_password_policy validate_registration_data); - + qw(send_email generate_token salt encrypt_password check_password_policy validate_registration_data); use Data::Dumper; use Try::Tiny; - #################################################################################### # for _under_ -checking if user is logged in to access other pages sub check_is_logged_in { - my $self = shift; - return 1 if $self->app->is_demo; - - # no session - if( !defined $self->session('user')){ - $self->redirect_to('youneedtologin'); - return; - } + my $self = shift; + return 1 if $self->app->is_demo; - # session exists, but user unknown - my $me = $self->app->repo->users_find(sub { $_->login eq $self->session('user') } ); - if( !defined $me ){ - $self->session( expires => 1 ); - $self->redirect_to('youneedtologin'); - return; - } + # no session + if (!defined $self->session('user')) { + $self->redirect_to('youneedtologin'); + return; + } + + # session exists, but user unknown + my $me + = $self->app->repo->users_find(sub { $_->login eq $self->session('user') }); + if (!defined $me) { + $self->session(expires => 1); + $self->redirect_to('youneedtologin'); + return; + } - return 1; + return 1; } #################################################################################### # for _under_ -checking sub under_check_is_manager { - my $self = shift; - return 1 if $self->app->is_demo; - return $self->under_check_has_rank( User->manager_rank ); + my $self = shift; + return 1 if $self->app->is_demo; + return $self->under_check_has_rank(User->manager_rank); } #################################################################################### # for _under_ -checking sub under_check_is_admin { - my $self = shift; - return 1 if $self->app->is_demo; - return $self->under_check_has_rank( User->admin_rank ); + my $self = shift; + return 1 if $self->app->is_demo; + return $self->under_check_has_rank(User->admin_rank); } #################################################################################### # for _under_ -checking sub under_check_has_rank { - my $self = shift; - my $required_rank = shift; - - return 1 if $self->app->is_demo; + my $self = shift; + my $required_rank = shift; - my $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } ); + return 1 if $self->app->is_demo; - if ( $me and $me->rank >= $required_rank ) { - return 1; - } - - my $your_rank = 'undefined'; - $your_rank = $me->rank if $me; + my $me + = $self->app->repo->users_find(sub { $_->login eq $self->session('user') }); - $self->flash( - msg_type => 'danger', - msg => "You need to have rank '" - . $required_rank - . "' to access this page! " - . "Your rank is: '" - . $your_rank . "'" - . "
You have tried to access: " - . $self->url_for('current')->to_abs - ); - - my $redirect_to = $self->get_referrer; - - if ( $self->get_referrer eq $self->url_for('current')->to_abs ) { - $redirect_to = $self->url_for('/'); - } - $self->redirect_to($redirect_to); - return; + if ($me and $me->rank >= $required_rank) { + return 1; + } + + my $your_rank = 'undefined'; + $your_rank = $me->rank if $me; + + $self->flash( + msg_type => 'danger', + msg => "You need to have rank '" + . $required_rank + . "' to access this page! " + . "Your rank is: '" + . $your_rank . "'" + . "
You have tried to access: " + . $self->url_for('current')->to_abs + ); + + my $redirect_to = $self->get_referrer; + + if ($self->get_referrer eq $self->url_for('current')->to_abs) { + $redirect_to = $self->url_for('/'); + } + $self->redirect_to($redirect_to); + return; } #################################################################################### #################################################################################### #################################################################################### sub manage_users { - my $self = shift; - my $dbh = $self->app->db; + my $self = shift; + my $dbh = $self->app->db; - my @user_objs = $self->app->repo->users_all; - $self->stash( user_objs => \@user_objs ); - $self->render( template => 'login/manage_users' ); + my @user_objs = $self->app->repo->users_all; + $self->stash(user_objs => \@user_objs); + $self->render(template => 'login/manage_users'); } #################################################################################### sub promote_to_rank { - my $self = shift; - my $rank = shift; - - my $profile_id = $self->param('id'); - my $user_obj - = $self->app->repo->users_find( sub { $_->id == $profile_id } ); - - my $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } ); - - if ( $me->is_admin ) { - if ( $me->equals($user_obj) ) { - $self->flash( - msg_type => 'danger', - msg => "You cannot degrade yourself!" - ); - } - else { - $user_obj->rank($rank); - $self->app->repo->users_update($user_obj); - - my $msg - = "User '" . $user_obj->login . "'' has now rank '$rank'."; - $self->app->logger->info($msg); - $self->flash( msg_type => 'success', msg => $msg ); - } + my $self = shift; + my $rank = shift; + + my $profile_id = $self->param('id'); + my $user_obj = $self->app->repo->users_find(sub { $_->id == $profile_id }); + + my $me + = $self->app->repo->users_find(sub { $_->login eq $self->session('user') }); + + if ($me->is_admin) { + if ($me->equals($user_obj)) { + $self->flash(msg_type => 'danger', msg => "You cannot degrade yourself!"); } else { - $self->flash( - msg_type => 'danger', - msg => "Only admins can promote/degrade users!" - ); + $user_obj->rank($rank); + $self->app->repo->users_update($user_obj); + + my $msg = "User '" . $user_obj->login . "'' has now rank '$rank'."; + $self->app->logger->info($msg); + $self->flash(msg_type => 'success', msg => $msg); } - $self->redirect_to('manage_users'); + } + else { + $self->flash( + msg_type => 'danger', + msg => "Only admins can promote/degrade users!" + ); + } + $self->redirect_to('manage_users'); } #################################################################################### sub make_user { - my $self = shift; - return $self->promote_to_rank( User->user_rank ); + my $self = shift; + return $self->promote_to_rank(User->user_rank); } #################################################################################### sub make_manager { - my $self = shift; - return $self->promote_to_rank( User->manager_rank ); + my $self = shift; + return $self->promote_to_rank(User->manager_rank); } #################################################################################### sub make_admin { - my $self = shift; - return $self->promote_to_rank( User->admin_rank ); + my $self = shift; + return $self->promote_to_rank(User->admin_rank); } #################################################################################### sub delete_user { - my $self = shift; - my $profile_id = $self->param('id'); + my $self = shift; + my $profile_id = $self->param('id'); - my $user_obj - = $self->app->repo->users_find( sub { $_->id == $profile_id } ); - my $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } ); - - - if ( $me and !$me->is_admin ) { - $self->flash( msg_type => 'danger', msg => 'You are not admin!' ); - $self->redirect_to('manage_users'); - return; - } - if ( $user_obj and $user_obj->is_admin ) { - $self->flash( - msg_type => 'danger', - msg => 'You cannot delete admin user!' - ); - $self->redirect_to('manage_users'); - return; - } - if ( $user_obj and $user_obj->equals($me) ) { - $self->flash( - msg_type => 'danger', - msg => 'You cannot delete yourself!' - ); - $self->redirect_to('manage_users'); - return; - } - if ($user_obj) { - $self->app->repo->users_delete($user_obj); - my $msg - = "User '$user_obj->{login}' real name: '$user_obj->{real_name}' has been deleted."; - $self->app->logger->info($msg); - $self->flash( msg_type => 'success', msg => $msg ); - } - else { - my $msg - = "Cannot delete user. Reason: cannot find user with ID '$profile_id'."; - $self->app->logger->info($msg); - $self->flash( msg_type => 'danger', msg => $msg ); - } + my $user_obj = $self->app->repo->users_find(sub { $_->id == $profile_id }); + my $me + = $self->app->repo->users_find(sub { $_->login eq $self->session('user') }); + if ($me and (!$me->is_admin)) { + $self->flash(msg_type => 'danger', msg => 'You are not admin!'); + $self->redirect_to('manage_users'); + return; + } + if ($user_obj and $user_obj->is_admin) { + $self->flash(msg_type => 'danger', msg => 'You cannot delete admin user!'); + $self->redirect_to('manage_users'); + return; + } + if ($user_obj and $user_obj->equals($me)) { + $self->flash(msg_type => 'danger', msg => 'You cannot delete yourself!'); $self->redirect_to('manage_users'); + return; + } + if ($user_obj) { + $self->app->repo->users_delete($user_obj); + my $msg + = "User '$user_obj->{login}' real name: '$user_obj->{real_name}' has been deleted."; + $self->app->logger->info($msg); + $self->flash(msg_type => 'success', msg => $msg); + } + else { + my $msg + = "Cannot delete user. Reason: cannot find user with ID '$profile_id'."; + $self->app->logger->info($msg); + $self->flash(msg_type => 'danger', msg => $msg); + } + + $self->redirect_to('manage_users'); } #################################################################################### sub foreign_profile { - my $self = shift; - my $profile_id = $self->param('id'); - my $user_obj - = $self->app->repo->users_find( sub { $_->id == $profile_id } ); + my $self = shift; + my $profile_id = $self->param('id'); + my $user_obj = $self->app->repo->users_find(sub { $_->id == $profile_id }); - $self->stash( usrobj => $user_obj ); - $self->render( template => 'login/profile' ); + $self->stash(usrobj => $user_obj); + $self->render(template => 'login/profile'); } #################################################################################### sub profile { - my $self = shift; - my $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } ); + my $self = shift; + my $me + = $self->app->repo->users_find(sub { $_->login eq $self->session('user') }); - $self->stash( usrobj => $me ); - $self->render( template => 'login/profile' ); + $self->stash(usrobj => $me); + $self->render(template => 'login/profile'); } #################################################################################### sub index { - my $self = shift; - $self->render( template => 'login/index' ); + my $self = shift; + $self->render(template => 'login/index'); } #################################################################################### sub forgot { - my $self = shift; - $self->app->logger->info("Forgot password form opened"); - $self->render( template => 'login/forgot_request' ); + my $self = shift; + $self->app->logger->info("Forgot password form opened"); + $self->render(template => 'login/forgot_request'); } #################################################################################### sub post_gen_forgot_token { - my $self = shift; + my $self = shift; # this is called when a user fills the form called "Recovery of forgotten password" - my $login = $self->param('user'); - my $email = $self->param('email'); + my $login = $self->param('user'); + my $email = $self->param('email'); + + my $user; + if ($login) { + $self->app->logger->info( + "Request to generate forgot-password-token for login '$login'."); + $user = $self->app->repo->users_find(sub { $_->login eq $login }); + } + if ($email) { + $self->app->logger->info( + "Request to generate forgot-password-token for email '$email'."); + $user = $self->app->repo->users_find(sub { $_->email eq $email }); + } + if (!$user) { + $self->app->logger->warn( + "Cannot find user '$login' nor email '$email' to generate forgot-password-token." + ); + $self->flash( + msg_type => 'warning', + msg => "User '$login' or email '$email' does not exist. Try again." + ); + $self->redirect_to('forgot'); + return; + } + else { + # store token in the user object + $user->forgot_token(generate_token); - my $user; - if ($login) { - $self->app->logger->info( - "Request to generate forgot-password-token for login '$login'."); - $user = $self->app->repo->users_find( sub { $_->login eq $login } ); - } - if ($email) { - $self->app->logger->info( - "Request to generate forgot-password-token for email '$email'."); - $user = $self->app->repo->users_find( sub { $_->email eq $email } ); + my $email_content = $self->render_to_string('email_forgot_password', + token => $user->forgot_token); + try { + my %email_config = ( + mailgun_domain => $self->app->config->{mailgun_domain}, + mailgun_key => $self->app->config->{mailgun_key}, + from => $self->app->config->{mailgun_from}, + to => $user->email, + content => $email_content, + subject => 'BibSpace password reset request' + ); + send_email(\%email_config); } + catch { + $self->app->logger->warn( + "Could not sent Email with Mailgun. This is okay for test, but not for production. Error: $_ ." + ); + }; + $self->app->logger->info("Forgot-password-token '" + . $user->forgot_token + . "' sent to '" + . $user->email + . "'."); - if ( !$user ) { - $self->app->logger->warn( - "Cannot find user '$login' nor email '$email' to generate forgot-password-token."); - $self->flash( - msg_type => 'warning', - msg => "User '$login' or email '$email' does not exist. Try again." - ); - $self->redirect_to('forgot'); - return; - } - else { - # store token in the user object - $user->forgot_token(generate_token); - - my $email_content = $self->render_to_string( 'email_forgot_password', - token => $user->forgot_token ); - try { - my %email_config = ( - mailgun_domain => $self->app->config->{mailgun_domain}, - mailgun_key => $self->app->config->{mailgun_key}, - from => $self->app->config->{mailgun_from}, - to => $user->email, - content => $email_content, - subject => 'BibSpace password reset request' - ); - send_email( \%email_config ); - } - catch { - $self->app->logger->warn( - "Could not sent Email with Mailgun. This is okay for test, but not for production. Error: $_ ." - ); - }; - - $self->app->logger->info( "Forgot-password-token '" - . $user->forgot_token - . "' sent to '" - . $user->email - . "'." ); - - $self->flash( - msg_type => 'info', - msg => - "Email with password reset instructions has been sent. Expect an email from " - . $self->app->config->{mailgun_from} - ); - $self->redirect_to('/'); + $self->flash( + msg_type => 'info', + msg => + "Email with password reset instructions has been sent. Expect an email from " + . $self->app->config->{mailgun_from} + ); + $self->redirect_to('/'); - } + } - $self->redirect_to('forgot'); + $self->redirect_to('forgot'); } #################################################################################### sub token_clicked { - my $self = shift; - my $token = $self->param('token'); + my $self = shift; + my $token = $self->param('token'); - $self->app->logger->info("Reset token clicked '$token'"); - $self->stash( token => $token ); - $self->render( template => 'login/set_new_password' ); + $self->app->logger->info("Reset token clicked '$token'"); + $self->stash(token => $token); + $self->render(template => 'login/set_new_password'); } #################################################################################### sub store_password { - my $self = shift; - my $token = $self->param('token'); - my $pass1 = $self->param('pass1'); - my $pass2 = $self->param('pass2'); - - # search for user that has this token - my $user; - if ($token) { - $user = $self->app->repo->users_find( - sub { defined $_->forgot_token and $_->forgot_token eq $token } ); - } + my $self = shift; + my $token = $self->param('token'); + my $pass1 = $self->param('pass1'); + my $pass2 = $self->param('pass2'); + + # search for user that has this token + my $user; + if ($token) { + $user = $self->app->repo->users_find( + sub { defined $_->forgot_token and $_->forgot_token eq $token }); + } + + if (!$user) { + $self->app->logger->warn( + "Forgot: Reset password token is invalid! Token: '$token'"); + $self->flash( + msg_type => 'danger', + msg => + 'Reset password token is invalid! Make sure you click the newest token that you requested.' + ); + $self->redirect_to('login_form'); + return; + } + if ($pass1 eq $pass2 and check_password_policy($pass1)) { - if ( !$user ) { - $self->app->logger->warn( - "Forgot: Reset password token is invalid! Token: '$token'"); - $self->flash( - msg_type => 'danger', - msg => - 'Reset password token is invalid! Make sure you click the newest token that you requested.' - ); - $self->redirect_to('login_form'); - return; - } - + my $salt = salt(); + my $hash = encrypt_password($pass1, $salt); + $user->pass($pass1); + $user->pass2($salt); + $user->forgot_token(""); + $self->flash( + msg_type => 'success', + msg => + 'Password change successful. All your password reset tokens have been removed. You may login now.' + ); + $self->app->logger->info( + "Forgot: Password change successful for token $token."); + $self->redirect_to('login_form'); + return; + } - if ( $pass1 eq $pass2 and check_password_policy($pass1) ) { - - my $salt = salt(); - my $hash = encrypt_password( $pass1, $salt ); - $user->pass($pass1); - $user->pass2($salt); - $user->forgot_token(""); - $self->flash( - msg_type => 'success', - msg => - 'Password change successful. All your password reset tokens have been removed. You may login now.' - ); - $self->app->logger->info( - "Forgot: Password change successful for token $token."); - $self->redirect_to('login_form'); - return; - } - - my $msg - = 'Passwords are not same or do not obey the password policy. Please try again.'; - $self->flash( msg => $msg, msg_type => 'warning' ); - $self->app->logger->info($msg); - $self->stash( token => $token ); - $self->redirect_to( 'token_clicked', token => $token ); + my $msg + = 'Passwords are not same or do not obey the password policy. Please try again.'; + $self->flash(msg => $msg, msg_type => 'warning'); + $self->app->logger->info($msg); + $self->stash(token => $token); + $self->redirect_to('token_clicked', token => $token); } #################################################################################### sub login { - my $self = shift; - my $input_login = $self->param('user'); - my $input_pass = $self->param('pass'); - - if ( !$input_login or !$input_pass ) { - $self->flash( - msg_type => 'warning', - msg => 'Please provide user-name and password.' - ); - $self->redirect_to( $self->url_for('login_form') ); - return; - } - - $self->app->logger->info("Trying to login as user '$input_login'"); + my $self = shift; + my $input_login = $self->param('user'); + my $input_pass = $self->param('pass'); - # get the user with login - my $user = $self->app->repo->users_find( - sub { $_->login eq $input_login } + if ((!$input_login) or (!$input_pass)) { + $self->flash( + msg_type => 'warning', + msg => 'Please provide user-name and password.' ); - - - my $auth_result; - if ( defined $user ){ - $self->app->logger->info("User '$input_login' exists."); - $auth_result = $user->authenticate($input_pass); - } + $self->redirect_to($self->url_for('login_form')); + return; + } - - if ( defined $user and $auth_result and $auth_result == 1){ - $self->session( user => $user->login ); - $self->session( user_name => $user->real_name ); - $self->session(url_history => []); - - $user->record_logging_in; - - $self->app->logger->info("Login as '$input_login' success."); - $self->redirect_to('/'); - return; - } - else { - $self->app->logger->info("User '$input_login' does not exist."); - $self->app->logger->info( - "Wrong user name or password for '$input_login'."); - $self->flash( - msg_type => 'danger', - msg => 'Wrong user name or password' - ); - $self->redirect_to( $self->url_for('login_form') ); - return; - } + $self->app->logger->info("Trying to login as user '$input_login'"); + + # get the user with login + my $user = $self->app->repo->users_find(sub { $_->login eq $input_login }); + + my $auth_result; + if (defined $user) { + $self->app->logger->info("User '$input_login' exists."); + $auth_result = $user->authenticate($input_pass); + } + + if (defined $user and $auth_result and $auth_result == 1) { + $self->session(user => $user->login); + $self->session(user_name => $user->real_name); + $self->session(url_history => []); + + $user->record_logging_in; + + $self->app->logger->info("Login as '$input_login' success."); + $self->redirect_to('/'); + return; + } + else { + $self->app->logger->info("User '$input_login' does not exist."); + $self->app->logger->info("Wrong user name or password for '$input_login'."); + $self->flash(msg_type => 'danger', msg => 'Wrong user name or password'); + $self->redirect_to($self->url_for('login_form')); + return; + } } #################################################################################### sub login_form { - my $self = shift; - $self->app->logger->info("Displaying login form."); - $self->render( template => 'login/index' ); + my $self = shift; + $self->app->logger->info("Displaying login form."); + $self->render(template => 'login/index'); } #################################################################################### sub bad_password { - my $self = shift; + my $self = shift; - $self->app->logger->info("Bad user name or password! (/badpassword)"); + $self->app->logger->info("Bad user name or password! (/badpassword)"); - $self->flash( - msg_type => 'danger', - msg => 'Wrong user name or password' - ); - $self->redirect_to( $self->url_for('login_form') ); + $self->flash(msg_type => 'danger', msg => 'Wrong user name or password'); + $self->redirect_to($self->url_for('login_form')); } #################################################################################### sub not_logged_in { - my $self = shift; + my $self = shift; - $self->app->logger->info( - "Called a page that requires login but user is not logged in. Redirecting to login." - ); + $self->app->logger->info( + "Called a page that requires login but user is not logged in. Redirecting to login." + ); - $self->flash( msg_type => 'danger', msg => 'You need to login first.' ); - $self->redirect_to( $self->url_for('login_form') ); + $self->flash(msg_type => 'danger', msg => 'You need to login first.'); + $self->redirect_to($self->url_for('login_form')); } #################################################################################### sub logout { - my $self = shift; - $self->app->logger->info("User logs out"); + my $self = shift; + $self->app->logger->info("User logs out"); - $self->session( expires => 1 ); - $self->redirect_to( $self->url_for('start') ); + $self->session(expires => 1); + $self->redirect_to($self->url_for('start')); } #################################################################################### sub register_disabled { - my $self = shift; - $self->app->logger->info( - "Login: informing that registration is disabled."); - $self->render( template => 'login/noregister' ); + my $self = shift; + $self->app->logger->info("Login: informing that registration is disabled."); + $self->render(template => 'login/noregister'); } #################################################################################### sub can_register { - my $self = shift; - my $registration_enabled = $self->app->config->{registration_enabled}; - - return 1 if $registration_enabled == 1; - my $me; - if ( $self->session('user') ) { - $me = $self->app->repo->users_find( - sub { $_->login eq $self->session('user') } - ); - } - return 1 if $me and $me->is_admin; - return; + my $self = shift; + my $registration_enabled = $self->app->config->{registration_enabled}; + + return 1 if $registration_enabled == 1; + my $me; + if ($self->session('user')) { + $me + = $self->app->repo->users_find(sub { $_->login eq $self->session('user') } + ); + } + return 1 if $me and $me->is_admin; + return; } #################################################################################### sub register { - my $self = shift; - - - if ( $self->can_register ) { - $self->stash( - name => 'James Bond', - email => 'test@example.com', - login => 'j.bond007', - password1 => '', - password2 => '' - ); - $self->render( template => 'login/register' ); - return; - } - else { - $self->redirect_to('/noregister'); - } + my $self = shift; + + if ($self->can_register) { + $self->stash( + name => 'James Bond', + email => 'test@example.com', + login => 'j.bond007', + password1 => '', + password2 => '' + ); + $self->render(template => 'login/register'); + return; + } + else { + $self->redirect_to('/noregister'); + } } #################################################################################### sub post_do_register { - my $self = shift; - my $config = $self->app->config; - my $login = $self->param('login'); - my $name = $self->param('name'); - my $email = $self->param('email'); - my $password1 = $self->param('password1'); - my $password2 = $self->param('password2'); - - - if ( !$self->can_register ) { - $self->redirect_to('/noregister'); - return; - } - - - $self->app->logger->info( - "Received registration data. Login: '$login', email: '$email'."); + my $self = shift; + my $config = $self->app->config; + my $login = $self->param('login'); + my $name = $self->param('name'); + my $email = $self->param('email'); + my $password1 = $self->param('password1'); + my $password2 = $self->param('password2'); + + if (!$self->can_register) { + $self->redirect_to('/noregister'); + return; + } + + $self->app->logger->info( + "Received registration data. Login: '$login', email: '$email'."); + + try { + # this throws on failure + validate_registration_data($login, $email, $password1, $password2); + my $existing_user + = $self->app->repo->users_find(sub { $_->login eq $login }); + die "This login is already taken.\n" if $existing_user; + + my $salt = salt(); + my $hash = encrypt_password($password1, $salt); + my $new_user = $self->app->entityFactory->new_User( + login => $login, + email => $email, + real_name => $name, + pass => $hash, + pass2 => $salt + ); + $self->app->repo->users_save($new_user); - try { - # this throws on failure - validate_registration_data( $login, $email, $password1, $password2 ); - my $existing_user - = $self->app->repo->users_find( sub { $_->login eq $login } ); - die "This login is already taken.\n" if $existing_user; - - my $salt = salt(); - my $hash = encrypt_password( $password1, $salt ); - my $new_user = $self->app->entityFactory->new_User( - login => $login, - email => $email, - real_name => $name, - pass => $hash, - pass2 => $salt - ); - $self->app->repo->users_save($new_user); - - $self->flash( - msg_type => 'success', - msg => - "User created successfully! You may now login using login: $login." - ); - $self->redirect_to('/'); - } - catch { - my $failure_reason = $_; - $self->app->logger->warn($failure_reason); - $self->flash( msg_type => 'danger', msg => $failure_reason ); - $self->stash( - name => $name, - email => $email, - login => $login, - password1 => $password1, - password2 => $password2 - ); - $self->redirect_to('register'); - }; + $self->flash( + msg_type => 'success', + msg => "User created successfully! You may now login using login: $login." + ); + $self->redirect_to('/'); + } + catch { + my $failure_reason = $_; + $self->app->logger->warn($failure_reason); + $self->flash(msg_type => 'danger', msg => $failure_reason); + $self->stash( + name => $name, + email => $email, + login => $login, + password1 => $password1, + password2 => $password2 + ); + $self->redirect_to('register'); + }; } #################################################################################### 1; diff --git a/lib/BibSpace/Controller/Persistence.pm b/lib/BibSpace/Controller/Persistence.pm index fdeae4e..2b9c223 100644 --- a/lib/BibSpace/Controller/Persistence.pm +++ b/lib/BibSpace/Controller/Persistence.pm @@ -18,18 +18,17 @@ use BibSpace::Functions::FDB; use Mojo::Base 'Mojolicious::Controller'; - ################################################################################# sub persistence_status { my $self = shift; 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 ); + = "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); } ################################################################################# @@ -37,38 +36,35 @@ sub persistence_status_ajax { my $self = shift; my $status - = "Status:
"
-      . $self->app->repo->lr->get_summary_table
-      . "
"; - $self->render( text => $status ); + = "Status:
"
+    . $self->app->repo->lr->get_summary_table
+    . "
"; + $self->render(text => $status); } ################################################################################# sub load_fixture { my $self = shift; - 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_file = $self->app->home->rel_file('fixture/bibspace_fixture.dat'); + $self->app->logger->info("Loading fixture from: " . $fixture_file->to_string); my $fixture = Backup->new( dir => '' . $fixture_file->dirname, filename => '' . $fixture_file->basename ); - restore_storable_backup( $fixture, $self->app ); + restore_storable_backup($fixture, $self->app); my $status - = "Status:
"
-      . $self->app->repo->lr->get_summary_table
-      . "
"; + = "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 ); + $self->redirect_to($self->get_referrer); } ################################################################################# sub save_fixture { @@ -76,69 +72,59 @@ sub save_fixture { $self->app->logger->warn("PERSISTENCE CONTROLLER does: save_fixture"); - my $fixture_file - = $self->app->home->rel_file('fixture/bibspace_fixture.dat'); + 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 $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. Storable::store $layer, $path; my $status - = "Status:
"
-      . $self->app->repo->lr->get_summary_table
-      . "
"; + = "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 ); + $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->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" - ); - $self->redirect_to( $self->get_referrer ); + = "Status:
"
+    . $self->app->repo->lr->get_summary_table
+    . "
"; + $self->flash(msg_type => 'success', msg => "Copied mysql => smart. $status"); + $self->redirect_to($self->get_referrer); } ################################################################################# sub copy_smart_to_mysql { my $self = shift; - - $self->app->repo->lr->copy_data( { from => '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" - ); - $self->redirect_to( $self->get_referrer ); + = "Status:
"
+    . $self->app->repo->lr->get_summary_table
+    . "
"; + $self->flash(msg_type => 'success', msg => "Copied smart => mysql. $status"); + $self->redirect_to($self->get_referrer); } ################################################################################# @@ -148,7 +134,7 @@ 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', @@ -159,19 +145,20 @@ sub insert_random_data { ); $self->app->repo->users_save($obj); - $obj = $self->app->entityFactory->new_Author( - uid => random_string($str_len), ); + $obj + = $self->app->entityFactory->new_Author(uid => random_string($str_len),); $self->app->repo->authors_save($obj); - $obj = $self->app->entityFactory->new_Entry( - bib => random_string($str_len), ); + $obj + = $self->app->entityFactory->new_Entry(bib => random_string($str_len),); $self->app->repo->entries_save($obj); - $obj = $self->app->entityFactory->new_TagType( - name => random_string($str_len), ); + $obj + = $self->app->entityFactory->new_TagType(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), @@ -179,21 +166,17 @@ sub insert_random_data { ); $self->app->repo->tags_save($obj); - - $obj = $self->app->entityFactory->new_Team( - name => random_string($str_len), ); + $obj + = $self->app->entityFactory->new_Team(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" - ); - $self->redirect_to( $self->get_referrer ); + = "Status:
"
+    . $self->app->repo->lr->get_summary_table
+    . "
"; + $self->flash(msg_type => 'success', msg => "Copied smart => mysql. $status"); + $self->redirect_to($self->get_referrer); } ################################################################################# sub reset_smart { @@ -213,15 +196,14 @@ sub reset_smart { $self->app->preferences->run_in_demo_mode(1); say "setting preferences->run_in_demo_mode to: '" - . $self->app->preferences->run_in_demo_mode . "'"; - + . $self->app->preferences->run_in_demo_mode . "'"; my $status - = "Status:
"
-      . $self->app->repo->lr->get_summary_table
-      . "
"; - $self->flash( msg_type => 'success', msg => $status ); - $self->redirect_to( $self->get_referrer ); + = "Status:
"
+    . $self->app->repo->lr->get_summary_table
+    . "
"; + $self->flash(msg_type => 'success', msg => $status); + $self->redirect_to($self->get_referrer); } ################################################################################# sub reset_mysql { @@ -233,23 +215,23 @@ sub reset_mysql { if ($layer) { $layer->reset_data; my $status - = "Status:
"
-        . $self->app->repo->lr->get_summary_table
-        . "
"; - $self->flash( msg_type => 'success', msg => $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
-        . "
"; + = "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 ); + $self->redirect_to($self->get_referrer); } ################################################################################# sub reset_all { @@ -261,20 +243,18 @@ sub reset_all { 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 # $self->app->insert_admin; # instead, do not insert admin and set system in demo mode $self->app->preferences->run_in_demo_mode(1); - my $status - = "Status:
"
-      . $self->app->repo->lr->get_summary_table
-      . "
"; - $self->flash( msg_type => 'success', msg => $status ); - $self->redirect_to( $self->get_referrer ); + = "Status:
"
+    . $self->app->repo->lr->get_summary_table
+    . "
"; + $self->flash(msg_type => 'success', msg => $status); + $self->redirect_to($self->get_referrer); } ################################################################################# sub system_status { @@ -285,14 +265,12 @@ sub system_status { my $backups_dir = $self->app->config->{backups_dir}; my $upload_dir = $self->app->get_upload_dir; - my $backup_dir_absolute = $self->config->{backups_dir}; $backup_dir_absolute - =~ s!/*$!/!; # makes sure that there is exactly one / at the end + =~ s!/*$!/!; # makes sure that there is exactly one / at the end my $errored = 0; - ################### $msg .= "
" . "Connecting to DB: "; try { @@ -342,11 +320,11 @@ sub system_status { $msg .= "
" . "End."; if ($errored) { - $self->render( text => $msg, status => 500 ); + $self->render(text => $msg, status => 500); return; } else { - $self->render( text => $msg, status => 200 ); + $self->render(text => $msg, status => 200); } } ################################################################################# diff --git a/lib/BibSpace/Controller/Preferences.pm b/lib/BibSpace/Controller/Preferences.pm index 35f738a..8704a03 100644 --- a/lib/BibSpace/Controller/Preferences.pm +++ b/lib/BibSpace/Controller/Preferences.pm @@ -4,12 +4,12 @@ use strict; use warnings; use utf8; use v5.16; #because of ~~ + # use File::Slurp; use Try::Tiny; use Data::Dumper; - use Mojo::Base 'Mojolicious::Controller'; use Storable; use BibSpace::Functions::Core; @@ -19,49 +19,55 @@ use Class::MOP; use Moose::Util qw/does_role/; - use BibSpace::Converter::IHtmlBibtexConverter; ################################################################################# sub index { - my $self = shift; + my $self = shift; - # http://search.cpan.org/~ether/Moose-2.2004/lib/Moose/Util.pm#does_role($class_or_obj,_$role_or_obj) - my @converterClasses = grep { does_role($_ , 'IHtmlBibtexConverter') } Class::MOP::get_all_metaclasses; - @converterClasses = grep { $_ ne 'IHtmlBibtexConverter' } @converterClasses; - +# http://search.cpan.org/~ether/Moose-2.2004/lib/Moose/Util.pm#does_role($class_or_obj,_$role_or_obj) + my @converterClasses = grep { does_role($_, 'IHtmlBibtexConverter') } + Class::MOP::get_all_metaclasses; + @converterClasses = grep { $_ ne 'IHtmlBibtexConverter' } @converterClasses; - $self->stash( preferences => $self->app->preferences, converters => \@converterClasses ); - $self->render( template => 'display/preferences' ); + $self->stash( + preferences => $self->app->preferences, + converters => \@converterClasses + ); + $self->render(template => 'display/preferences'); } ################################################################################# sub save { - my $self = shift; - my $bibitex_html_converter = $self->param('bibitex_html_converter'); - my $local_time_zone = $self->param('local_time_zone'); - my $output_time_format = $self->param('output_time_format'); - my $run_in_demo_mode = $self->param('run_in_demo_mode'); + my $self = shift; + my $bibitex_html_converter = $self->param('bibitex_html_converter'); + my $local_time_zone = $self->param('local_time_zone'); + my $output_time_format = $self->param('output_time_format'); + my $run_in_demo_mode = $self->param('run_in_demo_mode'); + + if ($run_in_demo_mode and $run_in_demo_mode eq 'on') { + $run_in_demo_mode = 1; + } + else { + $run_in_demo_mode = 0; + } - if($run_in_demo_mode and $run_in_demo_mode eq 'on'){ - $run_in_demo_mode = 1; - } - else{ - $run_in_demo_mode = 0; - } + my $msg = "Preferences saved!"; + my $msg_type = "success"; - my $msg = "Preferences saved!"; - my $msg_type = "success"; + # TODO: validate inputs + $self->app->preferences->run_in_demo_mode($run_in_demo_mode); + $self->app->preferences->bibitex_html_converter($bibitex_html_converter); + $self->app->preferences->local_time_zone($local_time_zone); + $self->app->preferences->output_time_format($output_time_format); - # TODO: validate inputs - $self->app->preferences->run_in_demo_mode($run_in_demo_mode); - $self->app->preferences->bibitex_html_converter($bibitex_html_converter); - $self->app->preferences->local_time_zone($local_time_zone); - $self->app->preferences->output_time_format($output_time_format); - + $self->stash( + preferences => $self->app->preferences, + msg_type => $msg_type, + msg => $msg + ); - $self->stash( preferences => $self->app->preferences, msg_type=>$msg_type, msg =>$msg ); - # $self->render( template => 'display/preferences' ); - $self->redirect_to( $self->get_referrer ); + # $self->render( template => 'display/preferences' ); + $self->redirect_to($self->get_referrer); } ################################################################################# 1; diff --git a/lib/BibSpace/Controller/Publications.pm b/lib/BibSpace/Controller/Publications.pm index 1b60534..a3fb1fc 100644 --- a/lib/BibSpace/Controller/Publications.pm +++ b/lib/BibSpace/Controller/Publications.pm @@ -21,7 +21,6 @@ use Encode; use BibSpace::Functions::Core; use BibSpace::Functions::FPublications; - use Mojo::Base 'Mojolicious::Controller'; use Mojo::Base 'Mojolicious::Plugin::Config'; use Mojo::UserAgent; @@ -56,12 +55,12 @@ our %mons = ( sub all { 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 { @@ -70,18 +69,17 @@ sub all_recently_added { $self->app->logger->info("Displaying recently added entries."); - my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + 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 ]; + @added_entries = @added_entries[0 .. $num - 1]; - my @filtered - = Fget_publications_main_hashed_args( $self, {}, \@added_entries ); + my @filtered = Fget_publications_main_hashed_args($self, {}, \@added_entries); # 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' ); + $self->stash(entries => \@filtered, all_entries => \@added_entries); + $self->render(template => 'publications/all'); } #################################################################################### @@ -91,21 +89,18 @@ sub all_recently_modified { $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 ); + = Fget_publications_main_hashed_args($self, {}, \@modified_entries); # 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'); } #################################################################################### @@ -114,55 +109,51 @@ sub all_without_tag { my $tagtype = $self->param('tagtype') // 1; # this will filter entries based on query - my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + 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 ); - + = 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' ); + = "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 @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 @entries = grep { scalar($_->get_authors) == 0 } @all; - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@entries ); + my @filtered = Fget_publications_main_hashed_args($self, {}, \@entries); my $msg - = "This list contains papers, that are currently not assigned to any of authors."; + = "This list contains papers, that are currently not assigned to any of authors."; $msg - .= ' Click to delete '; + .= ' 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'); - $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 } ); + 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 @all = Fget_publications_main_hashed_args($self, {year => undef}); my @teamEntres = $team->get_entries; my %inTeam = map { $_ => 1 } @teamEntres; @@ -171,19 +162,19 @@ sub show_unrelated_to_team { # hash destroys order! @entriesUnrelated = sort_publications(@entriesUnrelated); my @filtered - = Fget_publications_main_hashed_args( $self, {}, \@entriesUnrelated ); + = Fget_publications_main_hashed_args($self, {}, \@entriesUnrelated); my $msg = "This list contains papers, that are: "; - $self->stash( msg_type => 'info', msg => $msg ); - $self->stash( entries => \@filtered, all_entries => \@entriesUnrelated ); - $self->render( template => 'publications/all' ); + $self->stash(msg_type => 'info', msg => $msg); + $self->stash(entries => \@filtered, all_entries => \@entriesUnrelated); + $self->render(template => 'publications/all'); } #################################################################################### sub all_with_missing_month { @@ -191,35 +182,30 @@ sub all_with_missing_month { $self->app->logger->info("Displaying entries without month"); - - my @all = Fget_publications_main_hashed_args( $self, { year => undef } ); + my @all = Fget_publications_main_hashed_args($self, {year => undef}); my @entries - = grep { !defined $_->month or $_->month < 1 or $_->month > 12 } @all; + = grep { (!defined $_->month) or ($_->month < 1) or ($_->month > 12) } @all; - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@entries ); + my @filtered = Fget_publications_main_hashed_args($self, {}, \@entries); my $msg = "This list contains entries with missing BibTeX field 'month'. "; $msg .= "Add this data to get the proper chronological sorting."; - $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_candidates_to_delete { my $self = shift; - $self->app->logger->info( - "Displaying entries that are candidates_to_delete"); - + $self->app->logger->info("Displaying entries that are candidates_to_delete"); - 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_tags == 0 } @all; # no tags - @entries - = grep { scalar $_->get_teams == 0 } @entries; # no relation to teams - @entries = grep { scalar $_->get_exceptions == 0 } @entries; # no exceptions - my @filtered = Fget_publications_main_hashed_args( $self, {}, \@entries ); - + @entries = grep { scalar $_->get_teams == 0 } @entries; # no relation to teams + @entries = grep { scalar $_->get_exceptions == 0 } @entries; # no exceptions + my @filtered = Fget_publications_main_hashed_args($self, {}, \@entries); 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'); } #################################################################################### #################################################################################### @@ -240,7 +226,7 @@ sub all_candidates_to_delete { sub all_bibtex { 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) {
@@ -248,7 +234,7 @@ sub all_bibtex {
     $big_str .= "\n";
   }
   $big_str .= "\n
"; - $self->render( text => $big_str ); + $self->render(text => $big_str); } #################################################################################### @@ -256,11 +242,11 @@ sub all_read { my $self = shift; # this function does filtering ! - my @objs = Fget_publications_main_hashed_args( $self, { hidden => 0 } ); + 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); } #################################################################################### @@ -269,17 +255,17 @@ sub single { 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 }); my @objs; - if ( defined $entry ) { + if (defined $entry) { push @objs, $entry; } else { - $self->stash( msg_type => 'danger', msg => "Entry $id does not exist." ); + $self->stash(msg_type => 'danger', msg => "Entry $id does not exist."); } - $self->stash( entries => \@objs ); - $self->render( template => 'publications/all' ); + $self->stash(entries => \@objs); + $self->render(template => 'publications/all'); } #################################################################################### @@ -290,13 +276,13 @@ sub single_read { 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 ) { + if (defined $entry and $entry->is_hidden == 0) { push @objs, $entry; } - $self->stash( entries => \@objs ); - $self->render( template => 'publications/all_read' ); + $self->stash(entries => \@objs); + $self->render(template => 'publications/all_read'); } #################################################################################### sub fixMonths { @@ -315,7 +301,7 @@ sub fixMonths { msg => 'Fixing entries month field finished.', msg_type => 'info' ); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### sub toggle_hide { @@ -324,18 +310,17 @@ sub toggle_hide { $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 ) { + if (defined $entry) { $entry->toggle_hide; $self->app->repo->entries_update($entry); } else { - $self->flash( msg => "There is no entry with id $id" ); + $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 { @@ -344,18 +329,17 @@ sub make_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 ) { + if (defined $entry) { $entry->make_paper(); $self->app->repo->entries_update($entry); } else { - $self->flash( msg => "There is no entry with id $id" ); + $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 { @@ -364,25 +348,24 @@ sub make_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 ) { + if (defined $entry) { $entry->make_talk(); $self->app->repo->entries_update($entry); } else { - $self->flash( msg => "There is no entry with id $id" ); + $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 } ); + my @entries + = $self->app->repo->entries_filter(sub { scalar($_->get_authors) == 0 }); foreach my $entry (@entries) { my @au = $entry->authorships_all; @@ -396,12 +379,11 @@ sub delete_orphaned { 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->flash(msg => $msg, msg_type => 'info'); $self->redirect_to('all_orphaned'); } - #################################################################################### sub fix_file_urls { my $self = shift; @@ -412,7 +394,7 @@ sub fix_file_urls { my @all_entries; if ($id) { - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find(sub { $_->id == $id }); push @all_entries, $entry if $entry; } else { @@ -428,10 +410,9 @@ sub fix_file_urls { ++$num_checks; my $str; $str .= "Entry " . $entry->id . ": "; - $entry->discover_attachments( $self->app->get_upload_dir ); + $entry->discover_attachments($self->app->get_upload_dir); my @discovered_types = $entry->attachments_keys; - $str .= "has types: ("; foreach (@discovered_types) { $str .= " $_, "; @@ -447,10 +428,10 @@ sub fix_file_urls { id => $entry->id )->to_abs; - if ( $file and $file->exists ) { - $entry->remove_bibtex_fields( ['pdf'] ); + if ($file and $file->exists) { + $entry->remove_bibtex_fields(['pdf']); $str .= "\n\t"; - $entry->add_bibtex_field( "pdf", "$file_url" ); + $entry->add_bibtex_field("pdf", "$file_url"); $fixed = 1; $str .= "Added Bibtex filed PDF " . $file_url; } @@ -462,10 +443,10 @@ sub fix_file_urls { id => $entry->id )->to_abs; - if ( $file and $file->exists ) { - $entry->remove_bibtex_fields( ['slides'] ); + if ($file and $file->exists) { + $entry->remove_bibtex_fields(['slides']); $str .= "\n\t"; - $entry->add_bibtex_field( "slides", "$file_url" ); + $entry->add_bibtex_field("slides", "$file_url"); $fixed = 1; $str .= "Added Bibtex filed SLIDES " . $file_url; } @@ -474,8 +455,7 @@ sub fix_file_urls { if ($fixed) { $big_str .= $str; ++$num_fixes; - $entry->regenerate_html( 0, $self->app->bst, - $self->app->bibtexConverter ); + $entry->regenerate_html(0, $self->app->bst, $self->app->bibtexConverter); } } @@ -484,9 +464,9 @@ sub fix_file_urls { $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." + "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->redirect_to($self->get_referrer); } #################################################################################### sub remove_attachment { @@ -497,25 +477,23 @@ sub remove_attachment { $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 $entry = $self->app->repo->entries_find(sub { $_->id == $id }); + my ($msg, $msg_type); - $entry->discover_attachments( $self->app->get_upload_dir ); + $entry->discover_attachments($self->app->get_upload_dir); - - if ( $entry->attachments_has($filetype) ) { + if ($entry->attachments_has($filetype)) { $self->app->logger->debug("Entry has attachment of type '$filetype'."); - if ( $filetype eq 'paper' ) { - $entry->remove_bibtex_fields( ['pdf'] ); + if ($filetype eq 'paper') { + $entry->remove_bibtex_fields(['pdf']); } - elsif ( $filetype eq 'slides' ) { - $entry->remove_bibtex_fields( ['slides'] ); + elsif ($filetype eq 'slides') { + $entry->remove_bibtex_fields(['slides']); } $entry->delete_attachment($filetype); - $entry->regenerate_html( 1, $self->app->bst, - $self->app->bibtexConverter ); + $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'."; @@ -526,13 +504,13 @@ sub remove_attachment { $self->app->logger->debug("Entry has NO attachment of type '$filetype'."); $msg - = "File not found. Cannot remove attachment. Filetype '$filetype', entry '$id'."; + = "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 ); + $self->flash(msg_type => $msg_type, msg => $msg); + $self->redirect_to($self->get_referrer); } #################################################################################### sub discover_attachments { @@ -540,22 +518,21 @@ sub discover_attachments { my $id = $self->param('id'); my $do = $self->param('do'); - - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + 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 ); + 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
-        . "
"; + .= "Attachments debug:
"
+      . $entry->get_attachments_debug_string
+      . "
"; } else { $msg = "Cannot discover, entry '$id' not found."; @@ -563,9 +540,8 @@ sub discover_attachments { $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 { @@ -573,46 +549,45 @@ sub download { my $id = $self->param('id'); # entry ID my $filetype = $self->param('filetype'); - - my $entry = $self->app->repo->entries_find( sub { $_->id == $id } ); + my $entry = $self->app->repo->entries_find(sub { $_->id == $id }); my $file; if ($entry) { - $entry->discover_attachments( $self->app->get_upload_dir ); + $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." ); + $self->render(status => 404, text => "File not found."); return; } - if ( $file and -e $file ) { - $self->render_file( 'filepath' => $file ); + 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 ); + $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 $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 ); + 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 ); + $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 { @@ -621,12 +596,12 @@ sub add_pdf_post { my $filetype = $self->param('filetype'); my $uploaded_file = $self->param('uploaded_file'); - my $uploads_directory = Path::Tiny->new( $self->app->get_upload_dir ); + 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 ) { + 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; @@ -637,83 +612,76 @@ sub add_pdf_post { msg => "The File is too big and cannot be saved!", msg_type => "danger" ); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); return; } - - if ( !$uploaded_file ) { - $self->flash( msg => "File upload unsuccessful!", msg_type => "danger" ); + 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 ); + $self->redirect_to($self->get_referrer); return; } my $size = $uploaded_file->size; - my $sizeKB = int( $size / 1024 ); - if ( $size == 0 ) { + 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 ); + $self->redirect_to($self->get_referrer); return; } - 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_type => 'danger', - msg => "Entry '$id' does not exist." - ); - $self->redirect_to( $self->get_referrer ); + 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 @dot_arr = split(/\./, $name); my $extension = $dot_arr[-1]; - my $file_url; my $destination; - if ( $filetype eq 'paper' ) { + if ($filetype eq 'paper') { $entry->delete_attachment('paper'); - $destination - = $uploads_directory->path( "papers", "paper-$id.$extension" ); + $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 ); + $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" ); + $entry->add_bibtex_field('pdf', "$file_url"); } - elsif ( $filetype eq 'slides' ) { + elsif ($filetype eq 'slides') { $entry->delete_attachment('slides'); $destination - = $uploads_directory->path( "slides", "slides-paper-$id.$extension" ); + = $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 ); + $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" ); + $entry->add_bibtex_field('slides', "$file_url"); } else { # ignore - we support only pdf and slides so far @@ -723,15 +691,15 @@ sub add_pdf_post { "Saving attachment for entry '$id' under: '$destination'."); my $msg - = "Successfully uploaded the $sizeKB KB file as $filetype. + = "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 ); + $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); } #################################################################################### @@ -740,14 +708,14 @@ sub mark_author_to_regenerate { 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; if ($author) { - $self->app->logger->info( "Marking entries of author '" - . $author->uid - . "' for HTML regeneration." ); + $self->app->logger->info("Marking entries of author '" + . $author->uid + . "' for HTML regeneration."); @entries = $author->get_entries; foreach my $entry (@entries) { @@ -757,15 +725,13 @@ sub mark_author_to_regenerate { } my $msg - = "" - . scalar(@entries) - . " entries have been MARKED for regeneration. "; + = "" . 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->flash(msg_type => 'info', msg => $msg); + $self->redirect_to($self->get_referrer); } #################################################################################### sub regenerate_html_for_all { @@ -777,16 +743,16 @@ sub regenerate_html_for_all { $self->app->logger->info("regenerate_html_for_all is running"); my @entries - = $self->app->repo->entries_filter( sub { $_->need_html_regen == 1 } ); + = $self->app->repo->entries_filter(sub { $_->need_html_regen == 1 }); my $num_regen - = Fregenerate_html_for_array( $self->app, 0, $converter, \@entries ); + = 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 ); + $self->flash(msg_type => 'info', msg => $msg); + $self->redirect_to($self->get_referrer); } #################################################################################### sub regenerate_html_in_chunk { @@ -801,23 +767,23 @@ sub regenerate_html_in_chunk { "regenerate_html_in_chunk is running, chunk size $chunk_size "); my @entries - = $self->app->repo->entries_filter( sub { $_->need_html_regen == 1 } ); + = $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 @portion_of_entries = @entries[ 0 .. $last_entry_index ]; + 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 $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() ); + $self->flash(msg_type => 'info', msg => $msg); + $self->redirect_to($self->get_referrer()); } #################################################################################### sub mark_all_to_regenerate { @@ -835,14 +801,12 @@ sub mark_all_to_regenerate { $self->app->repo->entries_save(@entries); my $msg - = "" - . scalar(@entries) - . " entries have been MARKED for regeneration. "; + = "" . 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->flash(msg_type => 'info', msg => $msg); + $self->redirect_to($self->get_referrer()); } @@ -852,32 +816,28 @@ sub regenerate_html { my $converter = $self->app->bibtexConverter; 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", - msg_type => 'danger' - ); - $self->redirect_to( $self->get_referrer ); + 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 ); + = Fregenerate_html_for_array($self->app, 1, $converter, \@entries); my $msg; - if ( $num_regen == 1 ) { + 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->flash(msg_type => 'info', msg => $msg); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### @@ -885,16 +845,13 @@ sub delete_sure { 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 ) { + 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 ); + $self->flash(mgs_type => 'danger', msg => "There is no entry with id $id"); + $self->redirect_to($self->get_referrer); return; } @@ -908,7 +865,7 @@ sub delete_sure { $self->app->repo->entries_delete($entry); $self->app->logger->info("Entry '$id' has been deleted."); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### sub show_authors_of_entry { @@ -916,21 +873,19 @@ sub show_authors_of_entry { 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 ); + 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; - $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'); } #################################################################################### #################################################################################### @@ -941,22 +896,19 @@ sub manage_tags { $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 ); + 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; - - $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'); } #################################################################################### @@ -965,10 +917,10 @@ sub remove_tag { 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, @@ -978,8 +930,7 @@ sub remove_tag { ); my $label - = $self->app->repo->labelings_find( sub { $_->equals($search_label) } - ); + = $self->app->repo->labelings_find(sub { $_->equals($search_label) }); if ($label) { @@ -988,23 +939,21 @@ sub remove_tag { $tag->remove_labeling($label); $self->app->repo->labelings_delete($label); - $self->app->logger->info( - "Removed tag " . $tag->name . " from entry ID " . $entry->id . ". " ); + "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->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); } #################################################################################### @@ -1013,10 +962,10 @@ sub add_tag { 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 $label = Labeling->new( entry => $entry, tag => $tag, @@ -1036,7 +985,7 @@ sub add_tag { ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### #################################################################################### @@ -1045,16 +994,14 @@ sub manage_exceptions { 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 ); + 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; @@ -1062,8 +1009,7 @@ sub manage_exceptions { # 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; - + my @unassigned_teams = grep { not $exceptions_hash{$_->id} } @all_teams; $self->stash( entry => $entry, @@ -1073,7 +1019,7 @@ sub manage_exceptions { authors => \@authors, unassigned_teams => \@unassigned_teams ); - $self->render( template => 'publications/manage_exceptions' ); + $self->render(template => 'publications/manage_exceptions'); } #################################################################################### sub add_exception { @@ -1081,12 +1027,11 @@ sub add_exception { 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 $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, @@ -1100,22 +1045,22 @@ sub add_exception { $self->app->repo->exceptions_save($exception); $msg - = "Exception added! Entry ID " - . $entry->id - . " will be now listed under team '" - . $team->name . "'."; + = "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 . "."; + = "Cannot find entry or team to create exception. Searched team ID: " + . $team_id + . " entry ID: " + . $entry_id . "."; } - $self->flash( msg => $msg ); + $self->flash(msg => $msg); $self->app->logger->info($msg); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### @@ -1125,13 +1070,12 @@ sub remove_exception { 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; - if ( defined $entry and defined $team ) { + if (defined $entry and defined $team) { my $ex = Exception->new( team_id => $team_id, @@ -1140,40 +1084,39 @@ sub remove_exception { entry => $entry ); - my $exception - = $self->app->repo->exceptions_find( sub { $_->equals($ex) } ); + my $exception = $self->app->repo->exceptions_find(sub { $_->equals($ex) }); - if ( defined $exception ) { + 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 . ". "; + = "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 . "."; + = "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 . "."; + = "Cannot find exception to remove. Searched team ID: " + . $team_id + . " entry ID: " + . $entry_id . "."; } - $self->flash( msg => $msg ); + $self->flash(msg => $msg); $self->app->logger->info($msg); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### @@ -1191,43 +1134,42 @@ sub get_adding_editing_message_for_error_code { # 2 The proposed key is OK. # 3 Proposed key exists already - HTML message - if ( $exit_code eq 'ERR_BIBTEX' ) { + if ($exit_code eq 'ERR_BIBTEX') { return "You have bibtex errors! No changes were written to the database."; } - elsif ( $exit_code eq 'PREVIEW' ) { + elsif ($exit_code eq 'PREVIEW') { return 'Displaying preview. No changes were written to the database.'; } - elsif ( $exit_code eq 'ADD_OK' ) { + elsif ($exit_code eq 'ADD_OK') { return 'Entry added successfully. Switched to editing mode.'; } - elsif ( $exit_code eq 'EDIT_OK' ) { + elsif ($exit_code eq 'EDIT_OK') { return 'Entry updated successfully.'; } - elsif ( $exit_code eq 'KEY_OK' ) { + 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.'; + 'The proposed key is OK. You may continue with your edits. No changes were written to the database.'; } - elsif ( $exit_code eq 'KEY_TAKEN' ) { + elsif ($exit_code eq 'KEY_TAKEN') { return - 'The proposed key exists already in DB under ID . + 'The proposed key exists already in DB under ID .
Show me the existing entry ID ' - . $existing_id - . ' in a new window + . $self->url_for('edit_publication', id => $existing_id) + . '" target="_blank">Show me the existing entry ID ' + . $existing_id + . ' in a new window
Entry has not been saved. Please pick another BibTeX key. No changes were written to the database.'; } - elsif ( defined $exit_code and $exit_code ne '' ) { + elsif (defined $exit_code and $exit_code ne '') { return "Unknown exit code: $exit_code"; } } - #################################################################################### sub publications_add_get { my $self = shift; @@ -1241,17 +1183,17 @@ sub publications_add_get { publisher = {Printer-at-home publishing}, title = {{Selected aspects of some methods}}, year = {' . get_current_year() . '}, - month = {' . $mons{ get_current_month() } . '}, + month = {' . $mons{get_current_month()} . '}, day = {1--31}, }'; - my $e_dummy = $self->app->entityFactory->new_Entry( bib => $bib ); + my $e_dummy = $self->app->entityFactory->new_Entry(bib => $bib); $e_dummy->populate_from_bib(); - $e_dummy->generate_html( $self->app->bst, $self->app->bibtexConverter ); + $e_dummy->generate_html($self->app->bst, $self->app->bibtexConverter); - $self->stash( entry => $e_dummy, msg => $msg ); - $self->render( template => 'publications/add_entry' ); + $self->stash(entry => $e_dummy, msg => $msg); + $self->render(template => 'publications/add_entry'); } #################################################################################### sub publications_add_post { @@ -1283,97 +1225,88 @@ sub publications_add_post { # 2 => KEY_OK # 3 => KEY_TAKEN - - my $entry = $self->app->entityFactory->new_Entry( bib => $new_bib ); + my $entry = $self->app->entityFactory->new_Entry(bib => $new_bib); # any action - if ( !$entry->has_valid_bibtex ) { + if (!$entry->has_valid_bibtex) { $status_code_str = 'ERR_BIBTEX'; - my $msg - = get_adding_editing_message_for_error_code( $self, $status_code_str, - $existing_id ); + my $msg = get_adding_editing_message_for_error_code($self, $status_code_str, + $existing_id); my $msg_type = 'danger'; $self->app->logger->info( "Adding publication. Action: > $action <. Status code: $status_code_str." ); - $self->stash( entry => $entry, msg => $msg, msg_type => $msg_type ); - $self->render( template => 'publications/add_entry' ); + $self->stash(entry => $entry, msg => $msg, msg_type => $msg_type); + $self->render(template => 'publications/add_entry'); return; } - $entry->generate_html( $self->app->bst, $self->app->bibtexConverter ); - my $bibtex_warnings = FprintBibtexWarnings( $entry->warnings ); + $entry->generate_html($self->app->bst, $self->app->bibtexConverter); + my $bibtex_warnings = FprintBibtexWarnings($entry->warnings); # any action my $existing_entry = $self->app->repo->entries_find( - sub { $_->bibtex_key eq $entry->bibtex_key } ); + sub { $_->bibtex_key eq $entry->bibtex_key }); if ($existing_entry) { $status_code_str = 'KEY_TAKEN'; my $msg_type = 'danger'; $existing_id = $existing_entry->id; - my $msg - = get_adding_editing_message_for_error_code( $self, $status_code_str, - $existing_id ); + my $msg = get_adding_editing_message_for_error_code($self, $status_code_str, + $existing_id); $self->app->logger->info( "Adding publication. Action: > $action <. Status code: $status_code_str." ); - $self->stash( entry => $entry, msg => $msg, msg_type => $msg_type ); - $self->render( template => 'publications/add_entry' ); + $self->stash(entry => $entry, msg => $msg, msg_type => $msg_type); + $self->render(template => 'publications/add_entry'); return; } - - if ( $action eq 'preview' or $action eq 'check_key' ) { + if ($action eq 'preview' or $action eq 'check_key') { my $status_code_str = 'PREVIEW'; my $msg_type = 'info'; $msg_type = 'warning' if $bibtex_warnings; - my $msg - = get_adding_editing_message_for_error_code( $self, $status_code_str, - $existing_id ); + my $msg = get_adding_editing_message_for_error_code($self, $status_code_str, + $existing_id); $msg .= $bibtex_warnings; $self->app->logger->info( "Adding publication. Action: > $action <. Status code: $status_code_str." ); - $self->stash( entry => $entry, msg => $msg, msg_type => $msg_type ); - $self->render( template => 'publications/add_entry' ); + $self->stash(entry => $entry, msg => $msg, msg_type => $msg_type); + $self->render(template => 'publications/add_entry'); return; } - - if ( $action eq 'save' ) { + if ($action eq 'save') { $status_code_str = 'ADD_OK'; $entry->fix_month(); - $entry->generate_html( $self->app->bst, $self->app->bibtexConverter ); + $entry->generate_html($self->app->bst, $self->app->bibtexConverter); $self->app->repo->entries_save($entry); $added_under_id = $entry->id; ## !!! the entry must be added before executing Freassign_authors_to_entries_given_by_array ## why? beacuse authorship will be unable to map existing entry to the author - Freassign_authors_to_entries_given_by_array( $self->app, 1, [$entry] ); - + Freassign_authors_to_entries_given_by_array($self->app, 1, [$entry]); my $msg_type = 'success'; $msg_type = 'warning' if $bibtex_warnings; - my $msg - = get_adding_editing_message_for_error_code( $self, $status_code_str, - $existing_id ); + my $msg = get_adding_editing_message_for_error_code($self, $status_code_str, + $existing_id); $msg .= $bibtex_warnings; $self->app->logger->info( "Adding publication. Action: > $action <. Status code: $status_code_str." ); - $self->flash( msg => $msg, msg_type => $msg_type ); + $self->flash(msg => $msg, msg_type => $msg_type); $self->redirect_to( - $self->url_for( 'edit_publication', id => $added_under_id ) ); + $self->url_for('edit_publication', id => $added_under_id)); return; } - } #################################################################################### sub publications_edit_get { @@ -1382,18 +1315,18 @@ sub publications_edit_get { $self->app->logger->info("Editing publication 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 ); + if (!defined $entry) { + $self->flash(msg => "There is no entry with id $id"); + $self->redirect_to($self->get_referrer); return; } $entry->populate_from_bib(); - $entry->generate_html( $self->app->bst, $self->app->bibtexConverter ); + $entry->generate_html($self->app->bst, $self->app->bibtexConverter); - $self->stash( entry => $entry ); - $self->render( template => 'publications/edit_entry' ); + $self->stash(entry => $entry); + $self->render(template => 'publications/edit_entry'); } #################################################################################### sub publications_edit_post { @@ -1405,22 +1338,20 @@ sub publications_edit_post { my $param_check_key = $self->param('check_key'); my $action = 'save'; # user clicks save - $action = 'preview' if $self->param('preview'); # user clicks preview - $action = 'check_key' if $self->param('check_key'); # user clicks check key + $action = 'preview' if $self->param('preview'); # user clicks preview + $action = 'check_key' if $self->param('check_key'); # user clicks check key - $self->app->logger->info( - "Editing publication id $id. Action: > $action <."); + $self->app->logger->info("Editing publication id $id. Action: > $action <."); $new_bib =~ s/^\s+|\s+$//g; $new_bib =~ s/^\t//g; - - my ( $mentry, $status_code_str, $existing_id, $added_under_id ) - = Fhandle_add_edit_publication( $self->app, $new_bib, $id, $action, - $self->app->bst ); + my ($mentry, $status_code_str, $existing_id, $added_under_id) + = Fhandle_add_edit_publication($self->app, $new_bib, $id, $action, + $self->app->bst); my $adding_msg - = get_adding_editing_message_for_error_code( $self, $status_code_str, - $existing_id ); + = get_adding_editing_message_for_error_code($self, $status_code_str, + $existing_id); $self->app->logger->info( "Editing publication id $id. Action: > $action <. Status code: $status_code_str." @@ -1434,17 +1365,17 @@ sub publications_edit_post { # 2 => KEY_OK # 3 => KEY_TAKEN - my $bibtex_warnings = FprintBibtexWarnings( $mentry->warnings ); + my $bibtex_warnings = FprintBibtexWarnings($mentry->warnings); my $msg = $adding_msg . $bibtex_warnings; my $msg_type = 'success'; $msg_type = 'warning' if $bibtex_warnings =~ m/Warning/; $msg_type = 'danger' - if $status_code_str eq 'ERR_BIBTEX' - or $status_code_str eq 'KEY_TAKEN' - or $bibtex_warnings =~ m/Error/; + if $status_code_str eq 'ERR_BIBTEX' + or $status_code_str eq 'KEY_TAKEN' + or $bibtex_warnings =~ m/Error/; - $self->stash( entry => $mentry, msg => $msg, msg_type => $msg_type ); - $self->render( template => 'publications/edit_entry' ); + $self->stash(entry => $mentry, msg => $msg, msg_type => $msg_type); + $self->render(template => 'publications/edit_entry'); } #################################################################################### sub clean_ugly_bibtex { @@ -1452,24 +1383,24 @@ sub clean_ugly_bibtex { # TODO: put this into config or preferences! my @fields_to_clean - = qw(bdsk-url-1 bdsk-url-2 bdsk-url-3 date-added date-modified owner tags); + = qw(bdsk-url-1 bdsk-url-2 bdsk-url-3 date-added date-modified owner tags); $self->app->logger->info("Cleaning ugly Bibtex fields for all entries"); my @entries = $self->app->repo->entries_all; my $num_removed = 0; foreach my $entry (@entries) { - $num_removed = $num_removed - + $entry->clean_ugly_bibtex_fields( \@fields_to_clean ); + $num_removed + = $num_removed + $entry->clean_ugly_bibtex_fields(\@fields_to_clean); } $self->flash( msg_type => 'info', msg => - "All entries have now their Bibtex cleaned. I have removed $num_removed fields." + "All entries have now their Bibtex cleaned. I have removed $num_removed fields." ); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### 1; diff --git a/lib/BibSpace/Controller/PublicationsExperimental.pm b/lib/BibSpace/Controller/PublicationsExperimental.pm index c4ee017..98d2fc7 100644 --- a/lib/BibSpace/Controller/PublicationsExperimental.pm +++ b/lib/BibSpace/Controller/PublicationsExperimental.pm @@ -19,69 +19,64 @@ use Encode; use BibSpace::Functions::Core; use BibSpace::Functions::FPublications; - use Mojo::Base 'Mojolicious::Controller'; use Mojo::Base 'Mojolicious::Plugin::Config'; 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' ); #################################################################################### ## ADD form sub publications_add_many_get { - my $self = shift; + my $self = shift; - my $bib1 - = '@article{key-ENTRY1-' - . get_current_year() . ', + my $bib1 = '@article{key-ENTRY1-' . get_current_year() . ', author = {Johny Example}, title = {{Selected aspects of some methods ' . random_string(8) . '}}, journal = {Journal of this and that}, publisher = {Printer-at-home publishing}, year = {' . get_current_year() . '}, - month = {' . $mons{ 12 } . '}, + month = {' . $mons{12} . '}, day = {1--31}, }'; - my $bib2 - = '@article{key-ENTRY2-' - . get_current_year() . ', + my $bib2 = '@article{key-ENTRY2-' . get_current_year() . ', author = {Johny Example}, title = {{Selected aspects of some methods ' . random_string(8) . '}}, journal = {Journal of other things}, publisher = {Copy-machine publishing house}, year = {' . get_current_year() . '}, - month = {' . $mons{ 12 } . '}, + month = {' . $mons{12} . '}, day = {1--31}, }'; - my $bib = $bib1 . "\n\n" . $bib2; + my $bib = $bib1 . "\n\n" . $bib2; - my $msg - = "Adding multiple publications at once is experimental!
Adding mode You operate on an unsaved entry!"; + my $msg + = "Adding multiple publications at once is experimental!
Adding mode You operate on an unsaved entry!"; - $self->stash( - bib => $bib, - key => '', - existing_id => '', - exit_code => '', - preview => '' - ); - $self->stash( msg_type=>'warning', msg => $msg); - $self->render( template => 'publications/add_multiple_entries' ); + $self->stash( + bib => $bib, + key => '', + existing_id => '', + exit_code => '', + preview => '' + ); + $self->stash(msg_type => 'warning', msg => $msg); + $self->render(template => 'publications/add_multiple_entries'); } ############################################################################################################ @@ -90,182 +85,172 @@ sub publications_add_many_get { sub publications_add_many_post { - my $self = shift; - my $id = $self->param('id') // undef; - my $new_bib = $self->param('new_bib'); - my $preview_param = $self->param('preview') // undef; - my $save_param = $self->param('save') // undef; + my $self = shift; + my $id = $self->param('id') // undef; + my $new_bib = $self->param('new_bib'); + my $preview_param = $self->param('preview') // undef; + my $save_param = $self->param('save') // undef; - # my $check_key = || undef; - my $preview = 0; - my $msg = "Adding mode You operate on an unsaved entry!
"; + # my $check_key = || undef; + my $preview = 0; + my $msg = "Adding mode You operate on an unsaved entry!
"; - $self->app->logger->info("Adding multiple publications"); + $self->app->logger->info("Adding multiple publications"); - $self->app->logger->debug("Adding multiple publications with bib $new_bib"); + $self->app->logger->debug("Adding multiple publications with bib $new_bib"); - my $debug_str = ""; + my $debug_str = ""; - my $html_preview = ""; - my $code = -2; + my $html_preview = ""; + my $code = -2; - my @bibtex_codes = split_bibtex_entries($new_bib); + my @bibtex_codes = split_bibtex_entries($new_bib); + # status_code_strings + # -2 => PREVIEW + # -1 => ERR_BIBTEX + # 0 => ADD_OK + # 1 => EDIT_OK + # 2 => KEY_OK + # 3 => KEY_TAKEN + my $num_errors = 0; + for my $bibtex_code (@bibtex_codes) { - # status_code_strings - # -2 => PREVIEW - # -1 => ERR_BIBTEX - # 0 => ADD_OK - # 1 => EDIT_OK - # 2 => KEY_OK - # 3 => KEY_TAKEN - my $num_errors = 0; - for my $bibtex_code (@bibtex_codes) { + my ($mentry, $status_code_str, $existing_id, $added_under_id) + = Fhandle_add_edit_publication($self->app, $bibtex_code, -1, 'preview'); - my ( $mentry, $status_code_str, $existing_id, $added_under_id ) - = Fhandle_add_edit_publication( $self->app, $bibtex_code, -1, - 'preview' ); - - if ( $status_code_str eq 'ERR_BIBTEX' ) { - $debug_str - .= "BIBTEX error in
 $bibtex_code 
"; - $num_errors++; - } - elsif ( $status_code_str eq 'KEY_TAKEN' ) { # => bibtex OK, key OK - $debug_str - .= "KEY_TAKEN error in
 $bibtex_code 
"; - $num_errors++; - } - else{ - $debug_str - .= "$status_code_str for
 $bibtex_code 
"; - } + if ($status_code_str eq 'ERR_BIBTEX') { + $debug_str .= "BIBTEX error in
 $bibtex_code 
"; + $num_errors++; } - - if ( $num_errors > 0 ) { - $msg = "$num_errors have errors. Please correct entries before continuing. No changes were written to database.
$debug_str"; - $self->stash( - bib => $new_bib, - existing_id => 0, - key => '', - msg_type => 'danger', - msg => $msg, - exit_code => $code, - preview => $html_preview - ); - $self->render( template => 'publications/add_multiple_entries' ); - return; + elsif ($status_code_str eq 'KEY_TAKEN') { # => bibtex OK, key OK + $debug_str .= "KEY_TAKEN error in
 $bibtex_code 
"; + $num_errors++; } - if ( defined $preview_param ) { - $msg = "Check ready.
".$debug_str; - $self->stash( - bib => $new_bib, - existing_id => 0, - key => '', - msg_type => 'info', - msg => $msg, - exit_code => $code, - preview => $html_preview - ); - $self->render( template => 'publications/add_multiple_entries' ); - return; + else { + $debug_str .= "$status_code_str for
 $bibtex_code 
"; } + } - # here all Bibtex entries are OK - - my @key_arr = (); - - for my $bibtex_code (@bibtex_codes) { - - # $debug_str.="
Found code!"; - my $entry = $self->app->entityFactory->new_Entry( bib=>$bibtex_code ); - $entry->populate_from_bib; - $debug_str .= "
Found key: ".$entry->{bibtex_key}; + if ($num_errors > 0) { + $msg + = "$num_errors have errors. Please correct entries before continuing. No changes were written to database.
$debug_str"; + $self->stash( + bib => $new_bib, + existing_id => 0, + key => '', + msg_type => 'danger', + msg => $msg, + exit_code => $code, + preview => $html_preview + ); + $self->render(template => 'publications/add_multiple_entries'); + return; + } + if (defined $preview_param) { + $msg = "Check ready.
" . $debug_str; + $self->stash( + bib => $new_bib, + existing_id => 0, + key => '', + msg_type => 'info', + msg => $msg, + exit_code => $code, + preview => $html_preview + ); + $self->render(template => 'publications/add_multiple_entries'); + return; + } - push @key_arr, $entry->{bibtex_key}; - } + # here all Bibtex entries are OK - my @mentries = (); + my @key_arr = (); - my %seen; - my $are_unique = 0; + for my $bibtex_code (@bibtex_codes) { - # if size of arr is equal to size of uniq arr - $are_unique = 1 if uniq(@key_arr) == @key_arr; + # $debug_str.="
Found code!"; + my $entry = $self->app->entityFactory->new_Entry(bib => $bibtex_code); + $entry->populate_from_bib; + $debug_str .= "
Found key: " . $entry->{bibtex_key}; - # count how many times a given key appears - foreach my $value (@key_arr) { - $seen{$value}++; - } + push @key_arr, $entry->{bibtex_key}; + } - $debug_str .= "
Checking if input keys are unique: "; - $debug_str .= "Yes!" if $are_unique; - $debug_str .= "No! " unless $are_unique; - - if ( $are_unique == 0 ) { # if the array is not empty - $debug_str .= "
" - . "Some bibtex keys in the input are not unique. Please correct the input."; - foreach my $key ( keys %seen ) { - $debug_str - .= "
" - . "Bibtex key: $key exists " - . $seen{$key} - . " times!" - if $seen{$key} > 1; - } - $msg = $debug_str - . "Please correct entries before continuing. No changes were written to database."; - $self->stash( - bib => $new_bib, - existing_id => 0, - key => '', - msg_type => 'danger', - msg => $msg, - exit_code => $code, - preview => $html_preview - ); - $self->render( template => 'publications/add_multiple_entries' ); - return; - } + my @mentries = (); - my $msg_type = 'warning'; + my %seen; + my $are_unique = 0; - if( defined $save_param ){ - $debug_str .= "
Entries ready to add! Starting."; + # if size of arr is equal to size of uniq arr + $are_unique = 1 if uniq(@key_arr) == @key_arr; - $msg_type = 'success'; + # count how many times a given key appears + foreach my $value (@key_arr) { + $seen{$value}++; + } - for my $bibtex_code (@bibtex_codes) { - my ( $mentry, $status_code_str, $existing_id, $added_under_id ) - = Fhandle_add_edit_publication( $self->app, $bibtex_code, -1, 'save', - $self->app->bst ); + $debug_str .= "
Checking if input keys are unique: "; + $debug_str .= "Yes!" if $are_unique; + $debug_str .= "No! " unless $are_unique; - if ( $status_code_str eq 'ADD_OK' ) { - $debug_str .= "
" - . "Added key entry as id $added_under_id successfully!"; - } - else { # => bibtex OK, key OK - $debug_str .= "
" - . "Something went wrong. Status: $status_code_str
"; - $msg_type = 'danger'; - } - } + if ($are_unique == 0) { # if the array is not empty + $debug_str .= "
" + . "Some bibtex keys in the input are not unique. Please correct the input."; + foreach my $key (keys %seen) { + $debug_str + .= "
" . "Bibtex key: $key exists " . $seen{$key} . " times!" + if $seen{$key} > 1; } + $msg = $debug_str + . "Please correct entries before continuing. No changes were written to database."; + $self->stash( + bib => $new_bib, + existing_id => 0, + key => '', + msg_type => 'danger', + msg => $msg, + exit_code => $code, + preview => $html_preview + ); + $self->render(template => 'publications/add_multiple_entries'); + return; + } + my $msg_type = 'warning'; + if (defined $save_param) { + $debug_str .= "
Entries ready to add! Starting."; - $self->stash( - bib => $new_bib, - existing_id => 0, - msg_type => $msg_type, - key => '', - msg => $msg . $debug_str, - exit_code => $code, - preview => $html_preview - ); - $self->render( template => 'publications/add_multiple_entries' ); + $msg_type = 'success'; + + for my $bibtex_code (@bibtex_codes) { + my ($mentry, $status_code_str, $existing_id, $added_under_id) + = Fhandle_add_edit_publication($self->app, $bibtex_code, -1, 'save', + $self->app->bst); + + if ($status_code_str eq 'ADD_OK') { + $debug_str + .= "
" . "Added key entry as id $added_under_id successfully!"; + } + else { # => bibtex OK, key OK + $debug_str + .= "
" . "Something went wrong. Status: $status_code_str
"; + $msg_type = 'danger'; + } + } + } + + $self->stash( + bib => $new_bib, + existing_id => 0, + msg_type => $msg_type, + key => '', + msg => $msg . $debug_str, + exit_code => $code, + preview => $html_preview + ); + $self->render(template => 'publications/add_multiple_entries'); } #################################################################################### - 1; diff --git a/lib/BibSpace/Controller/PublicationsLanding.pm b/lib/BibSpace/Controller/PublicationsLanding.pm index 224eaab..060051d 100644 --- a/lib/BibSpace/Controller/PublicationsLanding.pm +++ b/lib/BibSpace/Controller/PublicationsLanding.pm @@ -12,7 +12,6 @@ use v5.16; #because of ~~ use strict; use warnings; - use TeX::Encode; use Encode; @@ -25,21 +24,20 @@ 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' ); - =item NAMING CONVENTION Peer-Reviewed Journal and Magazine Articles <--- this is section (the text is section description) @@ -56,523 +54,592 @@ Peer-Reviewed International Conference, Workshop Papers, and Book Chapters <--- [2] Piotr Rygielski, Viliam Simko, Felix Sittner, Doris Aschenbrenner, Samuel Kounev, and Klaus Schil... =cut -our $text_delimiter_l = ''; -our $text_delimiter_r = ''; +our $text_delimiter_l = ''; +our $text_delimiter_r = ''; our $anchor_delimiter_l = ' '; our $anchor_delimiter_r = ' '; -our $selected_text_delimiter_l = ''; -our $selected_text_delimiter_r = ''; +our $selected_text_delimiter_l = ''; +our $selected_text_delimiter_r = ''; our $selected_anchor_delimiter_l = '['; our $selected_anchor_delimiter_r = ']'; ############################################################################################################ ## Controller function sub landing_types { - my $self = shift; - my $bibtex_type = $self->param('bibtex_type') // undef; - my $entry_type = $self->param('entry_type') // undef; - - my @all_types - = $self->app->repo->types_filter( sub { $_->onLanding == 1 } ); - - # key: our bibtex type - # value: description of our bibtex type - my %hash_our_type_to_description - = map { $_->our_type => $_->description } @all_types; - - my @entries_to_show; - my @section_names = keys %hash_our_type_to_description; - - ########## - ## Step 1: define which sections to show on the landing list and get the entire papers set for this filtering query - ########## - if ($bibtex_type) { - # user wants to filter on bibtex_type => user wants to show only papers - # we assume that talks do not have bibtex_type - they are special - @section_names = ($bibtex_type); + my $self = shift; + my $bibtex_type = $self->param('bibtex_type') // undef; + my $entry_type = $self->param('entry_type') // undef; + + my @all_types = $self->app->repo->types_filter(sub { $_->onLanding == 1 }); + + # key: our bibtex type + # value: description of our bibtex type + my %hash_our_type_to_description + = map { $_->our_type => $_->description } @all_types; + + my @entries_to_show; + my @section_names = keys %hash_our_type_to_description; + + ########## + ## Step 1: define which sections to show on the landing list and get the entire papers set for this filtering query + ########## + if ($bibtex_type) { + + # user wants to filter on bibtex_type => user wants to show only papers + # we assume that talks do not have bibtex_type - they are special + @section_names = ($bibtex_type); + } + + if ($entry_type and $entry_type eq 'talk') { + + # user wants to show only talks + + # this needs to be added manually as talks are special + $hash_our_type_to_description{'talk'} = "Talks"; + @section_names = ('talk'); + @entries_to_show = $self->get_talks_for_landing; + } + elsif ($entry_type and $entry_type eq 'paper') { + + # user wants to show only papers + @entries_to_show = $self->get_papers_for_landing; + } + else { + # user wants to show everything = talks and papers + + # this needs to be added manually as talks are special + $hash_our_type_to_description{'talk'} = "Talks"; + push @section_names, 'talk'; + @entries_to_show = $self->get_entries_for_landing; + } + + ########## + ## Step 2: set default section descriptions if needed + ########## + ## issue default description if there is no custom description in the system + foreach my $section_name (sort reverse @section_names) { + if (!exists($hash_our_type_to_description{$section_name})) { + $hash_our_type_to_description{$section_name} + = get_generic_type_description($section_name); } + } - if ( $entry_type and $entry_type eq 'talk' ) { + # key: our bibtex type + # value: ref to array of entry objects + my %hash_our_type_to_entries; - # user wants to show only talks + ########## + ## Step 3: assign papers to given sections + ########## - # this needs to be added manually as talks are special - $hash_our_type_to_description{'talk'} = "Talks"; - @section_names = ('talk'); - @entries_to_show = $self->get_talks_for_landing; - } - elsif ( $entry_type and $entry_type eq 'paper' ) { + my @sections_having_entries; + foreach my $section_name (sort reverse @section_names) { - # user wants to show only papers - @entries_to_show = $self->get_papers_for_landing; + # TODO: refactor into: get_entries_for_section + my @entries_in_section; + if ($section_name eq 'talk') { + @entries_in_section = grep { $_->is_talk } @entries_to_show; } else { - # user wants to show everything = talks and papers - - # this needs to be added manually as talks are special - $hash_our_type_to_description{'talk'} = "Talks"; - push @section_names, 'talk'; - @entries_to_show = $self->get_entries_for_landing; - } - - - - - ########## - ## Step 2: set default section descriptions if needed - ########## - ## issue default description if there is no custom description in the system - foreach my $section_name ( sort reverse @section_names ) { - if ( !exists( $hash_our_type_to_description{$section_name} ) ) { - $hash_our_type_to_description{$section_name} - = get_generic_type_description($section_name); - } + @entries_in_section = grep { + $_->is_paper + and $_->matches_our_type($section_name, $self->app->repo) + } @entries_to_show; } + $hash_our_type_to_entries{$section_name} = \@entries_in_section; - # key: our bibtex type - # value: ref to array of entry objects - my %hash_our_type_to_entries; - - ########## - ## Step 3: assign papers to given sections - ########## - - my @sections_having_entries; - foreach my $section_name ( sort reverse @section_names ) { - - # TODO: refactor into: get_entries_for_section - my @entries_in_section; - if ( $section_name eq 'talk' ) { - @entries_in_section = grep { $_->is_talk } @entries_to_show; - } - else { - @entries_in_section - = grep { $_->is_paper and $_->matches_our_type($section_name, $self->app->repo) } - @entries_to_show; - } - - $hash_our_type_to_entries{$section_name} = \@entries_in_section; - - if ( scalar(@entries_in_section) > 0 ) { - push @sections_having_entries, $section_name; - } + if (scalar(@entries_in_section) > 0) { + push @sections_having_entries, $section_name; } - - - ## hash_our_type_to_entries: our bibtex type string -> ref_arr_entry_objects - ## hash_our_type_to_description: our bibtex type string -> our bibtex type description string - ## sections_having_entries: array of section names that have more than 0 entries - return $self->display_landing( - \%hash_our_type_to_entries, \%hash_our_type_to_description, - \@sections_having_entries, $self->get_switchlink_html('years'), - $self->get_filtering_navbar_html() - ); + } + + ## hash_our_type_to_entries: our bibtex type string -> ref_arr_entry_objects + ## hash_our_type_to_description: our bibtex type string -> our bibtex type description string + ## sections_having_entries: array of section names that have more than 0 entries + return $self->display_landing( + \%hash_our_type_to_entries, \%hash_our_type_to_description, + \@sections_having_entries, $self->get_switchlink_html('years'), + $self->get_filtering_navbar_html() + ); } ############################################################################################################ ## Controller function sub landing_years { - my $self = shift; - my $year = $self->param('year') // undef; - my $author = $self->param('author') // undef; + my $self = shift; + my $year = $self->param('year') // undef; + my $author = $self->param('author') // undef; - # shows talks + papers by default - # my $entry_type = $self->param('entry_type') // undef; + # shows talks + papers by default + # my $entry_type = $self->param('entry_type') // undef; + my $min_year = $self->get_year_of_oldest_entry($author) + // $self->current_year; + my $max_year = $self->current_year; - my $min_year = $self->get_year_of_oldest_entry($author) // $self->current_year; - my $max_year = $self->current_year; + # 8 is a month in which we show publications from the next year + if ($self->current_month > 8) { # TODO export to config. + $max_year++; + } - # 8 is a month in which we show publications from the next year - if ( $self->current_month > 8 ) { # TODO export to config. - $max_year++; - } + if ($year) { + $min_year = $year; + $max_year = $year; + } - if ($year) { - $min_year = $year; - $max_year = $year; - } - - my %hash_year_to_description - = map { $_ => $_ } ( $min_year .. $max_year ); - my %hash_year_to_entries; + my %hash_year_to_description = map { $_ => $_ } ($min_year .. $max_year); + my %hash_year_to_entries; - ## fetch all entries outside of the loop - my @all_entries = $self->get_entries_for_landing; + ## fetch all entries outside of the loop + my @all_entries = $self->get_entries_for_landing; - foreach my $year ( $min_year .. $max_year ) { + foreach my $year ($min_year .. $max_year) { - my @entries_to_show = grep { $_->year == $year } @all_entries; - $hash_year_to_entries{$year} = \@entries_to_show; + my @entries_to_show = grep { $_->year == $year } @all_entries; + $hash_year_to_entries{$year} = \@entries_to_show; - if ( scalar(@entries_to_show) == 0 ) { - delete $hash_year_to_description{$year}; - delete $hash_year_to_entries{$year}; + if (scalar(@entries_to_show) == 0) { + delete $hash_year_to_description{$year}; + delete $hash_year_to_entries{$year}; - } } + } - my @sections_sorted = reverse sort keys %hash_year_to_entries; + my @sections_sorted = reverse sort keys %hash_year_to_entries; - # displaying years - you may switch to types - my $switchlink = $self->get_switchlink_html("types"); - my $navbar_html = $self->get_filtering_navbar_html(); + # displaying years - you may switch to types + my $switchlink = $self->get_switchlink_html("types"); + my $navbar_html = $self->get_filtering_navbar_html(); - return $self->display_landing( \%hash_year_to_entries, - \%hash_year_to_description, \@sections_sorted, $switchlink, - $navbar_html ); + return $self->display_landing(\%hash_year_to_entries, + \%hash_year_to_description, \@sections_sorted, $switchlink, $navbar_html); } ############################################################################################################ sub display_landing { - my $self = shift; - my $hash_our_type_to_entries = shift; - my $hash_our_type_to_description = shift; - my $ordered_section_names_ref = shift; - my $switchlink = shift; - my $navbar_html = shift; - - my $navbar = $self->param('navbar') // 0; - my $show_title = $self->param('title') // 0; - my $show_switch = $self->param('switchlink') // 1; - my $query_permalink = $self->param('permalink'); - my $query_tag_name = $self->param('tag'); - - # reset switchlink if show_switch different to 1 - $switchlink = "" if $show_switch != 1; - $navbar_html = "" if $navbar != 1; - - - my $display_tag_name; - if ( defined $query_permalink ) { - - my $tag_obj_with_permalink = $self->app->repo->tags_find( - sub { - defined $_->permalink and $_->permalink eq $query_permalink; - } - ); - if ( defined $tag_obj_with_permalink ) { - $display_tag_name = $tag_obj_with_permalink->name; - } - else { - $display_tag_name = $query_permalink; - } - } - elsif ( defined $query_tag_name ) { - $display_tag_name = $query_tag_name; + my $self = shift; + my $hash_our_type_to_entries = shift; + my $hash_our_type_to_description = shift; + my $ordered_section_names_ref = shift; + my $switchlink = shift; + my $navbar_html = shift; + + my $navbar = $self->param('navbar') // 0; + my $show_title = $self->param('title') // 0; + my $show_switch = $self->param('switchlink') // 1; + my $query_permalink = $self->param('permalink'); + my $query_tag_name = $self->param('tag'); + + # reset switchlink if show_switch different to 1 + $switchlink = "" if $show_switch != 1; + $navbar_html = "" if $navbar != 1; + + my $display_tag_name; + if (defined $query_permalink) { + + my $tag_obj_with_permalink = $self->app->repo->tags_find( + sub { + defined $_->permalink and $_->permalink eq $query_permalink; + } + ); + if (defined $tag_obj_with_permalink) { + $display_tag_name = $tag_obj_with_permalink->name; } - - if ( defined $display_tag_name - and defined $show_title - and $show_title == 1 ) - { - $display_tag_name =~ s/_+/_/g; - $display_tag_name =~ s/_/\ /g; + else { + $display_tag_name = $query_permalink; } - - - my $title = "Publications and Talks "; - $title = " Publications " - if $self->param('entry_type') - and $self->param('entry_type') eq 'paper'; - $title = " Talks " - if $self->param('entry_type') - and $self->param('entry_type') eq 'talk'; - - - $title .= " of team '" . $self->param('team') . "'" - if $self->param('team'); - $title .= " of author '" . $self->param('author') . "'" - if $self->param('author'); - $title .= " labeled as '" . $display_tag_name . "'" if $display_tag_name; - $title .= " of type '" . $self->param('bibtex_type') . "'" - if $self->param('bibtex_type'); - $title .= " published in year '" . $self->param('year') . "'" - if $self->param('year'); - - # my $url = $self->req->url; - # say "scheme ".$url->scheme; - # say "userinfo ".$url->userinfo; - # say "host ".$url->host; - # say "port ".$url->port; - # say "path ".$url->path; - # say "query ".$url->query; - # say "fragment ".$url->fragment; - - # keys = years - # my @objs = @{ $hash_values{$year} }; - # foreach my $obj (@objs){ - $self->stash( - hash_our_type_to_entries => $hash_our_type_to_entries, - hash_our_type_to_description => $hash_our_type_to_description, - # this defines order of sections - ordered_section_names => $ordered_section_names_ref, - navbar => $navbar_html, - show_title => $show_title, - title => $title, - switch_link => $switchlink - ); - $self->res->headers->header( 'Access-Control-Allow-Origin' => '*' ); - - - my $html - = $self->render_to_string( template => 'publications/landing_obj' ); - $self->render( data => $html ); - - # $self->render( template => 'publications/landing_obj' ); + } + elsif (defined $query_tag_name) { + $display_tag_name = $query_tag_name; + } + + if (defined $display_tag_name and defined $show_title and $show_title == 1) { + $display_tag_name =~ s/_+/_/g; + $display_tag_name =~ s/_/\ /g; + } + + my $title = "Publications and Talks "; + $title = " Publications " + if $self->param('entry_type') + and $self->param('entry_type') eq 'paper'; + $title = " Talks " + if $self->param('entry_type') + and $self->param('entry_type') eq 'talk'; + + $title .= " of team '" . $self->param('team') . "'" if $self->param('team'); + $title .= " of author '" . $self->param('author') . "'" + if $self->param('author'); + $title .= " labeled as '" . $display_tag_name . "'" if $display_tag_name; + $title .= " of type '" . $self->param('bibtex_type') . "'" + if $self->param('bibtex_type'); + $title .= " published in year '" . $self->param('year') . "'" + if $self->param('year'); + + # my $url = $self->req->url; + # say "scheme ".$url->scheme; + # say "userinfo ".$url->userinfo; + # say "host ".$url->host; + # say "port ".$url->port; + # say "path ".$url->path; + # say "query ".$url->query; + # say "fragment ".$url->fragment; + + # keys = years + # my @objs = @{ $hash_values{$year} }; + # foreach my $obj (@objs){ + $self->stash( + hash_our_type_to_entries => $hash_our_type_to_entries, + hash_our_type_to_description => $hash_our_type_to_description, + + # this defines order of sections + ordered_section_names => $ordered_section_names_ref, + navbar => $navbar_html, + show_title => $show_title, + title => $title, + switch_link => $switchlink + ); + $self->res->headers->header('Access-Control-Allow-Origin' => '*'); + + my $html = $self->render_to_string(template => 'publications/landing_obj'); + $self->render(data => $html); + + # $self->render( template => 'publications/landing_obj' ); } ############################################################################################################ ####################################### HELPER functions for this controller ############################### ############################################################################################################ - sub get_switchlink_html { - my $self = shift; - my $keyword = shift; - - my $str; - $str .= '
'; - $str .= 'Grouping: '; - - - if ( $keyword eq 'years' ) { - $str .= $selected_anchor_delimiter_l.''.$selected_text_delimiter_l.'Types'.$selected_text_delimiter_r.''.$selected_anchor_delimiter_r; - $str .= $anchor_delimiter_l.''.$text_delimiter_l.'Years'.$text_delimiter_r.''.$anchor_delimiter_r; - } - elsif ( $keyword eq 'types' ) { - $str .= $anchor_delimiter_l.''.$text_delimiter_l.'Types'.$text_delimiter_r.''.$anchor_delimiter_r; - $str .= $selected_anchor_delimiter_l.''.$selected_text_delimiter_l.'Years'.$selected_text_delimiter_r.''.$selected_anchor_delimiter_r; - } - $str .= '
'; - return $str; + my $self = shift; + my $keyword = shift; + + my $str; + $str .= '
'; + $str .= 'Grouping: '; + + if ($keyword eq 'years') { + $str + .= $selected_anchor_delimiter_l + . '' + . $selected_text_delimiter_l . 'Types' + . $selected_text_delimiter_r . '' + . $selected_anchor_delimiter_r; + $str + .= $anchor_delimiter_l + . '' + . $text_delimiter_l . 'Years' + . $text_delimiter_r . '' + . $anchor_delimiter_r; + } + elsif ($keyword eq 'types') { + $str + .= $anchor_delimiter_l + . '' + . $text_delimiter_l . 'Types' + . $text_delimiter_r . '' + . $anchor_delimiter_r; + $str + .= $selected_anchor_delimiter_l + . '' + . $selected_text_delimiter_l . 'Years' + . $selected_text_delimiter_r . '' + . $selected_anchor_delimiter_r; + } + $str .= '
'; + return $str; } ############################################################################################################ ############################################################################################################ ############################################################################################################ -sub get_filtering_navbar_html { - my $self = shift; - - my $str; - ############### KIND - $str .= $self->get_navbar_kinds_html; - ############### TYPES - $str .= $self->get_navbar_types_html; - ############### YEARS - $str .= $self->get_navbar_years_html; - - $str .= '
'; - my $url = $self->url_with->query( [bibtex_type => undef, entry_type => undef, year => undef] ); - $str .= $anchor_delimiter_l.''.$text_delimiter_l.'clear all selections'.$text_delimiter_l.''.$anchor_delimiter_r; - $str .= '
'; - return $str; +sub get_filtering_navbar_html { + my $self = shift; + + my $str; + ############### KIND + $str .= $self->get_navbar_kinds_html; + ############### TYPES + $str .= $self->get_navbar_types_html; + ############### YEARS + $str .= $self->get_navbar_years_html; + + $str .= '
'; + my $url = $self->url_with->query( + [bibtex_type => undef, entry_type => undef, year => undef]); + $str + .= $anchor_delimiter_l + . '' + . $text_delimiter_l + . 'clear all selections' + . $text_delimiter_l . '' + . $anchor_delimiter_r; + $str .= '
'; + return $str; } ############################################################################################################ sub get_navbar_kinds_html { - my $self = shift; - - my $curr_bibtex_type = $self->req->param('bibtex_type') // undef; - my $curr_entry_type = $self->req->param('entry_type') // undef; - my $curr_year = $self->req->param('year') // undef; - - ############### KIND - my $str; - $str .= '
'; - $str .= 'Kind: '; - - - foreach my $key (qw(Paper Talk)) { - - my $url; - if($key eq 'Talk'){ - $url = $self->url_with->query( [entry_type => lc($key), bibtex_type => 'misc'] ); - } - else{ - $url = $self->url_with->query( [entry_type => lc($key)] ); - } - - my $text = $text_delimiter_l . $key . $text_delimiter_r; - - my $num = $self->num_pubs_filtering( - $curr_bibtex_type, - $key, - $curr_year ); - - if ( defined $curr_entry_type and lc($key) eq $curr_entry_type ) { - my $text = $selected_text_delimiter_l . $key . $selected_text_delimiter_r; - $str .= $selected_anchor_delimiter_l.''.$text.''.$selected_anchor_delimiter_r; - } - else { - my $text = $text_delimiter_l . $key . $text_delimiter_r; - $str .= $anchor_delimiter_l.''.$text.''.$anchor_delimiter_r; - } - } - $str .= '
'; - return $str; -} -############################################################################################################ -sub get_navbar_types_html { - my $self = shift; + my $self = shift; - my $curr_bibtex_type = $self->req->param('bibtex_type') // undef; - my $curr_entry_type = $self->req->param('entry_type') // undef; - my $curr_year = $self->req->param('year') // undef; + my $curr_bibtex_type = $self->req->param('bibtex_type') // undef; + my $curr_entry_type = $self->req->param('entry_type') // undef; + my $curr_year = $self->req->param('year') // undef; - my @landingTypes - = $self->app->repo->types_filter( sub { $_->onLanding == 1 } ); + ############### KIND + my $str; + $str .= '
'; + $str .= 'Kind: '; - my %bibtex_type_to_label - = map { $_->our_type => $_->description } @landingTypes; - foreach my $k ( keys %bibtex_type_to_label ) { - if ( !$bibtex_type_to_label{$k} ) { - $bibtex_type_to_label{$k} = get_generic_type_description($k); - } + foreach my $key (qw(Paper Talk)) { + + my $url; + if ($key eq 'Talk') { + $url = $self->url_with->query( + [entry_type => lc($key), bibtex_type => 'misc']); + } + else { + $url = $self->url_with->query([entry_type => lc($key)]); } - ############### TYPE - my $str; - $str .= '
'; - $str .= 'Type: '; + my $text = $text_delimiter_l . $key . $text_delimiter_r; + my $num = $self->num_pubs_filtering($curr_bibtex_type, $key, $curr_year); - foreach my $type ( sort { $a->our_type cmp $b->our_type } @landingTypes ) - { - my $key = $type->our_type; - my $num = $self->num_pubs_filtering( $key, $curr_entry_type, $curr_year ); - my $url = $self->url_with->query( [bibtex_type => $key] ); - - my $text = $text_delimiter_l . $bibtex_type_to_label{$key} . $text_delimiter_r; - - if ( defined $curr_bibtex_type and $key eq $curr_bibtex_type ) { - my $text = $selected_text_delimiter_l . $bibtex_type_to_label{$key} . $selected_text_delimiter_r; - if ($num) { - $str .= $selected_anchor_delimiter_l.''.$text.''.$selected_anchor_delimiter_r; - - } - else{ - $str .= $selected_anchor_delimiter_l.''.$text.''.$selected_anchor_delimiter_r; - } - } - else { - my $text = $text_delimiter_l . $bibtex_type_to_label{$key} . $text_delimiter_r; - if ($num) { - $str .= $anchor_delimiter_l.''.$text.''.$anchor_delimiter_r; - } - else { - $str .= $anchor_delimiter_l.''.$text.''.$anchor_delimiter_r; - } - } + if (defined $curr_entry_type and lc($key) eq $curr_entry_type) { + my $text = $selected_text_delimiter_l . $key . $selected_text_delimiter_r; + $str + .= $selected_anchor_delimiter_l + . '' + . $text . '' + . $selected_anchor_delimiter_r; + } + else { + my $text = $text_delimiter_l . $key . $text_delimiter_r; + $str + .= $anchor_delimiter_l + . '' + . $text . '' + . $anchor_delimiter_r; } - $str .= '
'; - return $str; + } + $str .= '
'; + return $str; } ############################################################################################################ -sub get_navbar_years_html { - my $self = shift; +sub get_navbar_types_html { + my $self = shift; - my $curr_bibtex_type = $self->param('bibtex_type') // undef; - my $curr_entry_type = $self->param('entry_type') // undef; - my $curr_year = $self->param('year') // undef; - my $author = $self->param('author') // undef; + my $curr_bibtex_type = $self->req->param('bibtex_type') // undef; + my $curr_entry_type = $self->req->param('entry_type') // undef; + my $curr_year = $self->req->param('year') // undef; - my $min_year = $self->get_year_of_oldest_entry($author) // $self->current_year; - my $max_year = $self->current_year; + my @landingTypes = $self->app->repo->types_filter(sub { $_->onLanding == 1 }); - # 8 is a month in which we show publications from the next year - if ( $self->current_month > 8 ) { # TODO export to config. - $max_year++; + my %bibtex_type_to_label + = map { $_->our_type => $_->description } @landingTypes; + foreach my $k (keys %bibtex_type_to_label) { + if (!$bibtex_type_to_label{$k}) { + $bibtex_type_to_label{$k} = get_generic_type_description($k); } - my @all_years = ( $min_year .. $max_year ); - @all_years = reverse @all_years; - - ############### YEARS - my $str; - $str .= '
'; - $str .= 'Year: '; - - - foreach my $key ( reverse sort @all_years ) { - my $num = $self->num_pubs_filtering( - $curr_bibtex_type, - $curr_entry_type, - $key ); - - my $url = $self->url_with->query( [year => $key] ); - - if ( defined $curr_year and $key eq $curr_year ) { - my $text = $selected_text_delimiter_l . $key . $selected_text_delimiter_r; - if ($num) { - $str .= $selected_anchor_delimiter_l.''.$text.''.$selected_anchor_delimiter_r; - } - else{ - $str .= $selected_anchor_delimiter_l.''.$text.''.$selected_anchor_delimiter_r; - } - } - else { - my $text = $text_delimiter_l . $key . $text_delimiter_r; - if ($num) { - $str .= $anchor_delimiter_l.''.$text.''.$anchor_delimiter_r; - } - else { - $str .= $anchor_delimiter_l.''.$text.''.$anchor_delimiter_r; - } - } + } + + ############### TYPE + my $str; + $str .= '
'; + $str .= 'Type: '; + + foreach my $type (sort { $a->our_type cmp $b->our_type } @landingTypes) { + my $key = $type->our_type; + my $num = $self->num_pubs_filtering($key, $curr_entry_type, $curr_year); + my $url = $self->url_with->query([bibtex_type => $key]); + + my $text + = $text_delimiter_l . $bibtex_type_to_label{$key} . $text_delimiter_r; + + if (defined $curr_bibtex_type and $key eq $curr_bibtex_type) { + my $text + = $selected_text_delimiter_l + . $bibtex_type_to_label{$key} + . $selected_text_delimiter_r; + if ($num) { + $str + .= $selected_anchor_delimiter_l + . '' + . $text . '' + . $selected_anchor_delimiter_r; + + } + else { + $str + .= $selected_anchor_delimiter_l + . '' + . $text . '' + . $selected_anchor_delimiter_r; + } } - $str .= '
'; - return $str; + else { + my $text + = $text_delimiter_l . $bibtex_type_to_label{$key} . $text_delimiter_r; + if ($num) { + $str + .= $anchor_delimiter_l + . '' + . $text . '' + . $anchor_delimiter_r; + } + else { + $str + .= $anchor_delimiter_l + . '' + . $text . '' + . $anchor_delimiter_r; + } + } + } + $str .= '
'; + return $str; +} +############################################################################################################ +sub get_navbar_years_html { + my $self = shift; + + my $curr_bibtex_type = $self->param('bibtex_type') // undef; + my $curr_entry_type = $self->param('entry_type') // undef; + my $curr_year = $self->param('year') // undef; + my $author = $self->param('author') // undef; + + my $min_year = $self->get_year_of_oldest_entry($author) + // $self->current_year; + my $max_year = $self->current_year; + + # 8 is a month in which we show publications from the next year + if ($self->current_month > 8) { # TODO export to config. + $max_year++; + } + my @all_years = ($min_year .. $max_year); + @all_years = reverse @all_years; + + ############### YEARS + my $str; + $str .= '
'; + $str .= 'Year: '; + + foreach my $key (reverse sort @all_years) { + my $num + = $self->num_pubs_filtering($curr_bibtex_type, $curr_entry_type, $key); + + my $url = $self->url_with->query([year => $key]); + + if (defined $curr_year and $key eq $curr_year) { + my $text = $selected_text_delimiter_l . $key . $selected_text_delimiter_r; + if ($num) { + $str + .= $selected_anchor_delimiter_l + . '' + . $text . '' + . $selected_anchor_delimiter_r; + } + else { + $str + .= $selected_anchor_delimiter_l + . '' + . $text . '' + . $selected_anchor_delimiter_r; + } + } + else { + my $text = $text_delimiter_l . $key . $text_delimiter_r; + if ($num) { + $str + .= $anchor_delimiter_l + . '' + . $text . '' + . $anchor_delimiter_r; + } + else { + $str + .= $anchor_delimiter_l + . '' + . $text . '' + . $anchor_delimiter_r; + } + } + } + $str .= '
'; + return $str; } ############################################################################################################ sub num_pubs_filtering { - my $self = shift; - my $curr_bibtex_type = shift; - my $curr_entry_type = shift; - my $curr_year = shift; - - - return scalar Fget_publications_main_hashed_args( - $self, - { bibtex_type => $curr_bibtex_type, - entry_type => $curr_entry_type, - year => $curr_year, - visible => 1, - hidden => 0 - } - ); + my $self = shift; + my $curr_bibtex_type = shift; + my $curr_entry_type = shift; + my $curr_year = shift; + + return scalar Fget_publications_main_hashed_args( + $self, + { + bibtex_type => $curr_bibtex_type, + entry_type => $curr_entry_type, + year => $curr_year, + visible => 1, + hidden => 0 + } + ); } ############################################################################################################ ############################################################################################################ ############################################################################################################ sub get_papers_for_landing { - my $self = shift; - return Fget_publications_main_hashed_args( - $self, - { entry_type => 'paper', - visible => 0, - hidden => 0 - # the rest of parameters will be taken from $self - } - ); + my $self = shift; + return Fget_publications_main_hashed_args( + $self, + { + entry_type => 'paper', + visible => 0, + hidden => 0 + + # the rest of parameters will be taken from $self + } + ); } ############################################################################################################ sub get_talks_for_landing { - my $self = shift; - return Fget_publications_main_hashed_args( - $self, - { entry_type => 'talk', - visible => 0, - hidden => 0 - # the rest of parameters will be taken from $self - } - ); + my $self = shift; + return Fget_publications_main_hashed_args( + $self, + { + entry_type => 'talk', + visible => 0, + hidden => 0 + + # the rest of parameters will be taken from $self + } + ); } ############################################################################################################ sub get_entries_for_landing { - my $self = shift; - return Fget_publications_main_hashed_args( - $self, - { visible => 0, - hidden => 0, - # the rest of parameters will be taken from $self - } - ); + my $self = shift; + return Fget_publications_main_hashed_args( + $self, + { + visible => 0, + hidden => 0, + + # the rest of parameters will be taken from $self + } + ); } ############################################################################################################ 1; diff --git a/lib/BibSpace/Controller/PublicationsSeo.pm b/lib/BibSpace/Controller/PublicationsSeo.pm index cb5abcb..7d258a2 100644 --- a/lib/BibSpace/Controller/PublicationsSeo.pm +++ b/lib/BibSpace/Controller/PublicationsSeo.pm @@ -1,7 +1,5 @@ package BibSpace::Controller::PublicationsSeo; - - use strict; use warnings; use utf8; @@ -12,9 +10,9 @@ use v5.16; #because of ~~ use TeX::Encode; use Encode; -use BibSpace::Functions::Core; -use BibSpace::Functions::FPublications; -use BibSpace::Controller::Publications; +use BibSpace::Functions::Core; +use BibSpace::Functions::FPublications; +use BibSpace::Controller::Publications; use Mojo::Base 'Mojolicious::Controller'; use Mojo::Base 'Mojolicious::Plugin::Config'; @@ -23,253 +21,251 @@ use Mojo::Log; #################################################################################### sub metalist { - my $self = shift; - + my $self = shift; - my @pubs = Fget_publications_main_hashed_args( $self, { entry_type => 'paper', hidden => 0 } ); + my @pubs = Fget_publications_main_hashed_args($self, + {entry_type => 'paper', hidden => 0}); - $self->stash( entries => \@pubs ); - $self->render( template => 'publicationsSEO/metalist' ); + $self->stash(entries => \@pubs); + $self->render(template => 'publicationsSEO/metalist'); } #################################################################################### sub meta { - my $self = shift; - my $id = $self->param('id'); - - my $mentry = $self->app->repo->entries_find(sub{ $_->id==$id } ); - - if ( !defined $mentry or $mentry->is_hidden ) { - $self->render( - text => 'Cannot find entry ID \'' . $id.'\'.', - status => 404 - ); - return; - } - - - # PARSING BIBTEX - - #this should happen earlier! - $mentry->bib( fix_bibtex_national_characters( $mentry->bib ) ); - $mentry->populate_from_bib(); - - my $bibtex_entry_str = $mentry->bib; - my $bibtex_entry = new Text::BibTeX::Entry(); - $bibtex_entry->parse_s($bibtex_entry_str); - unless ( $bibtex_entry->parse_ok ) { - $self->render( - text => - 'Error 503: Cannot parse BibTeX code for this entry! Entry id: ' - . $id, - status => 503 - ); # TODO: check proper error code - return; - } - - # EXTRACTING IMPORTANT FIELDS - - # TITLE - my $title = $mentry->get_title; - - my $citation_title = $title; - - # AUTHORS - my @names; - my @citation_authors; - if ( $bibtex_entry->exists('author') ) { - my @authors = $bibtex_entry->split('author'); - my (@n) = $bibtex_entry->names('author'); - @names = @n; - } - elsif ( $bibtex_entry->exists('editor') ) { - my @authors = $bibtex_entry->split('editor'); - my (@n) = $bibtex_entry->names('editor'); - @names = @n; - } - for my $name (@names) { - - my $name_clean = ""; - $name_clean = decode( 'latex', $name_clean ); - my $firstname = join( ' ', grep {defined $_} $name->part('first') ) if defined $name->part('first'); - my $von = join( ' ', $name->part('von') ) - if defined $name->part('von'); - my $lastname = join( ' ', $name->part('last') ); - my $jr = join( ' ', $name->part('jr') ) if defined $name->part('jr'); + my $self = shift; + my $id = $self->param('id'); - $name_clean = $firstname; - $name_clean .= " " . $von if defined $von; - $name_clean .= " " . $lastname if defined $lastname; - $name_clean .= " " . $jr if defined $jr; + my $mentry = $self->app->repo->entries_find(sub { $_->id == $id }); - $name_clean =~ s/\ +/ /g; - $name_clean =~ s/\ $//g; - - push @citation_authors, $name_clean; - } - - # PUBLICATION DATE - my $year = $bibtex_entry->get('year'); - - my $month = 0; - $month = $bibtex_entry->get('month') if $bibtex_entry->exists('month'); - - my $days = 0; - $days = $bibtex_entry->get('day') if $bibtex_entry->exists('day'); - my @day = (); - @day = split( "--", $days ) if defined $days; - my $first_day = 0; - $first_day = $day[0] if defined $days; - - my $citation_publication_date = $year; + if ((!defined $mentry) or ($mentry->is_hidden)) { + $self->render( + text => 'Cannot find entry ID \'' . $id . '\'.', + status => 404 + ); + return; + } + + # PARSING BIBTEX + + #this should happen earlier! + $mentry->bib(fix_bibtex_national_characters($mentry->bib)); + $mentry->populate_from_bib(); + + my $bibtex_entry_str = $mentry->bib; + my $bibtex_entry = new Text::BibTeX::Entry(); + $bibtex_entry->parse_s($bibtex_entry_str); + unless ($bibtex_entry->parse_ok) { + $self->render( + text => 'Error 503: Cannot parse BibTeX code for this entry! Entry id: ' + . $id, + status => 503 + ); # TODO: check proper error code + return; + } + + # EXTRACTING IMPORTANT FIELDS + + # TITLE + my $title = $mentry->get_title; + + my $citation_title = $title; + + # AUTHORS + my @names; + my @citation_authors; + if ($bibtex_entry->exists('author')) { + my @authors = $bibtex_entry->split('author'); + my (@n) = $bibtex_entry->names('author'); + @names = @n; + } + elsif ($bibtex_entry->exists('editor')) { + my @authors = $bibtex_entry->split('editor'); + my (@n) = $bibtex_entry->names('editor'); + @names = @n; + } + for my $name (@names) { + + my $name_clean = ""; + $name_clean = decode('latex', $name_clean); + my $firstname = undef; + $firstname = join(' ', grep { defined $_ } $name->part('first')) + if defined $name->part('first'); + my $von = undef; + $von = join(' ', $name->part('von')) if defined $name->part('von'); + my $lastname = join(' ', $name->part('last')); + my $jr = undef; + $jr = join(' ', $name->part('jr')) if defined $name->part('jr'); + + $name_clean = $firstname; + $name_clean .= " " . $von if defined $von; + $name_clean .= " " . $lastname if defined $lastname; + $name_clean .= " " . $jr if defined $jr; + + $name_clean =~ s/\ +/ /g; + $name_clean =~ s/\ $//g; + + push @citation_authors, $name_clean; + } + + # PUBLICATION DATE + my $year = $bibtex_entry->get('year'); + + my $month = 0; + $month = $bibtex_entry->get('month') if $bibtex_entry->exists('month'); + + my $days = 0; + $days = $bibtex_entry->get('day') if $bibtex_entry->exists('day'); + my @day = (); + @day = split("--", $days) if defined $days; + my $first_day = 0; + $first_day = $day[0] if defined $days; + + my $citation_publication_date = $year; # $citation_publication_date .= "/".$month if defined $month; # $citation_publication_date .= "/".$first_day if defined $first_day and defined $days;; - # ABSTRACT - my $abstract = $bibtex_entry->get('abstract'); - $abstract ||= "This paper has no abstract. The title is: " . $citation_title; - - $abstract = decode( 'latex', $abstract ); - $abstract =~ s/^\{//g; - $abstract =~ s/\}$//g; - - # TYPE - my $type = $bibtex_entry->type; - - my $citation_journal_title; # OK - my $citation_conference_title; #ok - my $citation_issn; # IGNORE - my $citation_isbn; # IGNORE - my $citation_volume; #ok - my $citation_issue; # ok - my $citation_firstpage; #ok - my $citation_lastpage; #ok - - if ( $type eq "article" ) { - if ( $bibtex_entry->exists('journal') ) { - $citation_journal_title = $bibtex_entry->get('journal'); - $citation_journal_title - = decode( 'latex', $citation_journal_title ); - } - if ( $bibtex_entry->exists('volume') ) { - $citation_volume = $bibtex_entry->get('volume'); - } - if ( $bibtex_entry->exists('number') ) { - $citation_issue = $bibtex_entry->get('number'); - } + # ABSTRACT + my $abstract = $bibtex_entry->get('abstract'); + $abstract ||= "This paper has no abstract. The title is: " . $citation_title; + + $abstract = decode('latex', $abstract); + $abstract =~ s/^\{//g; + $abstract =~ s/\}$//g; + + # TYPE + my $type = $bibtex_entry->type; + + my $citation_journal_title; # OK + my $citation_conference_title; #ok + my $citation_issn; # IGNORE + my $citation_isbn; # IGNORE + my $citation_volume; #ok + my $citation_issue; # ok + my $citation_firstpage; #ok + my $citation_lastpage; #ok + + if ($type eq "article") { + if ($bibtex_entry->exists('journal')) { + $citation_journal_title = $bibtex_entry->get('journal'); + $citation_journal_title = decode('latex', $citation_journal_title); } - - if ( $bibtex_entry->exists('pages') ) { - my $pages = $bibtex_entry->get('pages'); - - my @pages_arr; - if ( $pages =~ /--/ ) { - @pages_arr = split( "--", $pages ); - } - elsif ( $pages =~ /-/ ) { - @pages_arr = split( "--", $pages ); - } - else { - push @pages_arr, $pages; - push @pages_arr, $pages; - } - $citation_firstpage = $pages_arr[0] if defined $pages_arr[0]; - $citation_lastpage = $pages_arr[1] if defined $pages_arr[1]; + if ($bibtex_entry->exists('volume')) { + $citation_volume = $bibtex_entry->get('volume'); } - - if ( $bibtex_entry->exists('booktitle') ) { - $citation_conference_title = $bibtex_entry->get('booktitle'); - $citation_conference_title - = decode( 'latex', $citation_conference_title ); + if ($bibtex_entry->exists('number')) { + $citation_issue = $bibtex_entry->get('number'); } + } - # TECH REPORTS AND THESES + if ($bibtex_entry->exists('pages')) { + my $pages = $bibtex_entry->get('pages'); - my $citation_dissertation_institution; - my $citation_technical_report_institution; - my $citation_technical_report_number; - - if ( $type eq "mastersthesis" or $type eq "phdthesis" ) { - $citation_dissertation_institution = $bibtex_entry->get('school') - if $bibtex_entry->exists('school'); - $citation_dissertation_institution - = decode( 'latex', $citation_dissertation_institution ); + my @pages_arr; + if ($pages =~ /--/) { + @pages_arr = split("--", $pages); } - - if ( $type eq "techreport" ) { - $citation_technical_report_institution = $bibtex_entry->get('institution') - if $bibtex_entry->exists('institution'); - $citation_technical_report_institution - = decode( 'latex', $citation_technical_report_institution ); - $citation_technical_report_number = $bibtex_entry->get('number') - if $bibtex_entry->exists('number'); - $citation_technical_report_number = $bibtex_entry->get('type') - if $bibtex_entry->exists('type'); + elsif ($pages =~ /-/) { + @pages_arr = split("--", $pages); } - - # PDF URL - my $citation_pdf_url = undef; - - if ( $bibtex_entry->exists('pdf') ) { - my $local_file_paper = $mentry->get_attachment('paper'); - if ( $local_file_paper and -e $local_file_paper ) { - $citation_pdf_url = $self->url_for( - 'download_publication_pdf', - filetype => 'paper', - id => $id - ); - } - else { - $citation_pdf_url = $bibtex_entry->get('pdf'); - } + else { + push @pages_arr, $pages; + push @pages_arr, $pages; } - elsif ( $bibtex_entry->exists('slides') ) { - my $local_file_slides = $mentry->get_attachment('slides'); - if ( $local_file_slides and -e $local_file_slides ) { - $citation_pdf_url = $self->url_for( - 'download_publication_pdf', - filetype => 'slides', - id => $id - ); - } - else { - $citation_pdf_url = $bibtex_entry->get('slides'); - } + $citation_firstpage = $pages_arr[0] if defined $pages_arr[0]; + $citation_lastpage = $pages_arr[1] if defined $pages_arr[1]; + } + + if ($bibtex_entry->exists('booktitle')) { + $citation_conference_title = $bibtex_entry->get('booktitle'); + $citation_conference_title = decode('latex', $citation_conference_title); + } + + # TECH REPORTS AND THESES + + my $citation_dissertation_institution; + my $citation_technical_report_institution; + my $citation_technical_report_number; + + if ($type eq "mastersthesis" or $type eq "phdthesis") { + $citation_dissertation_institution = $bibtex_entry->get('school') + if $bibtex_entry->exists('school'); + $citation_dissertation_institution + = decode('latex', $citation_dissertation_institution); + } + + if ($type eq "techreport") { + $citation_technical_report_institution = $bibtex_entry->get('institution') + if $bibtex_entry->exists('institution'); + $citation_technical_report_institution + = decode('latex', $citation_technical_report_institution); + $citation_technical_report_number = $bibtex_entry->get('number') + if $bibtex_entry->exists('number'); + $citation_technical_report_number = $bibtex_entry->get('type') + if $bibtex_entry->exists('type'); + } + + # PDF URL + my $citation_pdf_url = undef; + + if ($bibtex_entry->exists('pdf')) { + my $local_file_paper = $mentry->get_attachment('paper'); + if ($local_file_paper and -e $local_file_paper) { + $citation_pdf_url = $self->url_for( + 'download_publication_pdf', + filetype => 'paper', + id => $id + ); } - elsif ( $bibtex_entry->exists('url') ) { - $citation_pdf_url = $bibtex_entry->get('url'); + else { + $citation_pdf_url = $bibtex_entry->get('pdf'); + } + } + elsif ($bibtex_entry->exists('slides')) { + my $local_file_slides = $mentry->get_attachment('slides'); + if ($local_file_slides and -e $local_file_slides) { + $citation_pdf_url = $self->url_for( + 'download_publication_pdf', + filetype => 'slides', + id => $id + ); } else { - # this entry has no pdf/slides/url. $citation_pdf_url remains undef + $citation_pdf_url = $bibtex_entry->get('slides'); } - - # READY SET OF VARIABLES HOLDING METADATA. Some may be undef - my $ca_ref = \@citation_authors; - - $self->stash( - citation_title => $citation_title, - citation_authors => $ca_ref, - abstract => $abstract, - citation_publication_date => $citation_publication_date, - citation_journal_title => $citation_journal_title, - citation_conference_title => $citation_conference_title, - citation_issn => $citation_issn, - citation_isbn => $citation_isbn, - citation_volume => $citation_volume, - citation_issue => $citation_issue, - citation_firstpage => $citation_firstpage, - citation_lastpage => $citation_lastpage, - citation_dissertation_institution => - $citation_dissertation_institution, - citation_technical_report_institution => - $citation_technical_report_institution, - citation_technical_report_number => $citation_technical_report_number, - citation_pdf_url => $citation_pdf_url - ); - - $self->render( template => 'publicationsSEO/meta' ); + } + elsif ($bibtex_entry->exists('url')) { + $citation_pdf_url = $bibtex_entry->get('url'); + } + else { + # this entry has no pdf/slides/url. $citation_pdf_url remains undef + } + + # READY SET OF VARIABLES HOLDING METADATA. Some may be undef + my $ca_ref = \@citation_authors; + + $self->stash( + citation_title => $citation_title, + citation_authors => $ca_ref, + abstract => $abstract, + citation_publication_date => $citation_publication_date, + citation_journal_title => $citation_journal_title, + citation_conference_title => $citation_conference_title, + citation_issn => $citation_issn, + citation_isbn => $citation_isbn, + citation_volume => $citation_volume, + citation_issue => $citation_issue, + citation_firstpage => $citation_firstpage, + citation_lastpage => $citation_lastpage, + citation_dissertation_institution => $citation_dissertation_institution, + citation_technical_report_institution => + $citation_technical_report_institution, + citation_technical_report_number => $citation_technical_report_number, + citation_pdf_url => $citation_pdf_url + ); + + $self->render(template => 'publicationsSEO/meta'); } #################################################################################### diff --git a/lib/BibSpace/Controller/Tags.pm b/lib/BibSpace/Controller/Tags.pm index f2cfdb8..8783d13 100644 --- a/lib/BibSpace/Controller/Tags.pm +++ b/lib/BibSpace/Controller/Tags.pm @@ -6,6 +6,7 @@ use Data::Dumper; use utf8; use Text::BibTeX; # parsing bib files use DateTime; + # use File::Slurp; use v5.16; #because of ~~ @@ -29,18 +30,18 @@ sub index { my $letter = $self->param('letter'); my $type = $self->param('type') // 1; - my @all_tags = $self->app->repo->tags_filter( sub { $_->type == $type } ); + my @all_tags = $self->app->repo->tags_filter(sub { $_->type == $type }); my @tags = @all_tags; - if ( defined $letter ) { - @tags = grep { ( substr( $_->name, 0, 1 ) cmp $letter ) == 0 } @all_tags; + if (defined $letter) { + @tags = grep { (substr($_->name, 0, 1) cmp $letter) == 0 } @all_tags; } - my @letters_arr = map { substr( $_->name, 0, 1 ) } @all_tags; + my @letters_arr = map { substr($_->name, 0, 1) } @all_tags; @letters_arr = uniq @letters_arr; @letters_arr = sort @letters_arr; @tags = sort { $a->name cmp $b->name } @tags; - $self->stash( otags => \@tags, type => $type, letters_arr => \@letters_arr ); - $self->render( template => 'tags/tags' ); + $self->stash(otags => \@tags, type => $type, letters_arr => \@letters_arr); + $self->render(template => 'tags/tags'); } #################################################################################### @@ -49,7 +50,7 @@ sub add { my $dbh = $self->app->db; my $type = $self->param('type') // 1; - $self->render( template => 'tags/add', type => $type ); + $self->render(template => 'tags/add', type => $type); } #################################################################################### @@ -58,21 +59,23 @@ sub add_post { my $tag_type = $self->param('type') // 1; my $tags_to_add = $self->param('new_tag'); - my @tags; my @tag_names; - if ( defined $tags_to_add ) { - my @pre_tag_names = split( ';', $tags_to_add ); + if (defined $tags_to_add) { + my @pre_tag_names = split(';', $tags_to_add); foreach my $tag (@pre_tag_names) { $tag = clean_tag_name($tag); - if ( defined $tag and $tag ne '' and length($tag) > 0 ) { + if (defined $tag and $tag ne '' and length($tag) > 0) { push @tag_names, $tag if defined $tag; } } foreach my $tag_name (@tag_names) { - my $new_tag = $self->app->entityFactory->new_Tag( name => $tag_name, type => $tag_type ); - + my $new_tag = $self->app->entityFactory->new_Tag( + name => $tag_name, + type => $tag_type + ); + $self->app->repo->tags_save($new_tag); $self->app->logger->info("Added new tag '$tag_name' type '$tag_type'."); push @tags, $new_tag; @@ -80,16 +83,16 @@ sub add_post { } } - - $self->flash( msg => "The following tags (of type $tag_type) were added successfully: " . " " - . join( ", ", map { $_->name } @tags ) + $self->flash( + msg => "The following tags (of type $tag_type) were added successfully: " + . " " + . join(", ", map { $_->name } @tags) . " ," . " ids: " - . join( ", ", map { $_->id } @tags ) - . "" ) + . join(", ", map { $_->id } @tags) . "") if scalar @tags > 0; - $self->redirect_to( $self->url_for( 'all_tags', type => $tag_type ) ); + $self->redirect_to($self->url_for('all_tags', type => $tag_type)); # $self->render(template => 'tags/add'); } @@ -105,7 +108,7 @@ sub edit { my $new_type = $self->param('new_type') || undef; my $saved = 0; - my $tag = $self->app->repo->tags_find( sub { $_->id == $id } ); + my $tag = $self->app->repo->tags_find(sub { $_->id == $id }); $tag->name($new_name) if defined $new_name; $tag->permalink($new_permalink) if defined $new_permalink; @@ -113,10 +116,10 @@ sub edit { $self->app->repo->tags_update($tag); - $self->flash( msg_type => 'success', msg => 'Changes saved.' ); + $self->flash(msg_type => 'success', msg => 'Changes saved.'); - $self->stash( tagobj => $tag ); - $self->render( template => 'tags/edit' ); + $self->stash(tagobj => $tag); + $self->render(template => 'tags/edit'); } @@ -127,56 +130,60 @@ sub get_authors_for_tag_and_team { my $tag_id = $self->param('tag_id'); my $team_id = $self->param('team_id'); - my $tag = $self->app->repo->tags_find( sub { $_->id == $tag_id } ); - if( !$tag ){ - $tag = $self->app->repo->tags_find( sub { $_->name eq $tag_id } ); + my $tag = $self->app->repo->tags_find(sub { $_->id == $tag_id }); + if (!$tag) { + $tag = $self->app->repo->tags_find(sub { $_->name eq $tag_id }); } - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); - if( !$team ){ - $team = $self->app->repo->teams_find( sub { $_->name eq $team_id } ); + my $team = $self->app->repo->teams_find(sub { $_->id == $team_id }); + if (!$team) { + $team = $self->app->repo->teams_find(sub { $_->name eq $team_id }); } - if ( !defined $tag ) { - $self->render( text => "Tag $tag_id does not exist", status => 404 ); + if (!defined $tag) { + $self->render(text => "Tag $tag_id does not exist", status => 404); return; } - if ( defined $team_id and !defined $team ) { - $self->render( text => "Team $team_id does not exist", status => 404 ); + if ((defined $team_id) and (!defined $team)) { + $self->render(text => "Team $team_id does not exist", status => 404); return; } my @authors = $tag->get_authors($dbh); - @authors = grep {$_->has_team($team)} @authors; + @authors = grep { $_->has_team($team) } @authors; - $self->stash( tag => $tag, authors => \@authors ); - $self->render( template => 'tags/authors_having_tag_read' ); + $self->stash(tag => $tag, authors => \@authors); + $self->render(template => 'tags/authors_having_tag_read'); } #################################################################################### sub get_tags_for_author_read { my $self = shift; my $author_id = $self->param('author_id'); - my $author = $self->app->repo->authors_find( sub { $_->id == $author_id } ); - if( !$author ){ - $author = $self->app->repo->authors_find( sub { $_->get_master->uid eq $author_id } ); + my $author = $self->app->repo->authors_find(sub { $_->id == $author_id }); + if (!$author) { + $author + = $self->app->repo->authors_find(sub { $_->get_master->uid eq $author_id } + ); } - if( !$author ){ - $author = $self->app->repo->authors_find( sub { $_->uid eq $author_id } ); + if (!$author) { + $author = $self->app->repo->authors_find(sub { $_->uid eq $author_id }); } - if ( !$author ) { - $self->render( text => "Cannot find author $author_id.", status => 404 ); + if (!$author) { + $self->render(text => "Cannot find author $author_id.", status => 404); return; } my @author_tags = $author->get_tags; - if ( !@author_tags ) { - $self->render( text => "Author $author_id has no tagged papers.", status => 200 ); + if (!@author_tags) { + $self->render( + text => "Author $author_id has no tagged papers.", + status => 200 + ); return; } - ### here list of objects should be created my @tagc_cloud_arr; @@ -184,14 +191,18 @@ sub get_tags_for_author_read { foreach my $tag (@author_tags) { - my $tag_name = $tag->{name}; $tag_name =~ s/_/\ /g; - my @objs = Fget_publications_main_hashed_args( $self, { hidden => 0, author => $author->{id}, tag => $tag->{id} } ); + my @objs = Fget_publications_main_hashed_args($self, + {hidden => 0, author => $author->{id}, tag => $tag->{id}}); my $count = scalar @objs; - my $url - = $self->url_for('lyp')->query( author => $author->{master}, tag => $tag_name, title => '1', navbar => '1' ); + my $url = $self->url_for('lyp')->query( + author => $author->{master}, + tag => $tag_name, + title => '1', + navbar => '1' + ); my $tag_cloud_obj = TagCloud->new(); $tag_cloud_obj->{url} = $url; @@ -201,84 +212,98 @@ sub get_tags_for_author_read { push @tagc_cloud_arr, $tag_cloud_obj; } - @sorted_tagc_cloud_arr = reverse sort { $a->{count} <=> $b->{count} } @tagc_cloud_arr; + @sorted_tagc_cloud_arr + = reverse sort { $a->{count} <=> $b->{count} } @tagc_cloud_arr; ### old code - $self->stash( tags => \@author_tags, author => $author, tcarr => \@sorted_tagc_cloud_arr ); - $self->render( template => 'tags/author_tags_read' ); + $self->stash( + tags => \@author_tags, + author => $author, + tcarr => \@sorted_tagc_cloud_arr + ); + $self->render(template => 'tags/author_tags_read'); } #################################################################################### # we mean here tags of type 1 sub get_tags_for_team_read { - my $self = shift; - my $team_id = $self->param('team_id'); - my $tag_type = 1; + my $self = shift; + my $team_id = $self->param('team_id'); + my $tag_type = 1; - my $team = $self->app->repo->teams_find( sub { $_->id == $team_id } ); - $team ||= $self->app->repo->teams_find( sub { $_->name eq $team_id } ); + my $team = $self->app->repo->teams_find(sub { $_->id == $team_id }); + $team ||= $self->app->repo->teams_find(sub { $_->name eq $team_id }); - - if ( !$team ) { - $self->render( text => "404. Team '$team_id' does not exist.", status => 404 ); + if (!$team) { + $self->render( + text => "404. Team '$team_id' does not exist.", + status => 404 + ); return; } my @team_entries = grep { $_->has_team($team) } $self->app->repo->entries_all; my %team_tags_hash; foreach my $paper (@team_entries) { + # merge two hashes - %team_tags_hash = (%team_tags_hash, map { "".$_->name => $_} $paper->get_tags($tag_type) ); + %team_tags_hash = (%team_tags_hash, + map { "" . $_->name => $_ } $paper->get_tags($tag_type)); } my @team_tags = values %team_tags_hash; - - if ( !@team_tags ) { - $self->render( text => "Team '$team_id' has no tagged papers.", status => 200 ); + if (!@team_tags) { + $self->render( + text => "Team '$team_id' has no tagged papers.", + status => 200 + ); return; } - my @tagc_cloud_arr; my @sorted_tagc_cloud_arr; foreach my $tag (@team_tags) { my $tag_name = $tag->name; $tag_name =~ s/_/\ /g; - + # FIXME: not all papers belong to team # FIXME: take exceptions into account - my @papers = grep { $_->has_team($team) } $tag->get_entries; - + my @papers = grep { $_->has_team($team) } $tag->get_entries; - my $url = "".$self->url_for('lyp')->query( team => $team->name, tag => $tag->name, title => '1', navbar => '1' ); + my $url = "" + . $self->url_for('lyp')->query( + team => $team->name, + tag => $tag->name, + title => '1', + navbar => '1' + ); my $tag_cloud_obj = TagCloud->new( url => $url, - count => "".scalar(@papers), + count => "" . scalar(@papers), name => $tag_name, ); push @tagc_cloud_arr, $tag_cloud_obj; } - @sorted_tagc_cloud_arr = reverse sort { - $a->count <=> $b->count - or $b->name cmp $a->name - } @tagc_cloud_arr; + @sorted_tagc_cloud_arr + = reverse sort { $a->count <=> $b->count or $b->name cmp $a->name } + @tagc_cloud_arr; - $self->stash( tcarr => \@sorted_tagc_cloud_arr ); - $self->render( template => 'tags/author_tags_read' ); + $self->stash(tcarr => \@sorted_tagc_cloud_arr); + $self->render(template => 'tags/author_tags_read'); } #################################################################################### sub get_authors_for_tag { - my $self = shift; - my $tag_id = $self->param('id'); + my $self = shift; + my $tag_id = $self->param('id'); - my $tag = $self->app->repo->tags_find( sub { $_->id == $tag_id } ); - if ( !defined $tag ) { - $self->render( text => "404. Tag '$tag_id' does not exist.", status => 404 ); + my $tag = $self->app->repo->tags_find(sub { $_->id == $tag_id }); + if (!defined $tag) { + $self->render(text => "404. Tag '$tag_id' does not exist.", status => 404); return; } @@ -288,13 +313,16 @@ sub get_authors_for_tag { my @subset_authors = map { $_->author } $paper->authorships_all; push @subset_authors, @authors; } - if ( !@authors ) { - $self->render( text => "There are no authors having papers with tag $tag_id.", status => 200 ); + if (!@authors) { + $self->render( + text => "There are no authors having papers with tag $tag_id.", + status => 200 + ); return; } - $self->stash( tag => $tag, authors => \@authors ); - $self->render( template => 'tags/authors_having_tag' ); + $self->stash(tag => $tag, authors => \@authors); + $self->render(template => 'tags/authors_having_tag'); } #################################################################################### @@ -302,31 +330,34 @@ sub delete { my $self = shift; my $id = $self->param('id'); - my $tag = $self->app->repo->tags_find( sub { $_->id == $id } ); + my $tag = $self->app->repo->tags_find(sub { $_->id == $id }); if ($tag) { my $name = $tag->name; ## TODO: refactor these blocks nicely! ## Deleting labelings my @labelings = $tag->labelings_all; + # for each entry, remove labeling in this team - foreach my $labeling ( @labelings ){ - $labeling->entry->remove_labeling($labeling); + foreach my $labeling (@labelings) { + $labeling->entry->remove_labeling($labeling); } $self->app->repo->labelings_delete(@labelings); + # remove all labelings for this team $tag->labelings_clear; + # finally delete tag $self->app->repo->tags_delete($tag); - $self->flash( msg_type => 'success', msg => "Tag $name has been deleted." ); + $self->flash(msg_type => 'success', msg => "Tag $name has been deleted."); $self->app->logger->info("Tag $name has been deleted."); } else { - $self->flash( msg_type => 'danger', msg => "Tag $id can not be deleted." ); + $self->flash(msg_type => 'danger', msg => "Tag $id can not be deleted."); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### 1; diff --git a/lib/BibSpace/Controller/Tagtypes.pm b/lib/BibSpace/Controller/Tagtypes.pm index b76f5a1..4f2c3ac 100644 --- a/lib/BibSpace/Controller/Tagtypes.pm +++ b/lib/BibSpace/Controller/Tagtypes.pm @@ -4,13 +4,13 @@ use Data::Dumper; use utf8; use Text::BibTeX; # parsing bib files use DateTime; + # use File::Slurp; use v5.16; #because of ~~ use strict; use warnings; - use BibSpace::Functions::Core; use BibSpace::Model::TagType; @@ -20,105 +20,103 @@ use Mojo::Log; #################################################################################### sub index { - my $self = shift; - my @tag_types = $self->app->repo->tagTypes_all; - $self->render( template => 'tagtypes/tagtypes', tagtypes => \@tag_types ); + my $self = shift; + my @tag_types = $self->app->repo->tagTypes_all; + $self->render(template => 'tagtypes/tagtypes', tagtypes => \@tag_types); } #################################################################################### sub add { - my $self = shift; - $self->render( template => 'tagtypes/add' ); + my $self = shift; + $self->render(template => 'tagtypes/add'); } #################################################################################### sub add_post { - my $self = shift; - my $dbh = $self->app->db; - my $name = $self->param('new_name'); - my $comment = $self->param('new_comment'); - - my $tt = $self->app->repo->tagTypes_find( sub { $_->name eq $name } ); - - if ( defined $tt ) { - $self->flash( - msg_type => 'error', - msg => 'Tag type with such name already exists.' - ); - } - else{ - $tt = $self->app->entityFactory->new_TagType(name => $name, comment => $comment); - $self->app->repo->tagTypes_save($tt); - $self->flash( msg_type => 'success', msg => 'Tag type added.' ); - } - - $self->redirect_to( $self->url_for('all_tag_types') ); + my $self = shift; + my $dbh = $self->app->db; + my $name = $self->param('new_name'); + my $comment = $self->param('new_comment'); + + my $tt = $self->app->repo->tagTypes_find(sub { $_->name eq $name }); + + if (defined $tt) { + $self->flash( + msg_type => 'error', + msg => 'Tag type with such name already exists.' + ); + } + else { + $tt = $self->app->entityFactory->new_TagType( + name => $name, + comment => $comment + ); + $self->app->repo->tagTypes_save($tt); + $self->flash(msg_type => 'success', msg => 'Tag type added.'); + } + + $self->redirect_to($self->url_for('all_tag_types')); } #################################################################################### sub delete { - my $self = shift; - my $id = $self->param('id'); + my $self = shift; + my $id = $self->param('id'); - # we do not allow to delete the two first tag types! - if ( $id == 1 or $id == 2 ) { - $self->flash( - msg_type => 'error', - msg => 'Tag Types 1 or 2 are essential and cannot be deleted.' - ); - $self->redirect_to( $self->url_for('all_tag_types') ); - return; - } + # we do not allow to delete the two first tag types! + if ($id == 1 or $id == 2) { + $self->flash( + msg_type => 'error', + msg => 'Tag Types 1 or 2 are essential and cannot be deleted.' + ); + $self->redirect_to($self->url_for('all_tag_types')); + return; + } - my $tt = $self->app->repo->tagTypes_find( sub { $_->id == $id } ); + my $tt = $self->app->repo->tagTypes_find(sub { $_->id == $id }); - my @tags_of_tag_type = $self->app->repo->tags_filter( sub { $_->type == $id } ); - $self->app->repo->tags_delete(@tags_of_tag_type); - $self->app->repo->tagTypes_delete($tt); + my @tags_of_tag_type = $self->app->repo->tags_filter(sub { $_->type == $id }); + $self->app->repo->tags_delete(@tags_of_tag_type); + $self->app->repo->tagTypes_delete($tt); - $self->flash( msg_type => 'success', msg => 'Tag type deleted.' ); + $self->flash(msg_type => 'success', msg => 'Tag type deleted.'); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### sub edit { - my $self = shift; - my $id = $self->param('id'); - - my $name = $self->param('new_name'); - my $comment = $self->param('new_comment'); - my $saved = 0; - - - my $tt = $self->app->repo->tagTypes_find( sub { $_->id == $id } ); - - if ( !defined $tt ) { - $self->flash( - msg_type => 'error', - msg => 'Tag Type does not exist.' - ); - $self->redirect_to( $self->url_for('all_tag_types') ); - return; - } - - if ( defined $name or defined $comment ) { - $tt->name($name) if defined $name; - $tt->comment($comment) if defined $comment; - $self->app->repo->tagTypes_update($tt); - - $self->flash( msg_type => 'success', msg => 'Update successful.' ); - $self->redirect_to( $self->url_for('all_tag_types') ); - return; - } - else { - $self->flash( - msg_type => 'warning', - msg => 'No change made or empty input.' - ); - } - - $self->stash( obj => $tt ); - $self->render( template => 'tagtypes/edit' ); - + my $self = shift; + my $id = $self->param('id'); + + my $name = $self->param('new_name'); + my $comment = $self->param('new_comment'); + my $saved = 0; + + my $tt = $self->app->repo->tagTypes_find(sub { $_->id == $id }); + + if (!defined $tt) { + $self->flash(msg_type => 'error', msg => 'Tag Type does not exist.'); + $self->redirect_to($self->url_for('all_tag_types')); + return; + } + + if (defined $name or defined $comment) { + $tt->name($name) if defined $name; + $tt->comment($comment) if defined $comment; + $self->app->repo->tagTypes_update($tt); + + $self->flash(msg_type => 'success', msg => 'Update successful.'); + $self->redirect_to($self->url_for('all_tag_types')); + return; + } + else { + $self->flash( + msg_type => 'warning', + msg => 'No change made or empty input.' + ); + } + + $self->stash(obj => $tt); + $self->render(template => 'tagtypes/edit'); } #################################################################################### diff --git a/lib/BibSpace/Controller/Teams.pm b/lib/BibSpace/Controller/Teams.pm index 3e8e5d9..30ca499 100644 --- a/lib/BibSpace/Controller/Teams.pm +++ b/lib/BibSpace/Controller/Teams.pm @@ -2,6 +2,7 @@ package BibSpace::Controller::Teams; use utf8; use DateTime; + # use File::Slurp; use v5.16; #because of ~~ @@ -20,58 +21,62 @@ use Mojo::Base 'Mojolicious::Plugin::Config'; sub show { my $self = shift; my @teams = $self->app->repo->teams_all; - $self->stash( teams => \@teams ); - $self->render( template => 'teams/teams', layout => 'admin' ); + $self->stash(teams => \@teams); + $self->render(template => 'teams/teams', layout => 'admin'); } ################################################################################################################ sub edit { my $self = shift; my $id = $self->param('id'); - my $team = $self->app->repo->teams_find( sub { $_->id == $id } ); + my $team = $self->app->repo->teams_find(sub { $_->id == $id }); - if ( !defined $team ) { - $self->flash( msg => "There is no team with id $id", msg_type => 'danger' ); - $self->redirect_to( $self->get_referrer ); + if (!defined $team) { + $self->flash(msg => "There is no team with id $id", msg_type => 'danger'); + $self->redirect_to($self->get_referrer); return; } my @team_members = $team->get_members; - - $self->stash( members => \@team_members, team => $team ); - $self->render( template => 'teams/members' ); + $self->stash(members => \@team_members, team => $team); + $self->render(template => 'teams/members'); } ################################################################################################################ sub add_team { my $self = shift; - $self->render( template => 'teams/add_team' ); + $self->render(template => 'teams/add_team'); } ############################################################################################################## sub add_team_post { my $self = shift; my $new_team_name = $self->param('new_team'); + my $existing_mteam + = $self->app->repo->teams_find(sub { $_->name eq $new_team_name }); - my $existing_mteam = $self->app->repo->teams_find( sub { $_->name eq $new_team_name } ); - - if ( defined $existing_mteam ) { - $self->app->logger->info( "add new team: team with proposed name ($new_team_name) exists!!" ); - $self->flash( msg => "Team with such name exists already! Pick a different one." ); - $self->redirect_to( $self->url_for('add_team_get') ); + if (defined $existing_mteam) { + $self->app->logger->info( + "add new team: team with proposed name ($new_team_name) exists!!"); + $self->flash( + msg => "Team with such name exists already! Pick a different one."); + $self->redirect_to($self->url_for('add_team_get')); return; } my $new_mteam = $self->app->entityFactory->new_Team(name => $new_team_name); $self->app->repo->teams_save($new_mteam); my $new_team_id = $new_mteam->id; - if ( !defined $new_team_id or $new_team_id <= 0 ) { - $self->flash( msg => "Something went wrong. The Team $new_team_name has not been added." ); - $self->redirect_to( $self->url_for('add_team_get') ); + if ( (!defined $new_team_id) or $new_team_id <= 0) { + $self->flash(msg => + "Something went wrong. The Team $new_team_name has not been added."); + $self->redirect_to($self->url_for('add_team_get')); return; } - $self->app->logger->info( "Add new team: Added new team with proposed name ($new_team_name). Team id is $new_team_id." ); - $self->redirect_to( 'edit_team', id => $new_team_id ); + $self->app->logger->info( + "Add new team: Added new team with proposed name ($new_team_name). Team id is $new_team_id." + ); + $self->redirect_to('edit_team', id => $new_team_id); } ############################################################################################################## @@ -79,19 +84,19 @@ sub delete_team { my $self = shift; my $id = $self->param('id'); - my $team = $self->app->repo->teams_find( sub { $_->id == $id } ); + my $team = $self->app->repo->teams_find(sub { $_->id == $id }); - if ( $team and $team->can_be_deleted ) { + if ($team and $team->can_be_deleted) { my $msg = "Team " . $team->name . " ID " . $team->id . " has been deleted"; - $self->app->logger->info( $msg ); - $self->flash( msg => $msg, msg_type => 'success' ); + $self->app->logger->info($msg); + $self->flash(msg => $msg, msg_type => 'success'); $self->do_delete_team($team); } else { - $self->flash( msg_type => 'warning', msg => "Unable to delete team id $id." ); + $self->flash(msg_type => 'warning', msg => "Unable to delete team id $id."); } - $self->redirect_to( $self->url_for('all_teams') ); + $self->redirect_to($self->url_for('all_teams')); } ############################################################################################################## @@ -100,18 +105,18 @@ sub delete_team_force { my $dbh = $self->app->db; my $id = $self->param('id'); - my $team = $self->app->repo->teams_find( sub { $_->id == $id } ); + my $team = $self->app->repo->teams_find(sub { $_->id == $id }); if ($team) { my $msg = "Team " . $team->name . " ID " . $team->id . " has been deleted"; - $self->app->logger->info( $msg ); - $self->flash( msg => $msg, msg_type => 'success' ); + $self->app->logger->info($msg); + $self->flash(msg => $msg, msg_type => 'success'); $self->do_delete_team($team); } - else{ - $self->flash( msg_type => 'warning', msg => "Unable to delete team id $id." ); + else { + $self->flash(msg_type => 'warning', msg => "Unable to delete team id $id."); } - $self->redirect_to( $self->url_for('all_teams') ); + $self->redirect_to($self->url_for('all_teams')); } ############################################################################################################## @@ -121,16 +126,17 @@ sub do_delete_team { ## Deleting memberships my @memberships = $team->memberships_all; + # for each team, remove membership in this team - foreach my $membership ( @memberships ){ - $membership->author->remove_membership($membership); + foreach my $membership (@memberships) { + $membership->author->remove_membership($membership); } $self->app->repo->memberships_delete(@memberships); + # remove all memberships for this team $team->memberships_clear; $self->app->repo->teams_delete($team); } ############################################################################################################## - 1; diff --git a/lib/BibSpace/Controller/Types.pm b/lib/BibSpace/Controller/Types.pm index baea45f..f204aee 100644 --- a/lib/BibSpace/Controller/Types.pm +++ b/lib/BibSpace/Controller/Types.pm @@ -2,7 +2,7 @@ package BibSpace::Controller::Types; use Data::Dumper; use utf8; -use v5.16; #because of ~~ +use v5.16; #because of ~~ use strict; use warnings; @@ -20,26 +20,26 @@ use Mojo::Log; sub all_our { my $self = shift; + my @types + = sort { $a->our_type cmp $b->our_type } $self->app->repo->types_all; - my @types = sort { $a->our_type cmp $b->our_type } $self->app->repo->types_all; - - $self->stash( otypes => \@types ); - $self->render( template => 'types/types' ); + $self->stash(otypes => \@types); + $self->render(template => 'types/types'); } #################################################################################### sub add_type { my $self = shift; - $self->render( template => 'types/add' ); + $self->render(template => 'types/add'); } #################################################################################### sub post_add_type { my $self = shift; my $new_type = $self->param('new_type'); - my $type = $self->app->entityFactory->new_Type(our_type => $new_type ); + my $type = $self->app->entityFactory->new_Type(our_type => $new_type); $self->app->repo->types_save($type); - $self->redirect_to( $self->url_for('all_types') ); + $self->redirect_to($self->url_for('all_types')); } #################################################################################### sub manage { @@ -47,19 +47,16 @@ sub manage { my $type_name = $self->param('name'); my @all = $self->app->repo->types_all; - my $type = $self->app->repo->types_find( sub { $_->our_type eq $type_name } ); - + my $type = $self->app->repo->types_find(sub { $_->our_type eq $type_name }); my @all_our_types = uniq map { $_->our_type } @all; my @all_bibtex_types = BibSpace::Functions::Core::official_bibtex_types; my @assigned_bibtex_types = $type->bibtexTypes_all; - # # cannot use objects as keysdue to stringification! my %types_hash = map { $_ => 1 } @assigned_bibtex_types; my @unassigned_btypes = grep { not $types_hash{$_} } @all_bibtex_types; - $self->stash( all_otypes => \@all_our_types, unassigned_btypes => \@unassigned_btypes, @@ -67,16 +64,17 @@ sub manage { assigned_btypes => \@assigned_bibtex_types, type => $type ); - $self->render( template => 'types/manage_types' ); + $self->render(template => 'types/manage_types'); } #################################################################################### sub toggle_landing { - my $self = shift; + my $self = shift; my $type_name = $self->param('name'); - my $type_obj = $self->app->repo->types_find( sub { $_->our_type eq $type_name } ); + my $type_obj + = $self->app->repo->types_find(sub { $_->our_type eq $type_name }); - if ( $type_obj->onLanding == 0 ) { + if ($type_obj->onLanding == 0) { $type_obj->onLanding(1); } else { @@ -84,36 +82,45 @@ sub toggle_landing { } $self->app->repo->types_update($type_obj); - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### sub post_store_description { my $self = shift; my $type_name = $self->param('our_type'); my $description = $self->param('new_description'); - my $type_obj = $self->app->repo->types_find( sub { $_->our_type eq $type_name } ); + my $type_obj + = $self->app->repo->types_find(sub { $_->our_type eq $type_name }); - if ( defined $type_obj and defined $description ) { + if (defined $type_obj and defined $description) { $type_obj->description($description); $self->app->repo->types_update($type_obj); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### sub delete_type { - my $self = shift; + my $self = shift; my $type_name = $self->param('name'); - my $type_obj = $self->app->repo->types_find( sub { $_->our_type eq $type_name } ); - if( $type_obj and $type_obj->can_be_deleted ){ - $self->app->repo->types_delete($type_obj); + my $type_obj + = $self->app->repo->types_find(sub { $_->our_type eq $type_name }); + if ($type_obj and $type_obj->can_be_deleted) { + $self->app->repo->types_delete($type_obj); - $self->flash( msg_type => 'success', message => "$type_name and its mappings have been deleted." ); + $self->flash( + msg_type => 'success', + message => "$type_name and its mappings have been deleted." + ); } - else{ - $self->flash( msg_type => 'warning', message => "$type_name cannot be deleted. Possible reasons: mappings exist or it is native bibtex type." ); + else { + $self->flash( + msg_type => 'warning', + message => + "$type_name cannot be deleted. Possible reasons: mappings exist or it is native bibtex type." + ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### sub map_types { @@ -121,11 +128,14 @@ sub map_types { my $o_type = $self->param('our_type'); my $b_type = $self->param('bibtex_type'); - my $type_obj = $self->app->repo->types_find( sub { $_->our_type eq $o_type } ); + my $type_obj = $self->app->repo->types_find(sub { $_->our_type eq $o_type }); - if ( !$o_type or !$b_type or !$type_obj ) { - $self->flash( message => "Cannot map. Incomplete input.", msg_type => 'danger' ); - $self->redirect_to( $self->get_referrer ); + if ((!$o_type) or (!$b_type) or (!$type_obj)) { + $self->flash( + message => "Cannot map. Incomplete input.", + msg_type => 'danger' + ); + $self->redirect_to($self->get_referrer); return; } @@ -135,16 +145,22 @@ sub map_types { if ($found) { $type_obj->bibtexTypes_add($b_type); $self->app->repo->types_update($type_obj); - $self->flash( message => "Mapping successful!", msg_type => 'success' ); + $self->flash(message => "Mapping successful!", msg_type => 'success'); } else { - $self->flash( message => "MAP ERROR: $b_type is not a valid bibtex type!", msg_type => 'danger' ); + $self->flash( + message => "MAP ERROR: $b_type is not a valid bibtex type!", + msg_type => 'danger' + ); } } else { - $self->flash( message => "Cannot map. Type not found.", msg_type => 'danger' ); + $self->flash( + message => "Cannot map. Type not found.", + msg_type => 'danger' + ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### @@ -153,29 +169,38 @@ sub unmap_types { my $o_type = $self->param('our_type'); my $b_type = $self->param('bibtex_type'); - my $type_obj = $self->app->repo->types_find( sub { $_->our_type eq $o_type } ); + my $type_obj = $self->app->repo->types_find(sub { $_->our_type eq $o_type }); - if ( !$b_type or !$type_obj ) { - $self->flash( message => "Cannot unmap. Incomplete input.", msg_type => 'danger' ); - $self->redirect_to( $self->get_referrer ); + if ((!$b_type) or (!$type_obj)) { + $self->flash( + message => "Cannot unmap. Incomplete input.", + msg_type => 'danger' + ); + $self->redirect_to($self->get_referrer); return; } elsif ($type_obj) { - my $idx_to_del = $type_obj->bibtexTypes_find_index( sub{ $_ eq $b_type } ); - if( $idx_to_del > -1 ){ - $type_obj->bibtexTypes_delete($idx_to_del); - $self->app->repo->types_update($type_obj); - $self->flash( message => "Unmapping successful!", msg_type => 'success' ); + my $idx_to_del = $type_obj->bibtexTypes_find_index(sub { $_ eq $b_type }); + if ($idx_to_del > -1) { + $type_obj->bibtexTypes_delete($idx_to_del); + $self->app->repo->types_update($type_obj); + $self->flash(message => "Unmapping successful!", msg_type => 'success'); } else { - $self->flash( message => "Unmap error: $b_type is not a valid bibtex type!", msg_type => 'danger' ); + $self->flash( + message => "Unmap error: $b_type is not a valid bibtex type!", + msg_type => 'danger' + ); } } else { - $self->flash( message => "Cannot unmap. Type not found.", msg_type => 'danger' ); + $self->flash( + message => "Cannot unmap. Type not found.", + msg_type => 'danger' + ); } - $self->redirect_to( $self->get_referrer ); + $self->redirect_to($self->get_referrer); } #################################################################################### diff --git a/lib/BibSpace/Converter/BibStyleConverter.pm b/lib/BibSpace/Converter/BibStyleConverter.pm index f48c9f1..c5bb93c 100644 --- a/lib/BibSpace/Converter/BibStyleConverter.pm +++ b/lib/BibSpace/Converter/BibStyleConverter.pm @@ -5,14 +5,13 @@ use BibSpace::Functions::Core; use List::MoreUtils qw(any uniq); - use Path::Tiny; use File::Spec; use Data::Dumper; use utf8; use Text::BibTeX; -use v5.16; +use v5.16; use Try::Tiny; use TeX::Encode; @@ -20,67 +19,64 @@ use Encode; use BibStyle::LocalBibStyle; - use Moose; use Moose::Util::TypeConstraints; use BibSpace::Util::ILogger; use BibSpace::Converter::IHtmlBibtexConverter; with 'IHtmlBibtexConverter'; -has 'logger' => ( is => 'ro', does => 'ILogger', required => 1 ); -has 'bst' => ( is => 'rw', isa => 'Maybe[Str]' ); -has 'html' => ( is => 'rw', isa => 'Maybe[Str]' ); +has 'logger' => (is => 'ro', does => 'ILogger', required => 1); +has 'bst' => (is => 'rw', isa => 'Maybe[Str]'); +has 'html' => (is => 'rw', isa => 'Maybe[Str]'); has 'warnings' => - ( is => 'rw', isa => 'Maybe[ArrayRef[Str]]', default => sub { [] } ); - + (is => 'rw', isa => 'Maybe[ArrayRef[Str]]', default => sub { [] }); sub set_template { - my ( $self, $template ) = @_; - $self->bst($template); + my ($self, $template) = @_; + $self->bst($template); } sub convert { - my ( $self, $bib, $bst ) = @_; - $bst ||= $self->bst; - die "Template not provided" unless $bst and -e $bst; - - - my ( $bbl_dirty, $dirty_bbl_array_ref, $warnings_arr_ref ) - = _convert_bib_to_bbl( $bib, $bst ); - $self->warnings($warnings_arr_ref); - # stateless call - my $clean_bbl = _clean_bbl($dirty_bbl_array_ref); - my $html_code = _add_html_links( $clean_bbl, $bib ); - $self->html($html_code); + my ($self, $bib, $bst) = @_; + $bst ||= $self->bst; + die "Template not provided" unless $bst and -e $bst; + + my ($bbl_dirty, $dirty_bbl_array_ref, $warnings_arr_ref) + = _convert_bib_to_bbl($bib, $bst); + $self->warnings($warnings_arr_ref); + + # stateless call + my $clean_bbl = _clean_bbl($dirty_bbl_array_ref); + my $html_code = _add_html_links($clean_bbl, $bib); + $self->html($html_code); } sub get_html { - my $self = shift; - $self->html; + my $self = shift; + $self->html; } sub get_warnings { - my $self = shift; - return @{ $self->warnings }; + my $self = shift; + return @{$self->warnings}; } #################################################################################### sub _convert_bib_to_bbl { my ($input_bib, $bst_file_path) = @_; - my $bibstyle = BibStyle::LocalBibStyle->new(); #Text::BibTeX::BibStyle->new(); die "Cannot find bst file under: $bst_file_path ." if !-e $bst_file_path; $bibstyle->read_bibstyle($bst_file_path); my $bbl = $bibstyle->execute([], $input_bib); - my $out = $bibstyle->get_output(); - + my $out = $bibstyle->get_output(); + my @bibstyle_output = @{$bibstyle->{output}}; my $warnings_arr_ref = $bibstyle->{warnings}; - my $bbl_dirty = join '', @bibstyle_output ; - my $dirty_bbl_array_ref = \@bibstyle_output ; + my $bbl_dirty = join '', @bibstyle_output; + my $dirty_bbl_array_ref = \@bibstyle_output; return ($bbl_dirty, $dirty_bbl_array_ref, $warnings_arr_ref); } @@ -93,26 +89,28 @@ sub _clean_bbl { my @arr = @{$bbl_arr_ref}; my @useful_lines; - foreach my $f (@arr){ + foreach my $f (@arr) { chomp $f; - # fix strange commas - # before: J\'{o}akim von Kistowski, , Hansfried Block, , John Beckett, , Cloyce Spradling, , Klaus-Dieter Lange, , and Samuel Kounev, . - # after: J\'{o}akim von Kistowski, Hansfried Block, John Beckett, Cloyce Spradling, Klaus-Dieter Lange, and Samuel Kounev. +# fix strange commas +# before: J\'{o}akim von Kistowski, , Hansfried Block, , John Beckett, , Cloyce Spradling, , Klaus-Dieter Lange, , and Samuel Kounev, . +# after: J\'{o}akim von Kistowski, Hansfried Block, John Beckett, Cloyce Spradling, Klaus-Dieter Lange, and Samuel Kounev. $f =~ s/(\w+),\s+,/$1,/g; $f =~ s/(\w+),\s+([\.,])/$1$2/g; - - if($f =~ m/^\\begin/ or $f =~ m/^\\end/){ + + if ($f =~ m/^\\begin/ or $f =~ m/^\\end/) { + # say "BB".$f; } - elsif($f =~ m/\\bibitem/){ + elsif ($f =~ m/\\bibitem/) { + # say "II".$f; push @useful_lines, $f; } - elsif($f =~ m/^\s*$/){ # line containing only whitespaces + elsif ($f =~ m/^\s*$/) { # line containing only whitespaces ; } - else{ + else { push @useful_lines, $f; } } @@ -120,35 +118,37 @@ sub _clean_bbl { my $useful_str = join '', @useful_lines; my $s = $useful_str; - # say "\nXXXX1\n".$s."\nXXXX\n"; - $s =~ s/\\newblock/\n\\newblock/g; # every newblock = newline in bbl (but not in html!) - $s =~ s/\\bibitem\{([^\}]*)\}/\\bibitem\{$1\}\n/; # new line after the bibtex key + $s =~ s/\\newblock/\n\\newblock/g + ; # every newblock = newline in bbl (but not in html!) + $s =~ s/\\bibitem\{([^\}]*)\}/\\bibitem\{$1\}\n/ + ; # new line after the bibtex key - my ($bibtex_key, $rest) = $s =~ m/\\bibitem\{([^\}.]*)\}(.*)/; # match until the first closing bracket - # extract the bibtex key and the rest - just in case you need it + my ($bibtex_key, $rest) + = $s + =~ m/\\bibitem\{([^\}.]*)\}(.*)/; # match until the first closing bracket + # extract the bibtex key and the rest - just in case you need it - $s =~ s/\\bibitem\{([^\}]*)\}\n?//; #remove first line with bibitem - $s =~ s/\\newblock\s+//g; # remove newblocks + $s =~ s/\\bibitem\{([^\}]*)\}\n?//; #remove first line with bibitem + $s =~ s/\\newblock\s+//g; # remove newblocks +# nested parenthesis cannot be handled with regexp :( +# I use this because it counts brackets! +# string_replace_with_counting($s, $opening, $closing, $avoid_l, $avoid_r, $opening_replace, $closing_replace) + $s = string_replace_with_counting($s, '{\\em', '}', '{', '}', + '', ''); - # nested parenthesis cannot be handled with regexp :( - # I use this because it counts brackets! - # string_replace_with_counting($s, $opening, $closing, $avoid_l, $avoid_r, $opening_replace, $closing_replace) - $s = string_replace_with_counting($s, '{\\em', '}', '{', '}', '', ''); - # if there are more (what is very rare), just ignore $s = string_replace_with_counting($s, '{\\em', '}', '{', '}', '', ''); - # find all that is between {}, count all pairs of {} replace the outermost with nothing - # does {zzz {aaa} ggg} => zzz {aaa} ggg - - $s = string_replace_with_counting($s, '\\url{', '}', '{', '}', '', ''); +# find all that is between {}, count all pairs of {} replace the outermost with nothing +# does {zzz {aaa} ggg} => zzz {aaa} ggg + $s = string_replace_with_counting($s, '\\url{', '}', '{', '}', + '', ''); - - # and here are the custom replacement functions in case something goes wrong... + # and here are the custom replacement functions in case something goes wrong... $s = german_letters_latex_to_html($s); $s = polish_letters_latex_to_html($s); $s = other_letters_latex_to_html($s); @@ -157,25 +157,24 @@ sub _clean_bbl { my $new_s = ""; $new_s = string_replace_with_counting($s, '{', '}', '{', '}', '', ''); - while($new_s ne $s){ + while ($new_s ne $s) { $s = $new_s; $new_s = string_replace_with_counting($s, '{', '}', '{', '}', '', ''); } - $s = str_replace_as_pod_latex($s); # this should catch everything but it doesn't + $s = str_replace_as_pod_latex($s) + ; # this should catch everything but it doesn't - $s =~ s!\\%!%!g; # replace % escape - $s =~ s!\\&!&!g; # replace & escape + $s =~ s!\\%!%!g; # replace % escape + $s =~ s!\\&!&!g; # replace & escape return $s; } - - #################################################################################### sub _add_html_links { my ($bbl_clean, $bib) = @_; - + my $s = $bbl_clean; my $entry = new Text::BibTeX::Entry(); @@ -193,106 +192,113 @@ sub _add_html_links { my @code = (); - if($entry->exists('pdf')){ + if ($entry->exists('pdf')) { push @code, build_link('pdf', $entry->get('pdf')); } - if($entry->exists('slides')){ + if ($entry->exists('slides')) { push @code, build_link('slides', $entry->get('slides')); } - if($entry->exists('doi')){ - push @code, build_link('DOI', "http://dx.doi.org/".$entry->get('doi')); + if ($entry->exists('doi')) { + push @code, build_link('DOI', "http://dx.doi.org/" . $entry->get('doi')); } - if($entry->exists('url')){ + if ($entry->exists('url')) { push @code, build_link('http', $entry->get('url')); } my $abstract_preview_a; my $abstract_preview_div; - if($entry->exists('abstract')){ + if ($entry->exists('abstract')) { my $content = $entry->get('abstract'); - # $abstract_preview_a = 'abstract'; - $abstract_preview_a = 'abstract'; - # $abstract_preview_div = ''; - $abstract_preview_div = '