library: Implement basic path management
I can add and remove root-level directories from the library database. I do not save the database when modified, and I don't yet run an update on all the files. Signed-off-by: Anna Schumaker <schumaker.anna@gmail.com>
This commit is contained in:
parent
fc3b5db59e
commit
9ddbaf0b97
1
config
1
config
|
@ -40,6 +40,7 @@ class Config:
|
|||
self.GROUP = False
|
||||
self.IDLE = False
|
||||
self.INDEX = False
|
||||
self.LIBRARY = False
|
||||
self.TEST = TEST
|
||||
self.reconfigure()
|
||||
|
||||
|
|
|
@ -22,6 +22,15 @@ Library: (lib/library.cpp)
|
|||
When a library : Track is created, it should be added to the "Library"
|
||||
group if it is NOT a member of the banned songs group.
|
||||
|
||||
- Databases:
|
||||
enum DB_Type {
|
||||
DB_ALBUM,
|
||||
DB_ARTIST,
|
||||
DB_GENRE,
|
||||
DB_LIBRARY,
|
||||
DB_TRACK,
|
||||
};
|
||||
|
||||
- Album:
|
||||
class library :: Album : public DatabaseEntry {
|
||||
public:
|
||||
|
@ -47,8 +56,8 @@ Library: (lib/library.cpp)
|
|||
|
||||
File << name
|
||||
|
||||
- Path:
|
||||
class library :: Path : public DatabaseEntry {
|
||||
- Library:
|
||||
class library :: Library : public DatabaseEntry {
|
||||
public:
|
||||
string root_path;
|
||||
bool enabled;
|
||||
|
@ -70,6 +79,7 @@ Library: (lib/library.cpp)
|
|||
short last_day;
|
||||
unsigned int play_count;
|
||||
unsigned int length;
|
||||
|
||||
bool banned;
|
||||
string title;
|
||||
string length_str;
|
||||
|
@ -119,39 +129,33 @@ Library: (lib/library.cpp)
|
|||
happen while idle.
|
||||
|
||||
- Testing:
|
||||
A test library should be created to test adding tags and anything else.
|
||||
The command `arecord -d 10 </dev/zero | lame - -b 32 -h silence.mp3`
|
||||
will create a 10 second long, silent mp3 file. Do something with this
|
||||
command and figure out how to apply tags!
|
||||
The script tests/library/gen_library.sh will create a sample library
|
||||
in the /tmp/ directory for testing purposes. All the track files are
|
||||
complete silence, but the script will fake up tags for each file.
|
||||
|
||||
- API
|
||||
library :: init();
|
||||
void library :: init();
|
||||
Initialize databases and read files from disk. Fill out
|
||||
groups and prepare filter as tracks are read.
|
||||
|
||||
library :: add_path(string dir);
|
||||
Add new row to paths table, update
|
||||
bool library :: add_path(string dir);
|
||||
If dir is not a directory:
|
||||
return false
|
||||
|
||||
library :: del_path(unsigned int lib_id);
|
||||
Invalidate a path row and all tracks owned by that path
|
||||
Add new row to the library_db table, begin an update only
|
||||
on the new path.
|
||||
return true
|
||||
|
||||
library :: update_path(lib_id);
|
||||
Update the given library path, if valid.
|
||||
void library :: del_path(unsigned int lib_id);
|
||||
Invalidate a library_db row and all tracks owned by that path
|
||||
|
||||
struct Track library :: resolve(track_id)
|
||||
void library :: update_path(lib_id);
|
||||
Update the given library_db row, if valid.
|
||||
|
||||
struct Track library :: lookup(track_id)
|
||||
Fill out a Track structure for the provided track_id
|
||||
|
||||
const Database<library :: Album> &library :: get_albums();
|
||||
Return the album database.
|
||||
|
||||
const Database<library :: Artist> &library :: get_artists();
|
||||
Return the artist database.
|
||||
|
||||
const Database<library :: Genre> &library :: get_genres();
|
||||
Return the genre database.
|
||||
|
||||
const Database<library :: Library> &library :: get_libraries();
|
||||
Return the library database.
|
||||
|
||||
const Database<library :: Track> &library :: get_tracks();
|
||||
Return the track database.
|
||||
#ifdef CONFIG_DEBUG
|
||||
void library :: print_db(DB_Type);
|
||||
Print the database corresponding to DB_Type
|
||||
endif /* CONFIG_DEBUG */
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright 2013 (c) Anna Schumaker.
|
||||
*/
|
||||
#ifndef OCARINA_LIBRARY_H
|
||||
#define OCARINA_LIBRARY_H
|
||||
|
||||
#include <database.h>
|
||||
#include <string>
|
||||
|
||||
namespace library
|
||||
{
|
||||
|
||||
enum DB_Type {
|
||||
DB_ALBUM,
|
||||
DB_ARTIST,
|
||||
DB_GENRE,
|
||||
DB_LIBRARY,
|
||||
DB_TRACK,
|
||||
};
|
||||
|
||||
class Library : public DatabaseEntry {
|
||||
public:
|
||||
std::string root_path;
|
||||
bool enabled;
|
||||
|
||||
Library(const std::string &, bool);
|
||||
void read(File &);
|
||||
void write(File &);
|
||||
#ifdef CONFIG_DEBUG
|
||||
void print();
|
||||
#endif /* CONFIG_DEBUG */
|
||||
bool operator==(Library &);
|
||||
};
|
||||
|
||||
|
||||
bool add_path(const std::string &);
|
||||
void del_path(unsigned int);
|
||||
#ifdef CONFIG_DEBUG
|
||||
void print_db(DB_Type);
|
||||
void reset();
|
||||
#endif /* CONFIG_DEBUG */
|
||||
};
|
||||
|
||||
#endif /* OCARINA_LIBRARY_H */
|
|
@ -2,7 +2,7 @@
|
|||
Import("env", "CONFIG")
|
||||
|
||||
class Module:
|
||||
def __init__(self, source = None, package = "", depends = ""):
|
||||
def __init__(self, source = None, package = "", depends = []):
|
||||
self.depends = depends
|
||||
self.package = package
|
||||
self.source = source
|
||||
|
@ -15,12 +15,13 @@ modules = {
|
|||
# #
|
||||
###########################
|
||||
|
||||
"DATABASE" : Module("database.cpp", depends = "FILE"),
|
||||
"DATABASE" : Module("database.cpp", depends = [ "FILE" ]),
|
||||
"FILE" : Module("file.cpp", package = "glib-2.0"),
|
||||
"FILTER" : Module("filter.cpp", depends = "INDEX"),
|
||||
"GROUP" : Module("group.cpp", depends = "INDEX"),
|
||||
"FILTER" : Module("filter.cpp", depends = [ "INDEX" ]),
|
||||
"GROUP" : Module("group.cpp", depends = [ "INDEX" ]),
|
||||
"IDLE" : Module("idle.cpp"),
|
||||
"INDEX" : Module("index.cpp", depends = "FILE"),
|
||||
"INDEX" : Module("index.cpp", depends = [ "FILE" ]),
|
||||
"LIBRARY" : Module("library.cpp", depends = [ "DATABASE", "IDLE" ]),
|
||||
|
||||
###########################
|
||||
###########################
|
||||
|
@ -38,8 +39,10 @@ def resolve(name):
|
|||
CONFIG.package(mod.package)
|
||||
|
||||
res = [ env.Object(mod.source) ]
|
||||
if CONFIG.__dict__.get(mod.depends) == False:
|
||||
res += resolve(mod.depends)
|
||||
|
||||
for dep in mod.depends:
|
||||
if CONFIG.__dict__.get(dep) == False:
|
||||
res += resolve(dep)
|
||||
|
||||
return res
|
||||
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2013 (c) Anna Schumaker.
|
||||
*/
|
||||
#include <library.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
|
||||
static Database<library :: Library> library_db("library.db", DB_NORMAL);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* library :: Library: Basic information about each directory in the library
|
||||
*/
|
||||
|
||||
library :: Library :: Library(const std::string &path, bool is_enabled)
|
||||
: root_path(path), enabled(is_enabled)
|
||||
{
|
||||
}
|
||||
|
||||
void library :: Library :: read(File &f)
|
||||
{
|
||||
}
|
||||
|
||||
void library :: Library :: write(File &f)
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
void library :: Library :: print()
|
||||
{
|
||||
:: print("%s", root_path.c_str());
|
||||
if (enabled == true)
|
||||
:: print(" (enabled)");
|
||||
else
|
||||
:: print(" (disabled)");
|
||||
}
|
||||
#endif /* CONFIG_DEBUG */
|
||||
|
||||
bool library :: Library :: operator==(library :: Library &rhs)
|
||||
{
|
||||
return root_path == rhs.root_path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* API used by the GUI begins here
|
||||
*/
|
||||
|
||||
bool library :: add_path(const std::string &dir)
|
||||
{
|
||||
if (g_file_test(dir.c_str(), G_FILE_TEST_IS_DIR) == false)
|
||||
return false;
|
||||
|
||||
library_db.insert(library :: Library(dir, true));
|
||||
return true;
|
||||
}
|
||||
|
||||
void library :: del_path(unsigned int id)
|
||||
{
|
||||
library_db.remove(id);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DEBUG
|
||||
void library :: print_db(DB_Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case DB_LIBRARY:
|
||||
library_db.print();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void library :: reset()
|
||||
{
|
||||
library_db.clear();
|
||||
}
|
||||
#endif /* CONFIG_DEBUG */
|
|
@ -57,7 +57,7 @@ rm_test_dir(xdg.BaseDirectory.xdg_data_home);
|
|||
#
|
||||
# Read SConscript files
|
||||
#
|
||||
scripts = [ "database", "file", "filter", "group", "idle", "index", "print" ]
|
||||
scripts = [ "database", "file", "filter", "group", "idle", "index", "library", "print" ]
|
||||
for s in scripts:
|
||||
CONFIG.reset(TEST = True)
|
||||
SConscript("%s/Sconscript" % s)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/python
|
||||
Import("Test", "CONFIG")
|
||||
|
||||
CONFIG.LIBRARY = True
|
||||
|
||||
Test("library", "library.cpp")
|
|
@ -29,6 +29,11 @@ function gen_tracks()
|
|||
for i in $(seq 10); do
|
||||
track="Track $i"
|
||||
let remainder=$i%4
|
||||
out="/tmp/$library/$artist/$album/$i - $track.ogg"
|
||||
|
||||
if [ -f "$out" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
case $remainder in
|
||||
0) OGG="1.ogg" ;;
|
||||
|
@ -74,3 +79,5 @@ for i in $(seq 0 4); do
|
|||
echo "Generating library: $i"
|
||||
gen_artists $i
|
||||
done
|
||||
|
||||
touch /tmp/library/file
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright 2013 (c) Anna Schumaker.
|
||||
*/
|
||||
#include <library.h>
|
||||
#include <print.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void gen_library()
|
||||
{
|
||||
system("tests/library/gen_library.sh");
|
||||
print("\n");
|
||||
}
|
||||
|
||||
void test_add_dir(const std::string &test, const std::string &dir, bool expected)
|
||||
{
|
||||
print("Test %s: ", test.c_str());
|
||||
if (library :: add_path(dir.c_str()) == expected)
|
||||
print("PASSED\n");
|
||||
else
|
||||
print("FAILED\n");
|
||||
library :: print_db(library :: DB_LIBRARY);
|
||||
}
|
||||
|
||||
void test_del_dir(const std::string &test, const unsigned int path_id)
|
||||
{
|
||||
print("Test %s\n", test.c_str());
|
||||
library :: del_path(path_id);
|
||||
library :: print_db(library :: DB_LIBRARY);
|
||||
}
|
||||
|
||||
/* Add paths library that SHOULD fail */
|
||||
void test_0()
|
||||
{
|
||||
test_add_dir("0a", "/tmp/library/error", false);
|
||||
test_add_dir("0b", "/tmp/library/file", false);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
/* Simple library path operations */
|
||||
void test_1()
|
||||
{
|
||||
test_add_dir("1a", "/tmp/library/0", true);
|
||||
library :: del_path(0);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
/* Test multiple paths */
|
||||
void test_2()
|
||||
{
|
||||
library :: reset();
|
||||
test_add_dir("2a", "/tmp/library/0", true);
|
||||
test_add_dir("2b", "/tmp/library/1", true);
|
||||
test_add_dir("2c", "/tmp/library/2", true);
|
||||
|
||||
test_del_dir("2d", 1);
|
||||
test_del_dir("2e", 0);
|
||||
test_del_dir("2f", 2);
|
||||
print("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
gen_library();
|
||||
|
||||
test_0();
|
||||
test_1();
|
||||
test_2();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue