1
0
mirror of https://github.com/xuthus83/pigallery2.git synced 2025-01-14 14:43:17 +08:00

implementing autocomplete call

This commit is contained in:
Braun Patrik 2016-05-04 18:34:54 +02:00
parent ff17089abf
commit 69489b8cb7
17 changed files with 160 additions and 61 deletions

View File

@ -7,6 +7,7 @@ import {GalleryManager} from "../model/memory/GalleryManager";
import {Directory} from "../../common/entities/Directory";
import {Config} from "../config/Config";
import {ObjectManagerRepository} from "../model/ObjectManagerRepository";
import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem";
export class GalleryMWs {
@ -56,8 +57,17 @@ export class GalleryMWs {
}
public static autocomplete(req:Request, res:Response, next:NextFunction){
//TODO: implement
return next(new Error(ErrorCodes.GENERAL_ERROR));
if(!(req.params.text)){
return next();
}
ObjectManagerRepository.getInstance().getSearchManager().autocomplete(req.params.text,(err,items:Array<AutoCompleteItem>) => {
if(err || !items){
return next(new Error(ErrorCodes.GENERAL_ERROR,err));
}
req.resultPipe = items;
return next();
});
}

View File

@ -0,0 +1,4 @@
import {AutoCompleteItem} from "../../common/entities/AutoCompleteItem";
export interface ISearchManager {
autocomplete(text, cb:(error: any,result:Array<AutoCompleteItem>) => void);
}

View File

@ -4,21 +4,27 @@ import {MongoGalleryManager} from "./mongoose/MongoGalleryManager";
import {MongoUserManager} from "./mongoose/MongoUserManager";
import {GalleryManager} from "./memory/GalleryManager";
import {UserManager} from "./memory/UserManager";
import {ISearchManager} from "./ISearchManager";
import {MongoSearchManager} from "./mongoose/MongoSearchManager";
import {SearchManager} from "./memory/SearchManager";
export class ObjectManagerRepository{
private _galleryManager:IGalleryManager;
private _userManager:IUserManager;
private _searchManager:ISearchManager;
private static _instance:ObjectManagerRepository = null;
public static InitMongoManagers(){
ObjectManagerRepository.getInstance().setGalleryManager(new MongoGalleryManager());
ObjectManagerRepository.getInstance().setUserManager(new MongoUserManager());
ObjectManagerRepository.getInstance().setSearchManager(new MongoSearchManager());
}
public static MemoryMongoManagers(){
ObjectManagerRepository.getInstance().setGalleryManager(new GalleryManager());
ObjectManagerRepository.getInstance().setUserManager(new UserManager());
ObjectManagerRepository.getInstance().setSearchManager(new SearchManager());
}
public static getInstance(){
@ -44,4 +50,13 @@ export class ObjectManagerRepository{
setUserManager(value:IUserManager) {
this._userManager = value;
}
getSearchManager():ISearchManager {
return this._searchManager;
}
setSearchManager(value:ISearchManager) {
this._searchManager = value;
}
}

View File

@ -0,0 +1,13 @@
import {AutoCompleteItem} from "../../../common/entities/AutoCompleteItem";
import {ISearchManager} from "../ISearchManager";
export class SearchManager implements ISearchManager{
autocomplete(text, cb:(error: any,result:Array<AutoCompleteItem>) => void){
throw new Error("not implemented");
}
}

View File

@ -1,42 +1,22 @@
import * as path from 'path';
import {Schema} from "mongoose";
import {Directory} from "../../../common/entities/Directory";
import {IGalleryManager} from "../IGalleryManager";
import {DatabaseManager} from "./DatabaseManager";
import {DiskManager} from "../DiskManger";
import {Utils} from "../../../common/Utils";
import {DirectoryModel} from "./entities/DirectoryModel";
import {PhotoModel} from "./entities/PhotoModel";
export class MongoGalleryManager implements IGalleryManager{
private DirectoryModel;
private PhotoModel;
constructor(){
this.DirectoryModel = DatabaseManager.getInstance().getModel('directory',{
name:String,
path:String,
lastUpdate:Date,
directories: [{
type: Schema.Types.ObjectId,
ref: 'directory'
}],
photos: [{
type: Schema.Types.ObjectId,
ref: 'photo'
}]
});
this.PhotoModel = DatabaseManager.getInstance().getModel('photo',{
name:String,
width:Number,
height:Number
});
}
public listDirectory(relativeDirectoryName, cb:(error: any,result:Directory) => void){
let directoryName = path.basename(relativeDirectoryName);
let directoryParent = path.join( path.dirname(relativeDirectoryName),"/");
this.DirectoryModel.findOne({name:directoryName, path: directoryParent}).populate('photos').populate('directories').exec( (err,res) =>{
DirectoryModel.findOne({name:directoryName, path: directoryParent}).populate('photos').populate('directories').exec( (err,res) =>{
if(err || !res){
return this.indexDirectory(relativeDirectoryName,cb);
}
@ -49,7 +29,7 @@ export class MongoGalleryManager implements IGalleryManager{
DiskManager.scanDirectory(relativeDirectoryName,(err,scannedDirectory)=>{
let arr = [];
scannedDirectory.directories.forEach((value) => {
let dir = new this.DirectoryModel(value);
let dir = new DirectoryModel(value);
Utils.setKeys(dir,value);
dir.save();
arr.push(dir);
@ -57,14 +37,14 @@ export class MongoGalleryManager implements IGalleryManager{
scannedDirectory.directories = arr;
arr = [];
scannedDirectory.photos.forEach((value) => {
let p = new this.PhotoModel(value);
let p = new PhotoModel(value);
Utils.setKeys(p,value);
p.save();
arr.push(p);
});
scannedDirectory.photos = arr;
this.DirectoryModel.create(scannedDirectory,(err)=>{
DirectoryModel.create(scannedDirectory,(err)=>{
return cb(err,scannedDirectory);
});

View File

@ -0,0 +1,45 @@
import {AutoCompleteItem, AutoCompeleteTypes} from "../../../common/entities/AutoCompleteItem";
import {ISearchManager} from "../ISearchManager";
import {DirectoryModel} from "./entities/DirectoryModel";
import {PhotoModel} from "./entities/PhotoModel";
export class MongoSearchManager implements ISearchManager{
constructor(){
}
autocomplete(text, cb:(error: any,result:Array<AutoCompleteItem>) => void){
console.log("autocomplete: " + text);
let items:Array<AutoCompleteItem> = [];
PhotoModel.find({name: { $regex: text, $options: "i" } }).limit(10).select('name').exec( (err,res) =>{
if(err || !res){
return cb(err,null);
}
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name),AutoCompeleteTypes.image));
DirectoryModel.find({name: { $regex: text, $options: "i" } }).limit(10).select('name').exec( (err,res) =>{
if(err || !res){
return cb(err,null);
}
items = items.concat(this.encapsulateAutoComplete(res.map(r => r.name),AutoCompeleteTypes.directory));
return cb(null,items);
});
});
}
private encapsulateAutoComplete(values:Array<string>,type: AutoCompeleteTypes){
let res = [];
values.forEach((value)=>{
res.push(new AutoCompleteItem(value,type));
});
return res;
}
}

View File

@ -0,0 +1,16 @@
import {DatabaseManager} from "../DatabaseManager";
import {Schema} from "mongoose";
export var DirectoryModel = DatabaseManager.getInstance().getModel('directory',{
name:String,
path:String,
lastUpdate:Date,
directories: [{
type: Schema.Types.ObjectId,
ref: 'directory'
}],
photos: [{
type: Schema.Types.ObjectId,
ref: 'photo'
}]
});

View File

@ -0,0 +1,8 @@
import {DatabaseManager} from "../DatabaseManager";
export var PhotoModel = DatabaseManager.getInstance().getModel('photo',{
name:String,
width:Number,
height:Number
});

View File

@ -17,7 +17,7 @@ export class GalleryRouter{
}
private addDirectoryList() {
this.app.get(["/api/gallery/:directory(*)","/api/gallery/","/api/gallery//"],
this.app.get(["/api/gallery/content/:directory(*)","/api/gallery/","/api/gallery//"],
AuthenticationMWs.authenticate,
GalleryMWs.listDirectory,
RenderingMWs.renderResult
@ -26,7 +26,7 @@ export class GalleryRouter{
private addGetImage() {
this.app.get(["/api/gallery/:imagePath(*\.(jpg|bmp|png|gif|jpeg))"],
this.app.get(["/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))"],
AuthenticationMWs.authenticate,
GalleryMWs.loadImage,
RenderingMWs.renderFile
@ -34,7 +34,7 @@ export class GalleryRouter{
};
private addGetImageThumbnail() {
this.app.get("/api/gallery/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?",
this.app.get("/api/gallery/content/:imagePath(*\.(jpg|bmp|png|gif|jpeg))/thumbnail/:size?",
AuthenticationMWs.authenticate,
GalleryMWs.loadImage,
ThumbnailGeneratorMWs.generateThumbnail,
@ -51,8 +51,8 @@ export class GalleryRouter{
};
private addAutoComplete() {
this.app.get("/api/gallery/autocomplete",
AuthenticationMWs.authenticate,
this.app.get("/api/gallery/autocomplete/:text",
// AuthenticationMWs.authenticate,
GalleryMWs.autocomplete,
RenderingMWs.renderResult
);

View File

@ -5,6 +5,6 @@ export enum AutoCompeleteTypes {
}
export class AutoCompleteItem{
constructor(text:string, type:AutoCompeleteTypes){}
constructor(public text:string,public type:AutoCompeleteTypes){}
}

View File

@ -5,9 +5,9 @@ export class Photo {
}
public static getThumbnailPath(directory:Directory,photo:Photo){
return Utils.concatUrls("/api/gallery",directory.path,directory.name,photo.name,"thumbnail");
return Utils.concatUrls("/api/gallery/content/",directory.path,directory.name,photo.name,"thumbnail");
}
public static getPhotoPath(directory:Directory,photo:Photo){
return Utils.concatUrls("/api/gallery",directory.path,directory.name,photo.name);
return Utils.concatUrls("/api/gallery/content/",directory.path,directory.name,photo.name);
}
}

View File

@ -1,6 +1,6 @@
///<reference path="../../browser.d.ts"/>
import {Component, OnInit, QueryList, ViewChild, AfterViewInit} from '@angular/core';
import {Component, OnInit} from '@angular/core';
import {AuthenticationService} from "../model/network/authentication.service.ts";
import {Router, RouteParams} from "@angular/router-deprecated";
import {GalleryService} from "./gallery.service";

View File

@ -15,7 +15,7 @@ export class GalleryService extends NetworkService{
}
public getDirectory(directoryName:string): Promise<Message<Directory>>{
return this.getJson("/gallery/"+directoryName);
return this.getJson("/gallery/content/"+directoryName);
}

View File

@ -20,7 +20,7 @@ export class GalleryPhotoComponent implements IRenderable{
}
getPhotoPath(){
return Utils.concatUrls("/api/gallery",this.directory.path,this.directory.name,this.photo.name,"thumbnail");
return Photo.getThumbnailPath(this.directory,this.photo);
}

View File

@ -3,6 +3,8 @@
import {Injectable} from "@angular/core";
import {Http} from "@angular/http";
import {NetworkService} from "../../model/network/network.service";
import {AutoCompleteItem} from "../../../../common/entities/AutoCompleteItem";
import {Message} from "../../../../common/entities/Message";
@Injectable()
export class AutoCompleteService extends NetworkService {
@ -12,10 +14,8 @@ export class AutoCompleteService extends NetworkService {
super(_http);
}
arraytmp:Array<string> = ["Afghanistan", "Albania", "Algeria", "Andorra", "Angola", "Anguilla", "Antigua &amp; Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia &amp; Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia", "Cameroon", "Cape Verde", "Cayman Islands", "Chad", "Chile", "China", "Colombia", "Congo", "Cook Islands", "Costa Rica", "Cote D Ivoire", "Croatia", "Cruise Ship", "Cuba", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Estonia", "Ethiopia", "Falkland Islands", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "French West Indies", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea", "Guinea Bissau", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kuwait", "Kyrgyz Republic", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Mauritania", "Mauritius", "Mexico", "Moldova", "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger", "Nigeria", "Norway", "Oman", "Pakistan", "Palestine", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russia", "Rwanda", "Saint Pierre &amp; Miquelon", "Samoa", "San Marino", "Satellite", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "South Africa", "South Korea", "Spain", "Sri Lanka", "St Kitts &amp; Nevis", "St Lucia", "St Vincent", "St. Lucia", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor L'Este", "Togo", "Tonga", "Trinidad &amp; Tobago", "Tunisia", "Turkey", "Turkmenistan", "Turks &amp; Caicos", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "Uruguay", "Uzbekistan", "Venezuela", "Vietnam", "Virgin Islands (US)", "Yemen", "Zambia", "Zimbabwe"];
public autoComplete(text:string) {
return this.arraytmp.filter(t => t.toLowerCase().indexOf(text.toLowerCase()) > -1).slice(0,10);
public autoComplete(text:string): Promise<Message<Array<AutoCompleteItem> >>{
return this.getJson("/gallery/autocomplete/"+text);
}

View File

@ -2,6 +2,8 @@
import {Component} from "@angular/core";
import {AutoCompleteService} from "./autocomplete.service";
import {AutoCompleteItem} from "../../../../common/entities/AutoCompleteItem";
import {Message} from "../../../../common/entities/Message";
@Component({
selector: 'gallery-search',
@ -11,32 +13,37 @@ import {AutoCompleteService} from "./autocomplete.service";
})
export class GallerySearchComponent {
autoCompleteItems:Array<AutoCompleteItem> = [];
autoCompleteItems:Array<AutoCompleteRenderItem> = [];
constructor(private _autoCompleteService:AutoCompleteService) {
}
getSuggestions(event:KeyboardEvent){
let searchText = (<HTMLInputElement>event.target).value;
let result = [];
if(searchText.length > 0) {
result = this._autoCompleteService.autoComplete(searchText);
this._autoCompleteService.autoComplete(searchText).then((message:Message<Array<AutoCompleteItem>>) =>{
if(message.error){
//TODO: implement
console.error(message.error);
return;
}
this.showSuggestions(message.result,searchText);
});
}
this.showSuggestions(result,searchText);
}
private showSuggestions(suggestions:Array<string>,searchText:string){
private showSuggestions(suggestions:Array<AutoCompleteItem>,searchText:string){
this.autoCompleteItems = [];
suggestions.forEach((value)=>{
let preIndex = value.toLowerCase().indexOf(searchText.toLowerCase());
let item = new AutoCompleteItem();
suggestions.forEach((item)=>{
let preIndex = item.text.toLowerCase().indexOf(searchText.toLowerCase());
let renderItem = new AutoCompleteRenderItem();
if(preIndex > -1){
item.preText = value.substring(0,preIndex);
item.highLightText = value.substring(preIndex, preIndex + searchText.length);
item.postText = value.substring(preIndex + searchText.length);
renderItem.preText = item.text.substring(0,preIndex);
renderItem.highLightText = item.text.substring(preIndex, preIndex + searchText.length);
renderItem.postText = item.text.substring(preIndex + searchText.length);
}else{
item.postText = value;
renderItem.postText = item.text;
}
this.autoCompleteItems.push(item);
this.autoCompleteItems.push(renderItem);
});
}
@ -45,7 +52,7 @@ export class GallerySearchComponent {
}
class AutoCompleteItem{
class AutoCompleteRenderItem{
constructor(public preText:string = "",public highLightText:string = "", public postText:string = ""){
}

View File

@ -7,6 +7,7 @@ import {UserService} from "./user.service.ts";
import {LoginCredential} from "../../../../common/entities/LoginCredential";
import {Message} from "../../../../common/entities/Message";
import { Cookie } from 'ng2-cookies/ng2-cookies';
import {ErrorCodes} from "../../../../common/entities/Error";
declare module ServerInject{
export var user;
@ -46,7 +47,7 @@ export class AuthenticationService{
public login(credential:LoginCredential){
this._userService.login(credential).then( (message:Message<User>) =>{
if(message.error){
console.log(message.error);
console.log(ErrorCodes[message.error.code] + "message: "+ message.error.message);
}else{
this.setUser(message.result);
}