Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package MirrorCache for openSUSE:Factory 
checked in at 2023-10-05 20:05:11
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/MirrorCache (Old)
 and      /work/SRC/openSUSE:Factory/.MirrorCache.new.28202 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "MirrorCache"

Thu Oct  5 20:05:11 2023 rev:33 rq:1115804 version:1.065

Changes:
--------
--- /work/SRC/openSUSE:Factory/MirrorCache/MirrorCache.changes  2023-09-21 
22:22:55.556598846 +0200
+++ /work/SRC/openSUSE:Factory/.MirrorCache.new.28202/MirrorCache.changes       
2023-10-05 20:06:32.238048591 +0200
@@ -1,0 +2,11 @@
+Thu Sep 28 10:12:08 UTC 2023 - Andrii Nikitin <andrii.niki...@suse.com>
+
+- Update to version 1.065:
+  * ui: Use https when applicable on mirrors report (#411)
+  * ui: Show country flag in mirror report (#411)
+  * ui: Tweak mirrors report (#411)
+  * ui: Remove tidy warnings from openSUSE branding (#411)
+  * ui: Add mirror details page (#411)
+  * Remove dark theme css code for Mirrors page (#408)
+
+-------------------------------------------------------------------

Old:
----
  MirrorCache-1.064.obscpio

New:
----
  MirrorCache-1.065.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ MirrorCache.spec ++++++
--- /var/tmp/diff_new_pack.YobdME/_old  2023-10-05 20:06:33.778104228 +0200
+++ /var/tmp/diff_new_pack.YobdME/_new  2023-10-05 20:06:33.778104228 +0200
@@ -22,7 +22,7 @@
 %define main_requires %{assetpack_requires} perl(Carp) perl(DBD::Pg) >= 3.7.4 
perl(DBI) >= 1.632 perl(DBIx::Class) >= 0.082801 
perl(DBIx::Class::DynamicDefault) perl(DateTime) perl(Encode) perl(Time::Piece) 
perl(Time::Seconds) perl(Time::ParseDate) perl(DateTime::Format::Pg) 
perl(Exporter) perl(File::Basename) perl(LWP::UserAgent) perl(Mojo::Base) 
perl(Mojo::ByteStream) perl(Mojo::IOLoop) perl(Mojo::JSON) perl(Mojo::Pg) 
perl(Mojo::URL) perl(Mojo::Util) perl(Mojolicious::Commands) 
perl(Mojolicious::Plugin) perl(Mojolicious::Plugin::RenderFile) 
perl(Mojolicious::Static) perl(Net::OpenID::Consumer) perl(POSIX) 
perl(Sort::Versions) perl(URI::Escape) perl(XML::Writer) perl(base) 
perl(constant) perl(diagnostics) perl(strict) perl(warnings) shadow 
rubygem(sass) perl(Net::DNS) perl(LWP::Protocol::https) perl(Digest::SHA) 
perl(Config::IniFiles)
 %define build_requires %{assetpack_requires} rubygem(sass) tidy sysuser-shadow 
sysuser-tools
 Name:           MirrorCache
-Version:        1.064
+Version:        1.065
 Release:        0
 Summary:        WebApp to redirect and manage mirrors
 License:        GPL-2.0-or-later

++++++ MirrorCache-1.064.obscpio -> MirrorCache-1.065.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/assets/assetpack.def 
new/MirrorCache-1.065/assets/assetpack.def
--- old/MirrorCache-1.064/assets/assetpack.def  2023-09-14 08:46:25.000000000 
+0200
+++ new/MirrorCache-1.065/assets/assetpack.def  2023-09-28 12:08:56.000000000 
+0200
@@ -121,6 +121,7 @@
 < javascripts/admintable.js
 < javascripts/admin_user.js
 < javascripts/audit_log.js
+< javascripts/server.js
 < 
https://raw.githubusercontent.com/bootstrapthemesco/bootstrap-4-multi-dropdown-navbar/beta2.0/js/bootstrap-4-navbar.js
 < https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.js
 < https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.js
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/assets/javascripts/admintable.js 
new/MirrorCache-1.065/assets/javascripts/admintable.js
--- old/MirrorCache-1.064/assets/javascripts/admintable.js      2023-09-14 
08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/assets/javascripts/admintable.js      2023-09-28 
12:08:56.000000000 +0200
@@ -281,6 +281,29 @@
     return result;
 }
 
+function renderAdminTableHostname(data, type, row, meta) {
+    if (type !== 'display') {
+        return data ? data : '';
+    }
+    if (isEditingAdminTableRow(meta)) {
+        return '<input type="text" value="' + htmlEscape(data) + '"/>';
+    }
+    return data? '<a href="/app/server/'+ htmlEscape(data) +'">' + 
htmlEscape(data) + '</>' : '';
+}
+
+function renderAdminTableLongText(data, type, row, meta) {
+    if (type !== 'display') {
+        return data ? data : '';
+    }
+    if (isEditingAdminTableRow(meta)) {
+        return '<input type="text" value="' + htmlEscape(data) + '"/>';
+    }
+    if (data && data.length > 25) {
+        return data.substring(0, 21) + '...';
+    }
+    return data ? data : '';
+}
+
 function renderAdminTableDescription(data, type, row, meta) {
     if (type !== 'display') {
         return data ? data : '';
@@ -374,7 +397,13 @@
             type: 'empty-string-last',
         };
         if (th.hasClass('col_value')) {
-            columnDef.render = renderAdminTableValue;
+            if (columnName == 'hostname') {
+                columnDef.render = renderAdminTableHostname;
+            } else if (columnName == 'public notes' || columnName == 'comment' 
|| columnName == 'sponsor') {
+                columnDef.render = renderAdminTableLongText;
+            } else {
+                columnDef.render = renderAdminTableValue;
+            }
             emptyRow[columnName] = "";
         } else if (th.hasClass('col_settings')) {
             columnDef.render = renderAdminTableSettings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/assets/javascripts/server.js 
new/MirrorCache-1.065/assets/javascripts/server.js
--- old/MirrorCache-1.064/assets/javascripts/server.js  1970-01-01 
01:00:00.000000000 +0100
+++ new/MirrorCache-1.065/assets/javascripts/server.js  2023-09-28 
12:08:56.000000000 +0200
@@ -0,0 +1,77 @@
+function setupServerNote(hostname) {
+    var table = $('#server_note');
+    var dataTable = table.DataTable({
+        ajax: {
+            url: '/rest/server/note/' + hostname,
+        },
+        deferRender: true,
+        columns: [{data: 'dt'}, {data: 'acc'}, {data: 'kind'}, {data: 'msg'}],
+        order: [[0, 'desc']],
+        initComplete: function () {
+            this.api()
+                .columns()
+                .every(function () {
+                    var column = this;
+                    var colheader = this.header();
+                    var title = $(colheader).text().trim();
+                    if (title !== 'Kind') {
+                        return false;
+                    }
+
+                    var select = $('<select id="select_kind"><option 
value="">All</option></select>')
+                        .appendTo($(column.header()).empty())
+                        .on('change', function () {
+                            var val = 
$.fn.dataTable.util.escapeRegex($(this).val());
+                            column
+                                // .search( val ? '^'+val+'$' : '', true, 
false )
+                                .search(val ? val : '', true, false)
+                                .draw();
+                        });
+
+                    select.append('<option value="Note">Note</option>');
+                    select.append('<option value="Email">Email</option>');
+                    select.append('<option value="Ftp">Ftp</option>');
+                    select.append('<option value="Rsync">Rsync</option>');
+                });
+        }
+    });
+}
+
+function setupServerIncident(server_id) {
+    var table = $('#server_incident').DataTable({
+        ajax: {
+            url: '/rest/server/check/' + server_id,
+        },
+        deferRender: true,
+        columns: [{data: 'dt'}, {data: 'capability'}, {data: 'extra'}],
+        order: [[0, 'desc']],
+    });
+}
+
+function addServerNote(hostname, kind, msg) {
+    $.ajax({
+        type: 'POST',
+        url: '/rest/server/note/' + hostname,
+        data: {
+            kind: kind,
+            msg: msg
+        },
+        success: function(data) {
+            location.reload();
+        },
+        error: function(xhr, ajaxOptions, thrownError) {
+            var error_message = 'An error occurred while adding server ' + 
kind + ': ';
+            if (xhr.responseJSON && xhr.responseJSON.error)
+                error_message += xhr.responseJSON.error;
+                addFlash('danger', error_message);
+        }
+    });
+}
+
+function addServerNoteButtonStatus() {
+    if(document.getElementById("new-note-text").value==="") {
+        document.getElementById('new-note-submit').disabled = true;
+    } else {
+        document.getElementById('new-note-submit').disabled = false;
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/lib/MirrorCache/Config.pm 
new/MirrorCache-1.065/lib/MirrorCache/Config.pm
--- old/MirrorCache-1.064/lib/MirrorCache/Config.pm     2023-09-14 
08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/Config.pm     2023-09-28 
12:08:56.000000000 +0200
@@ -54,6 +54,7 @@
 has custom_footer_message => $ENV{MIRRORCACHE_CUSTOM_FOOTER_MESSAGE};
 
 has browser_agent_mask => $ENV{MIRRORCACHE_BROWSER_AGENT_MASK} // 
'(?i)(firefox|msie|chrom|safari|seamonkey|opera|opr|trident).*';
+has country_image_dir => $ENV{MIRRORCACHE_COUNTRY_IMAGE_DIR} // 
'/srv/www/htdocs/webalizer/flags/';
 
 has geoip => undef;
 
@@ -63,7 +64,7 @@
     my $cfg;
     $cfg = Config::IniFiles->new(-file => $cfgfile, -fallback => 'default') if 
$cfgfile;
     if ($cfg) {
-        for my $k (qw/root root_nfs redirect redirect_huge huge_file_size 
small_file_size city_mmdb ip2location top_folders mirror_provider 
browser_agent_mask custom_footer_message/) {
+        for my $k (qw/root root_nfs redirect redirect_huge huge_file_size 
small_file_size city_mmdb ip2location top_folders mirror_provider 
browser_agent_mask custom_footer_message country_image_dir/) {
             if (my $v = $cfg->val('default', $k)) {
                 $self->$k($v);
             }
@@ -150,6 +151,10 @@
     }
 
     $self->geoip(\%geoip);
+    if (my $country_image_dir = $self->country_image_dir) {
+        ( -d $country_image_dir && -r $country_image_dir ) or 
$self->country_image_dir('');
+    }
+
     return 1;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/lib/MirrorCache/Schema/ResultSet/Server.pm 
new/MirrorCache-1.065/lib/MirrorCache/Schema/ResultSet/Server.pm
--- old/MirrorCache-1.064/lib/MirrorCache/Schema/ResultSet/Server.pm    
2023-09-14 08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/Schema/ResultSet/Server.pm    
2023-09-28 12:08:56.000000000 +0200
@@ -313,7 +313,12 @@
 )
 select s.id, s.region, s.country,
     s.sponsor, s.sponsor_url,
+    s.hostname as hostname,
     concat(s.hostname, s.urldir) as url,
+    case when (select rating from server_stability where capability = 'http'  
and server_id = s.id and server_stability.dt > now() - interval '1 day') > 0 
then concat('http://',  s.hostname, '/', s.urldir, '/') else '' end as http_url,
+    case when (select rating from server_stability where capability = 'https' 
and server_id = s.id and server_stability.dt > now() - interval '1 day') > 0 
then concat('https://', s.hostname, '/', s.urldir, '/') else '' end as 
https_url,
+    ( select msg from server_note where kind = 'Ftp'   and 
server_note.hostname = s.hostname order by server_note.dt desc limit 1) as 
ftp_url,
+    ( select msg from server_note where kind = 'Rsync' and 
server_note.hostname = s.hostname order by server_note.dt desc limit 1) as 
rsync_url,
     project,
     round(case when project_folder_count.cnt > 3 then s_eq * 100 / 
project_folder_count.cnt when s_eq =  project_folder_count.cnt then 100 else 50 
end, 0) score,
     s_eq, s_ne, victim, project_folder_count.cnt
@@ -340,8 +345,11 @@
 ) smry
 join project_folder_count on project_folder_count.project_id = smry.project_id
 join server s on smry.server_id = s.id and s.enabled
-order by region, country, score, url, project;
+order by region, country, score, hostname, project;
 END_SQL
+
+    $sql =~ s/interval '1 day'/interval 1 day/g unless ($dbh->{Driver}->{Name} 
eq 'Pg');
+
     my $prep = $dbh->prepare($sql);
     if ($project && $region) {
         $prep->execute($project, $project, $region);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/lib/MirrorCache/Task/Report.pm 
new/MirrorCache-1.065/lib/MirrorCache/Task/Report.pm
--- old/MirrorCache-1.064/lib/MirrorCache/Task/Report.pm        2023-09-14 
08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/Task/Report.pm        2023-09-28 
12:08:56.000000000 +0200
@@ -147,10 +147,16 @@
     # this is just tmp structure we use for aggregation
     my %report;
     my %sponsor;
+    my %capability;
+    my %url;
     for my $m (@$mirrors) {
-        $report{ $m->{region} }{ $m->{country} }{ $m->{url} }{ $m->{project} }
+        $report{ $m->{region} }{ $m->{country} }{ $m->{hostname} }{ 
$m->{project} }
           = [ $m->{score}, $m->{victim} ];
-        $sponsor{$m->{url}} = [$m->{sponsor},$m->{sponsor_url}];
+        $sponsor{$m->{hostname}} = [$m->{sponsor},$m->{sponsor_url}];
+        $url{$m->{hostname}} = $m->{url};
+        for my $capability (qw/http https ipv4 ipv6 ftp rsync/) {
+            $capability{$m->{hostname}}{$capability} = $m->{$capability . 
'_url'} if $m->{$capability . '_url'};
+        }
     }
 
     # json expects array, so we collect array here
@@ -159,18 +165,19 @@
         my $by_region = $report{$region};
         for my $country (sort keys %$by_region) {
             my $by_country = $by_region->{$country};
-            for my $url (sort keys %$by_country) {
+            for my $hostname (sort keys %$by_country) {
                 my %row = (
-                    region  => $region,
-                    country => $country,
-                    url     => $url,
+                    region   => $region,
+                    country  => $country,
+                    hostname => $hostname,
+                    url      => $url{$hostname},
                 );
-                if (my $sponsor = $sponsor{$url}) {
+                if (my $sponsor = $sponsor{$hostname}) {
                     $row{'sponsor'} = $sponsor->[0] if $sponsor->[0];
                     $row{'sponsor_url'} = $sponsor->[1] if $sponsor->[1];
                 }
 
-                my $by_project = $by_country->{$url};
+                my $by_project = $by_country->{$hostname};
                 for my $project (sort keys %$by_project) {
                     my $p = $by_project->{$project};
                     my $score = $p->[0];
@@ -182,6 +189,12 @@
                     $row{$project . 'score'}  = $score;
                     $row{$project . 'victim'} = $victim;
                 }
+                # add capabilities
+                for my $capability (qw/http https ipv4 ipv6 ftp rsync/) {
+                    if (my $capability_url = 
$capability{$hostname}{$capability}) {
+                        $row{$capability . '_url'} = $capability_url;
+                    }
+                }
                 push @report, \%row;
             }
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/lib/MirrorCache/WebAPI/Controller/App/Server.pm 
new/MirrorCache-1.065/lib/MirrorCache/WebAPI/Controller/App/Server.pm
--- old/MirrorCache-1.064/lib/MirrorCache/WebAPI/Controller/App/Server.pm       
2023-09-14 08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/WebAPI/Controller/App/Server.pm       
2023-09-28 12:08:56.000000000 +0200
@@ -38,4 +38,26 @@
     $self->redirect_to($self->url_for('server'));
 }
 
+sub show {
+    my $self = shift;
+    my $hostname = $self->param('hostname');
+
+    my $f = $self->schema->resultset('Server')->find({hostname => $hostname})
+        or return $self->reply->not_found;
+
+    my $admin_email = '';
+    if ($self->is_operator) {
+        $admin_email = $self->schema->storage->dbh->selectrow_array("SELECT 
msg FROM server_note WHERE hostname = ? AND kind = 'Email' ORDER BY dt DESC 
LIMIT 1", undef, $hostname);
+    }
+
+    my $server = {
+        id           => $f->id,
+        hostname     => $f->hostname,
+        public_notes => $f->public_notes,
+        admin_email  => $admin_email,
+    };
+
+    return $self->render('app/server/show', server => $server);
+}
+
 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/lib/MirrorCache/WebAPI/Controller/Rest/ServerNote.pm 
new/MirrorCache-1.065/lib/MirrorCache/WebAPI/Controller/Rest/ServerNote.pm
--- old/MirrorCache-1.064/lib/MirrorCache/WebAPI/Controller/Rest/ServerNote.pm  
1970-01-01 01:00:00.000000000 +0100
+++ new/MirrorCache-1.065/lib/MirrorCache/WebAPI/Controller/Rest/ServerNote.pm  
2023-09-28 12:08:56.000000000 +0200
@@ -0,0 +1,76 @@
+# Copyright (C) 2023 SUSE LLC
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, see <http://www.gnu.org/licenses/>.
+
+package MirrorCache::WebAPI::Controller::Rest::ServerNote;
+use Mojo::Base 'Mojolicious::Controller';
+use Data::Dumper;
+
+sub ins {
+    my ($self) = @_;
+
+    my $hostname = $self->param('hostname');
+    return $self->render(code => 400, text => "Mandatory argument is missing") 
unless $hostname;
+    my $acc      = $self->current_username;
+    my $kind     = $self->param('kind');
+    my $msg      = $self->param('msg');
+
+    my $prep = $self->schema->storage->dbh->prepare('insert into 
server_note(hostname, dt, acc, kind, msg) values(?, now(), ?, ?, ?)');
+    $prep->execute($hostname, $acc, $kind, $msg);
+
+    return $self->render(text => $hostname, status => 201);
+}
+
+sub list {
+    my ($self) = @_;
+
+    my $hostname = $self->param("hostname");
+    return $self->render(code => 400, text => "Mandatory argument is missing") 
unless $hostname;
+
+    my $sql = "select * from server_note where hostname = ?::text order by dt 
desc";
+    $sql =~ s/::text//g unless $self->schema->pg;
+
+    my $res = $self->schema->storage->dbh->selectall_arrayref($sql, {Columns 
=> {}}, $hostname);
+
+    return $self->render(json => { data => $res });
+}
+
+sub list_contact {
+    my ($self) = @_;
+
+    my $hostname = $self->param("hostname");
+    return $self->render(code => 400, text => "Mandatory argument is missing") 
unless $hostname;
+
+    my $sql = "select * from server_note where hostname = ?::text and not 
outdated and kind = 'email'";
+    $sql =~ s/::text//g unless $self->schema->pg;
+
+    my $res = $self->schema->storage->dbh->selectall_arrayref($sql, {Columns 
=> {}}, $hostname);
+
+    return $self->render(json => { data => $res });
+}
+
+sub list_incident {
+    my ($self) = @_;
+
+    my $id = $self->param("id");
+    return $self->render(code => 400, text => "Mandatory argument is missing") 
unless $id;
+
+    my $sql = "select * from server_capability_check where server_id = ? order 
by dt desc";
+
+    my $res = $self->schema->storage->dbh->selectall_arrayref($sql, {Columns 
=> {}}, $id);
+
+    return $self->render(json => { data => $res });
+}
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/lib/MirrorCache/WebAPI.pm 
new/MirrorCache-1.065/lib/MirrorCache/WebAPI.pm
--- old/MirrorCache-1.064/lib/MirrorCache/WebAPI.pm     2023-09-14 
08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/WebAPI.pm     2023-09-28 
12:08:56.000000000 +0200
@@ -178,6 +178,7 @@
     
$rest_r->get('/server_location')->name('rest_server_location')->to('server_location#list');
     $rest_r->get('/server/location')                              
->to('server_location#list');
     $rest_r->get('/server/:id')->to('table#list', table => 'Server');
+    
$rest_r->get('/server/check/:id')->name('rest_get_server_check')->to('server_note#list_incident');
     $rest_r->get('/project')->to('project#list');
     $rest_r->get('/project/:name')->to('project#show');
     
$rest_r->get('/project/:name/mirror_summary')->to('project#mirror_summary');
@@ -190,6 +191,9 @@
     
$rest_operator_r->post('/server/:id')->name('post_server')->to('table#update', 
table => 'Server');
     $rest_operator_r->delete('/server/:id')->to('table#destroy', table => 
'Server');
     
$rest_operator_r->put('/server/location/:id')->name('rest_put_server_location')->to('server_location#update_location');
+    
$rest_operator_r->post('/server/note/#hostname')->name('rest_put_server_note')->to('server_note#ins');
+    
$rest_operator_r->get('/server/note/#hostname')->name('rest_get_server_note')->to('server_note#list');
+    
$rest_operator_r->get('/server/contact/#hostname')->name('rest_get_server_contact')->to('server_note#list_contact');
     
$rest_operator_r->post('/sync_tree')->name('rest_post_sync_tree')->to('folder_jobs#sync_tree');
 
     $rest_r->get('/myserver')->name('rest_myserver')->to('table#list', table 
=> 'MyServer');
@@ -221,6 +225,7 @@
     my $app_r = $r->any('/app')->to(namespace => 
'MirrorCache::WebAPI::Controller::App');
 
     $app_r->get('/server')->name('server')->to('server#index');
+    $app_r->get('/server/#hostname')->name('server_show')->to('server#show');
     $app_r->get('/myserver')->name('myserver')->to('myserver#index');
     $app_r->get('/folder')->name('folder')->to('folder#index');
     $app_r->get('/folder/<id:num>')->name('folder_show')->to('folder#show');
@@ -250,6 +255,10 @@
     $self->asset->process;
     $self->plugin('Stat');
     $self->plugin('Dir');
+    if (my $country_image_dir = $self->mcconfig->country_image_dir) {
+        my $static = $self->static;
+        push @{$static->paths}, $country_image_dir;
+    }
     $self->log->info("server started:  $current_version");
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/lib/MirrorCache/resources/migrations/Pg.sql 
new/MirrorCache-1.065/lib/MirrorCache/resources/migrations/Pg.sql
--- old/MirrorCache-1.064/lib/MirrorCache/resources/migrations/Pg.sql   
2023-09-14 08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/resources/migrations/Pg.sql   
2023-09-28 12:08:56.000000000 +0200
@@ -374,5 +374,13 @@
 alter table hash add column if not exists sha512 varchar(128);
 -- 30 up
 alter table report_body add column if not exists tag varchar(16);
-
+-- 31 up
+create table server_note (
+    hostname  varchar(128) NOT NULL,
+    dt        timestamp NOT NULL,
+    acc       varchar(32),
+    kind      varchar(16),
+    msg       varchar(512),
+    primary key(hostname, dt)
+);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/lib/MirrorCache/resources/migrations/mysql.sql 
new/MirrorCache-1.065/lib/MirrorCache/resources/migrations/mysql.sql
--- old/MirrorCache-1.064/lib/MirrorCache/resources/migrations/mysql.sql        
2023-09-14 08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/lib/MirrorCache/resources/migrations/mysql.sql        
2023-09-28 12:08:56.000000000 +0200
@@ -375,3 +375,13 @@
 alter table hash add column if not exists sha512 varchar(128);
 -- 30 up
 alter table report_body add column if not exists tag varchar(16);
+-- 31 up
+create table server_note (
+    hostname  varchar(128) NOT NULL,
+    dt        timestamp NOT NULL,
+    acc       varchar(32),
+    kind      varchar(16),
+    msg       varchar(512),
+    primary key(hostname, dt)
+);
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/t/environ/11-server-note.sh 
new/MirrorCache-1.065/t/environ/11-server-note.sh
--- old/MirrorCache-1.064/t/environ/11-server-note.sh   1970-01-01 
01:00:00.000000000 +0100
+++ new/MirrorCache-1.065/t/environ/11-server-note.sh   2023-09-28 
12:08:56.000000000 +0200
@@ -0,0 +1,29 @@
+#!lib/test-in-container-environ.sh
+set -ex
+
+mc=$(environ mc $(pwd))
+
+ap8=$(environ ap8)
+ap7=$(environ ap7)
+
+$mc/backstage/shoot
+$mc/sql "insert into 
acc(username,email,fullname,nickname,is_operator,is_admin,t_created,t_updated) 
select 'eli','eli@test','Eli Test','eli',0,0,'2021-01-14 11:19:25','2021-01-14 
11:19:25'"
+
+$mc/sql "insert into server(hostname,urldir,enabled,country,region) select 
'$($ap7/print_address)','','t','us','na'"
+$mc/sql "insert into server(hostname,urldir,enabled,country,region) select 
'$($ap8/print_address)','','t','de','eu'"
+
+$mc/start
+$mc/curl /rest/server/note/$($ap7/print_address) -I | grep -E '302|/login'
+
+$mc/stop
+MIRRORCACHE_TRUST_ADDR=127.0.0.1 $mc/start
+
+$mc/curl /rest/server/note/$($ap7/print_address) -X POST -H 'Content-Type: 
application/x-www-form-urlencoded; charset=UTF-8' --data-raw 
"hostname=$($ap7/print_address)&kind=note&msg=test"
+
+test test == $($mc/sql "select msg from server_note where 
hostname='$($ap7/print_address)'")
+
+$mc/curl /rest/server/note/$($ap7/print_address) -i | grep 'test'
+
+$mc/sql "insert into server_capability_check(server_id, capability, dt, extra) 
select 1, 'http', now(), 'unknown error'"
+
+echo success
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/t/environ/14-project-report.sh 
new/MirrorCache-1.065/t/environ/14-project-report.sh
--- old/MirrorCache-1.064/t/environ/14-project-report.sh        2023-09-14 
08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/t/environ/14-project-report.sh        2023-09-28 
12:08:56.000000000 +0200
@@ -37,7 +37,7 @@
 rm -r $ap5/dt/project1/
 rm -r $ap4/dt/project2/
 
-$mc/sql "insert into 
server(hostname,sponsor,sponsor_url,urldir,enabled,country,region) select 
'$($ap6/print_address)','sponsor1','www.sponsor.org','','t','us','na'"
+$mc/sql "insert into 
server(hostname,sponsor,sponsor_url,urldir,enabled,country,region) select 
'$($ap6/print_address)','sponsor1 very long name inc Universitaties 
Subdivision','www.sponsor.org','','t','us','na'"
 $mc/sql "insert into server(hostname,urldir,enabled,country,region) select 
'$($ap7/print_address)','','t','us','na'"
 $mc/sql "insert into server(hostname,urldir,enabled,country,region) select 
'$($ap8/print_address)','','t','de','eu'"
 $mc/sql "insert into server(hostname,urldir,enabled,country,region) select 
'$($ap5/print_address)','','t','cn','as'"
@@ -48,6 +48,20 @@
 $mc/sql "insert into project(name,path,etalon) select 'proj1','/project1', 3"
 $mc/sql "insert into project(name,path,etalon) select '2.0 
2','/project2/folder2', 3"
 
+echo add extra info for the report
+$mc/sql "insert into server_note(dt,hostname,kind,msg) select now(), 
'$($ap7/print_address)','Ftp', 'ftp://ftp.ap7.com/opensuse'"
+$mc/sql "insert into server_note(dt,hostname,kind,msg) select now(), 
'$($ap6/print_address)','Ftp', 'ftp://ftp.ap6.com/opensuse'"
+sleep 1
+$mc/sql "insert into server_note(dt,hostname,kind,msg) select now(), 
'$($ap7/print_address)','Rsync', 'rsync://rsync.ap7.com/opensuse'"
+$mc/sql "insert into server_note(dt,hostname,kind,msg) select now(), 
'$($ap6/print_address)','Rsync', 'rsync://rsync.ap6.com/opensuse'"
+
+$mc/sql "insert into server_stability(dt,server_id,rating,capability) select 
now(), 1, 1000, 'https'"
+$mc/sql "insert into server_stability(dt,server_id,rating,capability) select 
now(), 1, 1000, 'http'"
+$mc/sql "insert into server_stability(dt,server_id,rating,capability) select 
now(), 1, 1000, 'ipv6'"
+$mc/sql "insert into server_stability(dt,server_id,rating,capability) select 
now(), 2, 0, 'https'"
+$mc/sql "insert into server_stability(dt,server_id,rating,capability) select 
now(), 2, 100, 'http'"
+
+
 $mc/backstage/job -e folder_sync -a '["/project1/folder1"]'
 $mc/backstage/job -e mirror_scan -a '["/project1/folder1"]'
 $mc/backstage/job -e folder_sync -a '["/project1/folder2"]'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/t/environ/14-project.sh 
new/MirrorCache-1.065/t/environ/14-project.sh
--- old/MirrorCache-1.064/t/environ/14-project.sh       2023-09-14 
08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/t/environ/14-project.sh       2023-09-28 
12:08:56.000000000 +0200
@@ -65,13 +65,13 @@
 echo proj1 is not on ap4, so it shouldnt appear in repmirror at all
 test $rc -gt 0
 
-$mc/curl /rest/repmirror  | grep -F 
'{"country":"cn","proj1score":"50","proj1victim":"","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1284"},{"country":"jp","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1274"},{"country":"de","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"eu","url":"127.0.0.1:1314"},{"country":"us","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1294"},{"country":"us","proj1score":"50","proj1victim":"\/project1\/folder2","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1304"}'
+$mc/curl /rest/repmirror  | grep -F 
'{"country":"cn","hostname":"127.0.0.1:1284","proj1score":"50","proj1victim":"","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1284"},{"country":"jp","hostname":"127.0.0.1:1274","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1274"},{"country":"de","hostname":"127.0.0.1:1314","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"eu","url":"127.0.0.1:1314"},{"country":"us","hostname":"127.0.0.1:1294","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1294"},{"country":"us","hostname":"127.0.0.1:1304","proj1score":"50","proj1victim":"\/project1\/folder2","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1304"}'
 
 $mc/curl /rest/project | grep -F '{"alias":"proj2","name":"proj 
2","path":"\/project2"}' | grep -F 
'{"alias":"proj1","name":"proj1","path":"\/project1"}'
 
 echo ceck the same when DB is offline
 $mc/db/stop
-$mc/curl /rest/repmirror  | grep -F 
'{"country":"cn","proj1score":"50","proj1victim":"","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1284"},{"country":"jp","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1274"},{"country":"de","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"eu","url":"127.0.0.1:1314"},{"country":"us","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1294"},{"country":"us","proj1score":"50","proj1victim":"\/project1\/folder2","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1304"}'
+$mc/curl /rest/repmirror  | grep -F 
'{"country":"cn","hostname":"127.0.0.1:1284","proj1score":"50","proj1victim":"","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1284"},{"country":"jp","hostname":"127.0.0.1:1274","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1274"},{"country":"de","hostname":"127.0.0.1:1314","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"eu","url":"127.0.0.1:1314"},{"country":"us","hostname":"127.0.0.1:1294","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1294"},{"country":"us","hostname":"127.0.0.1:1304","proj1score":"50","proj1victim":"\/project1\/folder2","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1304"}'
 
 $mc/curl /rest/project | grep -F '{"alias":"proj2","name":"proj 
2","path":"\/project2"}' | grep -F 
'{"alias":"proj1","name":"proj1","path":"\/project1"}'
 
@@ -79,7 +79,7 @@
 $mc/stop
 ENVIRON_MC_DB_AUTOSTART=0 $mc/start
 
-$mc/curl /rest/repmirror  | grep -F 
'{"country":"cn","proj1score":"50","proj1victim":"","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1284"},{"country":"jp","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1274"},{"country":"de","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"eu","url":"127.0.0.1:1314"},{"country":"us","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1294"},{"country":"us","proj1score":"50","proj1victim":"\/project1\/folder2","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1304"}'
+$mc/curl /rest/repmirror  | grep -F 
'{"country":"cn","hostname":"127.0.0.1:1284","proj1score":"50","proj1victim":"","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1284"},{"country":"jp","hostname":"127.0.0.1:1274","proj2score":"100","proj2victim":"","region":"as","url":"127.0.0.1:1274"},{"country":"de","hostname":"127.0.0.1:1314","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"eu","url":"127.0.0.1:1314"},{"country":"us","hostname":"127.0.0.1:1294","proj1score":"100","proj1victim":"","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1294"},{"country":"us","hostname":"127.0.0.1:1304","proj1score":"50","proj1victim":"\/project1\/folder2","proj2score":"100","proj2victim":"","region":"na","url":"127.0.0.1:1304"}'
 
 $mc/curl /rest/project | grep -F '{"alias":"proj2","name":"proj 
2","path":"\/project2"}' | grep -F 
'{"alias":"proj1","name":"proj1","path":"\/project1"}'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/MirrorCache-1.064/templates/app/server/show.html.ep 
new/MirrorCache-1.065/templates/app/server/show.html.ep
--- old/MirrorCache-1.064/templates/app/server/show.html.ep     1970-01-01 
01:00:00.000000000 +0100
+++ new/MirrorCache-1.065/templates/app/server/show.html.ep     2023-09-28 
12:08:56.000000000 +0200
@@ -0,0 +1,67 @@
+% layout 'bootstrap';
+% title "Server " . $server->{hostname};
+
+% content_for 'ready_function' => begin
+    is_operator = <%= (is_operator) ? 'true' : 'false' %>;
+    server_id = <%= $server->{id} %>;
+    if (is_operator) {
+        hostname = "<%= $server->{hostname} %>";
+        setupServerNote(hostname);
+    }
+    setupServerIncident(server_id);
+% end
+
+<div class="row">
+    <div class="col-sm-12">
+        <h2><%= title %></h2>
+
+    %= include 'layouts/info'
+
+    <div class="card">
+        <div class="card-body status-info">
+            <div><span>Host: </span><%= $server->{hostname} %></div>
+            <div><span>Id: </span><%= $server->{id} %></div>
+% if ($server->{public_notes}) {
+            <div><span>Public notes: </span><%= $server->{public_notes} 
%></div>
+% }
+            % # <div><span>Status: </span><%= include 
'app/server/server_status' %></div>
+% if ($server->{admin_email}) {
+            <div><span>Email: </span><%= $server->{admin_email} %></div>
+% }
+        </div>
+    </div>
+
+% if (is_operator) {
+    <h3>Private notes</h3>
+    <table id="server_note" class="table table-striped">
+        <thead>
+            <th>Date</th>
+            <th>User</th>
+            <th>Kind</th>
+            <th>Message</th>
+        </thead>
+    </table>
+    <div class="text-center">
+        <label for="new-note-select">New </label>
+        <select name="select" id="new-note-select">
+            <option value="Note">Note</option>
+            <option value="Email">Email</option>
+            <option value="Rsync">Rsync</option>
+            <option value="Ftp">Ftp</option>
+        </select>
+        <input type="text" id="new-note-text" name="new-note-text" 
onkeyup="addServerNoteButtonStatus()">
+        <input value="add" id="new-note-submit" 
onclick="addServerNote(hostname, 
document.getElementById('new-note-select').value, 
document.getElementById('new-note-text').value);" type="button" class="btn 
btn-default" disabled/>
+    </div>
+% }
+
+    <h3>Checks last two weeks</h3>
+    <table id="server_incident" class="table table-striped">
+        <thead>
+            <th>Date</th>
+            <th>Capability</th>
+            <th>Error</th>
+        </thead>
+    </table>
+</div>
+
+</div>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/templates/branding/openSUSE/header.html.ep 
new/MirrorCache-1.065/templates/branding/openSUSE/header.html.ep
--- old/MirrorCache-1.064/templates/branding/openSUSE/header.html.ep    
2023-09-14 08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/templates/branding/openSUSE/header.html.ep    
2023-09-28 12:08:56.000000000 +0200
@@ -1,6 +1,6 @@
 
 <nav class="navbar noprint navbar-expand-md sticky-top">
-  <a class="navbar-brand" href="/"><img 
src="https://static.opensuse.org/favicon.svg"; class="d-inline-block align-top" 
width="30" height="30"> <span class="navbar-title">Download</span></a>
+  <a class="navbar-brand" href="/"><img 
src="https://static.opensuse.org/favicon.svg"; class="d-inline-block align-top" 
width="30" height="30" alt='openSUSE icon'> <span 
class="navbar-title">Download</span></a>
   <button class="navbar-toggler" type="button" data-toggle="collapse" 
data-target="#navbar-collapse"><svg width="20" height="20" viewbox="0 0 16 16" 
fill="currentColor" xmlns="http://www.w3.org/2000/svg";><path 
fill-rule="evenodd" d="M2.5 11.5A.5.5 0 0 1 3 11h10a.5.5 0 0 1 0 1H3a.5.5 0 0 
1-.5-.5zm0-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm0-4A.5.5 0 0 
1 3 3h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5z"></path></svg></button>
 
   <div class="collapse navbar-collapse" id="navbar-collapse">
@@ -20,7 +20,7 @@
       </li>
     </ul>
     % if (my $extra = stash('extra_menu')) {
-    <div class="collapse navbar-collapse" id="navbar-collapse">
+    <div class="collapse navbar-collapse" id="navbar-collapse-extra">
       <ul class="nav navbar-nav mr-auto flex-md-shrink-0">
     %   for my $e (@$extra) {
           <li class="nav-item"><a class="nav-link" href="<%= $e->{href} 
%>"><%= $e->{title} %></a></li>
@@ -32,7 +32,7 @@
     <ul id="user-menu" class="navbar-nav">
       <li class="nav-item dropdown">
         <a class="nav-link" href="#" id="user-dropdown" role="button" 
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-          <img src="<%= icon_url 'logo.svg'%>">
+          <img src="<%= icon_url 'logo.svg'%>" alt="openSUSE logo">
           <span class="d-md-none">MirrorCache</span>
         </a>
         <div class="dropdown-menu dropdown-menu-right" 
aria-labelledby="user-dropdown">
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/MirrorCache-1.064/templates/report/mirrors/index.html.ep 
new/MirrorCache-1.065/templates/report/mirrors/index.html.ep
--- old/MirrorCache-1.064/templates/report/mirrors/index.html.ep        
2023-09-14 08:46:25.000000000 +0200
+++ new/MirrorCache-1.065/templates/report/mirrors/index.html.ep        
2023-09-28 12:08:56.000000000 +0200
@@ -67,7 +67,53 @@
 
 div.repo {
     float: left;
+    margin-left: 2px;
     margin-right: 2px;
+    max-width: 20pct;
+}
+
+div.country {
+    float: left;
+}
+
+div.flag {
+    float: right;
+}
+
+div.hostname {
+    float: left;
+    margin-left: 2px;
+    margin-right: 2px;
+    max-width: 20pct;
+}
+
+a.hostname {
+    font-size: larger;
+}
+
+div.url {
+    float: left;
+    margin-left: 2px;
+    margin-right: 2px;
+    max-width: 20pct;
+}
+
+a.url {
+    font-size: smaller;
+}
+
+div.sponsor {
+    float: right;
+    margin-left: 2px;
+    margin-right: 2px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    max-width: 10pct;
+}
+
+a.sponsor {
+    font-size: smaller;
 }
 
 tr:nth-child(even) {
@@ -88,24 +134,13 @@
     padding: 1.5rem 0.5rem;
 }
 
-@media (prefers-color-scheme: dark) {
-    td.newregion, tr:hover td.newregion {
-        background: #212529;
-    }
-    thead th {
-        background: linear-gradient(to top, #787878 0%, #363a3c 1px, #363a3c 
100%);
-    }
-    thead th:nth-child(even), thead th:nth-child(1), thead th:nth-child(3) {
-        background: linear-gradient(to top, #787878 0%, #2f3236 1px, #2f3236 
100%);
-    }
-}
-
 </style>
 % end
 
 %= include_branding 'report_mirrors_banner'
 % my $mc_branding = eval '$branding' // 'MirrorCache';
 % my $is_opensuse = $mc_branding eq 'openSUSE';
+% my $country_image_dir = eval('mcconfig->country_image_dir');
 
 <form>
 <div class="row">
@@ -116,10 +151,11 @@
             <thead>
                 <tr>
                     <th class="col_value">Country</th>
+                    <th class="col_value"><div 
class="hostname">Hostname</div><div class="url">Urls</div>
                     % if ($is_opensuse) {
-                    <th class="col_value">Operator</th>
+                      <div class="sponsor">Operator</div>
                     % }
-                    <th class="col_value">Url</th>
+                    </th>
                     % $first_old = '';
                     % $first = '';
                     % for my $project (@$projects) {
@@ -149,16 +185,33 @@
                 %     }
                 %     $prev_region = $region;
                 <tr>
-                %     my $url = $m->{url};
-                    <td><%= $m->{country} %></td>
+                %     my $hostname  = $m->{hostname};
+                %     my $url       = 'http://' . $m->{url};
+                %     my $url_https = $m->{https_url};
+                %     my $url_http  = $m->{http_url};
+                %     $url_http  =~ s/(\/)+$//g; # truncate trailing slashes
+                %     $url_https =~ s/(\/)+$//g; # truncate trailing slashes
+                %     $url = $url_http  if $url_http;
+                %     $url = $url_https if $url_https;
+                    <td><div class="country"><%= $m->{country} %></div>
+                %     if ($country_image_dir) {
+                      <div class="flag"><img src="/<%= $m->{country} %>.png" 
width="20" class="img-fluid" alt="country flag"></div>
+                %     }
+                    </td>
+                    <td><div class="hostname"><a class="hostname" 
href="/app/server/<%= $hostname %>"><%=$hostname%></a></div>
+                %   for my $capability (qw/http https ftp rsync ipv4 ipv6/) {
+                %       my $capability_url = $m->{$capability . '_url'};
+                %       next unless $capability_url;
+                        <div class="url"><a class="url" href="<%= 
$capability_url %>"><%= $capability %></a></div>
+                %   }
                 %     if ($is_opensuse) {
                 %         my $sponsor     = $m->{sponsor};
                 %         my $sponsor_url = $m->{sponsor_url};
                 %         $sponsor = $sponsor_url unless $sponsor;
                 %         $sponsor_url = $sponsor unless $sponsor_url;
-                    <td><a href="https://<%= $sponsor_url 
%>"><%=$sponsor%></a></td>
+                    <div class="sponsor"><a class="sponsor" href="https://<%= 
$sponsor_url %>"><%= $sponsor %></a></div>
                 %     }
-                    <td><a href="http://<%= $url %>"><%=$url%></a></td>
+                    </td>
                 %     my $inner = '';
                 %     $first_old = '';
                     <td>
@@ -189,7 +242,7 @@
                                title="diff in: <%=$victim%>"
                 %         }
                 %         $second = 'iso' if $second eq 'ISO' || $second eq 
'ISOs';
-                               href="http://<%=$url . $path%>">
+                               href="<%=$url . $path%>">
                                 <%= $second %>
                             </a>
                         </div>

++++++ MirrorCache.obsinfo ++++++
--- /var/tmp/diff_new_pack.YobdME/_old  2023-10-05 20:06:34.098115789 +0200
+++ /var/tmp/diff_new_pack.YobdME/_new  2023-10-05 20:06:34.102115934 +0200
@@ -1,5 +1,5 @@
 name: MirrorCache
-version: 1.064
-mtime: 1694673985
-commit: e0be7842c9b0fc3e12af5e6830a0816f54a593f6
+version: 1.065
+mtime: 1695895736
+commit: e5837a4b182eb631487b5c86d4226642fd7d2f9d
 

Reply via email to