Beispiel #1
0
/**
 * vu_check_latest_version:
 * @window: Somewhere where we may need use the display to inform the user about the version status
 *
 * Periodically checks the released latest VERSION file on the website to compare with the running version
 *
 */
void vu_check_latest_version ( GtkWindow *window )
{
	if ( ! a_vik_get_check_version () )
		return;

	gboolean do_check = FALSE;

	gint check_period;
	if ( ! a_settings_get_integer ( VIK_SETTINGS_VERSION_CHECK_PERIOD, &check_period ) ) {
		check_period = 14;
	}

	// Get last checked date...
	GDate *gdate_last = g_date_new();
	GDate *gdate_now = g_date_new();
	GTimeVal time_last;
	gchar *last_checked_date = NULL;

	// When no previous date available - set to do the version check
	if ( a_settings_get_string ( VIK_SETTINGS_VERSION_CHECKED_DATE, &last_checked_date) ) {
		if ( g_time_val_from_iso8601 ( last_checked_date, &time_last ) ) {
			g_date_set_time_val ( gdate_last, &time_last );
		}
		else
			do_check = TRUE;
	}
	else
		do_check = TRUE;

	GTimeVal time_now;
	g_get_current_time ( &time_now );
	g_date_set_time_val ( gdate_now, &time_now );

	if ( ! do_check ) {
		// Dates available so do the comparison
		g_date_add_days ( gdate_last, check_period );
		if ( g_date_compare ( gdate_last, gdate_now ) < 0 )
			do_check = TRUE;
	}

	g_date_free ( gdate_last );
	g_date_free ( gdate_now );

	if ( do_check ) {
#if GLIB_CHECK_VERSION (2, 32, 0)
		g_thread_try_new ( "latest_version_thread", (GThreadFunc)latest_version_thread, window, NULL );
#else
		g_thread_create ( (GThreadFunc)latest_version_thread, window, FALSE, NULL );
#endif
	}
}
static void
set_metadata (GstElement * camera)
{
  GstTagSetter *setter = GST_TAG_SETTER (camera);
  GTimeVal time = { 0, 0 };
  gchar *desc_str;
  GDate *date = g_date_new ();

  g_get_current_time (&time);
  g_date_set_time_val (date, &time);

  desc_str = g_strdup_printf ("captured by %s", g_get_real_name ());

  gst_tag_setter_add_tags (setter, GST_TAG_MERGE_REPLACE,
      GST_TAG_DATE, date,
      GST_TAG_DESCRIPTION, desc_str,
      GST_TAG_TITLE, "gst-camerabin-test capture",
      GST_TAG_GEO_LOCATION_LONGITUDE, 1.0,
      GST_TAG_GEO_LOCATION_LATITUDE, 2.0,
      GST_TAG_GEO_LOCATION_ELEVATION, 3.0,
      GST_TAG_DEVICE_MANUFACTURER, "gst-camerabin-test manufacturer",
      GST_TAG_DEVICE_MODEL, "gst-camerabin-test model", NULL);

  g_free (desc_str);
  g_date_free (date);
}
Beispiel #3
0
void
hippo_platform_impl_windows_migrate_cookie(const char *from_web_host,
                                           const char *to_web_host)
{
    char *username;
    char *password;

    // See if we already have a cookie from the new host
    if (read_ie_login_cookie(to_web_host, &username, &password)) {
        g_free(username);
        g_free(password);

        return;
    }

    if (!read_ie_login_cookie(from_web_host, &username, &password))
        return;

    GDate *date = g_date_new();
    GTimeVal timeval;
    g_get_current_time(&timeval);
    g_date_set_time_val(date, &timeval);
    g_date_add_days(date, 5 * 365); // 5 years, more or less

    // Can't use g_date_strftime, since that would be unpredictably located
    // while we need fixed english-locale DAY, DD-MMM-YYYY HH:MM:SS GMT

    static const char *days[] = {
        "Mon", "Tue", "Wed", "The", "Fri", "Sat", "Sun"
    };

    static const char * const months[] = {
        "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    };

    char *cookieUTF8 = g_strdup_printf("auth=host=%s&name=%s&password=%s; Path=/; expires = %s, %02d-%s-%04d 00:00:00 GMT", 
                                       to_web_host, 
                                       username, 
                                       password, 
                                       days[(int)g_date_get_weekday(date) - 1],
                                       g_date_get_day(date),
                                       months[(int)g_date_get_month(date) - 1],
                                       g_date_get_year(date));
    g_date_free(date);

    HippoBSTR cookie;
    cookie.setUTF8(cookieUTF8, -1);
    g_free(cookieUTF8);
    
    HippoBSTR authUrl;
    makeAuthUrl(to_web_host, &authUrl);
    InternetSetCookie(authUrl, NULL, cookie);

    g_free(username);
    g_free(password);
}
GDate* node_to_date (xmlNode *node)
{
    GTimeVal timeval;
    GDate *ret;
    xmlChar *tmp;

    ret = g_date_new ();
    tmp = xmlNodeGetContent (node);

    if (g_time_val_from_iso8601 ((char*) tmp, &timeval))
        g_date_set_time_val (ret, &timeval);

    xmlFree (tmp);
    return ret;
}
/**
 * gpk_log_get_localised_date:
 **/
static gchar *
gpk_log_get_localised_date (const gchar *timespec)
{
	GDate *date;
	GTimeVal timeval;
	gchar buffer[100];

	/* the old date */
	g_time_val_from_iso8601 (timespec, &timeval);

	/* get printed string */
	date = g_date_new ();
	g_date_set_time_val (date, &timeval);

	/* TRANSLATORS: strftime formatted please */
	g_date_strftime (buffer, 100, _("%A, %d %B %Y"), date);
	g_date_free (date);
	return g_strdup (buffer);
}
Beispiel #6
0
/**
 * pk_iso8601_to_date: (skip)
 * @iso_date: The ISO8601 date to convert
 *
 * Return value: If valid then a new %GDate, else NULL
 *
 * Since: 0.5.2
 **/
GDate *
pk_iso8601_to_date (const gchar *iso_date)
{
	gboolean ret = FALSE;
	guint retval;
	guint d = 0;
	guint m = 0;
	guint y = 0;
	GTimeVal time_val;
	GDate *date = NULL;

	if (iso_date == NULL || iso_date[0] == '\0')
		goto out;

	/* try to parse complete ISO8601 date */
	if (g_strstr_len (iso_date, -1, " ") != NULL)
		ret = g_time_val_from_iso8601 (iso_date, &time_val);
	if (ret && time_val.tv_sec != 0) {
		g_debug ("Parsed %s %i", iso_date, ret);
		date = g_date_new ();
		g_date_set_time_val (date, &time_val);
		goto out;
	}

	/* g_time_val_from_iso8601() blows goats and won't
	 * accept a valid ISO8601 formatted date without a
	 * time value - try and parse this case */
	retval = sscanf (iso_date, "%u-%u-%u", &y, &m, &d);
	if (retval != 3)
		goto out;

	/* check it's valid */
	ret = g_date_valid_dmy (d, m, y);
	if (!ret)
		goto out;

	/* create valid object */
	date = g_date_new_dmy (d, m, y);
out:
	return date;
}
Beispiel #7
0
static GtkWidget*
create_window1 (void)
{
	GtkWidget *window, *button1; 
	GtkImage *imageClient, *imageWellth, *imageBG;	
	GError** error = NULL;
	GTimeVal  time;
	GDate    *date_heap;
	
	GDate     date_stack;
	gchar     tmp_buffer[256];

	g_get_current_time( &time );
	date_heap = g_date_new();

	GDate* mod_date = g_date_new ();
	
	g_date_set_time_val( date_heap, &time );
	g_date_strftime( tmp_buffer, 256, "%x", date_heap );
	g_print( "Current date (heap):  %s\n", tmp_buffer );

	//g_date_set_year (mod_date, atoi (parts[2]));
	
	g_date_free( date_heap );
	
	/* Load UI from file */
	MainBuilder = gtk_builder_new ();
	if (!gtk_builder_add_from_file (MainBuilder, UI_FILE, error))
	{
		g_critical ("Couldn't load builder file: %s", (*error)->message);
		g_error_free (*error);
	}

	/* Auto-connect signal handlers */
	gtk_builder_connect_signals (MainBuilder, NULL);

	/* Get the window object from the ui file */
	window = GTK_WIDGET (gtk_builder_get_object (MainBuilder, TOP_WINDOW));
        if (!window)
        {
                g_critical ("Widget \"%s\" is missing in file %s.",
				TOP_WINDOW,
				UI_FILE);
        }

	//GdkPixbufAnimation * pixbufclntanm = gdk_pixbuf_animation_new_from_file(CLIENT_LOGO, error);
	GdkPixbufAnimation * pixbufwlthanm = gdk_pixbuf_animation_new_from_file(WELLTH_LOGO, error);
	//imageClient = (GtkImage *) GTK_WIDGET (gtk_builder_get_object (MainBuilder, "clnt_logo"));
	imageWellth = (GtkImage *) GTK_WIDGET (gtk_builder_get_object (MainBuilder, "wellth_logo"));
	//gtk_image_set_from_animation(GTK_IMAGE(imageClient), pixbufclntanm);
	gtk_image_set_from_animation (GTK_IMAGE(imageWellth), pixbufwlthanm);

	//GdkPixbufAnimation * pixbufBGanm = gdk_pixbuf_animation_new_from_file(BG1, error);
	imageBG = (GtkImage *) GTK_WIDGET (gtk_builder_get_object (MainBuilder, "image1"));
	gtk_image_set_from_animation(GTK_IMAGE(imageBG), pixbufBGanm);
#ifdef DISPLAY_ADD
	GdkPixbufAnimation * pixbufaddanm = gdk_pixbuf_animation_new_from_file(ADDS2, error);
	GtkImage *add = (GtkImage *) GTK_WIDGET (gtk_builder_get_object (MainBuilder, "adds"));
	gtk_image_set_from_animation(GTK_IMAGE(add), pixbufaddanm);
#endif
	button1 = GTK_WIDGET (gtk_builder_get_object (MainBuilder, "main_start_btn"));
 	 g_signal_connect (G_OBJECT (button1), "clicked", G_CALLBACK (start_button_clicked), NULL);

		
	
	priv = g_malloc (sizeof (struct _Private));
	/* ANJUTA: Widgets initialization for WindowMain.ui - DO NOT REMOVE */

	//g_object_unref (MainBuilder);
	
	return window;
}
Beispiel #8
0
static RhythmDBEntry *
add_mtp_track_to_db (RBMtpSource *source,
		     RhythmDB *db,
		     LIBMTP_track_t *track)
{
	RhythmDBEntry *entry = NULL;
	RhythmDBEntryType *entry_type;
	RBMtpSourcePrivate *priv = MTP_SOURCE_GET_PRIVATE (source);
	char *name = NULL;

	/* ignore everything except audio (allow audio/video types too, since they're probably pretty common) */
	if (!(LIBMTP_FILETYPE_IS_AUDIO (track->filetype) || LIBMTP_FILETYPE_IS_AUDIOVIDEO (track->filetype))) {
		rb_debug ("ignoring non-audio item %d (filetype %s)",
			  track->item_id,
			  LIBMTP_Get_Filetype_Description (track->filetype));
		return NULL;
	}

	/* Set URI */
	g_object_get (G_OBJECT (source), "entry-type", &entry_type, NULL);
	name = g_strdup_printf ("xrbmtp://%i/%s", track->item_id, track->filename);
	entry = rhythmdb_entry_new (RHYTHMDB (db), entry_type, name);
	g_free (name);
        g_object_unref (entry_type);

	if (entry == NULL) {
		rb_debug ("cannot create entry %i", track->item_id);
		g_object_unref (G_OBJECT (db));
		return NULL;
	}

	/* Set track number */
	if (track->tracknumber != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->tracknumber);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_TRACK_NUMBER,
				    &value);
		g_value_unset (&value);
	}

	/* Set length */
	if (track->duration != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->duration/1000);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_DURATION,
				    &value);
		g_value_unset (&value);
	}

	/* Set file size */
	if (track->filesize != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_UINT64);
		g_value_set_uint64 (&value, track->filesize);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
				    RHYTHMDB_PROP_FILE_SIZE,
				    &value);
		g_value_unset (&value);
	}

	/* Set playcount */
	if (track->usecount != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_ULONG);
		g_value_set_ulong (&value, track->usecount);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
					       RHYTHMDB_PROP_PLAY_COUNT,
					       &value);
		g_value_unset (&value);
	}
	/* Set rating */
	if (track->rating != 0) {
		GValue value = {0, };
		g_value_init (&value, G_TYPE_DOUBLE);
		g_value_set_double (&value, track->rating/20);
		rhythmdb_entry_set (RHYTHMDB (db), entry,
					       RHYTHMDB_PROP_RATING,
					       &value);
		g_value_unset (&value);
	}
	/* Set release date */
	if (track->date != NULL && track->date[0] != '\0') {
		GTimeVal tv;
		if (g_time_val_from_iso8601 (track->date, &tv)) {
			GDate d;
			GValue value = {0, };
			g_value_init (&value, G_TYPE_ULONG);
			g_date_set_time_val (&d, &tv);
			g_value_set_ulong (&value, g_date_get_julian (&d));
			rhythmdb_entry_set (RHYTHMDB (db), entry, RHYTHMDB_PROP_DATE, &value);
			g_value_unset (&value);
		}
	}

	/* Set title */
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_TITLE, track->title);

	/* Set album, artist and genre from MTP */
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ARTIST, track->artist);
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_ALBUM, track->album);
	entry_set_string_prop (RHYTHMDB (db), entry, RHYTHMDB_PROP_GENRE, track->genre);

	g_hash_table_insert (priv->entry_map, entry, track);
	rhythmdb_commit (RHYTHMDB (db));

	return entry;
}
Beispiel #9
0
/*
 * gda_ldap_attr_value_to_g_value:
 * Converts a #BerValue to a new #GValue
 *
 * Returns: a new #GValue, or %NULL on error
 */
