From 714fb62d17b56eaa00327e8428b4fc06086f9521 Mon Sep 17 00:00:00 2001
From: casey langen <casey.langen@gmail.com>
Date: Tue, 29 Aug 2017 18:16:24 -0700
Subject: [PATCH] Added a setting for enabling indexer logging. Should be
 useful for helping users discover corrupted tags.

---
 src/core/library/Indexer.cpp        | 47 +++++++++++++++++++++++++++++
 src/core/support/PreferenceKeys.cpp |  1 +
 src/core/support/PreferenceKeys.h   |  1 +
 3 files changed, 49 insertions(+)

diff --git a/src/core/library/Indexer.cpp b/src/core/library/Indexer.cpp
index a18cacf02..c9e75238d 100644
--- a/src/core/library/Indexer.cpp
+++ b/src/core/library/Indexer.cpp
@@ -46,6 +46,7 @@
 #include <core/db/Connection.h>
 #include <core/db/Statement.h>
 #include <core/plugin/PluginFactory.h>
+#include <core/support/Common.h>
 #include <core/support/Preferences.h>
 #include <core/support/PreferenceKeys.h>
 #include <core/sdk/IAnalyzer.h>
@@ -64,6 +65,7 @@
 
 static const std::string TAG = "Indexer";
 static const size_t TRANSACTION_INTERVAL = 300;
+static FILE* logFile = nullptr;
 
 #ifdef __arm__
 static const int MAX_THREADS = 2;
@@ -93,6 +95,24 @@ static std::string normalizeDir(std::string path) {
     return path;
 }
 
+static void openLogFile() {
+    if (!logFile) {
+        std::string path = GetDataDirectory() + "/indexer_log.txt";
+#ifdef WIN32
+        logFile = _wfopen(u8to16(path).c_str(), L"w");
+#else
+        logFile = fopen(path.c_str(), "w");
+#endif
+    }
+}
+
+static void closeLogFile() {
+    if (logFile) {
+        fclose(logFile);
+        logFile = nullptr;
+    }
+}
+
 static std::string normalizePath(const std::string& path) {
     return boost::filesystem::path(path).make_preferred().string();
 }
@@ -104,6 +124,10 @@ Indexer::Indexer(const std::string& libraryPath, const std::string& dbFilename)
 , state(StateIdle)
 , prefs(Preferences::ForComponent(prefs::components::Settings))
 , readSemaphore(prefs->GetInt(prefs::keys::MaxTagReadThreads, MAX_THREADS)) {
+    if (prefs->GetBool(prefs::keys::IndexerLogEnabled, false) && !logFile) {
+        openLogFile();
+    }
+
     this->metadataReaders = PluginFactory::Instance()
         .QueryInterface<IMetadataReader, MetadataDeleter>("GetMetadataReader");
 
@@ -126,6 +150,8 @@ Indexer::Indexer(const std::string& libraryPath, const std::string& dbFilename)
 }
 
 Indexer::~Indexer() {
+    closeLogFile();
+
     if (this->thread) {
         {
             boost::mutex::scoped_lock lock(this->stateMutex);
@@ -250,6 +276,10 @@ void Indexer::Synchronize(const SyncContext& context, boost::asio::io_service* i
 
     /* process local files */
     if (type == SyncType::All || type == SyncType::Local) {
+        if (logFile) {
+            fprintf(logFile, "\n\nSYNCING LOCAL FILES:\n");
+        }
+
         std::vector<std::string> paths;
         std::vector<int64_t> pathIds;
 
@@ -339,6 +369,10 @@ void Indexer::ReadMetadataFromFile(
         while (it != this->metadataReaders.end()) {
             try {
                 if ((*it)->CanRead(track.GetValue("extension").c_str())) {
+                    if (logFile) {
+                        fprintf(logFile, "    - %s\n", file.string().c_str());
+                    }
+
                     if ((*it)->Read(file.string().c_str(), &track)) {
                         saveToDb = true;
                         break;
@@ -360,6 +394,10 @@ void Indexer::ReadMetadataFromFile(
             auto it = this->audioDecoders.begin();
             while (it != this->audioDecoders.end()) {
                 if ((*it)->CanHandle(fullPath.c_str())) {
+                    if (logFile) {
+                        fprintf(logFile, "    - %s\n", file.string().c_str());
+                    }
+
                     saveToDb = true;
                     track.SetValue("title", file.leaf().string().c_str());
                     break;
@@ -470,6 +508,10 @@ void Indexer::SyncDirectory(
 }
 
 ScanResult Indexer::SyncSource(IIndexerSource* source) {
+    if (logFile) {
+        fprintf(logFile, "\n\nSYNCING SOURCE WITH ID: %d\n", source->SourceId());
+    }
+
     if (source->SourceId() == 0) {
         return ScanRollback;
     }
@@ -487,6 +529,11 @@ ScanResult Indexer::SyncSource(IIndexerSource* source) {
         while (tracks.Step() == db::Row) {
             TrackPtr track(new IndexerTrack(tracks.ColumnInt64(0)));
             track->SetValue(constants::Track::FILENAME, tracks.ColumnText(1));
+
+            if (logFile) {
+                fprintf(logFile, "    - %s\n", track->GetValue(constants::Track::FILENAME).c_str());
+            }
+
             source->ScanTrack(this, new RetainedTrackWriter(track), tracks.ColumnText(2));
             this->IncrementTracksScanned();
         }
diff --git a/src/core/support/PreferenceKeys.cpp b/src/core/support/PreferenceKeys.cpp
index 0523a5078..099ca6e4c 100644
--- a/src/core/support/PreferenceKeys.cpp
+++ b/src/core/support/PreferenceKeys.cpp
@@ -52,6 +52,7 @@ namespace musik { namespace core { namespace prefs {
     const std::string keys::OutputPlugin = "OutputPlugin";
     const std::string keys::Transport = "Transport";
     const std::string keys::Locale = "Locale";
+    const std::string keys::IndexerLogEnabled = "IndexerLogEnabled";
 
 } } }
 
diff --git a/src/core/support/PreferenceKeys.h b/src/core/support/PreferenceKeys.h
index cfe6ae33c..349ef18d6 100644
--- a/src/core/support/PreferenceKeys.h
+++ b/src/core/support/PreferenceKeys.h
@@ -56,6 +56,7 @@ namespace musik { namespace core { namespace prefs {
         extern const std::string OutputPlugin;
         extern const std::string Transport;
         extern const std::string Locale;
+        extern const std::string IndexerLogEnabled;
     }
 
 } } }