Browse Source

Upload history log. WAE award. Privacy policy.

Fabian Kurz 4 years ago
  1. 4
  2. 62
  3. BIN
  4. 86
  5. 39
  6. 202
  7. 5


@ -1,2 +1,6 @@
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteRule ^logout(/)?$ /login.php?f=logout [L]


@ -37,6 +37,12 @@
echo dxcc($_SESSION['callsign'], $band);
case 'wae':
$band = $_GET['band'];
if (in_array($band, $bands)) {
echo wae($_SESSION['callsign'], $band);
case 'lookup':
$call = validate_get('hiscall');
echo lookup($call, 'json');
@ -47,6 +53,12 @@
case 'upload':
case 'upload_history':
case 'upload_details':
case 'search':
@ -99,6 +111,12 @@
# strip "m" from band
if ($i == "band" && preg_match('/(\d+)/', $o->$i, $match)) {
$o->$i = $match[1];
if (!validate($i, $o->$i)) {
$err .= "$i (".$o->$i.") ";
@ -157,10 +175,10 @@
array_push($qsos, array('call' => $o->hiscall, 'nr' => $o->nr, 'date' => $o->date, 'band' => $o->band, 'dxcc' => $o->dxcc, 'was' => $o->was, 'waz' => $o->waz, 'wae' => $o->wae));
$qso_filtered = filter_qsos($qsos, $_SESSION['callsign']);
if (count($qso_filtered)) {
echo "QSO: ".$qso_filtered[0]['call']." ".$qso_filtered[0]['date']." ".$qso_filtered[0]['band']." needed for: ".$qso_filtered[0]['reasons']."<br>";
echo "Saved QSO: ".$qso_filtered[0]['call']." ".$qso_filtered[0]['date']." ".$qso_filtered[0]['band']." needed for: ".$qso_filtered[0]['reasons']."\n";
else {
echo "QSO not added (not a new point for any award).";
echo "QSO not added (not a new point for any award)!";
@ -242,7 +260,47 @@
function upload_history () {
global $db;
$ret = "<h2>Upload history</h2>";
$q = mysqli_query($db, "select * from cwops_uploads where uid=".$_SESSION['id']." order by ts desc limit 25");
$ret .= "<pre>";
while ($r = mysqli_fetch_array($q)) {
$ret .= "Upload date: ".$r['ts'].", Imported QSOs: ".sprintf("%4d", $r['count']).". <a target='_new' href='/api?action=upload_details&id=".$r['id']."'>Show details</a> (opens in new window)<br>";
$ret .= "</pre>";
echo $ret;
function upload_details () {
global $db;
if (is_numeric($_GET['id'])) {
$id = $_GET['id'];
else {
echo "Invalid ID";
$ret = "<pre>";
$q = mysqli_query($db, "select * from cwops_uploads where uid=".$_SESSION['id']." and id=$id");
while ($r = mysqli_fetch_array($q)) {
$ret .= "Upload date: ".$r['ts'].", Imported QSOs: ".$r['count']."<br>".$r['result'];
$ret .= "</pre>";
echo $ret;


Binary file not shown.


Width:  |  Height:  |  Size: 3.0 KiB


@ -9,6 +9,7 @@ $arr_states = array("AK"=>1, "HI"=>1, "CT"=>1, "ME"=>1, "MA"=>1, "NH"=>1, "RI"=>
function stats($c) {
global $db;
global $wae_adif;
@ -31,17 +32,23 @@ function stats($c) {
$r = mysqli_fetch_row($q);
$dxcc = $r[0];
$q = mysqli_query($db, "SELECT count(distinct(`dxcc`)) from cwops_log where `dxcc` > 0 and `mycall`='$c' and dxcc in (".implode(',', $wae_adif).")");
$r = mysqli_fetch_row($q);
$wae = $r[0];
$q = mysqli_query($db, "SELECT count(distinct(`waz`)) from cwops_log where `mycall`='$c'");
$r = mysqli_fetch_row($q);
$waz = $r[0];
<h2>Statistics for <?=$_SESSION['callsign'];?></h2>
<tr><td>ACA</td> <td><?=$aca?></td> <td><?=award_details('aca', 0);?></td></tr>
<tr><td>CMA</td> <td><?=$cma?></td> <td><?=award_details('cma', 0);?></td></tr>
<tr><td>WAS</td> <td><?=$was?></td> <td><?=award_details('was', 1);?></td></tr>
<tr><td>DXCC</td><td><?=$dxcc?></td><td><?=award_details('dxcc', 1);?></td></tr>
<tr><td>WAE</td><td><?=$wae?></td><td><?=award_details('wae', 1);?></td></tr>
<tr><td>WAZ</td> <td><?=$waz?></td> <td><?=award_details('waz', 1);?></td></tr>
@ -188,7 +195,8 @@ function waz($c, $b) {
function dxcc($c, $b) {
global $db;
global $dxcc;
$ret = "<h2>DXCC details for $c";
if ($b != "all") {
@ -211,6 +219,65 @@ function dxcc($c, $b) {
return $ret;
function wae($c, $b) {
global $db;
global $waes;
global $wae_adif;
global $dxcc;
$needed = array();
foreach (array_merge($wae_adif, array_keys($waes)) as $k) {
$needed[$k] = 1;
$ret = "<h2>WAE details for $c";
if ($b != "all") {
$band = " and band=$b ";
$ret .= " (".$b."m)";
$ret .="</h2>";
$q = mysqli_query($db, "SELECT `dxcc`, `nr`, hiscall, date, band from cwops_log where `mycall`='$c' and dxcc in (".implode(',', $wae_adif).") and wae='' $band group by `dxcc`");
if(!$q) {
echo mysqli_error($db);
$cnt = 1;
$ret .= "<table><tr><th>Count</th><th>DXCC</th><th>CWops</th><th>Call</th><th>Date</th><th>Band</th></tr>\n";
while ($r = mysqli_fetch_row($q)) {
$ret .= "<tr><td>".$cnt++."</td><td>".$dxcc[$r[0]]." (".$r[0].")</td><td>".$r[1]."</td><td>".$r[2]."</td><td>".$r[3]."</td><td>".$r[4]."</td></tr>\n";
# fetch extra WAE entities
$q = mysqli_query($db, "SELECT `wae`, `nr`, hiscall, date, band from cwops_log where `mycall`='$c' and LENGTH(wae) = 2 $band group by `wae`");
if(!$q) {
echo mysqli_error($db);
while ($r = mysqli_fetch_row($q)) {
$ret .= "<tr><td>".$cnt++."</td><td>".$waes[$r[0]]." (".$r[0].")</td><td>".$r[1]."</td><td>".$r[2]."</td><td>".$r[3]."</td><td>".$r[4]."</td></tr>\n";
// replace numeric ADIF numbers with DXCC names and WAE abbreviations with
// full name
foreach (array_keys($needed) as $k) {
if (is_numeric($k)) {
$needed[$dxcc[$k]] = 1;
else {
$needed[$waes[$k]] = 1;
$ret .= "</table><br>Still needed:<br>".implode('<br>', array_keys($needed));
return $ret;
# import an ADIF file to the log of $callsign
@ -228,6 +295,8 @@ function dxcc($c, $b) {
# 3. Iterate through imported log and based on (1) decide which QSOs are saved in the database.
function import($adif, $callsign) {
global $db;
$ret = "Starting import for $callsign...<br>";
$members = get_memberlist();
$ret .= "Loaded member list with ".count($members)." entries.<br>";
@ -239,11 +308,17 @@ function import($adif, $callsign) {
$ret .= "Full log of the import below. <a href='#' onClick='javascript:document.getElementById(\"import_log\").style.display = \"none\";'>Click here to hide</a>";
$ret .= "<pre id='import_log'>";
$import_log = "";
foreach ($qsos as $q) {
$ret .= "QSO: ".$q['call']." ".$q['date']." ".$q['band']." needed for: ".$q['reasons']."<br>";
$import_log .= "QSO: ".$q['call']." ".$q['date']." ".$q['band']." needed for: ".$q['reasons']."<br>";
$ret .= $import_log;
$ret .= "</pre>";
# save this to the upload history
$q = mysqli_query($db, "insert into cwops_uploads (`uid`, `ts`, `count`, `result`)
VALUES (".$_SESSION['id'].", NOW(), ".count($qsos)." ,'".mysqli_real_escape_string($db, $import_log)."')");
return $ret;
@ -345,7 +420,12 @@ function parse_adif($adif, $members) {
$qso['wae'] = $match[3];
else {
$qso['wae'] = '';
if (substr($qso['call'], 0, 3) == "IT9") {
$qso['wae'] = 'SY';
else {
$qso['wae'] = '';


@ -8,8 +8,8 @@ include('functions.php');
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="/style.css">
<title>CWops Award Tools</title>
<!-- link rel="icon" href="/favicon.ico">
<link rel="shortcut icon" href="/favicon.ico" -->
<link rel="icon" href="/favicon.ico">
<link rel="shortcut icon" href="/favicon.ico">
<h1>CWops Award Tools</h1>
@ -42,7 +42,7 @@ if ($_SESSION['id']) {
if (request.readyState == done && request.status == ok) {
if (request.responseText) {
document.getElementById('upload_result').innerHTML = request.responseText;
load_stats('overview', 'stat_main');
else if (request.readyState == done) {
@ -55,10 +55,17 @@ if ($_SESSION['id']) {
function show(item) {
document.getElementById("stats").style.fontWeight = "normal";
document.getElementById("edit").style.fontWeight = "normal";
document.getElementById("log").style.fontWeight = "normal";
document.getElementById("uploads").style.fontWeight = "normal";
document.getElementById("stats_div").style.display = "none";
document.getElementById("edit_div").style.display = "none";
document.getElementById("log_div").style.display = "none";
document.getElementById("uploads_div").style.display = "none";
document.getElementById(item + "_div").style.display = "inline";
document.getElementById(item).style.fontWeight = "bold";
function search () {
@ -183,15 +190,29 @@ if ($_SESSION['id']) {
function reload_upload_history() {
var request = new XMLHttpRequest();"GET", '/api?action=upload_history', true);
request.onreadystatechange = function() {
var done = 4, ok = 200;
if (request.readyState == done && request.status == ok) {
if (request.responseText) {
document.getElementById('uploads_div').innerHTML = request.responseText;
<button id='stats' onClick="javascript:show(;reload_stats();">Show Stats</button>
<button id='stats' style="font-weight:bold" onClick="javascript:show(;reload_stats();">Show Stats</button>
<button id='edit' onClick="javascript:show(;">Edit QSOs</button>
<button id='log' onClick="javascript:show(;">Enter QSOs</button>
<button id='uploads' onClick="javascript:show(;reload_upload_history();">Show upload history</button>
@ -235,6 +256,9 @@ search item below and hit <button id='search' onClick="javascript:search();">Sea
echo stats($_SESSION['callsign']);
<div id="uploads_div" style="display:none;">
<h2>QSO upload history</h2>
else {
@ -248,6 +272,9 @@ else {
<input type='submit' value='Log in or create new account'>
<p>When signing up, you accept the <a href="/privacy">privacy policy</a> of this site.</p>
<p>Lost your password? Get in touch with <a href="">Fabian, DJ1YFK</a> to reset your account.</p>
@ -256,10 +283,6 @@ else {
<p>Last modified: <? echo date ("Y-m-d", filemtime("index.php")); ?> - <a href="">Fabian Kurz, DJ1YFK</a> <a href="">&lt;;</a>
if (!$_SERVER['HTTPS']) { ?> - <a rel="nofollow" href="">Switch to https</a> <? }
else { ?> - <a rel="nofollow" href="">Switch to http</a> <? }
- <a href="/privacy">Impressum / Datenschutz / Privacy Policy</a> - <a href="">Source code repository</a>


@ -24,8 +24,6 @@ ol {
<p>*** copy of -- needs some editing before release ***
<h1>Impressum - Kontakt</h1>
<p> Diese Webseite wird betrieben von / This website is operated by</p>
@ -40,116 +38,22 @@ phone: +49 89 5457 8182
mail: <a href=""></a>
<h1>Informationen zum Datenschutz</h1>
<p>(English version below)</p>
<p>Lieber Besucher! Auf dieser Seite wird das Datenschutzkonzept dieses
Internetauftritts erläutert. Alle Daten werden nach geltendem deutschen
Datenschutzrecht behandelt.</p>
<p>Der Zweck dieser Seite ist die Förderung des Amateurfunks.
Die Seite bietet Auswertungen von Amateurfunklogbüchern im Kontext
der Jahreswettbewerbe des First Class CW Operators Club an, und stellt
aufgearbeitete Daten aus dem "Reverse Beacon Network", einem Netzwerk
aus automatisch arbeitenden Amateurfunkempfängern in übersichtlicher
Art und Weise dar. Die Verarbeitung der Daten erfolgt aufgrund der
DSGVO, u.a. Erwägungsgrundlage 47, unter der ein legitimes Interesse
an der Verarbeitung der Daten besteht.</p>
<h2>Verarbeitung personenbezogener Daten von Web-Besuchern</h2>
<li>Es gibt auf dieser Seite <strong>keine Benutzeraccounts</strong>.</li>
<li>Es werden <strong>keine Daten an Dritte</strong> weitergegeben, weder durch Einbettung
externer Inhalte, noch durch Weitegabe der Daten, die durch den Besuch
dieser Seite entstanden sind.</li>
<li>Diese Webseite verwendet <strong>nur Cookies, die auf der Seite selbst verwendet werden</strong>. Diese dienen zur Erinnerung von vorher getätigten Einstellungen bei einem erneuten Besuch. Die Verwendung von Cookies ist optional und kann jederzeit im Browser deaktiviert werden.</li>
<li>Nur die folgenden Daten werden im Log des Servers gespeichert:
<li>Datum und Zeitpunkt der Anfrage</li>
<li>Die genaue URL der Anfrage</li>
<li>ggf. eine Referrer-URL (d.h. woher der Browser kam)</li>
<li>Die Kennung des Browsers (z.B. Mozilla Firefox), sofern diese
mitgesendet wird.</li>
<li>Die oben genannten Daten werden gespeichert um einen sicheren Betrieb
der Webseite zu ermöglichen (Detektion von Einbruchsversuchen,
Bekämpfung von Spam, usw.), sowie um <strong>anonymisierte</strong>
Statistiken zu erzeugen. Logs werden maximal 30 Tage gespeichert
sind in dieser Zeit nur dem Betreiber der Seite zugänglich. Danach
werden die Logs unwiderruflich gelöscht. Zu keiner Zeit werden diese
Daten Dritten zugänglich gemacht.</li>
<li>Der Standort des Servers ist Deutschland.</li>
<li>Diese Webseite kann über einen gesicherten Kanal (https) abgerufen
<li>Falls Sie eine Mail an den Betreiber der Seite schicken, wird diese,
inklusive der Metadaten, permanent archiviert. Falls Sie dies nicht
wünschen, weisen Sie bitte in der Mail kurz darauf hin.</li>
<h2>Verwendung der vom Nutzer eingegebenen Daten</h2>
<p>Zusätzlich zu den o.g. Serverlogs können auf dieser Seite Nutzerdaten anfallen:<br>
<strong>Verwendung des FOC Windle Score Calculators:</strong> Hier lädt
ein Benutzer sein Amateurfunklogbuch hoch, und es werden Kontakte mit
Mitgliedern des FOC herausgefiltert und tabellarisch
für das gewählte Jahr dargestellt. Dabei gilt Folgendes in Bezug auf
ggf. personenbezogene Daten:
<li>Die hochgeladenen Daten werden nicht dauerhaft gespeichert,
sondern nur zur Berechnung der Ausgabetabelle verarbeitet.
Sobald die Tabelle generiert ist, werden diese Daten sofort
<li>Die Ergebnistabelle wird auf dem Server für einen Zeitraum
von maximal 7 Tagen gespeichert, ist aber nur dem Nutzer
zugänglich, da hier ein Link mit einer nur dem Nutzer bekannten
Codenummer verwendet wird.</li>
<h2>Daten aus dem Reverse Beacon Network</h2>
<p>Auf dieser Webseite werden Daten verarbeitet und dargestellt, die aus einem weltweiten, von Funkamateuren zu wissenschaftlich-experimentellen Zwecken betriebenen Netzwerk von automatischen SDR-Empfängern stammen. Diese Empfänger suchen automatisch auf allen Amateurfunkfrequenzen nach Stationen, die in Morsecode oder digitalen Sendearten einen sogenannten "allgemeinen Anruf" senden.</p>
<p>Diese Datensätze bestehen aus Amateurfunkrufzeichen (Sender und Empfänger), Frequenzen und Zeiten, zu denen dieses Rufzeichen einen allgemeinen Anruf getätigt hat.</p>
<p>Da der Amateurfunk als Experimentalfunkdienst nur in offener Sprache durchgeführt werden darf (d.h. keine Verschlüsselung oder Verschleierung des Rufzeichens erlaubt), muss ein Funkamateur, der einen solchen allgemeinen Anruf sendet, davon ausgehen, dass dieser gehört, dekodiert und ggf. protokolliert wird, sei es manuell durch andere Funkamateure, oder durch die o.g. automatisierten Empfänger.</li>
<p>Daher können die somit gewonnen Daten als öffentlich bekannt angesehen werden, und eine Verarbeitung dieser zu Zwecken, die den wissenschaftlich-experimentellen Zwecken des Amateurfunks dienen, kann als legitimes Interesse im Sinne der Erwägungsgrundlage 47 des DSGVO angesehen werden.</p>
<h2>Löschung von personenbezogenen Daten</h2>
<p>Jeder, dessen personenbezogene Daten auf diesem Server gespeichert sind, hat das Recht auf permanente Löschung. Diese kann formlos über die oben angegebenen Kontaktdaten per E-Mail oder in Schriftform eingefordert werden.</p>
<p>Der Betreiber dieser Seite fertigt wöchentlich Sicherheitskopien an, um im
Falle eines Datenverlusts die Seite wiederherstellen zu können. Dazu wird die
gesamte Seite und Datenbank abgespeichert und an einem sicheren Ort für Dritte
unzugänglich verwahrt. Diese Sicherungskopien werden maximal einen Monat lang
aufbewahrt und danach unwiderruflich gelöscht.</p>
<p>Sollte ein Nutzer seine Daten löschen lassen, muss dieser hinnehmen, dass diese
noch bis zu 4 Wochen lang in Form einer Sicherungskopie existieren.</p>
<h2>Auskunft über gespeicherte Daten</h2>
<p>Jedem Nutzer der Seite steht ein uneingeschränktes Recht auf Auskunft über
die Daten zu, die über ihn oder sie gespeichert sind. Diese können jederzeit
über die im Impressum angegebene Adresse (E-Mail oder Post) abgefragt
<p>Diese Seite ist ein rein privates Projekt um den Amateurfunk zu fördern. Es
werden keine kommerziellen Interessen verfolgt.</p>
<h1>Data Privacy and Security Information</h1>
<p>Dear visitor,<br>this site summarizes the data privacy and security aspects of using this website.
Note that all data is processed and stored in accordance with German data privacy laws.</p>
<p>The sole purpose of this website is to help members of the CW Operators' Club in attaining the <a href="">awards of the club</a>.
<p>This website offers services for radio amateurs, specifically those who are members of the First Class CW Operators' Club (FOC). It offers to check an uploaded amateur radio log against for contacts with members of the FOC. It also offers data that was received by the Reverse Beacon Network, an international network of SDR receivers with Morse- and digital mode decoders, in an easy to read format (RBN Activity reports). The processing of this data is based on legitimate interests in accordance with the GDPR (47).</p>
<h2>Personal data of website visitors</h2>
<h2>Personal data</h2>
<li>There are <strong>no user accounts</strong> on this website. All information can be queried by any user without logging in.</li>
<li>Accepting this privacy policy is required to create an account on this site.</li>
<li>There are <strong>no third parties</strong> involved when you visit this website. Neither by embedding any assets (scripts, images, ...) from other domains, nor by sharing any data that was generated during your visit with anyone else.</li>
<li>This website does <strong>only use first-party cookies</strong> which never leave the trust zone between you and this server. The cookies are used for the sole purpose of remembering personal settings you previously made on the site, so you can keep them between visiting sessions. Cookies are optional and may be blocked by the user.</li>
<li>This website only uses <strong>a session cookie</strong> with the sole
purpose of recognising an user during his visit on the website, to ensure
that after logging in he can access his saved preferences and training
results. <strong>The cookie is deleted when the user logs out.</strong></li>
<li>Only the following pieces of personal data are securely stored in the server logs, accessible by the operator.
<li>Date, time of the access</li>
@ -160,56 +64,82 @@ Note that all data is processed and stored in accordance with German data privac
<li>The data mentioned above is stored in order to ensure safe operation (intrusion detection, abuse prevention) and to generate anonymised statistics. Logs are stored for a maximum period of 30 days and irrevocably erased after this time. No data is shared with third parties.</li>
<li><strong>Additional data saved during your visit as a logged in user is described in detail in
the following paragraph.</strong></li>
<li>The server location is Germany.</li>
<li>This site can be accessed through an encrypted channel (https).</li>
<li>If you send an email to the operator, this mail including its headers will be archived indefinitely, but only accessible by the site operator.
If you don't want this, let us know in the mail.</li>
<h2>User submitted data</h2>
<p>Additionally to the server logs mentioned above, personal data may be processed as follows:<br>
<strong>Using the FOC Windle Point Calculator:</strong> A website user can upload his
ham radio logbook, from which then contacts with members of the
FOC are filtered out and returned in the form of a table. This has the following
implications on the use of personal data:
<li>The uploaded files are not saved permanently, but processed
<em>on the fly</em> to create a result table.</li>
<li>The table of results is saved on the server for up to
7 days after which it is permanently deleted. Only the user
can access this data by a personalised link.</li>
<h2>User generated data</h2>
Users of the site generate data by uploading their amateur radio logs, which are (in part) saved in a database.
The exact data is detailled in the following paragraph, along with how long it
is saved and the visibility. <strong>The data is collected for the sole purpose
of calculating points for awards and to create fully anonymized statistics.</strong>
<li><strong>Creating an account:</strong> Only an username (can be an anonymous
pseudonym) and a password are required. An email address can be voluntarily
entered and it will only be used to recover a lost password.<br>
<strong>Data storage duration:</strong> Until user change data or
deletes their account. <br>
<strong>Visibility:</strong> Only to site administrators. Not public.</li>
<li><strong>On each login:</strong> Account and time of the login.<br>
<strong>Data storage duration:</strong> 10 minutes after the last
activity on the site.<br>
<strong>Visibility:</strong> Site administrator only.</li>
<li><strong>Uploading ADIF logs:</strong> The uploaded data will be filtered
for relevant data, and for each record uploaded, at maximum the callsign,
date, frequency/band, DXCC, zone, state and WAE will be saved to the database.
Additionally a summary of the upload will be saved for later review by the user.<br>
<strong>Data storage duration:</strong> Until deleted by user or deletion of account.<br>
<strong>Visibility:</strong> Only to the user and site administrator.</li>
<li><strong>Any other data:</strong> Any other data not mentioned is always
handled with the utmost care and by the priciple of minimizing
<p>Users will only receive electronic mail from the site under the following
<li>When a password-reset was requested.</li>
<li>Important administrative announcements regarding the site (strictly no advertising, etc.)</li>
<h2>Reverse Beacon Network Data</h2>
<p>On this site, data originating from a world wide network of automated SDR receivers (the "Reverse Beacon Network"), which are operated by radio amateurs and continuously monitor the amateur radio frequencies for stations making a general call ("CQ"), is processed and displayed.</p>
<p>The operator of the site always technically has full access to <strong>all data</strong>
but will only make use of this privilege when absolutely necessary, e.g. to
fend off cyber attacks, investigate abusive behaviour, or to assist law
enforcement as required by law.</p>
<p>The data contains amateur radio callsigns, frequencies and timestamps when the callsign was heard making a general call.</p>
<p>Due to the open nature of amateur radio, which is an experimental and scientific radio service in which all
communication must be carried out in clear language, without encryption or any obfuscation,
it must be assumed that a radio amateur who is transmitting his callsign does this to be received by other amateurs and he has no reasonable expectation that his transmission remain private.</p>
<p>Therefore the processing of this data,
which was voluntarily transmitted, can be considered in the public domain, since it does not contain privileged or confidential information.</p>
<p>The usage for the purpose of generating amateur radio statistics and helping to advance radio propagation research, therefore is a legitimate interest according to article 47 of the GDPR.</p>
<h2>Disclosure of personal data</h2>
<p>Every user has the right to request a full copy of all personal data saved
on this site about him or her. This can be requested at any time via the
contact information provided (either by email or postal mail).</p>
<h2>Removal of personal data</h2>
<p>Anyone whose personal data is stored on this server has the right to have it permanently removed by simply contacting the above mentioned contact, by email or postal mail.</p>
<h2>Removal of data</h2>
<p>Every user can, at any time, delete his user account, or request the
deletion by contacting the site operator. Upon deletion, all data related to
the user account is immediately deleted, with the possible exception of log
files and backup copies, which will be deleted at latest 30 days later.</p>
<h2>Backup copies</h2>
<p>The site operator creates weekly database backups in order to restore the
site in case of a data loss (e.g. by hardware malfunctions). The whole database
<p>The site operator creates weekly backups in order to restore the
site in case of a data loss (e.g. by hardware malfunctions). The whole site
will be exported and stored in a safe place, without access of third
<p>If data is deleted in the main database, the entry may still exist
<p>If data is deleted in the main site, the information may still exist
in the backups for up to four weeks.</p>
<h2>Disclosure of personal data</h2>
<p>Every user has the right to request a full copy of all personal data saved
on this site about him or her. This can be requested at any time via the
contact information provided (either by E-Mail or postal mail).</p>
<p>Complaints can be filed with the <a href="">Bayerische Landesbeauftragte
für den Datenschutz</a>.</p>
<p>This website is a strictly private project aiming to help radio amateurs in their hobby. There are no commercial interests of any kind.</p>
<p>This website is a strictly private project. There are no commercial interests of any kind.</p>
<a href="/">Home</a>


@ -8,4 +8,9 @@ $waes = array(
"KO" => "Kosovo, Z6",
"ET" => "European Turkey, TA1"
# these ADIF DXCC numbers are European countries
$wae_adif = array(5, 7, 21, 27, 40, 45, 52, 54, 106, 114, 117, 118, 122, 126, 145, 146, 149, 167, 179, 180, 203, 206, 209, 212, 214, 221, 222, 223, 224, 225, 227, 230, 233, 236, 239, 242, 245, 246, 248, 251, 254, 257, 259, 260, 263, 265, 266, 269, 272, 275, 278, 279, 281, 284, 287, 288, 294, 295, 296, 497, 499, 501, 502, 503, 504, 514, 522);