Porównaj commity

...

31 Commity

Autor SHA1 Wiadomość Data
Patrick Burns 499c29bb5a
Merge 253da3797c into 42e76d8aa6 2024-04-16 11:02:28 -07:00
Peter Goodhall 42e76d8aa6
Fix SSTV localization strings 2024-04-16 13:59:50 +01:00
Peter Goodhall 4dc074241d
Merge pull request #3080 from nolith/qso_labels_awards
Print activator references on QSO labels
2024-04-16 13:59:02 +01:00
Alessio Caiazza cb85ad2144
Print activator references on QSO labels 2024-04-15 21:50:27 +02:00
Peter Goodhall 01ba223c27 Revert "Update pota.txt"
This reverts commit b551ba3a30.
2024-04-14 17:06:42 +01:00
Peter Goodhall 73032061e4 Tag 2.6.9 2024-04-14 16:23:57 +01:00
Patrick Burns 253da3797c pause for the night on passing tests 2024-04-07 21:31:41 -05:00
Patrick Burns f619a6b702 add a step to check that the link station button works 2024-04-07 20:53:47 -05:00
Patrick Burns 6c06956e9a add station logbook create tests 2024-04-07 20:29:50 -05:00
Patrick Burns ec8f4b4e5d 3 second delay was too fast 2024-04-07 20:18:29 -05:00
Patrick Burns 485c21a1eb attempting to add some caching and speed up the delay 2024-04-07 20:16:12 -05:00
Patrick Burns 08c5e4420f testing if i need both dxcc calls 2024-04-07 20:08:43 -05:00
Patrick Burns ede0b201a5 attempt to add the permissions stuff to the script.sh before adding it to github actions 2024-04-07 20:04:08 -05:00
Patrick Burns e0af386cc5 add another request for dxcc 2024-04-07 19:58:37 -05:00
Patrick Burns 08d2ffaa3b add a short delay to let web connect to db 2024-04-07 19:49:57 -05:00
Patrick Burns a361d593e5 move it to github actions run step 2024-04-07 19:46:21 -05:00
Patrick Burns f65a8c1e12 still trying to populate dxcc_entities for the station creation tests 2024-04-07 19:39:19 -05:00
Patrick Burns 3d5169bbdd move request to the before on the station tests 2024-04-07 19:25:23 -05:00
Patrick Burns 155537e99c add request to populate dxcc_entities 2024-04-07 19:18:48 -05:00
Patrick Burns 45fc6b96be station-location create added 2024-04-07 17:21:40 -05:00
Patrick Burns 3dd728d251 change notifications to alerts and only number login/verify since it sets a global flag 2024-04-07 16:18:45 -05:00
Patrick Burns 8ade6979df more login page tests 2024-04-07 16:09:22 -05:00
Patrick Burns e1f75906ee add tests for new account alerts 2024-04-07 15:58:55 -05:00
Patrick Burns 0e7232a50c add notes about running tests locally to readme 2024-04-07 14:33:17 -05:00
Patrick Burns f28bc904ad undo one more minor change that was related to qso testing, will address it later 2024-04-07 14:20:39 -05:00
Patrick Burns bfb39c0b1d undo qso changes, will address those later 2024-04-07 14:16:55 -05:00
Patrick Burns 6d7d5fb459 Merge branch 'dev' into cypress-end-to-end-testing 2024-04-07 14:09:58 -05:00
Patrick Burns 0473a3c621 update main.yml -> cypress-tests.yml 2024-04-07 14:09:45 -05:00
Patrick Burns a0a12c776c update test nad a few other minor updates 2024-04-07 14:04:11 -05:00
Patrick Burns 134d6bcf98 add sstv strings to the rest of the language files 2024-04-07 12:27:05 -05:00
Patrick Burns 238f1e66fa end to end testing 2024-04-05 15:36:16 -05:00
46 zmienionych plików z 42240 dodań i 54831 usunięć

9
.env.sample 100644
Wyświetl plik

@ -0,0 +1,9 @@
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=cloudlog
MYSQL_USER=cloudlog
MYSQL_PASSWORD=cloudlogpassword
MYSQL_HOST=db
MYSQL_PORT=3306
BASE_LOCATOR=IO91WM
WEBSITE_URL=http://localhost
DIRECTORY=/var/www/html

Wyświetl plik

@ -0,0 +1,45 @@
name: Cypress Tests
on: [pull_request]
jobs:
cypress-e2e-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Cache Cypress
uses: actions/cache@v2
with:
path: ~/.cache/Cypress
key: cypress-${{ hashFiles('package-lock.json') }}
restore-keys: |
cypress-
- name: Install Cypress
run: npm install cypress
- name: Cache .env
uses: actions/cache@v2
with:
path: .env
key: .env-${{ hashFiles('.env.sample') }}
restore-keys: |
.env-
- name: Setup .env
run: |
if [ ! -f .env ]; then
cp .env.sample .env
fi
- name: Build Docker services
run: docker-compose up -d
- name: Wait for services to start
run: sleep 5
- name: Populate dxcc_entities table
run: curl "http://localhost/index.php/update/dxcc"
- name: Run Cypress tests
run: npx cypress run

3
.gitignore vendored
Wyświetl plik

@ -13,8 +13,11 @@
/assets/qslcard/*
/assets/sstvimages/*
/assets/js/sections/custom.js
/cypress/screenshots
/node_modules/
.idea/*
.DS_Store
sync.sh
*.p12
*.swp
.env

28
Dockerfile 100644
Wyświetl plik

@ -0,0 +1,28 @@
# Use the official image for PHP and Apache
FROM php:7.4-apache
# Set the working directory to /var/www/html
WORKDIR /var/www/html
# Install system dependencies, including git and libxml2
RUN apt-get update && apt-get install -y \
libcurl4-openssl-dev \
libxml2-dev \
libzip-dev \
zlib1g-dev \
libpng-dev \
libonig-dev \
default-mysql-client \
curl \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& docker-php-ext-install pdo_mysql \
&& docker-php-ext-install mysqli \
&& docker-php-ext-install gd \
&& docker-php-ext-install mbstring \
&& docker-php-ext-install zip \
&& docker-php-ext-install xml \
&& a2enmod rewrite
# Expose port 80
EXPOSE 80

8
Dockerfile-db 100644
Wyświetl plik

@ -0,0 +1,8 @@
# Dockerfile-db
FROM mariadb:latest
# Add the install.sql file to the docker image
ADD install/assets/install.sql /docker-entrypoint-initdb.d
# Expose port 3306
EXPOSE 3306

Wyświetl plik

@ -11,24 +11,99 @@ Core Contributors: 2M0SQL ([@magicbug](https://github.com/magicbug)), LA8AJA ([@
Website: [http://www.cloudlog.co.uk](http://www.cloudlog.co.uk)
## Requirements
* Linux based Operating System
* Apache (Nginx should work)
* PHP Version 7.4 (PHP 8.2 works)
* MySQL (MySQL 5.7 or higher)
- Linux based Operating System
- Apache (Nginx should work)
- PHP Version 7.4 (PHP 8.2 works)
- MySQL (MySQL 5.7 or higher)
Notes
* If you want to log microwave QSOs you will need to use a 64bit operating system.
* We do not provide Docker support, however you are free to use it if you wish but we will not handle support.
- If you want to log microwave QSOs you will need to use a 64bit operating system.
- We do not provide Docker support, however you are free to use it if you wish but we will not handle support.
## Setup
Installation information can be found on the [wiki](https://github.com/magicbug/Cloudlog/wiki).
# Docker Development Environment
This guide provides instructions for setting up a local development environment using Docker and Docker Compose. Please note that this setup is not recommended for production use.
## Prerequisites
Before you begin, you need to install Docker and Docker Compose. You can download them using the following links:
- [Docker](https://docs.docker.com/get-docker/)
- [Docker Compose](https://docs.docker.com/compose/install/)
## Configuration
1. Copy the `.env.sample` file to `.env`:
```bash
cp .env.sample .env
```
2. Open the `.env` file and update the values to match your setup. The values from the `.env` file will be used to populate the database connection details on the install page. You should not need to change these unless your setup requires different values.
**Note:** Docker Compose creates a network for your application, and each service (container) in the Docker Compose file can reach each other via the service name. This is why the `DB_HOST` value in the `.env` file and on the install page should match the service name of the database in the `docker-compose.yml` file. For example, if the database service in `docker-compose.yml` is defined as `db`, then `DB_HOST` should be set as 'db'. This allows the application to communicate with the database service on its internal docker network.
## Starting the Development Environment
To start the development environment, run the following command in your terminal:
```bash
docker-compose up
```
# Running Cypress Tests Locally
Follow these steps to run the Cypress tests locally on your machine:
1. **Clone the repository**
If you haven't already, clone the repository to your local machine
2. **Setup .env file**
Copy the sample `.env` file and adjust it to your local environment:
```bash
cd your-repo
cp .env.sample .env
```
3. **Build Docker services**
Build and start the Docker services:
```bash
docker-compose up -d
```
4. **Install Cypress**
Navigate into the project directory and install Cypress:
```bash
npm install cypress
```
5. **Run the Cypress tests**
After the installation is complete, you can run the Cypress tests:
```bash
npx cypress run
```
## Support
Cloudlog has two support systems for code issues use Github issues, however if you have general issues with setting up your server please use our general discussion forum [https://github.com/magicbug/Cloudlog/discussions](https://github.com/magicbug/Cloudlog/discussions).
## Security Vulnerabilities
If you discover a security vulnerability within Cloudlog, please send an e-mail to Peter Goodhall, 2M0SQL via [peter@magicbug.co.uk](mailto:peter@magicbug.co.uk). All security vulnerabilities will be promptly addressed.
## Want Cloudlog Hosting?

Wyświetl plik

@ -22,7 +22,7 @@ $config['migration_enabled'] = TRUE;
|
*/
$config['migration_version'] = 177;
$config['migration_version'] = 178;
/*
|--------------------------------------------------------------------------

Wyświetl plik

@ -135,10 +135,11 @@ class Labels extends CI_Controller {
$offset = xss_clean($this->input->post('startat'));
$grid = $this->input->post('grid') === "true" ? 1 : 0;
$via = $this->input->post('via') === "true" ? 1 : 0;
$awards = $this->input->post('awards') === "true" ? 1 : 0;
$this->load->model('labels_model');
$result = $this->labels_model->export_printrequestedids($ids);
$this->prepareLabel($result, true, $offset, $grid, $via);
$this->prepareLabel($result, true, $offset, $grid, $via, $awards);
}
public function print($station_id) {
@ -146,18 +147,19 @@ class Labels extends CI_Controller {
$offset = xss_clean($this->input->post('startat'));
$grid = xss_clean($this->input->post('grid') ?? 0);
$via = xss_clean($this->input->post('via') ?? 0);
$awards = xss_clean($this->input->post('awards') ?? 0);
$this->load->model('stations');
if ($this->stations->check_station_is_accessible($station_id)) {
$this->load->model('labels_model');
$result = $this->labels_model->export_printrequested($clean_id);
$this->prepareLabel($result, false, $offset, $grid, $via);
$this->prepareLabel($result, false, $offset, $grid, $via, $awards);
} else {
redirect('labels');
}
}
function prepareLabel($qsos, $jscall = false, $offset = 1, $grid = false, $via = false) {
function prepareLabel($qsos, $jscall = false, $offset = 1, $grid = false, $via = false, $awards = false) {
$this->load->model('labels_model');
$label = $this->labels_model->getDefaultLabel();
@ -232,11 +234,7 @@ class Labels extends CI_Controller {
}
if ($qsos->num_rows() > 0) {
if ($label->qsos == 1) {
$this->makeMultiQsoLabel($qsos->result(), $pdf, 1, $offset, $ptype->orientation, $grid, $via);
} else {
$this->makeMultiQsoLabel($qsos->result(), $pdf, $label->qsos, $offset, $ptype->orientation, $grid, $via);
}
$this->makeMultiQsoLabel($qsos->result(), $pdf, $label->qsos, $offset, $ptype->orientation, $grid, $via, $awards);
} else {
$this->session->set_flashdata('message', '0 QSOs found for print!');
redirect('labels');
@ -244,7 +242,7 @@ class Labels extends CI_Controller {
$pdf->Output();
}
function makeMultiQsoLabel($qsos, $pdf, $numberofqsos, $offset, $orientation, $grid, $via) {
function makeMultiQsoLabel($qsos, $pdf, $numberofqsos, $offset, $orientation, $grid, $via, $awards) {
$text = '';
$current_callsign = '';
$current_sat = '';
@ -261,7 +259,7 @@ class Labels extends CI_Controller {
( ($qso->COL_BAND_RX !== $current_sat_bandrx) && ($this->pretty_sat_mode($qso->COL_SAT_MODE) !== '')) ) {
// ((($qso->COL_SAT_NAME ?? '' !== $current_sat) || ($qso->COL_CALL !== $current_callsign)) && ($qso->COL_SAT_NAME ?? '' !== '') && ($col->COL_BAND_RX ?? '' !== $current_sat_bandrx))) {
if (!empty($qso_data)) {
$this->finalizeData($pdf, $current_callsign, $qso_data, $numberofqsos, $orientation, $grid, $via);
$this->finalizeData($pdf, $current_callsign, $qso_data, $numberofqsos, $orientation, $grid, $via, $awards);
$qso_data = [];
}
$current_callsign = $qso->COL_CALL;
@ -281,19 +279,46 @@ class Labels extends CI_Controller {
'sat_mode' => $this->pretty_sat_mode($qso->COL_SAT_MODE ?? ''),
'sat_band_rx' => ($qso->COL_BAND_RX ?? ''),
'qsl_recvd' => $qso->COL_QSL_RCVD,
'mycall' => $qso->COL_STATION_CALLSIGN
'mycall' => $qso->COL_STATION_CALLSIGN,
'awards' => $this->stationAwardsList($qso)
];
}
if (!empty($qso_data)) {
$this->finalizeData($pdf, $current_callsign, $qso_data, $numberofqsos, $orientation, $grid, $via);
$this->finalizeData($pdf, $current_callsign, $qso_data, $numberofqsos, $orientation, $grid, $via, $awards);
}
}
function stationAwardsList($station_profile) {
$awards = "";
if (trim($station_profile->station_iota) !== '') {
$awards .= "IOTA:" . $station_profile->station_iota . " ";
}
if (trim($station_profile->station_sota) !== '') {
$awards .= "SOTA:" . $station_profile->station_sota . " ";
}
if (trim($station_profile->station_wwff) !== '') {
$awards .= "WWFF:" . $station_profile->station_wwff . " ";
}
if (trim($station_profile->station_pota) !== '') {
$awards .= "POTA:" . $station_profile->station_pota . " ";
}
if (trim($station_profile->station_sig) !== '' && trim($station_profile->station_sig_info) !== '') {
$awards .= $station_profile->station_sig . ":" . $station_profile->station_sig_info;
}
return $awards;
}
// New begin
function pretty_sat_mode($sat_mode) {
return(strlen($sat_mode ?? '') == 2 ? (strtoupper($sat_mode[0]).'/'.strtoupper($sat_mode[1])) : strtoupper($sat_mode ?? ''));
}
function finalizeData($pdf, $current_callsign, &$preliminaryData, $qso_per_label,$orientation, $grid, $via) {
function finalizeData($pdf, $current_callsign, &$preliminaryData, $qso_per_label,$orientation, $grid, $via, $awards) {
$tableData = [];
$count_qso = 0;
@ -313,7 +338,7 @@ class Labels extends CI_Controller {
if($count_qso == $qso_per_label){
$this->generateLabel($pdf, $current_callsign, $tableData,$count_qso,$qso,$orientation, $grid, $via);
$this->generateLabel($pdf, $current_callsign, $tableData,$count_qso,$qso,$orientation, $grid, $via, $awards);
$tableData = []; // reset the data
$count_qso = 0; // reset the counter
}
@ -321,12 +346,12 @@ class Labels extends CI_Controller {
}
// generate label for remaining QSOs
if($count_qso > 0){
$this->generateLabel($pdf, $current_callsign, $tableData,$count_qso,$qso,$orientation, $grid, $via);
$this->generateLabel($pdf, $current_callsign, $tableData,$count_qso,$qso,$orientation, $grid, $via, $awards);
$preliminaryData = []; // reset the data
}
}
function generateLabel($pdf, $current_callsign, $tableData,$numofqsos,$qso,$orientation,$grid=true, $via=false){
function generateLabel($pdf, $current_callsign, $tableData,$numofqsos,$qso,$orientation,$grid=true, $via=false, $awards=false){
$builder = new \AsciiTable\Builder();
$builder->addRows($tableData);
$text = "Confirming QSO".($numofqsos>1 ? 's' : '')." with ";
@ -347,6 +372,7 @@ class Labels extends CI_Controller {
}
$text.="\n";
if ($grid) { $text .= "My call: ".$qso['mycall']." Grid: ".$qso['mygrid']."\n"; }
if ($awards) { $text .= $qso['awards']."\n"; }
$text .= "Thanks for the QSO".($numofqsos>1 ? 's' : '');
$text .= " | ".($qso['qsl_recvd'] == 'Y' ? 'TNX' : 'PSE')." QSL";
$pdf->Add_Label($text,$orientation);

Wyświetl plik

@ -59,6 +59,10 @@ class User_Options extends CI_Controller {
echo json_encode($jsonout);
}
public function enableVersionDialog() {
$this->user_options_model->set_option('version_dialog', 'confirmed', array('boolean' => 'false'));
}
public function dismissVersionDialog() {
$this->user_options_model->set_option('version_dialog', 'confirmed', array('boolean' => 'true'));
}

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Manager';
$lang['general_word_qslcard_via'] = 'Чрез';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL Cards';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -79,6 +79,10 @@ $lang['general_word_qslcard_bureau'] = '卡片局';
$lang['general_word_qslcard_electronic'] = '电子卡片';
$lang['general_word_qslcard_manager'] = '卡片管理员';
$lang['general_word_qslcard_via'] = '通过via';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_eqslcard'] = '电子 QSL 卡片';
$lang['general_word_eqslcards'] = 'eQSL 卡片';
$lang['general_word_lotw'] = 'Logbook of the WorldLoTW';

Wyświetl plik

@ -17,6 +17,7 @@ $lang['menu_post_contest_logging'] = '比赛日志(手动)';
$lang['menu_bandmap'] = '波段地图';
$lang['menu_view_qsl'] = '浏览QSL卡片';
$lang['menu_view_eqsl'] = '浏览eQSL卡片';
$lang['menu_view_sstv'] = 'View SSTV Images';
$lang['menu_notes'] = '笔记';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Správce';
$lang['general_word_qslcard_via'] = 'Přes';
$lang['general_word_eqslcard'] = 'eQSL karta';
$lang['general_word_eqslcards'] = 'eQSL karty';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -17,6 +17,7 @@ $lang['menu_post_contest_logging'] = 'Uložit závodní log';
$lang['menu_bandmap'] = 'Bandmap';
$lang['menu_view_qsl'] = 'Zobrazit QSL';
$lang['menu_view_eqsl'] = 'Zobrazit eQSL';
$lang['menu_view_sstv'] = 'View SSTV Images';
$lang['menu_notes'] = 'Poznámky';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Manager';
$lang['general_word_qslcard_via'] = 'Via';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL Cards';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Manageri';
$lang['general_word_qslcard_via'] = 'Via';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL Cards';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -17,6 +17,7 @@ $lang['menu_post_contest_logging'] = 'Post Contest Logging';
$lang['menu_bandmap'] = 'Bandikartta';
$lang['menu_view_qsl'] = 'Näytä QSL';
$lang['menu_view_eqsl'] = 'Näytä eQSL';
$lang['menu_view_sstv'] = 'View SSTV Images';
$lang['menu_notes'] = 'Muistio';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = "Manager";
$lang['general_word_qslcard_via'] = "Via";
$lang['general_word_eqslcard'] = "Carte eQSL";
$lang['general_word_eqslcards'] = "Cartes eQSL";
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = "Logbook of the World";
$lang['general_word_lotw_short'] = "LoTW";

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Διευθυντής';
$lang['general_word_qslcard_via'] = 'Μέσω';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'Κάρτες eQSL';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Manager';
$lang['general_word_qslcard_via'] = 'Via';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'Cartoline eQSL';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Manager';
$lang['general_word_qslcard_via'] = 'Via';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL Cards';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -82,6 +82,10 @@ $lang['general_word_qslcard_manager'] = 'Менеджер';
$lang['general_word_qslcard_via'] = 'через';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -17,6 +17,7 @@ $lang['menu_post_contest_logging'] = 'Журнал прошедших сорев
$lang['menu_bandmap'] = 'План диапазонов';
$lang['menu_view_qsl'] = 'Просмотр QSL';
$lang['menu_view_eqsl'] = 'Просмотр eQSL';
$lang['menu_view_sstv'] = 'View SSTV Images';
$lang['menu_notes'] = 'Заметки';

Wyświetl plik

@ -82,6 +82,10 @@ $lang['general_word_qslcard_manager'] = 'Manager';
$lang['general_word_qslcard_via'] = 'Vía';
$lang['general_word_eqslcard'] = 'Tarjeta eQSL';
$lang['general_word_eqslcards'] = 'Tarjetas eQSL';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -17,6 +17,7 @@ $lang['menu_post_contest_logging'] = 'Registrar Entrada de Concurso';
$lang['menu_bandmap'] = 'mapa de Bandas';
$lang['menu_view_qsl'] = 'Ver Tarjetas QSL';
$lang['menu_view_eqsl'] = 'Ver Tarjetas eQSL';
$lang['menu_view_sstv'] = 'View SSTV Images';
$lang['menu_notes'] = 'Notas';

Wyświetl plik

@ -82,6 +82,10 @@ $lang['general_word_qslcard_manager'] = 'Manager';
$lang['general_word_qslcard_via'] = 'Via';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL Cards';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -17,6 +17,7 @@ $lang['menu_post_contest_logging'] = 'Post Tävlingsloggning';
$lang['menu_bandmap'] = 'Bandkarta';
$lang['menu_view_qsl'] = 'Se QSL';
$lang['menu_view_eqsl'] = 'Se eQSL';
$lang['menu_view_sstv'] = 'View SSTV Images';
$lang['menu_notes'] = 'Anteckningar';

Wyświetl plik

@ -81,6 +81,10 @@ $lang['general_word_qslcard_manager'] = 'Yönetici';
$lang['general_word_qslcard_via'] = 'üzerinden';
$lang['general_word_eqslcard'] = 'eQSL Card';
$lang['general_word_eqslcards'] = 'eQSL Kartları';
$lang['general_word_sstv_management'] = 'SSTV Management';
$lang['general_word_sstvimages'] = 'SSTV Images';
$lang['general_sstv_upload'] = 'Uploaded SSTV images';
$lang['general_sstv_upload_button'] = 'Upload SSTV image(s)';
$lang['general_word_lotw'] = 'Logbook of the World';
$lang['general_word_lotw_short'] = 'LoTW';

Wyświetl plik

@ -0,0 +1,30 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
* Tag Cloudlog as 2.6.9
*/
class Migration_tag_2_6_9 extends CI_Migration {
public function up()
{
// Tag Cloudlog 2.6.3
$this->db->where('option_name', 'version');
$this->db->update('options', array('option_value' => '2.6.9'));
// Trigger Version Info Dialog
$this->db->where('option_type', 'version_dialog');
$this->db->where('option_name', 'confirmed');
$this->db->update('user_options', array('option_value' => 'false'));
}
public function down()
{
$this->db->where('option_name', 'version');
$this->db->update('options', array('option_value' => '2.6.8'));
}
}

