Find files with full text search

James Peret 8 years ago
parent
commit
35927394ee

+ 10 - 0
app/index.html

@@ -31,10 +31,12 @@
31 31
     <script src="scripts/controllers/note-view-ctrl.js"></script>
32 32
     <script src="scripts/controllers/note-edit-ctrl.js"></script>
33 33
     <script src="scripts/services/file-service.js"></script>
34
+    <script src="scripts/services/search-service.js"></script>
34 35
     <script src="scripts/services/thumbnail-service.js"></script>
35 36
     <script src="scripts/services/prefs-service.js"></script>
36 37
     <script src="scripts/services/date-formatter.js" charset="utf-8"></script>
37 38
     <script src="scripts/directives/right-click-directive.js"></script>
39
+    <script src="scripts/directives/ng-enter.js"></script>
38 40
 
39 41
 
40 42
 
@@ -218,6 +220,14 @@
218 220
             </button>
219 221
           </div>
220 222
 
223
+          <div class="btn-group pull-right">
224
+            <form>
225
+              <div class="form-group">
226
+                <input type="text" ng-model="search_text" ng-enter="fileSearch()" class="form-control" placeholder="Search" style="height: 24px;">
227
+              </div>
228
+            </form>
229
+          </div>
230
+
221 231
         </div>
222 232
       </header>
223 233
 

+ 5 - 1
app/scripts/controllers/app-ctrl.js

@@ -33,7 +33,11 @@ angular.module('codexApp.index', [])
33 33
             break;
34 34
           case "Notebook":
35 35
             $scope.files = FileService.getFiles(FileService.getCurrentNote().path);
36
-
36
+            var info = $scope.files.length + " Items"
37
+            $rootScope.$broadcast('footer:info', info);
38
+            break;
39
+          case "Searched Files":
40
+            $scope.files = FileService.getSearchFiles();
37 41
             var info = $scope.files.length + " Items"
38 42
             $rootScope.$broadcast('footer:info', info);
39 43
             break;

+ 15 - 1
app/scripts/controllers/header-ctrl.js

@@ -8,7 +8,7 @@
8 8
  * Controller of the domainManagerApp
9 9
  */
10 10
 angular.module('codexApp.header', [])
11
-  .controller('HeaderCtrl',['$scope', '$rootScope', '$state', 'FileService', function ($scope,  $rootScope, $state, FileService) {
11
+  .controller('HeaderCtrl',['$scope', '$rootScope', '$state', 'FileService', 'SearchService', 'PrefsService', function ($scope,  $rootScope, $state, FileService, SearchService, PrefsService) {
12 12
 
13 13
     console.log('-> Header loaded')
14 14
 
@@ -113,4 +113,18 @@ angular.module('codexApp.header', [])
113 113
       }
114 114
     });
115 115
 
116
+    // Search Functions
117
+
118
+    SearchService.init();
119
+    $scope.fileSearch = function(){
120
+      console.log("> SEARCHING: " + $scope.search_text);
121
+      var results = SearchService.search($scope.search_text);
122
+      FileService.setSearchedFiles(results);
123
+      PrefsService.setCurrentView("Searched Files");
124
+      //$scope.activateSidebarBtn(0);
125
+      $rootScope.$broadcast('main-window:note-list');
126
+      $rootScope.$broadcast('window-view:change');
127
+      $state.go("index");
128
+    }
129
+
116 130
   }]);

+ 14 - 0
app/scripts/directives/ng-enter.js

@@ -0,0 +1,14 @@
1
+angular.module('codexApp')
2
+.directive('ngEnter', function() {
3
+        return function(scope, element, attrs) {
4
+            element.bind("keydown keypress", function(event) {
5
+                if(event.which === 13) {
6
+                        scope.$apply(function(){
7
+                                scope.$eval(attrs.ngEnter);
8
+                        });
9
+
10
+                        event.preventDefault();
11
+                }
12
+            });
13
+        };
14
+});

