]>
Dogcows Code - chaz/homebank/blob - src/hb-import-csv.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2017 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "hb-import.h"
26 /****************************************************************************/
28 /****************************************************************************/
37 /* our global datas */
38 extern struct HomeBank
*GLOBALS
;
39 extern struct Preferences
*PREFS
;
42 static gchar
*hb_csv_strndup (gchar
*str
, gsize n
)
49 new_str
= g_new (gchar
, n
+ 1);
57 strncpy (new_str
, str
, n
);
61 twoquote
= strstr(new_str
, "\"\"");
63 strcpy (twoquote
, twoquote
+1);
65 //todo: replace & < > ' " ??
75 static gchar
*hb_csv_find_delimiter(gchar
*string
)
78 gboolean enclosed
= FALSE
;
82 if( *s
== ';' && enclosed
== FALSE
)
97 gboolean
hb_csv_row_valid(gchar
**str_array
, guint nbcolumns
, gint
*csvtype
)
99 gboolean valid
= TRUE
;
104 gchar
*type
[5] = { "string", "date", "int", "double" };
108 DB( g_print("\n** hb_string_csv_valid: init %d\n", valid
) );
110 DB( g_print(" -> length %d, nbcolumns %d\n", g_strv_length( str_array
), nbcolumns
) );
112 if( g_strv_length( str_array
) != nbcolumns
)
118 for(i
=0;i
<nbcolumns
;i
++)
121 lasttype
= csvtype
[i
];
126 DB( g_print(" -> fail on column %d, type: %s\n", i
, type
[lasttype
]) );
130 DB( g_print(" -> control column %d, type: %d, valid: %d '%s'\n", i
, lasttype
, valid
, str_array
[i
]) );
135 valid
= hb_string_isdate(str_array
[i
]);
138 valid
= hb_string_isprint(str_array
[i
]);
141 valid
= hb_string_isdigit(str_array
[i
]);
145 //todo: use strtod (to take care or . or ,)
146 g_ascii_strtod(str_array
[i
], NULL
);
147 //todo : see this errno
150 DB( g_print("errno: %d\n", errno
) );
159 DB( g_print(" --> return %d\n", valid
) );
165 gchar
**hb_csv_row_get(gchar
*string
, gchar
*delimiter
, gint max_tokens
)
167 GSList
*string_list
= NULL
, *slist
;
168 gchar
**str_array
, *s
;
172 g_return_val_if_fail (string
!= NULL
, NULL
);
173 g_return_val_if_fail (delimiter
!= NULL
, NULL
);
174 g_return_val_if_fail (delimiter
[0] != '\0', NULL
);
177 max_tokens
= G_MAXINT
;
180 s
= hb_csv_find_delimiter (remainder
);
183 gsize delimiter_len
= strlen (delimiter
);
185 while (--max_tokens
&& s
&& *s
!= '\0')
190 string_list
= g_slist_prepend (string_list
, hb_csv_strndup (remainder
, len
));
191 DB( g_print(" stored=[%s]\n", (gchar
*)string_list
->data
) );
194 remainder
= s
+ delimiter_len
;
195 s
= hb_csv_find_delimiter (remainder
);
204 string_list
= g_slist_prepend (string_list
, hb_csv_strndup (remainder
, len
));
205 DB( g_print(" stored=[%s]\n", (gchar
*)string_list
->data
) );
208 str_array
= g_new (gchar
*, n
+ 1);
210 str_array
[n
--] = NULL
;
211 for (slist
= string_list
; slist
; slist
= slist
->next
)
212 str_array
[n
--] = slist
->data
;
214 g_slist_free (string_list
);
220 GList
*homebank_csv_import(gchar
*filename
, ImportContext
*ictx
)
224 static gint csvtype
[7] = {
234 DB( g_print("\n[import] homebank csv\n") );
236 io
= g_io_channel_new_file(filename
, "r", NULL
);
251 gchar
*accname
= g_strdup_printf(_("(account %d)"), da_acc_get_max_key() + 1);
252 tmp_acc
= import_create_account(accname
, NULL
);
256 if( ictx
->encoding
!= NULL
)
258 g_io_channel_set_encoding(io
, ictx
->encoding
, NULL
);
263 io_stat
= g_io_channel_read_line(io
, &tmpstr
, &length
, NULL
, &err
);
264 if( io_stat
== G_IO_STATUS_EOF
)
266 if( io_stat
== G_IO_STATUS_ERROR
)
268 DB (g_print(" + ERROR %s\n",err
->message
));
271 if( io_stat
== G_IO_STATUS_NORMAL
)
273 if( *tmpstr
!= '\0' )
279 hb_string_strip_crlf(tmpstr
);
280 DB( g_print("\n (row-%04d) ->|%s|<-\n", count
, tmpstr
) );
282 // 0:date; 1:paymode; 2:info; 3:payee, 4:wording; 5:amount; 6:category; 7:tags
283 str_array
= hb_csv_row_get(tmpstr
, ";", 8);
284 isvalid
= hb_csv_row_valid(str_array
, 8, csvtype
);
286 DB( g_print(" valid %d, '%s'\n", isvalid
, tmpstr
) );
290 g_warning ("csv parse: line %d, invalid column count or data", count
);
292 //todo log line in error to report user
296 Transaction
*newope
= da_transaction_malloc();
298 //DB( g_print(" ->%s\n", tmpstr ) );
300 newope
->date
= hb_date_get_julian(str_array
[0], ictx
->datefmt
);
301 if( newope
->date
== 0 )
303 g_warning ("csv parse: line %d, parse date failed", count
);
304 ictx
->cnt_err_date
++;
307 newope
->paymode
= atoi(str_array
[1]);
308 newope
->info
= g_strdup(str_array
[2]);
311 g_strstrip(str_array
[3]);
312 payitem
= da_pay_get_by_name(str_array
[3]);
315 payitem
= da_pay_malloc();
316 payitem
->name
= g_strdup(str_array
[3]);
317 payitem
->imported
= TRUE
;
318 da_pay_append(payitem
);
320 if( payitem
->imported
== TRUE
)
321 ictx
->cnt_new_pay
+= 1;
324 newope
->kpay
= payitem
->key
;
325 newope
->wording
= g_strdup(str_array
[4]);
326 newope
->amount
= hb_qif_parser_get_amount(str_array
[5]);
329 g_strstrip(str_array
[6]);
330 catitem
= da_cat_append_ifnew_by_fullname(str_array
[6], TRUE
);
331 if( catitem
!= NULL
)
333 newope
->kcat
= catitem
->key
;
335 if( catitem
->imported
== TRUE
&& catitem
->key
> 0 )
336 ictx
->cnt_new_cat
+= 1;
340 transaction_tags_parse(newope
, str_array
[7]);
343 newope
->kacc
= tmp_acc
->key
;
344 //newope->kxferacc = accnum;
346 newope
->flags
|= OF_ADDED
;
348 if( newope
->amount
> 0)
349 newope
->flags
|= OF_INCOME
;
352 DB( g_print(" storing %s : %s : %s :%s : %s : %s : %s : %s\n",
353 str_array[0], str_array[1], str_array[2],
354 str_array[3], str_array[4], str_array[5],
355 str_array[6], str_array[7]
359 list
= g_list_append(list
, newope
);
361 g_strfreev (str_array
);
368 g_io_channel_unref (io
);
371 ui_dialog_msg_infoerror(data->window, error > 0 ? GTK_MESSAGE_ERROR : GTK_MESSAGE_INFO,
372 _("Transaction CSV import result"),
373 _("%d transactions inserted\n%d errors in the file"),
This page took 0.052026 seconds and 4 git commands to generate.