]> arthur.barton.de Git - netatalk.git/commitdiff
Add support for filetype search
authorFrank Lahm <franklahm@googlemail.com>
Fri, 2 Nov 2012 00:17:02 +0000 (01:17 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Fri, 2 Nov 2012 00:17:02 +0000 (01:17 +0100)
etc/afpd/spotlight_SPARQL_map.c
etc/afpd/spotlight_SPARQL_map.h
etc/afpd/spotlight_module.c
etc/afpd/spotlight_rawquery_lexer.c
etc/afpd/spotlight_rawquery_lexer.l
etc/afpd/spotlight_rawquery_parser.c
etc/afpd/spotlight_rawquery_parser.y

index a39305509235dc9f7dd8d09a2a4ce9a8a251ce10..471634b7b64393e2cd64544534f0f081ae9f298e 100644 (file)
@@ -36,13 +36,14 @@ struct spotlight_sparql_map spotlight_sparql_map[] = {
     {"kMDItemContentModificationDate",  ssmt_date,  "nfo:fileLastModified"},
     {"kMDItemAttributeChangeDate",      ssmt_date,  "nfo:fileLastModified"},
     {"kMDItemAuthors",                  ssmt_str,   "dc:creator"},
-    {"kMDItemContentType",              ssmt_cnt,   "nie:mimeType"},
     {"kMDItemCopyright",                ssmt_str,   "nie:copyright"},
     {"kMDItemCountry",                  ssmt_str,   "nco:country"},
     {"kMDItemCreator",                  ssmt_str,   "dc:creator"},
     {"kMDItemDurationSeconds",          ssmt_num,   "nfo:duration"},
     {"kMDItemNumberOfPages",            ssmt_num,   "nfo:pageCount"},
     {"kMDItemTitle",                    ssmt_str,   "nie:title"},
+    {"_kMDItemGroupId",                 ssmt_type,  NULL},
+    {"kMDItemContentTypeTree",          ssmt_type,  NULL},
 
     /* Image metadata */
     {"kMDItemPixelWidth",               ssmt_num,   "nfo:width"},
@@ -62,3 +63,35 @@ struct spotlight_sparql_map spotlight_sparql_map[] = {
 
     {NULL, ssmt_str, NULL}
 };
+
+struct MDTypeMap MDTypeMap[] = {
+    {"1",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nmo#Email"},
+    {"2",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact"},
+    {"3",                       kMDTypeMapNotSup,   NULL}, /* PrefPane */
+    {"4",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Font"},
+    {"5",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Bookmark"},
+    {"6",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact"},
+    {"7",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Video"},
+    {"8",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Executable"},
+    {"9",                       kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Folder"},
+    {"10",                      kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Audio"},
+    {"11",                      kMDTypeMapMime,     "application/pdf"},
+    {"12",                      kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Presentation"},
+    {"13",                      kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Image"},
+    {"public.jpeg",             kMDTypeMapMime,     "image/jpeg"},
+    {"public.tiff",             kMDTypeMapMime,     "image/tiff"},
+    {"com.compuserve.gif",      kMDTypeMapMime,     "image/gif"},
+    {"public.png",              kMDTypeMapMime,     "image/png"},
+    {"com.microsoft.bmp",       kMDTypeMapMime,     "image/bmp"},
+    {"public.content",          kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Document"},
+    {"public.mp3",              kMDTypeMapMime,     "audio/mpeg"},
+    {"public.mpeg-4-audio",     kMDTypeMapMime,     "audio/x-aac"},
+    {"com.apple.application",   kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Software"},
+    {"public.text",             kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#TextDocument"},
+    {"public.plain-text",       kMDTypeMapMime,     "text/plain"},
+    {"public.rtf",              kMDTypeMapMime,     "text/rtf"},
+    {"public.html",             kMDTypeMapMime,     "text/html"},
+    {"public.xml",              kMDTypeMapMime,     "text/xml"},
+    {"public.source-code",      kMDTypeMapRDF,      "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#SourceCode"},
+    {NULL,                      kMDTypeMapNotSup,   NULL}
+};
index 2922241d5717f05e963f7f568d62c39b4a1be393..250894b1094ad12e4c18ea028915f61199e5575b 100644 (file)
@@ -25,7 +25,13 @@ enum ssm_type {
     ssmt_str,    /* a string value that requieres a SPARQL FILTER */
     ssmt_fts,    /* a string value that will be queried with SPARQL 'fts:match' */
     ssmt_date,   /* date values are handled in a special map function map_daterange() */
-    ssmt_cnt     /* kMDItemContentType, requires special mapping */
+    ssmt_type    /* kMDItemContentType, requires special mapping */
+};
+
+enum kMDTypeMap {
+    kMDTypeMapNotSup,           /* not supported */
+    kMDTypeMapRDF,              /* query with rdf:type */
+    kMDTypeMapMime              /* query with nie:mimeType */
 };
 
 struct spotlight_sparql_map {
@@ -34,7 +40,13 @@ struct spotlight_sparql_map {
     const char *ssm_sparql_attr;
 };
 
+struct MDTypeMap {
+    const char *mdtm_value;     /* MD query value of attributes '_kMDItemGroupId' and 'kMDItemContentTypeTree' */
+    enum kMDTypeMap mdtm_type;   /* whether SPARQL query must search attribute rdf:type or nie:mime_Type */
+    const char *mdtm_sparql;    /* the SPARQL query match string */
+};
+
 extern struct spotlight_sparql_map spotlight_sparql_map[];
 extern struct spotlight_sparql_map spotlight_sparql_date_map[];
-
+extern struct MDTypeMap MDTypeMap[];
 #endif
index efa814d33cd565dcbd304e871cdfdb97386223b9..5369319ce185eb5048dce8bd3ffa79164b41a1c1 100644 (file)
@@ -121,11 +121,11 @@ static int sl_mod_start_search(void *p)
     gchar *sparql_query;
     GError *error = NULL;
 
-    LOG(log_info, logtype_sl, "sl_mod_start_search: Spotlight query string: \"%s\"", slq->slq_qstring);
+    LOG(log_debug, logtype_sl, "sl_mod_start_search: Spotlight query string: \"%s\"", slq->slq_qstring);
 
     EC_ZERO_LOGSTR( map_spotlight_to_sparql_query(slq, &sparql_query),
                     "Mapping Spotlight query failed: \"%s\"", slq->slq_qstring );
-    LOG(log_info, logtype_sl, "sl_mod_start_search: SPARQL query: \"%s\"", sparql_query);
+    LOG(log_debug, logtype_sl, "sl_mod_start_search: SPARQL query: \"%s\"", sparql_query);
 
 #if 0
     /* Start the async query */
index a34e296b7929b8a51cebbe7e07342db3491acaf2..c2603cd06cbf2c9e768dc4f0c02c7ff8a2ca5a53 100644 (file)
@@ -388,7 +388,7 @@ static yyconst flex_int32_t yy_ec[256] =
        13,   14,    1,    1,    9,    9,    9,    9,    9,    9,
         9,    9,   15,    9,    9,    9,    9,    9,    9,    9,
         9,   16,    9,    9,    9,    9,    9,    9,    9,    9,
-        1,    1,    1,    1,    1,    1,   17,    9,    9,    9,
+        1,    1,    1,    1,    9,    1,   17,    9,    9,    9,
 
        18,   19,   20,    9,   21,    9,    9,   22,   23,   24,
        25,    9,    9,   26,   27,   28,   29,    9,    9,    9,
index 81e02bcbb51e7a9dfcf7e8a8e7884e52c8e5d1d5..4ddac640efb2775db3fab3bab88acf2b5c00f642 100644 (file)
@@ -12,7 +12,7 @@ InRange                               return FUNC_INRANGE;
 \$time\.iso                           return DATE_ISO;
 false                                 {yylval.bval = false; return BOOL;}
 true                                  {yylval.bval = true; return BOOL;}
-[a-zA-Z0-9\*\:\-\.]+                  {yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;}
+[a-zA-Z0-9_\*\:\-\.]+                 {yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;}
 \"                                    return QUOTE;
 \(                                    return OBRACE;
 \)                                    return CBRACE;
index 7a70abc96fb287b11d86f67814f1fafe3992b707..3ea474422ba18dc396e52ce39e47e4c30f7af7ca 100644 (file)
@@ -1468,7 +1468,7 @@ yyreduce:
     {
     ssp_result = talloc_asprintf(ssp_slq,
                                  "SELECT DISTINCT ?url WHERE "
-                                 "{ ?obj nie:url ?url FILTER(fn:starts-with(?url, 'file://%s/')) . %s}",
+                                 "{ ?obj nie:url ?url FILTER(regex(?url, '^file://%s/')) . %s}",
                                  ssp_slq->slq_vol->v_path, (yyvsp[(1) - (1)].sval));
     (yyval.sval) = ssp_result;
 }
@@ -1895,6 +1895,32 @@ EC_CLEANUP:
     return result;
 }
 
+static char *map_type_search(const char *attr, char op, const char *val)
+{
+    char *result = NULL;
+    const char *sparqlAttr;
+
+    for (struct MDTypeMap *p = MDTypeMap; p->mdtm_value; p++) {
+        if (strcmp(p->mdtm_value, val) == 0) {
+            switch (p->mdtm_type) {
+            case kMDTypeMapRDF:
+                sparqlAttr = "rdf:type";
+                break;
+            case kMDTypeMapMime:
+                sparqlAttr = "nie:mimeType";
+                break;
+            default:
+                return NULL;
+            }
+            result = talloc_asprintf(ssp_slq, "?obj %s '%s'",
+                                     sparqlAttr,
+                                     p->mdtm_sparql);
+            break;
+        }
+    }
+    return result;
+}
+
 const char *map_expr(const char *attr, char op, const char *val)
 {
     EC_INIT;
@@ -1948,6 +1974,9 @@ const char *map_expr(const char *attr, char op, const char *val)
                                          buf1);
                 sparqlvar++;
                 break;
+            case ssmt_type:
+                result = map_type_search(attr, op, val);
+                break;
             default:
                 yyerror("unknown Spotlight attribute type");
                 EC_FAIL;
index dc12dd3c6b4e3d9b2dce3e7b4a9dc7bd77bffa7a..60dc94b447fef73b106da4e2f192c5870ef19ffa 100644 (file)
@@ -73,7 +73,7 @@ line:
 expr                           {
     ssp_result = talloc_asprintf(ssp_slq,
                                  "SELECT DISTINCT ?url WHERE "
-                                 "{ ?obj nie:url ?url FILTER(fn:starts-with(?url, 'file://%s/')) . %s}",
+                                 "{ ?obj nie:url ?url FILTER(regex(?url, '^file://%s/')) . %s}",
                                  ssp_slq->slq_vol->v_path, $1);
     $$ = ssp_result;
 }
@@ -169,6 +169,32 @@ EC_CLEANUP:
     return result;
 }
 
+static char *map_type_search(const char *attr, char op, const char *val)
+{
+    char *result = NULL;
+    const char *sparqlAttr;
+
+    for (struct MDTypeMap *p = MDTypeMap; p->mdtm_value; p++) {
+        if (strcmp(p->mdtm_value, val) == 0) {
+            switch (p->mdtm_type) {
+            case kMDTypeMapRDF:
+                sparqlAttr = "rdf:type";
+                break;
+            case kMDTypeMapMime:
+                sparqlAttr = "nie:mimeType";
+                break;
+            default:
+                return NULL;
+            }
+            result = talloc_asprintf(ssp_slq, "?obj %s '%s'",
+                                     sparqlAttr,
+                                     p->mdtm_sparql);
+            break;
+        }
+    }
+    return result;
+}
+
 const char *map_expr(const char *attr, char op, const char *val)
 {
     EC_INIT;
@@ -222,6 +248,9 @@ const char *map_expr(const char *attr, char op, const char *val)
                                          buf1);
                 sparqlvar++;
                 break;
+            case ssmt_type:
+                result = map_type_search(attr, op, val);
+                break;
             default:
                 yyerror("unknown Spotlight attribute type");
                 EC_FAIL;