summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuan A. Suarez Romero <jasuarez@igalia.com>2010-03-12 17:29:05 +0100
committerJuan A. Suarez Romero <jasuarez@igalia.com>2010-03-12 17:29:05 +0100
commitf40884bcc71e72433cc82739489e8000ca25e266 (patch)
treef2637fdb61f2ebee6db5f5788599af12100404a3
parentcdf891968a8335cd96c712c6ae24b076531c2ade (diff)
parentac7af0ab66e0a28ec2431a2b6abc0f1934cf2642 (diff)
downloadgrilo-f40884bcc71e72433cc82739489e8000ca25e266.tar.gz
Merge commit 'grilo-0.1.4' into debian
-rw-r--r--Makefile.am2
-rw-r--r--NEWS15
-rw-r--r--TODO13
-rwxr-xr-xautogen.sh1
-rw-r--r--bindings/vala/grilo-0.1.vapi149
-rw-r--r--bindings/vala/grilo-0.1/grilo-0.1-custom.vala25
-rw-r--r--bindings/vala/grilo-0.1/grilo-0.1.gi235
-rw-r--r--configure.ac11
-rw-r--r--doc/brainstorming/itoral-initial-brainstorming.txt210
-rw-r--r--doc/brainstorming/jasuarez-initial-brainstorming.txt73
-rw-r--r--doc/brainstorming/to-be-discussed.txt51
-rw-r--r--doc/reference/grilo-docs.sgml17
-rw-r--r--grilo-0.1-uninstalled.pc.in2
-rw-r--r--m4/introspection.m494
-rw-r--r--src/Makefile.am57
-rw-r--r--src/content/Makefile.am39
-rw-r--r--src/content/grl-content-audio.h114
-rw-r--r--src/content/grl-content-box.c132
-rw-r--r--src/content/grl-content-box.h79
-rw-r--r--src/content/grl-content-image.h95
-rw-r--r--src/content/grl-content-media.h161
-rw-r--r--src/content/grl-content-video.c89
-rw-r--r--src/content/grl-content-video.h104
-rw-r--r--src/content/grl-content.c468
-rw-r--r--src/content/grl-content.h115
-rw-r--r--src/data/grl-config.c96
-rw-r--r--src/data/grl-config.h200
-rw-r--r--src/data/grl-data.c468
-rw-r--r--src/data/grl-data.h122
-rw-r--r--src/data/grl-media-audio.c (renamed from src/content/grl-content-audio.c)40
-rw-r--r--src/data/grl-media-audio.h114
-rw-r--r--src/data/grl-media-box.c148
-rw-r--r--src/data/grl-media-box.h85
-rw-r--r--src/data/grl-media-image.c (renamed from src/content/grl-content-image.c)50
-rw-r--r--src/data/grl-media-image.h95
-rw-r--r--src/data/grl-media-video.c98
-rw-r--r--src/data/grl-media-video.h151
-rw-r--r--src/data/grl-media.c (renamed from src/content/grl-content-media.c)73
-rw-r--r--src/data/grl-media.h389
-rw-r--r--src/grilo.h13
-rw-r--r--src/grl-error.h1
-rw-r--r--src/grl-media-source.c224
-rw-r--r--src/grl-media-source.h167
-rw-r--r--src/grl-metadata-key.h12
-rw-r--r--src/grl-metadata-source.c370
-rw-r--r--src/grl-metadata-source.h92
-rw-r--r--src/grl-plugin-registry.c198
-rw-r--r--src/grl-plugin-registry.h79
-rw-r--r--tools/grilo-test-ui/Makefile.am2
-rw-r--r--tools/grilo-test-ui/main.c156
-rw-r--r--tools/js/testGrilo.js68
-rw-r--r--tools/vala/Makefile.am2
-rw-r--r--tools/vala/grilo-test.vala4
53 files changed, 3737 insertions, 2131 deletions
diff --git a/Makefile.am b/Makefile.am
index ae0a4a9..c4507f5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -33,6 +33,8 @@ MAINTAINERCLEANFILES = \
DISTCLEANFILES = $(MAINTAINERCLEANFILES)
+EXTRA_DIST = ./m4/introspection.m4
+
DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
distclean-local:
diff --git a/NEWS b/NEWS
index 2473060..94002fa 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,18 @@
+NEW in 0.1.4
+============
+
+ * Improved documentation
+ * General improvements in code
+ * Added configuration api for plugins
+ * Refactored content classes
+ * Added introspection support in build system, and a Javascript sample that
+ uses it
+ * Aded new api to modify content
+ * Added new keys: play-count, last-played and last-position
+ * Renamed grl_plugins_get_sources_by_capabilities() to
+ grl_plugins_get_sources_by_operations()
+
+
NEW in 0.1.3
============
diff --git a/TODO b/TODO
index 0dca3fb..472d422 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,14 @@
- Handle GRL_RESOLVE_FULL when a certain key can be resolved by several plugins.
- -> Use rankings
-> Use alternative plugins if the selected one fails to resolve the key.
+- Consider using GAsync callback interface for callback implementations.
+ -> Also check issues for binding development related to this.
+- Consider using the Ethos GObject plugin framework to replace our current
+in-house plugin system.
+- Implement set_metadata interface.
+ -> Think how this would work out with plugins (i.e. a plugin for storing
+ratings, play-counts, etc).
+- Multiple-plugin operations (i.e. search by text on all plugins).
+- Python bindings.
+- Consider a more flexible post-processing mechanism for query
+operations (browse, search, etc).
+ -> We have to figure out if that's really necessary.
diff --git a/autogen.sh b/autogen.sh
index 63b9040..7d528c0 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -5,6 +5,7 @@ srcdir=`dirname $0`
test -z "$srcdir" && srcdir=.
REQUIRED_AUTOMAKE_VERSION=1.8
+ACLOCAL_FLAGS="-I m4"
PKG_NAME="grilo"
(test -f $srcdir/configure.ac) || {
diff --git a/bindings/vala/grilo-0.1.vapi b/bindings/vala/grilo-0.1.vapi
index 54af3c9..80d18cd 100644
--- a/bindings/vala/grilo-0.1.vapi
+++ b/bindings/vala/grilo-0.1.vapi
@@ -3,9 +3,16 @@
[CCode (cprefix = "Grl", lower_case_cprefix = "grl_")]
namespace Grl {
[CCode (cheader_filename = "grilo.h")]
- public class Content : GLib.Object {
+ public class Config : Grl.Data {
[CCode (has_construct_function = false)]
- public Content ();
+ public Config ();
+ [CCode (has_construct_function = false)]
+ public Config.for_plugin (string plugin);
+ }
+ [CCode (cheader_filename = "grilo.h")]
+ public class Data : GLib.Object {
+ [CCode (has_construct_function = false)]
+ public Data ();
public void add (Grl.KeyID key);
public GLib.Value @get (Grl.KeyID key);
public float get_float (Grl.KeyID key);
@@ -23,32 +30,19 @@ namespace Grl {
public void set_string (Grl.KeyID key, string strvalue);
public bool overwrite { get; set; }
}
+ [Compact]
[CCode (cheader_filename = "grilo.h")]
- public class ContentAudio : Grl.ContentMedia {
- [CCode (type = "GrlContentMedia*", has_construct_function = false)]
- public ContentAudio ();
- }
- [CCode (cheader_filename = "grilo.h")]
- public class ContentBox : Grl.ContentMedia {
- [CCode (type = "GrlContentMedia*", has_construct_function = false)]
- public ContentBox ();
- public int get_childcount ();
- public void set_childcount (int childcount);
- }
- [CCode (cheader_filename = "grilo.h")]
- public class ContentImage : Grl.ContentMedia {
- [CCode (type = "GrlContentMedia*", has_construct_function = false)]
- public ContentImage ();
- public void set_size (int width, int height);
+ public class KeyID {
}
[CCode (cheader_filename = "grilo.h")]
- public class ContentMedia : Grl.Content {
+ public class Media : Grl.Data {
[CCode (has_construct_function = false)]
- public ContentMedia ();
+ public Media ();
public unowned string get_author ();
public unowned string get_date ();
public unowned string get_description ();
public int get_duration ();
+ public unowned string get_id ();
public unowned string get_mime ();
public unowned string get_rating ();
public unowned string get_site ();
@@ -56,17 +50,36 @@ namespace Grl {
public unowned string get_thumbnail ();
public unowned string get_title ();
public unowned string get_url ();
+ public void set_author (string url);
+ public void set_date (string date);
+ public void set_description (string description);
+ public void set_duration (int duration);
+ public void set_id (string id);
+ public void set_mime (string mime);
public void set_rating (string rating, string max);
+ public void set_site (string site);
+ public void set_source (string source);
+ public void set_thumbnail (string thumbnail);
+ public void set_title (string title);
+ public void set_url (string url);
}
[CCode (cheader_filename = "grilo.h")]
- public class ContentVideo : Grl.ContentMedia {
- [CCode (type = "GrlContentMedia*", has_construct_function = false)]
- public ContentVideo ();
- public void set_size (int width, int height);
+ public class MediaAudio : Grl.Media {
+ [CCode (type = "GrlMedia*", has_construct_function = false)]
+ public MediaAudio ();
}
- [Compact]
[CCode (cheader_filename = "grilo.h")]
- public class KeyID {
+ public class MediaBox : Grl.Media {
+ [CCode (type = "GrlMedia*", has_construct_function = false)]
+ public MediaBox ();
+ public int get_childcount ();
+ public void set_childcount (int childcount);
+ }
+ [CCode (cheader_filename = "grilo.h")]
+ public class MediaImage : Grl.Media {
+ [CCode (type = "GrlMedia*", has_construct_function = false)]
+ public MediaImage ();
+ public void set_size (int width, int height);
}
[CCode (cheader_filename = "grilo.h")]
public class MediaPlugin : GLib.Object {
@@ -75,22 +88,23 @@ namespace Grl {
public unowned string get_id ();
public unowned string get_license ();
public unowned string get_name ();
+ public int get_rank ();
public unowned string get_site ();
public unowned string get_version ();
}
[CCode (cheader_filename = "grilo.h")]
public class MediaSource : Grl.MetadataSource {
- public virtual void browse (Grl.ContentMedia container, GLib.List keys, uint skip, uint count, Grl.MetadataResolutionFlags flags, Grl.MediaSourceResultCb callback);
+ public virtual void browse (Grl.Media container, GLib.List keys, uint skip, uint count, Grl.MetadataResolutionFlags flags, Grl.MediaSourceResultCb callback);
public virtual void cancel (uint operation_id);
public uint get_auto_split_threshold ();
public void* get_operation_data (uint operation_id);
- public virtual void metadata (Grl.ContentMedia media, GLib.List keys, Grl.MetadataResolutionFlags flags, Grl.MediaSourceMetadataCb callback);
+ public virtual void metadata (Grl.Media media, GLib.List keys, Grl.MetadataResolutionFlags flags, Grl.MediaSourceMetadataCb callback);
public virtual void query (string query, GLib.List keys, uint skip, uint count, Grl.MetadataResolutionFlags flags, Grl.MediaSourceResultCb callback);
- public virtual void remove (Grl.ContentMedia media, Grl.MediaSourceRemoveCb callback);
+ public virtual void remove (Grl.Media media, Grl.MediaSourceRemoveCb callback);
public virtual void search (string text, GLib.List keys, uint skip, uint count, Grl.MetadataResolutionFlags flags, Grl.MediaSourceResultCb callback);
public void set_auto_split_threshold (uint threshold);
public void set_operation_data (uint operation_id, void* data);
- public virtual void store (Grl.ContentBox parent, Grl.ContentMedia media, Grl.MediaSourceStoreCb callback);
+ public virtual void store (Grl.MediaBox parent, Grl.Media media, Grl.MediaSourceStoreCb callback);
public uint auto_split_threshold { get; set; }
}
[Compact]
@@ -98,7 +112,7 @@ namespace Grl {
public class MediaSourceBrowseSpec {
public uint browse_id;
public weak Grl.MediaSourceResultCb callback;
- public weak Grl.ContentMedia container;
+ public weak Grl.Media container;
public uint count;
public Grl.MetadataResolutionFlags flags;
public weak GLib.List keys;
@@ -112,7 +126,7 @@ namespace Grl {
public weak Grl.MediaSourceMetadataCb callback;
public Grl.MetadataResolutionFlags flags;
public weak GLib.List keys;
- public weak Grl.ContentMedia media;
+ public weak Grl.Media media;
public weak Grl.MediaSource source;
public void* user_data;
}
@@ -133,7 +147,7 @@ namespace Grl {
[CCode (cheader_filename = "grilo.h")]
public class MediaSourceRemoveSpec {
public weak Grl.MediaSourceRemoveCb callback;
- public weak Grl.ContentMedia media;
+ public weak Grl.Media media;
public weak string media_id;
public weak Grl.MediaSource source;
public void* user_data;
@@ -155,11 +169,17 @@ namespace Grl {
[CCode (cheader_filename = "grilo.h")]
public class MediaSourceStoreSpec {
public weak Grl.MediaSourceStoreCb callback;
- public weak Grl.ContentMedia media;
- public weak Grl.ContentBox parent;
+ public weak Grl.Media media;
+ public weak Grl.MediaBox parent;
public weak Grl.MediaSource source;
public void* user_data;
}
+ [CCode (cheader_filename = "grilo.h")]
+ public class MediaVideo : Grl.Media {
+ [CCode (type = "GrlMedia*", has_construct_function = false)]
+ public MediaVideo ();
+ public void set_size (int width, int height);
+ }
[Compact]
[CCode (cheader_filename = "grilo.h")]
public class MetadataKey {
@@ -176,7 +196,7 @@ namespace Grl {
public unowned string get_id ();
public unowned string get_name ();
public virtual unowned GLib.List key_depends (Grl.KeyID key_id);
- public virtual void resolve (GLib.List keys, Grl.ContentMedia media, uint flags, Grl.MetadataSourceResolveCb callback);
+ public virtual void resolve (GLib.List keys, Grl.Media media, uint flags, Grl.MetadataSourceResolveCb callback);
public virtual unowned GLib.List slow_keys ();
public virtual unowned GLib.List supported_keys ();
public virtual Grl.SupportedOps supported_operations ();
@@ -193,7 +213,7 @@ namespace Grl {
public weak Grl.MetadataSourceResolveCb callback;
public uint flags;
public weak GLib.List keys;
- public weak Grl.ContentMedia media;
+ public weak Grl.Media media;
public weak Grl.MetadataSource source;
public void* user_data;
}
@@ -212,6 +232,7 @@ namespace Grl {
public weak string id;
public weak string license;
public weak string name;
+ public int rank;
public weak string site;
public weak string version;
}
@@ -219,13 +240,15 @@ namespace Grl {
public class PluginRegistry : GLib.Object {
public static unowned Grl.PluginRegistry get_instance ();
[CCode (array_length = false)]
- public unowned Grl.MediaPlugin[] get_sources ();
+ public unowned Grl.MediaPlugin[] get_sources (bool ranked);
+ public unowned Grl.MediaPlugin get_sources_by_operations (Grl.SupportedOps ops, bool ranked);
public bool load (string path);
public bool load_all ();
public bool load_directory (string path);
public unowned Grl.MetadataKey lookup_metadata_key (Grl.KeyID key_id);
public unowned Grl.MediaPlugin lookup_source (string source_id);
public bool register_source (Grl.PluginInfo plugin, Grl.MediaPlugin source);
+ public void set_config (Grl.Config config);
public void unload (string plugin_id);
public void unregister_source (Grl.MediaPlugin source);
public virtual signal void source_added (Grl.MediaPlugin p0);
@@ -238,6 +261,14 @@ namespace Grl {
IDLE_RELAY,
FAST_ONLY
}
+ [CCode (cprefix = "GRL_PLUGIN_RANK_", has_type_id = false, cheader_filename = "grilo.h")]
+ public enum PluginRank {
+ LOWEST,
+ LOW,
+ DEFAULT,
+ HIGH,
+ HIGHEST
+ }
[CCode (cprefix = "GRL_OP_", has_type_id = false, cheader_filename = "grilo.h")]
public enum SupportedOps {
NONE,
@@ -262,15 +293,39 @@ namespace Grl {
REMOVE_FAILED,
}
[CCode (cheader_filename = "grilo.h", instance_pos = 2.1)]
- public delegate void MediaSourceMetadataCb (Grl.MediaSource source, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MediaSourceMetadataCb (Grl.MediaSource source, Grl.Media? media, GLib.Error error);
[CCode (cheader_filename = "grilo.h", instance_pos = 2.1)]
- public delegate void MediaSourceRemoveCb (Grl.MediaSource source, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MediaSourceRemoveCb (Grl.MediaSource source, Grl.Media? media, GLib.Error error);
[CCode (cheader_filename = "grilo.h", instance_pos = 4.1)]
- public delegate void MediaSourceResultCb (Grl.MediaSource source, uint browse_id, Grl.ContentMedia? media, uint remaining, GLib.Error error);
+ public delegate void MediaSourceResultCb (Grl.MediaSource source, uint browse_id, Grl.Media? media, uint remaining, GLib.Error? error);
[CCode (cheader_filename = "grilo.h", instance_pos = 4.1)]
- public delegate void MediaSourceStoreCb (Grl.MediaSource source, Grl.ContentBox parent, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MediaSourceStoreCb (Grl.MediaSource source, Grl.MediaBox? parent, Grl.Media? media, GLib.Error? error);
[CCode (cheader_filename = "grilo.h", instance_pos = 2.1)]
- public delegate void MetadataSourceResolveCb (Grl.MetadataSource source, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MetadataSourceResolveCb (Grl.MetadataSource source, Grl.Media? media, GLib.Error? error);
+ [CCode (cheader_filename = "grilo.h")]
+ public const int CONFIG_KEY_APIKEY;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_APIKEY_DESC;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_APIKEY_NAME;
+ [CCode (cheader_filename = "grilo.h")]
+ public const int CONFIG_KEY_APISECRET;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_APISECRET_DESC;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_APISECRET_NAME;
+ [CCode (cheader_filename = "grilo.h")]
+ public const int CONFIG_KEY_APITOKEN;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_APITOKEN_DESC;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_APITOKEN_NAME;
+ [CCode (cheader_filename = "grilo.h")]
+ public const int CONFIG_KEY_PLUGIN;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_PLUGIN_DESC;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string CONFIG_KEY_PLUGIN_NAME;
[CCode (cheader_filename = "grilo.h")]
public const string KEYID_FORMAT;
[CCode (cheader_filename = "grilo.h")]
@@ -292,6 +347,12 @@ namespace Grl {
[CCode (cheader_filename = "grilo.h")]
public const string METADATA_KEY_AUTHOR_NAME;
[CCode (cheader_filename = "grilo.h")]
+ public const int METADATA_KEY_BITRATE;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string METADATA_KEY_BITRATE_DESC;
+ [CCode (cheader_filename = "grilo.h")]
+ public const string METADATA_KEY_BITRATE_NAME;
+ [CCode (cheader_filename = "grilo.h")]
public const int METADATA_KEY_CHILDCOUNT;
[CCode (cheader_filename = "grilo.h")]
public const string METADATA_KEY_CHILDCOUNT_DESC;
@@ -398,5 +459,7 @@ namespace Grl {
[CCode (cheader_filename = "grilo.h")]
public const string PLUGIN_PATH_VAR;
[CCode (cheader_filename = "grilo.h")]
+ public const string PLUGIN_RANKS_VAR;
+ [CCode (cheader_filename = "grilo.h")]
public static void log_init (string domains);
}
diff --git a/bindings/vala/grilo-0.1/grilo-0.1-custom.vala b/bindings/vala/grilo-0.1/grilo-0.1-custom.vala
index a24b35a..39f57ed 100644
--- a/bindings/vala/grilo-0.1/grilo-0.1-custom.vala
+++ b/bindings/vala/grilo-0.1/grilo-0.1-custom.vala
@@ -1,5 +1,6 @@
namespace Grl {
- public class ContentMedia {
+ public class Media {
+ public unowned string get_id ();
public unowned string get_url ();
public unowned string get_author ();
public unowned string get_title ();
@@ -11,16 +12,28 @@ namespace Grl {
public unowned string get_mime ();
public unowned string get_rating ();
public int get_duration ();
+
+ public void set_id (string id);
+ public void set_url (string url);
+ public void set_author (string url);
+ public void set_title (string title);
+ public void set_description (string description);
+ public void set_source (string source);
+ public void set_thumbnail (string thumbnail);
+ public void set_site (string site);
+ public void set_duration (int duration);
+ public void set_date (string date);
+ public void set_mime (string mime);
}
[CCode (instance_pos = 2.1)]
- public delegate void MediaSourceMetadataCb (Grl.MediaSource source, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MediaSourceMetadataCb (MediaSource source, Media? media, GLib.Error error);
[CCode (instance_pos = 2.1)]
- public delegate void MediaSourceRemoveCb (Grl.MediaSource source, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MediaSourceRemoveCb (MediaSource source, Media? media, GLib.Error error);
[CCode (instance_pos = 4.1)]
- public delegate void MediaSourceResultCb (Grl.MediaSource source, uint browse_id, Grl.ContentMedia? media, uint remaining, GLib.Error? error);
+ public delegate void MediaSourceResultCb (MediaSource source, uint browse_id, Media? media, uint remaining, GLib.Error? error);
[CCode (instance_pos = 4.1)]
- public delegate void MediaSourceStoreCb (Grl.MediaSource source, Grl.ContentBox parent, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MediaSourceStoreCb (MediaSource source, MediaBox? parent, Media? media, GLib.Error? error);
[CCode (instance_pos = 2.1)]
- public delegate void MetadataSourceResolveCb (Grl.MetadataSource source, Grl.ContentMedia? media, GLib.Error error);
+ public delegate void MetadataSourceResolveCb (MetadataSource source, Media? media, GLib.Error? error);
}
diff --git a/bindings/vala/grilo-0.1/grilo-0.1.gi b/bindings/vala/grilo-0.1/grilo-0.1.gi
index 36ea84f..ef5bab3 100644
--- a/bindings/vala/grilo-0.1/grilo-0.1.gi
+++ b/bindings/vala/grilo-0.1/grilo-0.1.gi
@@ -11,7 +11,7 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="user_data" type="gpointer"/>
<parameter name="error" type="GError*"/>
</parameters>
@@ -20,7 +20,7 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="user_data" type="gpointer"/>
<parameter name="error" type="GError*"/>
</parameters>
@@ -30,7 +30,7 @@
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
<parameter name="browse_id" type="guint"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="remaining" type="guint"/>
<parameter name="user_data" type="gpointer"/>
<parameter name="error" type="GError*"/>
@@ -40,8 +40,8 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="parent" type="GrlContentBox*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="parent" type="GrlMediaBox*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="user_data" type="gpointer"/>
<parameter name="error" type="GError*"/>
</parameters>
@@ -50,7 +50,7 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMetadataSource*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="user_data" type="gpointer"/>
<parameter name="error" type="GError*"/>
</parameters>
@@ -60,7 +60,7 @@
<struct name="GrlMediaSourceBrowseSpec">
<field name="source" type="GrlMediaSource*"/>
<field name="browse_id" type="guint"/>
- <field name="container" type="GrlContentMedia*"/>
+ <field name="container" type="GrlMedia*"/>
<field name="keys" type="GList*"/>
<field name="skip" type="guint"/>
<field name="count" type="guint"/>
@@ -70,7 +70,7 @@
</struct>
<struct name="GrlMediaSourceMetadataSpec">
<field name="source" type="GrlMediaSource*"/>
- <field name="media" type="GrlContentMedia*"/>
+ <field name="media" type="GrlMedia*"/>
<field name="keys" type="GList*"/>
<field name="flags" type="GrlMetadataResolutionFlags"/>
<field name="callback" type="GrlMediaSourceMetadataCb"/>
@@ -90,7 +90,7 @@
<struct name="GrlMediaSourceRemoveSpec">
<field name="source" type="GrlMediaSource*"/>
<field name="media_id" type="gchar*"/>
- <field name="media" type="GrlContentMedia*"/>
+ <field name="media" type="GrlMedia*"/>
<field name="callback" type="GrlMediaSourceRemoveCb"/>
<field name="user_data" type="gpointer"/>
</struct>
@@ -107,8 +107,8 @@
</struct>
<struct name="GrlMediaSourceStoreSpec">
<field name="source" type="GrlMediaSource*"/>
- <field name="parent" type="GrlContentBox*"/>
- <field name="media" type="GrlContentMedia*"/>
+ <field name="parent" type="GrlMediaBox*"/>
+ <field name="media" type="GrlMedia*"/>
<field name="callback" type="GrlMediaSourceStoreCb"/>
<field name="user_data" type="gpointer"/>
</struct>
@@ -126,7 +126,7 @@
<struct name="GrlMetadataSourceResolveSpec">
<field name="source" type="GrlMetadataSource*"/>
<field name="keys" type="GList*"/>
- <field name="media" type="GrlContentMedia*"/>
+ <field name="media" type="GrlMedia*"/>
<field name="flags" type="guint"/>
<field name="callback" type="GrlMetadataSourceResolveCb"/>
<field name="user_data" type="gpointer"/>
@@ -144,6 +144,7 @@
<field name="author" type="gchar*"/>
<field name="license" type="gchar*"/>
<field name="site" type="gchar*"/>
+ <field name="rank" type="gint"/>
</struct>
<enum name="GrlError">
<member name="GRL_ERROR_BROWSE_FAILED" value="1"/>
@@ -161,6 +162,13 @@
<member name="GRL_RESOLVE_IDLE_RELAY" value="2"/>
<member name="GRL_RESOLVE_FAST_ONLY" value="4"/>
</enum>
+ <enum name="GrlPluginRank">
+ <member name="GRL_PLUGIN_RANK_LOWEST" value="-64"/>
+ <member name="GRL_PLUGIN_RANK_LOW" value="-32"/>
+ <member name="GRL_PLUGIN_RANK_DEFAULT" value="0"/>
+ <member name="GRL_PLUGIN_RANK_HIGH" value="32"/>
+ <member name="GRL_PLUGIN_RANK_HIGHEST" value="64"/>
+ </enum>
<enum name="GrlSupportedOps">
<member name="GRL_OP_NONE" value="0"/>
<member name="GRL_OP_METADATA" value="1"/>
@@ -172,176 +180,174 @@
<member name="GRL_OP_STORE_PARENT" value="64"/>
<member name="GRL_OP_REMOVE" value="128"/>
</enum>
- <object name="GrlContent" parent="GObject" type-name="GrlContent" get-type="grl_content_get_type">
- <method name="add" symbol="grl_content_add">
+ <object name="GrlConfig" parent="GrlData" type-name="GrlConfig" get-type="grl_config_get_type">
+ <constructor name="new" symbol="grl_config_new">
+ <return-type type="GrlConfig*"/>
+ </constructor>
+ <constructor name="new_for_plugin" symbol="grl_config_new_for_plugin">
+ <return-type type="GrlConfig*"/>
+ <parameters>
+ <parameter name="plugin" type="gchar*"/>
+ </parameters>
+ </constructor>
+ </object>
+ <object name="GrlData" parent="GObject" type-name="GrlData" get-type="grl_data_get_type">
+ <method name="add" symbol="grl_data_add">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="get" symbol="grl_content_get">
+ <method name="get" symbol="grl_data_get">
<return-type type="GValue*"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="get_float" symbol="grl_content_get_float">
+ <method name="get_float" symbol="grl_data_get_float">
<return-type type="gfloat"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="get_int" symbol="grl_content_get_int">
+ <method name="get_int" symbol="grl_data_get_int">
<return-type type="gint"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="get_keys" symbol="grl_content_get_keys">
+ <method name="get_keys" symbol="grl_data_get_keys">
<return-type type="GList*"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
</parameters>
</method>
- <method name="get_overwrite" symbol="grl_content_get_overwrite">
+ <method name="get_overwrite" symbol="grl_data_get_overwrite">
<return-type type="gboolean"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
</parameters>
</method>
- <method name="get_string" symbol="grl_content_get_string">
+ <method name="get_string" symbol="grl_data_get_string">
<return-type type="gchar*"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="has_key" symbol="grl_content_has_key">
+ <method name="has_key" symbol="grl_data_has_key">
<return-type type="gboolean"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="key_is_known" symbol="grl_content_key_is_known">
+ <method name="key_is_known" symbol="grl_data_key_is_known">
<return-type type="gboolean"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <constructor name="new" symbol="grl_content_new">
- <return-type type="GrlContent*"/>
+ <constructor name="new" symbol="grl_data_new">
+ <return-type type="GrlData*"/>
</constructor>
- <method name="remove" symbol="grl_content_remove">
+ <method name="remove" symbol="grl_data_remove">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
</parameters>
</method>
- <method name="set" symbol="grl_content_set">
+ <method name="set" symbol="grl_data_set">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
<parameter name="value" type="GValue*"/>
</parameters>
</method>
- <method name="set_float" symbol="grl_content_set_float">
+ <method name="set_float" symbol="grl_data_set_float">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
<parameter name="floatvalue" type="gint"/>
</parameters>
</method>
- <method name="set_int" symbol="grl_content_set_int">
+ <method name="set_int" symbol="grl_data_set_int">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
<parameter name="intvalue" type="gint"/>
</parameters>
</method>
- <method name="set_overwrite" symbol="grl_content_set_overwrite">
+ <method name="set_overwrite" symbol="grl_data_set_overwrite">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="overwrite" type="gboolean"/>
</parameters>
</method>
- <method name="set_string" symbol="grl_content_set_string">
+ <method name="set_string" symbol="grl_data_set_string">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContent*"/>
+ <parameter name="data" type="GrlData*"/>
<parameter name="key" type="GrlKeyID"/>
<parameter name="strvalue" type="gchar*"/>
</parameters>
</method>
<property name="overwrite" type="gboolean" readable="1" writable="1" construct="0" construct-only="0"/>
</object>
- <object name="GrlContentAudio" parent="GrlContentMedia" type-name="GrlContentAudio" get-type="grl_content_audio_get_type">
- <constructor name="new" symbol="grl_content_audio_new">
- <return-type type="GrlContentMedia*"/>
- </constructor>
- </object>
- <object name="GrlContentBox" parent="GrlContentMedia" type-name="GrlContentBox" get-type="grl_content_box_get_type">
- <method name="get_childcount" symbol="grl_content_box_get_childcount">
- <return-type type="gint"/>
- <parameters>
- <parameter name="content" type="GrlContentBox*"/>
- </parameters>
- </method>
- <constructor name="new" symbol="grl_content_box_new">
- <return-type type="GrlContentMedia*"/>
+ <object name="GrlMedia" parent="GrlData" type-name="GrlMedia" get-type="grl_media_get_type">
+ <constructor name="new" symbol="grl_media_new">
+ <return-type type="GrlMedia*"/>
</constructor>
- <method name="set_childcount" symbol="grl_content_box_set_childcount">
+ <method name="set_rating" symbol="grl_media_set_rating">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContentBox*"/>
- <parameter name="childcount" type="gint"/>
+ <parameter name="media" type="GrlMedia*"/>
+ <parameter name="rating" type="gchar*"/>
+ <parameter name="max" type="gchar*"/>
</parameters>
</method>
</object>
- <object name="GrlContentImage" parent="GrlContentMedia" type-name="GrlContentImage" get-type="grl_content_image_get_type">
- <constructor name="new" symbol="grl_content_image_new">
- <return-type type="GrlContentMedia*"/>
+ <object name="GrlMediaAudio" parent="GrlMedia" type-name="GrlMediaAudio" get-type="grl_media_audio_get_type">
+ <constructor name="new" symbol="grl_media_audio_new">
+ <return-type type="GrlMedia*"/>
</constructor>
- <method name="set_size" symbol="grl_content_image_set_size">
- <return-type type="void"/>
+ </object>
+ <object name="GrlMediaBox" parent="GrlMedia" type-name="GrlMediaBox" get-type="grl_media_box_get_type">
+ <method name="get_childcount" symbol="grl_media_box_get_childcount">
+ <return-type type="gint"/>
<parameters>
- <parameter name="content" type="GrlContentImage*"/>
- <parameter name="width" type="gint"/>
- <parameter name="height" type="gint"/>
+ <parameter name="box" type="GrlMediaBox*"/>
</parameters>
</method>
- </object>
- <object name="GrlContentMedia" parent="GrlContent" type-name="GrlContentMedia" get-type="grl_content_media_get_type">
- <constructor name="new" symbol="grl_content_media_new">
- <return-type type="GrlContentMedia*"/>
+ <constructor name="new" symbol="grl_media_box_new">
+ <return-type type="GrlMedia*"/>
</constructor>
- <method name="set_rating" symbol="grl_content_media_set_rating">
+ <method name="set_childcount" symbol="grl_media_box_set_childcount">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContentMedia*"/>
- <parameter name="rating" type="gchar*"/>
- <parameter name="max" type="gchar*"/>
+ <parameter name="box" type="GrlMediaBox*"/>
+ <parameter name="childcount" type="gint"/>
</parameters>
</method>
</object>
- <object name="GrlContentVideo" parent="GrlContentMedia" type-name="GrlContentVideo" get-type="grl_content_video_get_type">
- <constructor name="new" symbol="grl_content_video_new">
- <return-type type="GrlContentMedia*"/>
+ <object name="GrlMediaImage" parent="GrlMedia" type-name="GrlMediaImage" get-type="grl_media_image_get_type">
+ <constructor name="new" symbol="grl_media_image_new">
+ <return-type type="GrlMedia*"/>
</constructor>
- <method name="set_size" symbol="grl_content_video_set_size">
+ <method name="set_size" symbol="grl_media_image_set_size">
<return-type type="void"/>
<parameters>
- <parameter name="content" type="GrlContentVideo*"/>
+ <parameter name="image" type="GrlMediaImage*"/>
<parameter name="width" type="gint"/>
<parameter name="height" type="gint"/>
</parameters>
@@ -378,6 +384,12 @@
<parameter name="plugin" type="GrlMediaPlugin*"/>
</parameters>
</method>
+ <method name="get_rank" symbol="grl_media_plugin_get_rank">
+ <return-type type="gint"/>
+ <parameters>
+ <parameter name="plugin" type="GrlMediaPlugin*"/>
+ </parameters>
+ </method>
<method name="get_site" symbol="grl_media_plugin_get_site">
<return-type type="gchar*"/>
<parameters>
@@ -396,7 +408,7 @@
<return-type type="guint"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="container" type="GrlContentMedia*"/>
+ <parameter name="container" type="GrlMedia*"/>
<parameter name="keys" type="GList*"/>
<parameter name="skip" type="guint"/>
<parameter name="count" type="guint"/>
@@ -429,7 +441,7 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="keys" type="GList*"/>
<parameter name="flags" type="GrlMetadataResolutionFlags"/>
<parameter name="callback" type="GrlMediaSourceMetadataCb"/>
@@ -453,7 +465,7 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="callback" type="GrlMediaSourceRemoveCb"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
@@ -490,8 +502,8 @@
<return-type type="void"/>
<parameters>
<parameter name="source" type="GrlMediaSource*"/>
- <parameter name="parent" type="GrlContentBox*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="parent" type="GrlMediaBox*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="callback" type="GrlMediaSourceStoreCb"/>
<parameter name="user_data" type="gpointer"/>
</parameters>
@@ -547,6 +559,19 @@
</parameters>
</vfunc>
</object>
+ <object name="GrlMediaVideo" parent="GrlMedia" type-name="GrlMediaVideo" get-type="grl_media_video_get_type">
+ <constructor name="new" symbol="grl_media_video_new">
+ <return-type type="GrlMedia*"/>
+ </constructor>
+ <method name="set_size" symbol="grl_media_video_set_size">
+ <return-type type="void"/>
+ <parameters>
+ <parameter name="video" type="GrlMediaVideo*"/>
+ <parameter name="width" type="gint"/>
+ <parameter name="height" type="gint"/>
+ </parameters>
+ </method>
+ </object>
<object name="GrlMetadataSource" parent="GrlMediaPlugin" type-name="GrlMetadataSource" get-type="grl_metadata_source_get_type">
<method name="filter_slow" symbol="grl_metadata_source_filter_slow">
<return-type type="GList*"/>
@@ -594,7 +619,7 @@
<parameters>
<parameter name="source" type="GrlMetadataSource*"/>
<parameter name="keys" type="GList*"/>
- <parameter name="media" type="GrlContentMedia*"/>
+ <parameter name="media" type="GrlMedia*"/>
<parameter name="flags" type="guint"/>
<parameter name="callback" type="GrlMetadataSourceResolveCb"/>
<parameter name="user_data" type="gpointer"/>
@@ -662,6 +687,15 @@
<return-type type="GrlMediaPlugin**"/>
<parameters>
<parameter name="registry" type="GrlPluginRegistry*"/>
+ <parameter name="ranked" type="gboolean"/>
+ </parameters>
+ </method>
+ <method name="get_sources_by_operations" symbol="grl_plugin_registry_get_sources_by_operations">
+ <return-type type="GrlMediaPlugin**"/>
+ <parameters>
+ <parameter name="registry" type="GrlPluginRegistry*"/>
+ <parameter name="caps" type="GrlSupportedOps"/>
+ <parameter name="ranked" type="gboolean"/>
</parameters>
</method>
<method name="load" symbol="grl_plugin_registry_load">
@@ -706,6 +740,13 @@
<parameter name="source" type="GrlMediaPlugin*"/>
</parameters>
</method>
+ <method name="set_config" symbol="grl_plugin_registry_set_config">
+ <return-type type="void"/>
+ <parameters>
+ <parameter name="registry" type="GrlPluginRegistry*"/>
+ <parameter name="config" type="GrlConfig*"/>
+ </parameters>
+ </method>
<method name="unload" symbol="grl_plugin_registry_unload">
<return-type type="void"/>
<parameters>
@@ -735,6 +776,18 @@
</parameters>
</signal>
</object>
+ <constant name="GRL_CONFIG_KEY_APIKEY" type="int" value="23"/>
+ <constant name="GRL_CONFIG_KEY_APIKEY_DESC" type="char*" value="API Key"/>
+ <constant name="GRL_CONFIG_KEY_APIKEY_NAME" type="char*" value="api-key"/>
+ <constant name="GRL_CONFIG_KEY_APISECRET" type="int" value="25"/>
+ <constant name="GRL_CONFIG_KEY_APISECRET_DESC" type="char*" value="API secret"/>
+ <constant name="GRL_CONFIG_KEY_APISECRET_NAME" type="char*" value="api-secret"/>
+ <constant name="GRL_CONFIG_KEY_APITOKEN" type="int" value="24"/>
+ <constant name="GRL_CONFIG_KEY_APITOKEN_DESC" type="char*" value="API token"/>
+ <constant name="GRL_CONFIG_KEY_APITOKEN_NAME" type="char*" value="api-token"/>
+ <constant name="GRL_CONFIG_KEY_PLUGIN" type="int" value="22"/>
+ <constant name="GRL_CONFIG_KEY_PLUGIN_DESC" type="char*" value="Plugin ID creating the sources"/>
+ <constant name="GRL_CONFIG_KEY_PLUGIN_NAME" type="char*" value="plugin"/>
<constant name="GRL_KEYID_FORMAT" type="char*" value="u"/>
<constant name="GRL_METADATA_KEY_ALBUM" type="int" value="4"/>
<constant name="GRL_METADATA_KEY_ALBUM_DESC" type="char*" value="Album the media belongs to"/>
@@ -745,6 +798,9 @@
<constant name="GRL_METADATA_KEY_AUTHOR" type="int" value="8"/>
<constant name="GRL_METADATA_KEY_AUTHOR_DESC" type="char*" value="Creator of the media"/>
<constant name="GRL_METADATA_KEY_AUTHOR_NAME" type="char*" value="author"/>
+ <constant name="GRL_METADATA_KEY_BITRATE" type="int" value="21"/>
+ <constant name="GRL_METADATA_KEY_BITRATE_DESC" type="char*" value="Media bitrate in Kbits/s"/>
+ <constant name="GRL_METADATA_KEY_BITRATE_NAME" type="char*" value="bitrate"/>
<constant name="GRL_METADATA_KEY_CHILDCOUNT" type="int" value="15"/>
<constant name="GRL_METADATA_KEY_CHILDCOUNT_DESC" type="char*" value="Number of items contained in a container"/>
<constant name="GRL_METADATA_KEY_CHILDCOUNT_NAME" type="char*" value="childcount"/>
@@ -798,5 +854,6 @@
<constant name="GRL_METADATA_KEY_WIDTH_DESC" type="char*" value="Width of media (&apos;x&apos; resolution)"/>
<constant name="GRL_METADATA_KEY_WIDTH_NAME" type="char*" value="width"/>
<constant name="GRL_PLUGIN_PATH_VAR" type="char*" value="GRL_PLUGIN_PATH"/>
+ <constant name="GRL_PLUGIN_RANKS_VAR" type="char*" value="GRL_PLUGIN_RANKS"/>
</namespace>
</api>
diff --git a/configure.ac b/configure.ac
index 41bd6bd..2eb27ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,12 +6,14 @@
# Copyright (C) 2010 Igalia S.L.. All rights reserved.
m4_define([prj_name], [grilo])
-m4_define([prj_version], [0.1.3])
+m4_define([prj_version], [0.1.4])
+m4_define([prj_gir_name], [Grilo])
AC_INIT([prj_name], [prj_version])
AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src])
AM_CONFIG_HEADER(src/config.h)
@@ -118,6 +120,12 @@ AM_CONDITIONAL(HAVE_VALA, test "x$with_vala" = "xyes")
GTK_DOC_CHECK(1.9)
# ----------------------------------------------------------
+# GOBJECT-INTROSPECTION
+# ----------------------------------------------------------
+
+GOBJECT_INTROSPECTION_CHECK([0.6.7])
+
+# ----------------------------------------------------------
# GETTEXT
# ----------------------------------------------------------
@@ -163,7 +171,6 @@ AC_CONFIG_FILES([
grilo-0.1-uninstalled.pc
grilo-0.1.pc
src/Makefile
- src/content/Makefile
tools/Makefile
tools/grilo-test-ui/Makefile
tools/vala/Makefile
diff --git a/doc/brainstorming/itoral-initial-brainstorming.txt b/doc/brainstorming/itoral-initial-brainstorming.txt
deleted file mode 100644
index db80349..0000000
--- a/doc/brainstorming/itoral-initial-brainstorming.txt
+++ /dev/null
@@ -1,210 +0,0 @@
-Interesting services (examples)
---------------------------------
-
-youtube
-flickr
-last.fm
-local
-upnp
-
-bluetooth
-podcast
-radio directory
-internet tv
-radio fm
-ipod
-sintonizador tv
-webcam
-
-------------------------------------------------------------------
-
-1.- Define basic source API
- -> browse()
- -> metadata()
- -> store()
- -> remove()
- -> auth() (i.e. youtube upload)
- -> ...
-
-2.- Sources should expose a set of properties
- -> example youtube: a property for the search text, or the category, etc
- -> Using special parameter in methods is not so flexible
- -> Basic set of well known metadata defined at fw level (author, artist, album, date, etc)
- -> A source plugin does not have to implement all metadata
-
-3.- Source must provide some metadata like the URL fo the content, but not necesarily everything.
-
-4.- Metadata providers can specialize on metadata. They register the keys the can provide in the fw.
- -> Priorities for metadata providers and sources.
-
-5.- Source should allow to create new categories (using a string parameter)
- -> youtube (using a search string)
- -> Last.FM (using a string representing a prototype author)
- -> Local Metadata (using a metadata based search string)
- -> Local FS (using a path representing a directory)
-
- -> How this string is interpreted is plugin dependent
- -> The plugin "decodes" this string and registers the new category.
- -> Provide means for the plugins to manage their categories
- -> Probably an xml file and utilities to read and write it easily.
-
-1.- Define a basic set of metadata keys
- -> author, artist, album, title, uri, etc
- -> New plugins could add new metadata that is not standar (defined at fw level) by registering it.
-
-2.- Define API
- -> Define basic APIs: browse(), getMetadata(), search() -> Similar style to the ones existing in mafw, search() would search using
- a search string (usefult for things like youtube).
- -> Provide async implementation of these APIs at the framework level (source developers do not ave to care about this).
- -> Same for result emission (framework could take care of that).
- -> Define extended APIs: upload(), createCategory(), remove(), etc
- -> creating categories is plugin specific:
- -> youtube: a category could be a search string, or a youtube category, or both
- -> Last.FM: a category could be a string representing a target artist (for artists similar to....) or similar use cases.
- -> Local Content (Metadata): A category would be a metadata query (for example artist=whatever and genre=whatever)
- -> Local Content (Filesystem): A category would be a directory in the FS.
- -> Not all the sources would allow creating new categories (exmaple: upnp, ipod, etc).
- -> store() would move content from local to source (example: uploading a video to youtube).
- -> Some operations may need auth info.
- -> Sources can store its exposed structure in an xml file, and the fw provides utilities to manage that structure.
- -> Example, youtube
- <category id="TopRated">
- <uiname>Top Rated Videos</uiname>
- <query>http://gdata.youtube.com/feeds/standardfeeds/top_rated</query>
- </category>
- <category id="RecentlyFeatured">
- <uiname>Recently Featured Videos</uiname>
- <query>http://gdata.youtube.com/feeds/standardfeeds/Recently Featured</query>
- </category>
- <category id="IgaliaVideos">
- <uiname>Videos of Igalia</uiname>
- <query>http://gdata.youtube.com/feeds/api/videos?q=igalia&v=2</query>
- </category>
- -> Not all sources have to support/implemet all operations.
- -> Sources provide info on what operations they support.
-
-3.- Metadata Providers
- -> Only provide metadata information.
- -> There must be some kind of priorities for metadata providers and/or a fallback mechanism.
- -> examples of metadata providers: ratings, lyrics, etc.
-
- Use case: youtube provides ratings, but local content does not, how would a ratings plugin work
- on a youtube source? Should we use youtube's ratings or the plugin's? Should we rate the movie
- and store the result in youtube or in the plugin? Or should both be separate things (different
- metadata keys)?
-
- What to use as key of the media here? the file name? a hash? can we obtian the hash for all sources
- easily?
-
-4.- There is a plugin registry.
- -> The registry must store info about the plugin (ala gstreamer).
- -> Plugin name, description, UI name, Author, Web, License, etc
- -> Tool for scanning available plugins (ala gst-inspect).
- -> API for accessing the available plugins, filtering them, etc
-
-5.- run the plugin queries in a separate thread? => framework should provide means to deal with this sanely.
- or use mainloop? => In any case, the framework should take care of it.
-
-6.- Plugins may expose properties to configure its behavior
- -> Example: youtube's search string
- -> Example: youtube categories for the search
- -> Example: Last.FM's string for artists similar to...
- -> Another option: the source stablishes the categories by fixing them in the xml file and provides means
- to users to create new categories by calling createCategory() method.
- -> Benefit: API not so convoluted, problem is simplified a lot and probably it is flexible enough for most cases.
- -> It fits with the browse() idea (using properties would be more in the "searchByText() idea"
-
-7.- Browse()/Search() results are stored in a playlist-style object that can be used easily (hashtables).
-
-
--------------- 8< --------------------- 8< ---------------------- 8< ------------------------
-
-RadioFM
-
- -> Escribir en un fichero dev los parametros del sintonizador ioctl().
- -> La lectura del audio se hace desde un fichero de dispositivo
- -> Nosotros tenemos que hacer proxy de eso mendiante una URL que es la que proporcionamos en un getmetadata
- -> Al inicio, el plugin podria hacer un barrido de frecuencias y exponerlas como su listado de contenidos.
-
-Flickr, Last.FM
-
- -> Similar a youtube
-
-Framework
-
- -> Implementar search en vez de browse, las aplicaciones implementan su propio arbol.
- -> Implementar search y de esa forma los clientes pueden definir su arbol programaticamente, sin necesidad de browse.
- -> Source a devolver playlist que se pueden modelar con el patron agregacion (playlists de playlist).
-
-
------------------------ X --------------------------- x -------------------------- X ----------------------
-
-MediaSource
- -> Browse muy sencillo: sin filtros, sin recursividad
- -> Podemos añadir versiones mas complejas en forma de nuevas APIs (browse_complex que filtre y ordene).
- -> O incluso simplemente un API search() que se encargue de implementar consultas mas complejas.
- -> Mejor porque no todos los plugins tienen que soportar recursividad (que ademas añade cierta complejidad)
- y hace el API de browsing mas ligera.
- -> Los desarrolladores de los plugins mas sencillos (e.g. browsing de sistema de ficheros por directorios)
- no se tienen que preocupar de gestionar cosas que no van a implementar, simplemente implementan browse
- y no implementan search.
- -> IDEA: Podriamos eliminar el parametro count y hacer que browse()/search() devolvieses un iterador/contenedor inteligente
- El callback del browse solo devuelve el iterador/contenedor y solo se llama 1 vez a partir de ese punto es el cliente
- el que itera sobre los resultados y el iterador inteligente control el offset y el count, etc
- seria muy util por ejemplo al hacer browsing de servicios pesados como bluetooth, que pueden requerir hacer el browsing
- de forma diferente para hacerlo eficiente.
- De todas formas el mismo plugin podria hacer consultas mas grandes o mas pequeñas dependiendo de lo que se quiera hacer en la UI
- no es lo mismo hacer un browse de songs para mostrar todas las canciones de golpe que si se sabe que la UI esta haciendo un
- browse de songs para mostrar los resultados por paginas (en el segundo caso es mas eficiente consultas pequeñas, mientra que en el
- primero lo optimo seria tender a consultas mas grandes y hacer menos consultas).
- -> Podria ser interesante pensar en definir un tipo "Conjunto" para las claves que facilite saber si una clave esta o no en el conjunto.
- -> Util al implementar plugins para saber si se ha pedido o no una clave
- -> Util al implementar capabilities para saber si esta o no una capacidad determinada
- -> Quizas eliminar el API get_metadata() y quedarnos solo con el browse()?
- -> Browse de un container te da los metadatos de los contenidos y del container
- -> Browse de un nodo hoja te da los metadatos del nodo hoja.
- -> MediaPlugin deberia indicar las capacidades del plugin.
- -> Operaciones soportadas
- -> Metadatos soportados
- -> Quizas dos APIs diferentes implementadas a nivel de MediaSource?
- -> El propio MediaSource puede saber que ops estan soportadas simplemente mirando que operaciones virtuales no tienen una implementacion.
- -> Las subclases de MediaSource pueden proporcionar un metodo que de info sobre las claves implementadas que sea obligatorio implementar por las
- subclases. Lo mismo se emplearia para aquellos plugins que no implementan un source sino que son metadata providers.
- -> Tanto MediaSource como MetadataSource implementan una misma interfaz (la de MetadataSource).
- -> La interfaz define el metodo get_metadata() y otro para obtener info sobre las claves soportadas por el plugin.
- -> Renombrar clases?
- -> MediaSource --> MediaProvider
- -> MetadataSource --> MetadataProvider
- -> Probablemente necesitemos definir conjuntos y operaciones sobre conjuntos. Por ejemplo, el cliente pide claves A, B y C, y el plugin
- soporta A, C y D. Al final lo más conveniente sería pedirle al plugin A y C directamente, si el conjunto fuese vacío ya no se llamaría al
- plugin. Sería facil para cada clave saber qué plugins la soportan, etc.
- -> Otra posibilidad sería simplemente para cada plugin pasarle la lista y ellos resuelven todo lo que pueden y la consulta se resuelve
- siempre con valores multivaluados (si varios plugins son capaces de resolver una consulta, se obtienen varios resultados). Los plugins
- se ordenan por prioridades, etc
- -> Al final los metadatos no se le piden al plugin, sino al framework y este usa los plugins disponibles para obtener los metadatos...
- -> Como encajar esto con browse() y search() que tb resuelven metadatos?
- -> Lo más eficiente es no usar otros plugins, pero no siempre es lo que se desea. Quizas sea necesario confirgurar las operaciones
- de browse y search para indicar que tipo de comportamiento se requiere?
- -> Definir metadata a nivel del framework tb. Si el cliente hace metadata sobre el plugin, solo se usa el plugin, si lo hace sobre el
- framework, se usan todos los plugins posibles.
- -> Si se define sobre el framework, qué se le pasa a los plugins?
- -> Necesitamos un mecanismo rapido de conversion objectid -> uri, quizas definir el objectid como una clase en si misma con
- metodos para su manipulacion de forma que la URI se pueda obtener rapidamente y se obligue a usarla en la codificacion?
- -> Por ejemplo un plugin de ratings podria usar el objectid directamente para almacenar y recuprar ratings puesto que es el el que
- almacena toda la informacion, sin embargo un plugin de lyrics por ejemplo, no podria, a partir del objectid necesita recuperar otra
- informacion (artista, album, title...) y usar esa para recabar los datos. Eso implica comunicaciones entre los plugins, el plugin
- de lyrics ejercerá una consulta de metadata sobre el framework (o el source en particular) preguntando por esos datos.
- IDEA: modelar dependencias entre claves para hacer este tipo de gestiones de forma eficiente.
- -> Idea hacer comparaciones de claves mas eficiente usando identificadores para cada clave
- -> Definir un rango para claves definidas en el framework (artista, titulo, album, etc)
- -> Dejar otro rango para claves definidas por los plugins que se registran en el fw.
-
- -> Playlists y metadata
- -> Las playlists tienen los metadatos, probablemente estos metadatos se obtuvieron por medio de browse() o search().
- -> Al guardar la playlist se guardan tb los metadatos!
- -> Mas espacio, pero la recuperacion de la playlist es inmediata => cargar una playlist no implica tener que volver a
- consultar todos los metadatos de (potencialmente) muchisimos elementos.
- -> si el espacio es un problema (que no deberia), al guardar la playlist se eliminan los metadatos y solo se guardan los
- objectids, al recuperar la playlist no hay metadatos y el cliente se encarga de demandarlos bajo su propia cuenta y riesgo,
- sencillo y flexible segun se quiera optimizar eficiencia en disco o en carga.
-
diff --git a/doc/brainstorming/jasuarez-initial-brainstorming.txt b/doc/brainstorming/jasuarez-initial-brainstorming.txt
deleted file mode 100644
index ab32293..0000000
--- a/doc/brainstorming/jasuarez-initial-brainstorming.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-¿Multiples valores o no?
-
-Case principal: *Content*.
-Esta clase encapsula tanto objetos media simples, como contenedores
-
-Content == playlist
-
-Esquema básico: tiene propiedades (titulo, mime, ...), capacidades (qué operaciones se puede realizar sobre ellos) y métodos.
-Funciones básicas get/set para añadir propiedades
-
-Content.get(<property>);
-Content.set(<property>, <value>);
-Content.getURI();
-
-Las capacidades son especialmente interesantes para los contenedores.
-Indican qué operaciones (que no propiedades) se pueden realizar. Al igual que las propiedades, son dinámicas: un Content del mismo tipo puede en ciertas ocasiones permitir unas operaciones y en otras no.
-
- ContentAudio: un fichero de audio
- ContentVideo: un fichero de video
- ContentImage: una imagen
-
- ContentList: lista de contenido.
-
- Una playlist se podría ver como un ContentList donde cada elemento es un ContentAudio/Video.
- Una playlist de radio es un ContentList, pero cada entrada es una alternativa a usar para la reproduccion.
-
- Interesante: una playlist de radios seria un ContentList, donde cada elemento es a su vez otro ContentList que
- contiene las alternativas para la reproducción.
-
- Operación básica para un ContentList: implementar un iterador (anterior, siguiente).
- ¿Cómo se implementaría un random? Un shuffling se podría hacer como
-
- ContentList cl_shuffled = cl_normal.shuffle().
-
- El problema es con el random. Se podría añadir al iterador un método "next_random", que devolvería aleatoriamente un nuevo elemento. Para que visualmente se sepa que elemento hay que mostrar, un ContentList podría añadir una propiedad "index" para saber qué posicion ocupa dentro de la lista. Podría resultar necesario que el usuario especificase que quiere dicha propiedad (ver más abajo el tema de añadir propiedades en cadena).
-
-
- Cada ContentAudio/Video/Image puede añadir métodos propios que solo tienen interés para ese objeto.
- ¿Es activo el objeto? Es interesante saber si el objeto es básicamente una hashtable con propiedades, o existen métodos especiales sobre ellos. Una operacion interesante podría ser transcoding: e.g. puede un ContentImage[png] tener una operación para devolver otro ContentImage[jpg]? O es más bien una operación del source?
- En principio vamos a dejarlo como una hashtable con propiedades.
-
- El usuario puede crear sus propios tipos de Content -> un ContentList los manejaría opacamente.
-
-
- A partir de este se podría crear una lista de artistas, por ejemplo. Se devolvería un ContentList donde cada componente es un Content con la propiedad "artista" establecida (se puede considerar para empezar como un ContentNull, i.e., un content sin contenido real; simplifica mucho las cosas).
-
-
-Punto de interes: un Content, en principio puede tener virtualmente infinidad de propiedades, algunas de las cuales incluso podría ser "costoso" calcular: artista, album, género, carátula, letra, información de la wikipedia del artista, etc. Así que cuando se pide un Content a un source, habría que definir (o incluso predefinir) qué propiedades estamos interesados.
-
-El Source proporcionaría el contenido y tb. ciertas propiedades (¿debería el Source implementar tb. una interfaz de MetadataProvider? no estoy seguro), y luego los MetadataProviders o PropertyProviders irian "rellenando" los datos que faltan.
-
-Una idea interesante sería que cada MetadataProvider especificase qué tipo de propiedades es capaz de proporcionar, y qué necesita para proporcionarlos (se sobreentiende qué propiedad). Por ejemplo, para proporcionar la carátula de un album un provider prodría necesitar conocer el artista y el album. Ello implica que debería haber un conjunto predefinido de propiedades que todo el mundo ya conociese. ¿Sería interesante echarle un vistazo a lo de las ontologías que se emplean en tracker? De alguna manera, trata de crear un conjunto estándar y bien definido de propiedades....
-
-De todo esto se desprende que igual sería interesante tener un Content en capas, o cebolla. Un ejemplo: El usuario está interesado en una lista de albumes y sus carátulas. Puesto que no ha especificado artista, éste es necesario resolverlo para obtener la carátula. Dos opciones: la carátula no se obtiene (porque no se conoce el artista), o bien se añade a la lista de propiedades que el usuario ha pedido.
-
-Al final, cuando está todo calculado, dos opciones: se devuelve ese objeto con la propiedad añadida, o hay que sacarlo. Con el primer caso hay que entender que lo que el usuario especifica es una lista de las propieades en las que está interesado, no la lista que *exactamente* hay que devolver.
-
-Con la segunda opcion, hay que "extraer" la propiedad añadida artificialmente. El tema se complica si las dependencias entre propiedades se anidan. Una solución sería pues usar un ContentLayer, que basicamente permite anidar un content dentro de otro. Así, el Content que pide el usuario se añadiría dentro de otro Content al que se le añade la propiedad "artista". Cuando se pide el valor de una propiedad en un ContentLayer, si dicha propiedad no está en ese ContentLayer se busca en el hijo. Igual cuando se añade. Al final, se desencapsula el ContentLayer y se devuelve al solicitante sin dicha propiedad. Esto resuelve un problema que había en MAFW cuando se pedia una propiedad que requería de otra que no estaba.
-
-Otro tema relativo a la gestión de propiedades "costosas". Supongamos que las carátulas se bajan de inet. ¿Tendría que quedarse bloqueado el player porque ha solicitado 20 albumes y se están descargando las carátulas? Obviamente no.
-
-Solucion: considerar que las propiedades rápidamente resolvibles son tipo cached.
-Ejemplo: el artista sería cached. La carátula depende: si el provider sieempre coge la carátula de un directorio, sería cached (podría bajar las carátulas en background); si la baja de inet, sería uncached, e incluso podría ser una mezcla: si la tiene en la caché es "cached", mientras que si no, la baja de inet, la devuelve y la guarda en la caché. En este caso sería uncached.
-
-Por tanto, cuando se piden las propiedades, se debería especificar si estamos interesados en todas o solo en las cached. En el caso expuesto, se pedirían todas las cached, y al devolver se comprobaría que "carátula" no se ha resuelto porque no está cached (es interesante saber esto para saber si realmente es porque está sin cachear o porque no se pudo resolver por ningún provider; tb. es importante que el gestor de providers sea inteligente como para usar providers "cached") y podría pedirlas en background.
-
-Otro tema: que pasa con los recursos cuya propiedad no puede ser calculada hasta que pasa un evento (por ejemplo, que se reproduzca). El ejemplo es el renderer, que es capaz de devolver valores una vez que se ha empezado a reproducir.
-
-En este aspecto, igual es interesante que existan "señales" para notificar propiedades. El usuario (o el contenido?) reciviría una señal para indicar esto. Una forma de hacerlo sería que las propiedades puedan tener triggers, de forma que cuando alguien la modifica, se notifique. Así, el renderer podría cambiar el valor de una propiedad y el usuario se daría cuenta. Esto lleva a si es interesante/complicaciones de permitir cambios en los contenidos que ya tienen un valor).
-
-La otra opcion sería pasar del tema: al fin y al cabo, el renderer no lo gestionamos nosotros sino el cliente; podría él decidir qué hace.
-
- Un source devuelve siempre un content -> se simplifica el api (en teoría).
diff --git a/doc/brainstorming/to-be-discussed.txt b/doc/brainstorming/to-be-discussed.txt
deleted file mode 100644
index 360e691..0000000
--- a/doc/brainstorming/to-be-discussed.txt
+++ /dev/null
@@ -1,51 +0,0 @@
-1.- Should we use typed keys?
- -> Is a significant effort, but is it worth it?
- -> Does it really make somebody else's live easier?
- -> Check for use cases where that would be the case
- -> Are these use cases important enough?
- -> The alternative, all keys are string type.
- -> Simple implementation and usage.
- -> But would we be lacking flexibility or power somehow?
- -> Again check use cases.
-
-2.- Should MetadataKey should used as high level entity in API?
- -> So far, API handles only key ids.
- -> For instance, we have content_get(Content *c, gint KeyId)
- -> Should be good/interesting handling MetadataKey directly?
- -> Like content_get(Content *c, MetadataKey *key)
-
- -> It would require to have an API to get the MetadataKey for artist, album,
- and so on.
- -> But keys would carry with them all information that any one could use.
-
-3.- Grouping plugins
- -> So far, each plugin is exposed to client, with no relation with other
- plugins.
- -> Some libraries can provide more than one instance of same plugin.
- -> For instance, upnp plugins is shown each per server
- -> The same can happen for future plugins
- -> For instance, a user could design a by-disk plugin, so each time a
- disk is plugged a new plugin instance is created.
- -> So at the end, UI could be populated with a lot of plugins in its first
- view.
- -> Some multimedia players group the "sources" to improve user experience.
- -> Some group plugins by "type". That is, all upnp plugins are
- grouped together in their view.
- -> Some others group plugins by kind of information they manage:
- audio plugins, video plugins or image plugins.
- -> So a proposal would be adding a couple of "tags" to each plugin that
- would help user to implement above grouping approachs.
- -> One tag could be "type", so all plugins from the same library
- would share it. For instance, "upnp", "youtube", and so on.
- -> Other tag would be "content", telling which kind of content is
- able to manage: audio, video or image.
- -> This could be duplicated, telling a plugin is able to provide
- several kind of information.
-
-4.- Getting rid of function to notify slow keys
- -> While it is clear what is a "slow" key, reporting about them in a single function can be misunderstood.
- -> A key could be solved either in "fast" or "slow" form, being the latter more accurate. In this case, should the key be reported as fast or as slow?
- -> Also, a key could be fast in a operation while "slow" in another. What to inform in this case?
- -> Proposal is to keep the concept, but removing the function (if possible, as maybe it is a must for the good performance of framework)
- -> Instead, information about slow/fast keys should be in documentation about the appropriate plugin.
-
diff --git a/doc/reference/grilo-docs.sgml b/doc/reference/grilo-docs.sgml
index 6e537ef..6c27863 100644
--- a/doc/reference/grilo-docs.sgml
+++ b/doc/reference/grilo-docs.sgml
@@ -39,16 +39,17 @@
<xi:include href="xml/grl-media-plugin.xml"/>
<xi:include href="xml/grl-metadata-source.xml"/>
<xi:include href="xml/grl-media-source.xml"/>
- <xi:include href="xml/grl-content-media.xml"/>
</chapter>
- <chapter id="content">
- <title>Media content</title>
- <xi:include href="xml/grl-content.xml"/>
- <xi:include href="xml/grl-content-box.xml"/>
- <xi:include href="xml/grl-content-video.xml"/>
- <xi:include href="xml/grl-content-audio.xml"/>
- <xi:include href="xml/grl-content-image.xml"/>
+ <chapter id="data">
+ <title>Media data</title>
+ <xi:include href="xml/grl-data.xml"/>
+ <xi:include href="xml/grl-config.xml"/>
+ <xi:include href="xml/grl-media.xml"/>
+ <xi:include href="xml/grl-media-box.xml"/>
+ <xi:include href="xml/grl-media-video.xml"/>
+ <xi:include href="xml/grl-media-audio.xml"/>
+ <xi:include href="xml/grl-media-image.xml"/>
</chapter>
<chapter id="misc">
diff --git a/grilo-0.1-uninstalled.pc.in b/grilo-0.1-uninstalled.pc.in
index bc80c26..4e526c5 100644
--- a/grilo-0.1-uninstalled.pc.in
+++ b/grilo-0.1-uninstalled.pc.in
@@ -8,7 +8,7 @@ Name: Grilo Framework
Description: Grilo Framework for multimedia developers, Not Installed
Version: @VERSION@
Libs: ${libdir}/lib@GRL_NAME@.la
-Cflags: -I${includedir} -I${includedir}/content
+Cflags: -I${includedir} -I${includedir}/data
Requires: gobject-2.0
Requires.Private:
diff --git a/m4/introspection.m4 b/m4/introspection.m4
new file mode 100644
index 0000000..bfc52be
--- /dev/null
+++ b/m4/introspection.m4
@@ -0,0 +1,94 @@
+dnl -*- mode: autoconf -*-
+dnl Copyright 2009 Johan Dahlin
+dnl
+dnl This file is free software; the author(s) gives unlimited
+dnl permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+
+# serial 1
+
+m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL],
+[
+ AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+ AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+ AC_BEFORE([LT_INIT],[$0])dnl setup libtool first
+
+ dnl enable/disable introspection
+ m4_if([$2], [require],
+ [dnl
+ enable_introspection=yes
+ ],[dnl
+ AC_ARG_ENABLE(introspection,
+ AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]],
+ [Enable introspection for this build]),,
+ [enable_introspection=auto])
+ ])dnl
+
+ AC_MSG_CHECKING([for gobject-introspection])
+
+ dnl presence/version checking
+ AS_CASE([$enable_introspection],
+ [no], [dnl
+ found_introspection="no (disabled, use --enable-introspection to enable)"
+ ],dnl
+ [yes],[dnl
+ PKG_CHECK_EXISTS([gobject-introspection-1.0],,
+ AC_MSG_ERROR([gobject-introspection-1.0 is not installed]))
+ PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1],
+ found_introspection=yes,
+ AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME]))
+ ],dnl
+ [auto],[dnl
+ PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no)
+ ],dnl
+ [dnl
+ AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@])
+ ])dnl
+
+ AC_MSG_RESULT([$found_introspection])
+
+ INTROSPECTION_SCANNER=
+ INTROSPECTION_COMPILER=
+ INTROSPECTION_GENERATE=
+ INTROSPECTION_GIRDIR=
+ INTROSPECTION_TYPELIBDIR=
+ if test "x$found_introspection" = "xyes"; then
+ INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
+ INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
+ INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
+ INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
+ INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
+ INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0`
+ INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0`
+ INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection
+ fi
+ AC_SUBST(INTROSPECTION_SCANNER)
+ AC_SUBST(INTROSPECTION_COMPILER)
+ AC_SUBST(INTROSPECTION_GENERATE)
+ AC_SUBST(INTROSPECTION_GIRDIR)
+ AC_SUBST(INTROSPECTION_TYPELIBDIR)
+ AC_SUBST(INTROSPECTION_CFLAGS)
+ AC_SUBST(INTROSPECTION_LIBS)
+ AC_SUBST(INTROSPECTION_MAKEFILE)
+
+ AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes")
+])
+
+
+dnl Usage:
+dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version])
+
+AC_DEFUN([GOBJECT_INTROSPECTION_CHECK],
+[
+ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1])
+])
+
+dnl Usage:
+dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version])
+
+
+AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE],
+[
+ _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require])
+])
diff --git a/src/Makefile.am b/src/Makefile.am
index cf77a77..840e60b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,18 +5,15 @@
#
# Copyright (C) 2010 Igalia S.L. All rights reserved.
-SUBDIRS = content
-
lib_LTLIBRARIES = lib@GRL_NAME@.la
lib@GRL_NAME@_la_CFLAGS = \
$(DEPS_CFLAGS) \
-I$(srcdir) \
- -I$(srcdir)/content
+ -I$(srcdir)/data
lib@GRL_NAME@_la_LIBADD = \
- $(DEPS_LIBS) \
- $(builddir)/content/libcontent.la
+ $(DEPS_LIBS)
lib@GRL_NAME@_la_SOURCES = \
grl-media-plugin.c grl-media-plugin-priv.h \
@@ -26,6 +23,17 @@ lib@GRL_NAME@_la_SOURCES = \
grl-media-source.c \
grl-log.c
+data_c_sources = \
+ data/grl-data.c \
+ data/grl-media.c \
+ data/grl-media-audio.c \
+ data/grl-media-video.c \
+ data/grl-media-image.c \
+ data/grl-media-box.c \
+ data/grl-config.c
+
+lib@GRL_NAME@_la_SOURCES += $(data_c_sources)
+
lib@GRL_NAME@incdir = \
$(includedir)/@GRL_NAME@
@@ -39,6 +47,17 @@ lib@GRL_NAME@inc_HEADERS = \
grl-media-source.h \
grl-log.h
+data_h_headers = \
+ data/grl-data.h \
+ data/grl-media.h \
+ data/grl-media-box.h \
+ data/grl-media-audio.h \
+ data/grl-media-video.h \
+ data/grl-media-image.h \
+ data/grl-config.h
+
+lib@GRL_NAME@inc_HEADERS += $(data_h_headers)
+
noinst_HEADERS = \
grl-media-plugin-priv.h \
grl-metadata-source-priv.h
@@ -48,3 +67,31 @@ MAINTAINERCLEANFILES = \
*~
DISTCLEANFILES = $(MAINTAINERCLEANFILES)
+CLEANFILES =
+
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir)
+INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=$(srcdir)/data
+
+# introspection support
+if HAVE_INTROSPECTION
+introspection_sources = \
+ $(lib@GRL_NAME@inc_HEADERS) \
+ $(lib@GRL_NAME@_la_SOURCES)
+
+Grilo-@GRL_MAJORMINOR@.gir: lib@GRL_NAME@.la
+Grilo_0_1_gir_INCLUDES = GObject-2.0
+Grilo_0_1_gir_CFLAGS = $(lib@GRL_NAME@_la_CFLAGS)
+Grilo_0_1_gir_LIBS = lib@GRL_NAME@.la
+Grilo_0_1_gir_FILES = $(addprefix $(srcdir)/,$(introspection_sources))
+INTROSPECTION_GIRS += Grilo-@GRL_MAJORMINOR@.gir
+
+girdir = $(datadir)/gir-1.0
+dist_gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
+endif
diff --git a/src/content/Makefile.am b/src/content/Makefile.am
deleted file mode 100644
index 77b3719..0000000
--- a/src/content/Makefile.am
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Makefile.am
-#
-# Author: Juan A. Suárez Romero <jasuarez@igalia.com>
-#
-# Copyright (C) 2010 Igalia S.L. All rights reserved.
-
-noinst_LTLIBRARIES = libcontent.la
-
-libcontent_la_CFLAGS = \
- $(DEPS_CFLAGS) \
- -I$(srcdir) \
- -I$(srcdir)/..
-
-libcontent_la_LIBADD = $(DEPS_LIBS)
-
-libcontent_la_SOURCES = \
- grl-content.c \
- grl-content-media.c \
- grl-content-audio.c \
- grl-content-video.c \
- grl-content-image.c \
- grl-content-box.c
-
-libcontentincdir = $(includedir)/@GRL_NAME@
-
-libcontentinc_HEADERS = \
- grl-content.h \
- grl-content-media.h \
- grl-content-box.h \
- grl-content-audio.h \
- grl-content-video.h \
- grl-content-image.h
-
-MAINTAINERCLEANFILES = \
- *.in \
- *~
-
-DISTCLEANFILES = $(MAINTAINERCLEANFILES)
diff --git a/src/content/grl-content-audio.h b/src/content/grl-content-audio.h
deleted file mode 100644
index dd6ec14..0000000
--- a/src/content/grl-content-audio.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _GRL_CONTENT_AUDIO_H_
-#define _GRL_CONTENT_AUDIO_H_
-
-#include <grl-content-media.h>
-
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_CONTENT_AUDIO \
- (grl_content_audio_get_type())
-
-#define GRL_CONTENT_AUDIO(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_CONTENT_AUDIO, \
- GrlContentAudio))
-
-#define GRL_CONTENT_AUDIO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_CONTENT_AUDIO, \
- GrlContentAudioClass))
-
-#define GRL_IS_CONTENT_AUDIO(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_CONTENT_AUDIO))
-
-#define GRL_IS_CONTENT_AUDIO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_CONTENT_AUDIO))
-
-#define GRL_CONTENT_AUDIO_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_CONTENT_AUDIO, \
- GrlContentAudioClass))
-
-typedef struct _GrlContentAudio GrlContentAudio;
-typedef struct _GrlContentAudioClass GrlContentAudioClass;
-
-struct _GrlContentAudioClass
-{
- GrlContentMediaClass parent_class;
-};
-
-struct _GrlContentAudio
-{
- GrlContentMedia parent;
-};
-
-#define grl_content_audio_set_artist(content, artist) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_ARTIST, \
- (artist))
-
-#define grl_content_audio_set_album(content, album) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_ALBUM, \
- (album))
-
-#define grl_content_audio_set_genre(content, genre) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_GENRE, \
- (genre))
-
-#define grl_content_audio_set_lyrics(content, lyrics) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_LYRICS, \
- (lyrics))
-
-#define grl_content_audio_set_bitrate(content, bitrate) \
- grl_content_set_int(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_BITRATE, \
- (bitrate))
-
-#define grl_content_audio_get_artist(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_ARTIST)
-#define grl_content_audio_get_album(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_ALBUM)
-#define grl_content_audio_get_genre(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_GENRE)
-#define grl_content_audio_get_lyrics(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_LYRICS)
-#define grl_content_audio_get_bitrate(content) \
- grl_content_get_int(GRL_CONTENT((content)), GRL_METADATA_KEY_BITRATE)
-
-GType grl_content_audio_get_type (void) G_GNUC_CONST;
-
-GrlContentMedia *grl_content_audio_new (void);
-
-G_END_DECLS
-
-#endif /* _CONTENT_AUDIO_H_ */
diff --git a/src/content/grl-content-box.c b/src/content/grl-content-box.c
deleted file mode 100644
index 8f9833a..0000000
--- a/src/content/grl-content-box.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * A container for multiple medias.
- *
- * This high level class represents a container for multiple medias.
- *
- */
-
-#include "grl-content-box.h"
-
-#define MIME_BOX "x-grl/box"
-
-static void grl_content_box_dispose (GObject *object);
-static void grl_content_box_finalize (GObject *object);
-
-G_DEFINE_TYPE (GrlContentBox, grl_content_box, GRL_TYPE_CONTENT_MEDIA);
-
-static void
-grl_content_box_class_init (GrlContentBoxClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *)klass;
-
- gobject_class->dispose = grl_content_box_dispose;
- gobject_class->finalize = grl_content_box_finalize;
-}
-
-static void
-grl_content_box_init (GrlContentBox *self)
-{
- grl_content_box_set_childcount (self, GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN);
- grl_content_media_set_mime (GRL_CONTENT_MEDIA (self), MIME_BOX);
-}
-
-static void
-grl_content_box_dispose (GObject *object)
-{
- G_OBJECT_CLASS (grl_content_box_parent_class)->dispose (object);
-}
-
-static void
-grl_content_box_finalize (GObject *object)
-{
- g_signal_handlers_destroy (object);
- G_OBJECT_CLASS (grl_content_box_parent_class)->finalize (object);
-}
-
-/**
- * grl_content_box_new:
- *
- * Creates a new content box object.
- *
- * Returns: a newly-allocated content box.
- **/
-GrlContentMedia *
-grl_content_box_new (void)
-{
- return GRL_CONTENT_MEDIA (g_object_new (GRL_TYPE_CONTENT_BOX,
- NULL));
-}
-
-/**
- * grl_content_box_set_childcount:
- * @content: content to change
- * @childcount: number of children
- *
- * Sets the number of children of this box. Use
- * #GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN if it is unknown.
- **/
-void
-grl_content_box_set_childcount (GrlContentBox *content,
- gint childcount)
-{
- g_return_if_fail (GRL_IS_CONTENT_BOX (content));
-
- if (childcount != GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN) {
- grl_content_set_int (GRL_CONTENT (content),
- GRL_METADATA_KEY_CHILDCOUNT,
- childcount);
- } else {
- grl_content_set (GRL_CONTENT (content),
- GRL_METADATA_KEY_CHILDCOUNT,
- NULL);
- }
-}
-
-/**
- * grl_content_box_get_childcount:
- * @content: content to inspect
- *
- * Number of children of this box.
- *
- * Returns: number of children, or #GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN if
- * unknown.
- **/
-gint
-grl_content_box_get_childcount (GrlContentBox *content)
-{
- g_return_val_if_fail (GRL_IS_CONTENT_BOX (content),
- GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN);
-
- const GValue *value = grl_content_get (GRL_CONTENT (content),
- GRL_METADATA_KEY_CHILDCOUNT);
-
- if (value) {
- return g_value_get_int (value);
- } else {
- return GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN;
- }
-}
diff --git a/src/content/grl-content-box.h b/src/content/grl-content-box.h
deleted file mode 100644
index f15939c..0000000
--- a/src/content/grl-content-box.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _GRL_CONTENT_BOX_H_
-#define _GRL_CONTENT_BOX_H_
-
-#include <grl-content-media.h>
-
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_CONTENT_BOX \
- (grl_content_box_get_type())
-
-#define GRL_CONTENT_BOX(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_CONTENT_BOX, \
- GrlContentBox))
-
-#define GRL_CONTENT_BOX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_CONTENT_BOX, \
- GrlContentBoxClass))
-
-#define GRL_IS_CONTENT_BOX(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_CONTENT_BOX))
-
-#define GRL_IS_CONTENT_BOX_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_CONTENT_BOX))
-
-#define GRL_CONTENT_BOX_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_CONTENT_BOX, \
- GrlContentBoxClass))
-
-typedef struct _GrlContentBox GrlContentBox;
-typedef struct _GrlContentBoxClass GrlContentBoxClass;
-
-struct _GrlContentBoxClass
-{
- GrlContentMediaClass parent_class;
-};
-
-struct _GrlContentBox
-{
- GrlContentMedia parent;
-};
-
-GType grl_content_box_get_type (void) G_GNUC_CONST;
-GrlContentMedia *grl_content_box_new (void);
-void grl_content_box_set_childcount (GrlContentBox *content, gint childcount);
-gint grl_content_box_get_childcount (GrlContentBox *content);
-
-G_END_DECLS
-
-#endif /* _CONTENT_BOX_H_ */
diff --git a/src/content/grl-content-image.h b/src/content/grl-content-image.h
deleted file mode 100644
index 41e5eb0..0000000
--- a/src/content/grl-content-image.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _GRL_CONTENT_IMAGE_H_
-#define _GRL_CONTENT_IMAGE_H_
-
-#include <grl-content-media.h>
-
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_CONTENT_IMAGE \
- (grl_content_image_get_type())
-
-#define GRL_CONTENT_IMAGE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_CONTENT_IMAGE, \
- GrlContentImage))
-
-#define GRL_CONTENT_IMAGE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_CONTENT_IMAGE, \
- GrlContentImageClass))
-
-#define GRL_IS_CONTENT_IMAGE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_CONTENT_IMAGE))
-
-#define GRL_IS_CONTENT_IMAGE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_CONTENT_IMAGE))
-
-#define GRL_CONTENT_IMAGE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_CONTENT_IMAGE, \
- GrlContentImageClass))
-
-typedef struct _GrlContentImage GrlContentImage;
-typedef struct _GrlContentImageClass GrlContentImageClass;
-
-struct _GrlContentImageClass
-{
- GrlContentMediaClass parent_class;
-};
-
-struct _GrlContentImage
-{
- GrlContentMedia parent;
-};
-
-#define grl_content_image_set_width(content, width) \
- grl_content_set_int(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_WIDTH, \
- (width))
-
-#define grl_content_image_set_height(content, height) \
- grl_content_set_int(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_HEIGHT, \
- (height))
-
-#define grl_content_image_get_width(content) \
- grl_content_get_int(GRL_CONTENT((content)), GRL_METADATA_KEY_WIDTH)
-#define grl_content_image_get_height(content) \
- grl_content_get_int(GRL_CONTENT((content)), GRL_METADATA_KEY_HEIGHT)
-
-GType grl_content_image_get_type (void) G_GNUC_CONST;
-GrlContentMedia *grl_content_image_new (void);
-void grl_content_image_set_size (GrlContentImage *content,
- gint width,
- gint height);
-
-G_END_DECLS
-
-#endif /* _GRL_CONTENT_IMAGE_H_ */
diff --git a/src/content/grl-content-media.h b/src/content/grl-content-media.h
deleted file mode 100644
index 3971fbc..0000000
--- a/src/content/grl-content-media.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _GRL_CONTENT_MEDIA_H_
-#define _GRL_CONTENT_MEDIA_H_
-
-#include <grl-content.h>
-
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_CONTENT_MEDIA \
- (grl_content_media_get_type())
-
-#define GRL_CONTENT_MEDIA(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_CONTENT_MEDIA, \
- GrlContentMedia))
-
-#define GRL_CONTENT_MEDIA_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_CONTENT_MEDIA, \
- GrlContentMediaClass))
-
-#define GRL_IS_CONTENT_MEDIA(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_CONTENT_MEDIA))
-
-#define GRL_IS_CONTENT_MEDIA_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_CONTENT_MEDIA))
-
-#define GRL_CONTENT_MEDIA_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_CONTENT_MEDIA, \
- GrlContentMediaClass))
-
-typedef struct _GrlContentMedia GrlContentMedia;
-typedef struct _GrlContentMediaClass GrlContentMediaClass;
-
-struct _GrlContentMediaClass
-{
- GrlContentClass parent_class;
-};
-
-struct _GrlContentMedia
-{
- GrlContent parent;
-};
-
-#define grl_content_media_set_id(content, id) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_ID, \
- (id))
-
-#define grl_content_media_set_url(content, url) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_URL, \
- (url))
-
-#define grl_content_media_set_author(content, author) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_AUTHOR, \
- (author))
-
-#define grl_content_media_set_title(content, title) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_TITLE, \
- (title))
-
-#define grl_content_media_set_description(content, description) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_DESCRIPTION, \
- (description))
-
-#define grl_content_media_set_source(content, source) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_SOURCE, \
- (source))
-
-#define grl_content_media_set_thumbnail(content, thumbnail) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_THUMBNAIL, \
- (thumbnail))
-
-#define grl_content_media_set_site(content, site) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_SITE, \
- (site))
-
-#define grl_content_media_set_duration(content, duration) \
- grl_content_set_int(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_DURATION, \
- (duration))
-
-#define grl_content_media_set_date(content, date) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_DATE,\
- (date))
-
-#define grl_content_media_set_mime(content, mime) \
- grl_content_set_string(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_MIME, \
- (mime))
-
-void grl_content_media_set_rating (GrlContentMedia *content,
- const gchar *rating,
- const gchar *max);
-
-#define grl_content_media_get_id(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_ID)
-#define grl_content_media_get_url(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_URL)
-#define grl_content_media_get_author(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_AUTHOR)
-#define grl_content_media_get_title(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_TITLE)
-#define grl_content_media_get_description(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_DESCRIPTION)
-#define grl_content_media_get_source(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_SOURCE)
-#define grl_content_media_get_thumbnail(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_THUMBNAIL)
-#define grl_content_media_get_site(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_SITE)
-#define grl_content_media_get_duration(content) \
- grl_content_get_int(GRL_CONTENT((content)), GRL_METADATA_KEY_DURATION)
-#define grl_content_media_get_date(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_DATE)
-#define grl_content_media_get_mime(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_MIME)
-#define grl_content_media_get_rating(content) \
- grl_content_get_string(GRL_CONTENT((content)), GRL_METADATA_KEY_RATING)
-
-GType grl_content_media_get_type (void) G_GNUC_CONST;
-GrlContentMedia *grl_content_media_new (void);
-
-G_END_DECLS
-
-#endif /* _GRL_CONTENT_MEDIA_H_ */
diff --git a/src/content/grl-content-video.c b/src/content/grl-content-video.c
deleted file mode 100644
index 15e4459..0000000
--- a/src/content/grl-content-video.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * A multimedia content for video.
- *
- * This high level class represents an video multimedia item. It has methods to
- * set and get properties like framerate, width, height, and so on.
- *
- */
-
-#include "grl-content-video.h"
-
-
-static void grl_content_video_dispose (GObject *object);
-static void grl_content_video_finalize (GObject *object);
-
-G_DEFINE_TYPE (GrlContentVideo, grl_content_video, GRL_TYPE_CONTENT_MEDIA);
-
-static void
-grl_content_video_class_init (GrlContentVideoClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *)klass;
-
- gobject_class->dispose = grl_content_video_dispose;
- gobject_class->finalize = grl_content_video_finalize;
-}
-
-static void
-grl_content_video_init (GrlContentVideo *self)
-{
-}
-
-static void
-grl_content_video_dispose (GObject *object)
-{
- G_OBJECT_CLASS (grl_content_video_parent_class)->dispose (object);
-}
-
-static void
-grl_content_video_finalize (GObject *object)
-{
- g_signal_handlers_destroy (object);
- G_OBJECT_CLASS (grl_content_video_parent_class)->finalize (object);
-}
-
-/**
- * grl_content_video_new:
- *
- * Creates a new content video object.
- *
- * Returns: a newly-allocated content video.
- **/
-GrlContentMedia *
-grl_content_video_new (void)
-{
- return GRL_CONTENT_MEDIA (g_object_new (GRL_TYPE_CONTENT_VIDEO,
- NULL));
-}
-
-void
-grl_content_video_set_size (GrlContentVideo *content,
- gint width,
- int height)
-{
- grl_content_video_set_width (content, width);
- grl_content_video_set_height (content, height);
-}
diff --git a/src/content/grl-content-video.h b/src/content/grl-content-video.h
deleted file mode 100644
index 8928703..0000000
--- a/src/content/grl-content-video.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _GRL_CONTENT_VIDEO_H_
-#define _GRL_CONTENT_VIDEO_H_
-
-#include <grl-content-media.h>
-
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_CONTENT_VIDEO \
- (grl_content_video_get_type())
-
-#define GRL_CONTENT_VIDEO(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_CONTENT_VIDEO, \
- GrlContentVideo))
-
-#define GRL_CONTENT_VIDEO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_CONTENT_VIDEO, \
- GrlContentVideoClass))
-
-#define GRL_IS_CONTENT_VIDEO(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_CONTENT_VIDEO))
-
-#define GRL_IS_CONTENT_VIDEO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_CONTENT_VIDEO))
-
-#define GRL_CONTENT_VIDEO_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_CONTENT_VIDEO, \
- GrlContentVideoClass))
-
-typedef struct _GrlContentVideo GrlContentVideo;
-typedef struct _GrlContentVideoClass GrlContentVideoClass;
-
-struct _GrlContentVideoClass
-{
- GrlContentMediaClass parent_class;
-};
-
-struct _GrlContentVideo
-{
- GrlContentMedia parent;
-};
-
-#define grl_content_video_set_width(content, width) \
- grl_content_set_int(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_WIDTH, \
- (width))
-
-#define grl_content_video_set_height(content, height) \
- grl_content_set_int(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_HEIGHT, \
- (height))
-
-#define grl_content_video_set_framerate(content, framerate) \
- grl_content_set_float(GRL_CONTENT((content)), \
- GRL_METADATA_KEY_FRAMERATE, \
- (framerate))
-
-#define grl_content_video_get_width(content) \
- grl_content_get_int(GRL_CONTENT((content)), GRL_METADATA_KEY_WIDTH)
-#define grl_content_video_get_height(content) \
- grl_content_get_int(GRL_CONTENT((content)), GRL_METADATA_KEY_HEIGHT)
-#define grl_content_video_get_framerate(content) \
- grl_content_get_float(GRL_CONTENT((content)), GRL_METADATA_KEY_FRAMERATE)
-
-GType grl_content_video_get_type (void) G_GNUC_CONST;
-
-GrlContentMedia *grl_content_video_new (void);
-
-void grl_content_video_set_size (GrlContentVideo *content,
- gint width,
- gint height);
-
-G_END_DECLS
-
-#endif /* _GRL_CONTENT_VIDEO_H_ */
diff --git a/src/content/grl-content.c b/src/content/grl-content.c
deleted file mode 100644
index e20cb52..0000000
--- a/src/content/grl-content.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-/*
- * Low-level class to store content.
- *
- * This class acts as dictionary where keys and their values can be stored. It
- * is suggested to better high level classes, like #GrlContentMedia, which
- * provides functions to access known properties.
- *
- */
-
-#include "grl-content.h"
-
-enum {
- PROP_0,
- PROP_OVERWRITE
-};
-
-struct _GrlContentPrivate {
- GHashTable *data;
- gboolean overwrite;
-};
-
-static void grl_content_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-
-static void grl_content_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void grl_content_finalize (GObject *object);
-
-#define GRL_CONTENT_GET_PRIVATE(o) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((o), GRL_TYPE_CONTENT, GrlContentPrivate))
-
-G_DEFINE_TYPE (GrlContent, grl_content, G_TYPE_OBJECT);
-
-static void
-free_val (GValue *val)
-{
- if (val) {
- g_value_unset (val);
- g_free (val);
- }
-}
-
-static void
-grl_content_class_init (GrlContentClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass *)klass;
-
- gobject_class->set_property = grl_content_set_property;
- gobject_class->get_property = grl_content_get_property;
- gobject_class->finalize = grl_content_finalize;
-
- g_type_class_add_private (klass, sizeof (GrlContentPrivate));
-
- g_object_class_install_property (gobject_class,
- PROP_OVERWRITE,
- g_param_spec_boolean ("overwrite",
- "Overwrite",
- "Overwrite current values",
- FALSE,
- G_PARAM_READWRITE));
-}
-
-static void
-grl_content_init (GrlContent *self)
-{
- self->priv = GRL_CONTENT_GET_PRIVATE (self);
- self->priv->data = g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- (GDestroyNotify) free_val);
-}
-
-static void
-grl_content_finalize (GObject *object)
-{
- g_signal_handlers_destroy (object);
- G_OBJECT_CLASS (grl_content_parent_class)->finalize (object);
-}
-
-static void
-grl_content_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GrlContent *self = GRL_CONTENT (object);
-
- switch (prop_id) {
- case PROP_OVERWRITE:
- self->priv->overwrite = g_value_get_boolean (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-grl_content_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GrlContent *self = GRL_CONTENT (object);
-
- switch (prop_id) {
- case PROP_OVERWRITE:
- g_value_set_boolean (value, self->priv->overwrite);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * grl_content_new:
- *
- * Creates a new content object.
- *
- * Returns: a new content object.
- **/
-GrlContent *
-grl_content_new (void)
-{
- return g_object_new (GRL_TYPE_CONTENT,
- NULL);
-}
-
-/**
- * grl_content_get:
- * @content: content to retrieve value
- * @key: key to look up.
- *
- * Get the value associated with the key. If it does not contain any value, NULL
- * will be returned.
- *
- * Returns: a #GValue. This value should not be modified nor freed by user.
- **/
-const GValue *
-grl_content_get (GrlContent *content, GrlKeyID key)
-{
- g_return_val_if_fail (GRL_IS_CONTENT (content), NULL);
-
- return g_hash_table_lookup (content->priv->data, GRLKEYID_TO_POINTER(key));
-}
-
-/**
- * grl_content_set:
- * @content: content to modify
- * @key: key to change or add
- * @value: the new value
- *
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is freed and the new one is set.
- **/
-void
-grl_content_set (GrlContent *content, GrlKeyID key, const GValue *value)
-{
- GValue *copy = NULL;
- g_return_if_fail (GRL_IS_CONTENT (content));
-
- if (content->priv->overwrite ||
- g_hash_table_lookup (content->priv->data,
- GRLKEYID_TO_POINTER (key)) == NULL) {
- /* Dup value */
- if (value) {
- copy = g_new0 (GValue, 1);
- g_value_init (copy, G_VALUE_TYPE (value));
- g_value_copy (value, copy);
- }
-
- g_hash_table_insert (content->priv->data, GRLKEYID_TO_POINTER(key), copy);
- }
-}
-
-/**
- * grl_content_set_string:
- * @content: content to modify
- * @key: key to change or add
- * @strvalue: the new value
- *
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is freed and the new one is set.
- **/
-void
-grl_content_set_string (GrlContent *content,
- GrlKeyID key,
- const gchar *strvalue)
-{
- GValue value = { 0 };
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, strvalue);
- grl_content_set (content, key, &value);
- g_value_unset (&value);
-}
-
-/**
- * grl_content_get_string:
- * @content: content to inspect
- * @key: key to use
- *
- * Returns the value associated with the key. If key has no value, or value is
- * not string, or key is not in content, then NULL is returned.
- *
- * Returns: string associated with key, or NULL in other case. Caller should not
- * change nor free the value.
- **/
-const gchar *
-grl_content_get_string (GrlContent *content, GrlKeyID key)
-{
- const GValue *value = grl_content_get (content, key);
-
- if (!value || !G_VALUE_HOLDS_STRING(value)) {
- return NULL;
- } else {
- return g_value_get_string (value);
- }
-}
-
-/**
- * grl_content_set_int:
- * @content: content to change
- * @key: key to change or addd
- * @intvalue: the new value
- *
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is replaced by the new one.
- **/
-void
-grl_content_set_int (GrlContent *content, GrlKeyID key, gint intvalue)
-{
- GValue value = { 0 };
- g_value_init (&value, G_TYPE_INT);
- g_value_set_int (&value, intvalue);
- grl_content_set (content, key, &value);
-}
-
-/**
- * grl_content_get_int:
- * @content: content to inspect
- * @key: key to use
- *
- * Returns the value associated with the key. If key has no value, or value is
- * not a gint, or key is not in content, then 0 is returned.
- *
- * Returns: int value associated with key, or 0 in other case.
- **/
-gint
-grl_content_get_int (GrlContent *content, GrlKeyID key)
-{
- const GValue *value = grl_content_get (content, key);
-
- if (!value || !G_VALUE_HOLDS_INT(value)) {
- return 0;
- } else {
- return g_value_get_int (value);
- }
-}
-
-/**
- * grl_content_set_float:
- * @content: content to change
- * @key: key to change or addd
- * @floatvalue: the new value
- *
- * Sets the value associated with the key. If key already has a value and
- * #overwrite is TRUE, old value is replaced by the new one.
- **/
-void
-grl_content_set_float (GrlContent *content, GrlKeyID key, gint floatvalue)
-{
- GValue value = { 0 };
- g_value_init (&value, G_TYPE_FLOAT);
- g_value_set_float (&value, floatvalue);
- grl_content_set (content, key, &value);
-}
-
-/**
- * grl_content_get_float:
- * @content: content to inspect
- * @key: key to use
- *
- * Returns the value associated with the key. If key has no value, or value is
- * not a gfloat, or key is not in content, then 0 is returned.
- *
- * Returns: float value associated with key, or 0 in other case.
- **/
-gfloat
-grl_content_get_float (GrlContent *content, GrlKeyID key)
-{
- const GValue *value = grl_content_get (content, key);
-
- if (!value || !G_VALUE_HOLDS_FLOAT(value)) {
- return 0;
- } else {
- return g_value_get_float (value);
- }
-}
-
-/**
- * grl_content_add:
- * @content: content to change
- * @key: key to add
- *
- * Adds a new key to content, with no value. If key already exists, it does
- * nothing.
- **/
-void
-grl_content_add (GrlContent *content, GrlKeyID key)
-{
- if (!grl_content_has_key (content, key)) {
- grl_content_set (content, key, NULL);
- }
-}
-
-/**
- * grl_content_remove:
- * @content: content to change
- * @key: key to remove
- *
- * Removes key from content, freeing its value. If key is not in content, then
- * it does nothing.
- **/
-void
-grl_content_remove (GrlContent *content, GrlKeyID key)
-{
- g_return_if_fail (GRL_IS_CONTENT (content));
-
- g_hash_table_remove (content->priv->data, GRLKEYID_TO_POINTER(key));
-}
-
-/**
- * grl_content_has_key:
- * @content: content to inspect
- * @key: key to search
- *
- * Checks if key is in content.
- *
- * Returns: TRUE if key is in content, FALSE in other case.
- **/
-gboolean
-grl_content_has_key (GrlContent *content, GrlKeyID key)
-{
- g_return_val_if_fail (GRL_IS_CONTENT (content), FALSE);
-
- return g_hash_table_lookup_extended (content->priv->data,
- GRLKEYID_TO_POINTER(key), NULL, NULL);
-}
-
-/**
- * grl_content_get_keys:
- * @content: content to inspect
- *
- * Returns a list with keys contained in content.
- *
- * Returns: an array with the keys.
- **/
-GList *
-grl_content_get_keys (GrlContent *content)
-{
- GList *keylist;
-
- g_return_val_if_fail (GRL_IS_CONTENT (content), NULL);
-
- keylist = g_hash_table_get_keys (content->priv->data);
-
- return keylist;
-}
-
-/**
- * grl_content_key_is_known:
- * @content: content to inspect
- * @key: key to search
- *
- * Checks if the key has a value.
- *
- * Returns: TRUE if key has a value.
- **/
-gboolean
-grl_content_key_is_known (GrlContent *content, GrlKeyID key)
-{
- GValue *v;
-
- g_return_val_if_fail (GRL_IS_CONTENT (content), FALSE);
-
- v = g_hash_table_lookup (content->priv->data,
- GRLKEYID_TO_POINTER(key));
-
- if (!v) {
- return FALSE;
- }
-
- if (G_VALUE_HOLDS_STRING (v)) {
- return g_value_get_string(v) != NULL;
- }
-
- return TRUE;
-}
-
-/**
- * grl_content_set_overwrite:
- * @content: content to change
- * @overwrite: if content can be overwritten
- *
- * This controls if #grl_content_set will overwrite current value of a property
- * with the new one.
- *
- * Set it to TRUE so old values are overwritten, or FALSE in other case (default
- * is FALSE).
- **/
-void
-grl_content_set_overwrite (GrlContent *content, gboolean overwrite)
-{
- g_return_if_fail (GRL_IS_CONTENT (content));
-
- if (content->priv->overwrite != overwrite) {
- content->priv->overwrite = overwrite;
- g_object_notify (G_OBJECT (content), "overwrite");
- }
-}
-
-/**
- * grl_content_get_overwrite:
- * @content: content to inspect
- *
- * Checks if old values are replaced when calling #grl_content_set.
- *
- * Returns: TRUE if values will be overwritten.
- **/
-gboolean
-grl_content_get_overwrite (GrlContent *content)
-{
- g_return_val_if_fail (GRL_IS_CONTENT (content), FALSE);
-
- return content->priv->overwrite;
-}
diff --git a/src/content/grl-content.h b/src/content/grl-content.h
deleted file mode 100644
index 8330e29..0000000
--- a/src/content/grl-content.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2010 Igalia S.L.
- *
- * Contact: Iago Toral Quiroga <itoral@igalia.com>
- *
- * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef _GRL_CONTENT_H_
-#define _GRL_CONTENT_H_
-
-#include <glib-object.h>
-#include <grl-metadata-key.h>
-
-G_BEGIN_DECLS
-
-#define GRL_TYPE_CONTENT \
- (grl_content_get_type())
-
-#define GRL_CONTENT(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- GRL_TYPE_CONTENT, \
- GrlContent))
-
-#define GRL_CONTENT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), \
- GRL_TYPE_CONTENT, \
- GrlContentClass))
-
-#define GRL_IS_CONTENT(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
- GRL_TYPE_CONTENT))
-
-#define GRL_IS_CONTENT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), \
- GRL_TYPE_CONTENT))
-
-#define GRL_CONTENT_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- GRL_TYPE_CONTENT, \
- ContentClass))
-
-typedef struct _GrlContent GrlContent;
-typedef struct _GrlContentPrivate GrlContentPrivate;
-typedef struct _GrlContentClass GrlContentClass;
-
-struct _GrlContentClass
-{
- GObjectClass parent_class;
-};
-
-struct _GrlContent
-{
- GObject parent;
-
- GrlContentPrivate *priv;
-};
-
-GType grl_content_get_type (void) G_GNUC_CONST;
-
-GrlContent *grl_content_new (void);
-
-void grl_content_set (GrlContent *content, GrlKeyID key, const GValue *value);
-
-void grl_content_set_string (GrlContent *content,
- GrlKeyID key,
- const gchar *strvalue);
-
-void grl_content_set_int (GrlContent *content, GrlKeyID key, gint intvalue);
-
-void grl_content_set_float (GrlContent *content,
- GrlKeyID key,
- gint floatvalue);
-
-const GValue *grl_content_get (GrlContent *content, GrlKeyID key);
-
-const gchar *grl_content_get_string (GrlContent *content, GrlKeyID key);
-
-gint grl_content_get_int (GrlContent *content, GrlKeyID key);
-
-gfloat grl_content_get_float (GrlContent *content, GrlKeyID key);
-
-void grl_content_add (GrlContent *content, GrlKeyID key);
-
-void grl_content_remove (GrlContent *content, GrlKeyID key);
-
-gboolean grl_content_has_key (GrlContent *content, GrlKeyID key);
-
-GList *grl_content_get_keys (GrlContent *content);
-
-gboolean grl_content_key_is_known (GrlContent *content, GrlKeyID key);
-
-void grl_content_set_overwrite (GrlContent *content, gboolean overwrite);
-
-gboolean grl_content_get_overwrite (GrlContent *content);
-
-G_END_DECLS
-
-#endif /* _GRL_CONTENT_H_ */
diff --git a/src/data/grl-config.c b/src/data/grl-config.c
new file mode 100644
index 0000000..12a5117
--- /dev/null
+++ b/src/data/grl-config.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:grl-config
+ * @short_description: Configuration data storage
+ * @see_also: #GrlData
+ *
+ * This class is used to store configuration settings used by plugins.
+ */
+
+#include "grl-config.h"
+
+#undef G_LOG_DOMAIN
+#define G_LOG_DOMAIN "grl-config"
+
+static void grl_config_dispose (GObject *object);
+static void grl_config_finalize (GObject *object);
+
+G_DEFINE_TYPE (GrlConfig, grl_config, GRL_TYPE_DATA);
+
+static void
+grl_config_class_init (GrlConfigClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+
+ gobject_class->dispose = grl_config_dispose;
+ gobject_class->finalize = grl_config_finalize;
+}
+
+static void
+grl_config_init (GrlConfig *self)
+{
+}
+
+static void
+grl_config_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (grl_config_parent_class)->dispose (object);
+}
+
+static void
+grl_config_finalize (GObject *object)
+{
+ g_debug ("grl_config_finalize");
+ g_signal_handlers_destroy (object);
+ G_OBJECT_CLASS (grl_config_parent_class)->finalize (object);
+}
+
+/**
+ * grl_config_new:
+ * @plugin: plugin id for this configuration
+ * @source: source id for this configuration
+ *
+ * Creates a new data config object that will be associated with a plugin
+ * (if @source is NULL), or a specific source spawned from a plugin (if
+ * @source is not NULL). The latter may be useful for plugins
+ * spawning various sources, each one needing a different configuration.
+ *
+ * Returns: a newly-allocated data config.
+ */
+GrlConfig *
+grl_config_new (const gchar *plugin, const gchar *source)
+{
+ g_return_val_if_fail (plugin != NULL, NULL);
+ GrlConfig *config = g_object_new (GRL_TYPE_CONFIG, NULL);
+ if (plugin) {
+ grl_config_set_plugin (config, plugin);
+ }
+ if (source) {
+ grl_config_set_source (config, plugin);
+ }
+
+ return config;
+}
diff --git a/src/data/grl-config.h b/src/data/grl-config.h
new file mode 100644
index 0000000..1ca24e6
--- /dev/null
+++ b/src/data/grl-config.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_CONFIG_H_
+#define _GRL_CONFIG_H_
+
+#include <grl-data.h>
+
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_CONFIG \
+ (grl_config_get_type())
+
+#define GRL_CONFIG(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_CONFIG, \
+ GrlConfig))
+
+#define GRL_CONFIG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_CONFIG, \
+ GrlConfigClass))
+
+#define GRL_IS_CONFIG(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_CONFIG))
+
+#define GRL_IS_CONFIG_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_CONFIG))
+
+#define GRL_CONFIG_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_CONFIG, \
+ GrlConfigClass))
+
+
+#define GRL_CONFIG_KEY_PLUGIN 1
+#define GRL_CONFIG_KEY_PLUGIN_NAME "plugin"
+#define GRL_CONFIG_KEY_PLUGIN_DESC "Plugin ID to which the configuration applies"
+
+#define GRL_CONFIG_KEY_SOURCE 2
+#define GRL_CONFIG_KEY_SOURCE_NAME "source"
+#define GRL_CONFIG_KEY_SOURCE_DESC "Source ID to which the configuration applies"
+
+#define GRL_CONFIG_KEY_APIKEY 3
+#define GRL_CONFIG_KEY_APIKEY_NAME "api-key"
+#define GRL_CONFIG_KEY_APIKEY_DESC "API Key"
+
+#define GRL_CONFIG_KEY_APITOKEN 4
+#define GRL_CONFIG_KEY_APITOKEN_NAME "api-token"
+#define GRL_CONFIG_KEY_APITOKEN_DESC "API token"
+
+#define GRL_CONFIG_KEY_APISECRET 5
+#define GRL_CONFIG_KEY_APISECRET_NAME "api-secret"
+#define GRL_CONFIG_KEY_APISECRET_DESC "API secret"
+
+typedef struct _GrlConfig GrlConfig;
+typedef struct _GrlConfigClass GrlConfigClass;
+
+/**
+ * GrlConfigClass:
+ * @parent_class: the parent class structure
+ *
+ * Grilo Config Class
+ */
+struct _GrlConfigClass
+{
+ GrlDataClass parent_class;
+};
+
+struct _GrlConfig
+{
+ GrlData parent;
+};
+
+/**
+ * grl_config_set_plugin:
+ * @data: the config instance
+ * @plugin: the plugin id
+ *
+ * Set the plugin key in the configuration
+ */
+#define grl_config_set_plugin(data, plugin) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_CONFIG_KEY_PLUGIN, \
+ (plugin)) \
+
+/**
+ * grl_config_set_source:
+ * @data: the config instance
+ * @source: the source id
+ *
+ * Set the plugin key in the configuration
+ */
+#define grl_config_set_source(data, source) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_CONFIG_KEY_SOURCE, \
+ (source)) \
+
+/**
+ * grl_config_set_api_key:
+ * @data: the config instance
+ * @key: the API key
+ *
+ * Set the webservice API key in the configuration
+ */
+#define grl_config_set_api_key(data, key) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_CONFIG_KEY_APIKEY, \
+ (key))
+
+/**
+ * grl_config_set_api_token:
+ * @data: the config instance
+ * @token: the API token
+ *
+ * Set the webservice API token in the configuration
+ */
+#define grl_config_set_api_token(data, token) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_CONFIG_KEY_APITOKEN, \
+ (token))
+
+/**
+ * grl_config_set_api_secret:
+ * @data: the config instance
+ * @secret: the webservice passphrase
+ *
+ * Set the webservice passphrase in the configuration
+ */
+#define grl_config_set_api_secret(data, secret) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_CONFIG_KEY_APISECRET, \
+ (secret))
+
+/**
+ * grl_config_get_plugin:
+ * @data: the config instance
+ *
+ * Returns: (type utf8) (transfer none): the plugin id
+ */
+#define grl_config_get_plugin(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_CONFIG_KEY_PLUGIN)
+
+/**
+ * grl_config_get_api_key:
+ * @data: the config instance
+ *
+ * Returns: (type utf8) (transfer none): the webservice API key
+ */
+#define grl_config_get_api_key(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_CONFIG_KEY_APIKEY)
+
+/**
+ * grl_config_get_api_token:
+ * @data: the config instance
+ *
+ * Returns: (type utf8) (transfer none): the webservice API token
+ */
+#define grl_config_get_api_token(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_CONFIG_KEY_APITOKEN)
+
+/**
+ * grl_config_get_api_secret:
+ * @data: the config instance
+ *
+ * Returns: (type utf8) (transfer none): the webservice API passphrase
+ */
+#define grl_config_get_api_secret(data) \
+grl_data_get_string(GRL_DATA((data)), GRL_CONFIG_KEY_APISECRET)
+
+GType grl_config_get_type (void) G_GNUC_CONST;
+GrlConfig *grl_config_new (const gchar *plugin, const gchar *source);
+
+G_END_DECLS
+
+#endif /* _GRL_CONFIG_H_ */
diff --git a/src/data/grl-data.c b/src/data/grl-data.c
new file mode 100644
index 0000000..dc1e4b3
--- /dev/null
+++ b/src/data/grl-data.c
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:grl-data
+ * @short_description: Low-level class to store data
+ * @see_also: #GrlMedia, #GrlMediaBox, #GrlMediaVideo, #GrlMediaAudio, #GrlMediaImage
+ *
+ * This class acts as dictionary where keys and their values can be stored. It
+ * is suggested to better high level classes, like #GrlMedia, which
+ * provides functions to access known properties.
+ */
+
+#include "grl-data.h"
+
+enum {
+ PROP_0,
+ PROP_OVERWRITE
+};
+
+struct _GrlDataPrivate {
+ GHashTable *data;
+ gboolean overwrite;
+};
+
+static void grl_data_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void grl_data_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void grl_data_finalize (GObject *object);
+
+#define GRL_DATA_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GRL_TYPE_DATA, GrlDataPrivate))
+
+G_DEFINE_TYPE (GrlData, grl_data, G_TYPE_OBJECT);
+
+static void
+free_val (GValue *val)
+{
+ if (val) {
+ g_value_unset (val);
+ g_free (val);
+ }
+}
+
+static void
+grl_data_class_init (GrlDataClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+
+ gobject_class->set_property = grl_data_set_property;
+ gobject_class->get_property = grl_data_get_property;
+ gobject_class->finalize = grl_data_finalize;
+
+ g_type_class_add_private (klass, sizeof (GrlDataPrivate));
+
+ g_object_class_install_property (gobject_class,
+ PROP_OVERWRITE,
+ g_param_spec_boolean ("overwrite",
+ "Overwrite",
+ "Overwrite current values",
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+grl_data_init (GrlData *self)
+{
+ self->priv = GRL_DATA_GET_PRIVATE (self);
+ self->priv->data = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify) free_val);
+}
+
+static void
+grl_data_finalize (GObject *object)
+{
+ g_signal_handlers_destroy (object);
+ G_OBJECT_CLASS (grl_data_parent_class)->finalize (object);
+}
+
+static void
+grl_data_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GrlData *self = GRL_DATA (object);
+
+ switch (prop_id) {
+ case PROP_OVERWRITE:
+ self->priv->overwrite = g_value_get_boolean (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+grl_data_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GrlData *self = GRL_DATA (object);
+
+ switch (prop_id) {
+ case PROP_OVERWRITE:
+ g_value_set_boolean (value, self->priv->overwrite);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * grl_data_new:
+ *
+ * Creates a new data object.
+ *
+ * Returns: a new data object.
+ **/
+GrlData *
+grl_data_new (void)
+{
+ return g_object_new (GRL_TYPE_DATA,
+ NULL);
+}
+
+/**
+ * grl_data_get:
+ * @data: data to retrieve value
+ * @key: key to look up.
+ *
+ * Get the value associated with the key. If it does not contain any value, NULL
+ * will be returned.
+ *
+ * Returns: (transfer none) a #GValue. This value should not be modified nor freed by user.
+ **/
+const GValue *
+grl_data_get (GrlData *data, GrlKeyID key)
+{
+ g_return_val_if_fail (GRL_IS_DATA (data), NULL);
+
+ return g_hash_table_lookup (data->priv->data, GRLKEYID_TO_POINTER(key));
+}
+
+/**
+ * grl_data_set:
+ * @data: data to modify
+ * @key: key to change or add
+ * @value: the new value
+ *
+ * Sets the value associated with the key. If key already has a value and
+ * #overwrite is TRUE, old value is freed and the new one is set.
+ **/
+void
+grl_data_set (GrlData *data, GrlKeyID key, const GValue *value)
+{
+ GValue *copy = NULL;
+ g_return_if_fail (GRL_IS_DATA (data));
+
+ if (data->priv->overwrite ||
+ g_hash_table_lookup (data->priv->data,
+ GRLKEYID_TO_POINTER (key)) == NULL) {
+ /* Dup value */
+ if (value) {
+ copy = g_new0 (GValue, 1);
+ g_value_init (copy, G_VALUE_TYPE (value));
+ g_value_copy (value, copy);
+ }
+
+ g_hash_table_insert (data->priv->data, GRLKEYID_TO_POINTER(key), copy);
+ }
+}
+
+/**
+ * grl_data_set_string:
+ * @data: data to modify
+ * @key: key to change or add
+ * @strvalue: the new value
+ *
+ * Sets the value associated with the key. If key already has a value and
+ * #overwrite is TRUE, old value is freed and the new one is set.
+ **/
+void
+grl_data_set_string (GrlData *data,
+ GrlKeyID key,
+ const gchar *strvalue)
+{
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, strvalue);
+ grl_data_set (data, key, &value);
+ g_value_unset (&value);
+}
+
+/**
+ * grl_data_get_string:
+ * @data: data to inspect
+ * @key: key to use
+ *
+ * Returns the value associated with the key. If key has no value, or value is
+ * not string, or key is not in data, then NULL is returned.
+ *
+ * Returns: (transfer none): string associated with key, or NULL in other case. Caller should not change nor free the value.
+ **/
+const gchar *
+grl_data_get_string (GrlData *data, GrlKeyID key)
+{
+ const GValue *value = grl_data_get (data, key);
+
+ if (!value || !G_VALUE_HOLDS_STRING(value)) {
+ return NULL;
+ } else {
+ return g_value_get_string (value);
+ }
+}
+
+/**
+ * grl_data_set_int:
+ * @data: data to change
+ * @key: key to change or addd
+ * @intvalue: the new value
+ *
+ * Sets the value associated with the key. If key already has a value and
+ * #overwrite is TRUE, old value is replaced by the new one.
+ **/
+void
+grl_data_set_int (GrlData *data, GrlKeyID key, gint intvalue)
+{
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_INT);
+ g_value_set_int (&value, intvalue);
+ grl_data_set (data, key, &value);
+}
+
+/**
+ * grl_data_get_int:
+ * @data: data to inspect
+ * @key: key to use
+ *
+ * Returns the value associated with the key. If key has no value, or value is
+ * not a gint, or key is not in data, then 0 is returned.
+ *
+ * Returns: int value associated with key, or 0 in other case.
+ **/
+gint
+grl_data_get_int (GrlData *data, GrlKeyID key)
+{
+ const GValue *value = grl_data_get (data, key);
+
+ if (!value || !G_VALUE_HOLDS_INT(value)) {
+ return 0;
+ } else {
+ return g_value_get_int (value);
+ }
+}
+
+/**
+ * grl_data_set_float:
+ * @data: data to change
+ * @key: key to change or addd
+ * @floatvalue: the new value
+ *
+ * Sets the value associated with the key. If key already has a value and
+ * #overwrite is TRUE, old value is replaced by the new one.
+ **/
+void
+grl_data_set_float (GrlData *data, GrlKeyID key, gint floatvalue)
+{
+ GValue value = { 0 };
+ g_value_init (&value, G_TYPE_FLOAT);
+ g_value_set_float (&value, floatvalue);
+ grl_data_set (data, key, &value);
+}
+
+/**
+ * grl_data_get_float:
+ * @data: data to inspect
+ * @key: key to use
+ *
+ * Returns the value associated with the key. If key has no value, or value is
+ * not a gfloat, or key is not in data, then 0 is returned.
+ *
+ * Returns: float value associated with key, or 0 in other case.
+ **/
+gfloat
+grl_data_get_float (GrlData *data, GrlKeyID key)
+{
+ const GValue *value = grl_data_get (data, key);
+
+ if (!value || !G_VALUE_HOLDS_FLOAT(value)) {
+ return 0;
+ } else {
+ return g_value_get_float (value);
+ }
+}
+
+/**
+ * grl_data_add:
+ * @data: data to change
+ * @key: key to add
+ *
+ * Adds a new key to data, with no value. If key already exists, it does
+ * nothing.
+ **/
+void
+grl_data_add (GrlData *data, GrlKeyID key)
+{
+ if (!grl_data_has_key (data, key)) {
+ grl_data_set (data, key, NULL);
+ }
+}
+
+/**
+ * grl_data_remove:
+ * @data: data to change
+ * @key: key to remove
+ *
+ * Removes key from data, freeing its value. If key is not in data, then
+ * it does nothing.
+ **/
+void
+grl_data_remove (GrlData *data, GrlKeyID key)
+{
+ g_return_if_fail (GRL_IS_DATA (data));
+
+ g_hash_table_remove (data->priv->data, GRLKEYID_TO_POINTER(key));
+}
+
+/**
+ * grl_data_has_key:
+ * @data: data to inspect
+ * @key: key to search
+ *
+ * Checks if key is in data.
+ *
+ * Returns: TRUE if key is in data, FALSE in other case.
+ **/
+gboolean
+grl_data_has_key (GrlData *data, GrlKeyID key)
+{
+ g_return_val_if_fail (GRL_IS_DATA (data), FALSE);
+
+ return g_hash_table_lookup_extended (data->priv->data,
+ GRLKEYID_TO_POINTER(key), NULL, NULL);
+}
+
+/**
+ * grl_data_get_keys:
+ * @data: data to inspect
+ *
+ * Returns a list with keys contained in data.
+ *
+ * Returns: an array with the keys.
+ **/
+GList *
+grl_data_get_keys (GrlData *data)
+{
+ GList *keylist;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), NULL);
+
+ keylist = g_hash_table_get_keys (data->priv->data);
+
+ return keylist;
+}
+
+/**
+ * grl_data_key_is_known:
+ * @data: data to inspect
+ * @key: key to search
+ *
+ * Checks if the key has a value.
+ *
+ * Returns: TRUE if key has a value.
+ **/
+gboolean
+grl_data_key_is_known (GrlData *data, GrlKeyID key)
+{
+ GValue *v;
+
+ g_return_val_if_fail (GRL_IS_DATA (data), FALSE);
+
+ v = g_hash_table_lookup (data->priv->data,
+ GRLKEYID_TO_POINTER(key));
+
+ if (!v) {
+ return FALSE;
+ }
+
+ if (G_VALUE_HOLDS_STRING (v)) {
+ return g_value_get_string(v) != NULL;
+ }
+
+ return TRUE;
+}
+
+/**
+ * grl_data_set_overwrite:
+ * @data: data to change
+ * @overwrite: if data can be overwritten
+ *
+ * This controls if #grl_data_set will overwrite current value of a property
+ * with the new one.
+ *
+ * Set it to TRUE so old values are overwritten, or FALSE in other case (default
+ * is FALSE).
+ **/
+void
+grl_data_set_overwrite (GrlData *data, gboolean overwrite)
+{
+ g_return_if_fail (GRL_IS_DATA (data));
+
+ if (data->priv->overwrite != overwrite) {
+ data->priv->overwrite = overwrite;
+ g_object_notify (G_OBJECT (data), "overwrite");
+ }
+}
+
+/**
+ * grl_data_get_overwrite:
+ * @data: data to inspect
+ *
+ * Checks if old values are replaced when calling #grl_data_set.
+ *
+ * Returns: TRUE if values will be overwritten.
+ **/
+gboolean
+grl_data_get_overwrite (GrlData *data)
+{
+ g_return_val_if_fail (GRL_IS_DATA (data), FALSE);
+
+ return data->priv->overwrite;
+}
diff --git a/src/data/grl-data.h b/src/data/grl-data.h
new file mode 100644
index 0000000..500a297
--- /dev/null
+++ b/src/data/grl-data.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_DATA_H_
+#define _GRL_DATA_H_
+
+#include <glib-object.h>
+#include <grl-metadata-key.h>
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_DATA \
+ (grl_data_get_type())
+
+#define GRL_DATA(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_DATA, \
+ GrlData))
+
+#define GRL_DATA_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_DATA, \
+ GrlDataClass))
+
+#define GRL_IS_DATA(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_DATA))
+
+#define GRL_IS_DATA_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_DATA))
+
+#define GRL_DATA_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_DATA, \
+ DataClass))
+
+typedef struct _GrlData GrlData;
+typedef struct _GrlDataPrivate GrlDataPrivate;
+typedef struct _GrlDataClass GrlDataClass;
+
+/**
+ * GrlDataClass:
+ * @parent_class: the parent class structure
+ *
+ * Grilo Data class
+ */
+struct _GrlDataClass
+{
+ GObjectClass parent_class;
+};
+
+struct _GrlData
+{
+ GObject parent;
+
+ /*< private >*/
+ GrlDataPrivate *priv;
+};
+
+GType grl_data_get_type (void) G_GNUC_CONST;
+
+GrlData *grl_data_new (void);
+
+void grl_data_set (GrlData *data, GrlKeyID key, const GValue *value);
+
+void grl_data_set_string (GrlData *data,
+ GrlKeyID key,
+ const gchar *strvalue);
+
+void grl_data_set_int (GrlData *data, GrlKeyID key, gint intvalue);
+
+void grl_data_set_float (GrlData *data,
+ GrlKeyID key,
+ gint floatvalue);
+
+const GValue *grl_data_get (GrlData *data, GrlKeyID key);
+
+const gchar *grl_data_get_string (GrlData *data, GrlKeyID key);
+
+gint grl_data_get_int (GrlData *data, GrlKeyID key);
+
+gfloat grl_data_get_float (GrlData *data, GrlKeyID key);
+
+void grl_data_add (GrlData *data, GrlKeyID key);
+
+void grl_data_remove (GrlData *data, GrlKeyID key);
+
+gboolean grl_data_has_key (GrlData *data, GrlKeyID key);
+
+GList *grl_data_get_keys (GrlData *data);
+
+gboolean grl_data_key_is_known (GrlData *data, GrlKeyID key);
+
+void grl_data_set_overwrite (GrlData *data, gboolean overwrite);
+
+gboolean grl_data_get_overwrite (GrlData *data);
+
+G_END_DECLS
+
+#endif /* _GRL_DATA_H_ */
diff --git a/src/content/grl-content-audio.c b/src/data/grl-media-audio.c
index 51ea6ab..3230a12 100644
--- a/src/content/grl-content-audio.c
+++ b/src/data/grl-media-audio.c
@@ -23,58 +23,58 @@
*/
/*
- * A multimedia content for audio.
+ * A multimedia data for audio.
*
* This high level class represents an audio multimedia item. It has methods to
* set and get properties like album, and so on.
*
*/
-#include "grl-content-audio.h"
+#include "grl-media-audio.h"
-static void grl_content_audio_dispose (GObject *object);
-static void grl_content_audio_finalize (GObject *object);
+static void grl_media_audio_dispose (GObject *object);
+static void grl_media_audio_finalize (GObject *object);
-G_DEFINE_TYPE (GrlContentAudio, grl_content_audio, GRL_TYPE_CONTENT_MEDIA);
+G_DEFINE_TYPE (GrlMediaAudio, grl_media_audio, GRL_TYPE_MEDIA);
static void
-grl_content_audio_class_init (GrlContentAudioClass *klass)
+grl_media_audio_class_init (GrlMediaAudioClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
- gobject_class->dispose = grl_content_audio_dispose;
- gobject_class->finalize = grl_content_audio_finalize;
+ gobject_class->dispose = grl_media_audio_dispose;
+ gobject_class->finalize = grl_media_audio_finalize;
}
static void
-grl_content_audio_init (GrlContentAudio *self)
+grl_media_audio_init (GrlMediaAudio *self)
{
}
static void
-grl_content_audio_dispose (GObject *object)
+grl_media_audio_dispose (GObject *object)
{
- G_OBJECT_CLASS (grl_content_audio_parent_class)->dispose (object);
+ G_OBJECT_CLASS (grl_media_audio_parent_class)->dispose (object);
}
static void
-grl_content_audio_finalize (GObject *object)
+grl_media_audio_finalize (GObject *object)
{
g_signal_handlers_destroy (object);
- G_OBJECT_CLASS (grl_content_audio_parent_class)->finalize (object);
+ G_OBJECT_CLASS (grl_media_audio_parent_class)->finalize (object);
}
/**
- * grl_content_audio_new:
+ * grl_media_audio_new:
*
- * Creates a new content audio object.
+ * Creates a new data audio object.
*
- * Returns: a newly-allocated content audio.
+ * Returns: a newly-allocated data audio.
**/
-GrlContentMedia *
-grl_content_audio_new (void)
+GrlMedia *
+grl_media_audio_new (void)
{
- return GRL_CONTENT_MEDIA (g_object_new (GRL_TYPE_CONTENT_AUDIO,
- NULL));
+ return GRL_MEDIA (g_object_new (GRL_TYPE_MEDIA_AUDIO,
+ NULL));
}
diff --git a/src/data/grl-media-audio.h b/src/data/grl-media-audio.h
new file mode 100644
index 0000000..02c96bb
--- /dev/null
+++ b/src/data/grl-media-audio.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_MEDIA_AUDIO_H_
+#define _GRL_MEDIA_AUDIO_H_
+
+#include <grl-media.h>
+
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_MEDIA_AUDIO \
+ (grl_media_audio_get_type())
+
+#define GRL_MEDIA_AUDIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_MEDIA_AUDIO, \
+ GrlMediaAudio))
+
+#define GRL_MEDIA_AUDIO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_MEDIA_AUDIO, \
+ GrlMediaAudioClass))
+
+#define GRL_IS_MEDIA_AUDIO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_MEDIA_AUDIO))
+
+#define GRL_IS_MEDIA_AUDIO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_MEDIA_AUDIO))
+
+#define GRL_MEDIA_AUDIO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_MEDIA_AUDIO, \
+ GrlMediaAudioClass))
+
+typedef struct _GrlMediaAudio GrlMediaAudio;
+typedef struct _GrlMediaAudioClass GrlMediaAudioClass;
+
+struct _GrlMediaAudioClass
+{
+ GrlMediaClass parent_class;
+};
+
+struct _GrlMediaAudio
+{
+ GrlMedia parent;
+};
+
+#define grl_media_audio_set_artist(data, artist) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_ARTIST, \
+ (artist))
+
+#define grl_media_audio_set_album(data, album) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_ALBUM, \
+ (album))
+
+#define grl_media_audio_set_genre(data, genre) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_GENRE, \
+ (genre))
+
+#define grl_media_audio_set_lyrics(data, lyrics) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_LYRICS, \
+ (lyrics))
+
+#define grl_media_audio_set_bitrate(data, bitrate) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_BITRATE, \
+ (bitrate))
+
+#define grl_media_audio_get_artist(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_ARTIST)
+#define grl_media_audio_get_album(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_ALBUM)
+#define grl_media_audio_get_genre(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_GENRE)
+#define grl_media_audio_get_lyrics(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_LYRICS)
+#define grl_media_audio_get_bitrate(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_BITRATE)
+
+GType grl_media_audio_get_type (void) G_GNUC_CONST;
+
+GrlMedia *grl_media_audio_new (void);
+
+G_END_DECLS
+
+#endif /* _GRL_MEDIA_AUDIO_H_ */
diff --git a/src/data/grl-media-box.c b/src/data/grl-media-box.c
new file mode 100644
index 0000000..b968219
--- /dev/null
+++ b/src/data/grl-media-box.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:grl-media-box
+ * @short_description: A container for multiple medias
+ * @see_also: #GrlMedia, #GrlMediaVideo, #GrlMediaAudio, #GrlMediaImage
+ *
+ * This high level class represents a container for multiple medias.
+ *
+ * Usually, when you get a media, it is either an Image, a Video or a Music
+ * file, but when you create a hierarchy, for instance
+ *
+ * <informalexample>
+ * ROOT -&gt; &lt;artist&gt; -&gt; &lt;album&gt; -&gt; &lt;media&gt;
+ * </informalexample>
+ *
+ * the medias are only the leaf nodes, but which kind of "media"
+ * is an album?
+ *
+ * #GrlMediaBox is used to represent this kind of nodes: it is a "box" which
+ * can be browsed to get the medias (or other boxes) under it.
+ *
+ * In fact, you can only browse through media-boxes.
+ */
+
+#include "grl-media-box.h"
+
+#define MIME_BOX "x-grl/box"
+
+static void grl_media_box_dispose (GObject *object);
+static void grl_media_box_finalize (GObject *object);
+
+G_DEFINE_TYPE (GrlMediaBox, grl_media_box, GRL_TYPE_MEDIA);
+
+static void
+grl_media_box_class_init (GrlMediaBoxClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+
+ gobject_class->dispose = grl_media_box_dispose;
+ gobject_class->finalize = grl_media_box_finalize;
+}
+
+static void
+grl_media_box_init (GrlMediaBox *self)
+{
+ grl_media_box_set_childcount (self, GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN);
+ grl_media_set_mime (GRL_MEDIA (self), MIME_BOX);
+}
+
+static void
+grl_media_box_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (grl_media_box_parent_class)->dispose (object);
+}
+
+static void
+grl_media_box_finalize (GObject *object)
+{
+ g_signal_handlers_destroy (object);
+ G_OBJECT_CLASS (grl_media_box_parent_class)->finalize (object);
+}
+
+/**
+ * grl_media_box_new:
+ *
+ * Creates a new data box object.
+ *
+ * Returns: a newly-allocated data box.
+ */
+GrlMedia *
+grl_media_box_new (void)
+{
+ return GRL_MEDIA (g_object_new (GRL_TYPE_MEDIA_BOX,
+ NULL));
+}
+
+/**
+ * grl_media_box_set_childcount:
+ * @box: the media box instance
+ * @childcount: number of children
+ *
+ * Sets the number of children of this box. Use
+ * #GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN if it is unknown.
+ */
+void
+grl_media_box_set_childcount (GrlMediaBox *box,
+ gint childcount)
+{
+ g_return_if_fail (GRL_IS_MEDIA_BOX (box));
+
+ if (childcount != GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN) {
+ grl_data_set_int (GRL_DATA (box),
+ GRL_METADATA_KEY_CHILDCOUNT,
+ childcount);
+ } else {
+ grl_data_set (GRL_DATA (box),
+ GRL_METADATA_KEY_CHILDCOUNT,
+ NULL);
+ }
+}
+
+/**
+ * grl_media_box_get_childcount:
+ * @box: the media box instance
+ *
+ * Number of children of this box.
+ *
+ * Returns: number of children, or #GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN if
+ * unknown.
+ */
+gint
+grl_media_box_get_childcount (GrlMediaBox *box)
+{
+ g_return_val_if_fail (GRL_IS_MEDIA_BOX (box),
+ GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN);
+
+ const GValue *value = grl_data_get (GRL_DATA (box),
+ GRL_METADATA_KEY_CHILDCOUNT);
+
+ if (value) {
+ return g_value_get_int (value);
+ } else {
+ return GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN;
+ }
+}
diff --git a/src/data/grl-media-box.h b/src/data/grl-media-box.h
new file mode 100644
index 0000000..623b016
--- /dev/null
+++ b/src/data/grl-media-box.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_MEDIA_BOX_H_
+#define _GRL_MEDIA_BOX_H_
+
+#include <grl-media.h>
+
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_MEDIA_BOX \
+ (grl_media_box_get_type())
+
+#define GRL_MEDIA_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_MEDIA_BOX, \
+ GrlMediaBox))
+
+#define GRL_MEDIA_BOX_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_MEDIA_BOX, \
+ GrlMediaBoxClass))
+
+#define GRL_IS_MEDIA_BOX(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_MEDIA_BOX))
+
+#define GRL_IS_MEDIA_BOX_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_MEDIA_BOX))
+
+#define GRL_MEDIA_BOX_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_MEDIA_BOX, \
+ GrlMediaBoxClass))
+
+typedef struct _GrlMediaBox GrlMediaBox;
+typedef struct _GrlMediaBoxClass GrlMediaBoxClass;
+
+/**
+ * GrlMediaBoxClass:
+ * @parent_class: the parent class structure
+ *
+ * Grilo Media box Class
+ */
+struct _GrlMediaBoxClass
+{
+ GrlMediaClass parent_class;
+};
+
+struct _GrlMediaBox
+{
+ GrlMedia parent;
+};
+
+GType grl_media_box_get_type (void) G_GNUC_CONST;
+GrlMedia *grl_media_box_new (void);
+void grl_media_box_set_childcount (GrlMediaBox *box, gint childcount);
+gint grl_media_box_get_childcount (GrlMediaBox *box);
+
+G_END_DECLS
+
+#endif /* _GRL_MEDIA_BOX_H_ */
diff --git a/src/content/grl-content-image.c b/src/data/grl-media-image.c
index 853d632..df5c63a 100644
--- a/src/content/grl-content-image.c
+++ b/src/data/grl-media-image.c
@@ -23,67 +23,67 @@
*/
/*
- * A multimedia content for image.
+ * A multimedia data for image.
*
* This high level class represents an image multimedia item. It has methods to
* set and get properties like framerate, width, height, and so on.
*
*/
-#include "grl-content-image.h"
+#include "grl-media-image.h"
-static void grl_content_image_dispose (GObject *object);
-static void grl_content_image_finalize (GObject *object);
+static void grl_media_image_dispose (GObject *object);
+static void grl_media_image_finalize (GObject *object);
-G_DEFINE_TYPE (GrlContentImage, grl_content_image, GRL_TYPE_CONTENT_MEDIA);
+G_DEFINE_TYPE (GrlMediaImage, grl_media_image, GRL_TYPE_MEDIA);
static void
-grl_content_image_class_init (GrlContentImageClass *klass)
+grl_media_image_class_init (GrlMediaImageClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
- gobject_class->dispose = grl_content_image_dispose;
- gobject_class->finalize = grl_content_image_finalize;
+ gobject_class->dispose = grl_media_image_dispose;
+ gobject_class->finalize = grl_media_image_finalize;
}
static void
-grl_content_image_init (GrlContentImage *self)
+grl_media_image_init (GrlMediaImage *self)
{
}
static void
-grl_content_image_dispose (GObject *object)
+grl_media_image_dispose (GObject *object)
{
- G_OBJECT_CLASS (grl_content_image_parent_class)->dispose (object);
+ G_OBJECT_CLASS (grl_media_image_parent_class)->dispose (object);
}
static void
-grl_content_image_finalize (GObject *object)
+grl_media_image_finalize (GObject *object)
{
g_signal_handlers_destroy (object);
- G_OBJECT_CLASS (grl_content_image_parent_class)->finalize (object);
+ G_OBJECT_CLASS (grl_media_image_parent_class)->finalize (object);
}
/**
- * grl_content_image_new:
+ * grl_media_image_new:
*
- * Creates a new content image object.
+ * Creates a new data image object.
*
- * Returns: a newly-allocated content image.
+ * Returns: a newly-allocated data image.
**/
-GrlContentMedia *
-grl_content_image_new (void)
+GrlMedia *
+grl_media_image_new (void)
{
- return GRL_CONTENT_MEDIA (g_object_new (GRL_TYPE_CONTENT_IMAGE,
- NULL));
+ return GRL_MEDIA (g_object_new (GRL_TYPE_MEDIA_IMAGE,
+ NULL));
}
void
-grl_content_image_set_size (GrlContentImage *content,
- gint width,
- int height)
+grl_media_image_set_size (GrlMediaImage *image,
+ gint width,
+ int height)
{
- grl_content_image_set_width (content, width);
- grl_content_image_set_height (content, height);
+ grl_media_image_set_width (image, width);
+ grl_media_image_set_height (image, height);
}
diff --git a/src/data/grl-media-image.h b/src/data/grl-media-image.h
new file mode 100644
index 0000000..3548e97
--- /dev/null
+++ b/src/data/grl-media-image.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_MEDIA_IMAGE_H_
+#define _GRL_MEDIA_IMAGE_H_
+
+#include <grl-media.h>
+
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_MEDIA_IMAGE \
+ (grl_media_image_get_type())
+
+#define GRL_MEDIA_IMAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_MEDIA_IMAGE, \
+ GrlMediaImage))
+
+#define GRL_MEDIA_IMAGE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_MEDIA_IMAGE, \
+ GrlMediaImageClass))
+
+#define GRL_IS_MEDIA_IMAGE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_MEDIA_IMAGE))
+
+#define GRL_IS_MEDIA_IMAGE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_MEDIA_IMAGE))
+
+#define GRL_MEDIA_IMAGE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_MEDIA_IMAGE, \
+ GrlMediaImageClass))
+
+typedef struct _GrlMediaImage GrlMediaImage;
+typedef struct _GrlMediaImageClass GrlMediaImageClass;
+
+struct _GrlMediaImageClass
+{
+ GrlMediaClass parent_class;
+};
+
+struct _GrlMediaImage
+{
+ GrlMedia parent;
+};
+
+#define grl_media_image_set_width(data, width) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_WIDTH, \
+ (width))
+
+#define grl_media_image_set_height(data, height) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_HEIGHT, \
+ (height))
+
+#define grl_media_image_get_width(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_WIDTH)
+#define grl_media_image_get_height(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_HEIGHT)
+
+GType grl_media_image_get_type (void) G_GNUC_CONST;
+GrlMedia *grl_media_image_new (void);
+void grl_media_image_set_size (GrlMediaImage *image,
+ gint width,
+ gint height);
+
+G_END_DECLS
+
+#endif /* _GRL_MEDIA_IMAGE_H_ */
diff --git a/src/data/grl-media-video.c b/src/data/grl-media-video.c
new file mode 100644
index 0000000..a4e064d
--- /dev/null
+++ b/src/data/grl-media-video.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+/**
+ * SECTION:grl-media-video
+ * @short_description: A multimedia data for video
+ * @see_also: #hGrlConfig, #GrlMediaBox, #GrlMediaAudio, #GrlMediaImage
+ *
+ * This high level class represents an video multimedia item. It has methods to
+ * set and get properties like framerate, width, height, and so on.
+ */
+
+#include "grl-media-video.h"
+
+
+static void grl_media_video_dispose (GObject *object);
+static void grl_media_video_finalize (GObject *object);
+
+G_DEFINE_TYPE (GrlMediaVideo, grl_media_video, GRL_TYPE_MEDIA);
+
+static void
+grl_media_video_class_init (GrlMediaVideoClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+
+ gobject_class->dispose = grl_media_video_dispose;
+ gobject_class->finalize = grl_media_video_finalize;
+}
+
+static void
+grl_media_video_init (GrlMediaVideo *self)
+{
+}
+
+static void
+grl_media_video_dispose (GObject *object)
+{
+ G_OBJECT_CLASS (grl_media_video_parent_class)->dispose (object);
+}
+
+static void
+grl_media_video_finalize (GObject *object)
+{
+ g_signal_handlers_destroy (object);
+ G_OBJECT_CLASS (grl_media_video_parent_class)->finalize (object);
+}
+
+/**
+ * grl_media_video_new:
+ *
+ * Creates a new data video object.
+ *
+ * Returns: a newly-allocated data video.
+ */
+GrlMedia *
+grl_media_video_new (void)
+{
+ return GRL_MEDIA (g_object_new (GRL_TYPE_MEDIA_VIDEO,
+ NULL));
+}
+
+/**
+ * grl_media_video_set_size:
+ * @video: the media instance
+ * @width: the video's width
+ * @height: the video's height
+ *
+ * Set the width and the height of the video
+ */
+void
+grl_media_video_set_size (GrlMediaVideo *video,
+ gint width,
+ int height)
+{
+ grl_media_video_set_width (video, width);
+ grl_media_video_set_height (video, height);
+}
diff --git a/src/data/grl-media-video.h b/src/data/grl-media-video.h
new file mode 100644
index 0000000..679195d
--- /dev/null
+++ b/src/data/grl-media-video.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_MEDIA_VIDEO_H_
+#define _GRL_MEDIA_VIDEO_H_
+
+#include <grl-media.h>
+
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_MEDIA_VIDEO \
+ (grl_media_video_get_type())
+
+#define GRL_MEDIA_VIDEO(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_MEDIA_VIDEO, \
+ GrlMediaVideo))
+
+#define GRL_MEDIA_VIDEO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_MEDIA_VIDEO, \
+ GrlMediaVideoClass))
+
+#define GRL_IS_MEDIA_VIDEO(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_MEDIA_VIDEO))
+
+#define GRL_IS_MEDIA_VIDEO_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_MEDIA_VIDEO))
+
+#define GRL_MEDIA_VIDEO_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_MEDIA_VIDEO, \
+ GrlMediaVideoClass))
+
+typedef struct _GrlMediaVideo GrlMediaVideo;
+typedef struct _GrlMediaVideoClass GrlMediaVideoClass;
+
+/**
+ * GrlMediaVideoClass:
+ * @parent_class: the parent class structure
+ *
+ * Grilo Media video Class
+ */
+struct _GrlMediaVideoClass
+{
+ GrlMediaClass parent_class;
+};
+
+struct _GrlMediaVideo
+{
+ GrlMedia parent;
+};
+
+/**
+ * grl_media_video_set_width:
+ * @data: the media instance
+ * @width: the video's width
+ *
+ * Set the width of the video
+ */
+#define grl_media_video_set_width(data, width) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_WIDTH, \
+ (width))
+
+/**
+ * grl_media_video_set_height:
+ * @data: the media instance
+ * @height: the video's height
+ *
+ * Set the height of the video
+ */
+#define grl_media_video_set_height(data, height) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_HEIGHT, \
+ (height))
+
+/**
+ * grl_media_video_set_framerate:
+ * @data: the media instance
+ * @framerate: the video's framerate
+ *
+ * Set the framerate of the video
+ */
+#define grl_media_video_set_framerate(data, framerate) \
+ grl_data_set_float(GRL_DATA((data)), \
+ GRL_METADATA_KEY_FRAMERATE, \
+ (framerate))
+
+/**
+ * grl_media_video_get_width:
+ * @data: the media instance
+ *
+ * Returns: the width of the video
+ */
+#define grl_media_video_get_width(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_WIDTH)
+
+/**
+ * grl_media_video_get_height:
+ * @data: the media instance
+ *
+ * Returns: the height of the video
+ */
+#define grl_media_video_get_height(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_HEIGHT)
+
+/**
+ * grl_media_video_get_framerate:
+ * @data: the media instance
+ *
+ * Returns: the framerate of the video
+ */
+#define grl_media_video_get_framerate(data) \
+ grl_data_get_float(GRL_DATA((data)), GRL_METADATA_KEY_FRAMERATE)
+
+GType grl_media_video_get_type (void) G_GNUC_CONST;
+
+GrlMedia *grl_media_video_new (void);
+
+void grl_media_video_set_size (GrlMediaVideo *video,
+ gint width,
+ gint height);
+
+G_END_DECLS
+
+#endif /* _GRL_MEDIA_VIDEO_H_ */
diff --git a/src/content/grl-content-media.c b/src/data/grl-media.c
index 47834d8..e7cdaa9 100644
--- a/src/content/grl-content-media.c
+++ b/src/data/grl-media.c
@@ -22,74 +22,85 @@
*
*/
-/*
- * A multimedia content.
+/**
+ * SECTION:grl-media
+ * @short_description: A multimedia data transfer object
+ * @see_also: #GrlData, #GrlMediaBox, #GrlMediaVideo, #GrlMediaAudio, #GrlMediaImage
*
* This high level class represents a multimedia item. It has methods to
* set and get properties like author, title, description, and so on.
- *
*/
-#include "grl-content-media.h"
+#include "grl-media.h"
#undef G_LOG_DOMAIN
-#define G_LOG_DOMAIN "grl-content-media"
+#define G_LOG_DOMAIN "grl-media"
#define RATING_MAX 5.00
-static void grl_content_media_dispose (GObject *object);
-static void grl_content_media_finalize (GObject *object);
+static void grl_media_dispose (GObject *object);
+static void grl_media_finalize (GObject *object);
-G_DEFINE_TYPE (GrlContentMedia, grl_content_media, GRL_TYPE_CONTENT);
+G_DEFINE_TYPE (GrlMedia, grl_media, GRL_TYPE_DATA);
static void
-grl_content_media_class_init (GrlContentMediaClass *klass)
+grl_media_class_init (GrlMediaClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
- gobject_class->dispose = grl_content_media_dispose;
- gobject_class->finalize = grl_content_media_finalize;
+ gobject_class->dispose = grl_media_dispose;
+ gobject_class->finalize = grl_media_finalize;
}
static void
-grl_content_media_init (GrlContentMedia *self)
+grl_media_init (GrlMedia *self)
{
}
static void
-grl_content_media_dispose (GObject *object)
+grl_media_dispose (GObject *object)
{
- G_OBJECT_CLASS (grl_content_media_parent_class)->dispose (object);
+ G_OBJECT_CLASS (grl_media_parent_class)->dispose (object);
}
static void
-grl_content_media_finalize (GObject *object)
+grl_media_finalize (GObject *object)
{
- g_debug ("grl_content_media_finalize (%s)",
- grl_content_get_string (GRL_CONTENT (object),
- GRL_METADATA_KEY_TITLE));
+ g_debug ("grl_media_finalize (%s)",
+ grl_data_get_string (GRL_DATA (object),
+ GRL_METADATA_KEY_TITLE));
g_signal_handlers_destroy (object);
- G_OBJECT_CLASS (grl_content_media_parent_class)->finalize (object);
+ G_OBJECT_CLASS (grl_media_parent_class)->finalize (object);
}
/**
- * grl_content_media_new:
+ * grl_media_new:
*
- * Creates a new content media object.
+ * Creates a new data media object.
*
- * Returns: a newly-allocated content media.
+ * Returns: a newly-allocated data media.
**/
-GrlContentMedia *
-grl_content_media_new (void)
+GrlMedia *
+grl_media_new (void)
{
- return g_object_new (GRL_TYPE_CONTENT_MEDIA,
+ return g_object_new (GRL_TYPE_MEDIA,
NULL);
}
+/**
+ * grl_media_set_rating:
+ * @media: a media
+ * @rating: a string with the rating number
+ * @max: a string with the max rate value
+ *
+ * This method receives a rating and a max string, they
+ * are transformed into integers and the rating value is
+ * normalized.
+ */
void
-grl_content_media_set_rating (GrlContentMedia *content,
- const gchar *rating,
- const gchar *max)
+grl_media_set_rating (GrlMedia *media,
+ const gchar *rating,
+ const gchar *max)
{
g_return_if_fail (rating != NULL);
g_return_if_fail (max != NULL);
@@ -109,7 +120,7 @@ grl_content_media_set_rating (GrlContentMedia *content,
char value[G_ASCII_DTOSTR_BUF_SIZE];
gdouble normalized_value = (rating_value * RATING_MAX) / max_value;
g_ascii_formatd (value, sizeof (value), "%.2f", normalized_value);
- grl_content_set_string (GRL_CONTENT (content),
- GRL_METADATA_KEY_RATING,
- value);
+ grl_data_set_string (GRL_DATA (media),
+ GRL_METADATA_KEY_RATING,
+ value);
}
diff --git a/src/data/grl-media.h b/src/data/grl-media.h
new file mode 100644
index 0000000..5e89074
--- /dev/null
+++ b/src/data/grl-media.h
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2010 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral@igalia.com>
+ *
+ * Authors: Juan A. Suarez Romero <jasuarez@igalia.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_MEDIA_H_
+#define _GRL_MEDIA_H_
+
+#include <grl-data.h>
+
+
+G_BEGIN_DECLS
+
+#define GRL_TYPE_MEDIA \
+ (grl_media_get_type())
+
+#define GRL_MEDIA(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GRL_TYPE_MEDIA, \
+ GrlMedia))
+
+#define GRL_MEDIA_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GRL_TYPE_MEDIA, \
+ GrlMediaClass))
+
+#define GRL_IS_MEDIA(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ GRL_TYPE_MEDIA))
+
+#define GRL_IS_MEDIA_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+ GRL_TYPE_MEDIA))
+
+#define GRL_MEDIA_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GRL_TYPE_MEDIA, \
+ GrlMediaClass))
+
+typedef struct _GrlMedia GrlMedia;
+typedef struct _GrlMediaClass GrlMediaClass;
+
+/**
+ * GrlMediaClass:
+ * @parent_class: the parent class structure
+ *
+ * Grilo Media Class
+ */
+struct _GrlMediaClass
+{
+ GrlDataClass parent_class;
+};
+
+struct _GrlMedia
+{
+ GrlData parent;
+};
+
+/**
+ * grl_media_set_id:
+ * @data: the media
+ * @id: the identifier of the media
+ *
+ * Set the media identifier
+ */
+#define grl_media_set_id(data, id) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_ID, \
+ (id))
+
+/**
+ * grl_media_set_url:
+ * @data: the media
+ * @url: the media's URL
+ *
+ * Set the media's URL
+ */
+#define grl_media_set_url(data, url) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_URL, \
+ (url))
+
+/**
+ * grl_media_set_author:
+ * @data: the media
+ * @author: the media's author
+ *
+ * Set the media's author
+ */
+#define grl_media_set_author(data, author) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_AUTHOR, \
+ (author))
+
+/**
+ * grl_media_set_title:
+ * @data: the media
+ * @title: the title
+ *
+ * Set the media's title
+ */
+#define grl_media_set_title(data, title) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_TITLE, \
+ (title))
+
+/**
+ * grl_media_set_description:
+ * @data: the media
+ * @description: the description
+ *
+ * Set the media's description
+ */
+#define grl_media_set_description(data, description) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_DESCRIPTION, \
+ (description))
+
+/**
+ * grl_media_set_source:
+ * @data: the media
+ * @source: the source
+ *
+ * Set the media's source
+ */
+#define grl_media_set_source(data, source) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_SOURCE, \
+ (source))
+
+/**
+ * grl_media_set_thumbnail:
+ * @data: the media
+ * @thumbnail: the thumbnail URL
+ *
+ * Set the media's thumbnail URL
+ */
+#define grl_media_set_thumbnail(data, thumbnail) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_THUMBNAIL, \
+ (thumbnail))
+
+/**
+ * grl_media_set_site:
+ * @data: the media
+ * @site: the site
+ *
+ * Set the media's site
+ */
+#define grl_media_set_site(data, site) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_SITE, \
+ (site))
+/**
+ * grl_media_set_duration:
+ * @data: the media
+ * @duration: the duration
+ *
+ * Set the media's duration
+ */
+#define grl_media_set_duration(data, duration) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_DURATION, \
+ (duration))
+
+/**
+ * grl_media_set_date:
+ * @data: the media
+ * @date: the date
+ *
+ * Set the media's date (TBD)
+ */
+#define grl_media_set_date(data, date) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_DATE, \
+ (date))
+
+/**
+ * grl_media_set_mime:
+ * @data: the media
+ * @mime: the mime type
+ *
+ * Set the media's mime-type
+ */
+#define grl_media_set_mime(data, mime) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_MIME, \
+ (mime))
+
+/**
+ * grl_media_set_play_count:
+ * @data: the media
+ * @play_count: the play count
+ *
+ * Set the media play count
+ */
+#define grl_media_set_play_count(data, play_count) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_PLAY_COUNT, \
+ (play_count))
+
+/**
+ * grl_media_set_last_played:
+ * @data: the media
+ * @last_played: date when the media was last played
+ *
+ * Set the media last played date
+ */
+#define grl_media_set_last_played(data, last_played) \
+ grl_data_set_string(GRL_DATA((data)), \
+ GRL_METADATA_KEY_LAST_PLAYED, \
+ (last_played))
+
+/**
+ * grl_media_set_last_position:
+ * @data: the media
+ * @last_played: second at which the media playback was interrupted
+ *
+ * Set the media las played position
+ */
+#define grl_media_set_last_position(data, last_position) \
+ grl_data_set_int(GRL_DATA((data)), \
+ GRL_METADATA_KEY_LAST_POSITION, \
+ (last_position))
+
+void grl_media_set_rating (GrlMedia *media,
+ const gchar *rating,
+ const gchar *max);
+
+/**
+ * grl_media_get_id:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's identifier
+ */
+#define grl_media_get_id(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_ID)
+
+/**
+ * grl_media_get_url:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's URL
+ */
+#define grl_media_get_url(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_URL)
+
+/**
+ * grl_media_get_author:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's author
+ */
+#define grl_media_get_author(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_AUTHOR)
+
+/**
+ * grl_media_get_title:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's title
+ */
+#define grl_media_get_title(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_TITLE)
+
+/**
+ * grl_media_get_description:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's description
+ */
+#define grl_media_get_description(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_DESCRIPTION)
+
+/**
+ * grl_media_get_source:
+ * @data: the media object source
+ *
+ * Returns: (type utf8) (transfer none): the media's source
+ */
+#define grl_media_get_source(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_SOURCE)
+
+/**
+ * grl_media_get_thumbnail:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's thumbnail URL
+ */
+#define grl_media_get_thumbnail(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_THUMBNAIL)
+
+/**
+ * grl_media_get_site:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's site
+ */
+#define grl_media_get_site(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_SITE)
+
+/**
+ * grl_media_get_duration:
+ * @data: the media object
+ *
+ * Returns: the media's duration
+ */
+#define grl_media_get_duration(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_DURATION)
+
+/**
+ * grl_media_get_date:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's date (TBD)
+ */
+#define grl_media_get_date(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_DATE)
+
+/**
+ * grl_media_get_mime:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's mime-type
+ */
+#define grl_media_get_mime(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_MIME)
+
+/**
+ * grl_media_get_rating:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's rating
+ */
+#define grl_media_get_rating(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_RATING)
+
+/**
+ * grl_media_get_play_count:
+ * @data: the media object
+ *
+ * Returns: the media's play count
+ */
+#define grl_media_get_play_count(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_PLAY_COUNT)
+
+/**
+ * grl_media_get_last_position:
+ * @data: the media object
+ *
+ * Returns: the media's last_played position (in seconds)
+ */
+#define grl_media_get_last_position(data) \
+ grl_data_get_int(GRL_DATA((data)), GRL_METADATA_KEY_LAST_POSITION)
+
+/**
+ * grl_media_get_last_played:
+ * @data: the media object
+ *
+ * Returns: (type utf8) (transfer none): the media's last played time
+ */
+#define grl_media_get_last_played(data) \
+ grl_data_get_string(GRL_DATA((data)), GRL_METADATA_KEY_LAST_PLAYED)
+
+GType grl_media_get_type (void) G_GNUC_CONST;
+GrlMedia *grl_media_new (void);
+
+G_END_DECLS
+
+#endif /* _GRL_MEDIA_H_ */
diff --git a/src/grilo.h b/src/grilo.h
index df2057b..328f58c 100644
--- a/src/grilo.h
+++ b/src/grilo.h
@@ -36,11 +36,12 @@
#include <grl-media-source.h>
#include <grl-metadata-source.h>
#include <grl-metadata-key.h>
-#include <grl-content.h>
-#include <grl-content-media.h>
-#include <grl-content-audio.h>
-#include <grl-content-video.h>
-#include <grl-content-image.h>
-#include <grl-content-box.h>
+#include <grl-data.h>
+#include <grl-media.h>
+#include <grl-media-audio.h>
+#include <grl-media-video.h>
+#include <grl-media-image.h>
+#include <grl-media-box.h>
+#include <grl-config.h>
#endif /* _GRL_MEDIA_STORE_H_ */
diff --git a/src/grl-error.h b/src/grl-error.h
index 51b38d7..2e63fcd 100644
--- a/src/grl-error.h
+++ b/src/grl-error.h
@@ -34,6 +34,7 @@ typedef enum {
GRL_ERROR_MEDIA_NOT_FOUND,
GRL_ERROR_STORE_FAILED,
GRL_ERROR_REMOVE_FAILED,
+ GRL_ERROR_SET_METADATA_FAILED,
} GrlError;
#endif /* _GRL_ERROR_H_ */
diff --git a/src/grl-media-source.c b/src/grl-media-source.c
index 480df5a..a86c623 100644
--- a/src/grl-media-source.c
+++ b/src/grl-media-source.c
@@ -20,10 +20,29 @@
*
*/
+/**
+ * SECTION:grl-media-source
+ * @short_description: Abstract class for media providers
+ * @see_also: #GrlMediaPlugin, #GrlMetadataSource, #GrlMedia
+ *
+ * GrlMediaSource is the abstract base class needed to construct a
+ * source of media data.
+ *
+ * The media sources fetch media data descriptors and store them
+ * in data transfer objects represented as #GrlMedia.
+ *
+ * There are several methods to retrieve the media, such as searching
+ * a text expression, crafting a specific query, etc. And most of those
+ * methods are asynchronous.
+ *
+ * Examples of media sources are #GrlYoutubeSource, #GrlJamendoSource,
+ * etc.
+ */
+
#include "grl-media-source.h"
#include "grl-metadata-source-priv.h"
-#include "content/grl-content-media.h"
-#include "content/grl-content-box.h"
+#include "data/grl-media.h"
+#include "data/grl-media-box.h"
#include "grl-error.h"
#include <string.h>
@@ -47,7 +66,7 @@ struct _GrlMediaSourcePrivate {
};
struct SortedResult {
- GrlContentMedia *media;
+ GrlMedia *media;
guint remaining;
};
@@ -55,7 +74,7 @@ struct FullResolutionCtlCb {
GrlMediaSourceResultCb user_callback;
gpointer user_data;
GList *source_map_list;
- guint flags;
+ GrlMetadataResolutionFlags flags;
gboolean chained;
GList *next_index;
GList *waiting_list;
@@ -93,7 +112,7 @@ struct BrowseRelayIdle {
gpointer user_data;
GrlMediaSource *source;
guint browse_id;
- GrlContentMedia *media;
+ GrlMedia *media;
guint remaining;
GError *error;
gboolean chained;
@@ -103,7 +122,7 @@ struct MetadataFullResolutionCtlCb {
GrlMediaSourceMetadataCb user_callback;
gpointer user_data;
GList *source_map_list;
- guint flags;
+ GrlMetadataResolutionFlags flags;
};
struct MetadataFullResolutionDoneCb {
@@ -597,7 +616,7 @@ auto_split_run_next_chunk (struct BrowseRelayCb *brc, guint remaining)
static void
browse_result_relay_cb (GrlMediaSource *source,
guint browse_id,
- GrlContentMedia *media,
+ GrlMedia *media,
guint remaining,
gpointer user_data,
const GError *error)
@@ -672,8 +691,8 @@ browse_result_relay_cb (GrlMediaSource *source,
}
if (media) {
- grl_content_media_set_source (media,
- grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
+ grl_media_set_source (media,
+ grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
}
/* TODO: this should be TRUE if GRL_RESOLVE_FULL was requested too,
@@ -730,7 +749,7 @@ browse_result_relay_cb (GrlMediaSource *source,
static void
metadata_result_relay_cb (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -740,8 +759,8 @@ metadata_result_relay_cb (GrlMediaSource *source,
mrc = (struct MetadataRelayCb *) user_data;
if (media) {
- grl_content_media_set_source (media,
- grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
+ grl_media_set_source (media,
+ grl_metadata_source_get_id (GRL_METADATA_SOURCE (source)));
}
mrc->user_callback (source, media, mrc->user_data, error);
@@ -766,7 +785,7 @@ compare_sorted_results (gconstpointer a, gconstpointer b)
static void
full_resolution_add_to_waiting_list (GList **waiting_list,
- GrlContentMedia *media,
+ GrlMedia *media,
guint index)
{
struct SortedResult *result;
@@ -818,7 +837,7 @@ full_resolution_check_waiting_list (GList **waiting_list,
static void
full_resolution_done_cb (GrlMetadataSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -904,7 +923,7 @@ full_resolution_done_cb (GrlMetadataSource *source,
static void
full_resolution_ctl_cb (GrlMediaSource *source,
guint browse_id,
- GrlContentMedia *media,
+ GrlMedia *media,
guint remaining,
gpointer user_data,
const GError *error)
@@ -974,7 +993,7 @@ full_resolution_ctl_cb (GrlMediaSource *source,
static void
metadata_full_resolution_done_cb (GrlMetadataSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -1003,7 +1022,7 @@ metadata_full_resolution_done_cb (GrlMetadataSource *source,
static void
metadata_full_resolution_ctl_cb (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -1065,9 +1084,26 @@ grl_media_source_gen_browse_id (GrlMediaSource *source)
/* ================ API ================ */
+/**
+ * grl_media_source_browse:
+ * @source: a media source
+ * @container: a container of data transfer objects
+ * @keys: the list of #GrlKeyID to request
+ * @skip: the number if elements to skip in the browse operation
+ * @count: the number of elements to retrieve in the browse operation
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Browse from @skip, a @count number of media elements through an available list.
+ *
+ * This method is asynchronous.
+ *
+ * Returns: the operation identifier
+ */
guint
grl_media_source_browse (GrlMediaSource *source,
- GrlContentMedia *container,
+ GrlMedia *container,
const GList *keys,
guint skip,
guint count,
@@ -1152,8 +1188,8 @@ grl_media_source_browse (GrlMediaSource *source,
bs->user_data = _user_data;
if (!container) {
/* Special case: NULL container ==> NULL id */
- bs->container = grl_content_box_new ();
- grl_content_media_set_id (bs->container, NULL);
+ bs->container = grl_media_box_new ();
+ grl_media_set_id (bs->container, NULL);
} else {
bs->container = g_object_ref (container);
}
@@ -1183,6 +1219,24 @@ grl_media_source_browse (GrlMediaSource *source,
return browse_id;
}
+/**
+ * grl_media_source_search:
+ * @source: a media source
+ * @text: the text to search
+ * @keys: the list of #GrlKeyID to request
+ * @skip: the number if elements to skip in the browse operation
+ * @count: the number of elements to retrieve in the browse operation
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Search for the @text string in a media source for data identified with
+ * that string.
+ *
+ * This method is asynchronous.
+ *
+ * Returns: the operation identifier
+ */
guint
grl_media_source_search (GrlMediaSource *source,
const gchar *text,
@@ -1291,6 +1345,28 @@ grl_media_source_search (GrlMediaSource *source,
return search_id;
}
+/**
+ * grl_media_source_query:
+ * @source: a media source
+ * @query: the query to process
+ * @keys: the list of #GrlKeyID to request
+ * @skip: the number if elements to skip in the browse operation
+ * @count: the number of elements to retrieve in the browse operation
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Execute a specialized query (specific for each provider) on a media
+ * repository.
+ *
+ * It is different from grl_media_source_search() semantically, because
+ * the query implies a carefully crafted string, rather than a simple
+ * string to search.
+ *
+ * This method is asynchronous.
+ *
+ * Returns: the operation identifier
+ */
guint
grl_media_source_query (GrlMediaSource *source,
const gchar *query,
@@ -1401,9 +1477,23 @@ grl_media_source_query (GrlMediaSource *source,
return query_id;
}
+/**
+ * grl_media_source_metadata:
+ * @source: a media source
+ * @media: a data transfer object
+ * @keys: the list of #GrlKeyID to request
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * This method is intended to fetch the requested keys of metadata of
+ * a given @media to the media source.
+ *
+ * This method is asynchronous.
+ */
void
grl_media_source_metadata (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
const GList *keys,
GrlMetadataResolutionFlags flags,
GrlMediaSourceMetadataCb callback,
@@ -1474,8 +1564,8 @@ grl_media_source_metadata (GrlMediaSource *source,
ms->user_data = _user_data;
if (!media) {
/* Special case, NULL media ==> root container */
- ms->media = grl_content_box_new ();
- grl_content_media_set_id (ms->media, NULL);
+ ms->media = grl_media_box_new ();
+ grl_media_set_id (ms->media, NULL);
} else {
ms->media = g_object_ref (media);
}
@@ -1517,6 +1607,19 @@ grl_media_source_supported_operations (GrlMetadataSource *metadata_source)
return caps;
}
+/**
+ * grl_media_source_cancel:
+ * @source: a media source
+ * @operation_id: the identifier of the running operation
+ *
+ * Cancel a running method.
+ *
+ * Every method has a operation identifier, which is set as parameter in the
+ * callback. The running operation can be cancel then.
+ *
+ * The derived class must implement the cancel vmethod in order to
+ * honor the request.
+ */
void
grl_media_source_cancel (GrlMediaSource *source, guint operation_id)
{
@@ -1546,6 +1649,14 @@ grl_media_source_cancel (GrlMediaSource *source, guint operation_id)
}
}
+/**
+ * grl_media_source_set_operation_data:
+ * @source: a media source
+ * @operation_id: the identifier of a running operation
+ * @data: the data to attach
+ *
+ * Attach a pointer to the specific operation.
+ */
void
grl_media_source_set_operation_data (GrlMediaSource *source,
guint operation_id,
@@ -1556,6 +1667,15 @@ grl_media_source_set_operation_data (GrlMediaSource *source,
set_operation_data (source, operation_id, data);
}
+/**
+ * grl_media_source_get_operation_data:
+ * @source: a media source
+ * @operation_id: the identifier of a running operation
+ *
+ * Obtains the previously attached data
+ *
+ * Returns: (allow-none): The previously attached data.
+ */
gpointer
grl_media_source_get_operation_data (GrlMediaSource *source,
guint operation_id)
@@ -1565,6 +1685,14 @@ grl_media_source_get_operation_data (GrlMediaSource *source,
return get_operation_data (source, operation_id);
}
+/**
+ * grl_media_source_get_auto_split_threshold:
+ * @source: a media source
+ *
+ * TBD
+ *
+ * Returns: the assigned threshold
+ */
guint
grl_media_source_get_auto_split_threshold (GrlMediaSource *source)
{
@@ -1572,6 +1700,13 @@ grl_media_source_get_auto_split_threshold (GrlMediaSource *source)
return source->priv->auto_split_threshold;
}
+/**
+ * grl_media_source_set_auto_split_threshold:
+ * @source: a media source
+ * @threshold: the threshold to request
+ *
+ * TBD
+ */
void
grl_media_source_set_auto_split_threshold (GrlMediaSource *source,
guint threshold)
@@ -1580,10 +1715,22 @@ grl_media_source_set_auto_split_threshold (GrlMediaSource *source,
source->priv->auto_split_threshold = threshold;
}
+/**
+ * grl_media_source_store:
+ * @source: a media source
+ * @parent: a parent to store the data transfer objects
+ * @media: a data transfer object
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Store the @media into the @parent container
+ *
+ * This method is asynchronous.
+ */
void
grl_media_source_store (GrlMediaSource *source,
- GrlContentBox *parent,
- GrlContentMedia *media,
+ GrlMediaBox *parent,
+ GrlMedia *media,
GrlMediaSourceStoreCb callback,
gpointer user_data)
{
@@ -1594,8 +1741,8 @@ grl_media_source_store (GrlMediaSource *source,
GError *error = NULL;
g_return_if_fail (GRL_IS_MEDIA_SOURCE (source));
- g_return_if_fail (!parent || GRL_IS_CONTENT_BOX (parent));
- g_return_if_fail (GRL_IS_CONTENT_MEDIA (media));
+ g_return_if_fail (!parent || GRL_IS_MEDIA_BOX (parent));
+ g_return_if_fail (GRL_IS_MEDIA (media));
g_return_if_fail (callback != NULL);
g_return_if_fail ((!parent &&
grl_metadata_source_supported_operations (GRL_METADATA_SOURCE (source)) &
@@ -1605,14 +1752,14 @@ grl_media_source_store (GrlMediaSource *source,
GRL_OP_STORE_PARENT));
/* First, check that we have the minimum information we need */
- title = grl_content_media_get_title (media);
- url = grl_content_media_get_url (media);
+ title = grl_media_get_title (media);
+ url = grl_media_get_url (media);
if (!title) {
error = g_error_new (GRL_ERROR,
GRL_ERROR_STORE_FAILED,
"Media has no title, cannot store");
- } else if (!url && !GRL_IS_CONTENT_BOX (media)) {
+ } else if (!url && !GRL_IS_MEDIA_BOX (media)) {
error = g_error_new (GRL_ERROR,
GRL_ERROR_STORE_FAILED,
"Media has no URL, cannot store");
@@ -1637,9 +1784,20 @@ grl_media_source_store (GrlMediaSource *source,
}
}
+/**
+ * grl_media_source_remove:
+ * @source: a media source
+ * @media: a data transfer object
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Remove a @media from the @source repository.
+ *
+ * This method is asynchronous.
+ */
void
grl_media_source_remove (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
GrlMediaSourceRemoveCb callback,
gpointer user_data)
{
@@ -1649,13 +1807,13 @@ grl_media_source_remove (GrlMediaSource *source,
GError *error = NULL;
g_return_if_fail (GRL_IS_MEDIA_SOURCE (source));
- g_return_if_fail (GRL_IS_CONTENT_MEDIA (media));
+ g_return_if_fail (GRL_IS_MEDIA (media));
g_return_if_fail (callback != NULL);
g_return_if_fail (grl_metadata_source_supported_operations (GRL_METADATA_SOURCE (source)) &
GRL_OP_REMOVE);
/* First, check that we have the minimum information we need */
- id = grl_content_media_get_id (media);
+ id = grl_media_get_id (media);
if (!id) {
error = g_error_new (GRL_ERROR,
GRL_ERROR_REMOVE_FAILED,
diff --git a/src/grl-media-source.h b/src/grl-media-source.h
index 5574b37..a8bf744 100644
--- a/src/grl-media-source.h
+++ b/src/grl-media-source.h
@@ -25,8 +25,8 @@
#include <grl-media-plugin.h>
#include <grl-metadata-source.h>
-#include <grl-content.h>
-#include <grl-content-box.h>
+#include <grl-data.h>
+#include <grl-media-box.h>
#include <glib.h>
#include <glib-object.h>
@@ -74,35 +74,89 @@ struct _GrlMediaSource {
/* Callbacks for GrlMediaSource class */
+/**
+ * GrlMediaSourceResultCb:
+ * @source: a media source
+ * @browse_id: operation identifier
+ * @media: a data transfer object
+ * @remaining: the number of remaining #GrlMedia to process
+ * @user_data: user data passed to the used method
+ * @error: (not-error): possible #GError generated at processing
+ *
+ * Prototype for the callback passed to the media sources' methods
+ */
typedef void (*GrlMediaSourceResultCb) (GrlMediaSource *source,
guint browse_id,
- GrlContentMedia *media,
+ GrlMedia *media,
guint remaining,
gpointer user_data,
const GError *error);
+/**
+ * GrlMediaSourceMetadataCb:
+ * @source: a media source
+ * @media: a data transfer object
+ * @user_data: user data passed to grl_media_source_metadata()
+ * @error: (not-error): possible #GError generated at processing
+ *
+ * Prototype for the callback passed to grl_media_source_metadata()
+ */
typedef void (*GrlMediaSourceMetadataCb) (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error);
+/**
+ * GrlMediaSourceStoreCb:
+ * @source: a media source
+ * @parent: TBD
+ * @media: a data transfer object
+ * @user_data: user data passed to grl_media_source_store()
+ * @error: (not-error): possible #GError generated at processing
+ *
+ * Prototype for the callback passed to grl_media_source_store()
+ */
typedef void (*GrlMediaSourceStoreCb) (GrlMediaSource *source,
- GrlContentBox *parent,
- GrlContentMedia *media,
+ GrlMediaBox *parent,
+ GrlMedia *media,
gpointer user_data,
const GError *error);
+/**
+ * GrlMediaSourceRemoveCb:
+ * @source: a media source
+ * @media: a data transfer object
+ * @user_data: user data passed to grl_media_source_remove()
+ * @error: (not-error): possible #GError generated at processing
+ *
+ * Prototype for the callback passed to grl_media_source_remove()
+ */
typedef void (*GrlMediaSourceRemoveCb) (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error);
/* Types for MediaSourceClass */
+/**
+ * GrlMediaSourceBrowseSpec:
+ * @source: a media source
+ * @browse_id: operation identifier
+ * @container: a container of data transfer objects
+ * @keys: the list of #GrlKeyID to request
+ * @skip: the number if elements to skip in the browse operation
+ * @count: the number of elements to retrieve in the browse operation
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Data transport structure used internally by the plugins which support
+ * browse vmethod.
+ */
typedef struct {
GrlMediaSource *source;
guint browse_id;
- GrlContentMedia *container;
+ GrlMedia *container;
GList *keys;
guint skip;
guint count;
@@ -111,6 +165,21 @@ typedef struct {
gpointer user_data;
} GrlMediaSourceBrowseSpec;
+/**
+ * GrlMediaSourceSearchSpec:
+ * @source: a media source
+ * @search_id: operation identifier
+ * @text: the text to search
+ * @keys: the list of #GrlKeyID to request
+ * @skip: the number if elements to skip in the browse operation
+ * @count: the number of elements to retrieve in the browse operation
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Data transport structure used internally by the plugins which support
+ * search vmethod.
+ */
typedef struct {
GrlMediaSource *source;
guint search_id;
@@ -123,6 +192,21 @@ typedef struct {
gpointer user_data;
} GrlMediaSourceSearchSpec;
+/**
+ * GrlMediaSourceQuerySpec:
+ * @source: a media source
+ * @query_id: operation identifier
+ * @query: the query to process
+ * @keys: the list of #GrlKeyID to request
+ * @skip: the number if elements to skip in the browse operation
+ * @count: the number of elements to retrieve in the browse operation
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Data transport structure used internally by the plugins which support
+ * query vmethod.
+ */
typedef struct {
GrlMediaSource *source;
guint query_id;
@@ -135,27 +219,61 @@ typedef struct {
gpointer user_data;
} GrlMediaSourceQuerySpec;
+/**
+ * GrlMediaSourceMetadataSpec:
+ * @source: a media source
+ * @media: a data transfer object
+ * @keys: the list of #GrlKeyID to request
+ * @flags: the resolution mode
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Data transport structure used internally by the plugins which support
+ * metadata vmethod.
+ */
typedef struct {
GrlMediaSource *source;
- GrlContentMedia *media;
+ GrlMedia *media;
GList *keys;
GrlMetadataResolutionFlags flags;
GrlMediaSourceMetadataCb callback;
gpointer user_data;
} GrlMediaSourceMetadataSpec;
+/**
+ * GrlMediaSourceStoreSpec:
+ * @source: a media source
+ * @parent: a parent to store the data transfer objects
+ * @media: a data transfer object
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Data transport structure used internally by the plugins which support
+ * store vmethod.
+ */
typedef struct {
GrlMediaSource *source;
- GrlContentBox *parent;
- GrlContentMedia *media;
+ GrlMediaBox *parent;
+ GrlMedia *media;
GrlMediaSourceStoreCb callback;
gpointer user_data;
} GrlMediaSourceStoreSpec;
+/**
+ * GrlMediaSourceRemoveSpec:
+ * @source: a media source
+ * @media_id: media identifier to remove
+ * @media: a data transfer object
+ * @callback: the user defined callback
+ * @user_data: the user data to pass in the callback
+ *
+ * Data transport structure used internally by the plugins which support
+ * store vmethod.
+ */
typedef struct {
GrlMediaSource *source;
gchar *media_id;
- GrlContentMedia *media;
+ GrlMedia *media;
GrlMediaSourceRemoveCb callback;
gpointer user_data;
} GrlMediaSourceRemoveSpec;
@@ -164,6 +282,21 @@ typedef struct {
typedef struct _GrlMediaSourceClass GrlMediaSourceClass;
+/**
+ * GrlMediaSourceClass:
+ * @parent_class: the parent class structure
+ * @browse_id: operation identifier
+ * @browse: browse through a list of media
+ * @search: search for media
+ * @query: query for a specific media
+ * @cancel: cancel the current operation
+ * @metadata: request for specific metadata
+ * @store: store a media in a container
+ * @remove: remove a media from a container
+ *
+ * Grilo MediaSource class. Override the vmethods to implement the
+ * source functionality.
+ */
struct _GrlMediaSourceClass {
GrlMetadataSourceClass parent_class;
@@ -190,7 +323,7 @@ G_BEGIN_DECLS
GType grl_media_source_get_type (void);
guint grl_media_source_browse (GrlMediaSource *source,
- GrlContentMedia *container,
+ GrlMedia *container,
const GList *keys,
guint skip,
guint count,
@@ -217,20 +350,20 @@ guint grl_media_source_query (GrlMediaSource *source,
gpointer user_data);
void grl_media_source_metadata (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
const GList *keys,
GrlMetadataResolutionFlags flags,
GrlMediaSourceMetadataCb callback,
gpointer user_data);
void grl_media_source_store (GrlMediaSource *source,
- GrlContentBox *parent,
- GrlContentMedia *media,
+ GrlMediaBox *parent,
+ GrlMedia *media,
GrlMediaSourceStoreCb callback,
gpointer user_data);
void grl_media_source_remove (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
GrlMediaSourceRemoveCb callback,
gpointer user_data);
diff --git a/src/grl-metadata-key.h b/src/grl-metadata-key.h
index 7557dee..edc8555 100644
--- a/src/grl-metadata-key.h
+++ b/src/grl-metadata-key.h
@@ -114,6 +114,18 @@
#define GRL_METADATA_KEY_BITRATE_NAME "bitrate"
#define GRL_METADATA_KEY_BITRATE_DESC "Media bitrate in Kbits/s"
+#define GRL_METADATA_KEY_PLAY_COUNT 22
+#define GRL_METADATA_KEY_PLAY_COUNT_NAME "play count"
+#define GRL_METADATA_KEY_PLAY_COUNT_DESC "Media play count"
+
+#define GRL_METADATA_KEY_LAST_PLAYED 23
+#define GRL_METADATA_KEY_LAST_PLAYED_NAME "last played time"
+#define GRL_METADATA_KEY_LAST_PLAYED_DESC "Last time the media was played"
+
+#define GRL_METADATA_KEY_LAST_POSITION 24
+#define GRL_METADATA_KEY_LAST_POSITION_NAME "playback interrupted time"
+#define GRL_METADATA_KEY_LAST_POSITION_DESC "Time at which playback was interrupted"
+
#define GRL_KEYID_FORMAT "u"
#define POINTER_TO_GRLKEYID(p) GPOINTER_TO_UINT((p))
diff --git a/src/grl-metadata-source.c b/src/grl-metadata-source.c
index aa03db8..b8f3866 100644
--- a/src/grl-metadata-source.c
+++ b/src/grl-metadata-source.c
@@ -23,30 +23,31 @@
/**
* SECTION:grl-metadata-source
* @short_description: Abstract base class for metadata providers
- * @see_also: #GrlMediaPlugin, #GrlMediaSource, #GrlContentMedia
+ * @see_also: #GrlMediaPlugin, #GrlMediaSource, #GrlMedia
*
* GrlMetadataSource is the abstract base class needed to construct a
* source of metadata that can be used in a Grilo application.
*
* The metadata sources fetch metadata from different online or local
- * databases and store them in the passed #GrlContentMedia.
+ * databases and store them in the passed #GrlMedia.
*
* In opposition to #GrlMediaSource, #GrlMetadataSource does not create
- * new #GrlContentMedia instances, just fill them up with the metadata
+ * new #GrlMedia instances, just fill them up with the metadata
* provided by the specific #GrlMetadataSource.
*
* For example, #GrlLastfmAlbumartSource only provides album's covers,
- * and they will be used in the #GrlContentMedia generated by another
+ * and they will be used in the #GrlMedia generated by another
* #GrlMediaSource plugin.
*
* The main method is grl_metadata_source_resolve() which will retrieve
- * a list of #GrlKeyID requested for the passed #GrlContentMedia.
+ * a list of #GrlKeyID requested for the passed #GrlMedia.
*/
#include "grl-metadata-source.h"
#include "grl-metadata-source-priv.h"
#include "grl-plugin-registry.h"
-#include "content/grl-content-media.h"
+#include "grl-error.h"
+#include "data/grl-media.h"
#include <string.h>
@@ -77,6 +78,19 @@ struct ResolveRelayCb {
GrlMetadataSourceResolveSpec *spec;
};
+struct SetMetadataCtlCb {
+ GrlMetadataSource *source;
+ GrlMedia *media;
+ GrlMetadataSourceSetMetadataCb user_callback;
+ gpointer user_data;
+ GrlMetadataSourceSetMetadataSpec *spec;
+ gint pending;
+ GList *next;
+ GList *failed_keys;
+ GList *keymaps;
+ GList *specs;
+};
+
static void grl_metadata_source_finalize (GObject *plugin);
static void grl_metadata_source_get_property (GObject *plugin,
guint prop_id,
@@ -254,8 +268,74 @@ print_keys (gchar *label, const GList *keys)
}
static void
+free_set_metadata_ctl_cb_info (struct SetMetadataCtlCb *data)
+{
+ g_debug ("free_set_metadata_ctl_cb_info");
+
+ GList *iter;
+ g_object_unref (data->source);
+ g_object_unref (data->media);
+ g_list_free (data->failed_keys);
+ iter = data->keymaps;
+ while (iter) {
+ struct SourceKeyMap *map = (struct SourceKeyMap *) iter->data;
+ g_object_unref (map->source);
+ g_list_free (map->keys);
+ g_free (map);
+ iter = g_list_next (iter);
+ }
+ g_list_free (data->keymaps);
+ while (iter) {
+ g_free (iter->data);
+ iter = g_list_next (iter);
+ }
+ iter = data->specs;
+
+ g_free (data);
+}
+
+static void
+set_metadata_ctl_cb (GrlMetadataSource *source,
+ GrlMedia *media,
+ GList *failed_keys,
+ gpointer user_data,
+ const GError *error)
+{
+ g_debug ("set_metadata_ctl_cb");
+
+ struct SetMetadataCtlCb *smctlcb;
+ GError *own_error = NULL;
+
+ smctlcb = (struct SetMetadataCtlCb *) user_data;
+
+ if (failed_keys) {
+ smctlcb->failed_keys = g_list_concat (smctlcb->failed_keys, failed_keys);
+ }
+
+ smctlcb->pending--;
+ if (smctlcb->pending <= 0) {
+ /* We ignore the plugin errors, instead we create an own error
+ if some keys were not written */
+ if (smctlcb->failed_keys) {
+ own_error = g_error_new (GRL_ERROR,
+ GRL_ERROR_SET_METADATA_FAILED,
+ "Some keys could not be written");
+ }
+ smctlcb->user_callback (smctlcb->source,
+ media,
+ smctlcb->failed_keys,
+ smctlcb->user_data,
+ own_error);
+ if (own_error) {
+ g_error_free (own_error);
+ }
+ free_set_metadata_ctl_cb_info (smctlcb);
+ }
+}
+
+static void
resolve_result_relay_cb (GrlMetadataSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -283,6 +363,99 @@ resolve_idle (gpointer user_data)
return FALSE;
}
+static gboolean
+set_metadata_idle (gpointer user_data)
+{
+ g_debug ("set_metadata_idle");
+
+ GrlMetadataSourceSetMetadataSpec *sms;
+ struct SetMetadataCtlCb *smctlcb;
+ struct SourceKeyMap *keymap;
+
+ smctlcb = (struct SetMetadataCtlCb *) user_data;
+ keymap = (struct SourceKeyMap *) smctlcb->next->data;
+
+ sms = g_new0 (GrlMetadataSourceSetMetadataSpec, 1);
+ sms->source = keymap->source;
+ sms->keys = keymap->keys;
+ sms->media = smctlcb->media;
+ sms->callback = set_metadata_ctl_cb;
+ sms->user_data = smctlcb;
+
+ smctlcb->next = g_list_next (smctlcb->next);
+ smctlcb->specs = g_list_prepend (smctlcb->specs, sms);
+
+ GRL_METADATA_SOURCE_GET_CLASS (sms->source)->set_metadata (sms->source, sms);
+
+ return (smctlcb->next != NULL);
+}
+
+static GList *
+analyze_keys_to_write (GrlMetadataSource *source,
+ GList *keys,
+ GrlMetadataWritingFlags flags,
+ GList **failed_keys)
+{
+ GList *maps = NULL;
+ struct SourceKeyMap *map;
+ GrlPluginRegistry *registry;
+ GrlMediaPlugin **source_list;
+
+ /* 'supported_keys' holds keys that can be written by this source
+ 'key_list' holds those that must be hadled by other sources */
+ GList *key_list = g_list_copy (keys);
+ GList *supported_keys =
+ grl_metadata_source_filter_writable (source, &key_list, TRUE);
+
+ if (supported_keys) {
+ map = g_new0 (struct SourceKeyMap, 1);
+ map->source = g_object_ref (source);
+ map->keys = supported_keys;
+ maps = g_list_prepend (maps, map);
+ }
+
+ if (!(flags & GRL_WRITE_FULL)) {
+ /* We are only interested in using this source, we are done! */
+ goto done;
+ }
+
+ if (!key_list) {
+ /* All keys are writable by this source, we are done! */
+ goto done;
+ }
+
+ /* Check if other sources can write the missing keys */
+ registry = grl_plugin_registry_get_instance ();
+ source_list =
+ grl_plugin_registry_get_sources_by_operations (registry,
+ GRL_OP_SET_METADATA,
+ TRUE);
+ while (key_list && *source_list) {
+ GrlMetadataSource *_source;
+
+ _source = GRL_METADATA_SOURCE (*source_list);
+ source_list++;
+ if (_source == source) {
+ continue;
+ }
+
+ supported_keys =
+ grl_metadata_source_filter_writable (_source, &key_list, TRUE);
+ if (!supported_keys) {
+ continue;
+ }
+
+ map = g_new0 (struct SourceKeyMap, 1);
+ map->source = g_object_ref (_source);
+ map->keys = supported_keys;
+ maps = g_list_prepend (maps, map);
+ }
+
+ done:
+ *failed_keys = key_list;
+ return maps;
+}
+
/* ================ API ================ */
/**
@@ -340,6 +513,27 @@ grl_metadata_source_key_depends (GrlMetadataSource *source, GrlKeyID key_id)
}
/**
+ * grl_metadata_source_writable_keys:
+ * @source: a metadata source
+ *
+ * Similar to grl_metadata_source_supported_keys(), but these keys
+ * are marked as writable, meaning the source allows the client
+ * to provide new values for these keys that will be stored permanently.
+ *
+ * Returns: (transfer none) (allow-none): a #GList with the keys
+ */
+const GList *
+grl_metadata_source_writable_keys (GrlMetadataSource *source)
+{
+ g_return_val_if_fail (GRL_IS_METADATA_SOURCE (source), NULL);
+ if (GRL_METADATA_SOURCE_GET_CLASS (source)->writable_keys) {
+ return GRL_METADATA_SOURCE_GET_CLASS (source)->writable_keys (source);
+ } else {
+ return NULL;
+ }
+}
+
+/**
* grl_metadata_source_resolve:
* @source: a metadata source
* @keys: the #GList of #GrlKeyID to retrieve
@@ -357,8 +551,8 @@ grl_metadata_source_key_depends (GrlMetadataSource *source, GrlKeyID key_id)
void
grl_metadata_source_resolve (GrlMetadataSource *source,
const GList *keys,
- GrlContentMedia *media,
- guint flags,
+ GrlMedia *media,
+ GrlMetadataResolutionFlags flags,
GrlMetadataSourceResolveCb callback,
gpointer user_data)
{
@@ -412,7 +606,8 @@ grl_metadata_source_resolve (GrlMetadataSource *source,
* Compares the received @keys list with the supported key list by the
* metadata @source, and will delete those keys which are not supported.
*
- * Returns: (transfer full) (allow-none): if @return_filtered is %TRUE will return the list of intersected keys; otherwise %NULL
+ * Returns: (transfer full) (allow-none): if @return_filtered is %TRUE
+ * will return the list of intersected keys; otherwise %NULL
*/
GList *
grl_metadata_source_filter_supported (GrlMetadataSource *source,
@@ -472,7 +667,8 @@ grl_metadata_source_filter_supported (GrlMetadataSource *source,
* Similar to grl_metadata_source_filter_supported() but applied to
* the slow keys in grl_metadata_source_slow_keys()
*
- * Returns: (transfer full) (allow-none): if @return_filtered is %TRUE will return the list of intersected keys; otherwise %NULL
+ * Returns: (transfer full) (allow-none): if @return_filtered is %TRUE
+ * will return the list of intersected keys; otherwise %NULL
*/
GList *
grl_metadata_source_filter_slow (GrlMetadataSource *source,
@@ -528,6 +724,75 @@ grl_metadata_source_filter_slow (GrlMetadataSource *source,
return filtered_keys;
}
+/**
+ * grl_metadata_source_filter_writable:
+ * @source: a metadata source
+ * @keys: the list of keys to filter out
+ * @return_filtered: if %TRUE the return value shall be a new list with
+ * the matched keys
+ *
+ * Similar to grl_metadata_source_filter_supported() but applied to
+ * the writable keys in grl_metadata_source_writable_keys()
+ *
+ * Returns: (transfer full) (allow-none): if @return_filtered is %TRUE
+ * will return the list of intersected keys; otherwise %NULL
+ */
+GList *
+grl_metadata_source_filter_writable (GrlMetadataSource *source,
+ GList **keys,
+ gboolean return_filtered)
+{
+ const GList *writable_keys;
+ GList *iter_writable;
+ GList *iter_keys;
+ GrlKeyID key;
+ GList *filtered_keys = NULL;
+ gboolean got_match;
+ GrlKeyID writable_key;
+
+ /* TODO: All these filer_* methods could probably reuse most of the code */
+
+ g_return_val_if_fail (GRL_IS_METADATA_SOURCE (source), NULL);
+
+ writable_keys = grl_metadata_source_writable_keys (source);
+ if (!writable_keys) {
+ if (return_filtered) {
+ return g_list_copy (*keys);
+ } else {
+ return NULL;
+ }
+ }
+
+ iter_writable = (GList *) writable_keys;
+ while (iter_writable) {
+ got_match = FALSE;
+ iter_keys = *keys;
+
+ writable_key = POINTER_TO_GRLKEYID (iter_writable->data);
+ while (!got_match && iter_keys) {
+ key = POINTER_TO_GRLKEYID (iter_keys->data);
+ if (key == writable_key) {
+ got_match = TRUE;
+ } else {
+ iter_keys = g_list_next (iter_keys);
+ }
+ }
+
+ iter_writable = g_list_next (iter_writable);
+
+ if (got_match) {
+ if (return_filtered) {
+ filtered_keys =
+ g_list_prepend (filtered_keys, GRLKEYID_TO_POINTER (writable_key));
+ }
+ *keys = g_list_delete_link (*keys, iter_keys);
+ got_match = FALSE;
+ }
+ }
+
+ return filtered_keys;
+}
+
void
grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
const GList *keys,
@@ -541,8 +806,7 @@ grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
/* Filter keys supported by this source */
key_mapping->operation_keys =
- grl_metadata_source_filter_supported (GRL_METADATA_SOURCE (source),
- &key_list, TRUE);
+ grl_metadata_source_filter_supported (source, &key_list, TRUE);
if (key_list == NULL) {
g_debug ("Source supports all requested keys");
@@ -574,7 +838,9 @@ grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
GrlPluginRegistry *registry;
registry = grl_plugin_registry_get_instance ();
- source_list = grl_plugin_registry_get_sources (registry, TRUE);
+ source_list = grl_plugin_registry_get_sources_by_operations (registry,
+ GRL_OP_RESOLVE,
+ TRUE);
while (*source_list && key_list) {
gchar *name;
@@ -584,15 +850,7 @@ grl_metadata_source_setup_full_resolution_mode (GrlMetadataSource *source,
source_list++;
/* Interested in sources other than this */
- if (_source == GRL_METADATA_SOURCE (source)) {
- continue;
- }
-
- /* Interested in sources capable of resolving metadata
- based on other metadata */
- GrlMetadataSourceClass *_source_class =
- GRL_METADATA_SOURCE_GET_CLASS (_source);
- if (!_source_class->resolve) {
+ if (_source == source) {
continue;
}
@@ -716,12 +974,73 @@ grl_metadata_source_get_description (GrlMetadataSource *source)
}
/**
+ * grl_metadata_source_set_metadata:
+ * @source: a metadata source
+ * @media: the #GrlMedia object that we want to operate on.
+ * @key: a #GrlKeyID which value we want to change.
+ * @callback: the callback to execute when the operation is finished.
+ * @user_data: user data set for the @callback
+ *
+ * This is the main method of the #GrlMetadataSource class. It will
+ * get the value for @key from @media and store it permanently. After
+ * calling this method, future queries that return this media object
+ * shall return this new value for the selected key.
+ *
+ * This function is asynchronic and uses the Glib's main loop.
+ */
+void
+grl_metadata_source_set_metadata (GrlMetadataSource *source,
+ GrlMedia *media,
+ GList *keys,
+ GrlMetadataWritingFlags flags,
+ GrlMetadataSourceSetMetadataCb callback,
+ gpointer user_data)
+{
+ GList *keymaps;
+ GList *failed_keys = NULL;
+ GError *error;
+ struct SetMetadataCtlCb *smctlcb;
+
+ g_debug ("grl_metadata_source_set_metadata");
+
+ g_return_if_fail (GRL_IS_METADATA_SOURCE (source));
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (media != NULL);
+ g_return_if_fail (keys != NULL);
+ g_return_if_fail (grl_metadata_source_supported_operations (source) &
+ GRL_OP_SET_METADATA);
+
+ keymaps = analyze_keys_to_write (source, keys, flags, &failed_keys);
+ if (!keymaps) {
+ error = g_error_new (GRL_ERROR,
+ GRL_ERROR_SET_METADATA_FAILED,
+ "None of the specified keys is writable");
+ callback (source, media, failed_keys, user_data, error);
+ g_list_free (failed_keys);
+ return;
+ }
+
+ smctlcb = g_new0 (struct SetMetadataCtlCb, 1);
+ smctlcb->source = g_object_ref (source);
+ smctlcb->media = g_object_ref (media);
+ smctlcb->user_callback = callback;
+ smctlcb->user_data = user_data;
+ smctlcb->keymaps = keymaps;
+ smctlcb->failed_keys = failed_keys;
+ smctlcb->pending = g_list_length (keymaps);
+ smctlcb->next = keymaps;
+
+ g_idle_add (set_metadata_idle, smctlcb);
+}
+
+/**
* grl_metadata_source_supported_operations:
* @source: a metadata source
*
* By default the derived objects of #GrlMetadataSource can only resolve.
*
- * Returns: a bitwise mangle with the supported operations by the source
+ * Returns: (type uint): a bitwise mangle with the supported operations by
+ * the source
*/
GrlSupportedOps
grl_metadata_source_supported_operations (GrlMetadataSource *source)
@@ -738,5 +1057,8 @@ grl_metadata_source_supported_operations_impl (GrlMetadataSource *source)
metadata_source_class = GRL_METADATA_SOURCE_GET_CLASS (source);
if (metadata_source_class->resolve)
caps |= GRL_OP_RESOLVE;
+ if (metadata_source_class->set_metadata)
+ caps |= GRL_OP_SET_METADATA;
return caps;
}
+
diff --git a/src/grl-metadata-source.h b/src/grl-metadata-source.h
index 0b29649..60c5405 100644
--- a/src/grl-metadata-source.h
+++ b/src/grl-metadata-source.h
@@ -25,7 +25,7 @@
#include <grl-media-plugin.h>
#include <grl-metadata-key.h>
-#include <grl-content-media.h>
+#include <grl-media.h>
#include <glib.h>
#include <glib-object.h>
@@ -74,6 +74,17 @@ typedef enum {
GRL_RESOLVE_FAST_ONLY = (1 << 2), /* Only resolve fast metadata keys */
} GrlMetadataResolutionFlags;
+/**
+ * GrlMetadataWritingFlags:
+ * @GRL_WRITE_NORMAL: Normal mode.
+ * @GRL_WRITE_FULL: Try other plugins if necessary.
+ *
+ * Flags for metadata writing operations.
+ */
+typedef enum {
+ GRL_WRITE_NORMAL = 0, /* Normal mode */
+ GRL_WRITE_FULL = (1 << 0), /* Try other plugins if necessary */
+} GrlMetadataWritingFlags;
/* GrlMetadataSource object */
@@ -93,23 +104,40 @@ struct _GrlMetadataSource {
/**
* GrlMetadataSourceResolveCb:
* @source: a metadata source
- * @media: a #GrlContentMedia transfer object
+ * @media: a #GrlMedia transfer object
* @user_data: user data passed to grl_metadata_source_resolve()
* @error: (not-error): possible #GError generated when resolving the metadata
*
* Prototype for the callback passed to grl_metadata_source_resolve()
*/
typedef void (*GrlMetadataSourceResolveCb) (GrlMetadataSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error);
+
+/**
+ * GrlMetadataSourceSetMetadataCb:
+ * @source: a metadata source
+ * @media: a #GrlMedia transfer object
+ * @failed_keys: a #GList of keys that could not be updated, if any.
+ * @user_data: user data passed to grl_metadata_source_set_metadata()
+ * @error: (not-error): possible #GError generated when updating the metadata
+ *
+ * Prototype for the callback passed to grl_metadata_source_set_metadata()
+ */
+typedef void (*GrlMetadataSourceSetMetadataCb) (GrlMetadataSource *source,
+ GrlMedia *media,
+ GList *failed_keys,
+ gpointer user_data,
+ const GError *error);
+
/* Types for GrlMetadataSource */
/**
* GrlMetadataSourceResolveSpec:
* @source: a metadata source
* @keys: the #GList of #GrlKeyID to fetch and store
- * @media: a #GrlContentMedia transfer object
+ * @media: a #GrlMedia transfer object
* @flags: bitwise mask of #GrlMetadataResolutionFlags with the resolution
* strategy
* @callback: the callback passed to grl_metadata_source_resolve()
@@ -121,19 +149,41 @@ typedef void (*GrlMetadataSourceResolveCb) (GrlMetadataSource *source,
typedef struct {
GrlMetadataSource *source;
GList *keys;
- GrlContentMedia *media;
- guint flags;
+ GrlMedia *media;
+ GrlMetadataResolutionFlags flags;
GrlMetadataSourceResolveCb callback;
gpointer user_data;
} GrlMetadataSourceResolveSpec;
/**
+ * GrlMetadataSourceSetMetadataSpec:
+ * @source: a metadata source
+ * @media: a #GrlMedia transfer object
+ * @key_id: Key which value is to be stored
+ * @callback: the callback passed to grl_metadata_source_set_metadata()
+ * @user_data: user data passed to grl_metadata_source_set_metadata()
+ * @failed_keys: for internal use of the framework only.
+ * @keymaps: for internal use of the framework only.
+ *
+ * Represents the closure used by the derived objects to operate.
+ */
+typedef struct {
+ GrlMetadataSource *source;
+ GrlMedia *media;
+ GList *keys;
+ GrlMetadataWritingFlags flags;
+ GrlMetadataSourceSetMetadataCb callback;
+ gpointer user_data;
+ GList *failed_keys;
+} GrlMetadataSourceSetMetadataSpec;
+
+/**
* GrlSupportedOps:
* @GRL_OP_NONE: no one operation is supported
* @GRL_OP_METADATA: TBD
* @GRL_OP_RESOLVE: Fetch specific keys of metadata
- * @GRL_OP_BROWSE: Retrieve complete sets of #GrlContentMedia
- * @GRL_OP_SEARCH: Look up for #GrlContentMedia given a query
+ * @GRL_OP_BROWSE: Retrieve complete sets of #GrlMedia
+ * @GRL_OP_SEARCH: Look up for #GrlMedia given a query
* @GRL_OP_QUERY: TBD
* @GRL_OP_STORE: TBD
* @GRL_OP_STORE_PARENT: TBD
@@ -152,6 +202,7 @@ typedef enum {
GRL_OP_STORE = 1 << 5,
GRL_OP_STORE_PARENT = 1 << 6,
GRL_OP_REMOVE = 1 << 7,
+ GRL_OP_SET_METADATA = 1 << 8,
} GrlSupportedOps;
/* GrlMetadataSource class */
@@ -165,7 +216,10 @@ typedef struct _GrlMetadataSourceClass GrlMetadataSourceClass;
* @supported_keys: the list of keys that can be handled
* @slow_keys: the list of slow keys that can be fetched
* @key_depends: the list of keys which @key_id depends on
+ * @writable_keys: the list of keys which value can be written
* @resolve: resolve the metadata of a given transfer object
+ * @set_metadata: update metadata values for a given object in a
+ * permanent fashion
*
* Grilo MetadataSource class. Override the vmethods to implement the
* element functionality.
@@ -182,8 +236,13 @@ struct _GrlMetadataSourceClass {
const GList * (*key_depends) (GrlMetadataSource *source, GrlKeyID key_id);
+ const GList * (*writable_keys) (GrlMetadataSource *source);
+
void (*resolve) (GrlMetadataSource *source,
GrlMetadataSourceResolveSpec *rs);
+
+ void (*set_metadata) (GrlMetadataSource *source,
+ GrlMetadataSourceSetMetadataSpec *sms);
};
G_BEGIN_DECLS
@@ -204,16 +263,29 @@ GList *grl_metadata_source_filter_slow (GrlMetadataSource *source,
GList **keys,
gboolean return_filtered);
+GList *grl_metadata_source_filter_writable (GrlMetadataSource *source,
+ GList **keys,
+ gboolean return_filtered);
+
const GList *grl_metadata_source_key_depends (GrlMetadataSource *source,
GrlKeyID key_id);
+const GList *grl_metadata_source_writable_keys (GrlMetadataSource *source);
+
void grl_metadata_source_resolve (GrlMetadataSource *source,
const GList *keys,
- GrlContentMedia *media,
- guint flags,
+ GrlMedia *media,
+ GrlMetadataResolutionFlags flags,
GrlMetadataSourceResolveCb callback,
gpointer user_data);
+void grl_metadata_source_set_metadata (GrlMetadataSource *source,
+ GrlMedia *media,
+ GList *keys,
+ GrlMetadataWritingFlags flags,
+ GrlMetadataSourceSetMetadataCb callback,
+ gpointer user_data);
+
const gchar *grl_metadata_source_get_id (GrlMetadataSource *source);
const gchar *grl_metadata_source_get_name (GrlMetadataSource *source);
diff --git a/src/grl-plugin-registry.c b/src/grl-plugin-registry.c
index b95b1dc..99b54c4 100644
--- a/src/grl-plugin-registry.c
+++ b/src/grl-plugin-registry.c
@@ -20,6 +20,23 @@
*
*/
+/**
+ * SECTION:grl-plugin-registry
+ * @short_description: Grilo plugins loader and manager
+ * @see_also: #GrlMediaPlugin, #GrlMetadataSource, #GrlMediaSource
+ *
+ * The registry holds the metadata of a set of plugins.
+ *
+ * The #GrlPluginRegistry object is a list of plugins and some functions
+ * for dealing with them. Each #GrlMediaPlugin is matched 1-1 with a file
+ * on disk, and may or may not be loaded a given time. There only can be
+ * a single instance of #GstPluginRegistry (singleton pattern).
+ *
+ * A #GrlMediaPlugin can hold several data sources (#GrlMetadataSource or
+ * #GrlMediaSource), and #GrlPluginRegistry and shall register each one of
+ * them.
+ */
+
#include "grl-plugin-registry.h"
#include "grl-media-plugin-priv.h"
@@ -47,6 +64,7 @@
}
struct _GrlPluginRegistryPrivate {
+ GHashTable *configs;
GHashTable *plugins;
GHashTable *sources;
GrlMetadataKey *system_keys;
@@ -76,6 +94,13 @@ grl_plugin_registry_class_init (GrlPluginRegistryClass *klass)
g_type_class_add_private (klass, sizeof (GrlPluginRegistryPrivate));
+ /**
+ * GrlPluginRegistry::source-added:
+ * @registry: the registry
+ * @plugin: the plugin that has been added
+ *
+ * Signals that a plugin has been added to the registry.
+ */
registry_signals[SIG_SOURCE_ADDED] =
g_signal_new("source-added",
G_TYPE_FROM_CLASS(klass),
@@ -86,6 +111,13 @@ grl_plugin_registry_class_init (GrlPluginRegistryClass *klass)
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GRL_TYPE_MEDIA_PLUGIN);
+ /**
+ * GrlPluginRegistry::source-removed:
+ * @registry: the registry
+ * @plugin: the plugin that has been removed
+ *
+ * Signals that a plugin has been removed from the registry.
+ */
registry_signals[SIG_SOURCE_REMOVED] =
g_signal_new("source-removed",
G_TYPE_FROM_CLASS(klass),
@@ -103,6 +135,8 @@ grl_plugin_registry_init (GrlPluginRegistry *registry)
registry->priv = GRL_PLUGIN_REGISTRY_GET_PRIVATE (registry);
memset (registry->priv, 0, sizeof (GrlPluginRegistryPrivate));
+ registry->priv->configs =
+ g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
registry->priv->plugins = g_hash_table_new (g_str_hash, g_str_equal);
registry->priv->sources =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@@ -139,6 +173,9 @@ grl_plugin_registry_setup_system_keys (GrlPluginRegistry *registry)
GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_FRAMERATE);
GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_RATING);
GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_BITRATE);
+ GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_PLAY_COUNT);
+ GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_LAST_PLAYED);
+ GRL_REGISTER_SYSTEM_METADATA_KEY (registry, GRL_METADATA_KEY_LAST_POSITION);
}
static void
@@ -233,6 +270,17 @@ sort_by_rank (GrlMediaPlugin **source_list)
/* ================ API ================ */
+/**
+ * grl_plugin_registry_get_instance:
+ *
+ * As the registry is designed to work as a singleton, this
+ * method is in charge of creating the only instance or
+ * returned it if it is already in memory.
+ *
+ * Returns: a new or an already created instance of the registry.
+ *
+ * It is NOT MT-safe
+ */
GrlPluginRegistry *
grl_plugin_registry_get_instance (void)
{
@@ -245,6 +293,16 @@ grl_plugin_registry_get_instance (void)
return registry;
}
+/**
+ * grl_plugin_registry_register_source:
+ * @registry: the registry instance
+ * @plugin: the descriptor of the plugin which owns the srouce
+ * @source: the source to register
+ *
+ * Register a @source in the @registry with the given @plugin information
+ *
+ * Returns: %TRUE if success
+ */
gboolean
grl_plugin_registry_register_source (GrlPluginRegistry *registry,
const GrlPluginInfo *plugin,
@@ -270,6 +328,13 @@ grl_plugin_registry_register_source (GrlPluginRegistry *registry,
return TRUE;
}
+/**
+ * grl_plugin_registry_unregister_source:
+ * @registry: the registry instance
+ * @source: the source to unregister
+ *
+ * Removes the @source from the @registry hash table
+ */
void
grl_plugin_registry_unregister_source (GrlPluginRegistry *registry,
GrlMediaPlugin *source)
@@ -290,11 +355,21 @@ grl_plugin_registry_unregister_source (GrlPluginRegistry *registry,
g_free (id);
}
+/**
+ * grl_plugin_registry_load:
+ * @registry: the registry instance
+ * @path: the path to the so file
+ *
+ * Loads a module from shared object file stored in @path
+ *
+ * Returns: %TRUE if the module is loaded correctly
+ */
gboolean
grl_plugin_registry_load (GrlPluginRegistry *registry, const gchar *path)
{
GModule *module;
GrlPluginDescriptor *plugin;
+ GList *plugin_configs;
module = g_module_open (path, G_MODULE_BIND_LAZY);
if (!module) {
@@ -319,7 +394,10 @@ grl_plugin_registry_load (GrlPluginRegistry *registry, const gchar *path)
g_hash_table_insert (registry->priv->plugins,
(gpointer) plugin->info.id, plugin);
- if (!plugin->plugin_init (registry, &plugin->info)) {
+ plugin_configs = g_hash_table_lookup (registry->priv->configs,
+ plugin->info.id);
+
+ if (!plugin->plugin_init (registry, &plugin->info, plugin_configs)) {
g_hash_table_remove (registry->priv->plugins, plugin->info.id);
g_warning ("Failed to initialize plugin: '%s'", path);
return FALSE;
@@ -330,6 +408,16 @@ grl_plugin_registry_load (GrlPluginRegistry *registry, const gchar *path)
return TRUE;
}
+/**
+ * grl_plugin_registry_load_directory:
+ * @registry: the registry instance
+ * @path: the path to the directory
+ *
+ * Loads a set of modules from directory in @path which contains
+ * a group shared object files.
+ *
+ * Returns: %TRUE if the directory exists.
+ */
gboolean
grl_plugin_registry_load_directory (GrlPluginRegistry *registry,
const gchar *path)
@@ -357,6 +445,18 @@ grl_plugin_registry_load_directory (GrlPluginRegistry *registry,
return TRUE;
}
+/**
+ * grl_plugin_registry_load_all:
+ * @registry: the registry instance
+ *
+ * Load all the modules available in the default directory path.
+ *
+ * The default directory path can be changed through the environment
+ * variable %GRL_PLUGIN_PATH and it can contain several paths separated
+ * by ":"
+ *
+ * Returns: %TRUE always
+ */
gboolean
grl_plugin_registry_load_all (GrlPluginRegistry *registry)
{
@@ -382,6 +482,15 @@ grl_plugin_registry_load_all (GrlPluginRegistry *registry)
return TRUE;
}
+/**
+ * grl_plugin_registry_lookup_source:
+ * @registry: the registry instance
+ * @source_id: the id of a source
+ *
+ * This function will search and retrieve a source given its identifier.
+ *
+ * Returns: (allow-none): The source found.
+ */
GrlMediaPlugin *
grl_plugin_registry_lookup_source (GrlPluginRegistry *registry,
const gchar *source_id)
@@ -390,6 +499,17 @@ grl_plugin_registry_lookup_source (GrlPluginRegistry *registry,
source_id);
}
+/**
+ * grl_plugin_registry_get_sources:
+ * @registry: the registry instance
+ * @ranked: whether the returned list shall be returned ordered by rank
+ *
+ * This function will return all the available sources in the @registry.
+ *
+ * If @ranked is %TRUE, the source list will be ordered by rank.
+ *
+ * Returns: (transfer container): an array of available sources
+ */
GrlMediaPlugin **
grl_plugin_registry_get_sources (GrlPluginRegistry *registry,
gboolean ranked)
@@ -412,10 +532,23 @@ grl_plugin_registry_get_sources (GrlPluginRegistry *registry,
return source_list;
}
+/**
+ * grl_plugin_registry_get_sources_by_operations:
+ * @registry: the registry instance
+ * @ops: a bitwise mangle of the requested operations.
+ * @ranked: whether the returned list shall be returned ordered by rank
+ *
+ * Give an array of all the available sources in the @registry capable of
+ * perform the operations requested in @ops.
+ *
+ * If @ranked is %TRUE, the source list will be ordered by rank.
+ *
+ * Returns: (transfer container): an array of available sources
+ */
GrlMediaPlugin **
-grl_plugin_registry_get_sources_by_capabilities (GrlPluginRegistry *registry,
- GrlSupportedOps caps,
- gboolean ranked)
+grl_plugin_registry_get_sources_by_operations (GrlPluginRegistry *registry,
+ GrlSupportedOps ops,
+ gboolean ranked)
{
GHashTableIter iter;
GrlMediaPlugin **source_list;
@@ -428,9 +561,10 @@ grl_plugin_registry_get_sources_by_capabilities (GrlPluginRegistry *registry,
n = 0;
g_hash_table_iter_init (&iter, registry->priv->sources);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &p)) {
- GrlSupportedOps ops;
- ops = grl_metadata_source_supported_operations (GRL_METADATA_SOURCE (p));
- if ((ops & caps) == caps) {
+ GrlSupportedOps source_ops;
+ source_ops =
+ grl_metadata_source_supported_operations (GRL_METADATA_SOURCE (p));
+ if ((source_ops & ops) == ops) {
source_list[n++] = p;
}
}
@@ -443,6 +577,14 @@ grl_plugin_registry_get_sources_by_capabilities (GrlPluginRegistry *registry,
return source_list;
}
+/**
+ * grl_plugin_registry_unload:
+ * @registry: the registry instance
+ * @plugin_id: the identifier of the plugin
+ *
+ * Unload from memory a module identified by @plugin_id. This means call the
+ * module's deinit function.
+ */
void
grl_plugin_registry_unload (GrlPluginRegistry *registry,
const gchar *plugin_id)
@@ -461,9 +603,51 @@ grl_plugin_registry_unload (GrlPluginRegistry *registry,
}
}
+/**
+ * grl_plugin_registry_lookup_metadata_key:
+ * @registry: the registry instance
+ * @key_id: the key identifier
+ *
+ * Look up for the metadata key structure givne the @key_id.
+ *
+ * Returns: (transfer none): The metadata key structure.
+ */
const GrlMetadataKey *
grl_plugin_registry_lookup_metadata_key (GrlPluginRegistry *registry,
GrlKeyID key_id)
{
return &registry->priv->system_keys[key_id];
}
+
+/**
+ * grl_plugin_registry_add_config:
+ * @registry: the registry instance
+ * @config: a configuration set
+ *
+ * Add a configuration for a plugin/source.
+ */
+void
+grl_plugin_registry_add_config (GrlPluginRegistry *registry,
+ GrlConfig *config)
+{
+ const gchar *plugin_id;
+ GList *configs = NULL;
+
+ g_return_if_fail (config != NULL);
+
+ plugin_id = grl_config_get_plugin (config);
+ if (!plugin_id)
+ return;
+
+ configs = g_hash_table_lookup (registry->priv->configs, plugin_id);
+ if (configs) {
+ /* Notice that we are using g_list_append on purpose to avoid
+ having to insert again in the hash table */
+ configs = g_list_append (configs, config);
+ } else {
+ configs = g_list_prepend (configs, config);
+ g_hash_table_insert (registry->priv->configs,
+ (gpointer) plugin_id,
+ configs);
+ }
+}
diff --git a/src/grl-plugin-registry.h b/src/grl-plugin-registry.h
index fe9d371..06ebd09 100644
--- a/src/grl-plugin-registry.h
+++ b/src/grl-plugin-registry.h
@@ -29,6 +29,7 @@
#include <grl-media-source.h>
#include <grl-metadata-key.h>
+#include <grl-config.h>
#define GRL_PLUGIN_PATH_VAR "GRL_PLUGIN_PATH"
#define GRL_PLUGIN_RANKS_VAR "GRL_PLUGIN_RANKS"
@@ -63,6 +64,22 @@
/* Plugin registration */
+/**
+ * GRL_PLUGIN_REGISTER:
+ * @init: the module initialization. It shall instantiate the
+ * the #GrlMediaPlugins provided
+ * @deinit: (allow-none): function to execute when the registry needs to dispose the module
+ * @id: the module identifier
+ * @name: the module name
+ * @desc: a phrase describing the service provided by the module
+ * @version: the version string of the module
+ * @author: the author(s) of the module
+ * @license: the license used by the module
+ * @site: the website of the module
+ *
+ * Define the boilerplate for loadable modules. Defines a new module
+ * descriptor which provides a set of #GrlMediaPlugins
+ */
#define GRL_PLUGIN_REGISTER(init, \
deinit, \
id, \
@@ -90,6 +107,19 @@
typedef struct _GrlPluginRegistry GrlPluginRegistry;
+/**
+ * GrlPluginInfo:
+ * @id: the module identifier
+ * @name: the module name
+ * @desc: a phrase describing the service provided by the module
+ * @version: the version string of the module
+ * @author: the author(s) of the module
+ * @license: the license used by the module
+ * @site: the website of the module
+ * @rank: the plugin priority rank
+ *
+ * This structure stores the information related to a module
+ */
typedef struct _GrlPluginInfo {
const gchar *id;
const gchar *name;
@@ -101,14 +131,42 @@ typedef struct _GrlPluginInfo {
gint rank;
} GrlPluginInfo;
-typedef struct _GrlPluginDescriptor {
+typedef struct _GrlPluginDescriptor GrlPluginDescriptor;
+
+/**
+* GrlPluginDescriptor:
+* @info: the module information
+* @plugin_init: the module initialization. It shall instantiate the
+* the #GrlMediaPlugins provided
+* @plugin_deinit: function to execute when the registry needs
+* to dispose the module.
+*
+* This structure is used for the module loader
+*/
+struct _GrlPluginDescriptor {
GrlPluginInfo info;
- gboolean (*plugin_init) (GrlPluginRegistry *, const GrlPluginInfo *);
+ gboolean (*plugin_init) (GrlPluginRegistry *, const GrlPluginInfo *, GList *);
void (*plugin_deinit) (void);
-} GrlPluginDescriptor;
+};
/* Plugin ranks */
+/**
+ * GrlPluginRank:
+ * @GRL_PLUGIN_RANK_LOWEST: will be chosen last or not at all
+ * @GRL_PLUGIN_RANK_LOW: unlikely to be chosen
+ * @GRL_PLUGIN_RANK_DEFAULT: likely to be chosen
+ * @GRL_PLUGIN_RANK_HIGH: will be chosen
+ * @GRL_PLUGIN_RANK_HIGHEST: will be chosen first
+ *
+ * Module priority ranks. Defines the order in which the resolver
+ * (or similar rank-picking mechanisms) will choose this plugin
+ * over an alternative one with the same function.
+ *
+ * These constants serve as a rough guidance for defining the rank
+ * of a GrlPluginInfo. Any value is valid, including values bigger
+ * than GRL_PLUGIN_RANK_HIGHEST.
+ */
typedef enum {
GRL_PLUGIN_RANK_LOWEST = -64,
GRL_PLUGIN_RANK_LOW = -32,
@@ -133,6 +191,12 @@ struct _GrlPluginRegistry {
typedef struct _GrlPluginRegistryClass GrlPluginRegistryClass;
+/**
+ * GrlPluginRegistryClass:
+ * @parent_class: the parent class structure
+ *
+ * Grilo PluginRegistry class. Dynamic loader of plugins.
+ */
struct _GrlPluginRegistryClass {
GObjectClass parent_class;
@@ -168,13 +232,16 @@ GrlMediaPlugin *grl_plugin_registry_lookup_source (GrlPluginRegistry *registry,
GrlMediaPlugin **grl_plugin_registry_get_sources (GrlPluginRegistry *registry,
gboolean ranked);
-GrlMediaPlugin **grl_plugin_registry_get_sources_by_capabilities (GrlPluginRegistry *registry,
- GrlSupportedOps caps,
- gboolean ranked);
+GrlMediaPlugin **grl_plugin_registry_get_sources_by_operations (GrlPluginRegistry *registry,
+ GrlSupportedOps ops,
+ gboolean ranked);
const GrlMetadataKey *grl_plugin_registry_lookup_metadata_key (GrlPluginRegistry *registry,
GrlKeyID key_id);
+void grl_plugin_registry_add_config (GrlPluginRegistry *registry,
+ GrlConfig *config);
+
G_END_DECLS
#endif /* _GRL_PLUGIN_REGISTRY_H_ */
diff --git a/tools/grilo-test-ui/Makefile.am b/tools/grilo-test-ui/Makefile.am
index c401555..e2db348 100644
--- a/tools/grilo-test-ui/Makefile.am
+++ b/tools/grilo-test-ui/Makefile.am
@@ -16,7 +16,7 @@ grilo_test_ui_CFLAGS = \
-DPREFIX=$(prefix) \
$(GTK_CFLAGS) \
-I$(top_srcdir)/src \
- -I$(top_srcdir)/src/content
+ -I$(top_srcdir)/src/data
grilo_test_ui_LDADD = \
-ldl -lpthread \
diff --git a/tools/grilo-test-ui/main.c b/tools/grilo-test-ui/main.c
index ccf5d71..54c0e50 100644
--- a/tools/grilo-test-ui/main.c
+++ b/tools/grilo-test-ui/main.c
@@ -28,6 +28,13 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "test-ui"
+/* ----- Flickr Security tokens ---- */
+
+#define FLICKR_KEY "fa037bee8120a921b34f8209d715a2fa"
+#define FLICKR_SECRET "9f6523b9c52e3317"
+#define FLICKR_FROB "416-357-743"
+#define FLICKR_TOKEN "72157623286932154-c90318d470e96a29"
+
#define BROWSE_FLAGS (GRL_RESOLVE_FAST_ONLY | GRL_RESOLVE_IDLE_RELAY)
#define METADATA_FLAGS (GRL_RESOLVE_FULL | GRL_RESOLVE_IDLE_RELAY)
@@ -98,11 +105,11 @@ typedef struct {
GList *source_stack;
GList *container_stack;
GrlMediaSource *cur_source;
- GrlContentMedia *cur_container;
+ GrlMedia *cur_container;
/* Keeps track of the last element we showed metadata for */
GrlMediaSource *cur_md_source;
- GrlContentMedia *cur_md_media;
+ GrlMedia *cur_md_media;
/* Keeps track of browse/search state */
gboolean op_ongoing;
@@ -208,15 +215,15 @@ load_icon (const gchar *icon_name)
}
static GdkPixbuf *
-get_icon_for_media (GrlContentMedia *media)
+get_icon_for_media (GrlMedia *media)
{
- if (GRL_IS_CONTENT_BOX (media)) {
+ if (GRL_IS_MEDIA_BOX (media)) {
return load_icon (GTK_STOCK_DIRECTORY);
- } else if (GRL_IS_CONTENT_VIDEO (media)) {
+ } else if (GRL_IS_MEDIA_VIDEO (media)) {
return load_icon ("gnome-mime-video");
- } else if (GRL_IS_CONTENT_AUDIO (media)) {
+ } else if (GRL_IS_MEDIA_AUDIO (media)) {
return load_icon ("gnome-mime-audio");
- } else if (GRL_IS_CONTENT_IMAGE (media)) {
+ } else if (GRL_IS_MEDIA_IMAGE (media)) {
return load_icon ("gnome-mime-image");
} else {
return load_icon (GTK_STOCK_FILE);
@@ -254,7 +261,7 @@ metadata_keys (void)
}
static void
-browse_history_push (GrlMediaSource *source, GrlContentMedia *media)
+browse_history_push (GrlMediaSource *source, GrlMedia *media)
{
if (source)
g_object_ref (source);
@@ -266,7 +273,7 @@ browse_history_push (GrlMediaSource *source, GrlContentMedia *media)
}
static void
-browse_history_pop (GrlMediaSource **source, GrlContentMedia **media)
+browse_history_pop (GrlMediaSource **source, GrlMedia **media)
{
GList *tmp;
tmp = g_list_last (ui_state->source_stack);
@@ -276,14 +283,14 @@ browse_history_pop (GrlMediaSource **source, GrlContentMedia **media)
}
tmp = g_list_last (ui_state->container_stack);
if (tmp) {
- *media = (GrlContentMedia *) tmp->data;
+ *media = (GrlMedia *) tmp->data;
ui_state->container_stack = g_list_delete_link (ui_state->container_stack,
tmp);
}
}
static void
-set_cur_browse (GrlMediaSource *source, GrlContentMedia *media)
+set_cur_browse (GrlMediaSource *source, GrlMedia *media)
{
if (ui_state->cur_source)
g_object_unref (ui_state->cur_source);
@@ -300,7 +307,7 @@ set_cur_browse (GrlMediaSource *source, GrlContentMedia *media)
}
static void
-set_cur_metadata (GrlMediaSource *source, GrlContentMedia *media)
+set_cur_metadata (GrlMediaSource *source, GrlMedia *media)
{
if (ui_state->cur_md_source)
g_object_unref (ui_state->cur_md_source);
@@ -353,7 +360,7 @@ cancel_current_operation (void)
static void
metadata_cb (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -382,13 +389,13 @@ metadata_cb (GrlMediaSource *source,
if (media) {
registry = grl_plugin_registry_get_instance ();
- keys = grl_content_get_keys (GRL_CONTENT (media));
+ keys = grl_data_get_keys (GRL_DATA (media));
i = keys;
while (i) {
const GrlMetadataKey *key =
grl_plugin_registry_lookup_metadata_key (registry,
POINTER_TO_GRLKEYID (i->data));
- const GValue *g_value = grl_content_get (GRL_CONTENT (media),
+ const GValue *g_value = grl_data_get (GRL_DATA (media),
POINTER_TO_GRLKEYID (i->data));
gchar *value = g_value ? g_strdup_value_contents (g_value) : "";
gtk_list_store_append (GTK_LIST_STORE (view->metadata_model), &iter);
@@ -407,10 +414,10 @@ metadata_cb (GrlMediaSource *source,
when the treeview is cleared */
/* Set/unset show button */
- if ((GRL_IS_CONTENT_AUDIO (media) ||
- GRL_IS_CONTENT_VIDEO (media) ||
- GRL_IS_CONTENT_IMAGE (media)) &&
- (ui_state->last_url = grl_content_media_get_url (media))) {
+ if ((GRL_IS_MEDIA_AUDIO (media) ||
+ GRL_IS_MEDIA_VIDEO (media) ||
+ GRL_IS_MEDIA_IMAGE (media)) &&
+ (ui_state->last_url = grl_media_get_url (media))) {
gtk_widget_set_sensitive (view->show_btn, TRUE);
} else {
gtk_widget_set_sensitive (view->show_btn, FALSE);
@@ -436,7 +443,7 @@ operation_finished (void)
static void
browse_cb (GrlMediaSource *source,
guint browse_id,
- GrlContentMedia *media,
+ GrlMedia *media,
guint remaining,
gpointer user_data,
const GError *error)
@@ -456,10 +463,10 @@ browse_cb (GrlMediaSource *source,
if (media) {
icon = get_icon_for_media (media);
- name = grl_content_media_get_title (media);
- if (GRL_IS_CONTENT_BOX (media)) {
+ name = grl_media_get_title (media);
+ if (GRL_IS_MEDIA_BOX (media)) {
gint childcount =
- grl_content_box_get_childcount (GRL_CONTENT_BOX (media));
+ grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
type = OBJECT_TYPE_CONTAINER;
if (childcount != GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN) {
name = g_strdup_printf ("%s (%d)", name, childcount);
@@ -522,7 +529,7 @@ browse_cb (GrlMediaSource *source,
}
static void
-browse (GrlMediaSource *source, GrlContentMedia *container)
+browse (GrlMediaSource *source, GrlMedia *container)
{
guint browse_id;
if (source) {
@@ -555,10 +562,10 @@ browser_activated_cb (GtkTreeView *tree_view,
{
GtkTreeModel *model;
GtkTreeIter iter;
- GrlContentMedia *content;
+ GrlMedia *content;
gint type;
GrlMediaSource *source;
- GrlContentMedia *container;
+ GrlMedia *container;
model = gtk_tree_view_get_model (tree_view);
gtk_tree_model_get_iter (model, &iter, path);
@@ -592,7 +599,7 @@ browser_activated_cb (GtkTreeView *tree_view,
}
static void
-metadata (GrlMediaSource *source, GrlContentMedia *media)
+metadata (GrlMediaSource *source, GrlMedia *media)
{
if (source) {
/* If source does not support metadata() operation, then use the current
@@ -618,7 +625,7 @@ browser_row_selected_cb (GtkTreeView *tree_view,
GtkTreePath *path;
GtkTreeIter iter;
GrlMediaSource *source;
- GrlContentMedia *content;
+ GrlMedia *content;
gtk_tree_view_get_cursor (tree_view, &path, NULL);
gtk_tree_model_get_iter (view->browser_model, &iter, path);
@@ -634,12 +641,12 @@ browser_row_selected_cb (GtkTreeView *tree_view,
metadata (source, content);
}
- /* Check if we can store content in the selected item */
+ /* Check if we can store content in the selected item */
if (content == NULL &&
(grl_metadata_source_supported_operations (GRL_METADATA_SOURCE (source)) &
GRL_OP_STORE)) {
gtk_widget_set_sensitive (view->store_btn, TRUE);
- } else if (content && GRL_IS_CONTENT_BOX (content) &&
+ } else if (content && GRL_IS_MEDIA_BOX (content) &&
grl_metadata_source_supported_operations (GRL_METADATA_SOURCE (source)) &
GRL_OP_STORE_PARENT) {
gtk_widget_set_sensitive (view->store_btn, TRUE);
@@ -670,13 +677,13 @@ show_btn_clicked_cb (GtkButton *btn, gpointer user_data)
if (ui_state->last_url) {
uri_list = g_list_append (uri_list, (gpointer) ui_state->last_url);
- if (GRL_IS_CONTENT_IMAGE (ui_state->cur_md_media)) {
+ if (GRL_IS_MEDIA_IMAGE (ui_state->cur_md_media)) {
app = launchers->eog;
} else {
/* Content from apple-trailers should be opened with mplayer, as they
require to change the user-agent */
- if (strcmp (grl_content_get_string (GRL_CONTENT (ui_state->cur_md_media),
- GRL_METADATA_KEY_SOURCE),
+ if (strcmp (grl_data_get_string (GRL_DATA (ui_state->cur_md_media),
+ GRL_METADATA_KEY_SOURCE),
"grl-apple-trailers") == 0) {
app = launchers->mplayer;
} else {
@@ -691,7 +698,14 @@ show_btn_clicked_cb (GtkButton *btn, gpointer user_data)
g_warning ("Cannot use '%s' to show '%s'; using default application",
g_app_info_get_name (app),
ui_state->last_url);
- g_app_info_launch_default_for_uri (ui_state->last_url, NULL, NULL);
+ g_error_free (error);
+ error = NULL;
+ g_app_info_launch_default_for_uri (ui_state->last_url, NULL, &error);
+ if (error) {
+ g_warning ("Cannot use default application to show '%s'. "
+ "Stopping playback", ui_state->last_url);
+ g_error_free (error);
+ }
}
}
}
@@ -700,7 +714,7 @@ static void
back_btn_clicked_cb (GtkButton *btn, gpointer user_data)
{
GrlMediaSource *prev_source = NULL;
- GrlContentMedia *prev_container = NULL;
+ GrlMedia *prev_container = NULL;
/* TODO: when using dynamic sources this will break
because we have references to the removed sources
@@ -721,8 +735,8 @@ back_btn_clicked_cb (GtkButton *btn, gpointer user_data)
static void
store_cb (GrlMediaSource *source,
- GrlContentBox *box,
- GrlContentMedia *media,
+ GrlMediaBox *box,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -742,7 +756,7 @@ store_btn_clicked_cb (GtkButton *btn, gpointer user_data)
GtkTreeModel *model = NULL;
GtkTreeIter iter;
GrlMediaSource *source;
- GrlContentMedia *container;
+ GrlMedia *container;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view->browser));
gtk_tree_selection_get_selected (sel, &model, &iter);
@@ -782,18 +796,18 @@ store_btn_clicked_cb (GtkButton *btn, gpointer user_data)
gtk_widget_show_all (dialog);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
- GrlContentMedia *media;
+ GrlMedia *media;
const gchar *url = gtk_entry_get_text (GTK_ENTRY (e2));
if (!url || !url[0]) {
- media = grl_content_box_new ();
+ media = grl_media_box_new ();
} else {
- media = grl_content_media_new ();
- grl_content_media_set_url (media, url);
+ media = grl_media_new ();
+ grl_media_set_url (media, url);
}
- grl_content_media_set_title (media, gtk_entry_get_text (GTK_ENTRY (e1)));
- grl_content_media_set_description (media,
- gtk_entry_get_text (GTK_ENTRY (e3)));
- grl_media_source_store (source, GRL_CONTENT_BOX (container),
+ grl_media_set_title (media, gtk_entry_get_text (GTK_ENTRY (e1)));
+ grl_media_set_description (media,
+ gtk_entry_get_text (GTK_ENTRY (e3)));
+ grl_media_source_store (source, GRL_MEDIA_BOX (container),
media, store_cb, NULL);
}
@@ -808,11 +822,11 @@ store_btn_clicked_cb (GtkButton *btn, gpointer user_data)
}
static void
-remove_item_from_view (GrlMediaSource *source, GrlContentMedia *media)
+remove_item_from_view (GrlMediaSource *source, GrlMedia *media)
{
GtkTreeIter iter;
GrlMediaSource *iter_source;
- GrlContentMedia *iter_media;
+ GrlMedia *iter_media;
gboolean found = FALSE;
gboolean more;
@@ -839,7 +853,7 @@ remove_item_from_view (GrlMediaSource *source, GrlContentMedia *media)
static void
remove_cb (GrlMediaSource *source,
- GrlContentMedia *media,
+ GrlMedia *media,
gpointer user_data,
const GError *error)
{
@@ -859,7 +873,7 @@ remove_btn_clicked_cb (GtkButton *btn, gpointer user_data)
GtkTreeModel *model = NULL;
GtkTreeIter iter;
GrlMediaSource *source;
- GrlContentMedia *media;
+ GrlMedia *media;
sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view->browser));
gtk_tree_selection_get_selected (sel, &model, &iter);
@@ -881,7 +895,7 @@ remove_btn_clicked_cb (GtkButton *btn, gpointer user_data)
static void
search_cb (GrlMediaSource *source,
guint search_id,
- GrlContentMedia *media,
+ GrlMedia *media,
guint remaining,
gpointer user_data,
const GError *error)
@@ -901,10 +915,10 @@ search_cb (GrlMediaSource *source,
if (media) {
icon = get_icon_for_media (media);
- name = grl_content_media_get_title (media);
- if (GRL_IS_CONTENT_BOX (media)) {
+ name = grl_media_get_title (media);
+ if (GRL_IS_MEDIA_BOX (media)) {
gint childcount =
- grl_content_box_get_childcount (GRL_CONTENT_BOX (media));
+ grl_media_box_get_childcount (GRL_MEDIA_BOX (media));
type = OBJECT_TYPE_CONTAINER;
if (childcount != GRL_METADATA_KEY_CHILDCOUNT_UNKNOWN) {
name = g_strdup_printf ("%s (%d)", name, childcount);
@@ -1059,9 +1073,9 @@ query_combo_setup (void)
view->query_combo_model);
registry = grl_plugin_registry_get_instance ();
- sources = grl_plugin_registry_get_sources_by_capabilities (registry,
- GRL_OP_QUERY,
- FALSE);
+ sources = grl_plugin_registry_get_sources_by_operations (registry,
+ GRL_OP_QUERY,
+ FALSE);
while (sources[i]) {
gchar *name =
g_strdup (grl_metadata_source_get_name (GRL_METADATA_SOURCE (sources[i])));
@@ -1095,9 +1109,9 @@ search_combo_setup (void)
view->search_combo_model);
registry = grl_plugin_registry_get_instance ();
- sources = grl_plugin_registry_get_sources_by_capabilities (registry,
- GRL_OP_SEARCH,
- FALSE);
+ sources = grl_plugin_registry_get_sources_by_operations (registry,
+ GRL_OP_SEARCH,
+ FALSE);
while (sources[i]) {
gchar *name =
g_strdup (grl_metadata_source_get_name (GRL_METADATA_SOURCE (sources[i])));
@@ -1115,6 +1129,21 @@ search_combo_setup (void)
}
static void
+set_flickr_config (void)
+{
+ GrlConfig *config;
+ GrlPluginRegistry *registry;
+
+ config = grl_config_new ("grl-flickr", NULL);
+ grl_config_set_api_key (config, FLICKR_KEY);
+ grl_config_set_api_token (config, FLICKR_TOKEN);
+ grl_config_set_api_secret (config, FLICKR_SECRET);
+
+ registry = grl_plugin_registry_get_instance ();
+ grl_plugin_registry_add_config (registry, config);
+}
+
+static void
launchers_setup (void)
{
launchers = g_new0 (UriLaunchers, 1);
@@ -1352,9 +1381,9 @@ show_plugins ()
clear_panes ();
i = 0;
- sources = grl_plugin_registry_get_sources_by_capabilities (registry,
- GRL_OP_BROWSE,
- FALSE);
+ sources = grl_plugin_registry_get_sources_by_operations (registry,
+ GRL_OP_BROWSE,
+ FALSE);
while (sources[i]) {
gchar *name;
GdkPixbuf *icon;
@@ -1468,6 +1497,7 @@ main (int argc, gchar *argv[])
grl_log_init ("*:*");
launchers_setup ();
ui_setup ();
+ set_flickr_config ();
load_plugins ();
gtk_main ();
return 0;
diff --git a/tools/js/testGrilo.js b/tools/js/testGrilo.js
new file mode 100644
index 0000000..5991cc4
--- /dev/null
+++ b/tools/js/testGrilo.js
@@ -0,0 +1,68 @@
+//
+// testGrilo.js
+// Simple program to test Grilo's introspected API.
+//
+// Copyright (C) 2010, Igalia S.L.
+//
+// Author: Eduardo Lima Mitev <elima@igalia.com>
+//
+
+const Grl = imports.gi.Grilo;
+const MainLoop = imports.mainloop;
+
+function SimplePlayList () {
+ this._init ();
+}
+
+SimplePlayList.prototype = {
+ _init: function () {
+ Grl.grl_log_init ("*:-");
+ let registry = Grl.GrlPluginRegistry.get_instance ();
+
+ let sources = [];
+ this.sources = sources;
+
+ registry.connect ("source_added",
+ function (pluginRegistry, mediaSource) {
+ let ops = mediaSource.supported_operations ();
+ if (ops & Grl.GrlSupportedOps.SEARCH) {
+ log ("Detected new source availabe: '" +
+ mediaSource.get_name () +
+ "' and it supports search");
+ sources.push (mediaSource);
+ }
+ });
+
+ registry.connect ("source_removed",
+ function (pluginRegistry, mediaSource) {
+ log ("source removed");
+ });
+
+ if (registry.load_all () == false) {
+ log ("Failed to load plugins.");
+ }
+ },
+
+ _searchCallback: function search_cb () {
+ log ("yeah");
+ },
+
+ search: function (q) {
+ for each (let source in this.sources) {
+ log (source.get_name () + " - " + q);
+ source.search (q, [Grl.GRL_METADATA_KEY_ID], 0, 10,
+ Grl.GrlMetadataResolutionFlags.FULL |
+ Grl.GrlMetadataResolutionFlags.IDLE_RELAY,
+ this._searchCallback, source);
+ }
+ }
+};
+
+let playList = new SimplePlayList ();
+
+if (ARGV[0] != null) {
+ playList.search (ARGV[0]);
+ MainLoop.run ("main");
+}
+else
+ log ("Query parameter missing");
diff --git a/tools/vala/Makefile.am b/tools/vala/Makefile.am
index c47c170..28a5299 100644
--- a/tools/vala/Makefile.am
+++ b/tools/vala/Makefile.am
@@ -25,7 +25,7 @@ grilo_simple_playlist_CFLAGS = \
-DPREFIX=$(prefix) \
$(DEPS_CFLAGS) \
-I$(top_srcdir)/src \
- -I$(top_srcdir)/src/content
+ -I$(top_srcdir)/src/data
grilo_simple_playlist_LDADD = \
$(DEP_LIBS) \
diff --git a/tools/vala/grilo-test.vala b/tools/vala/grilo-test.vala
index 725f3e7..8d9b218 100644
--- a/tools/vala/grilo-test.vala
+++ b/tools/vala/grilo-test.vala
@@ -38,14 +38,14 @@ public class SimplePlaylist : Object {
private void search_cb (Grl.MediaSource source,
uint browse_id,
- Grl.ContentMedia? media,
+ Grl.Media? media,
uint remaining,
GLib.Error? error) {
if (error != null) {
critical ("Error: %s", error.message);
}
- if (media != null && (media is ContentAudio || media is ContentVideo)) {
+ if (media != null && (media is MediaAudio || media is MediaVideo)) {
var url = media.get_url ();
if (url != null) {
print ("%s\n", media.get_url ());