Wyświetl plik

@ -11,6 +11,12 @@
<input class="form-check-input" type="checkbox" name="via" id="via">
</div>
</div>
<div class="mb-3 row">
<label class="my-1 me-2 col-md-4" for="via">Include awards?</label>
<div class="form-check-inline">
<input class="form-check-input" type="checkbox" name="awards" id="awards">
</div>
</div>
<div class="mb-3 row">
<label class="my-1 me-2 col-md-4" for="startat">Start printing at?</label>
<div class="d-flex align-items-center">

Plik diff jest za duży Load Diff

11
cypress.config.js 100644
Wyświetl plik

@ -0,0 +1,11 @@
const { defineConfig } = require("cypress");
module.exports = defineConfig({
projectId: 'gm8wco',
e2e: {
baseUrl: "http://localhost/",
setupNodeEvents(on, config) {
// implement node event listeners here
},
},
});

Wyświetl plik

@ -0,0 +1,85 @@
describe("Login Test", () => {
it("Should log in successfully", () => {
// Define the username and password
const username = "m0abc";
const password = "demo";
// Visit the login page
cy.visit("/index.php/user/login");
// Type the username and password into the input fields
cy.get('input[name="user_name"]').type(username);
cy.get('input[name="user_password"]').type(password);
// Click the login button
cy.get('button[type="submit"]').click();
// Check if the login was successful
// This could be checking/ for a URL change, looking for a log out button, etc.
cy.url().should("include", "/dashboard");
cy.contains("Logout");
});
it("Should display an error message on failed login", () => {
// Define the username and password
const username = "m0abc";
const password = "wrongpassword";
// Visit the login page
cy.visit("/index.php/user/login");
// Type the username and password into the input fields
cy.get('input[name="user_name"]').type(username);
cy.get('input[name="user_password"]').type(password);
// Click the login button
cy.get('button[type="submit"]').click();
// Check if the login was successful
// This could be checking/ for a URL change, looking for a log out button, etc.
cy.url().should("include", "/login");
cy.get("body")
.contains("Incorrect username or password!")
.should("be.visible")
.and("have.class", "alert-danger");
});
it("Should display an error message on empty fields", () => {
// Visit the login page
cy.visit("/index.php/user/login");
// Click the login button
cy.get('button[type="submit"]').click();
// Check if the login was successful
// This could be checking/ for a URL change, looking for a log out button, etc.
cy.url().should("include", "/login");
cy.get("body")
.contains(`The "Username" field is required.`)
.should("be.visible")
.parent()
.and("have.class", "alert-danger");
cy.get("body")
.contains(`The "Password" field is required.`)
.should("be.visible")
.parent()
.and("have.class", "alert-danger");
});
it("Should display and open the forgot password page", () => {
// Visit the login page
cy.visit("/index.php/user/login");
// Click the "Forgot Password?" link
cy.get("a")
.contains("Forgot your password?")
.should("be.visible")
.click();
// Check if the correct page has been loaded by checking the URL
cy.url().should("include", "/forgot_password");
});
});

