1+ const emitStream = require ( 'emit-stream' )
2+ const { URL } = require ( 'url' )
13const _throttle = require ( 'lodash.throttle' )
24const lock = require ( '../lib/lock' )
35const db = require ( '../dbs/profile-data-db' )
6+ const archivesDb = require ( '../dbs/archives' )
47const users = require ( '../users' )
58const dat = require ( '../dat' )
69
10+ const { crawlerEvents} = require ( './util' )
711const posts = require ( './posts' )
812const followgraph = require ( './followgraph' )
913const siteDescriptions = require ( './site-descriptions' )
@@ -21,6 +25,7 @@ const watches = {}
2125exports . posts = posts
2226exports . followgraph = followgraph
2327exports . siteDescriptions = siteDescriptions
28+ const createEventsStream = exports . createEventsStream = ( ) => emitStream ( crawlerEvents )
2429
2530exports . setup = async function ( ) {
2631}
@@ -32,6 +37,7 @@ exports.watchSite = async function (archive) {
3237 console . log ( 'watchSite' , archive . url )
3338
3439 if ( ! ( archive . url in watches ) ) {
40+ crawlerEvents . emit ( 'watch' , { sourceUrl : archive . url } )
3541 const queueCrawl = _throttle ( ( ) => crawlSite ( archive ) , 5e3 )
3642
3743 // watch for file changes
@@ -57,6 +63,7 @@ exports.watchSite = async function (archive) {
5763exports . unwatchSite = async function ( url ) {
5864 // stop watching for file changes
5965 if ( url in watches ) {
66+ crawlerEvents . emit ( 'unwatch' , { sourceUrl : url } )
6067 watches [ url ] . close ( )
6168 watches [ url ] = null
6269 }
@@ -65,6 +72,7 @@ exports.unwatchSite = async function (url) {
6572const crawlSite =
6673exports . crawlSite = async function ( archive ) {
6774 console . log ( 'crawling' , archive . url )
75+ crawlerEvents . emit ( 'crawl-start' , { sourceUrl : archive . url } )
6876 var release = await lock ( 'crawl:' + archive . url )
6977 try {
7078 // get/create crawl source
@@ -80,7 +88,49 @@ exports.crawlSite = async function (archive) {
8088 followgraph . crawlSite ( archive , crawlSource ) ,
8189 siteDescriptions . crawlSite ( archive , crawlSource )
8290 ] )
91+ } catch ( err ) {
92+ crawlerEvents . emit ( 'crawl-error' , { sourceUrl : archive . url , err : err . toString ( ) } )
8393 } finally {
94+ crawlerEvents . emit ( 'crawl-finish' , { sourceUrl : archive . url } )
8495 release ( )
8596 }
86- }
97+ }
98+
99+ const getCrawlStates =
100+ exports . getCrawlStates = async function ( ) {
101+ var rows = await db . all ( `
102+ SELECT
103+ crawl_sources.url AS url,
104+ GROUP_CONCAT(crawl_sources_meta.crawlSourceVersion) AS versions,
105+ GROUP_CONCAT(crawl_sources_meta.crawlDataset) AS datasets,
106+ MAX(crawl_sources_meta.updatedAt) AS updatedAt
107+ FROM crawl_sources
108+ INNER JOIN crawl_sources_meta ON crawl_sources_meta.crawlSourceId = crawl_sources.id
109+ GROUP BY crawl_sources.id
110+ ` )
111+ return Promise . all ( rows . map ( async ( { url, versions, datasets, updatedAt} ) => {
112+ var datasetVersions = { }
113+ versions = versions . split ( ',' )
114+ datasets = datasets . split ( ',' )
115+ for ( let i = 0 ; i < datasets . length ; i ++ ) {
116+ datasetVersions [ datasets [ i ] ] = Number ( versions [ i ] )
117+ }
118+ var meta = await archivesDb . getMeta ( toHostname ( url ) )
119+ return { url, title : meta . title , datasetVersions, updatedAt}
120+ } ) )
121+ }
122+
123+ const resetSite =
124+ exports . resetSite = async function ( url ) {
125+ await db . run ( `DELETE FROM crawl_sources WHERE url = ?` , [ url ] )
126+ }
127+
128+ exports . WEBAPI = { createEventsStream, getCrawlStates, resetSite}
129+
130+ // internal methods
131+ // =
132+
133+ function toHostname ( url ) {
134+ url = new URL ( url )
135+ return url . hostname
136+ }
0 commit comments