You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
8.8 KiB
318 lines
8.8 KiB
9 years ago
|
/*
|
||
|
* fm-search-uri.c
|
||
|
*
|
||
|
* Copyright 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
|
||
|
* Copyright 2012-2014 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify
|
||
|
* it under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 2 of the License, or
|
||
|
* (at your option) any later version.
|
||
|
*
|
||
|
* This program 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 General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software
|
||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
|
* MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "fm-search.h"
|
||
|
#include <string.h>
|
||
|
|
||
|
struct _FmSearch
|
||
|
{
|
||
|
gboolean recursive;
|
||
|
gboolean show_hidden;
|
||
|
char* name_patterns;
|
||
|
gboolean name_ci;
|
||
|
gboolean name_regex;
|
||
|
char* content_pattern;
|
||
|
gboolean content_ci;
|
||
|
gboolean content_regex;
|
||
|
GList* mime_types;
|
||
|
GList* search_path_list;
|
||
|
guint64 max_size;
|
||
|
guint64 min_size;
|
||
|
char* max_mtime;
|
||
|
char* min_mtime;
|
||
|
};
|
||
|
|
||
|
FmSearch* fm_search_new (void)
|
||
|
{
|
||
|
FmSearch* search = (FmSearch*)g_slice_new0(FmSearch);
|
||
|
return search;
|
||
|
}
|
||
|
|
||
|
void fm_search_free(FmSearch* search)
|
||
|
{
|
||
|
g_list_free_full(search->mime_types, (GDestroyNotify)g_free);
|
||
|
g_list_free_full(search->search_path_list, (GDestroyNotify)g_free);
|
||
|
g_free(search->name_patterns);
|
||
|
g_free(search->content_pattern);
|
||
|
g_free(search->max_mtime);
|
||
|
g_free(search->min_mtime);
|
||
|
g_slice_free(FmSearch, search);
|
||
|
}
|
||
|
|
||
|
gboolean fm_search_get_recursive(FmSearch* search)
|
||
|
{
|
||
|
return search->recursive;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_recursive(FmSearch* search, gboolean recursive)
|
||
|
{
|
||
|
search->recursive = recursive;
|
||
|
}
|
||
|
|
||
|
gboolean fm_search_get_show_hidden(FmSearch* search)
|
||
|
{
|
||
|
return search->show_hidden;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_show_hidden(FmSearch* search, gboolean show_hidden)
|
||
|
{
|
||
|
search->show_hidden = show_hidden;
|
||
|
}
|
||
|
|
||
|
const char* fm_search_get_name_patterns(FmSearch* search)
|
||
|
{
|
||
|
return search->name_patterns;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_name_patterns(FmSearch* search, const char* name_patterns)
|
||
|
{
|
||
|
g_free(search->name_patterns);
|
||
|
search->name_patterns = g_strdup(name_patterns);
|
||
|
}
|
||
|
|
||
|
gboolean fm_search_get_name_ci(FmSearch* search)
|
||
|
{
|
||
|
return search->name_ci;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_name_ci(FmSearch* search, gboolean name_ci)
|
||
|
{
|
||
|
search->name_ci = name_ci;
|
||
|
}
|
||
|
|
||
|
gboolean fm_search_get_name_regex(FmSearch* search)
|
||
|
{
|
||
|
return search->name_regex;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_name_regex(FmSearch* search, gboolean name_regex)
|
||
|
{
|
||
|
search->name_regex = name_regex;
|
||
|
}
|
||
|
|
||
|
const char* fm_search_get_content_pattern(FmSearch* search)
|
||
|
{
|
||
|
return search->content_pattern;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_content_pattern(FmSearch* search, const char* content_pattern)
|
||
|
{
|
||
|
g_free(search->content_pattern);
|
||
|
search->content_pattern = g_strdup(content_pattern);
|
||
|
}
|
||
|
|
||
|
gboolean fm_search_get_content_ci(FmSearch* search)
|
||
|
{
|
||
|
return search->content_ci;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_content_ci(FmSearch* search, gboolean content_ci)
|
||
|
{
|
||
|
search->content_ci = content_ci;
|
||
|
}
|
||
|
|
||
|
gboolean fm_search_get_content_regex(FmSearch* search)
|
||
|
{
|
||
|
return search->content_regex;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_content_regex(FmSearch* search, gboolean content_regex)
|
||
|
{
|
||
|
search->content_regex = content_regex;
|
||
|
}
|
||
|
|
||
|
void fm_search_add_dir(FmSearch* search, const char* dir)
|
||
|
{
|
||
|
GList* l = g_list_find_custom(search->search_path_list, dir, (GCompareFunc)strcmp);
|
||
|
if(!l)
|
||
|
search->search_path_list = g_list_prepend(search->search_path_list, g_strdup(dir));
|
||
|
}
|
||
|
|
||
|
void fm_search_remove_dir(FmSearch* search, const char* dir)
|
||
|
{
|
||
|
GList* l = g_list_find_custom(search->search_path_list, dir, (GCompareFunc)strcmp);
|
||
|
if(G_LIKELY(l))
|
||
|
{
|
||
|
g_free(l->data);
|
||
|
search->search_path_list = g_list_delete_link(search->search_path_list, l);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GList* fm_search_get_dirs(FmSearch* search)
|
||
|
{
|
||
|
return search->search_path_list;
|
||
|
}
|
||
|
|
||
|
void fm_search_add_mime_type(FmSearch* search, const char* mime_type)
|
||
|
{
|
||
|
GList* l = g_list_find_custom(search->mime_types, mime_type, (GCompareFunc)strcmp);
|
||
|
if(!l)
|
||
|
search->mime_types = g_list_prepend(search->mime_types, g_strdup(mime_type));
|
||
|
}
|
||
|
|
||
|
void fm_search_remove_mime_type(FmSearch* search, const char* mime_type)
|
||
|
{
|
||
|
GList* l = g_list_find_custom(search->mime_types, mime_type, (GCompareFunc)strcmp);
|
||
|
if(G_LIKELY(l))
|
||
|
{
|
||
|
g_free(l->data);
|
||
|
search->mime_types = g_list_delete_link(search->mime_types, l);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GList* fm_search_get_mime_types(FmSearch* search)
|
||
|
{
|
||
|
return search->mime_types;
|
||
|
}
|
||
|
|
||
|
guint64 fm_search_get_max_size(FmSearch* search)
|
||
|
{
|
||
|
return search->max_size;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_max_size(FmSearch* search, guint64 size)
|
||
|
{
|
||
|
search->max_size = size;
|
||
|
}
|
||
|
|
||
|
guint64 fm_search_get_min_size(FmSearch* search)
|
||
|
{
|
||
|
return search->min_size;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_min_size(FmSearch* search, guint64 size)
|
||
|
{
|
||
|
search->min_size = size;
|
||
|
}
|
||
|
|
||
|
/* format of mtime: YYYY-MM-DD */
|
||
|
const char* fm_search_get_max_mtime(FmSearch* search)
|
||
|
{
|
||
|
return search->max_mtime;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_max_mtime(FmSearch* search, const char* mtime)
|
||
|
{
|
||
|
g_free(search->max_mtime);
|
||
|
search->max_mtime = g_strdup(mtime);
|
||
|
}
|
||
|
|
||
|
/* format of mtime: YYYY-MM-DD */
|
||
|
const char* fm_search_get_min_mtime(FmSearch* search)
|
||
|
{
|
||
|
return search->min_mtime;
|
||
|
}
|
||
|
|
||
|
void fm_search_set_min_mtime(FmSearch* search, const char* mtime)
|
||
|
{
|
||
|
g_free(search->min_mtime);
|
||
|
search->min_mtime = g_strdup(mtime);
|
||
|
}
|
||
|
|
||
|
/* really build the path */
|
||
|
FmPath* fm_search_dup_path(FmSearch* search)
|
||
|
{
|
||
|
FmPath* search_path = NULL;
|
||
|
GString* search_str = g_string_sized_new(1024);
|
||
|
/* build the search:// URI to perform the search */
|
||
|
g_string_append(search_str, "search://");
|
||
|
|
||
|
if(search->search_path_list) /* we need to have at least one dir path */
|
||
|
{
|
||
|
char *escaped;
|
||
|
/* add paths */
|
||
|
GList* l;
|
||
|
for(l = search->search_path_list; ; )
|
||
|
{
|
||
|
char *path_str = (char*)l->data;
|
||
|
/* escape possible '?' and ',' */
|
||
|
escaped = g_uri_escape_string(path_str, "!$&'()*+:;=/@", TRUE);
|
||
|
g_string_append(search_str, escaped);
|
||
|
g_free(escaped);
|
||
|
|
||
|
l = l->next;
|
||
|
if(!l) /* no more items */
|
||
|
break;
|
||
|
g_string_append_c(search_str, ','); /* separator for paths */
|
||
|
}
|
||
|
|
||
|
g_string_append_c(search_str, '?');
|
||
|
g_string_append_printf(search_str, "recursive=%c", search->recursive ? '1' : '0');
|
||
|
g_string_append_printf(search_str, "&show_hidden=%c", search->show_hidden ? '1' : '0');
|
||
|
if(search->name_patterns && *search->name_patterns)
|
||
|
{
|
||
|
/* escape ampersands in pattern */
|
||
|
escaped = g_uri_escape_string(search->name_patterns, ":/?#[]@!$'()*+,;", TRUE);
|
||
|
if(search->name_regex)
|
||
|
g_string_append_printf(search_str, "&name_regex=%s", escaped);
|
||
|
else
|
||
|
g_string_append_printf(search_str, "&name=%s", escaped);
|
||
|
if(search->name_ci)
|
||
|
g_string_append_printf(search_str, "&name_ci=%c", search->name_ci ? '1' : '0');
|
||
|
g_free(escaped);
|
||
|
}
|
||
|
|
||
|
if(search->content_pattern && *search->content_pattern)
|
||
|
{
|
||
|
/* escape ampersands in pattern */
|
||
|
escaped = g_uri_escape_string(search->content_pattern, ":/?#[]@!$'()*+,;^<>{}", TRUE);
|
||
|
if(search->content_regex)
|
||
|
g_string_append_printf(search_str, "&content_regex=%s", escaped);
|
||
|
else
|
||
|
g_string_append_printf(search_str, "&content=%s", escaped);
|
||
|
g_free(escaped);
|
||
|
if(search->content_ci)
|
||
|
g_string_append_printf(search_str, "&content_ci=%c", search->content_ci ? '1' : '0');
|
||
|
}
|
||
|
|
||
|
/* search for the files of specific mime-types */
|
||
|
if(search->mime_types)
|
||
|
{
|
||
|
GList* l;
|
||
|
g_string_append(search_str, "&mime_types=");
|
||
|
for(l = search->mime_types; l; l=l->next)
|
||
|
{
|
||
|
const char* mime_type = (const char*)l->data;
|
||
|
g_string_append(search_str, mime_type);
|
||
|
if(l->next)
|
||
|
g_string_append_c(search_str, ';');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if(search->min_size)
|
||
|
g_string_append_printf(search_str, "&min_size=%llu", search->min_size);
|
||
|
|
||
|
if(search->max_size)
|
||
|
g_string_append_printf(search_str, "&max_size=%llu", search->max_size);
|
||
|
|
||
|
if(search->min_mtime)
|
||
|
g_string_append_printf(search_str, "&min_mtime=%s", search->min_mtime);
|
||
|
|
||
|
if(search->max_mtime)
|
||
|
g_string_append_printf(search_str, "&max_mtime=%s", search->max_mtime);
|
||
|
|
||
|
search_path = fm_path_new_for_uri(search_str->str);
|
||
|
g_string_free(search_str, TRUE);
|
||
|
}
|
||
|
return search_path;
|
||
|
}
|