Loading

GrlRelatedKeys

  1. diff --git a/src/lua-factory/grl-lua-library.c b/src/lua-factory/grl-lua-library.c
  2. index 9a553ef..5d5d243 100644
  3. --- a/src/lua-factory/grl-lua-library.c
  4. +++ b/src/lua-factory/grl-lua-library.c
  5. @@ -319,12 +319,170 @@ grl_util_add_table_to_media (lua_State *L,
  6.    }
  7.  }
  8.  
  9. +static void
  10. +grl_util_add_key (lua_State *L,
  11. +                  GObject *object,
  12. +                  gboolean is_media)
  13. +{
  14. +  GrlRegistry *registry = grl_registry_get_default ();
  15. +  GrlKeyID key_id = GRL_METADATA_KEY_INVALID;
  16. +  gchar *key_name = g_strdup (lua_tostring (L, -2));
  17. +  gchar *ptr = NULL;
  18. +  GType type = G_TYPE_NONE;
  19. +
  20. +  /* Handled before */
  21. +  if (g_strcmp0 (key_name, "type") == 0) {
  22. +    goto next_key;
  23. +  }
  24. +
  25. +  /* Replace '_' to '-': convenient for the developer */
  26. +  while ((ptr = strstr (key_name, "_")) != NULL) {
  27. +    *ptr = '-';
  28. +  }
  29. +
  30. +  key_id = grl_registry_lookup_metadata_key (registry, key_name);
  31. +  if (key_id != GRL_METADATA_KEY_INVALID) {
  32. +    type = grl_registry_lookup_metadata_key_type (registry, key_id);
  33. +
  34. +    switch (type) {
  35. +    case G_TYPE_INT:
  36. +    case G_TYPE_INT64:
  37. +      if (lua_isnumber (L, -1)) {
  38. +        gint success;
  39. +        gint64 value = lua_tointegerx (L, -1, &success);
  40. +        if (success) {
  41. +          if (type == G_TYPE_INT)
  42. +            if (is_media)
  43. +              grl_data_set_int (GRL_DATA (object), key_id, value);
  44. +            else
  45. +              grl_related_keys_set_int (GRL_RELATED_KEYS (object),
  46. +                                        key_id,
  47. +                                        value);
  48. +          else
  49. +            if (is_media)
  50. +              grl_data_set_int64 (GRL_DATA (object), key_id, value);
  51. +            else
  52. +              GRL_WARNING ("'%s' requires an INT type, while an INT64 was provided",
  53. +                        key_name);
  54. +        } else {
  55. +          GRL_WARNING ("'%s' requires an INT type, while a value '%s' was provided",
  56. +                     key_name, lua_tostring(L, -1));
  57. +        }
  58. +      } else if (lua_istable (L, -1)) {
  59. +        if (is_media)
  60. +          grl_util_add_table_to_media (L, GRL_MEDIA (object), key_id, key_name, type);
  61. +        else
  62. +          GRL_WARNING ("Table not compatible for GrlResolve");
  63. +      } else if (!lua_isnil (L, -1)) {
  64. +        GRL_WARNING ("'%s' is not compatible for '%s'",
  65. +                     lua_typename (L, lua_type(L, -1)), key_name);
  66. +      }
  67. +      break;
  68. +
  69. +    case G_TYPE_FLOAT:
  70. +      if (lua_isnumber (L, -1)) {
  71. +        if (is_media)
  72. +          grl_data_set_float (GRL_DATA (object), key_id, lua_tonumber (L, -1));
  73. +        else
  74. +          grl_related_keys_set_float ( GRL_RELATED_KEYS (object),
  75. +                                       key_id,
  76. +                                       lua_tonumber (L, -1));
  77. +      } else if (lua_istable (L, -1)) {
  78. +        if (is_media)
  79. +          grl_util_add_table_to_media (L, GRL_MEDIA (object), key_id, key_name, type);
  80. +        else
  81. +          GRL_WARNING ("Table not compatible for GrlResolve");
  82. +      } else if (!lua_isnil (L, -1)) {
  83. +        GRL_WARNING ("'%s' is not compatible for '%s'",
  84. +                     lua_typename (L, lua_type(L, -1)), key_name);
  85. +      }
  86. +      break;
  87. +
  88. +    case G_TYPE_STRING:
  89. +      if (lua_isstring (L, -1)) {
  90. +        if (is_media)
  91. +          grl_data_set_lua_string (GRL_DATA (object), key_id, key_name, lua_tostring (L, -1));
  92. +        else
  93. +          grl_related_keys_set_string (GRL_RELATED_KEYS (object),
  94. +                                       key_id,
  95. +                                       lua_tostring (L, -1));
  96. +      } else if (lua_istable (L, -1)) {
  97. +        if (is_media)
  98. +          grl_util_add_table_to_media (L, GRL_MEDIA (object), key_id, key_name, type);
  99. +        else
  100. +          GRL_WARNING ("Table not compatible for GrlResolve");
  101. +      } else if (!lua_isnil (L, -1)) {
  102. +        GRL_WARNING ("'%s' is not compatible for '%s'",
  103. +                     lua_typename (L, lua_type(L, -1)), key_name);
  104. +      }
  105. +      break;
  106. +    case G_TYPE_BOOLEAN:
  107. +      if (lua_isboolean (L, -1)) {
  108. +        if (is_media)
  109. +          grl_data_set_boolean (GRL_DATA (object), key_id, lua_toboolean (L, -1));
  110. +        else
  111. +          grl_related_keys_set_boolean (GRL_RELATED_KEYS (object),
  112. +                                        key_id,
  113. +                                        lua_toboolean (L, -1));
  114. +      } else if (!lua_isnil (L, -1)) {
  115. +        GRL_WARNING ("'%s' is not compatible for '%s'",
  116. +                     lua_typename (L, lua_type(L, -1)), key_name);
  117. +      }
  118. +      break;
  119. +
  120. +    default:
  121. +      /* Non-fundamental types don't reduce to ints, so can't be
  122. +       * in the switch statement */
  123. +      if (type == G_TYPE_DATE_TIME) {
  124. +        GDateTime *date;
  125. +        const char *date_str = lua_tostring (L, -1);
  126. +        date = grl_date_time_from_iso8601 (date_str);
  127. +        /* Try a number of seconds since Epoch */
  128. +        if (!date) {
  129. +          gint64 date_int = g_ascii_strtoll (date_str, NULL, 0);
  130. +          if (date_int)
  131. +            date = g_date_time_new_from_unix_utc (date_int);
  132. +        }
  133. +        if (date) {
  134. +          if (is_media)
  135. +            grl_data_set_boxed (GRL_DATA (object), key_id, date);
  136. +          else
  137. +            grl_related_keys_set_boxed (GRL_RELATED_KEYS (object),
  138. +                                        key_id,
  139. +                                        date);
  140. +          g_date_time_unref (date);
  141. +        } else {
  142. +          GRL_WARNING ("'%s' is not a valid ISO-8601 or Epoch date", date_str);
  143. +        }
  144. +      } else if (type == G_TYPE_BYTE_ARRAY) {
  145. +         gsize size = luaL_len (L, -1);
  146. +         const guint8 *binary = (const guint8 *) lua_tostring (L, -1);
  147. +         if (is_media)
  148. +           grl_data_set_binary (GRL_DATA (object), key_id, binary, size);
  149. +         else
  150. +           grl_related_keys_set_binary (GRL_RELATED_KEYS (object),
  151. +                                        key_id,
  152. +                                        binary,
  153. +                                        size);
  154. +      } else if (!lua_isnil (L, -1)) {
  155. +        GRL_WARNING ("'%s' is being ignored as G_TYPE is not being handled.",
  156. +                     key_name);
  157. +      }
  158. +    }
  159. +  } else {
  160. +    GRL_WARNING ("'%s' is not a valid keyword", key_name);
  161. +  }
  162. +
  163. +next_key:
  164. +  g_free (key_name);
  165. +}
  166. +
  167.  static GrlMedia *
  168.  grl_util_build_media (lua_State *L,
  169.                        GrlMedia *user_media)
  170.  {
  171. -  GrlRegistry *registry;
  172.    GrlMedia *media = user_media;
  173. +  int array_len;
  174.  
  175.    if (!lua_istable (L, 1)) {
  176.      if (!lua_isnil (L, 1))
  177. @@ -333,6 +491,10 @@ grl_util_build_media (lua_State *L,
  178.      return user_media;
  179.    }
  180.  
  181. +  lua_len (L, 1);
  182. +  array_len = lua_tointeger (L, -1);
  183. +  lua_pop (L, 1);
  184. +
  185.    if (media == NULL) {
  186.      lua_getfield (L, 1, "type");
  187.      if (lua_isstring (L, -1)) {
  188. @@ -351,115 +513,25 @@ grl_util_build_media (lua_State *L,
  189.      lua_pop (L, 1);
  190.    }
  191.  
  192. -  registry = grl_registry_get_default ();
  193.    lua_pushnil (L);
  194.    while (lua_next (L, 1) != 0) {
  195. -    GrlKeyID key_id = GRL_METADATA_KEY_INVALID;
  196. -    gchar *key_name = g_strdup (lua_tostring (L, -2));
  197. -    gchar *ptr = NULL;
  198. -    GType type = G_TYPE_NONE;
  199. -
  200. -    /* Handled above */
  201. -    if (g_strcmp0 (key_name, "type") == 0) {
  202. -      goto next_key;
  203. -    }
  204. -
  205. -    /* Replace '_' to '-': convenient for the developer */
  206. -    while ((ptr = strstr (key_name, "_")) != NULL) {
  207. -      *ptr = '-';
  208. -    }
  209. -
  210. -    key_id = grl_registry_lookup_metadata_key (registry, key_name);
  211. -    if (key_id != GRL_METADATA_KEY_INVALID) {
  212. -      type = grl_registry_lookup_metadata_key_type (registry, key_id);
  213. -
  214. -      switch (type) {
  215. -      case G_TYPE_INT:
  216. -      case G_TYPE_INT64:
  217. -        if (lua_isnumber (L, -1)) {
  218. -          gint success;
  219. -          gint64 value = lua_tointegerx (L, -1, &success);
  220. -          if (success) {
  221. -            if (type == G_TYPE_INT)
  222. -              grl_data_set_int (GRL_DATA (media), key_id, value);
  223. -            else
  224. -              grl_data_set_int64 (GRL_DATA (media), key_id, value);
  225. -          } else {
  226. -            GRL_WARNING ("'%s' requires an INT type, while a value '%s' was provided",
  227. -                       key_name, lua_tostring(L, -1));
  228. -          }
  229. -        } else if (lua_istable (L, -1)) {
  230. -          grl_util_add_table_to_media (L, media, key_id, key_name, type);
  231. -        } else if (!lua_isnil (L, -1)) {
  232. -          GRL_WARNING ("'%s' is not compatible for '%s'",
  233. -                       lua_typename (L, lua_type(L, -1)), key_name);
  234. -        }
  235. -        break;
  236. -
  237. -      case G_TYPE_FLOAT:
  238. -        if (lua_isnumber (L, -1)) {
  239. -          grl_data_set_float (GRL_DATA (media), key_id, lua_tonumber (L, -1));
  240. -        } else if (lua_istable (L, -1)) {
  241. -          grl_util_add_table_to_media (L, media, key_id, key_name, type);
  242. -        } else if (!lua_isnil (L, -1)) {
  243. -          GRL_WARNING ("'%s' is not compatible for '%s'",
  244. -                       lua_typename (L, lua_type(L, -1)), key_name);
  245. -        }
  246. -        break;
  247. -
  248. -      case G_TYPE_STRING:
  249. -        if (lua_isstring (L, -1)) {
  250. -          grl_data_set_lua_string (GRL_DATA (media), key_id, key_name, lua_tostring (L, -1));
  251. -        } else if (lua_istable (L, -1)) {
  252. -          grl_util_add_table_to_media (L, media, key_id, key_name, type);
  253. -        } else if (!lua_isnil (L, -1)) {
  254. -          GRL_WARNING ("'%s' is not compatible for '%s'",
  255. -                       lua_typename (L, lua_type(L, -1)), key_name);
  256. -        }
  257. -        break;
  258. -      case G_TYPE_BOOLEAN:
  259. -        if (lua_isboolean (L, -1)) {
  260. -          grl_data_set_boolean (GRL_DATA (media), key_id, lua_toboolean (L, -1));
  261. -        } else if (!lua_isnil (L, -1)) {
  262. -          GRL_WARNING ("'%s' is not compatible for '%s'",
  263. -                       lua_typename (L, lua_type(L, -1)), key_name);
  264. -        }
  265. -        break;
  266. -
  267. -      default:
  268. -        /* Non-fundamental types don't reduce to ints, so can't be
  269. -         * in the switch statement */
  270. -        if (type == G_TYPE_DATE_TIME) {
  271. -          GDateTime *date;
  272. -          const char *date_str = lua_tostring (L, -1);
  273. -          date = grl_date_time_from_iso8601 (date_str);
  274. -          /* Try a number of seconds since Epoch */
  275. -          if (!date) {
  276. -            gint64 date_int = g_ascii_strtoll (date_str, NULL, 0);
  277. -            if (date_int)
  278. -              date = g_date_time_new_from_unix_utc (date_int);
  279. -          }
  280. -          if (date) {
  281. -            grl_data_set_boxed (GRL_DATA (media), key_id, date);
  282. -            g_date_time_unref (date);
  283. -          } else {
  284. -            GRL_WARNING ("'%s' is not a valid ISO-8601 or Epoch date", date_str);
  285. -          }
  286. -        } else if (type == G_TYPE_BYTE_ARRAY) {
  287. -           gsize size = luaL_len (L, -1);
  288. -           const guint8 *binary = (const guint8 *) lua_tostring (L, -1);
  289. -           grl_data_set_binary (GRL_DATA (media), key_id, binary, size);
  290. -        } else if (!lua_isnil (L, -1)) {
  291. -          GRL_WARNING ("'%s' is being ignored as G_TYPE is not being handled.",
  292. -                       key_name);
  293. -        }
  294. +    if (lua_type (L, -2) == LUA_TNUMBER &&
  295. +        lua_tointeger (L, -2) >= 1 && lua_tointeger (L, -2) <= array_len) {
  296. +      if (lua_type (L, -1) != LUA_TTABLE) {
  297. +          GRL_WARNING ("Array indexes should be tables to be resolved to \
  298. +                        GrlRelatedKeys");
  299. +          continue;
  300.        }
  301. +      GrlRelatedKeys *related_keys = grl_related_keys_new ();
  302. +      lua_pushnil (L);
  303. +      while (lua_next (L, -2) != 0) {
  304. +        grl_util_add_key (L, G_OBJECT (related_keys), FALSE);
  305. +        lua_pop (L, 1);
  306. +      }
  307. +      grl_data_add_related_keys (GRL_DATA (media), related_keys);
  308.      } else {
  309. -      GRL_WARNING ("'%s' is not a valid keyword", key_name);
  310. +      grl_util_add_key (L, G_OBJECT (media), TRUE);
  311.      }
  312. -
  313. -next_key:
  314. -    g_free (key_name);
  315.      lua_pop (L, 1);
  316.    }
  317.    return media;