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://data.astrometry.net/");
30 connect(openIndexFileDirectory, SIGNAL(clicked()),
this, SLOT(slotOpenIndexFileDirectory()));
32 astrometryIndex[2.8] =
"00";
33 astrometryIndex[4.0] =
"01";
34 astrometryIndex[5.6] =
"02";
35 astrometryIndex[8] =
"03";
36 astrometryIndex[11] =
"04";
37 astrometryIndex[16] =
"05";
38 astrometryIndex[22] =
"06";
39 astrometryIndex[30] =
"07";
40 astrometryIndex[42] =
"08";
41 astrometryIndex[60] =
"09";
42 astrometryIndex[85] =
"10";
43 astrometryIndex[120] =
"11";
44 astrometryIndex[170] =
"12";
45 astrometryIndex[240] =
"13";
46 astrometryIndex[340] =
"14";
47 astrometryIndex[480] =
"15";
48 astrometryIndex[680] =
"16";
49 astrometryIndex[1000] =
"17";
50 astrometryIndex[1400] =
"18";
51 astrometryIndex[2000] =
"19";
56 &OpsAstrometryIndexFiles::slotUpdate);
58 for (
auto &checkBox : checkboxes)
67 for (
auto &bar : progressBars)
69 if(bar->objectName().contains(
"progress"))
71 bar->setVisible(
false);
72 bar->setTextVisible(
false);
76 for (
auto &button : qButtons)
78 if(button->objectName().contains(
"cancel"))
80 button->setVisible(
false);
84 for (
QLabel * label : qLabels)
88 label->setVisible(
false);
100 addDirectoryToList(dir);
104 if(indexLocations->currentIndex() != 0)
105 removeDirectoryFromList(indexLocations->currentText());
111void OpsAstrometryIndexFiles::showEvent(
QShowEvent *)
113 updateIndexDirectoryList();
117void OpsAstrometryIndexFiles::updateIndexDirectoryList()
121 QStringList astrometryDataDirs = KSUtils::getAstrometryDataDirs();
123 indexLocations->clear();
124 if(astrometryDataDirs.
count() > 1)
125 indexLocations->addItem(
"All Sources");
126 indexLocations->addItems(astrometryDataDirs);
130void OpsAstrometryIndexFiles::addDirectoryToList(
QString directory)
137 QStringList indexFileDirs = Options::astrometryIndexFolderList();
138 if(indexFileDirs.
contains(directoryPath))
140 indexFileDirs.
append(directoryPath);
141 Options::setAstrometryIndexFolderList(indexFileDirs);
142 updateIndexDirectoryList();
145void OpsAstrometryIndexFiles::removeDirectoryFromList(
QString directory)
147 QStringList indexFileDirs = Options::astrometryIndexFolderList();
148 if(indexFileDirs.
contains(directory))
151 Options::setAstrometryIndexFolderList(indexFileDirs);
152 updateIndexDirectoryList();
156void OpsAstrometryIndexFiles::slotUpdate()
160 for (
auto &checkBox : checkboxes)
162 checkBox->setChecked(
false);
165 if(indexLocations->count() == 0)
168 double fov_w, fov_h, fov_pixscale;
171 alignModule->getFOVScale(fov_w, fov_h, fov_pixscale);
173 double fov_check = qMax(fov_w, fov_h);
179 QStringList astrometryDataDirs = Options::astrometryIndexFolderList();
181 bool allDirsSelected = (indexLocations->currentIndex() == 0 && astrometryDataDirs.
count() > 1);
182 bool folderIsWriteable;
188 folderDetails->setText(
i18n(
"Downloads Disabled, this is not a directory, it is a list of all index files."));
189 folderIsWriteable =
false;
190 astrometryDataDirsToIndex = astrometryDataDirs;
191 openIndexFileDirectory->setEnabled(
false);
195 QString folderPath = indexLocations->currentText();
197 if(folderIsWriteable)
198 folderDetails->setText(
i18n(
"Downloads Enabled, the directory exists and is writeable."));
200 folderDetails->setText(
i18n(
"Downloads Disabled, directory permissions issue."));
202 folderDetails->setText(
i18n(
"Downloads Disabled, directory does not exist."));
203 astrometryDataDirsToIndex << folderPath;
204 openIndexFileDirectory->setEnabled(
true);
206 folderDetails->setCursorPosition(0);
210 for(
auto &astrometryDataDir : astrometryDataDirsToIndex)
212 QDir directory(astrometryDataDir);
213 QStringList indexList = directory.entryList(nameFilter);
215 for (
auto &indexName : indexList)
217 if (fileCountMatches(directory, indexName))
219 indexName = indexName.replace(
'-',
'_').left(10);
220 QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
227 for (
auto &checkBox : checkboxes)
229 checkBox->setEnabled(folderIsWriteable);
230 checkBox->setIcon(
QIcon(
":/icons/astrometry-optional.svg"));
231 checkBox->setToolTip(
i18n(
"Optional"));
232 checkBox->setStyleSheet(
"");
235 float last_skymarksize = 2;
237 for (
auto &skymarksize : astrometryIndex.keys())
239 QString indexName1 =
"index_41" + astrometryIndex.value(skymarksize);
240 QString indexName2 =
"index_42" + astrometryIndex.value(skymarksize);
241 QString indexName3 =
"index_52" + astrometryIndex.value(skymarksize);
242 QCheckBox *indexCheckBox1 = findChild<QCheckBox *>(indexName1);
243 QCheckBox *indexCheckBox2 = findChild<QCheckBox *>(indexName2);
244 QCheckBox *indexCheckBox3 = findChild<QCheckBox *>(indexName3);
245 if ((skymarksize >= 0.40 * fov_check && skymarksize <= 0.9 * fov_check) ||
246 (fov_check > last_skymarksize && fov_check < skymarksize))
250 indexCheckBox1->
setIcon(
QIcon(
":/icons/astrometry-required.svg"));
255 indexCheckBox2->
setIcon(
QIcon(
":/icons/astrometry-required.svg"));
260 indexCheckBox3->
setIcon(
QIcon(
":/icons/astrometry-required.svg"));
264 else if (skymarksize >= 0.10 * fov_check && skymarksize <= fov_check)
268 indexCheckBox1->
setIcon(
QIcon(
":/icons/astrometry-recommended.svg"));
273 indexCheckBox2->
setIcon(
QIcon(
":/icons/astrometry-recommended.svg"));
278 indexCheckBox3->
setIcon(
QIcon(
":/icons/astrometry-recommended.svg"));
283 last_skymarksize = skymarksize;
289 for(
QString astrometryDataDir : astrometryDataDirs)
291 QDir directory(astrometryDataDir);
292 QStringList indexList = directory.entryList(nameFilter);
294 for (
auto &indexName : indexList)
296 if (fileCountMatches(directory, indexName))
298 indexName = indexName.replace(
'-',
'_').left(10);
299 QCheckBox *indexCheckBox = findChild<QCheckBox *>(indexName);
301 indexCheckBox->
setStyleSheet(
"QCheckBox{font-weight: bold; color:green}");
307int OpsAstrometryIndexFiles::indexFileCount(
QString indexName)
322bool OpsAstrometryIndexFiles::fileCountMatches(
QDir directory,
QString indexName)
324 QString indexNameMatch = indexName.
left(10) +
"*.fits";
326 return list.
count() == indexFileCount(indexName);
329void OpsAstrometryIndexFiles::slotOpenIndexFileDirectory()
331 if(indexLocations->count() == 0)
337bool OpsAstrometryIndexFiles::astrometryIndicesAreAvailable()
339 auto url =
QUrl(indexURL->text());
342 timeout.setInterval(5000);
343 timeout.setSingleShot(
true);
345 while (!response->isFinished())
347 if (!timeout.isActive())
349 response->deleteLater();
352 qApp->processEvents();
357 response->deleteLater();
359 return wasSuccessful;
363 int currentIndex,
int maxIndex,
double fileSize)
366 downloadTime.
start();
369 if (currentIndex < 10)
370 indexString =
'0' + indexString;
372 QString indexSeriesName = checkBox->
text().remove(
'&');
373 QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_progress");
374 QLabel *indexDownloadInfo = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_info");
375 QPushButton *indexDownloadCancel = findChild<QPushButton *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_cancel");
376 QLabel *indexDownloadPerc = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_perc");
378 setDownloadInfoVisible(indexSeriesName, checkBox,
true);
380 if(indexDownloadInfo)
382 if (indexDownloadProgress && maxIndex > 0)
383 indexDownloadProgress->
setValue(currentIndex * 100 / maxIndex);
385 indexDownloadInfo->
setText(info);
386 emit newDownloadProgress(info);
391 indexURL.
replace(
'*', indexString);
400 if(fileSize > 4000000)
401 timeout = fileSize / downloadSpeed;
408 if(indexDownloadPerc)
411 [ = ](qint64 bytesReceived, qint64 bytesTotal)
413 if (indexDownloadProgress)
415 indexDownloadProgress->
setValue(bytesReceived);
416 indexDownloadProgress->
setMaximum(bytesTotal);
419 indexDownloadPerc->
setText(info);
420 emit newDownloadProgress(info);
425 timeoutTimer.disconnect();
428 KSNotification::error(
429 i18n(
"Download Timed out. Either the network is not fast enough, the file is not accessible, or you are not connected."),
431 disconnectDownload(cancelConnection, replyConnection, percentConnection);
437 setDownloadInfoVisible(indexSeriesName, checkBox,
false);
439 timeoutTimer.start(timeout);
444 qDebug() << Q_FUNC_INFO <<
"Download Cancelled.";
446 disconnectDownload(cancelConnection, replyConnection, percentConnection);
447 emit newDownloadProgress(
i18n(
"%1 download cancelled.", indexSeriesName));
453 setDownloadInfoVisible(indexSeriesName, checkBox,
false);
462 disconnectDownload(cancelConnection, replyConnection, percentConnection);
463 setDownloadInfoVisible(indexSeriesName, checkBox,
false);
475 indexFileN.
replace(
'*', indexString);
477 QFile file(indexFileN);
482 KSNotification::error(
i18n(
"File Write Error"),
i18n(
"Error"), 10);
488 file.write(responseData.
data(), responseData.
size());
491 int dtime = downloadTime.
elapsed();
492 actualdownloadSpeed = (actualdownloadSpeed + (downloadedFileSize / dtime)) / 2;
493 qDebug() << Q_FUNC_INFO <<
"Filesize: " << downloadedFileSize <<
", time: " << dtime <<
", inst speed: " <<
494 downloadedFileSize / dtime <<
495 ", averaged speed: " << actualdownloadSpeed;
496 emit newDownloadProgress(
i18n(
"%1 download complete.", indexSeriesName));
502 KSNotification::error(
i18n(
"Astrometry Folder Permissions Error"),
i18n(
"Error"), 10);
505 if (currentIndex == maxIndex)
510 downloadIndexFile(URL, fileN, checkBox, currentIndex + 1, maxIndex, fileSize);
515void OpsAstrometryIndexFiles::setDownloadInfoVisible(
QString indexSeriesName,
QCheckBox *checkBox,
bool set)
519 QProgressBar *indexDownloadProgress = findChild<QProgressBar *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_progress");
520 QLabel *indexDownloadInfo = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_info");
521 QPushButton *indexDownloadCancel = findChild<QPushButton *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_cancel");
522 QLabel *indexDownloadPerc = findChild<QLabel *>(indexSeriesName.
replace(
'-',
'_').
left(10) +
"_perc");
523 if (indexDownloadProgress)
525 if (indexDownloadInfo)
527 if (indexDownloadCancel)
529 if (indexDownloadPerc)
536 disconnect(*cancelConnection);
538 disconnect(*replyConnection);
539 if(percentConnection)
540 disconnect(*percentConnection);
543void OpsAstrometryIndexFiles::downloadOrDeleteIndexFiles(
bool checked)
547 if (indexLocations->count() == 0)
550 QString astrometryDataDir = indexLocations->currentText();
553 KSNotification::sorry(
554 i18n(
"The selected Index File directory does not exist. Please either create it or choose another."),
i18n(
"Sorry"), 10);
560 QString indexSeriesName = checkBox->
text().remove(
'&');
561 QString filePath = astrometryDataDir +
'/' + indexSeriesName;
562 QString fileNumString = indexSeriesName.
mid(8, 2);
569 nullptr,
i18n(
"The file %1 already exists in another directory. Are you sure you want to download it to this directory as well?",
579 if (astrometryIndicesAreAvailable())
584 if (this->indexURL->text().
endsWith(
"/"))
586 BASE_URL = this->indexURL->text();
590 BASE_URL = this->indexURL->text() +
"/";
594 URL = BASE_URL +
"4100/" + indexSeriesName;
595 else if (indexSeriesName.startsWith(
QLatin1String(
"index-42")))
596 URL = BASE_URL +
"4200/" + indexSeriesName;
597 else if (indexSeriesName.startsWith(
QLatin1String(
"index-52")))
598 URL =
"https://portal.nersc.gov/project/cosmo/temp/dstn/index-5200/LITE/" + indexSeriesName;
600 int maxIndex = indexFileCount(indexSeriesName) - 1;
602 double fileSize = 1E11 * qPow(astrometryIndex.key(fileNumString),
605 fileSize /= maxIndex;
606 downloadIndexFile(URL, filePath, checkBox, 0, maxIndex, fileSize);
610 KSNotification::sorry(
i18n(
"Could not contact Astrometry Index Server."),
i18n(
"Error"), 10);
616 nullptr,
i18n(
"Are you sure you want to delete these index files? %1", indexSeriesName),
620 if (
QFileInfo(astrometryDataDir).isWritable())
623 QDir directory(astrometryDataDir);
625 for (
auto &fileName : indexList)
627 if (fileName.contains(indexSeriesName.left(10)))
629 if (!directory.
remove(fileName))
631 KSNotification::error(
i18n(
"File Delete Error"),
i18n(
"Error"), 10);
641 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 append(QList< T > &&value)
qsizetype count() const const
bool removeOne(const AT &t)
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
NetworkError error() 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)