Skip to content

Commit 97ee03f

Browse files
committed
redo to save user clock position, not location
1 parent 76dd0a3 commit 97ee03f

11 files changed

Lines changed: 183 additions & 190 deletions

File tree

migrations/v0_initial_setup.sql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ CREATE TABLE IF NOT EXISTS "user_location_log" (
5353
FOREIGN KEY ('user_id') REFERENCES users('id')
5454
);
5555
**
56-
CREATE TABLE IF NOT EXISTS "user_location" (
56+
CREATE TABLE IF NOT EXISTS "user_position" (
5757
'user_id' INTEGER NOT NULL UNIQUE,
58-
'location_id' INTEGER NOT NULL,
59-
PRIMARY KEY ('user_id', 'location_id'),
58+
'position_id' INTEGER NOT NULL,
59+
PRIMARY KEY ('user_id', 'position_id'),
6060
FOREIGN KEY ('user_id') REFERENCES users('id'),
61-
FOREIGN KEY ('location_id') REFERENCES locations('id')
61+
FOREIGN KEY ('position_id') REFERENCES clock_face('id')
6262
);
6363
**
6464
CREATE TABLE IF NOT EXISTS "position_locations" (

src/controllers/clockFaceController.js

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,40 +2,44 @@ const wizardDAO = require("../dao/wizardDao");
22
const clockFaceDAO = require("../dao/clockFaceDao");
33
const locationDAO = require("../dao/locationDAO");
44

5-
async function getClockPositionFromUserID(user_id, defaultLocationID) {
6-
let location = await wizardDAO.getUserLocationFromUserID(user_id);
7-
let positionLocation = await clockFaceDAO.getClockPositionLocationFromLocationID(location.location_id);
5+
async function getClockPositionFromUserID(user_id) {
6+
let positionInfo = await wizardDAO.getUserClockPositionInfoFromUserID(user_id);
87

9-
if (!positionLocation) {
10-
return clockFaceDAO.getClockPositionFromLocationID(defaultLocationID);
8+
if (!positionInfo) {
9+
return getDefaultClockPosition();
1110
} else {
12-
return clockFaceDAO.getClockPositionFromID(positionLocation.position_id);
11+
return clockFaceDAO.getClockPositionFromID(positionInfo.position_id);
12+
}
13+
}
14+
15+
async function getClockPositionFromLocationID(locationID) {
16+
let clockPositionInfo = await clockFaceDAO.getClockPositionInfoFromLocationID(locationID);
17+
if (!clockPositionInfo) {
18+
return null;
19+
} else {
20+
return clockFaceDAO.getClockPositionFromID(clockPositionInfo.position_id);
1321
}
1422
}
1523

1624
async function getAllUsersClockFacePositions() {
1725
const users = await wizardDAO.getAllUsers();
1826
let usersClockPosition = [];
1927
for (let user of users) {
20-
let userLocation = await wizardDAO.getUserLocationFromUserID(user.id);
21-
let position = await getClockPositionFromUserLocation(userLocation);
22-
let wizard= {name: user.username, position: position};
28+
let clockPosition = await getClockPositionFromUserID(user.id);
29+
let wizard= {name: user.username, position: clockPosition};
2330
usersClockPosition.push(wizard);
2431
}
2532
return usersClockPosition;
2633
}
2734

28-
async function getClockPositionFromUserLocation(userLocation) {
29-
let defaultLocation = await locationDAO.getDefaultLocation();
30-
let positionLocation = await clockFaceDAO.getClockPositionLocationFromLocationID(userLocation.location_id);
31-
if (!positionLocation) {
32-
return clockFaceDAO.getClockPositionFromLocationID(defaultLocation.id);
33-
} else {
34-
return clockFaceDAO.getClockPositionFromID(positionLocation.position_id);
35-
}
35+
async function getDefaultClockPosition() {
36+
const defaultLocation = await locationDAO.getDefaultLocation();
37+
return getClockPositionFromLocationID(defaultLocation.id);
3638
}
3739

3840
module.exports = {
3941
getAllUsersClockFacePositions,
40-
getClockPositionFromUserID
42+
getClockPositionFromUserID,
43+
getClockPositionFromLocationID,
44+
getDefaultClockPosition
4145
};

src/controllers/dbController.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ async function initializeAdminUser() {
7373
'false'
7474
]);
7575
dbConnector.run(`INSERT OR IGNORE INTO user_roles (user_id, role_id) VALUES (1, 1)`);
76-
dbConnector.run(`INSERT OR IGNORE INTO user_location (user_id, location_id) VALUES (1, 1)`);
76+
dbConnector.run(`INSERT OR IGNORE INTO user_position (user_id, position_id) VALUES (1, 13)`);
7777
dbConnector.run(`UPDATE server_settings SET value='true' WHERE setting_name='adminInitialized'`);
7878
dbConnector.run("COMMIT");
7979
});
Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
const locationDAO = require("../dao/locationDAO");
2-
const followerDAO = require("../dao/followerDao");
3-
const loggingDAO = require("../dao/loggingDao");
4-
const wizardDAO = require("../dao/wizardDao");
52
const clockFaceDAO = require("../dao/clockFaceDao");
6-
const clockFaceController = require("./clockFaceController");
7-
const dobby = require("./discordController");
8-
const settingsService = require("../controllers/serverSettingController").default.getInstance();
93

104
async function addLocationInfo(location) {
115
await locationDAO.addLocation(location);
@@ -43,109 +37,9 @@ async function getAllLocationsForClockPositionID(clockPositionID) {
4337
return locations;
4438
}
4539

46-
async function updateUserLocation(userID, coords, isHeartbeat) {
47-
const locations = await locationDAO.getAllLocations();
48-
const followerIDList = [];
49-
50-
// Check for Followers
51-
await followerDAO.getFollowerInfoFromLeadID(userID).then(results => {
52-
for (let followInfo of results) {
53-
followerIDList.push(followInfo.follower_id);
54-
}
55-
});
56-
57-
// Update Location Logs
58-
await loggingDAO.updateUserLocationLog(userID, coords.latitude, coords.longitude);
59-
if (followerIDList.length > 0) {
60-
for (let followerID of followerIDList) {
61-
await loggingDAO.updateUserLocationLog(followerID, coords.latitude, coords.longitude);
62-
}
63-
}
64-
65-
for (let location of locations) {
66-
if (isUserWithinLocation(coords.latitude, coords.longitude, location.latitude, location.longitude, location.radius)) {
67-
await fireLocationUpdate(userID, location.id, isHeartbeat);
68-
await wizardDAO.updateUserLocation(userID, location.id).catch(() =>{
69-
return false;
70-
});
71-
if (followerIDList.length > 0) {
72-
await updateFollowersLocations(followerIDList, location.id);
73-
}
74-
return true;
75-
}
76-
}
77-
78-
const defaultLocation = await locationDAO.getDefaultLocation();
79-
await fireLocationUpdate(userID, defaultLocation.id, isHeartbeat);
80-
await wizardDAO.updateUserLocation(userID, defaultLocation.id).catch(() =>{
81-
return false;
82-
});
83-
if (followerIDList.length > 0) {
84-
await updateFollowersLocations(followerIDList, defaultLocation.id);
85-
}
86-
return true;
87-
}
88-
89-
async function updateFollowersLocations(followers, locationID) {
90-
for (let followerID of followers) {
91-
await fireLocationUpdate(followerID, locationID);
92-
await wizardDAO.updateUserLocation(followerID, locationID);
93-
}
94-
}
95-
96-
async function fireLocationUpdate(userID, locationID, isHeartbeat) {
97-
let clockPosition = await clockFaceDAO.getClockPositionFromLocationID(locationID);
98-
let defaultLocationID = await locationDAO.getDefaultLocation();
99-
await clockFaceController.getClockPositionFromUserID(userID, defaultLocationID).then((result) => {
100-
if (settingsService.getSettingValue("notifyEveryPositionUpdate") === "true") {
101-
sendDiscordPing(userID, clockPosition, isHeartbeat);
102-
} else {
103-
if (result.face_position !== clockPosition.face_position) {
104-
sendDiscordPing(userID, clockPosition, isHeartbeat);
105-
}
106-
}
107-
});
108-
}
109-
110-
async function sendDiscordPing(userID, clockPosition, isHeartbeat) {
111-
await wizardDAO.getUserFromID(userID).then(async (result) => {
112-
if (result.isFollower === "false") {
113-
await dobby.notifyLocationChange(result.username, clockPosition.name, isHeartbeat);
114-
} else {
115-
let leadID = await followerDAO.getLeadIDFromFollowerID(result.id);
116-
let lead = await wizardDAO.getUserFromID(leadID.lead_id);
117-
await dobby.notifyFollowerLocationChange(result.username, lead.username, clockPosition.name);
118-
}
119-
});
120-
}
121-
122-
function isUserWithinLocation(userLat, userLong, locationLat, locationLong, radius) {
123-
return getDistanceFromLatLonInM(userLat, userLong, locationLat, locationLong) <= radius;
124-
}
125-
126-
// From https://stackoverflow.com/a/27943
127-
function getDistanceFromLatLonInM(userLat, userLong, locationLat, locationLong) {
128-
var R = 6371; // Radius of the earth in km
129-
var dLat = deg2rad(locationLat-userLat); // deg2rad below
130-
var dLon = deg2rad(locationLong-userLong);
131-
var a =
132-
Math.sin(dLat/2) * Math.sin(dLat/2) +
133-
Math.cos(deg2rad(userLat)) * Math.cos(deg2rad(locationLat)) *
134-
Math.sin(dLon/2) * Math.sin(dLon/2)
135-
;
136-
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
137-
var d = R * c; // Distance in km
138-
return d * 1000; // Convert to m
139-
}
140-
141-
function deg2rad(deg) {
142-
return deg * (Math.PI/180)
143-
}
144-
14540
module.exports = {
14641
addLocationInfo,
14742
updateLocationInfo,
14843
deleteLocationInfo,
14944
getAllLocationsForClockPositionID,
150-
updateUserLocation
15145
}

src/controllers/wizardController.js

Lines changed: 112 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
const roleDAO = require("../dao/roleDao");
2-
const locationDAO = require("../dao/locationDAO");
32
const loggingDAO = require("../dao/loggingDao");
43
const followerDAO = require("../dao/followerDao");
54
const wizardDAO = require("../dao/wizardDao");
5+
const clockFaceController = require("../controllers/clockFaceController");
6+
const locationDAO = require("../dao/locationDAO");
7+
const clockFaceDAO = require("../dao/clockFaceDao");
8+
const dobby = require("./discordController");
9+
const settingsService = require("../controllers/serverSettingController").default.getInstance();
610

711
async function addUserInfo(username, password, role, isFollower, leadID) {
8-
const defaultLocation = await locationDAO.getDefaultLocation();
12+
const defaultPosition = await clockFaceController.getDefaultClockPosition();
913
await wizardDAO.addUser(username, password, role, isFollower).then(async () => {
1014
let newUser = await wizardDAO.getUserFromName(username)
1115
await roleDAO.addUserToRole(newUser.id, role);
12-
await wizardDAO.setUserLocation(newUser.id, defaultLocation.id);
16+
await wizardDAO.setUserClockPosition(newUser.id, defaultPosition.id);
1317
if (isFollower) {
1418
await updateUserToFollower(newUser.id, leadID);
1519
}
@@ -38,8 +42,107 @@ async function updateUserInfo(user) {
3842
return true;
3943
}
4044

45+
async function handleUserLocationUpdate(userID, coords, isHeartbeat) {
46+
const locations = await locationDAO.getAllLocations();
47+
const followerIDList = [];
48+
49+
// Check for Followers
50+
await followerDAO.getFollowerInfoFromLeadID(userID).then(results => {
51+
for (let followInfo of results) {
52+
followerIDList.push(followInfo.follower_id);
53+
}
54+
});
55+
56+
// Update Location Logs
57+
await loggingDAO.updateUserLocationLog(userID, coords.latitude, coords.longitude);
58+
if (followerIDList.length > 0) {
59+
for (let followerID of followerIDList) {
60+
await loggingDAO.updateUserLocationLog(followerID, coords.latitude, coords.longitude);
61+
}
62+
}
63+
64+
for (let location of locations) {
65+
if (isUserWithinLocation(coords.latitude, coords.longitude, location.latitude, location.longitude, location.radius)) {
66+
let clockPosition = await clockFaceController.getClockPositionFromLocationID(location.id);
67+
await fireLocationUpdate(userID, clockPosition, isHeartbeat);
68+
await wizardDAO.updateUserClockPosition(userID, clockPosition.id).catch(() =>{
69+
return false;
70+
});
71+
if (followerIDList.length > 0) {
72+
await updateFollowersClockPosition(followerIDList, clockPosition.id);
73+
}
74+
return true;
75+
}
76+
}
77+
78+
const defaultClockPosition = await clockFaceController.getDefaultClockPosition();
79+
await fireLocationUpdate(userID, defaultClockPosition, isHeartbeat);
80+
await wizardDAO.updateUserClockPosition(userID, defaultClockPosition.id).catch(() =>{
81+
return false;
82+
});
83+
if (followerIDList.length > 0) {
84+
await updateFollowersClockPosition(followerIDList, defaultClockPosition.id);
85+
}
86+
return true;
87+
}
88+
89+
async function updateFollowersClockPosition(followers, clockPositionID) {
90+
const clockPosition = clockFaceDAO.getClockPositionFromID(clockPositionID);
91+
for (let followerID of followers) {
92+
await fireLocationUpdate(followerID, clockPosition, null);
93+
await wizardDAO.updateUserClockPosition(followerID, clockPositionID);
94+
}
95+
}
96+
97+
async function fireLocationUpdate(userID, clockPosition, isHeartbeat) {
98+
if (settingsService.getSettingValue("notifyEveryPositionUpdate") === "true") {
99+
await sendDiscordPing(userID, clockPosition, isHeartbeat);
100+
} else {
101+
const userClockPosition = await clockFaceController.getClockPositionFromUserID(userID);
102+
if (userClockPosition.face_position !== clockPosition.face_position) {
103+
await sendDiscordPing(userID, clockPosition, isHeartbeat);
104+
}
105+
}
106+
}
107+
108+
async function sendDiscordPing(userID, clockPosition, isHeartbeat) {
109+
await wizardDAO.getUserFromID(userID).then(async (result) => {
110+
if (result.isFollower === "false") {
111+
await dobby.notifyLocationChange(result.username, clockPosition.name, isHeartbeat);
112+
} else {
113+
let leadID = await followerDAO.getLeadIDFromFollowerID(result.id);
114+
let lead = await wizardDAO.getUserFromID(leadID.lead_id);
115+
await dobby.notifyFollowerLocationChange(result.username, lead.username, clockPosition.name);
116+
}
117+
});
118+
}
119+
120+
function isUserWithinLocation(userLat, userLong, locationLat, locationLong, radius) {
121+
return getDistanceFromLatLonInM(userLat, userLong, locationLat, locationLong) <= radius;
122+
}
123+
124+
// From https://stackoverflow.com/a/27943
125+
function getDistanceFromLatLonInM(userLat, userLong, locationLat, locationLong) {
126+
var R = 6371; // Radius of the earth in km
127+
var dLat = deg2rad(locationLat-userLat); // deg2rad below
128+
var dLon = deg2rad(locationLong-userLong);
129+
var a =
130+
Math.sin(dLat/2) * Math.sin(dLat/2) +
131+
Math.cos(deg2rad(userLat)) * Math.cos(deg2rad(locationLat)) *
132+
Math.sin(dLon/2) * Math.sin(dLon/2)
133+
;
134+
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
135+
var d = R * c; // Distance in km
136+
return d * 1000; // Convert to m
137+
}
138+
139+
function deg2rad(deg) {
140+
return deg * (Math.PI/180)
141+
}
142+
143+
41144
async function deleteUserInfo(userID){
42-
await wizardDAO.deleteUserLocation(userID);
145+
await wizardDAO.deleteUserClockPosition(userID);
43146
await loggingDAO.clearUserLocationLog(userID);
44147
await roleDAO.removeUserFromRole(userID);
45148
await wizardDAO.getUserFromID(userID).then(async user => {
@@ -54,9 +157,9 @@ async function deleteUserInfo(userID){
54157

55158
async function updateUserToFollower(followerID, leadID) {
56159
await followerDAO.applyFollowLink(followerID, leadID);
57-
await wizardDAO.getUserLocationFromUserID(leadID).then(async (locationInfo) => {
58-
if (locationInfo) {
59-
await wizardDAO.setUserLocation(followerID, locationInfo.location_id);
160+
await wizardDAO.getUserClockPositionInfoFromUserID(leadID).then(async (clockPositionInfo) => {
161+
if (clockPositionInfo) {
162+
await wizardDAO.setUserClockPosition(followerID, clockPositionInfo.position_id);
60163
}
61164
})
62165
}
@@ -80,5 +183,6 @@ async function removeLeadFromFollowers(userID) {
80183
module.exports = {
81184
addUserInfo,
82185
updateUserInfo,
83-
deleteUserInfo
186+
deleteUserInfo,
187+
handleUserLocationUpdate
84188
};

0 commit comments

Comments
 (0)