Have the initial pull download working. More work to do on parsing the resulting .adi file and cleaning up the model.
这个提交包含在:
父节点
07e2d5c6d7
当前提交
d90facf293
共有 4 个文件被更改,包括 368 次插入 和 0 次删除
295
application/controllers/eqsl.php
普通文件
295
application/controllers/eqsl.php
普通文件
|
|
@ -0,0 +1,295 @@
|
|||
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class eqsl extends CI_Controller {
|
||||
|
||||
/* Controls who can access the controller and its functions */
|
||||
function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->load->helper(array('form', 'url'));
|
||||
|
||||
$this->load->model('user_model');
|
||||
if(!$this->user_model->authorize(2)) { $this->session->set_flashdata('notice', 'You\'re not allowed to do that!'); redirect('dashboard'); }
|
||||
}
|
||||
|
||||
private function loadFromFile($filepath)
|
||||
{
|
||||
// Figure out how we should be marking QSLs confirmed via eQSL
|
||||
$query = $query = $this->db->query('SELECT eqsl_rcvd_mark FROM config');
|
||||
$q = $query->row();
|
||||
$config['eqsl_rcvd_mark'] = $q->eqsl_rcvd_mark;
|
||||
|
||||
ini_set('memory_limit', '-1');
|
||||
set_time_limit(0);
|
||||
|
||||
$this->load->library('adif_parser');
|
||||
|
||||
$this->adif_parser->load_from_file($filepath);
|
||||
|
||||
$this->adif_parser->initialize();
|
||||
|
||||
$table = "<table>";
|
||||
|
||||
while($record = $this->adif_parser->get_record())
|
||||
{
|
||||
if(count($record) == 0)
|
||||
{
|
||||
break;
|
||||
};
|
||||
|
||||
$time_on = date('Y-m-d', strtotime($record['qso_date'])) ." ".date('H:i', strtotime($record['time_on']));
|
||||
|
||||
$qsl_date = date('Y-m-d', strtotime($record['qslrdate'])) ." ".date('H:i', strtotime($record['qslrdate']));
|
||||
|
||||
if (isset($record['time_off'])) {
|
||||
$time_off = date('Y-m-d', strtotime($record['qso_date'])) ." ".date('H:i', strtotime($record['time_off']));
|
||||
} else {
|
||||
$time_off = date('Y-m-d', strtotime($record['qso_date'])) ." ".date('H:i', strtotime($record['time_on']));
|
||||
}
|
||||
|
||||
// The report from eQSL should only contain entries that have been confirmed via eQSL
|
||||
// If there's a match for the QSO from the report in our log, it's confirmed via eQSL.
|
||||
|
||||
// If we have a positive match from LoTW, record it in the DB according to the user's preferences
|
||||
if ($record['qsl_sent'] == "Y")
|
||||
{
|
||||
$record['qsl_sent'] = $config['lotw_rcvd_mark'];
|
||||
}
|
||||
|
||||
$status = $this->logbook_model->import_check($time_on, $record['call'], $record['band']);
|
||||
//////////////////////////////////////////////
|
||||
$eqsl_status = $this->logbook_model->eqsl_update($time_on, $record['call'], $record['band'], $record['qsl_rcvd']);
|
||||
|
||||
$table .= "<tr>";
|
||||
$table .= "<td>".$time_on."</td>";
|
||||
$table .= "<td>".$record['call']."</td>";
|
||||
$table .= "<td>".$record['mode']."</td>";
|
||||
$table .= "<td>".$record['qsl_rcvd']."</td>";
|
||||
$table .= "<td>".$qsl_date."</td>";
|
||||
$table .= "<td>QSO Record: ".$status."</td>";
|
||||
$table .= "<td>eQSL Record: ".$lotw_status."</td>";
|
||||
$table .= "<tr>";
|
||||
};
|
||||
|
||||
$table .= "</table>";
|
||||
|
||||
unlink($filepath);
|
||||
|
||||
$data['lotw_table'] = $table;
|
||||
|
||||
$data['page_title'] = "eQSL ADIF Information";
|
||||
$this->load->view('layout/header', $data);
|
||||
$this->load->view('eqsl/analysis');
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
|
||||
public function import() {
|
||||
$data['page_title'] = "eQSL Import";
|
||||
|
||||
$config['upload_path'] = './uploads/';
|
||||
$config['allowed_types'] = 'adi|ADI';
|
||||
|
||||
$this->load->library('upload', $config);
|
||||
|
||||
$this->load->model('logbook_model');
|
||||
|
||||
if ($this->input->post('eqslimport') == 'fetch')
|
||||
{
|
||||
$file = $config['upload_path'] . 'eqslreport_download.adi';
|
||||
|
||||
// Get credentials for LoTW
|
||||
$query = $this->user_model->get_by_id($this->session->userdata('user_id'));
|
||||
$q = $query->row();
|
||||
$data['user_eqsl_name'] = $q->user_eqsl_name;
|
||||
$data['user_eqsl_password'] = $q->user_eqsl_password;
|
||||
|
||||
// Get URL for downloading the eqsl.cc inbox
|
||||
$query = $query = $this->db->query('SELECT eqsl_download_url FROM config');
|
||||
$q = $query->row();
|
||||
$eqsl_url = $q->eqsl_download_url;
|
||||
|
||||
// Validate that LoTW credentials are not empty
|
||||
if ($data['user_eqsl_name'] == '' || $data['user_eqsl_password'] == '')
|
||||
{
|
||||
$this->session->set_flashdata('warning', 'You have not defined your eQSL.cc credentials!'); redirect('eqsl/import');
|
||||
}
|
||||
|
||||
// Query the logbook to determine when the last LoTW confirmation was
|
||||
$eqsl_last_qsl_date = $this->logbook_model->eqsl_last_qsl_rcvd_date();
|
||||
|
||||
// Build URL for eQSL inbox file
|
||||
$eqsl_url .= "?";
|
||||
$eqsl_url .= "UserName=" . $data['user_eqsl_name'];
|
||||
$eqsl_url .= "&Password=" . $data['user_eqsl_password'];
|
||||
|
||||
$eqsl_url .= "&RcvdSince=" . $eqsl_last_qsl_date;
|
||||
|
||||
// Pull back only confirmations
|
||||
$eqsl_url .= "&ConfirmedOnly=1";
|
||||
|
||||
// At this point, what we get isn't the ADI file we need, but rather
|
||||
// an HTML page, which contains a link to the generated ADI file that we want.
|
||||
// Adapted from Original PHP code by Chirp Internet: www.chirp.com.au
|
||||
|
||||
$input = @file_get_contents($eqsl_url) or die("Could not access file: $eqsl_url");
|
||||
$regexp = "<a\s[^>]*href=(\"??)([^\" >]*?)\\1[^>]*>(.*)<\/a>";
|
||||
if(preg_match_all("/$regexp/siU", $input, $matches)) {
|
||||
foreach( $matches[2] as $match )
|
||||
{
|
||||
// Look for the link that has the .adi file, and download it to $file
|
||||
if (substr($match, -4, 4) == ".adi")
|
||||
{
|
||||
file_put_contents($file, file_get_contents("http://eqsl.cc/qslcard/" . $match));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ini_set('memory_limit', '-1');
|
||||
//$this->loadFromFile($file);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ! $this->upload->do_upload())
|
||||
{
|
||||
|
||||
$data['error'] = $this->upload->display_errors();
|
||||
|
||||
$this->load->view('layout/header', $data);
|
||||
$this->load->view('eqsl/import');
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = array('upload_data' => $this->upload->data());
|
||||
|
||||
$this->loadFromFile('./uploads/'.$data['upload_data']['file_name']);
|
||||
}
|
||||
}
|
||||
} // end function
|
||||
|
||||
public function export() {
|
||||
$data['page_title'] = "eQSL Report Upload";
|
||||
|
||||
$config['upload_path'] = './uploads/';
|
||||
$config['allowed_types'] = 'tq8|TQ8';
|
||||
|
||||
$this->load->library('upload', $config);
|
||||
|
||||
if ( ! $this->upload->do_upload())
|
||||
{
|
||||
$data['error'] = $this->upload->display_errors();
|
||||
|
||||
$this->load->view('layout/header', $data);
|
||||
$this->load->view('eqsl/export');
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
else
|
||||
{
|
||||
$data = array('upload_data' => $this->upload->data());
|
||||
|
||||
// Figure out how we should be marking QSLs confirmed via LoTW
|
||||
$query = $query = $this->db->query('SELECT lotw_login_url FROM config');
|
||||
$q = $query->row();
|
||||
$config['lotw_login_url'] = $q->lotw_login_url;
|
||||
|
||||
// Set some fields that we're going to need for ARRL login
|
||||
$query = $this->user_model->get_by_id($this->session->userdata('user_id'));
|
||||
$q = $query->row();
|
||||
$fields['login'] = $q->user_lotw_name;
|
||||
$fields['password'] = $q->user_lotw_password;
|
||||
$fields['acct_sel'] = "";
|
||||
|
||||
if ($fields['login'] == '' || $fields['password'] == '')
|
||||
{
|
||||
$this->session->set_flashdata('warning', 'You have not defined your ARRL LoTW credentials!'); redirect('lotw/status');
|
||||
}
|
||||
|
||||
// Curl stuff goes here
|
||||
|
||||
// First we need to get a cookie
|
||||
|
||||
// options
|
||||
$cookie_file_path = "./uploads/cookies.txt";
|
||||
$agent = "Mozilla/4.0 (compatible;)";
|
||||
|
||||
// begin script
|
||||
$ch = curl_init();
|
||||
|
||||
// extra headers
|
||||
$headers[] = "Accept: */*";
|
||||
$headers[] = "Connection: Keep-Alive";
|
||||
|
||||
// basic curl options for all requests
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
|
||||
// TODO: These SSL things should probably be set to true :)
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
|
||||
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file_path);
|
||||
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file_path);
|
||||
|
||||
// Set login URL
|
||||
curl_setopt($ch, CURLOPT_URL, $config['lotw_login_url']);
|
||||
|
||||
// set postfields using what we extracted from the form
|
||||
$POSTFIELDS = http_build_query($fields);
|
||||
|
||||
// set post options
|
||||
curl_setopt($ch, CURLOPT_POST, 1);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS);
|
||||
|
||||
// perform login
|
||||
$result = curl_exec($ch);
|
||||
if (stristr($result, "Username/password incorrect"))
|
||||
{
|
||||
$this->session->set_flashdata('warning', 'Your ARRL username and/or password is incorrect.'); redirect('lotw/status');
|
||||
}
|
||||
|
||||
|
||||
// Now we need to use that cookie and upload the file
|
||||
// change URL to upload destination URL
|
||||
curl_setopt($ch, CURLOPT_URL, $config['lotw_login_url']);
|
||||
|
||||
// Grab the file
|
||||
$postfile = array(
|
||||
"upfile"=>"@./uploads/".$data['upload_data']['file_name'],
|
||||
);
|
||||
|
||||
//Upload it
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfile);
|
||||
$response = curl_exec($ch);
|
||||
if (stristr($response, "accepted"))
|
||||
{
|
||||
$this->session->set_flashdata('lotw_status', 'accepted');
|
||||
$data['page_title'] = "eQSL Logs Sent";
|
||||
}
|
||||
elseif (stristr($response, "rejected"))
|
||||
{
|
||||
$this->session->set_flashdata('lotw_status', 'rejected');
|
||||
$data['page_title'] = "LoTW .TQ8 Sent";
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're here, we didn't find what we're looking for in the ARRL response
|
||||
// and LoTW is probably down or broken.
|
||||
$this->session->set_flashdata('warning', 'Did not receive proper response from LoTW. Try again later.');
|
||||
$data['page_title'] = "LoTW .TQ8 Not Sent";
|
||||
}
|
||||
|
||||
// Now we need to clean up
|
||||
unlink($cookie_file_path);
|
||||
unlink('./uploads/'.$data['upload_data']['file_name']);
|
||||
|
||||
$this->load->view('layout/header', $data);
|
||||
$this->load->view('eqsl/status');
|
||||
$this->load->view('layout/footer');
|
||||
}
|
||||
}
|
||||
|
||||
} // end class
|
||||
|
|
@ -599,6 +599,51 @@ class Logbook_model extends CI_Model {
|
|||
return $row->COL_LOTW_QSLRDATE;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Update a QSO with eQSL QSL info
|
||||
// We could also probably use this use this: http://eqsl.cc/qslcard/VerifyQSO.txt
|
||||
// http://www.eqsl.cc/qslcard/ImportADIF.txt
|
||||
function eqsl_update($datetime, $callsign, $band, $qsl_status) {
|
||||
$data = array(
|
||||
'COL_EQSL_QSLRDATE' => CURRENT_TIMESTAMP, // eQSL doesn't give us a date, so let's use current
|
||||
'COL_EQSL_QSL_RCVD' => $qsl_status,
|
||||
);
|
||||
|
||||
$this->db->where('date_format(COL_TIME_ON, \'%Y-%m-%d %H:%i\') = "'.$datetime.'"');
|
||||
$this->db->where('COL_CALL', $callsign);
|
||||
$this->db->where('COL_BAND', $band);
|
||||
|
||||
$this->db->update($this->config->item('table_name'), $data);
|
||||
|
||||
return "Updated";
|
||||
}
|
||||
|
||||
// Get the last date we received an eQSL
|
||||
function eqsl_last_qsl_rcvd_date() {
|
||||
$this->db->select("DATE_FORMAT(COL_EQSL_QSLRDATE,'%Y%m%d') AS COL_EQSL_QSLRDATE", FALSE);
|
||||
$this->db->where('COL_EQSL_QSLRDATE IS NOT NULL');
|
||||
$this->db->order_by("COL_EQSL_QSLRDATE", "desc");
|
||||
$this->db->limit(1);
|
||||
|
||||
$query = $this->db->get($this->config->item('table_name'));
|
||||
$row = $query->row();
|
||||
|
||||
return $row->COL_EQSL_QSLRDATE;
|
||||
}
|
||||
|
||||
// Determine if we've already received an eQSL for this QSO.. this needs writing.
|
||||
function eqsl_dupe_check($datetime, $callsign, $band, $qsl_status) {
|
||||
$this->db->select('COL_LOTW_QSLRDATE');
|
||||
$this->db->where('COL_LOTW_QSLRDATE IS NOT NULL');
|
||||
$this->db->order_by("COL_LOTW_QSLRDATE", "desc");
|
||||
$this->db->limit(1);
|
||||
|
||||
$query = $this->db->get($this->config->item('table_name'));
|
||||
$row = $query->row();
|
||||
|
||||
return $row->COL_LOTW_QSLRDATE;
|
||||
}
|
||||
|
||||
function import($record) {
|
||||
// Join date+time
|
||||
//$datetime = date('Y-m-d') ." ". $this->input->post('start_time');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
<div id="container">
|
||||
<h2><?php echo $page_title; ?></h2>
|
||||
<?php $this->load->view('layout/messages'); ?>
|
||||
|
||||
<?php echo form_open_multipart('eqsl/import');?>
|
||||
<table>
|
||||
<tr>
|
||||
<td><input type="radio" name="eqslimport" id="upload" value="upload" checked /> Upload a file</td>
|
||||
<td>
|
||||
<p>Upload the Exported ADIF file from eQSL from the <a href="http://eqsl.cc/qslcard/DownloadInBox.cfm" target="_blank">Download Inbox</a> page, to mark QSOs as confirmed on eQSL.</p>
|
||||
<p><span class="label important">Important</span> Log files must have the file type .adi</p>
|
||||
<input type="file" name="userfile" size="20" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="radio" name="eqslimport" id="fetch" value="fetch" /> Pull eQSL data for me</td>
|
||||
<td>
|
||||
<p>Cloudlog will use the eQSL username an password stored in your user profile to download confirmations from eQSL for you. We will only download confirmations received since your last eQSL confirmed QSO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input class="btn primary" type="submit" value="Import" />
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
|
@ -87,9 +87,11 @@
|
|||
<!-- <li><a href="<?php echo site_url('adif/export');?>" title="ADIF Export">ADIF Export</a></li> -->
|
||||
<li><a href="<?php echo site_url('export');?>" title="Data Export">Data Export</a></li>
|
||||
<li><a href="<?php echo site_url('api/help');?>" title="API">API</a></li>
|
||||
<li><a href="<?php echo site_url('eqsl/import');?>" title="eQSL Import">eQSL Import</a></li>
|
||||
<li><a href="<?php echo site_url('lotw/import');?>" title="LoTW Import">LoTW Import</a></li>
|
||||
<li><a href="<?php echo site_url('lotw/export');?>" title="LoTW Export">LoTW Export</a></li>
|
||||
</ul>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
正在加载…
在新工单中引用