diff options
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/base64.c | 75 | ||||
-rw-r--r-- | src/requests.c | 1 | ||||
-rw-r--r-- | src/torrent.c | 5 | ||||
-rw-r--r-- | src/torrent.h | 1 | ||||
-rw-r--r-- | src/trg-cell-renderer-epoch.c | 115 | ||||
-rw-r--r-- | src/trg-cell-renderer-epoch.h | 51 | ||||
-rw-r--r-- | src/trg-torrent-model.c | 4 | ||||
-rw-r--r-- | src/trg-torrent-model.h | 1 | ||||
-rw-r--r-- | src/trg-torrent-tree-view.c | 2 | ||||
-rw-r--r-- | src/trg-tree-view.c | 16 | ||||
-rw-r--r-- | src/trg-tree-view.h | 2 |
12 files changed, 236 insertions, 38 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 466147e..46ddbf2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -66,6 +66,7 @@ transmission_remote_gtk_SOURCES = main.c \ trg-remote-prefs-dialog.c \ trg-cell-renderer-wanted.c \ trg-cell-renderer-priority.c \ + trg-cell-renderer-epoch.c \ trg-torrent-move-dialog.c \ trg-stats-dialog.c \ trg-torrent-graph.c \ diff --git a/src/base64.c b/src/base64.c index 8e0562b..40aa190 100644 --- a/src/base64.c +++ b/src/base64.c @@ -17,50 +17,49 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <stdlib.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> #include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> + +#include <glib.h> #include "base64.h" -static const char cb64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -void encodeblock(unsigned char in[3], unsigned char out[4], int len) -{ - out[0] = cb64[in[0] >> 2]; - out[1] = cb64[((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4)]; - out[2] = - (unsigned char) (len > - 1 ? cb64[((in[1] & 0x0f) << 2) | - ((in[2] & 0xc0) >> 6)] : '='); - out[3] = (unsigned char) (len > 2 ? cb64[in[2] & 0x3f] : '='); -} +#define my_print_errno(x) printf("%s: error (%d) %s\n", __func__, errno, x); char *base64encode(char *filename) { - FILE *infile = fopen(filename, "rb"); - unsigned char in[3], out[4]; - int i, len, j = 0; - char *output = NULL; - while (!feof(infile)) { - len = 0; - for (i = 0; i < 3; i++) { - in[i] = (unsigned char) getc(infile); - if (!feof(infile)) { - len++; - } else { - in[i] = 0; - } - } - if (len) { - output = (char *) realloc(output, j + 5); - encodeblock(in, out, len); - for (i = 0; i < 4; i++) { - output[j++] = out[i]; - } - } + gint fd = open(filename, O_RDONLY); + struct stat sb; + void *addr; + gchar *b64out = NULL; + + if (fd < 0) { + my_print_errno("opening file"); + return NULL; } - output[j] = '\0'; - fclose(infile); - return output; + + if (fstat(fd, &sb) == -1) { + my_print_errno("on fstat"); + close(fd); + return NULL; + } + + addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) { + my_print_errno("on mmap"); + close(fd); + return NULL; + } + + b64out = g_base64_encode((guchar*) addr, sb.st_size); + munmap(addr, sb.st_size); + close(fd); + + return b64out; } diff --git a/src/requests.c b/src/requests.c index 9c252c7..d3edc3a 100644 --- a/src/requests.c +++ b/src/requests.c @@ -122,6 +122,7 @@ JsonNode *torrent_get(void) json_array_add_string_element(fields, FIELD_RATEUPLOAD); json_array_add_string_element(fields, FIELD_RATEDOWNLOAD); json_array_add_string_element(fields, FIELD_STATUS); + json_array_add_string_element(fields, FIELD_ADDED_DATE); json_array_add_string_element(fields, FIELD_UPLOADEDEVER); json_array_add_string_element(fields, FIELD_SIZEWHENDONE); json_array_add_string_element(fields, FIELD_ID); diff --git a/src/torrent.c b/src/torrent.c index f56c2bc..3c6f0d4 100644 --- a/src/torrent.c +++ b/src/torrent.c @@ -61,6 +61,11 @@ const gchar *torrent_get_name(JsonObject * t) return json_object_get_string_member(t, FIELD_NAME); } +gint64 torrent_get_added_date(JsonObject *t) +{ + return json_object_get_int_member(t, FIELD_ADDED_DATE); +} + gboolean torrent_get_honors_session_limits(JsonObject * t) { return json_object_get_boolean_member(t, FIELD_HONORS_SESSION_LIMITS); diff --git a/src/torrent.h b/src/torrent.h index f8f7d47..248e0d4 100644 --- a/src/torrent.h +++ b/src/torrent.h @@ -64,6 +64,7 @@ gboolean torrent_get_is_finished(JsonObject * t); gboolean torrent_get_honors_session_limits(JsonObject * t); gint64 torrent_get_bandwidth_priority(JsonObject * t); gint64 torrent_get_upload_limit(JsonObject * t); +gint64 torrent_get_added_date(JsonObject *t); gboolean torrent_get_upload_limited(JsonObject * t); gint64 torrent_get_download_limit(JsonObject * t); gboolean torrent_get_download_limited(JsonObject * t); diff --git a/src/trg-cell-renderer-epoch.c b/src/trg-cell-renderer-epoch.c new file mode 100644 index 0000000..28e2d5c --- /dev/null +++ b/src/trg-cell-renderer-epoch.c @@ -0,0 +1,115 @@ +/* + * transmission-remote-gtk - Transmission RPC client for GTK + * Copyright (C) 2011 Alan Fitton + + * 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 depochils. + + * 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 <stdint.h> +#include <gtk/gtk.h> + +#include "trg-cell-renderer-epoch.h" +#include "util.h" + +enum { + PROP_0, + PROP_EPOCH_VALUE +}; + +G_DEFINE_TYPE(TrgCellRendererEpoch, trg_cell_renderer_epoch, + GTK_TYPE_CELL_RENDERER_TEXT) +#define TRG_CELL_RENDERER_EPOCH_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_CELL_RENDERER_EPOCH, TrgCellRendererEpochPrivate)) +typedef struct _TrgCellRendererEpochPrivate TrgCellRendererEpochPrivate; + +struct _TrgCellRendererEpochPrivate { + gdouble epoch_value; +}; + +static void +trg_cell_renderer_epoch_get_property(GObject * object, guint property_id, + GValue * value, GParamSpec * pspec) +{ + TrgCellRendererEpochPrivate *priv = + TRG_CELL_RENDERER_EPOCH_GET_PRIVATE(object); + switch (property_id) { + case PROP_EPOCH_VALUE: + g_value_set_int64(value, priv->epoch_value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void +trg_cell_renderer_epoch_set_property(GObject * object, guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + TrgCellRendererEpochPrivate *priv = + TRG_CELL_RENDERER_EPOCH_GET_PRIVATE(object); + + if (property_id == PROP_EPOCH_VALUE) { + gint64 new_value = g_value_get_int64(value); + if (priv->epoch_value != new_value) { + GDateTime *dt = g_date_time_new_from_unix_utc(new_value); + gchar *timestring = g_date_time_format(dt, "%F %H:%M:%S"); + g_object_set(object, "text", timestring, NULL); + g_free(timestring); + g_date_time_unref(dt); + priv->epoch_value = new_value; + } + } else { + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + } +} + +static void +trg_cell_renderer_epoch_class_init(TrgCellRendererEpochClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + object_class->get_property = trg_cell_renderer_epoch_get_property; + object_class->set_property = trg_cell_renderer_epoch_set_property; + + g_object_class_install_property(object_class, + PROP_EPOCH_VALUE, + g_param_spec_int64("epoch-value", + "Epoch Value", + "Epoch Value", + INT64_MIN, + INT64_MAX, + 0, + G_PARAM_READWRITE + | + G_PARAM_STATIC_NAME + | + G_PARAM_STATIC_NICK + | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private(klass, sizeof(TrgCellRendererEpochPrivate)); +} + +static void +trg_cell_renderer_epoch_init(TrgCellRendererEpoch * self G_GNUC_UNUSED) +{ +} + +GtkCellRenderer *trg_cell_renderer_epoch_new(void) +{ + return + GTK_CELL_RENDERER(g_object_new(TRG_TYPE_CELL_RENDERER_EPOCH, NULL)); +} diff --git a/src/trg-cell-renderer-epoch.h b/src/trg-cell-renderer-epoch.h new file mode 100644 index 0000000..af235bf --- /dev/null +++ b/src/trg-cell-renderer-epoch.h @@ -0,0 +1,51 @@ +/* + * transmission-remote-gtk - Transmission RPC client for GTK + * Copyright (C) 2011 Alan Fitton + + * 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 depochils. + + * 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. + */ + +#ifndef TRG_CELL_RENDERER_EPOCH_H_ +#define TRG_CELL_RENDERER_EPOCH_H_ + +#include <glib-object.h> +#include <gtk/gtk.h> + +G_BEGIN_DECLS +#define TRG_TYPE_CELL_RENDERER_EPOCH trg_cell_renderer_epoch_get_type() +#define TRG_CELL_RENDERER_EPOCH(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_CELL_RENDERER_EPOCH, TrgCellRendererEpoch)) +#define TRG_CELL_RENDERER_EPOCH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_CELL_RENDERER_EPOCH, TrgCellRendererEpochClass)) +#define TRG_IS_CELL_RENDERER_EPOCH(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_CELL_RENDERER_EPOCH)) +#define TRG_IS_CELL_RENDERER_EPOCH_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_CELL_RENDERER_EPOCH)) +#define TRG_CELL_RENDERER_EPOCH_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_CELL_RENDERER_EPOCH, TrgCellRendererEpochClass)) + typedef struct { + GtkCellRendererText parent; +} TrgCellRendererEpoch; + +typedef struct { + GtkCellRendererTextClass parent_class; +} TrgCellRendererEpochClass; + +GType trg_cell_renderer_epoch_get_type(void); + +GtkCellRenderer *trg_cell_renderer_epoch_new(void); + +G_END_DECLS +#endif /* TRG_CELL_RENDERER_EPOCH_H_ */ diff --git a/src/trg-torrent-model.c b/src/trg-torrent-model.c index 1753619..ca33d6c 100644 --- a/src/trg-torrent-model.c +++ b/src/trg-torrent-model.c @@ -123,6 +123,7 @@ static void trg_torrent_model_init(TrgTorrentModel * self) column_types[TORRENT_COLUMN_SEEDS] = G_TYPE_INT; column_types[TORRENT_COLUMN_LEECHERS] = G_TYPE_INT; column_types[TORRENT_COLUMN_DOWNSPEED] = G_TYPE_INT64; + column_types[TORRENT_COLUMN_ADDED] = G_TYPE_INT64; column_types[TORRENT_COLUMN_UPSPEED] = G_TYPE_INT64; column_types[TORRENT_COLUMN_ETA] = G_TYPE_INT64; column_types[TORRENT_COLUMN_UPLOADED] = G_TYPE_INT64; @@ -237,9 +238,12 @@ update_torrent_iter(gint64 serial, TrgTorrentModel * model, -1); gtk_list_store_set(GTK_LIST_STORE(model), iter, TORRENT_COLUMN_UPDATESERIAL, serial, -1); + gtk_list_store_set(GTK_LIST_STORE(model), iter, + TORRENT_COLUMN_ADDED, torrent_get_added_date(t), -1); #else gtk_list_store_set(GTK_LIST_STORE(model), iter, TORRENT_COLUMN_ICON, statusIcon, + TORRENT_COLUMN_ADDED, torrent_get_added_date(t), TORRENT_COLUMN_NAME, torrent_get_name(t), TORRENT_COLUMN_SIZE, torrent_get_size(t), TORRENT_COLUMN_DONE, diff --git a/src/trg-torrent-model.h b/src/trg-torrent-model.h index 03ee64f..eb58449 100644 --- a/src/trg-torrent-model.h +++ b/src/trg-torrent-model.h @@ -89,6 +89,7 @@ enum { TORRENT_COLUMN_UPLOADED, TORRENT_COLUMN_DOWNLOADED, TORRENT_COLUMN_RATIO, + TORRENT_COLUMN_ADDED, TORRENT_COLUMN_ID, TORRENT_COLUMN_JSON, TORRENT_COLUMN_UPDATESERIAL, diff --git a/src/trg-torrent-tree-view.c b/src/trg-torrent-tree-view.c index f6a99c6..196a74d 100644 --- a/src/trg-torrent-tree-view.c +++ b/src/trg-torrent-tree-view.c @@ -61,6 +61,8 @@ static void trg_torrent_tree_view_init(TrgTorrentTreeView * tv) TORRENT_COLUMN_DOWNLOADED, -1); trg_tree_view_add_ratio_column(TRG_TREE_VIEW(tv), _("Ratio"), TORRENT_COLUMN_RATIO, -1); + trg_tree_view_add_epoch_column(TRG_TREE_VIEW(tv), _("Added"), + TORRENT_COLUMN_ADDED, -1); gtk_tree_view_set_search_column(GTK_TREE_VIEW(tv), TORRENT_COLUMN_NAME); diff --git a/src/trg-tree-view.c b/src/trg-tree-view.c index 582b1d6..d828d0e 100644 --- a/src/trg-tree-view.c +++ b/src/trg-tree-view.c @@ -24,6 +24,7 @@ #include "trg-cell-renderer-size.h" #include "trg-cell-renderer-ratio.h" #include "trg-cell-renderer-eta.h" +#include "trg-cell-renderer-epoch.h" G_DEFINE_TYPE(TrgTreeView, trg_tree_view, GTK_TYPE_TREE_VIEW) @@ -137,6 +138,21 @@ void trg_tree_view_add_speed_column(TrgTreeView * tv, char *title, gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column); } +void trg_tree_view_add_epoch_column(TrgTreeView * tv, char *title, + int index, int width) +{ + GtkCellRenderer *renderer; + GtkTreeViewColumn *column; + + renderer = trg_cell_renderer_epoch_new(); + column = gtk_tree_view_column_new_with_attributes(title, renderer, + "epoch-value", + index, NULL); + + trg_tree_view_std_column_setup(column, index, width); + gtk_tree_view_append_column(GTK_TREE_VIEW(tv), column); +} + void trg_tree_view_add_ratio_column(TrgTreeView * tv, char *title, int index, int width) { diff --git a/src/trg-tree-view.h b/src/trg-tree-view.h index aa984a4..9cb8748 100644 --- a/src/trg-tree-view.h +++ b/src/trg-tree-view.h @@ -74,5 +74,7 @@ void trg_tree_view_add_eta_column(TrgTreeView * tv, char *title, int index, int width); void trg_tree_view_std_column_setup(GtkTreeViewColumn * column, int index, int width); +void trg_tree_view_add_epoch_column(TrgTreeView * tv, char *title, + int index, int width); #endif /* _TRG_TREE_VIEW_H_ */ |