Complete location as a criteria for search
This commit is contained in:
		
							
								
								
									
										114
									
								
								src/db.js
									
									
									
									
									
								
							
							
						
						
									
										114
									
								
								src/db.js
									
									
									
									
									
								
							@@ -19,7 +19,7 @@ const getClient = async () => {
 | 
			
		||||
 | 
			
		||||
    if ((await client.query("SELECT * FROM cities")).rowCount < 6079) {
 | 
			
		||||
        await client.query("DELETE FROM cities");
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        //Not sure if pg has support for such kind of things, sooooooooo 
 | 
			
		||||
        exec(`psql -h ${process.env.POSTGRES_HOST} -p ${process.env.POSTGRES_PORT} -d ${process.env.POSTGRES_DB} -U ${process.env.POSTGRES_USER} -f ./cities.sql`, (error) => {
 | 
			
		||||
            if (error) logError(error);
 | 
			
		||||
@@ -61,33 +61,50 @@ const eraseUserMedia = async (roomId) => {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const selectProfilesForUser = async (roomId) => {
 | 
			
		||||
    let myInterest = (await db.query("SELECT interest FROM users WHERE room_id = $1", [roomId])).rows[0].interest;
 | 
			
		||||
    let mySex = (await db.query("SELECT sex FROM users WHERE room_id = $1", [roomId])).rows[0].sex;
 | 
			
		||||
    let userAge = (await db.query("SELECT age FROM users WHERE room_id = $1", [roomId])).rows[0].age;
 | 
			
		||||
    //Selecting profiles other than user's and with difference in age +-2.
 | 
			
		||||
    let user;
 | 
			
		||||
    if (myInterest === 'b') // both, no matter what sex
 | 
			
		||||
        user = (await db.query(`SELECT
 | 
			
		||||
                                    room_id, name, age, sex, description, country, city FROM users
 | 
			
		||||
                                WHERE
 | 
			
		||||
                                    age::numeric <@ ANY(ARRAY[numrange($1 - 2, $1 + 2)])
 | 
			
		||||
                                AND room_id != $2
 | 
			
		||||
                                AND (interest = $3 OR interest = 'b')
 | 
			
		||||
                                ORDER BY RANDOM()
 | 
			
		||||
                                LIMIT 1`, [userAge, roomId, mySex])
 | 
			
		||||
        ).rows[0];
 | 
			
		||||
    else {
 | 
			
		||||
        user = (await db.query(`SELECT 
 | 
			
		||||
                                    room_id, name, age, sex, description, country, city FROM users
 | 
			
		||||
                                WHERE
 | 
			
		||||
                                    age::numeric <@ ANY(ARRAY[numrange($1 - 2, $1 + 2)])
 | 
			
		||||
                                AND room_id != $2
 | 
			
		||||
                                AND sex = $3
 | 
			
		||||
                                AND (interest = $4 OR interest = 'b')
 | 
			
		||||
                                ORDER BY RANDOM()
 | 
			
		||||
                                LIMIT 1`, [userAge, roomId, myInterest, mySex])
 | 
			
		||||
        ).rows[0];
 | 
			
		||||
    }
 | 
			
		||||
    const { myrange, myinterest, mysex, myage, mycity, mycountry } = (await db.query(`SELECT range AS myrange, 
 | 
			
		||||
                                                                                             interest AS myinterest, 
 | 
			
		||||
                                                                                             sex AS mysex, 
 | 
			
		||||
                                                                                             age AS myage, 
 | 
			
		||||
                                                                                             city AS mycity, 
 | 
			
		||||
                                                                                             country AS mycountry 
 | 
			
		||||
                                                                                      FROM users WHERE room_id = $1`, [roomId])
 | 
			
		||||
    ).rows[0];
 | 
			
		||||
    const { lat, lng } = (await db.query("SELECT lat, lng FROM cities WHERE name = $1 AND country = $2", [mycity, mycountry])).rows[0];
 | 
			
		||||
    //Selecting profiles other than user's and fitting their needs
 | 
			
		||||
    /*
 | 
			
		||||
    2 * ASIN(SQRT(
 | 
			
		||||
                                                                                POWER(SIN( (deg2rad(lat - $6::double precision)) / 2 ), 2) 
 | 
			
		||||
                                                                                + COS(deg2rad(lat)) 
 | 
			
		||||
                                                                                * COS(deg2rad($6::double precision)) 
 | 
			
		||||
                                                                                * POWER(SIN(deg2rad(lng - $7::double precision)/2), 2) 
 | 
			
		||||
                                                                             )) 
 | 
			
		||||
                                                                             * 6371 <= $5::double precision
 | 
			
		||||
    */
 | 
			
		||||
    let user = (await db.query(`SELECT 
 | 
			
		||||
                                room_id, name, age, sex, description, country, city FROM users
 | 
			
		||||
                            WHERE
 | 
			
		||||
                                age::numeric <@ ANY(ARRAY[numrange($1 - 2, $1 + 2)])
 | 
			
		||||
                            AND room_id != $2
 | 
			
		||||
                            AND ${myinterest !== 'b' ? "sex = $3" : "$3 = $3 AND $4 = $4 AND $5 = $5 AND $6 = $6 AND $7 = $7"}
 | 
			
		||||
                            AND ${myrange !== 0 ?
 | 
			
		||||
                                `city = ANY(ARRAY(SELECT name 
 | 
			
		||||
                                                    FROM cities 
 | 
			
		||||
                                                    WHERE name = ANY(ARRAY(SELECT name 
 | 
			
		||||
                                                                            FROM cities 
 | 
			
		||||
                                                                            WHERE 
 | 
			
		||||
                                                                            check_distance($6::double precision, $7::double precision, lat, lng, $5::double precision)
 | 
			
		||||
                                                                    
 | 
			
		||||
                                                    ))
 | 
			
		||||
                                ))`
 | 
			
		||||
                                :
 | 
			
		||||
                                `check_distance($6::double precision, $7::double precision, (SELECT lat FROM cities WHERE name = city AND cities.country = country), (SELECT lng FROM cities WHERE name = city AND cities.country = country), range)`
 | 
			
		||||
                            }
 | 
			
		||||
                            AND (range >= $5::double precision AND range != 0)
 | 
			
		||||
                            AND (interest = $4 OR interest = 'b')
 | 
			
		||||
                            ORDER BY RANDOM()
 | 
			
		||||
                            LIMIT 1`, [myage, roomId, myinterest, mysex, myrange, lat, lng])
 | 
			
		||||
    ).rows[0];
 | 
			
		||||
 | 
			
		||||
    if (!user) return null;
 | 
			
		||||
    let media = await getUserProfilePictures(user.room_id);
 | 
			
		||||
 | 
			
		||||
@@ -174,6 +191,43 @@ const getUserLanguage = async (roomId) => {
 | 
			
		||||
    return (await db.query("SELECT language FROM users WHERE room_id = $1", [roomId])).rows[0].language;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const checkCountry = async (name) => {
 | 
			
		||||
    let res = (await db.query(`SELECT country AS name, levenshtein(country, $1) AS similarity
 | 
			
		||||
                               FROM cities
 | 
			
		||||
                               ORDER BY similarity ASC
 | 
			
		||||
                               LIMIT 3`, [name])
 | 
			
		||||
    ).rows;
 | 
			
		||||
 | 
			
		||||
    if (res[0].similarity == 0) { // 'similarity' is actually inversed. The less 'similarity', the more it similar. 0 means the same
 | 
			
		||||
        return {
 | 
			
		||||
            exists: true
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
        exists: false,
 | 
			
		||||
        variants: res
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const checkCity = async (name) => {
 | 
			
		||||
    let res = (await db.query(`SELECT name, country, levenshtein(name, $1) AS similarity
 | 
			
		||||
                               FROM cities
 | 
			
		||||
                               ORDER BY similarity ASC
 | 
			
		||||
                               LIMIT 5`, [name])
 | 
			
		||||
    ).rows;
 | 
			
		||||
 | 
			
		||||
    if (res[0].similarity == 0) {
 | 
			
		||||
        return {
 | 
			
		||||
            exists: true,
 | 
			
		||||
            country: res[0].country
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
        exists: false,
 | 
			
		||||
        variants: res
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export {
 | 
			
		||||
    eraseUser,
 | 
			
		||||
    appendUserPictures,
 | 
			
		||||
@@ -196,5 +250,7 @@ export {
 | 
			
		||||
    getUnreadMessages,
 | 
			
		||||
    markMessageAsRead,
 | 
			
		||||
    setUserLanguage,
 | 
			
		||||
    getUserLanguage
 | 
			
		||||
    getUserLanguage,
 | 
			
		||||
    checkCountry,
 | 
			
		||||
    checkCity
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										36
									
								
								src/index.js
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								src/index.js
									
									
									
									
									
								
							@@ -32,7 +32,9 @@ import {
 | 
			
		||||
    setUserState,
 | 
			
		||||
    uploadMediaAsMessage,
 | 
			
		||||
    setUserLanguage,
 | 
			
		||||
    getUserLanguage
 | 
			
		||||
    getUserLanguage,
 | 
			
		||||
    checkCountry,
 | 
			
		||||
    checkCity
 | 
			
		||||
} from './db.js';
 | 
			
		||||
 | 
			
		||||
import { processRequest, showRandomProfileToUser, showNewLikes } from "./interactions.js";
 | 
			
		||||
@@ -84,15 +86,41 @@ client.on("room.message", async (roomId, event) => {
 | 
			
		||||
 | 
			
		||||
                break;
 | 
			
		||||
            case "country":
 | 
			
		||||
                let checkResultCountry = await checkCountry(answer);
 | 
			
		||||
                if (!checkResultCountry.exists) {
 | 
			
		||||
                    console.log(checkResultCountry.variants)
 | 
			
		||||
                    await client.sendText(roomId, i18n.t(
 | 
			
		||||
                        ["errors", "wrongcountry"],
 | 
			
		||||
                        {
 | 
			
		||||
                            first: checkResultCountry.variants[0].name,
 | 
			
		||||
                            second: checkResultCountry.variants[1].name,
 | 
			
		||||
                            third: checkResultCountry.variants[2].name
 | 
			
		||||
                        }
 | 
			
		||||
                    ));
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                await processRequest(client, roomId, current_action, answer, 'city');
 | 
			
		||||
                break;
 | 
			
		||||
            case "city":
 | 
			
		||||
                let checkResultCity = await checkCity(answer); 
 | 
			
		||||
                if (!checkResultCity.exists) {
 | 
			
		||||
                    await client.sendText(roomId, i18n.t(
 | 
			
		||||
                        ["errors", "wrongcity"],
 | 
			
		||||
                        {
 | 
			
		||||
                            first: checkResultCity.variants[0].name,
 | 
			
		||||
                            second: checkResultCity.variants[1].name,
 | 
			
		||||
                            third: checkResultCity.variants[2].name,
 | 
			
		||||
                            fourth: checkResultCity.variants[3].name,
 | 
			
		||||
                            fifth: checkResultCity.variants[4].name,
 | 
			
		||||
                        }
 | 
			
		||||
                    ));
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                await processRequest(client, roomId, current_action, answer, 'range');
 | 
			
		||||
                break;
 | 
			
		||||
            case "range":
 | 
			
		||||
                answer = parseInt(answer.split(" ")[0]);
 | 
			
		||||
                console.log(answer)
 | 
			
		||||
                if (!answer) {
 | 
			
		||||
                if (!answer && answer != 0) {
 | 
			
		||||
                    await client.sendText(roomId, i18n.t(["setup", "range"]));
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -187,7 +215,7 @@ client.on("room.message", async (roomId, event) => {
 | 
			
		||||
 | 
			
		||||
                    return;
 | 
			
		||||
                } else if (answer == '🏠️' || answer == '4') {
 | 
			
		||||
                    await client.sendText(roomId, messages.general.menu);
 | 
			
		||||
                    await client.sendText(roomId, i18n.t(["general", "menu"]));
 | 
			
		||||
                    await setUserState(roomId, 'menu');
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -87,8 +87,7 @@ ${chosenProfile.description}`;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    await client.sendText(roomId, messages.general.rate);
 | 
			
		||||
    await client.sendText(roomId, i18n.t(["general", "rate"]));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const showProfileToUser = async (client, roomId, profileId) => {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user