1 /**
2 * Copyright (C) 2014 Aaron Ball <nullspoon@iohq.net>
3 *
4 * Noteless is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * Noteless is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with noteless. If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "note_list.h"
18
19 /**
20 * Constructor
21 *
22 * @param list List to be instantiated
23 * @param path Path to the treasure... er... notes
24 * @param ext Extension of the notes to pay attention to
25 */
26 void note_list_new(note_list_t* list, char* path, char* ext) {
27 list->count = 0;
28 strcpy(list->extension, ext);
29 strcpy(list->path, path);
30
31 DIR* d = opendir(path);
32 struct dirent* ent;
33
34 int ext_len = strlen(ext);
35
36 // First iterration to get a matching file count
37 while((ent = readdir(d))) {
38 // The start index of the extension in the current filename
39 int ext_start = strlen(ent->d_name) - ext_len;
40
41 if(strncmp(&ent->d_name[ext_start], ext, ext_len) == 0) {
42 list->count++;
43 }
44 }
45
46 // Create name list of previously discovered size
47 list->names = malloc(sizeof(char*) * list->count);
48
49 rewinddir(d);
50 int i = 0;
51 // Second iterration for populating the file list
52 while((ent = readdir(d))) {
53 // The start index of the extension in the current filename
54 int ext_start = strlen(ent->d_name) - ext_len;
55
56 // If the current file's extension matches the list extension
57 if(strncmp(&ent->d_name[ext_start], ext, ext_len) == 0) {
58 // Allocate space in the array for the filename (all the way up to the
59 // period starting the extension)
60 list->names[i] = malloc(sizeof(char) * ext_start);
61
62 // Copy the temp filename into the struct
63 // As previously mentioned, we want to copy minus one char (the period)
64 // so we have room for the null byte char.
65 strncpy(list->names[i], ent->d_name, ext_start);
66
67 // Insert null byte char one before the extension (the period)
68 list->names[i][ext_start - 1] = '\0';
69
70 i++;
71 }
72 }
73
74 closedir(d);
75 }
76
77
78 void note_list_free(note_list_t* list) {
79 for(int i = 0; i < list->count; i++) {
80 free(list->names[i]);
81 }
82 free(list->names);
83 }
84
85
86 // void note_list::get_notes( string base, string ext, string sub ) {
87 // // Dir pointer
88 // DIR* dp;
89 //
90 // string search_dir = base;
91 // // Append the subdir if necessary
92 // if( sub != "" ) {
93 // // Open the subdir if it's specified
94 // search_dir = base + "/" + sub;
95 // }
96 // dp = opendir( search_dir.c_str() );
97 //
98 // if( dp ) {
99 // // Prepare to iterrate through dir items
100 // struct dirent* item;
101 // while( item = readdir( dp ) ) {
102 // string name = item->d_name;
103 //
104 // path p( base + "/" + sub + "/" + name );
105 //
106 // if( name[0] != '.' ) {
107 // if( p.is_dir() == 1 ) {
108 // // TODO
109 // // I really hate the way I'm doing this repeatedly. Going to need a
110 // // better way.
111 // if( sub != "" ) {
112 // get_notes( base, ext, sub + "/" + name );
113 // } else {
114 // get_notes( base, ext, name );
115 // }
116 // } else {
117 // // This will be replaced later with path.join() when it's implemented
118 // if( sub != "" ) {
119 // add( base, sub + "/" + name );
120 // } else {
121 // add( base, name );
122 // }
123 // }
124 // }
125 // }
126 // closedir( dp );
127 // }
128 // }
129
130
131 /**
132 * Adds a new note item to the list by path.
133 *
134 * @param string path Path to the note to be added to the list
135 *
136 * @return 0
137 */
138 // int note_list::add( string base, string name ) {
139 // note n( base, name );
140 // notes.push_back( n );
141 // return 0;
142 // }
143
144
145 /**
146 * Opens a new note for editing
147 *
148 * @param string editor Path to the editor to use for editing
149 * @param string note_name Name of the note to be created and edited
150 *
151 * @return int Success or failure (always success for now)
152 */
153 // int note_list::create( string editor, string note_name ) {
154 // string spath = _dirname + '/' + note_name + '.' + _ext;
155 // path p( spath );
156 // note n( p );
157 // n.edit( editor );
158 // return 0;
159 // }
160
161
162 /**
163 * Opens the specified note for editing
164 *
165 * @param list Note list the note-to-be-edited belongs to
166 * @param editor Path to the editor to use for editing
167 * @param note_name Name of the note to be edited
168 */
169 int note_list_edit(note_list_t* list, char* editor, char* note_name) {
170 int id = note_list_get_note_id(list, note_name);
171 if(id != -1) {
172 // Construct the note path
173 // It's safe to assume 256 here since various other path variables also
174 // limit to 256.
175 char path[256];
176 strcpy(path, list->path);
177 strcat(path, "/");
178 strcat(path, list->names[id]);
179 strcat(path, ".");
180 strcat(path, list->extension);
181
182 note_t note;
183 note_new(¬e, path);
184 note_edit(¬e, editor);
185 } else {
186 printf("Note '%s' does not exist.\n", note_name);
187 return 1;
188 }
189 return 0;
190 }
191
192
193 /**
194 * Searches all note *names* (friendly and unfriendly) for the given name and
195 * returns the note id (not necissarily persistent). If note does not exist,
196 * returns -1. Can be used for a sort of "note_exists" method as such.
197 *
198 * Note that this does a partial comparison, so only the number of characters
199 * passed for note_name is the number compared, thus allowing for fuzzy-ish
200 * name matching. This will return the id of the first matched note name.
201 *
202 * @param list Note list to search for the given note [partial] name
203 * @param note_name Name of the note to search for
204 *
205 * @return int The integer of the note. -1 if note does not exist
206 */
207 int note_list_get_note_id(note_list_t* list, char* note_name) {
208 for(int i = 0; i < list->count; i++) {
209 if(strncmp(list->names[i], note_name, strlen(note_name)) == 0) {
210 return i;
211 }
212 }
213 return -1;
214 }
215
216
217 /**
218 * Returns the contents of the requested note
219 *
220 * @param string note_name Name of the note to get the contents for
221 *
222 * @return vector<string> Contents of the note, broken per line into a vector.
223 */
224 // int note_list::cat_note( string note_name, vector<string>* pbody ) {
225 // // Check for the requested note
226 // int id = find_note_id( note_name );
227 // if( id != -1 ) {
228 // // Read in the note's contents
229 // notes[id].read();
230 // *pbody = notes[id].body;
231 // } else {
232 // return 1;
233 // }
234 // return 0;
235 // }
236
237 /**
238 * Deletes the specified note
239 *
240 * @param string note_name Name of the note to be deleted
241 *
242 * @return int Exit code (1 = error, 0 = success)
243 */
244 // int note_list::rm( string note_name ) {
245 // int id = find_note_id( note_name );
246 // if( id == -1 ) {
247 // cout << "Note \"" << note_name << "\" does not exist." << endl;
248 // return 1;
249 // } else {
250 // notes[id].rm();
251 // }
252 // return 0;
253 // }
254
255 /**
256 * TODO
257 */
258 // int note_list_find(note_list_t* list, int case_sensitive, char* term ) {
259 // for(int i = 0; i < notes.size(); i++) {
260 // vector<string> note_matches = notes[i].find( case_sensitive, term );
261 // if( note_matches.size() > 0 ) {
262 // for( int m = 0; m < note_matches.size(); m++ ) {
263 // matches.push_back( note_matches[m] );
264 // }
265 // }
266 // }
267 // return matches;
268 // }
|