+ 10 - 1
app/scripts/services/file-service.js

@@ -5,6 +5,7 @@ angular.module('codexApp')
5 5
   var appDataPath = "";
6 6
   var appData = {};
7 7
   var notes_dir = "";
8
+  var searched_files = [];
8 9
 
9 10
   var getAppData = function(){
10 11
     var remote = require('remote');
@@ -144,7 +145,7 @@ angular.module('codexApp')
144 145
               break;
145 146
           }
146 147
         }
147
-        console.log(thumb);
148
+        //console.log(thumb);
148 149
         if(thumb == "" || thumb == undefined){
149 150
           console.log("> NO THUMBNAIL FOUND! GENERATING NEW ONE")
150 151
           thumb = saveThumbnail(file_path);
@@ -592,4 +593,12 @@ angular.module('codexApp')
592 593
     return saveThumbnail(file_path);
593 594
   }
594 595
 
596
+  this.setSearchedFiles = function(files){
597
+    searched_files = files;
598
+  }
599
+
600
+  this.getSearchFiles = function() {
601
+    return searched_files;
602
+  }
603
+
595 604
 }])

+ 63 - 0
app/scripts/services/search-service.js

@@ -0,0 +1,63 @@
1
+angular.module('codexApp')
2
+.service('SearchService', [ '$rootScope', '$http', 'ThumbnailService', '$state', 'FileService',  function($rootScope, $http, ThumbnailService, $state, FileService) {
3
+
4
+  var fs = require('fs');
5
+
6
+  var fulltextsearchlight = require('full-text-search-light');
7
+  var search = new fulltextsearchlight();
8
+  var appDataPath = FileService.getAppDataPath();
9
+
10
+  this.init = function() {
11
+    // Load db
12
+    fulltextsearchlight.load(appDataPath + '/search.json', function(error, search_loaded){
13
+      if(error){
14
+        console.log("> SEARCH DB NOT FOUND!")
15
+        console.log(error)
16
+        search.save(appDataPath + '/search.json', function(error){
17
+          console.log("> CREATING SEARCH DB")
18
+          buildSearchDB();
19
+          console.log("> NEW SEARCH DB CREATED")
20
+        });
21
+      }
22
+      else {
23
+        search = search_loaded
24
+        console.log("> SEARCH DB LOADED");
25
+      }
26
+    });
27
+  }
28
+
29
+  this.search = function(search_text) {
30
+    var results = search.search(search_text)
31
+    console.log("> FOUND " + results.length + " RESULTS");
32
+    return results
33
+  }
34
+
35
+  var buildSearchDB = function() {
36
+    var parsed_files = []
37
+    var all_files = FileService.getAllFiles();
38
+    for (var i = 0; i < all_files.length; i++) {
39
+      file = all_files[i]
40
+      var file_data = {
41
+        path: file.path,
42
+        title: file.title,
43
+        type: file.type
44
+      }
45
+      if(file.type == "Markdown"){
46
+        var raw_data = fs.readFileSync(file.path, 'utf8');
47
+        var data = new Buffer(raw_data).toString('utf8')
48
+        console.log(file);
49
+        file_data.content = data;
50
+        file_data.thumbnail = file.thumbnail;
51
+      }
52
+      parsed_files.push(file_data);
53
+    }
54
+    for (var i = 0; i < parsed_files.length; i++) {
55
+      console.log(parsed_files[i].title);
56
+      search.add(parsed_files[i]);
57
+    }
58
+    search.save(appDataPath + '/search.json', function(error){
59
+      console.log("> SEARCH DB SAVED")
60
+    });
61
+  }
62
+
63
+}])

+ 1 - 0
package.json

@@ -23,6 +23,7 @@
23 23
   ],
24 24
   "dependencies": {
25 25
     "electron-debug": "^0.2.1",
26
+    "full-text-search-light": "0.0.16",
26 27
     "marked": "^0.3.5"
27 28
   },
28 29
   "devDependencies": {