LCOV - code coverage report
Current view: top level - src/project/internal - convertfiletoscoreservice.h Coverage Total Hit
Test: filtered_coverage.info Lines: 100.0 % 2 2
Test Date: 2026-11-05 04:07:02

            Line data    Source code
       1              : /*
       2              :  * SPDX-License-Identifier: GPL-3.0-only
       3              :  * MuseScore-Studio-CLA-applies
       4              :  *
       5              :  * MuseScore Studio
       6              :  * Music Composition & Notation
       7              :  *
       8              :  * Copyright (C) 2026 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : #pragma once
      23              : 
      24              : #include <cstdint>
      25              : #include <optional>
      26              : #include <unordered_map>
      27              : #include <vector>
      28              : 
      29              : #include <QObject>
      30              : #include <QTimer>
      31              : 
      32              : #include "project/iconvertfiletoscoreservice.h"
      33              : 
      34              : #include "async/asyncable.h"
      35              : #include "modularity/ioc.h"
      36              : 
      37              : #include "cloud/musescorecom/imusescorecomservice.h"
      38              : #include "io/ifilesystem.h"
      39              : #include "multiwindows/imultiwindowsprovider.h"
      40              : #include "project/iprojectconfiguration.h"
      41              : 
      42              : namespace mu::project {
      43              : class ConvertFileToScoreService : public QObject, public IConvertFileToScoreService, public muse::async::Asyncable, public muse::Contextable
      44              : {
      45              :     Q_OBJECT
      46              : 
      47              : public:
      48              :     muse::GlobalInject<muse::cloud::IMuseScoreComService> museScoreComService;
      49              :     muse::GlobalInject<muse::io::IFileSystem> fileSystem;
      50              :     muse::GlobalInject<IProjectConfiguration> configuration;
      51              :     muse::GlobalInject<muse::mi::IMultiWindowsProvider> multiwindowsProvider;
      52              : 
      53           62 :     explicit ConvertFileToScoreService(const muse::modularity::ContextPtr& iocCtx, QObject* parent = nullptr)
      54           62 :         : QObject(parent), muse::Contextable(iocCtx) {}
      55              : 
      56              :     void init();
      57              :     void resumeConvert();
      58              : 
      59              :     const ConvertConfig& config() const override;
      60              : 
      61              :     bool isFileSupported(const muse::io::path_t& path) const override;
      62              :     muse::RetVal<ConvertFilesValidation> validateFiles(const muse::io::paths_t& paths) const override;
      63              :     muse::Ret validateLink(const QUrl& link) const override;
      64              : 
      65              :     muse::RetVal<muse::Progress> uploadToConvert(const ConvertInput& input, const muse::String& convertedScoreName) override;
      66              :     muse::async::Channel<muse::Ret, WatchedScore> convertFinished() const override;
      67              : 
      68              :     muse::ValNt<UploadingScoreList> uploadingScores() const override;
      69              :     muse::ValNt<WatchedScoreList> watchedScores() const override;
      70              :     const WatchedScore* watchedScoreById(int scoreId) const override;
      71              : 
      72              :     muse::async::Channel<PollingStatus> pollingStatusChanged() const override;
      73              :     void retryPolling() override;
      74              : 
      75              :     void submitReview(int scoreId, ReviewRating rating, const QString& comment = QString()) override;
      76              :     void submitReviewComment(int scoreId, const QString& comment) override;
      77              : 
      78              :     void cancelUpload(int uploadId) override;
      79              :     void cancelConversion(ConvertType type, int convertId) override;
      80              : 
      81              : protected:
      82              :     //! NOTE: overridable so tests can fake elapsed time instead of waiting on the real clock
      83              :     virtual int64_t nowMs() const;
      84              : 
      85              :     //! NOTE: protected so tests can trigger a poll directly instead of waiting on the real timer
      86              :     void poll();
      87              : 
      88              : private:
      89              :     static constexpr int MIN_RETRY_INTERVAL_MS = 60000;
      90              :     static constexpr int MAX_POLL_RETRY_DURATION_MS = 10 * 60000; // gives up after ~10 minutes
      91              : 
      92              :     void loadWatchedScores();
      93              :     void saveWatchedScores();
      94              : 
      95              :     void removeUpload(int uploadId);
      96              :     void watch(ConvertType type, int itemId, const muse::String& convertedScoreName);
      97              :     bool hasAnyScoresToPoll() const;
      98              :     void resetPollState();
      99              :     void handlePollFailure(const muse::Ret& ret);
     100              :     void giveUpPolling(const muse::Ret& ret, muse::secs_t elapsed);
     101              :     void updateWatchedScores(const muse::cloud::ConvertQueueList& queue, const WatchedScoreList& snapshot);
     102              : 
     103              :     void updateStatus(WatchedScore& watched, muse::cloud::ConvertStatus status, muse::cloud::ConvertErrorCode errorCode);
     104              : 
     105              :     ConvertConfig m_config;
     106              : 
     107              :     QTimer m_timer;
     108              :     int64_t m_pollRetryStartMs = 0;
     109              :     int m_pollIntervalMs = MIN_RETRY_INTERVAL_MS;
     110              :     int m_pollFailureCount = 0;
     111              :     UploadingScoreList m_uploadingScores;
     112              :     std::vector<WatchedScore> m_watchedScores;
     113              :     std::unordered_map<int /*uploadId*/, muse::ProgressPtr> m_uploadProgresses;
     114              :     int m_lastUploadId = 0;
     115              :     bool m_pollInProgress = false;
     116              :     bool m_manualRetryRequested = false;
     117              :     bool m_isSaving = false;
     118              : 
     119              :     muse::async::Notification m_uploadingScoresChanged;
     120              :     muse::async::Notification m_watchedScoresChanged;
     121              :     muse::async::Channel<PollingStatus> m_pollingStatusChanged;
     122              :     muse::async::Channel<muse::Ret, WatchedScore> m_convertFinished;
     123              : };
     124              : }
        

Generated by: LCOV version 2.0-1