]>
Dogcows Code - chaz/homebank/blob - src/hb-import-csv.c
0e9e3879d59375161e7665a3fd4f47627604dc17
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 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(ImportContext
*ictx
, GenFile
*genfile
)
223 //GList *list = NULL;
224 static gint csvtype
[7] = {
234 DB( g_print("\n[import] homebank csv\n") );
236 io
= g_io_channel_new_file(genfile
->filepath
, "r", NULL
);
249 newacc
= hb_import_gen_acc_get_next(ictx
, FILETYPE_CSV_HB
, NULL
, NULL
);
251 if( genfile
->encoding
!= NULL
)
253 g_io_channel_set_encoding(io
, genfile
->encoding
, NULL
);
258 io_stat
= g_io_channel_read_line(io
, &tmpstr
, &length
, NULL
, &err
);
259 if( io_stat
== G_IO_STATUS_EOF
)
261 if( io_stat
== G_IO_STATUS_ERROR
)
263 DB (g_print(" + ERROR %s\n",err
->message
));
266 if( io_stat
== G_IO_STATUS_NORMAL
)
268 if( *tmpstr
!= '\0' )
274 hb_string_strip_crlf(tmpstr
);
275 DB( g_print("\n (row-%04d) ->|%s|<-\n", count
, tmpstr
) );
277 // 0:date; 1:paymode; 2:info; 3:payee, 4:wording; 5:amount; 6:category; 7:tags
278 str_array
= hb_csv_row_get(tmpstr
, ";", 8);
279 isvalid
= hb_csv_row_valid(str_array
, 8, csvtype
);
281 DB( g_print(" valid %d, '%s'\n", isvalid
, tmpstr
) );
285 g_warning ("csv parse: line %d, invalid column count or data", count
);
287 //todo log line in error to report user
291 GenTxn
*newope
= da_gen_txn_malloc();;
293 DB( g_print(" ->%s\n", tmpstr
) );
295 /* convert to generic transaction */
296 newope
->date
= g_strdup(str_array
[0]);
297 newope
->paymode
= atoi(str_array
[1]);
298 //added 5.1.8 forbid to import 5=internal xfer
299 if(newope
->paymode
== PAYMODE_INTXFER
)
300 newope
->paymode
= PAYMODE_XFER
;
301 newope
->rawinfo
= g_strdup(str_array
[2]);
302 newope
->rawpayee
= g_strdup(g_strstrip(str_array
[3]));
303 newope
->rawmemo
= g_strdup(str_array
[4]);
304 newope
->amount
= hb_qif_parser_get_amount(str_array
[5]);
305 newope
->category
= g_strdup(g_strstrip(str_array
[6]));
306 newope
->tags
= g_strdup(str_array
[7]);
307 newope
->account
= g_strdup(newacc
->name
);
309 /* todo: move this eval date valid */
310 //guint32 juliantmp = hb_date_get_julian(str_array[0], ictx->datefmt);
311 ///if( juliantmp == 0 )
312 // ictx->cnt_err_date++;
315 DB( g_print(" storing %s : %s : %s :%s : %s : %s : %s : %s\n",
316 str_array[0], str_array[1], str_array[2],
317 str_array[3], str_array[4], str_array[5],
318 str_array[6], str_array[7]
321 /* csv file are standalone, so no way to link a target txn */
322 if(newope
->paymode
== PAYMODE_INTXFER
)
323 newope
->paymode
= PAYMODE_XFER
;
325 da_gen_txn_append(ictx
, newope
);
327 g_strfreev (str_array
);
334 g_io_channel_unref (io
);
337 ui_dialog_msg_infoerror(data->window, error > 0 ? GTK_MESSAGE_ERROR : GTK_MESSAGE_INFO,
338 _("Transaction CSV import result"),
339 _("%d transactions inserted\n%d errors in the file"),
345 return ictx
->gen_lst_txn
;
This page took 0.045789 seconds and 4 git commands to generate.