1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 David Dent
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
25 /* function return values */
29 TIDY_RETURN_ERROR
= 1,
31 TIDY_RETURN_ABORT
= 3,
39 } tidy_types
[MAX_TYPES
];
41 bool tidy_loaded_and_changed
= false;
43 #define DEFAULT_FILES PLUGIN_APPS_DIR "/disktidy.config"
44 #define CUSTOM_FILES PLUGIN_APPS_DIR "/disktidy_custom.config"
45 void add_item(const char* name
, int index
)
47 rb
->strcpy(tidy_types
[index
].filestring
, name
);
48 if (name
[rb
->strlen(name
)-1] == '/')
50 tidy_types
[index
].directory
= true;
51 tidy_types
[index
].filestring
[rb
->strlen(name
)-1] = '\0';
54 tidy_types
[index
].directory
= false;
56 static int find_file_string(const char *file
, char *last_group
)
59 int i
= 0, idx_last_group
= -1;
61 rb
->strcpy(temp
, file
);
62 if (temp
[rb
->strlen(temp
)-1] == '/')
65 temp
[rb
->strlen(temp
)-1] = '\0';
67 while (i
<tidy_type_count
)
69 if (!rb
->strcmp(tidy_types
[i
].filestring
, temp
) &&
70 folder
== tidy_types
[i
].directory
)
72 else if (!rb
->strcmp(tidy_types
[i
].filestring
, last_group
))
76 /* not found, so insert it into its group */
77 if (file
[0] != '<' && idx_last_group
!= -1)
79 for (i
=idx_last_group
; i
<tidy_type_count
; i
++)
81 if (tidy_types
[i
].filestring
[0] == '<')
87 /* shift items up one */
88 for (i
=tidy_type_count
;i
>idx_last_group
;i
--)
90 rb
->strcpy(tidy_types
[i
].filestring
, tidy_types
[i
-1].filestring
);
91 tidy_types
[i
].directory
= tidy_types
[i
-1].directory
;
92 tidy_types
[i
].remove
= tidy_types
[i
-1].remove
;
95 add_item(file
, idx_last_group
+1);
96 return idx_last_group
+1;
101 bool tidy_load_file(const char* file
)
103 int fd
= rb
->open(file
, O_RDONLY
), i
;
104 char buf
[MAX_PATH
], *str
, *remove
;
105 char last_group
[MAX_PATH
] = "";
109 while ((tidy_type_count
< MAX_TYPES
) &&
110 rb
->read_line(fd
, buf
, MAX_PATH
))
112 if (rb
->settings_parseline(buf
, &str
, &remove
))
114 i
= find_file_string(str
, last_group
);
115 new = (i
>= tidy_type_count
);
116 if (!rb
->strcmp(remove
, "yes"))
117 tidy_types
[i
].remove
= true;
118 else tidy_types
[i
].remove
= false;
126 rb
->strcpy(last_group
, str
);
133 bool tidy_remove_item(char *item
, int attr
)
137 bool ret
= false, rem
= false;
138 for (i
=0; ret
== false && i
< tidy_type_count
; i
++)
140 file
= tidy_types
[i
].filestring
;
141 if (file
[rb
->strlen(file
)-1] == '*')
143 if (!rb
->strncmp(file
, item
, rb
->strlen(file
)-1))
146 else if (!rb
->strcmp(file
, item
))
150 if (!tidy_types
[i
].remove
)
152 if (attr
&ATTR_DIRECTORY
)
153 ret
= tidy_types
[i
].directory
;
160 void tidy_lcd_status(const char *name
, int *removed
)
162 char text
[24]; /* "Cleaned up nnnnn items" */
164 /* display status text */
165 rb
->lcd_clear_display();
166 rb
->lcd_puts(0, 0, "Working ...");
167 rb
->lcd_puts(0, 1, name
);
168 rb
->snprintf(text
, 24, "Cleaned up %d items", *removed
);
169 #ifdef HAVE_LCD_BITMAP
170 rb
->lcd_puts(0, 2, text
);
175 void tidy_get_absolute_path(struct dirent
*entry
, char *fullname
,
178 /* gets absolute path using dirent and name */
179 rb
->strcpy(fullname
, name
);
180 if (rb
->strlen(name
) > 1)
182 rb
->strcat(fullname
, "/");
184 rb
->strcat(fullname
, entry
->d_name
);
187 enum tidy_return
tidy_removedir(const char *name
, int *removed
)
189 /* delete directory */
190 struct dirent
*entry
;
191 enum tidy_return status
= TIDY_RETURN_OK
;
194 char fullname
[MAX_PATH
];
196 /* display status text */
197 tidy_lcd_status(name
, removed
);
201 dir
= rb
->opendir(name
);
204 while((status
== TIDY_RETURN_OK
) && ((entry
= rb
->readdir(dir
)) != 0))
207 /* check for user input and usb connect */
208 button
= rb
->get_action(CONTEXT_STD
, TIMEOUT_NOBLOCK
);
209 if (button
== ACTION_STD_CANCEL
)
212 return TIDY_RETURN_ABORT
;
214 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
217 return TIDY_RETURN_USB
;
222 /* get absolute path */
223 tidy_get_absolute_path(entry
, fullname
, name
);
225 if (entry
->attribute
& ATTR_DIRECTORY
)
227 /* dir ignore "." and ".." */
228 if ((rb
->strcmp(entry
->d_name
, ".") != 0) && \
229 (rb
->strcmp(entry
->d_name
, "..") != 0))
231 tidy_removedir(fullname
, removed
);
238 rb
->remove(fullname
);
248 status
= TIDY_RETURN_ERROR
;
253 enum tidy_return
tidy_clean(const char *name
, int *removed
)
255 /* deletes junk files and dirs left by system */
256 struct dirent
*entry
;
257 enum tidy_return status
= TIDY_RETURN_OK
;
259 int del
; /* has the item been deleted */
261 char fullname
[MAX_PATH
];
263 /* display status text */
264 tidy_lcd_status(name
, removed
);
268 dir
= rb
->opendir(name
);
271 while((status
== TIDY_RETURN_OK
) && ((entry
= rb
->readdir(dir
)) != 0))
274 /* check for user input and usb connect */
275 button
= rb
->get_action(CONTEXT_STD
, TIMEOUT_NOBLOCK
);
276 if (button
== ACTION_STD_CANCEL
)
279 return TIDY_RETURN_ABORT
;
281 if (rb
->default_event_handler(button
) == SYS_USB_CONNECTED
)
284 return TIDY_RETURN_USB
;
289 if (entry
->attribute
& ATTR_DIRECTORY
)
291 /* directory ignore "." and ".." */
292 if ((rb
->strcmp(entry
->d_name
, ".") != 0) && \
293 (rb
->strcmp(entry
->d_name
, "..") != 0))
297 /* get absolute path */
298 tidy_get_absolute_path(entry
, fullname
, name
);
300 if (tidy_remove_item(entry
->d_name
, entry
->attribute
))
303 tidy_removedir(fullname
, removed
);
309 /* dir not deleted so clean it */
310 status
= tidy_clean(fullname
, removed
);
318 if (tidy_remove_item(entry
->d_name
, entry
->attribute
))
320 *removed
+= 1; /* increment removed files counter */
322 /* get absolute path */
323 char fullname
[MAX_PATH
];
324 tidy_get_absolute_path(entry
, fullname
, name
);
327 rb
->remove(fullname
);
337 return TIDY_RETURN_ERROR
;
341 enum tidy_return
tidy_do(void)
343 /* clean disk and display num of items removed */
345 enum tidy_return status
;
346 char text
[24]; /* "Cleaned up nnnnn items" */
348 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
352 status
= tidy_clean("/", &removed
);
354 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
355 rb
->cpu_boost(false);
358 if ((status
== TIDY_RETURN_OK
) || (status
== TIDY_RETURN_ABORT
))
360 rb
->lcd_clear_display();
361 rb
->snprintf(text
, 24, "Cleaned up %d items", removed
);
362 if (status
== TIDY_RETURN_ABORT
)
364 rb
->splash(HZ
, "User aborted");
365 rb
->lcd_clear_display();
367 rb
->splash(HZ
*2, text
);
372 enum themable_icons
get_icon(int item
, void * data
)
375 if (tidy_types
[item
].filestring
[0] == '<') /* special type */
377 else if (tidy_types
[item
].remove
)
383 char * get_name(int selected_item
, void * data
,
384 char * buffer
, size_t buffer_len
)
387 if (tidy_types
[selected_item
].directory
)
389 rb
->snprintf(buffer
, buffer_len
, "%s/",
390 tidy_types
[selected_item
].filestring
);
393 return tidy_types
[selected_item
].filestring
;
396 int list_action_callback(int action
, struct gui_synclist
*lists
)
398 if (action
== ACTION_STD_OK
)
400 int selection
= rb
->gui_synclist_get_sel_pos(lists
);
401 if (tidy_types
[selection
].filestring
[0] == '<')
404 if (!rb
->strcmp(tidy_types
[selection
].filestring
, "< ALL >"))
406 for (i
=0; i
<tidy_type_count
; i
++)
408 if (tidy_types
[i
].filestring
[0] != '<')
409 tidy_types
[i
].remove
= true;
412 else if (!rb
->strcmp(tidy_types
[selection
].filestring
, "< NONE >"))
414 for (i
=0; i
<tidy_type_count
; i
++)
416 if (tidy_types
[i
].filestring
[0] != '<')
417 tidy_types
[i
].remove
= false;
420 else /* toggle all untill the next <> */
423 while (selection
< tidy_type_count
&&
424 tidy_types
[selection
].filestring
[0] != '<')
426 tidy_types
[selection
].remove
= !tidy_types
[selection
].remove
;
432 tidy_types
[selection
].remove
= !tidy_types
[selection
].remove
;
433 tidy_loaded_and_changed
= true;
434 return ACTION_REDRAW
;
439 enum tidy_return
tidy_lcd_menu(void)
442 enum tidy_return status
= TIDY_RETURN_OK
;
443 bool menu_quit
= false;
445 MENUITEM_STRINGLIST(menu
, "Disktidy Menu", NULL
,
446 "Start Cleaning", "Files to Clean",
451 switch(rb
->do_menu(&menu
, &selection
, NULL
, false))
454 menu_quit
= true; /* start cleaning */
459 bool show_icons
= rb
->global_settings
->show_icons
;
460 struct simplelist_info list
;
461 /* force the icons so its readable */
462 rb
->global_settings
->show_icons
= true;
463 rb
->simplelist_info_init(&list
, "Files to Clean",
464 tidy_type_count
, NULL
);
465 list
.get_icon
= get_icon
;
466 list
.get_name
= get_name
;
467 list
.action_callback
= list_action_callback
;
468 rb
->simplelist_show_list(&list
);
469 rb
->global_settings
->show_icons
= show_icons
;
474 status
= TIDY_RETURN_ABORT
; /* exit plugin */
482 /* this is the plugin entry point */
483 enum plugin_status
plugin_start(const void* parameter
)
485 enum tidy_return status
;
489 tidy_load_file(DEFAULT_FILES
);
490 tidy_load_file(CUSTOM_FILES
);
491 if (tidy_type_count
== 0)
493 rb
->splash(3*HZ
, "Missing disktidy.config file");
496 status
= tidy_lcd_menu();
497 if (tidy_loaded_and_changed
)
499 int fd
= rb
->creat(CUSTOM_FILES
);
503 for(i
=0;i
<tidy_type_count
;i
++)
505 rb
->fdprintf(fd
, "%s%c: %s\n", tidy_types
[i
].filestring
,
506 tidy_types
[i
].directory
?'/':'\0',
507 tidy_types
[i
].remove
?"yes":"no");
512 if (status
== TIDY_RETURN_ABORT
)
522 case TIDY_RETURN_ERROR
:
524 case TIDY_RETURN_USB
:
525 return PLUGIN_USB_CONNECTED
;
526 case TIDY_RETURN_ABORT
:
531 if (rb
->default_event_handler(rb
->button_get(false)) == SYS_USB_CONNECTED
)
532 return PLUGIN_USB_CONNECTED
;