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 for the entire filename (we'll strip the extension off
59 // as needed later). This will make calculating path lengths much
60 // simpler.
61 list->names[i] = malloc(sizeof(char) * strlen(ent->d_name));
62
63 // Copy the filename into the struct
64 strcpy(list->names[i], ent->d_name);
65
66 i++;
67 }
68 }
69
70 closedir(d);
71 }
72
73
74 void note_list_free(note_list_t* list) {
75 for(int i = 0; i < list->count; i++) {
76 free(list->names[i]);
77 }
78 free(list->names);
79 }
80
81
82 // void note_list::get_notes( string base, string ext, string sub ) {
83 // // Dir pointer
84 // DIR* dp;
85 //
86 // string search_dir = base;
87 // // Append the subdir if necessary
88 // if( sub != "" ) {
89 // // Open the subdir if it's specified
90 // search_dir = base + "/" + sub;
91 // }
92 // dp = opendir( search_dir.c_str() );
93 //
94 // if( dp ) {
95 // // Prepare to iterrate through dir items
96 // struct dirent* item;
97 // while( item = readdir( dp ) ) {
98 // string name = item->d_name;
99 //
100 // path p( base + "/" + sub + "/" + name );
101 //
102 // if( name[0] != '.' ) {
103 // if( p.is_dir() == 1 ) {
104 // // TODO
105 // // I really hate the way I'm doing this repeatedly. Going to need a
106 // // better way.
107 // if( sub != "" ) {
108 // get_notes( base, ext, sub + "/" + name );
109 // } else {
110 // get_notes( base, ext, name );
111 // }
112 // } else {
113 // // This will be replaced later with path.join() when it's implemented
114 // if( sub != "" ) {
115 // add( base, sub + "/" + name );
116 // } else {
117 // add( base, name );
118 // }
119 // }
120 // }
121 // }
122 // closedir( dp );
123 // }
124 // }
125
126
127 /**
128 * Adds a new note item to the list by path.
129 *
130 * @param string path Path to the note to be added to the list
131 *
132 * @return 0
133 */
134 // int note_list::add( string base, string name ) {
135 // note n( base, name );
136 // notes.push_back( n );
137 // return 0;
138 // }
139
140
141 /**
142 * Opens a new note for editing
143 *
144 * @param string editor Path to the editor to use for editing
145 * @param string note_name Name of the note to be created and edited
146 *
147 * @return int Success or failure (always success for now)
148 */
149 // int note_list::create( string editor, string note_name ) {
150 // string spath = _dirname + '/' + note_name + '.' + _ext;
151 // path p( spath );
152 // note n( p );
153 // n.edit( editor );
154 // return 0;
155 // }
156
157
158 /**
159 * Opens the specified note for editing
160 *
161 * @param list Note list the note-to-be-edited belongs to
162 * @param editor Path to the editor to use for editing
163 * @param note_name Name of the note to be edited
164 */
165 int note_list_edit(note_list_t* list, char* editor, char* note_name) {
166 int id = note_list_get_note_id(list, note_name);
167 if(id != -1) {
168 // Construct the note path
169 // It's safe to assume 256 here since various other path variables also
170 // limit to 256.
171 char path[256];
172 strcpy(path, list->path);
173 strcat(path, "/");
174 strcat(path, list->names[id]);
175
176 note_t note;
177 note_new(¬e, path);
178 note_edit(¬e, editor);
179 } else {
180 printf("Note '%s' does not exist.\n", note_name);
181 return 1;
182 }
183 return 0;
184 }
185
186
187 /**
188 * Searches all note *names* (friendly and unfriendly) for the given name and
189 * returns the note id (not necissarily persistent). If note does not exist,
190 * returns -1. Can be used for a sort of "note_exists" method as such.
191 *
192 * Note that this does a partial comparison, so only the number of characters
193 * passed for note_name is the number compared, thus allowing for fuzzy-ish
194 * name matching. This will return the id of the first matched note name.
195 *
196 * @param list Note list to search for the given note [partial] name
197 * @param note_name Name of the note to search for
198 *
199 * @return int The integer of the note. -1 if note does not exist
200 */
201 int note_list_get_note_id(note_list_t* list, char* note_name) {
202 for(int i = 0; i < list->count; i++) {
203 if(strncmp(list->names[i], note_name, strlen(note_name)) == 0) {
204 return i;
205 }
206 }
207 return -1;
208 }
209
210
211 /**
212 * Returns the contents of the requested note
213 *
214 * @param string note_name Name of the note to get the contents for
215 *
216 * @return vector<string> Contents of the note, broken per line into a vector.
217 */
218 int note_list_cat_note(note_list_t* list, char* note_name) {
219 // Check for the requested note
220 int id = note_list_get_note_id(list, note_name);
221 if(id != -1) {
222 // Construct the full note path
223 char path[strlen(list->path) + strlen(list->names[id]) + 3];
224 strcpy(path, list->path);
225 strcat(path, "/");
226 strcat(path, list->names[id]);
227
228 note_t note;
229 note_new(¬e, path);
230
231 // Read in the note's contents
232 note_cat(¬e);
233 } else {
234 return 1;
235 }
236 return 0;
237 }
238
239 /**
240 * Deletes the specified note
241 *
242 * @param string note_name Name of the note to be deleted
243 *
244 * @return int Exit code (1 = error, 0 = success)
245 */
246 // int note_list::rm( string note_name ) {
247 // int id = find_note_id( note_name );
248 // if( id == -1 ) {
249 // cout << "Note \"" << note_name << "\" does not exist." << endl;
250 // return 1;
251 // } else {
252 // notes[id].rm();
253 // }
254 // return 0;
255 // }
256
257 /**
258 * TODO
259 */
260 // int note_list_find(note_list_t* list, int case_sensitive, char* term ) {
261 // for(int i = 0; i < notes.size(); i++) {
262 // vector<string> note_matches = notes[i].find( case_sensitive, term );
263 // if( note_matches.size() > 0 ) {
264 // for( int m = 0; m < note_matches.size(); m++ ) {
265 // matches.push_back( note_matches[m] );
266 // }
267 // }
268 // }
269 // return matches;
270 // }
|