Skip to content

Commit

Permalink
Merge branch 'betterprivacy' of git://github.com/poempelfox/mirrorbit…
Browse files Browse the repository at this point in the history
…s into poempelfox-betterprivacy
  • Loading branch information
etix committed Nov 5, 2018
2 parents 5a8c3b5 + 97a2fdf commit e731fee
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 28 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ WeightDistributionRange | Multiplier of the distance to the first mirror to find
DisableOnMissingFile | Disable a mirror if an advertised file on rsync/ftp appears to be missing on HTTP
MaxLinkHeaders | Amount of backup mirror locations returned in HTTP headers
Fallbacks | A list of possible mirrors to use as fallback if a request fails or if the database is unreachable. **These mirrors are not tracked by mirrorbits.** It is assumed they have all the files available in the local repository.
LocalJSPath | A local path or URL containing the JavaScript used by the templates. If this is not set (the default), the JavaScript will just be loaded from the usual CDNs. See also `contrib/localjs/fetchfiles.sh`.

## Running

Expand Down
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var (
defaultConfig = Configuration{
Repository: "",
Templates: "",
LocalJSPath: "",
OutputMode: "auto",
ListenAddress: ":8080",
Gzip: false,
Expand Down Expand Up @@ -55,6 +56,7 @@ var (
type Configuration struct {
Repository string `yaml:"Repository"`
Templates string `yaml:"Templates"`
LocalJSPath string `yaml:"LocalJSPath"`
OutputMode string `yaml:"OutputMode"`
ListenAddress string `yaml:"ListenAddress"`
Gzip bool `yaml:"Gzip"`
Expand Down
125 changes: 125 additions & 0 deletions contrib/localjs/fetchfiles.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/bin/bash

# List of scripts to fetch and store locally
whattofetch=(
"https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/excanvas.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/excanvas.min.js"
"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"
"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.pie.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.pie.min.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot.tooltip/0.9.0/jquery.flot.tooltip.js"
"https://cdnjs.cloudflare.com/ajax/libs/flot.tooltip/0.9.0/jquery.flot.tooltip.min.js"
"https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/leaflet.css"
"https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/leaflet.js"
"https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/images/marker-icon.png"
"https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/images/marker-shadow.png"
"https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.0/MarkerCluster.css"
"https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.0/leaflet.markercluster.js"
)

showhelp()
{
echo "Syntax: $0 directory"
echo "where directory is the directory in which you want to store the downloaded files."
echo ""
echo "This will download the Javascript- and Font-files used by the default"
echo "templates in mirrorbits. You can then self-host that directory tree on"
echo "your webserver instead of using external CDNs."
echo "You then need to set the LocalJSPath option in your mirrorbits config to"
echo "point at the web-accessible path to that directory."
}

getlocalfilename ()
{
local sfn="$1"
lfn=${sfn#https://cdnjs.cloudflare.com/ajax/libs}
}

downloadfile ()
{
curl=`which curl`
if [ ${#curl} -ge 4 ] ; then
$curl --output "$2" "$1"
return
fi
wget=`which wget`
if [ ${#wget} -ge 4 ] ; then
$wget --output-document="$2" "$1"
return
fi
echo "ERROR: Neither curl nor wget were found in path. Please install either curl or wget."
exit 1
}

if [ "$#" -ne 1 ] ; then
showhelp
exit 1
fi
if [ "$1" == "--help" -o "$1" == "-h" ] ; then
showhelp
exit 0
fi
localdir="$1"
if [ ! -d "$localdir" ] ; then
echo "Target directory ${localdir} does not exist or is not a directory."
showhelp
exit 1
fi

unzip=`which unzip`
if [ ${#unzip} -lt 5 ] ; then
echo "ERROR: unzip was not found in path. Please install unzip."
exit 1
fi
for sf in ${whattofetch[@]}; do
lfn="/void/void/void/void/"
getlocalfilename "$sf"
# lfn is now filled.
tf="${localdir}${lfn}"
if [ -e "$tf" ] ; then
echo "No need to fetch $sf to $tf, it already exists."
else
tdn=`dirname "${tf}"`
if [ ! -e "$tdn" ] ; then
mkdir -p "$tdn"
fi
downloadfile "$sf" "$tf"
fi
done

# The font stuff is a bit more messy.

# For the Lato font, we rely on a service that's packing the mess into
# a ZIP file for us.
if [ ! -e "${localdir}/fonts" ] ; then
mkdir -p "${localdir}/fonts"
fi
downloadfile "https://google-webfonts-helper.herokuapp.com/api/fonts/lato?download=zip&subsets=latin&variants=900,regular" "${localdir}/fonts/lato-font-900and400.zip"
# Make sure the webserver cannot access the file for licensing reasons, as
# that would count as distribution and require proper attribution which
# we cannot guarantee.
chmod go-rwx "${localdir}/fonts/lato-font-900and400.zip"
unzip "${localdir}/fonts/lato-font-900and400.zip" -d "${localdir}/fonts/"

# For fontawesome, we download and unpack the whole ZIP as well.
# Downloading individual files will not work here, as depending on the
# browser random other files will be included.
if [ ! -e "${localdir}/font-awesome" ] ; then
mkdir -p "${localdir}/font-awesome"
fi
if [ -e "${localdir}/font-awesome/4.7.0" ] ; then
# Only download and extract if that directory isn't there yet, as we
# have to use a 'mv' command here that would fail if the target already
# existed.
echo "Note: Skipping font-awesome download and extraction, it seems to be in place already."
echo "To force redownload and extraction, remove '${localdir}/font-awesome/4.7.0'"
else
downloadfile "https://fontawesome.com/v4.7.0/assets/font-awesome-4.7.0.zip" "${localdir}/font-awesome-4.7.0.zip"
chmod go-rwx "${localdir}/font-awesome-4.7.0.zip"
unzip "${localdir}/font-awesome-4.7.0.zip" -d "${localdir}/font-awesome"
mv "${localdir}/font-awesome/font-awesome-4.7.0" "${localdir}/font-awesome/4.7.0"
fi

4 changes: 3 additions & 1 deletion http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ func (h *HTTP) mirrorHandler(w http.ResponseWriter, r *http.Request, ctx *Contex
ClientInfo: clientInfo,
IP: remoteIP,
Fallback: fallback,
LocalJSPath: GetConfig().LocalJSPath,
}

var resultRenderer resultsRenderer
Expand Down Expand Up @@ -484,6 +485,7 @@ type SyncOffset struct {
type MirrorStatsPage struct {
List []MirrorStats
MirrorList []mirrors.Mirror
LocalJSPath string
}

// byDownloadNumbers is a sorting function
Expand Down Expand Up @@ -589,7 +591,7 @@ func (h *HTTP) mirrorStatsHandler(w http.ResponseWriter, r *http.Request, ctx *C
}

w.Header().Set("Content-Type", "text/html; charset=utf-8")
err = ctx.Templates().mirrorstats.ExecuteTemplate(w, "base", MirrorStatsPage{results, mlist})
err = ctx.Templates().mirrorstats.ExecuteTemplate(w, "base", MirrorStatsPage{results, mlist, GetConfig().LocalJSPath})
if err != nil {
log.Errorf("HTTP error: %s", err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
Expand Down
1 change: 1 addition & 0 deletions mirrors/mirrors.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ type Results struct {
MirrorList Mirrors
ExcludedList Mirrors `json:",omitempty"`
Fallback bool `json:",omitempty"`
LocalJSPath string
}

// Redirects is handling the per-mirror authorization of HTTP redirects
Expand Down
38 changes: 36 additions & 2 deletions templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,42 @@
<head>
<title>{{template "title" .}}</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
{{if not .LocalJSPath}}
<link href='//fonts.googleapis.com/css?family=Lato:400,900' rel='stylesheet' type='text/css'>
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
{{else}}
<style type="text/css">
/* Generated with https://google-webfonts-helper.herokuapp.com */
/* lato-regular - latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 400;
src: url('{{.LocalJSPath}}/fonts/lato-v14-latin-regular.eot'); /* IE9 Compat Modes */
src: local('Lato Regular'), local('Lato-Regular'),
url('{{.LocalJSPath}}/fonts/lato-v14-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-regular.woff') format('woff'), /* Modern Browsers */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-regular.svg#Lato') format('svg'); /* Legacy iOS */
}

/* lato-900 - latin */
@font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 900;
src: url('{{.LocalJSPath}}/fonts/lato-v14-latin-900.eot'); /* IE9 Compat Modes */
src: local('Lato Black'), local('Lato-Black'),
url('{{.LocalJSPath}}/fonts/lato-v14-latin-900.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-900.woff2') format('woff2'), /* Super Modern Browsers */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-900.woff') format('woff'), /* Modern Browsers */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-900.ttf') format('truetype'), /* Safari, Android, iOS */
url('{{.LocalJSPath}}/fonts/lato-v14-latin-900.svg#Lato') format('svg'); /* Legacy iOS */
}
</style>
<link href="{{.LocalJSPath}}/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
{{end}}
<style type="text/css">
body {
margin: 0px;
Expand Down Expand Up @@ -90,7 +124,7 @@
<div id="wrapper">
<div id="header">
<div class="title">
<a href="http://github.com/etix/mirrorbits" target="_blank" style="text-decoration: none; color: inherit;">Mirrorbits <i class="fa fa-globe" style="vertical-align: middle;"></i></a>
<a href="http://github.com/etix/mirrorbits" target="_blank" style="text-decoration: none; color: inherit;">Mirrorbits <i class="fa fa-globe" style="vertical-align: middle;" aria-hidden="true"></i></a>
</div>
<div class="headline">{{template "headline" .}}</div>
</div>
Expand Down
81 changes: 56 additions & 25 deletions templates/mirrorlist.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,33 +2,64 @@
{{define "headline"}}{{.FileInfo.Path}}{{end}}

{{define "head"}}
<script type="text/javascript" src="https://www.google.com/jsapi?autoload={'modules':[{'name':'visualization','version':'1.1','packages':['corechart']}]}"></script>
<script type="text/javascript">
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.arrayToDataTable([
['mirror','probability'],
{{range $i, $v := .MirrorList}}{{if $v.Weight}}['{{$v.ID}}', {{$v.Weight}}],{{end}}{{end}}
]);

// Set chart options
var options = {
title: 'Load distribution',
width: 600,
height: 320,
chartArea: {'width': '90%', 'height': '90%'},
sliceVisibilityThreshold: .01,
is3D: true
};

// Instantiate and draw our chart, passing in some options.
var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
{{if not .LocalJSPath}}
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.pie.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/flot.tooltip/0.9.0/jquery.flot.tooltip.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.0/MarkerCluster.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/leaflet.js"></script>
{{else}}
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="{{.LocalJSPath}}/flot/0.8.3/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="{{.LocalJSPath}}/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="{{.LocalJSPath}}/flot/0.8.3/jquery.flot.min.js"></script>
<script type="text/javascript" src="{{.LocalJSPath}}/flot/0.8.3/jquery.flot.pie.min.js"></script>
<script type="text/javascript" src="{{.LocalJSPath}}/flot.tooltip/0.9.0/jquery.flot.tooltip.min.js"></script>
<link rel="stylesheet" href="{{.LocalJSPath}}/leaflet/1.0.2/leaflet.css" />
<script src="{{.LocalJSPath}}/leaflet/1.0.2/leaflet.js"></script>
{{end}}
<script type="text/javascript">
$(function() {
var mirrordistchartdata = [
{{range $i, $v := .MirrorList}}{{if $v.Weight}}{ label: '{{$v.ID}}', data: {{$v.Weight}}},{{end}}{{end}}
];
$.plot('#chart_div', mirrordistchartdata, {
series: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 0.75,
formatter: labelFormatter,
threshold: 0.02
},
combine: {
threshold: 0.02 // 0.02 == 2%
},
}
},
legend: {
show: true
},
grid: {
hoverable: true
},
tooltip: {
show: true,
content: "%s: %p.2%",
shifts: {
x: 10, y: 0
},
defaultTheme: true
}
});
});
function labelFormatter(label, series) {
return "<div style='font-size:8pt; text-align:center; padding:2px; color:white;'>" + series.percent.toFixed(1) + "%</div>";
}
</script>
<style>
.numberboxinmapblue {
background:blue; color:white; border:none;
Expand Down
7 changes: 7 additions & 0 deletions templates/mirrorstats.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@
{{define "headline"}}Mirrorstats{{end}}

{{define "head"}}
{{if not .LocalJSPath}}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/leaflet.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.0/MarkerCluster.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.0.2/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/1.0.0/leaflet.markercluster.js"></script>
{{else}}
<link rel="stylesheet" href="{{.LocalJSPath}}/leaflet/1.0.2/leaflet.css" />
<link rel="stylesheet" href="{{.LocalJSPath}}/leaflet.markercluster/1.0.0/MarkerCluster.css" />
<script src="{{.LocalJSPath}}/leaflet/1.0.2/leaflet.js"></script>
<script src="{{.LocalJSPath}}/leaflet.markercluster/1.0.0/leaflet.markercluster.js"></script>
{{end}}
<style type="text/css">
#map { }
.marker-cluster {
Expand Down

0 comments on commit e731fee

Please sign in to comment.