Browse Source

Initial commit

master
Fabian Kurz 2 years ago
commit
31795ab412
  1. 2
      .gitignore
  2. 2
      .htaccess
  3. 10
      db.php
  4. 14
      db/cwops_log.sql
  5. 6
      db/cwops_members.sql
  6. 7
      db/cwops_users.sql
  7. 37
      db/import.pl
  8. 67
      functions.php
  9. 58
      index.php
  10. 62
      login.php
  11. 214
      privacy.php
  12. 47
      style.css

2
.gitignore

@ -0,0 +1,2 @@
*~
*.csv

2
.htaccess

@ -0,0 +1,2 @@
RewriteEngine On
RewriteRule ^logout(/)?$ /login.php?f=logout [L]

10
db.php

@ -0,0 +1,10 @@
<?
# DB config
$mysql_host = "localhost";
$mysql_user = "cwops";
$mysql_pass = "cwops";
$mysql_dbname = "CWops";
$db = mysqli_connect($mysql_host,$mysql_user,$mysql_pass,$mysql_dbname) or die
("<h1>Sorry: Could not connect to database.</h1>");
?>

14
db/cwops_log.sql

@ -0,0 +1,14 @@
CREATE TABLE `cwops_log` (
`mycall` varchar(64) NOT NULL default '',
`date` date NOT NULL,
`year` int NOT NULL default 0,
`band` float NOT NULL default 0,
`nr` int NOT NULL default 0,
`hiscall` varchar(64) NOT NULL default '',
`dxcc` int NOT NULL default 0,
`wae` varchar(2) NOT NULL default '',
`waz` int NOT NULL default 0,
`was` varchar(2) NOT NULL default '',
PRIMARY KEY (`callsign`),
KEY(`nr`)
);

6
db/cwops_members.sql

@ -0,0 +1,6 @@
CREATE TABLE `cwops_members` (
`nr` bigint(5) NOT NULL default 0,
`callsign` varchar(64) NOT NULL default '',
`joined` date NOT NULL,
`left` date NOT NULL
);

7
db/cwops_users.sql

@ -0,0 +1,7 @@
CREATE TABLE `cwops_users` (
`id` bigint(5) NOT NULL auto_increment,
`callsign` varchar(64) NOT NULL default '',
`email` varchar(64) NOT NULL default '',
`password` varchar(64) NOT NULL default '',
PRIMARY KEY (`ID`)
) AUTO_INCREMENT = 1;

37
db/import.pl

@ -0,0 +1,37 @@
#!/usr/bin/perl#
use warnings;
use strict;
# 7,,,K5MA,Jan,,,,,,,,,,,,,,,,,31-Dec-2009,13-Nov-2018,K,MA,SK
print "delete from cwops_members;\n";
while (my $line = <>) {
next unless ($line =~ /^\d/);
my @a = split(/,/, $line);
my $nr = $a[0];
my $callsign = $a[3];
my $joined = $a[21];
my $left = $a[22];
$joined = &dateformat($joined);
if ($left) {
$left = &dateformat($left)
}
else {
$left = "20990101";
}
print "INSERT into cwops_members (`nr`, `callsign`, `joined`, `left`) VALUES ('$nr', '$callsign', '$joined', '$left');\n";
}
# in 1-Jun-2019 out -> 20190601
sub dateformat {
my %months = ( "Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04", "May" => "05", "Jun" => "06", "Jul" => "07", "Aug" => "08", "Sep" => "09", "Oct" => "10", "Nov" => "11", "Dec" => "12" );
my @d = split(/-/, shift);
return sprintf("%s%s%02d", $d[2], $months{$d[1]}, $d[0]);
}

67
functions.php