GValue *
gda_ldap_attr_value_to_g_value (LdapConnectionData *cdata, GType type, BerValue *bv)
{
	GValue *value = NULL;
	if ((type == G_TYPE_DATE_TIME) ||
	    (type == G_TYPE_DATE)) {
		/* see ftp://ftp.rfc-editor.org/in-notes/rfc4517.txt,
		 * section 3.3.13: Generalized Time
		 */
		GTimeVal tv;
		gboolean conv;
		if (! (conv = g_time_val_from_iso8601 (bv->bv_val,
						       &tv))) {
			/* Add the 'T' char */
			gchar *tmp, *str;
			gint i, len;
			str = bv->bv_val;
			len = strlen (str);
			if (len > 8) {
				tmp = g_new (gchar, len + 2);
				for (i = 0; i < 8; i++)
					tmp[i] = str[i];
				tmp [8] = 'T';
				for (i = 9; str[i]; i++)
					tmp[i] = str[i-1];
				tmp[i] = 0;
				conv = g_time_val_from_iso8601 (tmp, &tv);
				g_free (tmp);
			}
		}
		if (conv) {
			struct tm *ptm;
#ifdef HAVE_LOCALTIME_R
			struct tm tmpstm;
			ptm = localtime_r (&(tv.tv_sec), &tmpstm);
#elif HAVE_LOCALTIME_S
			struct tm tmpstm;
			if (localtime_s (&tmpstm, &(tv.tv_sec)) == 0)
				ptm = &tmpstm;
			else
				ptm = NULL;
#else
			ptm = localtime (&(tv.tv_sec));
#endif

			if (!ptm)
				return NULL;

			if (g_type_is_a (type, G_TYPE_DATE_TIME)) {
				GTimeZone *tz = g_time_zone_new ("Z"); // UTC
				GDateTime *ts = g_date_time_new (tz,
																				 ptm->tm_year + 1900,
																				 ptm->tm_mon + 1,
																				 ptm->tm_mday,
																				 ptm->tm_hour,
																				 ptm->tm_min,
																				 ptm->tm_sec);
				value = gda_value_new (G_TYPE_DATE_TIME);
				g_value_set_boxed (value, ts);
				g_date_time_unref (ts);
			}
			else {
				GDate *date;
				date = g_date_new ();
				g_date_set_time_val (date, &tv);
				value = gda_value_new (type);
				g_value_take_boxed (value, date);
			}
		}
	}
	else if (type == GDA_TYPE_BINARY) {
		guchar *data;
		data = g_new (guchar, bv->bv_len);
		memcpy (data, bv->bv_val, sizeof (guchar) * bv->bv_len);
		value = gda_value_new_binary (data, bv->bv_len);
	}
	else
		value = gda_value_new_from_string (bv->bv_val, type);

	return value;
}
Beispiel #10
0
static void
end_element(
	GMarkupParseContext *ctx, 
	const gchar *name, 
	gpointer ud,
	GError **error)
{
	parse_data_t *pd = (parse_data_t*)ud;
	gint id;
	union 
	{
		gint id;
		gpointer pid;
	} start_id;
	gint ii;

	// Check to see if the first element found has been closed
	// If so, ignore any junk following it.
	if (pd->closed_top)
		return;

	for (ii = 0; ii < TAG_MAP_SZ; ii++)
	{
		if (strcmp(name, tag_map[ii].tag) == 0)
		{
			id = tag_map[ii].id;
			break;
		}
	}
	if (ii == TAG_MAP_SZ)
	{
		g_warning("Unrecognized start tag (%s)", name);
		return;
	}
	start_id.pid = g_queue_pop_head(pd->tag_stack);
	if (start_id.id != id)
		g_warning("start tag != end tag: (%s %d) %d", name, id, id);

	GValue *gval = NULL;
	GValue *current = g_queue_peek_head(pd->stack);
	GType gtype = 0;
	switch (id)
	{
		case P_PLIST:
		{ // Ignore
		} break;
		case P_KEY:
		{
			if (pd->key) g_free(pd->key);
			pd->key = g_strdup(pd->value);
			return;
		} break;
		case P_DICT:
		{
			g_queue_pop_head(pd->stack);
		} break;
		case P_ARRAY:
		{
			g_queue_pop_head(pd->stack);
		} break;
		case P_INTEGER:
		{
			gint64 val = g_strtod(pd->value, NULL);
			gval = ghb_int64_value_new(val);
		} break;
		case P_REAL:
		{
			gdouble val = g_strtod(pd->value, NULL);
			gval = ghb_double_value_new(val);
		} break;
		case P_STRING:
		{
			gval = ghb_string_value_new(pd->value);
		} break;
		case P_DATE:
		{
			GDate date;
			GTimeVal time;
			g_time_val_from_iso8601(pd->value, &time);
			g_date_set_time_val(&date, &time);
			gval = ghb_date_value_new(&date);
		} break;
		case P_TRUE:
		{
			gval = ghb_boolean_value_new(TRUE);
		} break;
		case P_FALSE:
		{
			gval = ghb_boolean_value_new(FALSE);
		} break;
		case P_DATA:
		{
			ghb_rawdata_t *data;
			data = g_malloc(sizeof(ghb_rawdata_t));
			data->data = g_base64_decode(pd->value, &(data->size));
			gval = ghb_rawdata_value_new(data);
		} break;
	}
	if (gval)
	{
		// Get the top of the data structure stack and if it's an array
		// or dict, add the current element
		if (current == NULL)
		{
			pd->plist = gval;
			pd->closed_top = TRUE;
			return;
		}
		gtype = G_VALUE_TYPE(current);
		if (gtype == ghb_array_get_type())
		{
			ghb_array_append(current, gval);
		}
		else if (gtype == ghb_dict_get_type())
		{
			if (pd->key == NULL)
			{
				g_warning("No key for dictionary item");
				ghb_value_free(gval);
			}
			else
			{
				ghb_dict_insert(current, g_strdup(pd->key), gval);
			}
		}
		else
		{
			g_error("Invalid container type. This shouldn't happen");
		}
	}
	if (g_queue_is_empty(pd->stack))
		pd->closed_top = TRUE;
}
static char *
format_last_used (guint64 timestamp)
{
	GTimeVal now_tv;
	GDate *now, *last;
	char *last_used = NULL;

	if (!timestamp)
		return g_strdup (_("never"));

	g_get_current_time (&now_tv);
	now = g_date_new ();
	g_date_set_time_val (now, &now_tv);

	last = g_date_new ();
	g_date_set_time_t (last, (time_t) timestamp);

	/* timestamp is now or in the future */
	if (now_tv.tv_sec <= timestamp) {
		last_used = g_strdup (_("now"));
		goto out;
	}

	if (g_date_compare (now, last) <= 0) {
		guint minutes, hours;

		/* Same day */

		minutes = (now_tv.tv_sec - timestamp) / 60;
		if (minutes == 0) {
			last_used = g_strdup (_("now"));
			goto out;
		}

		hours = (now_tv.tv_sec - timestamp) / 3600;
		if (hours == 0) {
			/* less than an hour ago */
			last_used = g_strdup_printf (ngettext ("%d minute ago", "%d minutes ago", minutes), minutes);
			goto out;
		}

		last_used = g_strdup_printf (ngettext ("%d hour ago", "%d hours ago", hours), hours);
	} else {
		guint days, months, years;

		days = g_date_get_julian (now) - g_date_get_julian (last);
		if (days == 0) {
			last_used = g_strdup ("today");
			goto out;
		}

		months = days / 30;
		if (months == 0) {
			last_used = g_strdup_printf (ngettext ("%d day ago", "%d days ago", days), days);
			goto out;
		}

		years = days / 365;
		if (years == 0) {
			last_used = g_strdup_printf (ngettext ("%d month ago", "%d months ago", months), months);
			goto out;
		}

		last_used = g_strdup_printf (ngettext ("%d year ago", "%d years ago", years), years);
	}

out:
	g_date_free (now);
	g_date_free (last);
	return last_used;
}
/*
 * Parse a filename pattern and replace markers with values from a TrackDetails
 * structure.
 *
 * Valid markers so far are:
 * %at -- album title
 * %aa -- album artist
 * %aA -- album artist (lowercase)
 * %as -- album artist sortname
 * %aS -- album artist sortname (lowercase)
 * %ay -- album year
 * %ag -- album genre
 * %aG -- album genre (lowercase)
 * %an -- album disc number
 * %aN -- album disc number, zero padded
 * %tn -- track number (i.e 8)
 * %tN -- track number, zero padded (i.e 08)
 * %tt -- track title
 * %ta -- track artist
 * %tA -- track artist (lowercase)
 * %ts -- track artist sortname
 * %tS -- track artist sortname (lowercase)
 * %td -- track duration
 * %te -- track elapsed time
 * %tb -- track bitrate
 * %st -- stream title
 */