Wyświetl plik

@ -0,0 +1,62 @@
describe("Version Info Modal", () => {
beforeEach(() => {
cy.login();
});
it("should open after login", () => {
// Make sure the dialog is enabled
cy.request({
method: "POST",
url: "http://localhost/index.php/user_options/enableVersionDialog",
}).wait(1000);
cy.get(".modal-title").contains("Version Info").should("be.visible");
});
it("should close after clicking 'Close' button", () => {
// Make sure the dialog is enabled
cy.request({
method: "POST",
url: "http://localhost/index.php/user_options/enableVersionDialog",
}).wait(1000);
// check if the modal is visible
cy.get(".modal-title").contains("Version Info").should("be.visible");
// click the 'Close' button
cy.get("button")
.contains("Close")
.should("be.visible")
.wait(500)
.click();
// check if the modal is not visible
cy.get(".modal-title")
.contains("Version Info")
.should("not.be.visible");
});
it("should close after clicking 'Don't show again' button", () => {
// Make sure the dialog is enabled
cy.request({
method: "POST",
url: "http://localhost/index.php/user_options/enableVersionDialog",
}).wait(1000);
// check if the modal is visible
cy.get(".modal-title").contains("Version Info").should("be.visible");
// click the "Don't show again" button
cy.get("button")
.contains("Don't show again")
.should("be.visible")
.wait(500)
.click();
// check if the modal is not visible
cy.get(".modal-title")
.contains("Version Info")
.should("not.be.visible");
});
it("should not show the version info dialog after click 'Dont show again' button", () => {
// check if the modal is not visible
cy.get(".modal-title").should("not.exist");
});
});

Wyświetl plik

@ -0,0 +1,91 @@
// Test suite for new account alerts within the application
describe("New account alerts", () => {
// Before each test, perform login operation. Assumes cy.login() is a custom command.
beforeEach(() => {
cy.login();
});
// Alert messages expected to be seen by brand new accounts
const locationsAlertMessage =
"You have no station locations. Go here to create it!";
const logbookAlertMessage =
"You have no station logbook. Go here to create it!";
const activeStationAlertMessage =
"Attention: you need to set an active station location.";
const noQSOAlertMessage =
"You have made no QSOs today; time to turn on the radio!";
// Test to verify the locations alert message and its link
it(`should show a "${locationsAlertMessage}" alert with a valid link to create it`, () => {
// Verify alert visibility and class for urgency
cy.get("body")
.contains(locationsAlertMessage)
.should("be.visible")
.and("have.class", "alert-danger");
// Validate the hyperlink's destination within the alert
cy.contains(locationsAlertMessage).within(() => {
cy.get("a")
.contains("here")
.should("have.attr", "href")
.and("equal", "http://localhost/index.php/station");
});
});
// Test navigation to the station creation page via the alert link
it("should navigate to the station creation page after clicking the link in the alert", () => {
// Trigger click on the link within the alert message
cy.contains(locationsAlertMessage).within(() => {
cy.get("a").contains("here").click();
});
// Assert the correct page has been loaded by checking the URL
cy.url().should("include", "/station");
});
// Test to verify the logbook alert message and its link
it(`should show a "${logbookAlertMessage}" alert with a valid link to create it`, () => {
// Verify alert visibility and class for urgency
cy.get("body")
.contains(logbookAlertMessage)
.should("be.visible")
.and("have.class", "alert-danger");
// Validate the hyperlink's destination within the alert
cy.contains(logbookAlertMessage).within(() => {
cy.get("a")
.contains("here")
.should("have.attr", "href")
.and("equal", "http://localhost/index.php/logbooks");
});
});
// Test navigation to the logbook creation page via the alert link
it("should navigate to the logbook creation page after clicking the link in the alert", () => {
// Trigger click on the link within the alert message
cy.contains(logbookAlertMessage).within(() => {
cy.get("a").contains("here").click();
});
// Assert the correct page has been loaded by checking the URL
cy.url().should("include", "/logbooks");
});
// Test to verify the active station alert is properly displayed
it(`should display an "${activeStationAlertMessage}" alert`, () => {
// Verify alert visibility and class for urgency
cy.get("body")
.contains(activeStationAlertMessage)
.should("be.visible")
.and("have.class", "alert-danger");
});
// Test to verify the no QSO alert is properly displayed
it(`should display a "${noQSOAlertMessage}" alert`, () => {
// Verify alert visibility and class for importance
cy.get("body")
.contains(noQSOAlertMessage)
.should("be.visible")
.and("have.class", "alert-warning");
});
});

Wyświetl plik

@ -0,0 +1,69 @@
describe("Create station location", () => {
beforeEach(() => {
cy.login();
});
it("should load an empty list of station locations", () => {
cy.visit("/index.php/station");
// Check that the table is not present
cy.get("#station_locations_table").should("not.exist");
});
it("should have a button to create a new station location", () => {
cy.visit("/index.php/station");
// Check that the button is present
cy.get("a")
.contains("Create a Station Location")
.should("exist")
.click();
cy.url().should("include", "/station/create");
});
it("should create a new station location", () => {
cy.visit("/index.php/station/create");
// Define the station location name
const stationLocationName = "Test Station Location";
const stationCallsign = "2M0SQL";
const stationPower = "100";
const stationDXCC = "United States Of America - K";
const stationCity = "Olathe";
const stationState = "Kansas";
const stationCounty = "Johnson";
const stationGridsquare = "EM28";
const stationCQ = "4";
const stationITU = "7";
// Type the station location name into the input field
cy.get('input[name="station_profile_name"]').type(stationLocationName);
cy.get('input[name="station_callsign"]').type(stationCallsign);
cy.get('input[name="station_power"]').type(stationPower);
cy.get('select[name="dxcc"]').select(stationDXCC);
cy.get('input[name="city"]').type(stationCity);
cy.get('select[name="station_state"]').select(stationState);
cy.get("#stationCntyInput-selectized")
.type(stationCounty, { force: true }) // force typing if the element isn't initially visible
.get(".selectize-dropdown-content > div") // get the dropdown content
.contains(stationCounty) // find the option containing the county name
.click(); // click to select the option
cy.get('input[name="gridsquare"]').type(stationGridsquare);
cy.get('select[name="station_cq"]').select(stationCQ);
cy.get('select[name="station_itu"]').select(stationITU);
// Click the save button
cy.get('button[type="submit"]')
.contains("Create Station Location")
.click();
// Check if the station location was created successfully
cy.url().should("include", "/station");
// // Check if the station location is present in the table
cy.get("#station_locations_table")
.contains(stationLocationName)
.should("exist");
});
});

Wyświetl plik

@ -0,0 +1,83 @@
describe("Create station logbook", () => {
beforeEach(() => {
cy.login();
});
it("should load an empty list of station locations", () => {
// Navigate to the logbooks page
cy.visit("/index.php/logbooks");
// Check that the table is not present
cy.get("#station_logbooks_table").should("not.exist");
});
it("should have a button to create a new station location", () => {
// Navigate to the logbooks page
cy.visit("/index.php/logbooks");
// Check that the button is present
cy.get("a").contains("Create Station Logbook").should("exist").click();
cy.url().should("include", "/logbooks/create");
});
it("should create a new station location", () => {
// Navigate to the create logbook page
cy.visit("/index.php/logbooks/create");
// Define the station location name
const stationLogbookName = "Home QTH";
// Type the station location name into the input field
cy.get('input[name="stationLogbook_Name"]').type(stationLogbookName);
// Click the save button
cy.get('button[type="submit"]')
.contains("Create Station Logbook")
.click();
// Check if the station location was created successfully
cy.url().should("include", "/logbooks");
// // Check if the station location is present in the table
cy.get("#station_logbooks_table")
.contains(stationLogbookName)
.should("exist");
});
// it("should set as active station logbook when button clicked", () => {
// // Navigate to the logbooks page
// cy.visit("/index.php/logbooks");
// // Check that the button is present
// cy.get("a").contains("Set as Active Logbook").should("exist").click();
// // Check if the station was set to active
// cy.get("body")
// .contains("Active Logbook")
// .should("be.visible")
// .and("have.class", "badge text-bg-success");
// });
// it("should link to a station location from the edit logbook page", () => {
// // Navigate to the logbooks page
// cy.visit("/index.php/logbooks");
// // Click the edit button
// cy.get("i.fas.fa-edit").should("exist").click();
// // Ensure that the edit link navigates to the correct page
// cy.url().should("include", "/logbooks/edit");
// // Scroll to the bottom of the page
// cy.scrollTo("bottom");
// // Click the link location button
// cy.get("button").contains("Link Location").should("exist").click();
// // Make sure that our table now shows the linked station location
// cy.get("#station_logbooks_linked_table")
// .contains("Test Station Location")
// .should("exist");
// });
});

Wyświetl plik

@ -0,0 +1,8 @@
Cypress.Commands.add("login", () => {
const username = "m0abc";
const password = "demo";
cy.visit("/index.php/user/login");
cy.get('input[name="user_name"]').type(username);
cy.get('input[name="user_password"]').type(password);
cy.get('button[type="submit"]').click();
});

Wyświetl plik

@ -0,0 +1,20 @@
// ***********************************************************
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

25
docker-compose.yml 100644
Wyświetl plik

@ -0,0 +1,25 @@
version: "3.8"
services:
web:
build: .
env_file:
- .env
ports:
- "80:80"
volumes:
- ./:/var/www/html:rw
command: ["./script.sh"]
depends_on:
- db
db:
build:
context: .
dockerfile: Dockerfile-db
env_file:
- .env
volumes:
- db_data:/var/lib/mysql
volumes:
db_data: {}

Wyświetl plik

@ -148,10 +148,10 @@ if($_POST) {
<fieldset>
<legend>Database settings</legend>
<label for="hostname">Hostname</label><input type="text" id="hostname" value="localhost" class="input_text" name="hostname" />
<label for="username">Username</label><input type="text" id="username" class="input_text" name="username" />
<label for="password">Password</label><input type="password" id="password" class="input_text" name="password" />
<label for="database">Database Name</label><input type="text" id="database" class="input_text" name="database" />
<label for="hostname">Hostname</label><input type="text" id="hostname" value="<?php echo getenv('MYSQL_HOST') ?: 'localhost'; ?>" class="input_text" name="hostname" />
<label for="username">Username</label><input type="text" id="username" value="<?php echo getenv('MYSQL_USER'); ?>" class="input_text" name="username" />
<label for="password">Password</label><input type="password" id="password" value="<?php echo getenv('MYSQL_PASSWORD'); ?>" class="input_text" name="password" />
<label for="database">Database Name</label><input type="text" id="database" value="<?php echo getenv('MYSQL_DATABASE'); ?>" class="input_text" name="database" />
<input type="submit" value="Install" id="submit" />
</fieldset>
</form>

1981
package-lock.json wygenerowano 100644

Plik diff jest za duży Load Diff

15
package.json 100644
Wyświetl plik

@ -0,0 +1,15 @@
{
"name": "cloudlog",
"version": "1.0.0",
"description": "> Important: Only accepting PRs on the \"dev\" branch.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"cypress": "^13.7.2"
}
}

102
script.sh 100755
Wyświetl plik

@ -0,0 +1,102 @@
#!/bin/bash
# Define the file path for .env and the file to modify
if [ -f "./.env" ]; then
ENV_FILE="./.env"
else
ENV_FILE="./.env.sample"
fi
CONFIG_FILE="install/config/config.php"
DATABASE_FILE="install/config/database.php"
DEST_DIR="application/config"
# Check if .env file exists
if [ ! -f "$ENV_FILE" ]; then
echo ".env file not found!"
exit 1
fi
# Read the .env file
source $ENV_FILE
# Check if MYSQL_DATABASE is set
if [ -z "${MYSQL_DATABASE}" ]; then
echo "MYSQL_DATABASE is not set in .env file!"
exit 1
fi
# Check if MYSQL_USER is set
if [ -z "${MYSQL_USER}" ]; then
echo "MYSQL_USER is not set in .env file!"
exit 1
fi
# Check if MYSQL_PASSWORD is set
if [ -z "${MYSQL_PASSWORD}" ]; then
echo "MYSQL_PASSWORD is not set in .env file!"
exit 1
fi
# Check if MYSQL_HOST is set
if [ -z "${MYSQL_HOST}" ]; then
echo "MYSQL_HOST is not set in .env file!"
exit 1
fi
# Check if BASE_LOCATOR is set
if [ -z "${BASE_LOCATOR}" ]; then
echo "BASE_LOCATOR is not set in .env file!"
exit 1
fi
# Check if WEBSITE_URL is set
if [ -z "${WEBSITE_URL}" ]; then
echo "WEBSITE_URL is not set in .env file!"
exit 1
fi
# Check if DIRECTORY is set
if [ -z "${DIRECTORY}" ]; then
echo "DIRECTORY is not set in .env file!"
exit 1
fi
# Check if destination directory exists, if not create it
if [ ! -d "$DEST_DIR" ]; then
mkdir -p $DEST_DIR
fi
# Use sed with a different delimiter (`|`) to avoid conflicts with special characters
sed -i "s|%DATABASE%|${MYSQL_DATABASE}|g" $DATABASE_FILE
sed -i "s|%USERNAME%|${MYSQL_USER}|g" $DATABASE_FILE
sed -i "s|%PASSWORD%|${MYSQL_PASSWORD}|g" $DATABASE_FILE
sed -i "s|%HOSTNAME%|${MYSQL_HOST}|g" $DATABASE_FILE
sed -i "s|%baselocator%|${BASE_LOCATOR}|g" $CONFIG_FILE
sed -i "s|%websiteurl%|${WEBSITE_URL}|g" $CONFIG_FILE
sed -i "s|%directory%|${DIRECTORY}|g" $CONFIG_FILE
# Move the files to the destination directory
mv $CONFIG_FILE $DEST_DIR
mv $DATABASE_FILE $DEST_DIR
# Delete the /install directory
rm -rf /install
echo "Replacement complete."
# Set Permissions
chown -R root:www-data /var/www/html/application/config/
chown -R root:www-data /var/www/html/application/logs/
chown -R root:www-data /var/www/html/assets/qslcard/
chown -R root:www-data /var/www/html/backup/
chown -R root:www-data /var/www/html/updates/
chown -R root:www-data /var/www/html/uploads/
chown -R root:www-data /var/www/html/images/eqsl_card_images/
chown -R root:www-data /var/www/html/assets/json
chmod -R g+rw /var/www/html/application/config/
chmod -R g+rw /var/www/html/application/logs/
chmod -R g+rw /var/www/html/assets/qslcard/
chmod -R g+rw /var/www/html/backup/
chmod -R g+rw /var/www/html/updates/
chmod -R g+rw /var/www/html/uploads/
chmod -R g+rw /var/www/html/images/eqsl_card_images/
chmod -R g+rw /var/www/html/assets/json
# Start Apache in the foreground
exec apache2-foreground