2019-07-19 13:51:57 -07:00
let db = require ( '@config/database' )
2019-07-30 12:21:12 -07:00
let Tags = require ( '@models/Tag' )
2019-07-24 11:06:50 -07:00
let Attachment = require ( '@models/Attachment' )
var rp = require ( 'request-promise' ) ;
var SolrNode = require ( 'solr-node' ) ;
2019-07-30 12:21:12 -07:00
let Note = module . exports = { }
2019-07-24 11:06:50 -07:00
// Create client
var client = new SolrNode ( {
host : '127.0.0.1' ,
port : '8983' ,
core : 'note' ,
protocol : 'http'
} ) ;
2019-07-19 13:51:57 -07:00
2019-07-30 12:21:12 -07:00
Note . create = ( userId , noteText ) => {
2019-07-19 13:51:57 -07:00
return new Promise ( ( resolve , reject ) => {
2019-07-24 11:06:50 -07:00
if ( userId == null || userId < 10 ) { reject ( 'User Id required to create note' ) }
2019-07-20 16:07:22 -07:00
const created = Math . round ( ( + new Date ) / 1000 )
2019-07-19 13:51:57 -07:00
db . promise ( )
2019-07-30 13:27:26 -07:00
. query ( 'INSERT INTO note (user_id, text, created) VALUES (?,?,?)' , [ userId , noteText , created ] )
2019-07-19 13:51:57 -07:00
. then ( ( rows , fields ) => {
resolve ( rows [ 0 ] . insertId ) //Only return the new note ID when creating a new note
} )
. catch ( console . log )
} )
}
2019-07-30 12:21:12 -07:00
Note . update = ( userId , noteId , noteText , fancyInput , color ) => {
2019-07-19 13:51:57 -07:00
return new Promise ( ( resolve , reject ) => {
2019-07-20 16:07:22 -07:00
const now = Math . round ( ( + new Date ) / 1000 )
2019-07-19 13:51:57 -07:00
db . promise ( )
2019-07-30 13:27:26 -07:00
. query ( 'UPDATE note SET text = ?, raw_input = ?, updated = ?, color = ? WHERE id = ? AND user_id = ? LIMIT 1' , [ noteText , fancyInput , now , color , noteId , userId ] )
2019-07-19 13:51:57 -07:00
. then ( ( rows , fields ) => {
2019-07-24 11:06:50 -07:00
//Process note text and attachment data
Attachment . scanTextForWebsites ( userId , noteId , noteText ) . then ( attachmentText => {
//
// Update Solr index
//
Tags . string ( userId , noteId ) . then ( tagString => {
// JSON Data
var data = {
'id' : noteId , //string - ID of note
'user_id' : userId , //int
'note_text' : noteText ,
2019-07-30 13:27:26 -07:00
'note_tag' : tagString ,
2019-07-24 11:06:50 -07:00
'attachment_text' : attachmentText ,
} ;
// Update document to Solr server
client . update ( data , function ( err , result ) {
if ( err ) { console . log ( err ) ; return ; }
console . log ( 'Note Solr Update, node/solrid (' + noteId + '):' ) ;
console . log ( result . responseHeader )
} ) ;
} )
} )
//Send back updated response
2019-07-19 13:51:57 -07:00
resolve ( rows [ 0 ] )
} )
. catch ( console . log )
} )
}
2019-07-30 12:21:12 -07:00
Note . delete = ( userId , noteId ) => {
2019-07-19 13:51:57 -07:00
return new Promise ( ( resolve , reject ) => {
2019-07-30 13:27:26 -07:00
db . promise ( ) . query ( 'DELETE FROM note WHERE note.id = ? AND note.user_id = ?' , [ noteId , userId ] )
2019-07-29 00:22:47 -07:00
. then ( ( rows , fields ) => {
db . promise ( ) . query ( 'DELETE FROM attachment WHERE attachment.note_id = ? AND attachment.user_id = ?' , [ noteId , userId ] )
. then ( ( rows , fields ) => {
2019-07-30 13:27:26 -07:00
db . promise ( ) . query ( 'DELETE FROM note_tag WHERE note_tag.note_id = ? AND note_tag.user_id = ?' , [ noteId , userId ] )
2019-07-29 00:22:47 -07:00
. then ( ( rows , fields ) => {
resolve ( true )
} )
} )
} )
2019-07-19 13:51:57 -07:00
} )
}
2019-07-30 12:21:12 -07:00
Note . get = ( userId , noteId ) => {
2019-07-19 13:51:57 -07:00
return new Promise ( ( resolve , reject ) => {
db . promise ( )
2019-07-30 13:27:26 -07:00
. query ( 'SELECT text, updated, raw_input, color FROM note WHERE user_id = ? AND id = ? LIMIT 1' , [ userId , noteId ] )
2019-07-19 13:51:57 -07:00
. then ( ( rows , fields ) => {
resolve ( rows [ 0 ] [ 0 ] )
} )
. catch ( console . log )
} )
}
2019-07-30 12:21:12 -07:00
Note . solrQuery = ( userId , searchQuery , searchTags ) => {
2019-07-19 13:51:57 -07:00
return new Promise ( ( resolve , reject ) => {
2019-07-24 11:06:50 -07:00
if ( searchQuery != '' && searchQuery != null ) {
let urlQuery = ` /solr/note/select?hl.fl=note_text&hl=on&q=user_id: ${ userId } AND note_text: ${ searchQuery } &wt=json `
urlQuery = ` /solr/note/select?
2019-07-30 13:27:26 -07:00
hl . fl = note _text , attachment _text , note _tag &
2019-07-24 11:06:50 -07:00
hl = on &
2019-07-30 13:27:26 -07:00
q = user _id : $ { userId } AND ( note _text : $ { searchQuery } OR attachment _text : $ { searchQuery } OR note _tag : $ { searchQuery } ) &
2019-07-24 11:06:50 -07:00
wt = json &
fl = id &
2019-07-30 13:27:26 -07:00
hl . fl = note _text , attachment _text , note _tag &
2019-07-24 11:06:50 -07:00
hl . snippets = 20 &
hl . maxAnalyzedChars = 100000 `
rp ( 'http://127.0.0.1:8983' + urlQuery )
. then ( function ( htmlString ) {
let solrResult = JSON . parse ( htmlString )
resolve ( solrResult )
} )
} else {
resolve ( [ ] )
2019-07-19 13:51:57 -07:00
}
2019-07-24 11:06:50 -07:00
} )
}
2019-07-19 13:51:57 -07:00
2019-07-30 12:21:12 -07:00
Note . search = ( userId , searchQuery , searchTags ) => {
2019-07-24 11:06:50 -07:00
return new Promise ( ( resolve , reject ) => {
2019-07-19 13:51:57 -07:00
//Define return data objects
let returnData = {
'notes' : [ ] ,
'tags' : [ ]
}
2019-07-30 12:21:12 -07:00
Note . solrQuery ( userId , searchQuery , searchTags ) . then ( solrResult => {
2019-07-24 11:06:50 -07:00
let highlights = solrResult . highlighting
//Parse Note ID's from solr search
let solrNoteIds = [ ]
if ( solrResult . response ) {
solrResult . response . docs . forEach ( item => {
solrNoteIds . push ( parseInt ( item . id ) )
} )
}
//Default note lookup gets all notes
let noteSearchQuery = `
2019-07-30 13:27:26 -07:00
SELECT note . id ,
SUBSTRING ( note . text , 1 , 400 ) as text ,
updated , color ,
count ( distinct note _tag . id ) as tag _count ,
count ( distinct attachment . id ) as attachment _count
FROM note
LEFT JOIN note _tag ON ( note . id = note _tag . note _id )
LEFT JOIN attachment ON ( note . id = attachment . note _id AND attachment . attachment _type = 1 )
WHERE note . user _id = ? `
2019-07-24 11:06:50 -07:00
let searchParams = [ userId ]
if ( solrNoteIds . length > 0 ) {
searchParams . push ( solrNoteIds )
2019-07-30 13:27:26 -07:00
noteSearchQuery += ' AND note.id IN (?)'
2019-07-24 11:06:50 -07:00
}
// if(searchQuery != ''){
// //If a search query is defined, search notes for that word
// searchParams.push('%'+searchQuery+'%')
// noteSearchQuery += ' AND text LIKE ?'
// }
if ( searchTags . length > 0 ) {
//If tags are passed, use those tags in search
searchParams . push ( searchTags )
2019-07-30 13:27:26 -07:00
noteSearchQuery += ' AND note_tag.tag_id IN (?)'
2019-07-19 13:51:57 -07:00
}
2019-07-24 11:06:50 -07:00
//Finish up note query
2019-07-30 13:27:26 -07:00
noteSearchQuery += ' GROUP BY note.id ORDER BY updated DESC, created DESC, id DESC'
2019-07-24 11:06:50 -07:00
2019-07-19 13:51:57 -07:00
db . promise ( )
2019-07-24 11:06:50 -07:00
. query ( noteSearchQuery , searchParams )
. then ( ( noteRows , noteFields ) => {
//Push all notes
returnData [ 'notes' ] = noteRows [ 0 ]
//pull out all note ids so we can fetch all tags for those notes
let noteIds = [ ]
returnData [ 'notes' ] . forEach ( note => {
//Grab note ID for finding tags
noteIds . push ( note . id )
//Attempt to pull string out of first tag in note
2019-07-29 00:22:47 -07:00
let reg = note . text . match ( /<([\w]+)[^>]*>(.*?)<\/\1>/g )
//Pull out first html tag contents, that is the title
if ( reg != null && reg [ 0 ] ) {
note . title = reg [ 0 ] //First line from HTML
} else {
note . title = note . text //Entire note
2019-07-24 11:06:50 -07:00
}
2019-07-29 00:22:47 -07:00
//Clean up html title
note . title = note . title
2019-07-24 11:06:50 -07:00
. replace ( /&[#A-Za-z0-9]+;/g , '' ) //Rip out all HTML entities
. replace ( /<[^>]+>/g , '' ) //Rip out all HTML tags
2019-07-29 00:22:47 -07:00
//Generate Subtext
2019-07-30 12:10:31 -07:00
note . subtext = ''
2019-07-29 00:22:47 -07:00
if ( note . text != '' && note . title != '' ) {
note . subtext = note . text
. replace ( /&[#A-Za-z0-9]+;/g , ' ' ) //Rip out all HTML entities
. replace ( /<[^>]+>/g , ' ' ) //Rip out all HTML tags
. replace ( /\s+/g , ' ' ) //Remove all whitespace
. substring ( note . title . length + 2 )
}
2019-07-24 11:06:50 -07:00
note . note _highlights = [ ]
note . attachment _highlights = [ ]
note . tag _highlights = [ ]
//Push in solr highlights
if ( highlights && highlights [ note . id ] && highlights [ note . id ] . note _text ) {
note [ 'note_highlights' ] = highlights [ note . id ] . note _text
}
if ( highlights && highlights [ note . id ] && highlights [ note . id ] . attachment _text ) {
note [ 'attachment_highlights' ] = highlights [ note . id ] . attachment _text
}
2019-07-30 13:27:26 -07:00
if ( highlights && highlights [ note . id ] && highlights [ note . id ] . note _tag ) {
note [ 'tag_highlights' ] = highlights [ note . id ] . note _tag
2019-07-24 11:06:50 -07:00
}
2019-07-30 12:10:31 -07:00
//Clear out note.text before sending it to front end
delete note . text
2019-07-24 11:06:50 -07:00
} )
//If no notes are returned, there are no tags, return empty
if ( noteIds . length == 0 ) {
resolve ( returnData )
}
//Only show tags of selected notes
db . promise ( )
2019-07-30 13:27:26 -07:00
. query ( ` SELECT tag.id, tag.text, count(tag.id) as usages FROM note_tag
JOIN tag ON ( tag . id = note _tag . tag _id )
WHERE note _tag . user _id = ?
2019-07-24 11:06:50 -07:00
AND note _id IN ( ? )
2019-07-30 13:27:26 -07:00
GROUP BY tag . id
2019-07-24 11:06:50 -07:00
ORDER BY usages DESC ; ` ,[userId, noteIds])
. then ( ( tagRows , tagFields ) => {
returnData [ 'tags' ] = tagRows [ 0 ]
2019-07-19 13:51:57 -07:00
2019-07-24 11:06:50 -07:00
resolve ( returnData )
} )
. catch ( console . log )
2019-07-19 13:51:57 -07:00
} )
. catch ( console . log )
} )
. catch ( console . log )
2019-07-24 11:06:50 -07:00
2019-07-19 13:51:57 -07:00
} )
}