static char *
parse_pattern (const char *pattern, GHashTable *properties, gint64 elapsed)
{
	/* p is the pattern iterator, i is a general purpose iterator */
	const char *p;
	char *temp;
	GString *s;

	if (pattern == NULL || pattern[0] == 0)
		return g_strdup (" ");

	s = g_string_new (NULL);

	p = pattern;
	while (*p) {
		char *string = NULL;
		const char **strv = NULL;
		GVariant *value = NULL;

		/* If not a % marker, copy and continue */
		if (*p != '%') {
			g_string_append_c (s, *p++);
			/* Explicit increment as we continue past the increment */
			continue;
		}

		/* Is a % marker, go to next and see what to do */
		switch (*++p) {
		case '%':
			/*
			 * Literal %
			 */
			g_string_append_c (s, '%');
			break;
		case 'a':
			/*
			 * Album tag
			 */
			switch (*++p) {
			case 't':
				value = g_hash_table_lookup (properties, "xesam:album");
				if (value)
					string = g_variant_dup_string (value, NULL);
				break;
			case 'T':
				value = g_hash_table_lookup (properties, "xesam:album");
				if (value)
					string = g_utf8_strdown (g_variant_get_string (value, NULL), -1);
				break;
			case 'a':
				value = g_hash_table_lookup (properties, "xesam:artist");
				if (value) {
					strv = g_variant_get_strv (value, NULL);
					string = g_strdup (strv[0]);
				}
				break;
			case 'A':
				value = g_hash_table_lookup (properties, "xesam:artist");
				if (value) {
					strv = g_variant_get_strv (value, NULL);
					string = g_utf8_strdown (strv[0], -1);
				}
				break;
			case 's':
				value = g_hash_table_lookup (properties, "rhythmbox:albumArtistSortname");
				if (value)
					string = g_variant_dup_string (value, NULL);
				break;
			case 'S':
				value = g_hash_table_lookup (properties, "rhythmbox:albumArtistSortname");
				if (value)
					string = g_utf8_strdown (g_variant_get_string (value, NULL), -1);
				break;
			case 'y':
				/* Release year */
				value = g_hash_table_lookup (properties, "xesam:contentCreated");
				if (value) {
					const char *iso8601;
					GTimeVal tv;

					iso8601 = g_variant_get_string (value, NULL);
					if (g_time_val_from_iso8601 (iso8601, &tv)) {
						GDate d;
						g_date_set_time_val (&d, &tv);

						string = g_strdup_printf ("%u", g_date_get_year (&d));
					}
				}
				break;
				/* Disc number */
			case 'n':
				value = g_hash_table_lookup (properties, "xesam:discNumber");
				if (value)
					string = g_strdup_printf ("%u", g_variant_get_int32 (value));
				break;
			case 'N':
				value = g_hash_table_lookup (properties, "xesam:discNumber");
				if (value)
					string = g_strdup_printf ("%02u", g_variant_get_int32 (value));
				break;
				/* genre */
			case 'g':
				value = g_hash_table_lookup (properties, "xesam:genre");
				if (value) {
					strv = g_variant_get_strv (value, NULL);
					string = g_strdup (strv[0]);
				}
				break;
			case 'G':
				value = g_hash_table_lookup (properties, "xesam:genre");
				if (value) {
					strv = g_variant_get_strv (value, NULL);
					string = g_utf8_strdown (strv[0], -1);
				}
				break;
			default:
				string = g_strdup_printf ("%%a%c", *p);
			}

			break;

		case 't':
			/*
			 * Track tag
			 */
			switch (*++p) {
			case 't':
				value = g_hash_table_lookup (properties, "rhythmbox:streamTitle");
				if (value == NULL)
					value = g_hash_table_lookup (properties, "xesam:title");
				if (value)
					string = g_variant_dup_string (value, NULL);
				break;
			case 'T':
				value = g_hash_table_lookup (properties, "rhythmbox:streamTitle");
				if (value == NULL)
					value = g_hash_table_lookup (properties, "xesam:title");
				if (value)
					string = g_utf8_strdown (g_variant_get_string (value, NULL), -1);
				break;
			case 'a':
				value = g_hash_table_lookup (properties, "xesam:artist");
				if (value) {
					strv = g_variant_get_strv (value, NULL);
					string = g_strdup (strv[0]);
				}
				break;
			case 'A':
				value = g_hash_table_lookup (properties, "xesam:artist");
				if (value) {
					strv = g_variant_get_strv (value, NULL);
					string = g_utf8_strdown (strv[0], -1);
				}
				break;
			case 's':
				value = g_hash_table_lookup (properties, "rhythmbox:artistSortname");
				if (value)
					string = g_variant_dup_string (value, NULL);
				break;
			case 'S':
				value = g_hash_table_lookup (properties, "rhythmbox:artistSortname");
				if (value)
					string = g_utf8_strdown (g_variant_get_string (value, NULL), -1);
				break;
			case 'n':
				/* Track number */
				value = g_hash_table_lookup (properties, "xesam:trackNumber");
				if (value)
					string = g_strdup_printf ("%u", g_variant_get_int32 (value));
				break;
			case 'N':
				/* Track number, zero-padded */
				value = g_hash_table_lookup (properties, "xesam:trackNumber");
				if (value)
					string = g_strdup_printf ("%02u", g_variant_get_int32 (value));
				break;
			case 'd':
				/* Track duration */
				value = g_hash_table_lookup (properties, "mpris:length");
				if (value)
					string = rb_make_duration_string (g_variant_get_int64 (value));
				break;
			case 'e':
				/* Track elapsed time */
				string = rb_make_duration_string (elapsed);
				break;
			case 'b':
				/* Track bitrate */
				value = g_hash_table_lookup (properties, "xesam:audioBitrate");
				if (value)
					string = g_strdup_printf ("%u", g_variant_get_int32 (value) / 1024);
				break;

			default:
				string = g_strdup_printf ("%%t%c", *p);
 			}

			break;

		case 's':
			/*
			 * Stream tag
			 */
			switch (*++p) {
			case 't':
				value = g_hash_table_lookup (properties, "rhythmbox:streamTitle");
				if (value) {
					value = g_hash_table_lookup (properties, "xesam:title");
					if (value) {
						string = g_variant_dup_string (value, NULL);
					}
				}
				break;
			default:
				string = g_strdup_printf ("%%s%c", *p);
 			}
			break;

		default:
			string = g_strdup_printf ("%%%c", *p);
		}

		if (string)
			g_string_append (s, string);
		g_free (string);

		++p;
	}

	temp = s->str;
	g_string_free (s, FALSE);
	return temp;
}
gboolean
e_reap_trash_directory_sync (GFile *trash_directory,
                             gint expiry_in_days,
                             GCancellable *cancellable,
                             GError **error)
{
	GFileEnumerator *file_enumerator;
	GQueue directories = G_QUEUE_INIT;
	GFile *reaping_directory;
	GFileInfo *file_info;
	const gchar *attributes;
	gboolean success = TRUE;
	GError *local_error = NULL;

	g_return_val_if_fail (G_IS_FILE (trash_directory), FALSE);
	g_return_val_if_fail (expiry_in_days > 0, FALSE);

	reaping_directory = g_file_get_child (
		trash_directory, REAPING_DIRECTORY_NAME);

	attributes =
		G_FILE_ATTRIBUTE_STANDARD_NAME ","
		G_FILE_ATTRIBUTE_STANDARD_TYPE ","
		G_FILE_ATTRIBUTE_TIME_MODIFIED;

	file_enumerator = g_file_enumerate_children (
		trash_directory, attributes,
		G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
		cancellable, error);

	if (file_enumerator == NULL)
		return FALSE;

	file_info = g_file_enumerator_next_file (
		file_enumerator, cancellable, &local_error);

	while (file_info != NULL) {
		GFileType file_type;
		GTimeVal mtime;
		GDate *date_now;
		GDate *date_mtime;
		const gchar *name;
		gboolean reap_it;
		gint days_old;

		name = g_file_info_get_name (file_info);
		file_type = g_file_info_get_file_type (file_info);
		g_file_info_get_modification_time (file_info, &mtime);

		/* Calculate how many days ago the file was modified. */
		date_now = g_date_new ();
		g_date_set_time_t (date_now, time (NULL));
		date_mtime = g_date_new ();
		g_date_set_time_val (date_mtime, &mtime);
		days_old = g_date_days_between (date_mtime, date_now);
		g_date_free (date_mtime);
		g_date_free (date_now);

		reap_it =
			(file_type == G_FILE_TYPE_DIRECTORY) &&
			(days_old >= expiry_in_days);

		if (reap_it) {
			GFile *child;

			child = g_file_get_child (trash_directory, name);

			/* If we find an unfinished reaping directory, put
			 * it on the head of the queue so we reap it first. */
			if (g_file_equal (child, reaping_directory))
				g_queue_push_head (&directories, child);
			else
				g_queue_push_tail (&directories, child);
		}

		g_object_unref (file_info);

		file_info = g_file_enumerator_next_file (
			file_enumerator, cancellable, &local_error);
	}

	if (local_error != NULL) {
		g_propagate_error (error, local_error);
		success = FALSE;
	}

	g_object_unref (file_enumerator);

	/* Now delete the directories we've queued up. */
	while (success && !g_queue_is_empty (&directories)) {
		GFile *directory;

		directory = g_queue_pop_head (&directories);

		/* First we rename the directory to prevent it
		 * from being recovered while being deleted. */
		if (!g_file_equal (directory, reaping_directory))
			success = g_file_move (
				directory, reaping_directory,
				G_FILE_COPY_NONE, cancellable,
				NULL, NULL, error);

		if (success)
			success = e_file_recursive_delete_sync (
				reaping_directory, cancellable, error);

		g_object_unref (directory);
	}

	/* Flush the queue in case we aborted on an error. */
	while (!g_queue_is_empty (&directories))
		g_object_unref (g_queue_pop_head (&directories));

	g_object_unref (reaping_directory);

	return success;
}