summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilherme Lepsch <lepsch@expertisesolutions.com.br>2014-12-09 10:36:20 -0200
committerGuilherme Lepsch <lepsch@expertisesolutions.com.br>2014-12-09 10:36:20 -0200
commit3a56797736cc7bda9b2377715d09d70f2cf6f787 (patch)
treeacb7775237a3964d2e1baf6024dcab0bd657b4d2
parent1aab1ceac70547dd64f4de663ee37e0a3262dfcd (diff)
* Background tagging of media files.
-rw-r--r--src/file_scanner.cc83
-rw-r--r--src/file_scanner.hh13
2 files changed, 89 insertions, 7 deletions
diff --git a/src/file_scanner.cc b/src/file_scanner.cc
index 39e3d6e..928ef65 100644
--- a/src/file_scanner.cc
+++ b/src/file_scanner.cc
@@ -8,6 +8,8 @@
8#include <fileref.h> 8#include <fileref.h>
9#include <tag.h> 9#include <tag.h>
10 10
11#include <Ecore.hh>
12
11namespace { 13namespace {
12 template<typename T, typename... Args> 14 template<typename T, typename... Args>
13 std::unique_ptr<T> make_unique(Args&&... args) 15 std::unique_ptr<T> make_unique(Args&&... args)
@@ -32,12 +34,18 @@ namespace {
32 34
33namespace emc { 35namespace emc {
34 36
35file_scanner::file_scanner(std::function<void(const tag&)> media_file_add_cb) 37file_scanner::file_scanner(std::function<void(tag)> media_file_add_cb)
36 : media_file_add_cb(media_file_add_cb) 38 : media_file_add_cb(media_file_add_cb)
39 , worker(&file_scanner::process, this)
40 , terminated(false)
37{} 41{}
38 42
39file_scanner::~file_scanner() 43file_scanner::~file_scanner()
40{} 44{
45 terminated = true;
46 pending_file.notify_one();
47 worker.join();
48}
41 49
42void file_scanner::start() 50void file_scanner::start()
43{ 51{
@@ -82,7 +90,7 @@ bool file_scanner::file_found(eio::model &file_model, void *info)
82 auto item_count = *static_cast<unsigned int*>(info); 90 auto item_count = *static_cast<unsigned int*>(info);
83 std::cout << "Number of items found: " << item_count << std::endl; 91 std::cout << "Number of items found: " << item_count << std::endl;
84 if (0 == item_count) 92 if (0 == item_count)
85 return false; 93 return false;
86 94
87 Eina_Accessor *accessor = nullptr; 95 Eina_Accessor *accessor = nullptr;
88 file_model.children_slice_get(0, 0, &accessor); 96 file_model.children_slice_get(0, 0, &accessor);
@@ -132,9 +140,15 @@ bool file_scanner::file_status(eio::model &file, void *info)
132 140
133void file_scanner::check_media_file(const std::string &path) 141void file_scanner::check_media_file(const std::string &path)
134{ 142{
135 // TODO: Read file tag in background 143 std::cout << "Checking media file: " << path << std::endl;
144 {
145 efl::eina::unique_lock<efl::eina::mutex> lock(mutex);
146 pending_files.push(path);
147 }
148 std::cout << "Notifying: " << path << std::endl;
149 pending_file.notify_one();
136 150
137 std::cout << "Checking if filename is a recognized media type: " << path << std::endl; 151 /*std::cout << "Checking if filename is a recognized media type: " << path << std::endl;
138 152
139 TagLib::FileRef file(path.c_str()); 153 TagLib::FileRef file(path.c_str());
140 if (file.isNull() || !file.tag()) 154 if (file.isNull() || !file.tag())
@@ -164,7 +178,64 @@ void file_scanner::check_media_file(const std::string &path)
164 new_tag.album = to_string(tag->album()); 178 new_tag.album = to_string(tag->album());
165 new_tag.genre = to_string(tag->genre()); 179 new_tag.genre = to_string(tag->genre());
166 new_tag.year = tag->year(); 180 new_tag.year = tag->year();
167 media_file_add_cb(new_tag); 181 media_file_add_cb(new_tag);*/
182}
183
184void file_scanner::process()
185{
186 efl::eina::unique_lock<efl::eina::mutex> lock(mutex);
187 while (!terminated)
188 {
189 std::cout << "Waiting for new files" << std::endl;
190 pending_file.wait(lock);
191 if (terminated) return;
192
193 process_pending_files();
194 }
195}
196
197void
198file_scanner::process_pending_files()
199{
200 while (!pending_files.empty())
201 {
202 std::cout << "Processing " << pending_files.size() << " file(s)..." << std::endl;
203 auto path = pending_files.front();
204 pending_files.pop();
205 process_file(path);
206 }
207}
208
209void
210file_scanner::process_file(const std::string &path)
211{
212 std::cout << "Checking if filename is a recognized media type: " << path << std::endl;
213
214 TagLib::FileRef file(path.c_str());
215 if (file.isNull() || !file.tag())
216 return;
217
218 TagLib::Tag *tag = file.tag();
219
220 auto to_string = [](const TagLib::String &str) -> std::string
221 {
222 if (str == TagLib::String::null)
223 return "";
224
225 const auto UNICODE = true;
226 return str.to8Bit(UNICODE);
227 };
228
229 ::emc::tag new_tag;
230 new_tag.file = path;
231 new_tag.title = to_string(tag->title());
232 new_tag.track = tag->track();
233 new_tag.artist = to_string(tag->artist());
234 new_tag.album = to_string(tag->album());
235 new_tag.genre = to_string(tag->genre());
236 new_tag.year = tag->year();
237
238 efl::ecore::main_loop_thread_safe_call_async(std::bind(media_file_add_cb, new_tag));
168} 239}
169 240
170} 241}
diff --git a/src/file_scanner.hh b/src/file_scanner.hh
index 0c5f473..f44640c 100644
--- a/src/file_scanner.hh
+++ b/src/file_scanner.hh
@@ -1,6 +1,7 @@
1#ifndef _FILE_SCANNER_HH 1#ifndef _FILE_SCANNER_HH
2#define _FILE_SCANNER_HH 2#define _FILE_SCANNER_HH
3 3
4#include <Eina.hh>
4#include <Eio.h> 5#include <Eio.h>
5#include <Emodel.h> 6#include <Emodel.h>
6#include <Emodel.hh> 7#include <Emodel.hh>
@@ -8,6 +9,7 @@
8 9
9#include <functional> 10#include <functional>
10#include <memory> 11#include <memory>
12#include <queue>
11#include <string> 13#include <string>
12#include <vector> 14#include <vector>
13 15
@@ -29,7 +31,7 @@ struct tag
29class file_scanner 31class file_scanner
30{ 32{
31public: 33public:
32 file_scanner(std::function<void(const tag&)> media_file_add_cb); 34 file_scanner(std::function<void(tag)> media_file_add_cb);
33 ~file_scanner(); 35 ~file_scanner();
34 36
35 void start(); 37 void start();
@@ -41,9 +43,18 @@ private:
41 bool file_status(eio::model &file_model, void *info); 43 bool file_status(eio::model &file_model, void *info);
42 void check_media_file(const std::string &path); 44 void check_media_file(const std::string &path);
43 45
46 void process();
47 void process_pending_files();
48 void process_file(const std::string &path);
49
44private: 50private:
45 std::vector<std::unique_ptr<eio::model>> files; 51 std::vector<std::unique_ptr<eio::model>> files;
46 std::function<void(const tag&)> media_file_add_cb; 52 std::function<void(const tag&)> media_file_add_cb;
53 ::efl::eina::condition_variable pending_file;
54 ::efl::eina::mutex mutex;
55 ::efl::eina::thread worker;
56 bool terminated;
57 std::queue<std::string> pending_files;
47}; 58};
48 59
49} 60}