1(function(angular) { 2 "use strict"; 3 4 var app = angular.module('search.service.find', []); 5 app.factory('searchService', ['$http', '$rootScope', '$q', function($http, $rootScope, $q){ 6 $rootScope.lastResult = $rootScope.lastResult || { agent:null, space:null, event:null }; 7 var activeRequests = 0, 8 canceler = null, 9 lastEmitedResult = 'null', 10 lastEmitedCountResult = 'null', 11 lastQueries = {enabledEntities: null, space: null, agent: null, event: null, project: null, listedEntity: null, list:null, page: null}; 12 13 $rootScope.spinnerCount = $rootScope.spinnerCount || 0; 14 15 $rootScope.$on('searchDataChange', search); 16 $rootScope.$on('resultPagination', search); 17 18 $rootScope.searchArgs = { 19 list: {}, 20 map: {} 21 }; 22 23 function search (ev, data){ 24 25 var results = {}, 26 numRequests = 0, 27 numSuccessRequests = 0, 28 numCountRequests = 0, 29 numCountSuccessRequests = 0, 30 countResults = {}, 31 paginating = ev.name === 'resultPagination'; 32 33 34 if(!paginating){ 35 $rootScope.resetPagination(); 36 } 37 38 var activeEntity = data.global.filterEntity; 39 var entities = ['space', 'event', 'agent']; 40 if(data.global.viewMode === 'map'){ 41 var compareEnabledEntities = angular.equals(lastQueries.enabledEntities, data.global.enabled); 42 var entityQueryData = {}; 43 44 // adiciona os filtros avançados utilizados pelo tema ao skeleton acima 45 entities.forEach(function(entity){ 46 if(data.global.enabled[entity]) { 47 entityQueryData = data2searchData(entity, data[entity]); 48 if(!angular.equals(entityQueryData, lastQueries[entity]) || !compareEnabledEntities){ 49 lastQueries[entity] = angular.copy(entityQueryData); 50 callApi(entity, entityQueryData); 51 }else{ 52 results[entity] = $rootScope.lastResult[entity]; 53 } 54 55 if(entity !== lastQueries.listedEntity) 56 $rootScope.pagination[activeEntity] = 1; 57 } 58 }); 59 60 lastQueries.enabledEntities = angular.copy(data.global.enabled); 61 }else{ 62 63 var listQueryData = data2searchData(activeEntity, data[activeEntity]); 64 65 if(activeEntity !== lastQueries.listedEntity) 66 $rootScope.pagination[activeEntity] = 1; 67 68 var isDiff = (paginating && $rootScope.pagination[activeEntity] !== lastQueries.page) || (!angular.equals(listQueryData, lastQueries.list) || lastQueries.listedEntity !== activeEntity); 69 70 if( isDiff ){ 71 $rootScope.isPaginating = true; 72 lastQueries.listedEntity = activeEntity; 73 lastQueries.list = angular.copy(listQueryData); 74 callApi(activeEntity, angular.copy(listQueryData)); 75 }else{ 76 $rootScope.isPaginating = false; 77 } 78 } 79 80 endCountRequest(); 81 endRequest(); 82 83 function callApi(entity, sData){ 84 85 var requestEntity = entity, 86 requestAction = 'find'; 87 88 if(entity === 'event'){ 89 if(data.global.viewMode === 'list'){ 90 requestAction = 'findByLocation'; 91 }else{ 92 requestEntity = 'space' ; 93 requestAction = 'findByEvents'; 94 } 95 96 } 97 98 $rootScope.searchArgs[data.global.viewMode][entity] = sData; 99 100 101 //Counting XX events in YY spaces (events in map mode) 102 if(requestEntity === 'space' && requestAction === 'findByEvents'){ 103 104 var otherRequestEntity = 'event'; 105 var otherRequestAction = 'findByLocation'; 106 107 numCountRequests++; 108 activeRequests++; 109 $rootScope.spinnerCount++; 110 111 countResults['event'] = {}; 112 113 apiCount(otherRequestEntity, sData, otherRequestAction).success(function(rs){ 114 numCountSuccessRequests++; 115 activeRequests--; 116 $rootScope.spinnerCount--; 117 118 countResults['event'].events = rs; 119 endCountRequest(); 120 }); 121 122 } 123 124 numRequests++; 125 activeRequests++; 126 $rootScope.spinnerCount++; 127 128 apiFind(requestEntity, sData, $rootScope.pagination[entity], requestAction).success(function(rs,status,header){ 129 var metadata = JSON.parse(header('API-Metadata')); 130 131 numSuccessRequests++; 132 activeRequests--; 133 $rootScope.spinnerCount--; 134 135 results[entity] = rs; 136 137 endRequest(); 138 139 if(requestEntity === 'space' && requestAction === 'findByEvents') { 140 countResults[entity].spaces = metadata.count; 141 }else if(requestEntity === 'event' && requestAction === 'findByLocation' && metadata == null){ 142 countResults['event'] = 0; 143 }else{ 144 countResults[entity] = metadata.count; 145 } 146 numCountSuccessRequests++; 147 numCountRequests++; 148 endCountRequest(); 149 }); 150 151 } 152 153 function countAndRemoveResultsNotInMap(entity, results){
154 results[entity].forEach(function(item, index) { 155 if (!item.location || (item.location.latitude == 0 && item.location.longitude == 0)) { 156 $rootScope.resultsNotInMap[entity]++; 157 } 158 }); 159 } 160 161 function endRequest(){ 162 if(numRequests > 0 && numSuccessRequests === numRequests && lastEmitedResult !== JSON.stringify(results)){ 163 if(data.global.viewMode === 'map') { 164 $rootScope.resultsNotInMap = {agent: 0, space: 0, event: 0}; 165 if(results.agent) { 166 countAndRemoveResultsNotInMap('agent', results); 167 } 168 if(results.space) { 169 countAndRemoveResultsNotInMap('space', results); 170 } 171 if(results.event) { 172 countAndRemoveResultsNotInMap('event', results); 173 } 174 } 175 176 lastEmitedResult = JSON.stringify(results); 177 results.paginating = paginating; 178 $rootScope.lastResult = results; 179 $rootScope.$emit('searchResultsReady', results); 180 } 181 } 182 183 function endCountRequest(){ 184 if(numCountRequests > 0 && numCountSuccessRequests === numCountRequests && lastEmitedCountResult !== JSON.stringify(countResults)){ 185 $rootScope.$emit('searchCountResultsReady', countResults); 186 } 187 } 188 189 function data2searchData(entity, entityData){ 190 191 var searchData = {}; 192 193 if(entityData.keyword){ 194 searchData['@keyword'] = entityData.keyword.replace(/ /g,'%25'); 195 } 196 197 for (var search_filter in entityData.filters){ 198 199 if(entityData.from) 200 searchData['@from'] = moment(entityData.from).format('YYYY-MM-DD'); 201 if(entityData.to) 202 searchData['@to'] = moment(entityData.to).format('YYYY-MM-DD'); 203 204 if(entityData.ropen){ 205 var today = moment().format('YYYY-MM-DD HH:mm'); 206 searchData.registrationFrom = 'LTE(' + today + ')'; 207 searchData.registrationTo = 'GTE(' + today + ')'; 208 } 209 210 if(search_filter == 'documento') { 211 searchData['documento'] = entityData.filters['documento']; 212 } 213 if(entityData.filters[search_filter]){ 214 var filter = MapasCulturais.filters[entity].filter(function(f){ 215 return f.filter.param === search_filter; 216 })[0]; 217 if(filter) { 218 if (!filter.isArray) { 219 searchData[filter.prefix + filter.filter.param] = filter.filter.value.replace(/\{val\}/g, entityData.filters[search_filter]); 220 } else if (entityData.filters[search_filter].length){ 221 if (filter.type === 'term'){ 222 var search_value = entityData.filters[search_filter].map(function(e){ 223 return MapasCulturais.taxonomyTerms[filter.filter.param][e] || e; 224 }); 225 searchData['term:'+ filter.prefix + filter.filter.param] = filter.filter.value.replace(/\{val\}/g, search_value.join(',')); 226 } else 227 searchData[filter.prefix + filter.filter.param] = filter.filter.value.replace(/\{val\}/g, entityData.filters[search_filter].join(',')); 228 } 229 } 230 } 231 } 232 233 if(data.global.locationFilters.enabled !== null){ 234 var type = data.global.locationFilters.enabled; 235 var center = data.global.locationFilters[type].center; 236 var radius = data.global.locationFilters[type].radius; 237 searchData._geoLocation = 'GEONEAR(' + center.lng + ',' + center.lat + ',' + radiu
237s + ')'; 238 } 239 if(entityData.sort) { 240 searchData['@order'] = entityData.sort.sortBy + ' ' + entityData.sort.type; 241 } 242 return searchData; 243 } 244 245 function apiFind(entity, searchData, page, action) { 246 if(MapasCulturais.searchFilters && MapasCulturais.searchFilters[entity]){ 247 angular.extend(searchData, MapasCulturais.searchFilters[entity]); 248 } 249 250 var selectData = MapasCulturais.searchQueryFields; 251 252 var apiExportURL = MapasCulturais.baseURL + 'api/'; 253 var exportEntity = entity; 254 if(entity === 'space'){ 255 if(action === 'find') { 256 selectData += ',endereco,acessibilidade'; 257 }else{ 258 exportEntity = 'event'; 259 selectData += ',classificacaoEtaria,project.name,project.singleUrl,occurrences'; 260 apiExportURL += 'event/findByLocation/?'; 261 } 262 }else if (entity === 'project'){ 263 selectData += ',registrationFrom,registrationTo'; 264 }else if(entity === 'event'){ 265 selectData += ',classificacaoEtaria,project.name,project.singleUrl,occurrences.{*,space.{*}}'; 266 } 267 268 if(data.global.viewMode === 'list'){ 269 searchData['@select'] = selectData; 270 searchData['@files'] = '(avatar.avatarMedium):url'; 271 if(page) { 272 searchData['@page'] = page; 273 searchData['@limit'] = '10'; 274 } 275 }else{ 276 searchData['@select'] = 'id,name,location'; 277 } 278 279 action = action || 'find'; 280 delete searchData['@count']; 281 282 var querystring = ''; 283 var Description = MapasCulturais.EntitiesDescription[exportEntity]; 284 var exportSelect = ['singleUrl,isVerified,type,terms']; 285 var dontExportSelect = { 286 user: true, 287 publicLocation: true, 288 status: true, 289 subsite: true, 290 sentNotification: true 291 } 292 Object.keys(Description).forEach(function(prop) { 293 if(prop[0] == '_'){ 294 return; 295 } 296 if (dontExportSelect[prop]) 297 return; 298 299 var def = Description[prop]; 300 var selectProperty = def['@select'] || prop; 301 if(def.isMetadata || (!def.isMetadata && !def.isEntityRelation)){ 302 303 // Não adiciona os metadados geograficos que devem ser ocultos (que começam com "_") 304 if (isRemovableMeta(prop)) 305 return; 306 307 exportSelect.push(selectProperty); 308 } else if(def.isEntityRelation) { 309 if(def.isOwningSide){ 310 exportSelect.push(prop + '.{id,name,singleUrl}'); 311 } else if (prop == 'occurrences') { 312 exportSelect.push('occurrences.{space.{id,name,singleUrl,En_CEP,' + 313 'En_Nome_Logradouro,En_Num,En_Complemento,En_Bairro,En_Municipio,En_Estado},rule}'); 314 } 315 } 316 }); 317 318 var queryString_apiExport = '@select='+exportSelect.join(','); 319 320 //removes type column from event export 321 if(apiExportURL.indexOf('event/findByLocation') !== -1) 322 queryString_apiExport = queryString_apiExport.replace(',type',''); 323 else 324 apiExportURL += entity + '/' + action + '/?'; 325 326 for(var att in searchData) { 327 querystring += "&"+att+"="+searchData[att]; 328 if(att != '@select' && att!='@page' && att!='@limit' && att!='@files') 329 queryString_apiExport += "&"+att+"="+searchData[att]; 330 } 331 332 $rootScope.apiURL = apiExportURL+queryString_apiExport; 333 334 335 336 return $http({method: 'GET', cache:true, url:MapasCulturais.baseURL + 'api/' + entity + '/' + action + '/?'+querystring , data:searchData}); 337 } 338 339 function apiCount(entity, searchData, action) { 340 341 action = action || 'find'; 342 var querystring = ""; 343 344 for(var att in searchData) { 345 querystring += "&"+att+"="+searchData[att]; 346 } 347 return $http({method: 'GET', cache:true, url: MapasCulturais.baseURL + 'api/'+entity+'/' + action + '/?@count=1&'+querystring, data:searchData}); 348 } 349 350 function isRemovableMeta(prop) { 351 var isGeo = prop.substr(0,4) == 'geo_'; 352 var isFva = prop.substr(0,3) == 'fva'; 353 354 return isGeo || isFva; 355 } 356 } 357 358 return 'done'; 359 }]); 360 361})(angular); 362 363 364 365
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.