Advertisement
Guest User

Untitled

a guest
Jun 12th, 2016
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 53.83 KB | None | 0 0
  1. /// <reference path="../tsdefs/mongodb.d.ts" />
  2. /// <reference path="../tsdefs/rx.d.ts" />
  3.  
  4. import * as ReactiveX from 'rx'; // don't delete!
  5. import {User} from "../model/user";
  6. import {Collection} from "mongodb";
  7. import {MongoClient} from "mongodb";
  8. import {Db} from "mongodb";
  9. import {InsertOneWriteOpResult} from "mongodb";
  10. import {CursorResult} from "mongodb";
  11. import Observable = ReactiveX.Observable;
  12. import Subject = ReactiveX.Subject;
  13. import {TokenManager} from "../TokenManager";
  14. import {Bassin} from "../model/bassin";
  15. import {Storm} from "../model/storm";
  16. import {Building} from "../model/building";
  17. import {UpdateWriteOpResult} from "mongodb";
  18. import {UserHistory} from "../model/history/userHistory";
  19. import {DayInfo} from "../model/history/dayInfo";
  20. import {BuildingHistory} from "../model/history/buildingHistory";
  21. import {Settings} from "../model/settings";
  22.  
  23. import {Model} from "../model/model";
  24. import {Hatchery} from "../model/hatchery";
  25. import {Specie} from "../model/specie";
  26. import {ObjectID} from "mongodb";
  27. import {FeedingModel} from "../model/feedingModel";
  28. import {SeaCage} from "../model/seaCage";
  29. import {FishContainer} from "../model/fishContainer";
  30.  
  31. export class UserManager {
  32.  
  33. private mongoClient:MongoClient;
  34. private url:string;
  35. private userCollection:Collection;
  36. private historyCollection:Collection;
  37. private settingsCollection:Collection;
  38. private outputModelsCollection:Collection;
  39. private constantInputModelCollection:Collection;
  40. private generatedInputModelCollection:Collection;
  41. private db:Db;
  42.  
  43. constructor() {
  44. this.mongoClient = require('mongodb').MongoClient;
  45. this.url = 'mongodb://Uninova:uninova4@ds011422.mlab.com:11422/uninova';
  46. }
  47.  
  48. public connect():Observable<Db> {
  49. var observable:Observable<Db> = Observable.fromPromise<Db>(this.mongoClient.connect(this.url));
  50. observable.subscribe(
  51. (db:Db) => {
  52. this.db = db;
  53. this.userCollection = db.collection("users");
  54. this.historyCollection = db.collection("history");
  55. this.settingsCollection = db.collection("data");
  56. this.outputModelsCollection = db.collection("outputmodels");
  57. this.constantInputModelCollection = db.collection("constantinputmodels");
  58. this.generatedInputModelCollection = db.collection("generatedinputmodels");
  59. }
  60. );
  61. return observable;
  62. }
  63.  
  64. public getEnvironmentalModel(username: string, id: string): Observable<Model> {
  65. return Observable.create<Model>(
  66. observer => {
  67. this.readUser(username).subscribe(
  68. (user: User) => {
  69. Observable.fromPromise<CursorResult>(this.generatedInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next()).map(
  70. doc => doc == null ? null : new Model(doc.name, doc.data.slice(0, user.day))
  71. ).subscribe((model: Model) => {observer.onNext(model)});
  72. }
  73. )
  74. }
  75. );
  76. }
  77.  
  78. public getMortalityModelById(id: string): Observable<Model> {
  79. return Observable.fromPromise<CursorResult>(this.generatedInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next()).map(
  80. doc => {
  81. return doc == null ? null : new Model(doc.name, doc.data)
  82. }
  83. );
  84. }
  85.  
  86. public deleteUser(token: string): Observable<any> {
  87. return Observable.create<any>(
  88. observer => {
  89. let username: string = TokenManager.getField(token, "username");
  90. this.deleteUserAccount(username).subscribe(() => this.deleteUserHistory(username).subscribe(() => observer.onNext(null)));
  91. }
  92. );
  93. }
  94.  
  95. private deleteUserAccount(username: string): Observable<any> {
  96. return Observable.fromPromise(this.userCollection.deleteOne({username: username}));
  97. }
  98.  
  99. private deleteUserHistory(username: string): Observable<any> {
  100. return Observable.fromPromise(this.historyCollection.deleteOne({username: username}));
  101. }
  102.  
  103. /* createUser
  104. We try to find a user with the corresponding username in the collection to see if the username is already taken.
  105. If not, we create a new user object and set it's registeredNumber value to the current amount of users in the collection.
  106. This user object gets inserted in the collection as a new document.
  107. Finally we pass the user object to the TokenManager to generate a token which will be passed to the client for future authentication.
  108. */
  109. public createUser(username:string, password:string):Observable<string> {
  110. return Observable.create<string>(
  111. observer => {
  112. this.readUser(username).subscribe(
  113. readUser => {
  114. if (readUser == null) {
  115. Observable.fromPromise<number>(this.userCollection.count({})).subscribe(count => {
  116. this.generateTemperatureModel().subscribe(temperatureModelData => {
  117. this.generateOxygenModel(temperatureModelData.model).subscribe(oxygenModelObjectId => {
  118. this.generatePhModel(temperatureModelData.model).subscribe(phModelObjectId => {
  119. this.getSettingsData().subscribe((settings:Settings) => {
  120. var storms:Storm[] = this.getRandomStorms(temperatureModelData.model);
  121. var user:User = new User(username, password, settings.startersMoney, "1", count, false, 1, [], storms, temperatureModelData.id.toString(), oxygenModelObjectId.toString(), phModelObjectId.toString(), "", "", "");
  122. Observable.fromPromise<InsertOneWriteOpResult>(this.userCollection.insertOne(user)).subscribe(() => observer.onNext(TokenManager.tokenify(user)));
  123. });
  124. });
  125. });
  126. });
  127. });
  128. } else observer.onNext("");
  129. }
  130. );
  131. }
  132. );
  133. }
  134.  
  135. private generateTemperatureModel():Observable<any> {
  136. var temperatureModel:Model = new Model();
  137. var data = [];
  138. for (var i:number = 0; i < 365; i++) {
  139. if (Math.random() > 0.95)
  140. data[i] = 15.005;
  141. else
  142. data[i] = Math.round(((Math.random() + 1.75) * Math.sin(i * 6.0) + 23) * 100) / 100;
  143. }
  144. temperatureModel.name = "temperatureModel";
  145. temperatureModel.data = data;
  146. return Observable.fromPromise<InsertOneWriteOpResult>(this.generatedInputModelCollection.insertOne(temperatureModel)).map((iowor:InsertOneWriteOpResult) => {
  147. var modelData = {};
  148. modelData["model"] = temperatureModel;
  149. modelData["id"] = iowor.insertedId;
  150. return modelData;
  151. });
  152. }
  153.  
  154. private getRandomStorms(model:Model):Storm[] {
  155. var storms:Storm[] = [];
  156. for (var i:number = 0; i < model.data.length; i++) {
  157. if (model.data[i] == 15.005) {
  158. var randomGravity:number = Math.floor(Math.random() * 9) + 1;
  159. storms.push(new Storm(randomGravity, i));
  160. }
  161. }
  162.  
  163. return storms;
  164.  
  165.  
  166. /* var storms: Storm[] = [];
  167. var amountOfStorms: number = Math.floor(Math.random() * 5) + 1; // 1 to 6 (inclusive) storms a year
  168. var randomAlreadyTaken: boolean;
  169.  
  170. while (storms.length < amountOfStorms) {
  171. randomAlreadyTaken = false;
  172. var randomDay: number = Math.floor(Math.random() * 364) + 1;
  173. for (var i: number = 0; i < storms.length; i++) {
  174. if (storms[i].day == randomDay) {
  175. randomAlreadyTaken = true;
  176. break;
  177. }
  178. }
  179. if (randomAlreadyTaken) continue;
  180. var randomGravity: number = Math.floor(Math.random() * 9) + 1;
  181. storms.push(new Storm(randomGravity, randomDay));
  182. }
  183. return storms;*/
  184. }
  185.  
  186.  
  187. public generateOxygenModel(temparetureModel:Model):Observable<ObjectID> {
  188. var oxygenModel:Model = new Model();
  189. var data:number[] = [];
  190. for (var i:number = 0; i < 365; i++)
  191. data[i] = i;
  192. oxygenModel.name = "oxygenModel";
  193. oxygenModel.data = data;
  194. return Observable.fromPromise<InsertOneWriteOpResult>(this.generatedInputModelCollection.insertOne(oxygenModel)).map((iowor:InsertOneWriteOpResult) => iowor.insertedId);
  195. }
  196.  
  197. public generatePhModel(temperatureModel:Model):Observable<ObjectID> {
  198. var phModel:Model = new Model();
  199. var data:number[] = [];
  200. for (var i:number = 0; i < 365; i++)
  201. data[i] = i;
  202. phModel.name = "phModel";
  203. phModel.data = data;
  204. return Observable.fromPromise<InsertOneWriteOpResult>(this.generatedInputModelCollection.insertOne(phModel)).map((iowor:InsertOneWriteOpResult) => iowor.insertedId);
  205. }
  206.  
  207. public getHistory(token:string):Observable<UserHistory> {
  208. return Observable.fromPromise<CursorResult>(this.historyCollection.find({username: TokenManager.getField(token, "username")}).limit(1).next()).map(
  209. doc =>
  210. doc == null ? null : new UserHistory(doc.username, doc.buildingData)
  211. );
  212. }
  213.  
  214. public getFoodNeededForDay(feedingModelId: string, day: number): Observable<number> {
  215. return Observable.create<number>(
  216. observer => {
  217. this.getFeedingModelByIdRoute(feedingModelId).subscribe((model: Model) => observer.onNext(model.data[day % 365]));
  218. }
  219. );
  220. }
  221.  
  222. /* login
  223. We read the user from the collection by their username.
  224. If the passwords match we return the user's token for future authentication, otherwise an empty string.
  225. */
  226. public login(username:string, password:string):Observable<any> {
  227. return Observable.create<any>(
  228. observer =>
  229. this.readUser(username).subscribe(
  230. (user:User) =>
  231. observer.onNext((user != null && user.password.localeCompare(password) == 0) ? {
  232. "token": TokenManager.tokenify(user),
  233. "aquasmart": user.hasAquaSmart,
  234. "profileLevel": user.profileLevel
  235. } : null)
  236. )
  237. );
  238. }
  239.  
  240. public generateAverageWeight(token:string):Observable<string> {
  241. return Observable.create<string>(
  242. observer => {
  243. this.readUser(TokenManager.getField(token, "username")).subscribe((user:User) => {
  244. var buildings:Building[] = this.getParsedBuildings(JSON.stringify(user.buildings));
  245. for (var i:number = 0; i < buildings.length; i++) {
  246. let building:Building = buildings[i];
  247. if (building instanceof Hatchery) {
  248. this.calcAverageWeight(user, building as Hatchery).subscribe((avgWeightModel:Model) => {
  249. Observable.fromPromise<InsertOneWriteOpResult>(this.outputModelsCollection.insertOne(avgWeightModel)).map((iowor:InsertOneWriteOpResult) => iowor.insertedId.toString()).subscribe((id:string) => observer.onNext(id));
  250. });
  251. }
  252. }
  253. })
  254. }
  255. );
  256. }
  257.  
  258. private calcAverageWeight(user:User, hatchery:Hatchery):Observable<Model> {
  259. return Observable.create<Model>(
  260. observer => {
  261. let avgWeightModel:Model = new Model("Average Weight", []);
  262.  
  263. let isStandardFeedingModel: boolean =
  264. user.fishType1CustomFeedingModelId != hatchery.feedingModelId &&
  265. user.fishType2CustomFeedingModelId != hatchery.feedingModelId &&
  266. user.fishType3CustomFeedingModelId != hatchery.feedingModelId;
  267.  
  268. this.getFeedingModelById(0, hatchery, hatchery.feedingModelId, isStandardFeedingModel).subscribe(feedingModelData => {
  269. let feedingModel:FeedingModel = feedingModelData.model;
  270. this.getFcrValuesForSpecie(hatchery.specie).subscribe((fcrValues:number[]) => {
  271. this.getWaterTemperatureValues().subscribe((waterTemperatureValues:number[]) => {
  272. for (var i:number = 0; i < +user.day; i++) {
  273. let currentAvgWeight:number = feedingModel.data[i] / (((fcrValues[1] - fcrValues[0]) / 2) + fcrValues[0]) * (1 + (waterTemperatureValues[0] - ((waterTemperatureValues[1] - waterTemperatureValues[0]) / 2) / (waterTemperatureValues[1] - waterTemperatureValues[0])));
  274. avgWeightModel.data.push(currentAvgWeight);
  275.  
  276. if (i == +user.day - 1)
  277. observer.onNext(avgWeightModel);
  278. }
  279. })
  280. })
  281. })
  282. }
  283. );
  284. }
  285.  
  286. private getSpecieName(specieType:string):Observable<string> {
  287. let fieldName:string = specieType.toLowerCase() + "Name";
  288. return Observable.fromPromise<CursorResult>(this.settingsCollection.find({}).limit(1).next()).map(
  289. doc => doc == null ? null : doc[fieldName]
  290. );
  291. }
  292.  
  293. private getSpecieType(specie:string):Observable<string> {
  294. return Observable.create<string>(
  295. observer => {
  296. if (specie.toLowerCase() == "specie1" || specie.toLowerCase() == "specie2" || specie.toLowerCase() == "specie3")
  297. observer.onNext(specie);
  298. else {
  299. Observable.fromPromise<CursorResult>(this.settingsCollection.find({}).limit(1).next()).subscribe(doc => {
  300. if (doc["specie1Name"].toLowerCase() == specie.toLowerCase())
  301. observer.onNext("specie1");
  302. if (doc["specie2Name"].toLowerCase() == specie.toLowerCase())
  303. observer.onNext("specie2");
  304. if (doc["specie3Name"].toLowerCase() == specie.toLowerCase())
  305. observer.onNext("specie3");
  306. });
  307. }
  308. }
  309. );
  310. }
  311.  
  312. private getFcrValuesForSpecie(specie:string):Observable<number[]> {
  313. return Observable.create<number[]>(
  314. observer => {
  315. this.getSpecieType(specie).subscribe((specieType:string) => {
  316. var object = {};
  317. let field1Name:string = "fcrMin" + specieType[0].toUpperCase() + specieType.substr(1).toLowerCase();
  318. let field2Name:string = "fcrMax" + specieType[0].toUpperCase() + specieType.substr(1).toLowerCase();
  319. object[field1Name] = 1;
  320. object[field2Name] = 1;
  321. Observable.fromPromise<CursorResult>(this.settingsCollection.find({}).limit(1).next()).map(
  322. doc => doc == null ? null : [doc[field1Name], doc[field2Name]]
  323. ).subscribe(sup => observer.onNext(sup));
  324. });
  325. }
  326. );
  327. }
  328.  
  329. private getWaterTemperatureValues():Observable<number[]> {
  330. return Observable.fromPromise<CursorResult>(this.settingsCollection.find({}).limit(1).next()).map(
  331. doc => doc == null ? null : [doc["minWaterTemperature"], doc["maxWaterTemperature"]]
  332. );
  333. }
  334.  
  335. private getParsedBuildings(buildingsJson:string):Building[] {
  336. var parsedBuildings:Building[] = [];
  337. var buildings = JSON.parse(buildingsJson);
  338. for (var i:number = 0; i < buildings.length; i++) {
  339. if (buildings[i]["name"].toLowerCase().indexOf("hatchery") > -1)
  340. parsedBuildings[i] = new Hatchery(buildings[i]["position"], buildings[i]["rotation"], buildings[i]["name"], buildings[i]["mortalityModelId"], buildings[i]["bassins"], buildings[i]["feedingModelId"], buildings[i]["transformation"], buildings[i]["specie"], buildings[i]["daySinceFilled"], buildings[i]["visitedHatchery"]);
  341. else if (buildings[i]["name"].toLowerCase().indexOf("seacage") > -1)
  342. parsedBuildings[i] = new SeaCage(buildings[i]["position"], buildings[i]["rotation"], buildings[i]["name"], buildings[i]["mortalityModelId"], buildings[i]["amountOfFish"], buildings[i]["feedingModelId"], buildings[i]["transformation"], buildings[i]["specie"], buildings[i]["daySinceFilled"], buildings[i]["visitedSea"], buildings[i]["visitedBoat"]);
  343. else
  344. parsedBuildings[i] = new Building(buildings[i]["position"], buildings[i]["rotation"], buildings[i]["name"]);
  345. }
  346. return parsedBuildings;
  347. }
  348.  
  349. //First: save received buildings to user's history
  350. //Second: change bassins and mortality and such
  351. //Third: incrDayForUser
  352. public nextDay(token:string, buildings:string, money: string, fishType1CustomFeedingModelId: string, fishType2CustomFeedingModelId: string, fishType3CustomFeedingModelId: string):Observable<Building[]> {
  353. return Observable.create<Building[]>(
  354. observer => {
  355. var username:string = TokenManager.getField(token, "username");
  356. console.log("wtf: " + username);
  357. Observable.fromPromise<CursorResult>(this.userCollection.find({username: username}).limit(1).next())
  358. .map(doc => new User(doc.username, "nope", doc.money, doc.day, doc.registeredNumber, doc.hasAquaSmart, doc.profileLevel, doc.buildings, doc.storms, doc.temperatureModelId, doc.oxygenModelId, doc.phModelId, doc.fishType1CustomFeedingModelId, doc.fishType2CustomFeedingModelId, doc.fishType3CustomFeedingModelId, doc._id))
  359. .subscribe(
  360. (user:User) => {
  361. this.getData(token).subscribe((previousDayUserObject:User) => {
  362. this.saveAsHistoryFor(username, +money, +user.day, this.getParsedBuildings(buildings)).subscribe( // save history
  363. () => {
  364. let newBuildings:Building[] = this.getParsedBuildings(buildings);
  365. this.getSettingsData().subscribe(
  366. (settings:Settings) => {
  367. this.getEnvironmentalModel(username, user.temperatureModelId).subscribe(
  368. (temperatureModel:Model) => {
  369. if (newBuildings != null && newBuildings.length > 0) {
  370. for (let building of newBuildings) {
  371. if (building instanceof Hatchery) {
  372. for (var bassin of building.bassins)
  373. bassin.amountOfFishes -= this.calculateFatalitiesBassin(user, temperatureModel, building as Hatchery, bassin as Bassin, settings);
  374. } else if (building instanceof SeaCage)
  375. (building as SeaCage).amountOfFish -= this.calculateFatalitiesSeaCage(user, temperatureModel, building as SeaCage, settings);
  376. }
  377.  
  378. let totalBuildingCount:number = newBuildings.length;
  379. var buildingCount:number = 0;
  380. let newestBuildings:Building[] = this.checkMortalityModels(previousDayUserObject, newBuildings);
  381. for (let building of newestBuildings) {
  382. this.pushToMortalityModel(user, building).subscribe((pushedBuilding: Building) => {
  383. if (++buildingCount == totalBuildingCount) {
  384. this.updateUserBuildings(token, newestBuildings).subscribe(
  385. (someBuildings:Building[]) => {
  386. var sDay: string = user.day;
  387. var nDay: number = +sDay;
  388. nDay++;
  389. user.day = "" + nDay;
  390. this.updateUser(username, nDay, fishType1CustomFeedingModelId, fishType2CustomFeedingModelId, fishType3CustomFeedingModelId, +money).subscribe(() => observer.onNext(newestBuildings));
  391. })
  392. }
  393. })
  394. }
  395. }
  396. })
  397. })
  398. })
  399. })
  400. })
  401. })
  402. }
  403.  
  404. private checkMortalityModels(previousDayUser: User, currentDayBuildings: Building[]): Building[] {
  405. let previousDayBuildings: Building[] = this.getParsedBuildings(JSON.stringify(previousDayUser.buildings));
  406. for (var i: number = 0; i < previousDayBuildings.length; i++) {
  407. let previousDayBuilding: Building = previousDayBuildings[i];
  408. for (var j: number = 0; j < currentDayBuildings.length; j++) {
  409. let currentDayBuilding: Building = currentDayBuildings[j];
  410. if (previousDayBuilding.name == currentDayBuilding.name) {
  411. if (previousDayBuilding instanceof Hatchery) {
  412. let previousDayHatchery: Hatchery = previousDayBuilding as Hatchery;
  413. let currentDayHatchery: Hatchery = currentDayBuilding as Hatchery;
  414.  
  415. var previousDayHatcheryAmountOfFishes: number = 0;
  416. for (var k: number = 0; k < previousDayHatchery.bassins.length; k++)
  417. previousDayHatcheryAmountOfFishes += previousDayHatchery.bassins[k].amountOfFishes;
  418.  
  419. var currentDayHatcheryAmountOfFishes: number = 0;
  420. for (var k: number = 0; k < currentDayHatchery.bassins.length; k++)
  421. currentDayHatcheryAmountOfFishes += currentDayHatchery.bassins[k].amountOfFishes;
  422.  
  423. //todo: && not empty
  424. if ((previousDayHatcheryAmountOfFishes != 0 && currentDayHatcheryAmountOfFishes == 0) ||
  425. (currentDayHatcheryAmountOfFishes > previousDayHatcheryAmountOfFishes)) {
  426. currentDayHatchery.mortalityModelId = null;
  427. }
  428. } else if (previousDayBuilding instanceof SeaCage) {
  429. let previousDaySeaCage: SeaCage = previousDayBuilding as SeaCage;
  430. let currentDaySeaCage: SeaCage = currentDayBuilding as SeaCage;
  431.  
  432. if ((previousDaySeaCage.amountOfFish != 0 && currentDaySeaCage.amountOfFish == 0) ||
  433. (currentDaySeaCage.amountOfFish > previousDaySeaCage.amountOfFish)) {
  434. currentDaySeaCage.mortalityModelId = null;
  435. }
  436. }
  437. }
  438. }
  439. }
  440.  
  441. return currentDayBuildings;
  442. }
  443.  
  444. private pushToMortalityModel(user: User, building: Building): Observable<Building> {
  445. return Observable.create<Building>(
  446. observer => {
  447. if (building instanceof Hatchery || building instanceof SeaCage) {
  448. Observable.create<string>(
  449. innerObserver => {
  450. if ((building as FishContainer).mortalityModelId == null || (building as FishContainer).mortalityModelId == "") {
  451. let mortalityModel: Model = new Model("mortalityModel", []);
  452. Observable.fromPromise<InsertOneWriteOpResult>(this.generatedInputModelCollection.insertOne(mortalityModel))
  453. .map((iowor:InsertOneWriteOpResult) => iowor.insertedId.toString())
  454. .subscribe(
  455. (insertedId:string) => {
  456. innerObserver.onNext(insertedId);
  457. }
  458. );
  459. } else
  460. innerObserver.onNext((building as FishContainer).mortalityModelId);
  461. }
  462. ).subscribe((mortalityModelId:string) => {
  463. console.log("MORTALITYMODELID: " + mortalityModelId);
  464. (building as FishContainer).mortalityModelId = mortalityModelId;
  465. if (building instanceof Hatchery) {
  466. var amountOfFishes:number = 0;
  467. for (var i:number = 0; i < (building as Hatchery).bassins.length; i++)
  468. amountOfFishes += building.bassins[i].amountOfFishes;
  469. Observable.fromPromise<any>(this.generatedInputModelCollection.findOneAndUpdate(
  470. {_id: new ObjectID((building as FishContainer).mortalityModelId)},
  471. {$push: {data: amountOfFishes}})
  472. ).subscribe(() => observer.onNext(building));
  473. } else if (building instanceof SeaCage)
  474. Observable.fromPromise<any>(this.generatedInputModelCollection.findOneAndUpdate(
  475. {_id: new ObjectID((building as FishContainer).mortalityModelId)},
  476. {$push: {data: (building as SeaCage).amountOfFish}})
  477. ).subscribe(() => observer.onNext(building));
  478. })
  479. } else
  480. observer.onNext(null);
  481. })
  482. };
  483.  
  484.  
  485.  
  486. //gets called when user adds buildings in overview then hits escape
  487. public saveData(token:string, buildings:Building[], money: number, fishType1CustomFeedingModelId: string, fishType2CustomFeedingModelId: string, fishType3CustomFeedingModelId: string):Observable<any> {
  488. return Observable.create<any>(
  489. observer => {
  490. if (TokenManager.validate(token)) {
  491. var requestingUsername:string = TokenManager.getField(token, "username");
  492. Observable.fromPromise<UpdateWriteOpResult>(
  493. this.userCollection.updateOne(
  494. {username: requestingUsername},
  495. {$set: {buildings: buildings, fishType1CustomFeedingModelId: fishType1CustomFeedingModelId, fishType2CustomFeedingModelId: fishType2CustomFeedingModelId, fishType3CustomFeedingModelId: fishType3CustomFeedingModelId}},
  496. {}
  497. )).subscribe(
  498. (result:UpdateWriteOpResult) =>
  499. observer.onNext(result.modifiedCount)
  500. );
  501. }
  502. }
  503. );
  504. }
  505.  
  506. private updateUser(username: string, day: number, fishType1CustomFeedingModelId: string, fishType2CustomFeedingModelId: string, fishType3CustomFeedingModelId: string, money: number): Observable<any> {
  507. return Observable.create<any>(
  508. observer => {
  509. Observable.create<any>(
  510. innerObserver => {
  511. if (day != 365)
  512. innerObserver.onNext(null);
  513. else
  514. this.getNewEnvironmentalModels().subscribe((environmentalModels: string[]) => innerObserver.onNext(environmentalModels));
  515. }
  516. ).subscribe(
  517. (environmentalModels: string[]) => {
  518.  
  519. let objectToSave = {
  520. day: day,
  521. fishType1CustomFeedingModelId: fishType1CustomFeedingModelId,
  522. fishType2CustomFeedingModelId: fishType2CustomFeedingModelId,
  523. fishType3CustomFeedingModelId: fishType3CustomFeedingModelId,
  524. money: money
  525. };
  526.  
  527. if (environmentalModels != null) {
  528. objectToSave["temperatureModelId"] = environmentalModels[0];
  529. objectToSave["oxygenModelId"] = environmentalModels[1];
  530. objectToSave["phModelId"] = environmentalModels[2];
  531. console.log(objectToSave["temperatureModelId"]);
  532. console.log(objectToSave["oxygenModelId"]);
  533. console.log(objectToSave["phModelId"]);
  534. }
  535.  
  536. Observable.fromPromise<UpdateWriteOpResult>(
  537. this.userCollection.updateOne(
  538. {username: username},
  539. {$set: objectToSave},
  540. {}
  541. )).subscribe(
  542. (result:UpdateWriteOpResult) =>
  543. observer.onNext(result) //result is omitted
  544. )
  545. });
  546. }
  547. );
  548. }
  549.  
  550. private getNewEnvironmentalModels(): Observable<string[]> {
  551. console.log("NEW SHIT");
  552. return Observable.create<string[]>(
  553. observer => {
  554. this.generateTemperatureModel().subscribe(temperatureModelData => {
  555. this.generateOxygenModel(temperatureModelData.model).subscribe(oxygenModelObjectId => {
  556. this.generatePhModel(temperatureModelData.module).subscribe(phModelObjectId => {
  557. observer.onNext([temperatureModelData.id.toString(), oxygenModelObjectId.toString(), phModelObjectId.toString()])
  558. })
  559. })
  560. })
  561. }
  562. )
  563. }
  564.  
  565. private incrDayForUser(username:string, currentDay:number):Observable<any> {
  566. return Observable.create<any>(
  567. observer => {
  568. Observable.fromPromise<UpdateWriteOpResult>(this.userCollection.updateOne({username: username}, {$set: {day: currentDay + 1}}, {})).subscribe(
  569. (result:UpdateWriteOpResult) =>
  570. observer.onNext(result) //result is omitted
  571. );
  572. }
  573. );
  574. }
  575.  
  576. public saveCustomFeedingModel(model: Model): Observable<string> {
  577. return Observable.fromPromise<InsertOneWriteOpResult>(this.generatedInputModelCollection.insertOne(new Model(model.name, model.data)))
  578. .map((iowor: InsertOneWriteOpResult) => iowor.insertedId.toString());
  579. }
  580.  
  581. //Does history already exist for this user?
  582. // no -> create one and insert data we received
  583. // yes -> insert data we received in 'days' collection of user's history
  584. private saveAsHistoryFor(username: string, money: number, currentDay:number, buildings: Building[]): Observable<any> {
  585. let dayHistory = {};
  586. dayHistory["day"] = currentDay;
  587. dayHistory["money"] = money;
  588.  
  589. let buildingData = [];
  590. for (var i: number = 0; i < buildings.length; i++) {
  591. let building:Building = buildings[i];
  592. if (building instanceof Hatchery || building instanceof SeaCage) {
  593. let currentBuildingDataBlock = {};
  594. currentBuildingDataBlock["name"] = building.name;
  595. var amountOfFish:number = 0;
  596. if (building instanceof Hatchery) {
  597. let bassins:Bassin[] = (building as Hatchery).bassins;
  598. for (var j:number = 0; j < bassins.length; j++)
  599. amountOfFish += bassins[j].amountOfFishes;
  600. } else if (building instanceof SeaCage)
  601. amountOfFish = (building as SeaCage).amountOfFish;
  602. currentBuildingDataBlock["amountOfFish"] = amountOfFish;
  603. buildingData.push(currentBuildingDataBlock);
  604. }
  605. }
  606.  
  607. dayHistory["buildingData"] = buildingData;
  608.  
  609. return Observable.create<any>(
  610. observer => {
  611. Observable.fromPromise<number>(this.historyCollection.count({username: username})).subscribe(count => {
  612. if (count == 0) { // no history for user yet -> create history object for user
  613. let userObject = {};
  614. userObject["username"] = username;
  615. userObject["history"] = [dayHistory];
  616. Observable.fromPromise<InsertOneWriteOpResult>(this.historyCollection.insertOne(userObject)).subscribe(() => observer.onNext(null));
  617. } else // history for user -> push to user's array
  618. Observable.fromPromise<any>(this.historyCollection.findOneAndUpdate({username: username}, {$push: {history: dayHistory}})).subscribe(() => observer.onNext(null));
  619. });
  620. }
  621. );
  622. }
  623.  
  624. private getDataUsername(username: string): Observable<User> {
  625. return Observable.create<User>(
  626. observer => {
  627. this.readUser(username).subscribe(
  628. (user: User) =>
  629. observer.onNext(user)
  630. );
  631. }
  632. );
  633. }
  634.  
  635. /* getData
  636. This method gets invoked when the user is logged in.
  637. Returns the user's document from the database which also contains buildings, bassins and storms.
  638. */
  639. public getData(token: string): Observable<User> {
  640. return Observable.create<User>(
  641. observer => {
  642. var username: string = TokenManager.getField(token, "username");
  643. this.readUser(username).subscribe(
  644. (user:User) =>
  645. observer.onNext(user)
  646. );
  647. }
  648. );
  649. }
  650.  
  651. public getNeighbourData(token:string):Observable<User[]> {
  652. return Observable.create<User[]>(
  653. observer => {
  654. var registeredNumber = TokenManager.getField(token, "registeredNumber");
  655. var neighbours:User[] = [];
  656. Observable.create<User>(
  657. observerLeftNeighbour => {
  658. if (+registeredNumber > 0)
  659. this.getDataFromRegisteredNumber(registeredNumber - 1).subscribe((leftNeighbour:User) => observerLeftNeighbour.onNext(leftNeighbour));
  660. else
  661. observerLeftNeighbour.onNext(null);
  662. }
  663. ).subscribe((leftNeighbour:User) => {
  664. neighbours[0] = leftNeighbour;
  665. Observable.create<User>(
  666. observerRightNeighbour => {
  667. Observable.fromPromise<number>(this.userCollection.count({})).subscribe(count => {
  668. if (+registeredNumber < count - 1)
  669. this.getDataFromRegisteredNumber(registeredNumber + 1).subscribe((rightNeighbour:User) => observerRightNeighbour.onNext(rightNeighbour));
  670. else
  671. observerRightNeighbour.onNext(null);
  672. });
  673. }
  674. ).subscribe((rightNeighbour:User) => {
  675. neighbours[1] = rightNeighbour;
  676. observer.onNext(neighbours);
  677. });
  678. });
  679. }
  680. )
  681. }
  682.  
  683. public getSettingsData():Observable<Settings> {
  684. var settings: Settings;
  685. return Observable.fromPromise<CursorResult>(this.settingsCollection.find({}).limit(1).next()).map(
  686. doc => doc == null ? null : (settings = doc)
  687. );
  688. }
  689.  
  690. /*
  691. *
  692. * string name
  693. * string specie
  694. * int amountOfFish
  695. * list<Model> models: feedingmodel, ph model, oxygen model
  696. * */
  697.  
  698. public getHatcheryModels(username: string): Observable<any[]> {
  699. return Observable.create<any[]>(
  700. observer => {
  701. var fishContainerModels = [];
  702. this.getDataUsername(username).subscribe((user: User) => {
  703. var lastFishContainerI: number = -1;
  704. var count: number = 0;
  705. var total: number = 0;
  706. var bs: Building[] = this.getParsedBuildings(JSON.stringify(user.buildings));
  707. for (var i:number = 0; i < bs.length; i++) {
  708. var building:Building = bs[i];
  709. if (building instanceof Hatchery || building instanceof SeaCage) {
  710. lastFishContainerI = i;
  711. total++;
  712. }
  713. }
  714.  
  715. if (lastFishContainerI == -1)
  716. observer.onNext(null);
  717.  
  718. var currentFishContainerCount:number = 0;
  719. for (var i:number = 0; i < bs.length; i++) {
  720. var building:Building = bs[i];
  721. if (building instanceof Hatchery || building instanceof SeaCage) {
  722. //var hatchery: Hatchery = building as Hatchery;
  723. var fishContainer:FishContainer = building as FishContainer;
  724. currentFishContainerCount++;
  725. const fishContainerModel: any = {};
  726. fishContainerModel.name = fishContainer.name;
  727. fishContainerModel.specie = fishContainer.specie;
  728. var amountOfFish:number = 0;
  729.  
  730. if (building instanceof Hatchery) {
  731. for (var j:number = 0; j < (building as Hatchery).bassins.length; j++)
  732. amountOfFish += (building as Hatchery).bassins[j].amountOfFishes;
  733. } else if (building instanceof SeaCage) {
  734. amountOfFish = (building as SeaCage).amountOfFish;
  735. }
  736. fishContainerModel.amountOfFish = amountOfFish;
  737. const models:Model[] = [];
  738.  
  739. console.log("FISHCONTAINER:");
  740. console.log(JSON.stringify(fishContainer));
  741.  
  742. let isStandardFeedingModel: boolean =
  743. user.fishType1CustomFeedingModelId != fishContainer.feedingModelId &&
  744. user.fishType2CustomFeedingModelId != fishContainer.feedingModelId &&
  745. user.fishType3CustomFeedingModelId != fishContainer.feedingModelId;
  746.  
  747. this.getFeedingModelById(i, fishContainer, fishContainer.feedingModelId, isStandardFeedingModel).subscribe(feedingModelData => {
  748. models.push(feedingModelData.model == null ? null : feedingModelData.model);
  749. this.getPhModelById(feedingModelData.hatcheryI, feedingModelData.building, feedingModelData.building.phModelId).subscribe(phModelData => {
  750. models.push(phModelData.model == null ? null : phModelData.model);
  751. this.getOxygenModelById(phModelData.hatcheryI, phModelData.building, phModelData.building.oxygenModelId).subscribe(oxygenModelData => {
  752. models.push(oxygenModelData.model == null ? null : oxygenModelData.model);
  753. this.getMortalityModelById(oxygenModelData.building.mortalityModelId).subscribe((mortalityModel: Model) => {
  754. count++;
  755. models.push(mortalityModel == null ? null : mortalityModel);
  756. fishContainerModel["models"] = models;
  757. fishContainerModels.push(fishContainerModel);
  758. //if (oxygenModelData.hatcheryI == lastFishContainerI)
  759. if (count == total)
  760. observer.onNext(fishContainerModels);
  761. });
  762. });
  763. });
  764. });
  765. }
  766. }
  767. });
  768. }
  769. )
  770. }
  771.  
  772. public getFeedingModelByIdRoute(id: string): Observable<FeedingModel> {
  773. return Observable.fromPromise(this.constantInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next());
  774. }
  775.  
  776. public getFeedingModelsForSpecie(specie:string):Observable<FeedingModel[]> {
  777. return Observable.create<FeedingModel[]>(
  778. observer => {
  779. let models = [];
  780. this.constantInputModelCollection.find({specie: specie}).forEach(doc => models.push(doc == null ? null : new FeedingModel(doc._id, doc.name, doc.specie, doc.data)), (error) => {
  781. observer.onNext(models)
  782. });
  783. }
  784. )
  785. }
  786.  
  787. public getHatcheryFishCountHistory(token: string): Observable<Model> {
  788. var user:string = TokenManager.getField(token, "username");
  789.  
  790. return Observable.create<Model>(o => {
  791. Observable.fromPromise<CursorResult>(this.historyCollection.find({username: user}).sort({_id: -1}).next())
  792. .subscribe(d => {
  793. var model:Model = null;
  794.  
  795.  
  796.  
  797. return o.onNext(model);
  798. });
  799. });
  800. }
  801.  
  802. private updateUserBuildings(token:string, buildings:Building[]):Observable<Building[]> {
  803. return Observable.create<Building[]>(
  804. observer => {
  805. if (TokenManager.validate(token)) {
  806. //this.checkForOxygenAndPhModels(buildings).subscribe((newBuildings: Building[]) => {
  807. // In newBuildings, ALL hatcheries have an oxygen and phModel generated, also the new ones
  808. var username:string = TokenManager.getField(token, "username");
  809. Observable.fromPromise<UpdateWriteOpResult>(this.userCollection.updateOne({username: username}, {$set: {buildings: buildings/*newBuildings*/}}, {})).subscribe((result:UpdateWriteOpResult) => observer.onNext(buildings/*newBuildings*/));
  810. //});
  811. } else observer.onNext(null);
  812. }
  813. );
  814. }
  815.  
  816. private readUser(username:string):Observable<User> {
  817. return Observable.fromPromise<CursorResult>(this.userCollection.find({username: username}).limit(1).next()).map(
  818. doc =>
  819. doc == null ? null : new User(doc.username, doc.password, doc.money, doc.day, doc.registeredNumber, doc.hasAquaSmart, doc.profileLevel, doc.buildings, doc.storms, doc.temperatureModelId, doc.oxygenModelId, doc.phModelId, doc.fishType1CustomFeedingModelId, doc.fishType2CustomFeedingModelId, doc.fishType3CustomFeedingModelId, doc._id)
  820. );
  821. }
  822.  
  823. private getDataFromRegisteredNumber(registeredNumber:number): Observable<User> {
  824. return Observable.create<User>(
  825. observer => {
  826. Observable.fromPromise<CursorResult>(this.userCollection.find({registeredNumber: registeredNumber}).limit(1).next()).map(
  827. doc => {
  828. return doc == null ? null : new User(doc.username, "nice try ;)", doc.money, doc.day, doc.registeredNumber, doc.hasAquaSmart, doc.profileLevel, doc.buildings, doc.storms, doc.temperatureModel, doc.oxygenModelId, doc.phModelId, doc.fishType1CustomFeedingModelId, doc.fishType2CustomFeedingModelId, doc.fishType3CustomFeedingModelId, doc._id);
  829. }
  830. ).subscribe((user:User) => observer.onNext(user));
  831. }
  832. );
  833. }
  834.  
  835. public updateProfile(username: string, aquasmart: boolean, profileLevel: number): Observable<any> {
  836. return Observable.create<any>(
  837. observer =>
  838. Observable.fromPromise<CursorResult>(this.userCollection.updateOne({username: username}, {$set: {hasAquaSmart: aquasmart, profileLevel: profileLevel}}, {})).subscribe(() => observer.onNext(null))
  839. );
  840. }
  841.  
  842. private calculateFatalitiesSeaCage(user: User, temperatureModel: Model, seaCage: SeaCage, settings: Settings): number {
  843. var fatalityPercentage: number = settings.percentageOfMortalitySeacage;
  844. if (seaCage.visitedSea)
  845. fatalityPercentage -= 0.04;
  846. if (seaCage.visitedBoat)
  847. fatalityPercentage -= 0.01;
  848.  
  849. if (temperatureModel.data[user.day] <= settings.minWaterTemperature || temperatureModel.data[user.day] >= settings.maxWaterTemperature)
  850. fatalityPercentage += 0.02;
  851.  
  852. console.log("Seacage fish: " + seaCage.amountOfFish + " - " + (seaCage.amountOfFish * fatalityPercentage));
  853.  
  854. return seaCage.amountOfFish * fatalityPercentage;
  855. //todo insert value into mortality model
  856. }
  857.  
  858. private calculateFatalitiesBassin(user: User, temperatureModel: Model, hatchery: Hatchery, bassin: Bassin, settings: Settings): number {
  859. var fatalityPercentage: number = settings.percentageOfMortalityHatchery;
  860. if (hatchery.visitedHatchery)
  861. fatalityPercentage -= 0.02;
  862.  
  863. if (temperatureModel.data[user.day] <= settings.minWaterTemperature || temperatureModel.data[user.day] >= settings.maxWaterTemperature)
  864. fatalityPercentage += 0.02;
  865.  
  866. return bassin.amountOfFishes * fatalityPercentage;
  867. //todo insert value into mortality model
  868. }
  869.  
  870. public changeFeedingModel(token:string, hatcheryNumber:number, transformation:number) {
  871. //todo: haal uit hatchery welke vissoort er is -> haal standaard model voor vissoort
  872. let username:string = TokenManager.getField(token, "username");
  873. this.readUser(username).subscribe(
  874. user => {
  875. for (var i:number = 0; i < user.buildings.length; i++) {
  876. let buildingName:string = user.buildings[i].name.toLowerCase();
  877. let splitted:string[] = buildingName.split("_");
  878. /*if (buildingName.indexOf("hatchery") > -1 && +splitted[splitted.length - 1] == hatcheryNumber) {
  879. console.log("FOUND HATCHERY NUMBER : " + hatcheryNumber);
  880. } else {
  881. console.log("NOT YET FOUND HATCHERY NUMBER : " + hatcheryNumber + ", currently at: " + i);
  882. }*/
  883. }
  884. }
  885. );
  886. }
  887.  
  888. public getFeedingModelById(hatcheryI:number, building:Building, id: string, isStandardFeedingModel: boolean):Observable<any> {
  889. console.log("Trying to get feeding model by id: " + id);
  890. return Observable.create<any>(
  891. observer => {
  892. if (id == null || id == "")
  893. observer.onNext({model: null, building: building, hatcheryI: hatcheryI});
  894. else {
  895. if (isStandardFeedingModel) {
  896. Observable.fromPromise<CursorResult>(this.constantInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next()).map(
  897. doc => {
  898. var returnObject = {};
  899. console.log("ReturnObject.model: " + doc);
  900. returnObject["model"] = (doc == null ? null : new Model(doc.name, doc.data));
  901. returnObject["building"] = building;
  902. returnObject["hatcheryI"] = hatcheryI;
  903. return returnObject;
  904. }
  905. ).subscribe(returnObject => observer.onNext(returnObject));
  906. } else {
  907. Observable.fromPromise<CursorResult>(this.generatedInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next()).map(
  908. doc => {
  909. var returnObject = {};
  910. console.log("ReturnObject.model: " + doc);
  911. returnObject["model"] = (doc == null ? null : new Model(doc.name, doc.data));
  912. returnObject["building"] = building;
  913. returnObject["hatcheryI"] = hatcheryI;
  914. return returnObject;
  915. }
  916. ).subscribe(returnObject => observer.onNext(returnObject));
  917. }
  918. }
  919. }
  920. );
  921. }
  922.  
  923. private getPhModelById(hatcheryI:number, building:Building, id?:string):Observable<any> {
  924. return Observable.create<any>(
  925. observer => {
  926. if (id == null || id == "")
  927. observer.onNext({model: null, building: building, hatcheryI: hatcheryI});
  928. else {
  929. Observable.fromPromise<CursorResult>(this.generatedInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next()).map(
  930. doc => {
  931. var returnObject = {};
  932. returnObject["model"] = (doc == null ? null : new Model(doc.name, doc.data));
  933. returnObject["building"] = building;
  934. returnObject["hatcheryI"] = hatcheryI;
  935. return returnObject;
  936. }
  937. ).subscribe(returnObject => observer.onNext(returnObject));
  938. }
  939. }
  940. );
  941. }
  942.  
  943. private getOxygenModelById(hatcheryI:number, building:Building, id:string):Observable<any> {
  944. return Observable.create<any>(
  945. observer => {
  946. if (id == null || id == "")
  947. observer.onNext({model: null, building: building, hatcheryI: hatcheryI});
  948. else {
  949. Observable.fromPromise<CursorResult>(this.generatedInputModelCollection.find({_id: new ObjectID(id)}).limit(1).next()).map(
  950. doc => {
  951. var returnObject = {};
  952. returnObject["model"] = (doc == null ? null : new Model(doc.name, doc.data));
  953. returnObject["building"] = building;
  954. returnObject["hatcheryI"] = hatcheryI;
  955. return returnObject;
  956. }
  957. ).subscribe(returnObject => observer.onNext(returnObject));
  958. }
  959. }
  960. );
  961. }
  962.  
  963. /* private generateOxygenAndPhModelForHatcheryIfNecessary(i: number, hatchery: Hatchery): Observable<any> {
  964. return Observable.create<any>(
  965. observer => {
  966. if ((hatchery.phModelId == null) && // building has no phModel
  967. (hatchery.oxygenModelId == null)) { // && building has no oxygenModel
  968. this.generateOxygenModel().subscribe((oxygenModelId:ObjectID) => {
  969. this.generatePhModel().subscribe((phModelId:ObjectID) => {
  970. var returnObject = {};
  971. hatchery.oxygenModelId = oxygenModelId.toString();
  972. hatchery.phModelId = phModelId.toString();
  973. returnObject["building"] = hatchery;
  974. returnObject["i"] = i;
  975. observer.onNext(returnObject);
  976. });
  977. });
  978. } else observer.onNext({building: hatchery, i: i});
  979. }
  980. );
  981. }*/
  982.  
  983. /*private checkForOxygenAndPhModels(buildings: Building[]): Observable<Building[]> {
  984. return Observable.create<Building[]>(
  985. observer => {
  986. var lastHatcheryI: number = -1;
  987. for (var i: number = 0; i < buildings.length; i++) {
  988. if (buildings[i].name.indexOf("hatchery") > -1)
  989. lastHatcheryI = i;
  990. }
  991.  
  992. for (var i: number = 0; i < buildings.length; i++) {
  993. //if (buildings[i].name.indexOf("hatchery") > -1) {
  994. if (buildings[i] instanceof Hatchery) {
  995. this.generateOxygenAndPhModelForHatcheryIfNecessary(i, buildings[i] as Hatchery).subscribe(returnObject => {
  996. buildings[returnObject.i] = returnObject.building;
  997. if (+returnObject.i === +lastHatcheryI)
  998. observer.onNext(buildings);
  999. });
  1000. }
  1001. }
  1002. }
  1003. );
  1004. }*/
  1005.  
  1006. public getOpenDataUsers():Observable<string[]> {
  1007. return Observable.create<string[]>(
  1008. observer => {
  1009. let users: string[] = [];
  1010. this.userCollection.find({hasAquaSmart: "True"}).forEach(
  1011. doc =>
  1012. users.push(doc == null ? null : doc.username), (error) => {
  1013. observer.onNext(users);
  1014. });
  1015. }
  1016. );
  1017. }
  1018. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement