2#include "opsastrometryindexfiles.h"
8#include "ksnotification.h"
10#include <KConfigDialog>
13#include <QDesktopServices>
17OpsAstrometryIndexFiles::OpsAstrometryIndexFiles(Align *parent) :
QDialog(
KStars::Instance())
22 actualdownloadSpeed = downloadSpeed;
26 indexURL->setText(
"http://broiler.astrometry.net/~dstn/");
30 connect(openIndexFileDirectory, SIGNAL(clicked()),
this, SLOT(slotOpenIndexFileDirectory()));
37 astrometryIndex[2.8] =
"00";
38 astrometryIndex[4.0] =
"01";
39 astrometryIndex[5.6] =
"02";
40 astrometryIndex[8] =
"03";
41 astrometryIndex[11] =
"04";
42 astrometryIndex[16] =
"05";
43 astrometryIndex[22] =
"06";
44 astrometryIndex[30] =
"07";
45 astrometryIndex[42] =
"08";
46 astrometryIndex[60] =
"09";
47 astrometryIndex[85] =
"10";
48 astrometryIndex[120] =
"11";
49 astrometryIndex[170] =
"12";
50 astrometryIndex[240] =
"13";
51 astrometryIndex[340] =
"14";
52 astrometryIndex[480] =
"15";
53 astrometryIndex[680] =
"16";
54 astrometryIndex[1000] =
"17";
55 astrometryIndex[1400] =
"18";
56 astrometryIndex[2000] =
"19";
61 &OpsAstrometryIndexFiles::slotUpdate);
63 for (
auto &checkBox : checkboxes)
72 for (
auto &bar : progressBars)
74 if(bar->objectName().contains(
"progress"))
76 bar->setVisible(
false);
77 bar->setTextVisible(
false);
81 for (
auto &button : qButtons)
83 if(button->objectName().contains(
"cancel"))
85 button->setVisible(
false);
89 for (
QLabel * label : qLabels)
93 label->setVisible(
false);
105 addDirectoryToList(dir);
109 if(indexLocations->currentIndex() != 0)
110 removeDirectoryFromList(indexLocations->currentText());
116void OpsAstrometryIndexFiles::showEvent(
QShowEvent *)
118 updateIndexDirectoryList();
122void OpsAstrometryIndexFiles::updateIndexDirectoryList()
126 QStringList astrometryDataDirs = KSUtils::getAstrometryDataDirs();
128 indexLocations->clear();
129 if(astrometryDataDirs.
count() > 1)
130 indexLocations->addItem(
"All Sources");
131 indexLocations->addItems(astrometryDataDirs);
135void OpsAstrometryIndexFiles::addDirectoryToList(
QString directory)
142 QStringList indexFileDirs = Options::astrometryIndexFolderList();
143 if(indexFileDirs.
contains(directoryPath))
145 indexFileDirs.
append(directoryPath);
146 Options::setAstrometryIndexFolderList(indexFileDirs);
147 updateIndexDirectoryList();
150void OpsAstrometryIndexFiles::removeDirectoryFromList(
QString directory)
152 QStringList indexFileDirs = Options::astrometryIndexFolderList();
153 if(indexFileDirs.
contains(directory))
156 Options::setAstrometryIndexFolderList(indexFileDirs);
157 updateIndexDirectoryList();
161void OpsAstrometryIndexFiles::slotUpdate()
165 for (
auto &checkBox : checkboxes)
167 checkBox->setChecked(
false);
170 if(indexLocations->count() == 0)
173 double fov_w, fov_h, fov_pixscale;
176 alignModule->getFOVScale(fov_w, fov_h, fov_pixscale);
178 double fov_check = qMax(fov_w, fov_h);
184 QStringList astrometryDataDirs = Options::astrometryIndexFolderList();
186 bool allDirsSelected = (indexLocations->currentIndex() == 0 && astrometryDataDirs.
count() > 1);
187 bool folderIsWriteable;
193 folderDetails->setText(
i18n(
"Downloads Disabled, this is not a directory, it is a list of all index files."));
194 folderIsWriteable =
false;
195 astrometryDataDirsToIndex = astrometryDataDirs;
196 openIndexFileDirectory->setEnabled(
false);
200 QString folderPath = indexLocations->currentText();
202 if(folderIsWriteable)
203 folderDetails->setText(
i18n(
"Downloads Enabled, the directory exists and is writeable."));
205 folderDetails->setText(
i18n(
"Downloads Disabled, directory permissions issue."));
207 folderDetails->setText(
i18n(
"Downloads Disabled, directory does not exist."));
208 astrometryDataDirsToIndex << folderPath;
209 openIndexFileDirectory->setEnabled(
true);
211 folderDetails->setCursorPosition(0);
215 for(
auto &astrometryDataDir : astrometryDataDirsToIndex)
217 QDir directory(astrometryDataDir);
218 QStringList indexList = directory.entryList(nameFilter);
220 for (
auto &indexName : indexList)
222 if (fileCountMatches(directory, indexName))
224 indexName = indexName.replace(
'-',
'_').left(10);
225 QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
232 for (
auto &checkBox : checkboxes)
234 checkBox->setEnabled(folderIsWriteable);
235 checkBox->setIcon(
QIcon(
":/icons/astrometry-optional.svg"));
236 checkBox->setToolTip(
i18n(
"Optional"));
237 checkBox->setStyleSheet(
"");
240 float last_skymarksize = 2;
242 for (
auto &skymarksize : astrometryIndex.keys())
244 QString indexName1 =
"index_41" + astrometryIndex.value(skymarksize);
245 QString indexName2 =
"index_42" + astrometryIndex.value(skymarksize);
246 QString indexName3 =
"index_52" + astrometryIndex.value(skymarksize);
247 QCheckBox *indexCheckBox1 = findChild<QCheckBox *>(indexName1);
248 QCheckBox *indexCheckBox2 = findChild<QCheckBox *>(indexName2);
249 QCheckBox *indexCheckBox3 = findChild<QCheckBox *>(indexName3);
250 if ((skymarksize >= 0.40 * fov_check && skymarksize <= 0.9 * fov_check) ||
251 (fov_check > last_skymarksize && fov_check < skymarksize))
255 indexCheckBox1->
setIcon(
QIcon(
":/icons/astrometry-required.svg"));
260 indexCheckBox2->
setIcon(
QIcon(
":/icons/astrometry-required.svg"));
265 indexCheckBox3->
setIcon(
QIcon(
":/icons/astrometry-required.svg"));
269 else if (skymarksize >= 0.10 * fov_check && skymarksize <= fov_check)
273 indexCheckBox1->
setIcon(
QIcon(
":/icons/astrometry-recommended.svg"));
278 indexCheckBox2->
setIcon(
QIcon(
":/icons/astrometry-recommended.svg"));
283 indexCheckBox3->
setIcon(
QIcon(
":/icons/astrometry-recommended.svg"));
288 last_skymarksize = skymarksize;
294 for(
QString astrometryDataDir : astrometryDataDirs)
296 QDir directory(astrometryDataDir);
297 QStringList indexList = directory.entryList(nameFilter);
299 for (
auto &indexName : indexList)
301 if (fileCountMatches(directory, indexName))
303 indexName = indexName.replace(
'-',
'_').left(10);
304 QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
306 indexCheckBox->
setStyleSheet(
"QCheckBox{font-weight: bold; color:green}");
312int OpsAstrometryIndexFiles::indexFileCount(
QString indexName)
327bool OpsAstrometryIndexFiles::fileCountMatches(
QDir directory,
QString indexName)
329 QString indexNameMatch = indexName.
left(10) +
"*.fits";
331 return list.
count() == indexFileCount(indexName);
334void OpsAstrometryIndexFiles::slotOpenIndexFileDirectory()
336 if(indexLocations->count() == 0)
342bool OpsAstrometryIndexFiles::astrometryIndicesAreAvailable()
344 QUrl indexUrl =
QUrl(this->indexURL->text());
347 timeout.setInterval(5000);
348 timeout.setSingleShot(
true);
352 if (!timeout.isActive())
357 qApp->processEvents();
364 return wasSuccessful;
368 int currentIndex,
int maxIndex,
double fileSize)
371 downloadTime.
start();
374 if (currentIndex < 10)
375 indexString =
'0' + indexString;
377 QString indexSeriesName = checkBox->
text().remove(
'&');
378 QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_progress");
379 QLabel *indexDownloadInfo = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_info");
380 QPushButton *indexDownloadCancel = findChild<QPushButton *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_cancel");
381 QLabel *indexDownloadPerc = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_perc");
383 setDownloadInfoVisible(indexSeriesName, checkBox,
true);
385 if(indexDownloadInfo)
387 if (indexDownloadProgress && maxIndex > 0)
388 indexDownloadProgress->
setValue(currentIndex * 100 / maxIndex);
390 indexDownloadInfo->
setText(info);
391 emit newDownloadProgress(info);
396 indexURL.
replace(
'*', indexString);
405 if(fileSize > 4000000)
406 timeout = fileSize / downloadSpeed;
413 if(indexDownloadPerc)
416 [ = ](qint64 bytesReceived, qint64 bytesTotal)
418 if (indexDownloadProgress)
420 indexDownloadProgress->
setValue(bytesReceived);
421 indexDownloadProgress->
setMaximum(bytesTotal);
424 indexDownloadPerc->
setText(info);
425 emit newDownloadProgress(info);
430 timeoutTimer.disconnect();
433 KSNotification::error(
434 i18n(
"Download Timed out. Either the network is not fast enough, the file is not accessible, or you are not connected."),
436 disconnectDownload(cancelConnection, replyConnection, percentConnection);
442 setDownloadInfoVisible(indexSeriesName, checkBox,
false);
444 timeoutTimer.start(timeout);
449 qDebug() << Q_FUNC_INFO <<
"Download Cancelled.";
451 disconnectDownload(cancelConnection, replyConnection, percentConnection);
452 emit newDownloadProgress(
i18n(
"%s download cancelled.", indexSeriesName));
458 setDownloadInfoVisible(indexSeriesName, checkBox,
false);
467 disconnectDownload(cancelConnection, replyConnection, percentConnection);
468 setDownloadInfoVisible(indexSeriesName, checkBox,
false);
480 indexFileN.
replace(
'*', indexString);
482 QFile file(indexFileN);
487 KSNotification::error(
i18n(
"File Write Error"),
i18n(
"Error"), 10);
493 file.write(responseData.
data(), responseData.
size());
496 int dtime = downloadTime.
elapsed();
497 actualdownloadSpeed = (actualdownloadSpeed + (downloadedFileSize / dtime)) / 2;
498 qDebug() << Q_FUNC_INFO <<
"Filesize: " << downloadedFileSize <<
", time: " << dtime <<
", inst speed: " <<
499 downloadedFileSize / dtime <<
500 ", averaged speed: " << actualdownloadSpeed;
501 emit newDownloadProgress(
i18n(
"%1 download complete.", indexSeriesName));
507 KSNotification::error(
i18n(
"Astrometry Folder Permissions Error"),
i18n(
"Error"), 10);
510 if (currentIndex == maxIndex)
515 downloadIndexFile(URL, fileN, checkBox, currentIndex + 1, maxIndex, fileSize);
520void OpsAstrometryIndexFiles::setDownloadInfoVisible(
QString indexSeriesName,
QCheckBox *checkBox,
bool set)
524 QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_progress");
525 QLabel *indexDownloadInfo = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_info");
526 QPushButton *indexDownloadCancel = findChild<QPushButton *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_cancel");
527 QLabel *indexDownloadPerc = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_perc");
528 if (indexDownloadProgress)
530 if (indexDownloadInfo)
532 if (indexDownloadCancel)
534 if (indexDownloadPerc)
541 disconnect(*cancelConnection);
543 disconnect(*replyConnection);
544 if(percentConnection)
545 disconnect(*percentConnection);
548void OpsAstrometryIndexFiles::downloadOrDeleteIndexFiles(
bool checked)
552 if (indexLocations->count() == 0)
555 QString astrometryDataDir = indexLocations->currentText();
558 KSNotification::sorry(
559 i18n(
"The selected Index File directory does not exist. Please either create it or choose another."),
i18n(
"Sorry"), 10);
565 QString indexSeriesName = checkBox->
text().remove(
'&');
566 QString filePath = astrometryDataDir +
'/' + indexSeriesName;
567 QString fileNumString = indexSeriesName.
mid(8, 2);
574 nullptr,
i18n(
"The file %1 already exists in another directory. Are you sure you want to download it to this directory as well?",
584 if (astrometryIndicesAreAvailable())
589 if (this->indexURL->text().
endsWith(
"/"))
591 BASE_URL = this->indexURL->text();
595 BASE_URL = this->indexURL->text() +
"/";
599 URL = BASE_URL +
"4100/" + indexSeriesName;
600 else if (indexSeriesName.startsWith(
QLatin1String(
"index-42")))
601 URL = BASE_URL +
"4200/" + indexSeriesName;
602 else if (indexSeriesName.startsWith(
QLatin1String(
"index-52")))
603 URL =
"https://portal.nersc.gov/project/cosmo/temp/dstn/index-5200/LITE/" + indexSeriesName;
605 int maxIndex = indexFileCount(indexSeriesName) - 1;
607 double fileSize = 1E11 * qPow(astrometryIndex.key(fileNumString),
610 fileSize /= maxIndex;
611 downloadIndexFile(URL, filePath, checkBox, 0, maxIndex, fileSize);
615 KSNotification::sorry(
i18n(
"Could not contact Astrometry Index Server."),
i18n(
"Error"), 10);
621 nullptr,
i18n(
"Are you sure you want to delete these index files? %1", indexSeriesName),
625 if (
QFileInfo(astrometryDataDir).isWritable())
628 QDir directory(astrometryDataDir);
630 for (
auto &fileName : indexList)
632 if (fileName.contains(indexSeriesName.left(10)))
634 if (!directory.
remove(fileName))
636 KSNotification::error(
i18n(
"File Delete Error"),
i18n(
"Error"), 10);
646 KSNotification::error(
i18n(
"Astrometry Folder Permissions Error"),
i18n(
"Error"), 10);
This is the main window for KStars.
QString i18n(const char *text, const TYPE &arg...)
Ekos is an advanced Astrophotography tool for Linux.
QString path(const QString &relativePath)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
KIOCORE_EXPORT QString dir(const QString &fileClass)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString label(StandardShortcut id)
qsizetype size() const const
void currentIndexChanged(int index)
bool openUrl(const QUrl &url)
QStringList entryList(Filters filters, SortFlags sort) const const
bool remove(const QString &fileName)
qint64 elapsed() const const
QString getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
bool exists() const const
bool isWritable() const const
qint64 size() const const
QString errorString() const const
void setText(const QString &)
void textChanged(const QString &text)
void append(QList< T > &&value)
qsizetype count() const const
bool removeOne(const AT &t)
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
NetworkError error() const const
bool isFinished() const const
QObject * sender() const const
void setMaximum(int maximum)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString left(qsizetype n) const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QUrl fromLocalFile(const QString &localFile)
QString url(FormattingOptions options) const const