summaryrefslogtreecommitdiff
path: root/src/lib/note.cpp
blob: dac08ea962405585f9c5cfbddeb1351e26cef3a1 (plain)
    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.h"
   18 
   19 /**
   20  * Creates a new empty note object since no filename was specified.
   21  */
   22 note::note( path p ) {
   23   _path = p;
   24   name = _path.filename;
   25   extension = get_extension();
   26 }
   27 
   28 /**
   29  * Creates a new empty note object since no filename was specified.
   30  */
   31 note::note( string p ) {
   32   path tmp_path( p );
   33   _path = tmp_path;
   34   name = _path.filename;
   35   extension = get_extension();
   36 }
   37 
   38 /**
   39  * Creates a new empty note object since no filename was specified.
   40  */
   41 note::note( string base, string note_name ) {
   42   path tmp_path( base + "/" + note_name );
   43   _path = tmp_path;
   44   name = note_name;
   45   extension = get_extension();
   46 }
   47 
   48 /**
   49  * Opens a new note using the specified editor.
   50  *
   51  * @param string editor Path to the editor binary to use for editing.
   52  *
   53  * @return int Success or failure of the command
   54  */
   55 int note::create( string editor ) {
   56   return edit( editor );
   57 }
   58 
   59 /**
   60  * Opens a note using the specified editor
   61  *
   62  * @param string editor Path to the editor binary to use for editing.
   63  *
   64  * @return int Success or failure of the command
   65  */
   66 int note::edit( string editor ) {
   67   string cmd = editor;
   68   cmd += " ";
   69   cmd += _path.out();
   70   return system( cmd.c_str() );
   71 }
   72 
   73 /**
   74  * Converts a 1 digit integer to a single char equivelant
   75  *
   76  * @param int i The integer to be converted
   77  *
   78  * @return char The char equivelent of the int argument
   79  */
   80 const char note::itoc( int i ) {
   81   if( i == 0 ) {
   82     return '0';
   83   } else if( i == 1 ) {
   84     return '1';
   85   } else if( i == 2 ) {
   86     return '2';
   87   } else if( i == 3 ) {
   88     return '3';
   89   } else if( i == 4 ) {
   90     return '4';
   91   } else if( i == 5 ) {
   92     return '5';
   93   } else if( i == 6 ) {
   94     return '6';
   95   } else if( i == 7 ) {
   96     return '7';
   97   } else if( i == 8 ) {
   98     return '8';
   99   } else if( i == 9 ) {
  100     return '9';
  101   }
  102 }
  103 
  104 /**
  105  * Converts an integer into a string
  106  *
  107  * @param int i - Integer to be converted
  108  *
  109  * @return string String equivelent of integer argument
  110  */
  111 string note::itos( int i ) {
  112   string str = "";
  113   // Since we don't want any black holes, return 0 without trying to divide by
  114   // 10.
  115   if( i == 0 ) {
  116     return "0";
  117   }
  118   while( i != 0 ) {
  119     str = itoc( i % 10 ) + str;
  120     i /= 10;
  121   }
  122   return str;
  123 }
  124 
  125 /**
  126  * Reads in the contents of the note. This exists so we don't have to keep
  127  * writing the file open, check, get line, blah blah blah repeatedly.
  128  *
  129  * @return void
  130  */
  131 void note::read() {
  132   // Don't do this unless body hasn't already been read
  133   if( body.size() == 0 ) {
  134     // Open the file
  135     ifstream fs( _path.out().c_str() );
  136 
  137     // Verify the file handle opened sucessfully
  138     if( ! fs.is_open() ) {
  139       cout << "Could not open file at " << _path.out() << "." << endl;
  140       exit( 1 );
  141     }
  142 
  143     string line;
  144     while( getline( fs, line ) ) {
  145       body.push_back( line );
  146     }
  147     fs.close();
  148   }
  149 }
  150 
  151 /**
  152  * Returns the current localtime. Useful for "random" non-conflicting
  153  * filenames.
  154  *
  155  * @return string The current date time in format YYYYMMDD.HHMMSS.
  156  */
  157 string note::get_current_date_time() {
  158   string date;
  159   time_t rawtime;
  160   time( &rawtime );
  161   struct tm* now = localtime( &rawtime );
  162 
  163   // Date
  164   // Year
  165   int year = now->tm_year + 1900;
  166   date += itos( year );
  167   // Month
  168   int mon = now->tm_mon + 1;
  169   if( mon < 10 ) { date += "0"; }
  170   date += itos( mon );
  171   // Day
  172   int day = now->tm_mday;
  173   if( day < 10 ) { date += "0"; }
  174   date += itos( day );
  175 
  176   date += ".";
  177 
  178   // Time
  179   // Hour
  180   int hour = now->tm_hour;
  181   if( hour < 10 ) { date += "0"; }
  182   date += itos( hour );
  183   // Minute
  184   int min = now->tm_min;
  185   if( min < 10 ) { date += "0"; }
  186   date += itos( min );
  187   // Second
  188   int sec = now->tm_sec;
  189   if( sec < 10 ) { date += "0"; }
  190   date += itos( sec );
  191 
  192   return date;
  193 }
  194 
  195 /**
  196  * Parses the current instance filename to determine its extension.
  197  * 
  198  * @return string The filename. Null pointer if file has no extension.
  199  */
  200 string note::get_extension() {
  201   string ext;
  202   // Iterrate from the right to the left. This will keep us from catching
  203   // filenames with multiple periods in them.
  204   for( int i = name.length(); i > 0; i-- ) {
  205     // Determine the index 
  206     if( name[i] == '.' ) {
  207       // Increment so we don't get the period
  208       i++;
  209       ext = name.substr( i, name.length() - i );
  210       break;
  211     }
  212   }
  213   return ext;
  214 }
  215 
  216 /**
  217  * Gets the filename of the current note instance without its extension.
  218  *
  219  * @return string Note filename without extension
  220  */
  221 string note::friendly_name() {
  222   return name.substr( 0, name.length() - extension.length() - 1 ); 
  223 }
  224 
  225 /**
  226  * TODO
  227  */
  228 vector<string> note::find( bool case_sensitive, string term ) {
  229   vector<string> lines;
  230 
  231   // Memory for storing matched lines
  232   vector<string> matches;
  233 
  234   // Read the notes contents into memory
  235   read();
  236 
  237   for( int i = 0; i < body.size(); i++ ) {
  238     if( line_matches( body[i], term ) == true ) {
  239       // Format the output
  240       string out = friendly_name() + ": " + itos( i );
  241       out += ": " + body[i];
  242       // Add to the match list
  243       matches.push_back( out );
  244     }
  245   }
  246   return matches;
  247 }
  248 
  249 /**
  250  * Performs a char by char comparison of a line and a search term. If the
  251  * search term is found anywhere within the line even once, returns true;
  252  * Otherwise, returns false.
  253  *
  254  * @param string line The line of text to search
  255  * @param string term The search term
  256  *
  257  * @return bool Whether or not the search term was found in the line
  258  */
  259 bool note::line_matches( string line, string term ) {
  260   // Define the two long arrays
  261   long line_l[line.size()];
  262   long term_l[term.size()];
  263 
  264   // Convert the line to a long array
  265   for( int i = 0; i < line.size(); i++ ) { line_l[i] = line[i]; }
  266 
  267   // Convert the search term to a long array
  268   for( int i = 0; i < term.size(); i++ ) { term_l[i] = term[i]; }
  269 
  270 
  271   // Iterrate through each letter in the line
  272   for( int l = 0; l < line.size(); l++ ) {
  273     // Iterrate through the search term
  274     for( int t = 0; t < term.size(); t++ ) {
  275       if( term_l[t] >= 97 && term_l[t] <= 122 )  {
  276         // Term char is lower. Compare down then up
  277         if( line_l[l] != term_l[t]
  278         && line_l[l] != term_l[t] - 32 ) {
  279           break;
  280         }
  281       } else if( term_l[t] >= 65 && term_l[t] <= 90 ) {
  282         // Term char is upper. Compare up then down
  283         if( line_l[l] != term_l[t]
  284         && line_l[l] != term_l[t] + 32 ) {
  285           break;
  286         }
  287       } else {
  288         // Term char isn't a letter. Must be a symbol or something ELSE...
  289         // Teehee
  290         if( line_l[l] != term_l[t] ) { break; }
  291       }
  292 
  293       // Increment the line letter to check the next one on the next search
  294       // term letter loop
  295       l++;
  296       // If we reach the end of the search term, match!
  297       if( t == term.size() - 1 ) { return true; }
  298     }
  299   }
  300   return false;
  301 }

Generated by cgit