diff options
author | George Sedov <radist.morse@gmail.com> | 2015-11-27 13:56:54 +0300 |
---|---|---|
committer | Victor Toso <me@victortoso.com> | 2016-01-30 11:09:03 +0100 |
commit | 2bfcff90d589d4335105a6423616c7de61cf4c71 (patch) | |
tree | c1d19bd91df060f6f95ab9c321aff9421e76c62b | |
parent | 66abb77948744d09722c503c029b4c458beb19d0 (diff) |
lua-factory: change grl.get_options() into the static table
It's part of the work aimed at removing the OperationSpec from the
global scope.
grl_l_operation_get_keys was replced by push_operation_requested_keys
grl_l_operation_get_options was split and replaced by
push_operation_type_filter
push_operation_range_filters
push_operation_filters
grl_lua_library_push_grl_options
https://bugzilla.gnome.org/show_bug.cgi?id=753141
Acked-by: Victor Toso <me@victortoso.com>
-rw-r--r-- | src/lua-factory/grl-lua-common.h | 5 | ||||
-rw-r--r-- | src/lua-factory/grl-lua-factory.c | 27 | ||||
-rw-r--r-- | src/lua-factory/grl-lua-library.c | 527 |
3 files changed, 340 insertions, 219 deletions
diff --git a/src/lua-factory/grl-lua-common.h b/src/lua-factory/grl-lua-common.h index 9c6f901..79f8fd3 100644 --- a/src/lua-factory/grl-lua-common.h +++ b/src/lua-factory/grl-lua-common.h @@ -68,14 +68,11 @@ typedef enum { typedef struct _OperationSpec { GrlSource *source; guint operation_id; - GrlOperationOptions *options; - GList *keys; LuaOperationType op_type; union { GrlSourceResultCb result; GrlSourceResolveCb resolve; } cb; - char *string; GrlMedia *media; gpointer user_data; guint error_code; @@ -93,4 +90,6 @@ OperationSpec * grl_lua_library_get_current_operation (lua_State *L); void grl_lua_library_save_goa_data (lua_State *L, gpointer goa_object); gpointer grl_lua_library_load_goa_data (lua_State *L); +void grl_lua_library_push_grl_options (lua_State *L, guint operation_id, GrlOperationOptions *options, GList *keys); + #endif /* _GRL_LUA_LIBRARY_COMMON_H_ */ diff --git a/src/lua-factory/grl-lua-factory.c b/src/lua-factory/grl-lua-factory.c index 1f93d75..8954671 100644 --- a/src/lua-factory/grl-lua-factory.c +++ b/src/lua-factory/grl-lua-factory.c @@ -1495,10 +1495,7 @@ grl_lua_factory_source_search (GrlSource *source, os->operation_id = ss->operation_id; os->cb.result = ss->callback; os->user_data = ss->user_data; - os->string = g_strdup (text); os->error_code = GRL_CORE_ERROR_SEARCH_FAILED; - os->keys = g_list_copy (ss->keys); - os->options = grl_operation_options_copy (ss->options); os->op_type = LUA_SEARCH; grl_lua_library_save_operation_data (L, os); @@ -1506,7 +1503,9 @@ grl_lua_factory_source_search (GrlSource *source, lua_getglobal (L, LUA_SOURCE_OPERATION[LUA_SEARCH]); lua_pushstring (L, text); - if (lua_pcall (L, 1, 0, 0)) { + grl_lua_library_push_grl_options (L, ss->operation_id, ss->options, ss->keys); + + if (lua_pcall (L, 2, 0, 0)) { GRL_WARNING ("%s '%s'", "calling search function fail:", lua_tolstring (L, -1, NULL)); lua_pop (L, 1); @@ -1534,10 +1533,7 @@ grl_lua_factory_source_browse (GrlSource *source, os->media = bs->container; os->cb.result = bs->callback; os->user_data = bs->user_data; - os->string = g_strdup (media_id); os->error_code = GRL_CORE_ERROR_BROWSE_FAILED; - os->keys = g_list_copy (bs->keys); - os->options = grl_operation_options_copy (bs->options); os->op_type = LUA_BROWSE; grl_lua_library_save_operation_data (L, os); @@ -1545,7 +1541,9 @@ grl_lua_factory_source_browse (GrlSource *source, lua_getglobal (L, LUA_SOURCE_OPERATION[LUA_BROWSE]); lua_pushstring (L, media_id); - if (lua_pcall (L, 1, 0, 0)) { + grl_lua_library_push_grl_options (L, bs->operation_id, bs->options, bs->keys); + + if (lua_pcall (L, 2, 0, 0)) { GRL_WARNING ("%s '%s'", "calling browse function fail:", lua_tolstring (L, -1, NULL)); lua_pop (L, 1); @@ -1572,10 +1570,7 @@ grl_lua_factory_source_query (GrlSource *source, os->operation_id = qs->operation_id; os->cb.result = qs->callback; os->user_data = qs->user_data; - os->string = g_strdup (query); os->error_code = GRL_CORE_ERROR_QUERY_FAILED; - os->keys = g_list_copy (qs->keys); - os->options = grl_operation_options_copy (qs->options); os->op_type = LUA_QUERY; grl_lua_library_save_operation_data (L, os); @@ -1583,7 +1578,9 @@ grl_lua_factory_source_query (GrlSource *source, lua_getglobal (L, LUA_SOURCE_OPERATION[LUA_QUERY]); lua_pushstring (L, query); - if (lua_pcall (L, 1, 0, 0)) { + grl_lua_library_push_grl_options (L, qs->operation_id, qs->options, qs->keys); + + if (lua_pcall (L, 2, 0, 0)) { GRL_WARNING ("%s '%s'", "calling query function fail:", lua_tolstring (L, -1, NULL)); lua_pop (L, 1); @@ -1611,15 +1608,15 @@ grl_lua_factory_source_resolve (GrlSource *source, os->media = rs->media; os->user_data = rs->user_data; os->error_code = GRL_CORE_ERROR_RESOLVE_FAILED; - os->keys = g_list_copy (rs->keys); - os->options = grl_operation_options_copy (rs->options); os->op_type = LUA_RESOLVE; grl_lua_library_save_operation_data (L, os); grl_lua_library_set_current_operation (L, os->operation_id); lua_getglobal (L, LUA_SOURCE_OPERATION[LUA_RESOLVE]); - if (lua_pcall (L, 0, 0, 0)) { + grl_lua_library_push_grl_options (L, rs->operation_id, rs->options, rs->keys); + + if (lua_pcall (L, 1, 0, 0)) { GRL_WARNING ("%s '%s'", "calling resolve function fail:", lua_tolstring (L, -1, NULL)); lua_pop (L, 1); diff --git a/src/lua-factory/grl-lua-library.c b/src/lua-factory/grl-lua-library.c index ec53faf..84ec452 100644 --- a/src/lua-factory/grl-lua-library.c +++ b/src/lua-factory/grl-lua-library.c @@ -722,202 +722,6 @@ net_wc_new_with_options(lua_State *L, /* ================== Lua-Library methods ================================== */ -/** -* grl.get_options -* -* @option: (string) Name of the option you want (e.g. count, flags). -* @key: (string) Name of the key when option request it. -* @return: The option or nil if none; -*/ -static gint -grl_l_operation_get_options (lua_State *L) -{ - OperationSpec *os; - const gchar *option; - - luaL_argcheck (L, lua_isstring (L, 1), 1, "expecting option (string)"); - - os = grl_lua_library_get_current_operation (L); - g_return_val_if_fail (os != NULL, 0); - option = lua_tostring (L, 1); - - if (g_strcmp0 (option, "type") == 0) { - const char *type; - switch (os->op_type) { - case LUA_SEARCH: - type = "search"; - break; - case LUA_BROWSE: - type = "browse"; - break; - case LUA_QUERY: - type = "query"; - break; - case LUA_RESOLVE: - type = "resolve"; - break; - default: - g_assert_not_reached (); - } - - lua_pushstring (L, type); - return 1; - } - - if (g_strcmp0 (option, "count") == 0) { - gint count = grl_operation_options_get_count (os->options); - - lua_pushinteger (L, count); - return 1; - } - - if (g_strcmp0 (option, "skip") == 0) { - guint skip = grl_operation_options_get_skip (os->options); - - lua_pushinteger (L, skip); - return 1; - } - - if (g_strcmp0 (option, "flags") == 0) { - GrlResolutionFlags flags = grl_operation_options_get_resolution_flags (os->options); - - lua_pushinteger (L, (gint) flags); - return 1; - } - - if (g_strcmp0 (option, "key-filter") == 0) { - GrlKeyID key; - GValue *value = NULL; - const gchar *key_name = NULL; - GrlRegistry *registry = grl_registry_get_default (); - - luaL_argcheck (L, lua_isstring (L, 2), 2, "expecting key name"); - key_name = lua_tostring (L, 2); - - key = grl_registry_lookup_metadata_key (registry, key_name); - value = grl_operation_options_get_key_filter (os->options, key); - switch (grl_registry_lookup_metadata_key_type (registry, key)) { - case G_TYPE_INT: - (value) ? (void) lua_pushinteger (L, g_value_get_int (value)) : lua_pushnil (L); - break; - - case G_TYPE_FLOAT: - (value) ? (void) lua_pushnumber (L, g_value_get_float (value)) : lua_pushnil (L); - break; - - case G_TYPE_STRING: - (value) ? (void) lua_pushstring (L, g_value_get_string (value)) : lua_pushnil (L); - break; - - case G_TYPE_BOOLEAN: - (value) ? (void) lua_pushboolean (L, g_value_get_boolean (value)) : lua_pushnil (L); - break; - - default: - GRL_DEBUG ("'%s' is being ignored as G_TYPE is not being handled.", - key_name); - } - return 1; - } - - if (g_strcmp0 (option, "range-filter") == 0) { - GValue *min = NULL; - GValue *max = NULL; - GrlKeyID key; - const gchar *key_name = NULL; - GrlRegistry *registry = grl_registry_get_default (); - - luaL_argcheck (L, lua_isstring (L, 2), 2, "expecting key name"); - key_name = lua_tostring (L, 2); - - key = grl_registry_lookup_metadata_key (registry, key_name); - if (key != GRL_METADATA_KEY_INVALID) { - grl_operation_options_get_key_range_filter (os->options, key, &min, &max); - switch (grl_registry_lookup_metadata_key_type (registry, key)) { - case G_TYPE_INT: - (min) ? (void) lua_pushinteger (L, g_value_get_int (min)) : lua_pushnil (L); - (max) ? (void) lua_pushinteger (L, g_value_get_int (max)) : lua_pushnil (L); - break; - - case G_TYPE_FLOAT: - (min) ? (void) lua_pushnumber (L, g_value_get_float (min)) : lua_pushnil (L); - (max) ? (void) lua_pushnumber (L, g_value_get_float (max)) : lua_pushnil (L); - break; - - case G_TYPE_STRING: - (min) ? (void) lua_pushstring (L, g_value_get_string (min)) : lua_pushnil (L); - (max) ? (void) lua_pushstring (L, g_value_get_string (max)) : lua_pushnil (L); - break; - - default: - GRL_DEBUG ("'%s' is being ignored as G_TYPE is not being handled.", - key_name); - } - } - return 2; - } - - if (g_strcmp0 (option, "operation-id") == 0) { - lua_pushinteger (L, (gint) os->operation_id); - return 1; - } - - if (g_strcmp0 (option, "media-id") == 0 && - os->op_type == LUA_BROWSE) { - lua_pushstring (L, os->string); - return 1; - } - - if (g_strcmp0 (option, "query") == 0 && - os->op_type == LUA_QUERY) { - lua_pushstring (L, os->string); - return 1; - } - - if (g_strcmp0 (option, "search") == 0 && - os->op_type == LUA_SEARCH) { - lua_pushstring (L, os->string); - return 1; - } - - luaL_error (L, "'%s' is not available nor implemented.", option); - return 0; -} - -/** -* grl.get_media_keys -* -* @return: array of all requested keys from application (may be empty); -*/ -static gint -grl_l_operation_get_keys (lua_State *L) -{ - OperationSpec *os; - GrlRegistry *registry; - GList *it; - gint i = 0; - - os = grl_lua_library_get_current_operation (L); - g_return_val_if_fail (os != NULL, 0); - - registry = grl_registry_get_default (); - lua_newtable (L); - for (it = os->keys; it; it = g_list_next (it)) { - GrlKeyID key_id; - const gchar *key_name; - - key_id = GRLPOINTER_TO_KEYID (it->data); - key_name = grl_registry_lookup_metadata_key_name (registry, key_id); - if (key_id != GRL_METADATA_KEY_INVALID) { - lua_pushinteger (L, i + 1); - lua_pushstring (L, key_name); - lua_settable (L, -3); - i++; - } - } - return 1; -} - static gboolean push_grl_media_key (lua_State *L, GrlMedia *media, @@ -1182,12 +986,9 @@ grl_l_callback (lua_State *L) /* Free Operation Spec */ if (count == 0) { - g_list_free (os->keys); - g_object_unref (os->options); os->callback_done = TRUE; grl_lua_library_remove_operation_data (L, os->operation_id); grl_lua_library_set_current_operation (L, 0); - g_free (os->string); g_slice_free (OperationSpec, os); } @@ -1528,8 +1329,6 @@ gint luaopen_grilo (lua_State *L) { static const luaL_Reg library_fn[] = { - {"get_options", &grl_l_operation_get_options}, - {"get_requested_keys", &grl_l_operation_get_keys}, {"get_media_keys", &grl_l_media_get_keys}, {"callback", &grl_l_callback}, {"fetch", &grl_l_fetch}, @@ -1772,3 +1571,329 @@ grl_lua_library_load_goa_data (lua_State *L) return NULL; #endif /* GOA_ENABLED */ } + +/** + * push_operation_requested_keys + * + * Pushes the table representing the list of requested + * keys for the current operation on top of the lua stack. + * + * @L: LuaState where the data is stored. + * @keys: The requested keys of the current operation. + * @return: Nothing. + */ +static void +push_operation_requested_keys (lua_State *L, + GList *keys) +{ + GrlRegistry *registry = grl_registry_get_default (); + GList *it; + gint i = 1; + + lua_newtable (L); + for (it = keys; it != NULL; it = it->next) { + GrlKeyID key_id; + const gchar *key_name; + + key_id = GRLPOINTER_TO_KEYID (it->data); + if (key_id == GRL_METADATA_KEY_INVALID) + continue; + + key_name = grl_registry_lookup_metadata_key_name (registry, key_id); + lua_pushinteger (L, i); + lua_pushstring (L, key_name); + lua_settable (L, -3); + i++; + } +} + +/** + * push_operation_type_filter + * + * Pushes the type filter table into the filters table. The + * filters table should already be on top of the lua stack. + * + * @L: LuaState where the data is stored. + * @options: The GrlOperationOptions from which to retrieve filter. + * @return: Nothing. + */ +static void +push_operation_type_filter (lua_State *L, + GrlOperationOptions *options) +{ + GrlTypeFilter type_filter; + + g_assert (lua_istable (L, -1)); + + type_filter = grl_operation_options_get_type_filter (options); + + lua_pushstring (L, "types"); + lua_newtable (L); + + lua_pushstring (L, "audio"); + lua_pushboolean (L, (type_filter & GRL_TYPE_FILTER_AUDIO)); + lua_settable (L, -3); + lua_pushstring (L, "video"); + lua_pushboolean (L, (type_filter & GRL_TYPE_FILTER_VIDEO)); + lua_settable (L, -3); + lua_pushstring (L, "image"); + lua_pushboolean (L, (type_filter & GRL_TYPE_FILTER_IMAGE)); + lua_settable (L, -3); + lua_settable (L, -3); +} + +/** + * push_operation_range_filters + * + * Pushes the elements of the filters table representing + * the range filters into the table. The filters table should + * already be on top of the lua stack. + * + * @L: LuaState where the data is stored. + * @options: The GrlOperationOptions from which to retrieve filters. + * @return: Nothing. + */ +static void +push_operation_range_filters (lua_State *L, + GrlOperationOptions *options) +{ + GrlRegistry *registry; + GList *range_filters; + GList *it; + + g_assert (lua_istable (L, -1)); + + registry = grl_registry_get_default (); + range_filters = grl_operation_options_get_key_range_filter_list (options); + + for (it = range_filters; it != NULL; it = it->next) { + GrlKeyID key_id; + gchar *key_name; + gchar *ptr; + GValue *min = NULL; + GValue *max = NULL; + gboolean success = TRUE; + + key_id = GRLPOINTER_TO_KEYID (it->data); + if (key_id == GRL_METADATA_KEY_INVALID) + continue; + + grl_operation_options_get_key_range_filter (options, key_id, &min, &max); + key_name = g_strdup (grl_registry_lookup_metadata_key_name (registry, key_id)); + + /* Replace '-' to '_': as a convenience for the developer */ + while ((ptr = strstr (key_name, "-")) != NULL) { + *ptr = '_'; + } + + lua_pushstring (L, key_name); + g_free (key_name); + lua_newtable (L); + + switch (grl_registry_lookup_metadata_key_type (registry, key_id)) { + case G_TYPE_INT: + lua_pushstring (L, "min"); + (min) ? (void) lua_pushinteger (L, g_value_get_int (min)) : lua_pushnil (L); + lua_settable (L, -3); + lua_pushstring (L, "max"); + (max) ? (void) lua_pushinteger (L, g_value_get_int (max)) : lua_pushnil (L); + lua_settable (L, -3); + break; + + case G_TYPE_FLOAT: + lua_pushstring (L, "min"); + (min) ? (void) lua_pushnumber (L, g_value_get_float (min)) : lua_pushnil (L); + lua_settable (L, -3); + lua_pushstring (L, "max"); + (max) ? (void) lua_pushnumber (L, g_value_get_float (max)) : lua_pushnil (L); + lua_settable (L, -3); + break; + + case G_TYPE_STRING: + lua_pushstring (L, "min"); + (min) ? (void) lua_pushstring (L, g_value_get_string (min)) : lua_pushnil (L); + lua_settable (L, -3); + lua_pushstring (L, "max"); + (max) ? (void) lua_pushstring (L, g_value_get_string (max)) : lua_pushnil (L); + lua_settable (L, -3); + break; + + case G_TYPE_INT64: + lua_pushstring (L, "min"); + (min) ? (void) lua_pushinteger (L, g_value_get_int64 (min)) : lua_pushnil (L); + lua_settable (L, -3); + lua_pushstring (L, "max"); + (max) ? (void) lua_pushinteger (L, g_value_get_int64 (max)) : lua_pushnil (L); + lua_settable (L, -3); + break; + + default: + if (grl_registry_lookup_metadata_key_type (registry, key_id) == G_TYPE_DATE_TIME) { + /* since the value would be used for comparison, and since os.time() + * returns unix time in lua, it'd be a good idea to pass g_date_time + * as unix time here */ + GDateTime *date; + lua_pushstring (L, "min"); + if (min) { + date = g_value_get_boxed (min); + lua_pushinteger (L, g_date_time_to_unix (date)); + } else { + lua_pushnil (L); + } + lua_settable (L, -3); + lua_pushstring (L, "max"); + if (max) { + date = g_value_get_boxed (max); + lua_pushinteger (L, g_date_time_to_unix (date)); + } else { + lua_pushnil (L); + } + lua_settable (L, -3); + } else { + GRL_DEBUG ("Key %s has unhandled G_TYPE. Lua source will miss this data", + grl_registry_lookup_metadata_key_name (registry, key_id)); + + success = FALSE; + } + } + + if (success) { + lua_settable (L, -3); + } else { + lua_pop (L, 2); + } + } + g_list_free (range_filters); +} + +/** + * push_operation_filters + * + * Pushes the elements of the filters table representing + * the non-range filters into the table. The filters table + * should already be on top of the lua stack. + * + * @L: LuaState where the data is stored. + * @options: The GrlOperationOptions from which to retrieve filters. + * @return: Nothing. + */ +static void +push_operation_filters (lua_State *L, + GrlOperationOptions *options) +{ + GrlRegistry *registry; + GList *filters; + GList *it; + + g_assert (lua_istable (L, -1)); + + registry = grl_registry_get_default (); + filters = grl_operation_options_get_key_filter_list (options); + + for (it = filters; it != NULL; it = it->next) { + GrlKeyID key_id; + gchar *key_name; + gchar *ptr; + GValue *value = NULL; + gboolean success = TRUE; + + key_id = GRLPOINTER_TO_KEYID (it->data); + if (key_id == GRL_METADATA_KEY_INVALID) + continue; + + value = grl_operation_options_get_key_filter (options, key_id); + key_name = g_strdup (grl_registry_lookup_metadata_key_name (registry, key_id)); + + /* Replace '-' to '_': as a convenience for the developers */ + while ((ptr = strstr (key_name, "-")) != NULL) { + *ptr = '_'; + } + + lua_pushstring (L, key_name); + g_free (key_name); + + /* Keep all the filters in tables */ + lua_newtable (L); + lua_pushstring (L, "value"); + + switch (grl_registry_lookup_metadata_key_type (registry, key_id)) { + case G_TYPE_INT: + (value) ? (void) lua_pushinteger (L, g_value_get_int (value)) : lua_pushnil (L); + break; + + case G_TYPE_FLOAT: + (value) ? (void) lua_pushnumber (L, g_value_get_float (value)) : lua_pushnil (L); + break; + + case G_TYPE_STRING: + (value) ? (void) lua_pushstring (L, g_value_get_string (value)) : lua_pushnil (L); + break; + + case G_TYPE_BOOLEAN: + (value) ? (void) lua_pushboolean (L, g_value_get_boolean (value)) : lua_pushnil (L); + break; + + case G_TYPE_INT64: + (value) ? (void) lua_pushinteger (L, g_value_get_int64 (value)) : lua_pushnil (L); + break; + + default: + GRL_DEBUG ("'%s' is being ignored as G_TYPE is not being handled.", + grl_registry_lookup_metadata_key_name (registry, key_id)); + success = FALSE; + } + if (success) { + lua_settable (L, -3); + lua_settable (L, -3); + } else { + lua_pop (L, 3); + } + } + g_list_free (filters); +} + +/** + * grl_lua_library_push_grl_options + * + * Pushes the table representing the various options of the operation + * on top of the lua stack. + * + * @L: LuaState where the data is stored. + * @opearation_id: id of the current operation + * @option: The options of the current operation. + * @key: The requested keys of the current operation. + * @return: Nothing. + */ +void +grl_lua_library_push_grl_options (lua_State *L, + guint operation_id, + GrlOperationOptions *options, + GList *keys) +{ + lua_newtable (L); + + lua_pushstring (L, "count"); + lua_pushinteger (L, grl_operation_options_get_count (options)); + lua_settable (L, -3); + + lua_pushstring (L, "skip"); + lua_pushinteger (L, grl_operation_options_get_skip (options)); + lua_settable (L, -3); + + lua_pushstring (L, "operation_id"); + lua_pushinteger (L, (gint) operation_id); + lua_settable (L, -3); + + lua_pushstring (L, "requested_keys"); + push_operation_requested_keys(L, keys); + lua_settable (L, -3); + + lua_pushstring (L, "filters"); + lua_newtable (L); + + push_operation_type_filter (L, options); + push_operation_range_filters (L, options); + push_operation_filters (L, options); + + lua_settable (L, -3); +} |