@ -0,0 +1,67 @@
<?php
include_once("db.php");
function stats($c) {
global $db;
}
# import an ADIF file to the log of $callsign
#
# Only import QSOs when it's a new
# - Member (identified by his number) on this band OR in a new year
# - State on this band
# - DXCC on this band
# - WAZ on this band
# - WAE (on any band)
# Steps:
# 1. Load the current member list into an array
# 2. Parse ADI into an array, omitting all calls that are not members (considering the date of the QSO) and non-CW-QSOs
# 3. Iterate through imported log and based on (1) decide which QSOs are saved in the database.
function import($adif, $callsign) {
$members = get_memberlist();
$qsos = parse_adif($adif, $members);
}
function get_memberlist() {
global $db;
$q = mysqli_query($db, "SELECT * from cwops_members;");
$members = array();
while ($r = mysqli_fetch_array($q, MYSQLI_ASSOC)) {
array_push($members, $r);
}
return $members;
}
# parse ADIF but only QSOs which are included in $members
function parse_adif($adif, $members) {
# make hash table for quicker member lookup
$mh = array();
foreach ($members as $m) {
$mh[$m["callsign"]] = $m["nr"];
}
}
import("x", "y");
?>

58
index.php

@ -0,0 +1,58 @@
<?
session_start();
include('functions.php');
?>
<!DOCTYPE html>
<html>
<head>
<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" -->
</head>
<body>
<h1>CWops Award Tools</h1>
<p>This server provides services for members of <a href="https://cwops.org/">CWops</a>. It's maintained by <a href="https://fkurz.net">Fabian, DJ1YFK</a> (CWops #1566) and is not an official web site of the club.</p> <hr>
<h2>ACA, CMA, WAS, WAE and WAZ tracking</h2>
<?
if ($_SESSION['id']) {
?>
<p>Logged in as <?=$_SESSION['callsign'];?>. <a href="/logout">Log out</a></p>
<?
echo stats($_SESSION['callsign']);
}
else {
?>
<p>In order to track your standings for the various <a href="https://cwops.org/contact-us/awards/">CWops awards</a>, create a free account <em>or</em> if you already have an account, log in with the form below:</p>
<form action='/login' method='POST'>
<table><tr><td>Callsign:</td><td> <input name='callsign' type='text' size='10'></td></tr>
<tr><td>Password:</td><td><input name='password' type='password' size='10'></td></tr>
</table>
<input type='submit' value='Log in or create new account'>
</form>
<p>Lost your password? Get in touch with <a href="mailto:fabian@fkurz.net">Fabian, DJ1YFK</a> to reset your account.</p>
<?
}
?>
<hr>
<p>Last modified: <? echo date ("Y-m-d", filemtime("index.php")); ?> - <a href="http://fkurz.net/">Fabian Kurz, DJ1YFK</a> <a href="mailto:fabian@fkurz.net">&lt;fabian@fkurz.net&gt;</a>
<?
if (!$_SERVER['HTTPS']) { ?> - <a rel="nofollow" href="https://cwops.telegraphy.de/">Switch to https</a> <? }
else { ?> - <a rel="nofollow" href="http://cwops.telegraphy.de/">Switch to http</a> <? }
?>
- <a href="/privacy">Impressum / Datenschutz / Privacy Policy</a>
</p>
</body>
</html>

62
login.php

@ -0,0 +1,62 @@
<?
session_start();
include_once('db.php');
if ($_GET['f'] == 'logout') {
session_destroy();
header("Location: http://cwops.telegraphy.de/");
return;
}
$call = strtoupper($_POST['callsign']);
$password = $_POST['password'];
# check validity
if (!preg_match('/^[a-z0-9\/]+$/i', $call)) {
echo "Callsign can only contain A-Z, 0-9 and /.";
echo "<a href='/'>Return to home page</a>";
return;
}
log_in_or_create($call, $password, true);
function log_in_or_create ($call, $password, $recursive) {
global $db;
$q = mysqli_query($db, "SELECT * from cwops_users where callsign='$call'");
$user = mysqli_fetch_object($q);
if ($user) {
if (password_verify($password, $user->password)) {
header("Location: http://cwops.telegraphy.de/");
$_SESSION['id'] = $user->id;
$_SESSION['callsign'] = $user->callsign;
echo "Login successful! Forwarding...";
error_log("successful login of ".$user->callsign);
return;
}
else {
echo "Password incorrect. Try again.";
echo "<a href='/'>Return to home page</a>";
return;
}
}
else { # create account
$hash = password_hash($password, PASSWORD_DEFAULT);
$q = mysqli_query($db, "INSERT into cwops_users (`callsign`, `password`) VALUES ('$call', '$hash');");
# now log in
if ($recursive) {
log_in_or_create($call, $password, false);
}
}
}
?>

214
privacy.php

@ -0,0 +1,214 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" >
<link rel="shortcut icon" href="favicon.png">
<link rel="icon" href="favicon.png">
<link rel="stylesheet" href="style.css">
<title>cwops.telegraphy.de - Informationen zum Datenschutz / Data Privacy and Security Information</title>
<style>
p {
max-width: 50em;
text-align: justify;
}
ul {
max-width: 45em;
text-align: justify;
}
ol {
max-width: 45em;
text-align: justify;
}
</style>
</head>
<body>
<h1>Impressum - Kontakt</h1>
<p> Diese Webseite wird betrieben von / This website is operated by</p>
<p>Fabian Kurz, DJ1YFK<br>
Frohschammerstr. 8<br>
D-80807 München<br>
Germany<br>
<br>
phone: +49 89 5457 8182
<br>
mail: <a href="mailto:fabian@fkurz.net">fabian@fkurz.net</a>
</p>
<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>
<ul>
<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:
<ul>
<li>Datum und Zeitpunkt der Anfrage</li>
<li>IP-Adresse</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>
</ul>
<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
und
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
werden.</li>
<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>
</ul>
<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:
<ol>
<li>Die hochgeladenen Daten werden nicht dauerhaft gespeichert,
sondern nur zur Berechnung der Ausgabetabelle verarbeitet.
Sobald die Tabelle generiert ist, werden diese Daten sofort
verworfen.</li>
<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>
</ol>
</p>
<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>
<h2>Sicherungskopien</h2>
<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
werden.</p>
<h2>Sonstiges</h2>
<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>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>
<ul>
<li>There are <strong>no user accounts</strong> on this website. All information can be queried by any user without logging in.</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>Only the following pieces of personal data are securely stored in the server logs, accessible by the operator.
<ul>
<li>Date, time of the access</li>
<li>IP address of the accessing computer</li>
<li>The exact URL (address) of the request</li>
<li>The referrer URL (e.g. where did the user come from)</li>
<li>The user's browser identification string</li>
</ul>
</li>
<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>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>
</ul>
<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:
<ol>
<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>
</ol>
</p>
<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 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>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>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
will be exported and stored in a safe place, without access of third
parties.</p>
<p>If data is deleted in the main database, the entry 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>
<h2>Miscellaneous</h2>
<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>
<hr>
<a href="/">Home</a>
</body>
</html>

47
style.css

@ -0,0 +1,47 @@
body,td{font-family:Ubuntu,calibri,tahoma,arial,sans-serif; font-size: 12px}
h2 {font-size:18px}
h3 {
margin-bottom: 1px;
padding-bottom: 1px;
}
h4 {
padding: 0px 0px 0px 5px;
margin: 0px 0px 0px 5px;
}
ul {
margin-top: 3px;
margin-bottom: 3px;
}
table {
border-width: 2px;
border-color: #000000;
border-style: solid;
}
th {
background-color: #aabbff;
}
td {
padding-right: 6px;
padding-left: 6px;
}
code {
background-color: #dddddd;
}
.newspot { background-color: #ffcccc; }
.midspot { background-color: #ffffff; }
.oldspot { background-color: #eeeeee; }
.right { text-align:right; }
.snr40 { color: #000000; }
.snr30 { color: #444444; }
.snr20 { color: #888888; }
.snr10 { color: #aaaaaa; }
.snr00 { color: #cccccc; }
.snr40hc { font-weight: bold; color: #000000; }
.snr30hc { color: #111111; }
.snr20hc { color: #222222; }
.snr10hc { color: #333333; }
.snr00hc { color: #444444; }
Loading…
Cancel
Save