diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4b1013ec3..dbf4c4488 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -43,6 +43,7 @@ set(SOURCES core/localredirectserver.cpp core/mimedata.cpp core/potranslator.cpp + core/temporaryfile.cpp utilities/strutils.cpp utilities/envutils.cpp utilities/colorutils.cpp diff --git a/src/core/temporaryfile.cpp b/src/core/temporaryfile.cpp new file mode 100644 index 000000000..68fab5dda --- /dev/null +++ b/src/core/temporaryfile.cpp @@ -0,0 +1,73 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#include +#include +#include + +#include "core/logging.h" + +#include "temporaryfile.h" + +TemporaryFile::TemporaryFile(const QString &filename_pattern) { + + int i = 0; + do { + filename_ = GenerateFilename(filename_pattern); + ++i; + } while (QFile::exists(filename_) && i < 100); + + if (QFile::exists(filename_)) { + qLog(Error) << "Could not get a filename from pattern" << filename_pattern; + filename_.clear(); + } + else { + qLog(Debug) << "Temporary file" << filename_ << "available"; + } + +} + +TemporaryFile::~TemporaryFile() { + + if (!filename_.isEmpty() && QFile::exists(filename_)) { + qLog(Debug) << "Deleting temporary file" << filename_; + if (!QFile::remove(filename_)) { + qLog(Debug) << "Could not delete temporary file" << filename_; + } + } + +} + +QString TemporaryFile::GenerateFilename(const QString &filename_pattern) const { + + static const QString random_chars = QStringLiteral("abcdefghijklmnopqrstuvwxyz0123456789"); + + QString filename = filename_pattern; + + Q_FOREVER { + const qint64 i = filename.indexOf(QLatin1Char('X')); + if (i == -1) break; + const qint64 index = QRandomGenerator::global()->bounded(0, random_chars.length()); + const QChar random_char = random_chars.at(index); + filename[i] = random_char; + } + + return filename; + +} diff --git a/src/core/temporaryfile.h b/src/core/temporaryfile.h new file mode 100644 index 000000000..a599e7e6e --- /dev/null +++ b/src/core/temporaryfile.h @@ -0,0 +1,39 @@ +/* + * Strawberry Music Player + * Copyright 2024, Jonas Kvinge + * + * Strawberry is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Strawberry is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Strawberry. If not, see . + * + */ + +#ifndef TEMPORARYFILE_H +#define TEMPORARYFILE_H + +#include + +class TemporaryFile { + public: + explicit TemporaryFile(const QString &filename_pattern); + ~TemporaryFile(); + + QString filename() const { return filename_; } + + private: + QString GenerateFilename(const QString &filename_pattern) const; + + private: + QString filename_; +}; + +#endif // TEMPORARYFILE_H diff --git a/tests/src/utilities_test.cpp b/tests/src/utilities_test.cpp index c5a305010..7a163c03a 100644 --- a/tests/src/utilities_test.cpp +++ b/tests/src/utilities_test.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "test_utils.h" @@ -35,6 +36,7 @@ #include "utilities/colorutils.h" #include "utilities/transliterate.h" #include "core/logging.h" +#include "core/temporaryfile.h" TEST(UtilitiesTest, PrettyTimeDelta) { @@ -244,3 +246,19 @@ TEST(UtilitiesTest, ReplaceMessage) { ASSERT_EQ(Utilities::ReplaceMessage(QStringLiteral("%title% - %artist%"), song, QLatin1String("")), song.title() + QStringLiteral(" - ") + song.artist()); } + +TEST(UtilitiesTest, TemporaryFile) { + + QString filename_pattern = QStringLiteral("/tmp/test-XXXX.jpg"); + + TemporaryFile temp_file(filename_pattern); + + EXPECT_FALSE(temp_file.filename().isEmpty()); + + EXPECT_FALSE(temp_file.filename() == filename_pattern); + + static const QRegularExpression regex_temp_filename(QStringLiteral("^\\/tmp\\/test-....\\.jpg$")); + + EXPECT_TRUE(regex_temp_filename.match(temp_file.filename()).hasMatch()); + +}