Skip to content

Commit

Permalink
Merge pull request #57 from TomFanella4/development
Browse files Browse the repository at this point in the history
Sprint 3
  • Loading branch information
TomFanella4 authored Apr 28, 2018
2 parents a7dd5a7 + bf4f5de commit 23f6ac1
Show file tree
Hide file tree
Showing 47 changed files with 1,481 additions and 482 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Mobile application for iOS and Android used to connect busy professionals on the
- `GET: /`
- `POST: /login/<linkedin code>`
- `POST: /test/<type of test>`
- `POST: /imitateuser/<user id>`
- Authenticated
- `POST: /refreshtoken`
- `POST: /meetover/<other user id>`
Expand Down
9 changes: 8 additions & 1 deletion backend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ vendor/
.envrc
firebase-config.json
data/otherJobs/
data/data.exe
data/data.exe
data/FinalTestUsers.json
data/corpus.dat
data/jobs.csv
data/meetOver.model
data/rawTestUsers.json
data/transcripts.csv
matching/main.go
9 changes: 8 additions & 1 deletion backend/data/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,14 @@ func jobDataToUser(jd JobData, rawUser User) (User, error) {
rawUser.Profile.Headline = js.Titles[r(len(js.Titles))]
rawUser.Profile.Industry = js.Skills[r(len(js.Skills))]
rawUser.Profile.FormattedName = rawUser.Profile.FirstName + " " + rawUser.Profile.LastName
rawUser.Profile.ID = rawUser.ID
start = r(len(js.Description)) / 2
rawUser.Profile.Summary = js.Description[start:]
summaryLen := 150
if len(js.Description[start:]) > summaryLen {
rawUser.Profile.Summary = js.Description[start : start+summaryLen]
} else {
rawUser.Profile.Summary = js.Description[start:]
}
return rawUser, nil
}

Expand Down Expand Up @@ -199,6 +205,7 @@ func genTechUsers(rawUsers []User) []User {
} else {
profile.Summary = summary
}
profile.ID = u.ID
rawUsers[i] = u
rawUsers[i].Profile = profile
}
Expand Down
4 changes: 2 additions & 2 deletions backend/data/stopwords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ $
*
..
...
###
'll
's
'm
Expand Down Expand Up @@ -214,7 +215,6 @@ your
yours
yourself
yourselves
###
return
arent
cant
Expand Down Expand Up @@ -254,4 +254,4 @@ wouldnt
youd
youll
youre
youve
youve
48 changes: 36 additions & 12 deletions backend/firebase/Messaging.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@ import (
"time"
)

func createThreadForUser(ID1 string, threadID string, ID2 string, origin string) error {
func createThreadForUser(ID1 string, threadID string, ID2 string, origin string, initialMessage string) error {
threadList, err := fbClient.Ref("/users/" + ID1 + "/threadList/" + threadID)
if err != nil {
return err
}

threadInfo := map[string]interface{}{
"_id": threadID,
"userID": ID2,
"origin": origin,
"status": "pending",
"_id": threadID,
"userID": ID2,
"origin": origin,
"status": "pending",
"requestMessage": initialMessage,
}
if err := threadList.Update(threadInfo); err != nil {
return err
Expand All @@ -25,7 +26,7 @@ func createThreadForUser(ID1 string, threadID string, ID2 string, origin string)
}

// AddThread Creates a messaging thread between two users
func AddThread(P1 string, P2 string) error {
func AddThread(P1 string, P2 string, initialMessage string) error {
ID1, ID2 := "", ""
origin1, origin2 := "", ""

Expand All @@ -41,25 +42,48 @@ func AddThread(P1 string, P2 string) error {

threadID := ID1 + separator + ID2

if err := createThreadForUser(ID1, threadID, ID2, origin1); err != nil {
if err := createThreadForUser(ID1, threadID, ID2, origin1, initialMessage); err != nil {
return err
}
if err := createThreadForUser(ID2, threadID, ID1, origin2); err != nil {
if err := createThreadForUser(ID2, threadID, ID1, origin2, initialMessage); err != nil {
return err
}

thread, err := fbClient.Ref("/messages/" + threadID + "/0")
initiatorUser, err := GetUser(P1)
if err != nil {
return err
}

initialMessage := map[string]interface{}{
initiator := map[string]interface{}{
"_id": initiatorUser.Profile.ID,
"avatar": initiatorUser.Profile.PictureURL,
"name": initiatorUser.Profile.FormattedName,
}

startMessageMap := map[string]interface{}{
"_id": 0,
"text": "Welcome to the chat!",
"text": "Start of the chat",
"createdAt": time.Now().UTC().Format(time.RFC3339),
"system": true,
}
if err := thread.Update(initialMessage); err != nil {
initialMessageMap := map[string]interface{}{
"_id": 1,
"text": initialMessage,
"createdAt": time.Now().UTC().Format(time.RFC3339),
"user": initiator,
}

messagesMap := map[string]interface{}{
"0": startMessageMap,
"1": initialMessageMap,
}

threadRef, err := fbClient.Ref("/messages/" + threadID)
if err != nil {
return err
}

if err := threadRef.Update(messagesMap); err != nil {
return err
}

Expand Down
18 changes: 14 additions & 4 deletions backend/firebase/User.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"meetover/backend/user"
)

const filterUsers = false

// InitUser Updates access token if user exists or adds a new User as user in firebase
func InitUser(p user.Profile, aTokenResp user.ATokenResponse) (bool, error) {
// Check if token exists
Expand Down Expand Up @@ -62,21 +64,29 @@ func GetUser(uid string) (user.User, error) {
}

// GetProspectiveUsers Get the list of people for matching in the area
func GetProspectiveUsers(coords location.Geolocation, radius int, lastUpdate int) ([]user.User, error) {
// TODO:
func GetProspectiveUsers(coords location.Geolocation, radius float64, lastUpdate int) ([]user.User, error) {
// Filter users by Geolocation and radius
userMap := map[string]user.User{}
users := []user.User{}

//create oldest date acceptable
oldestStamp := location.MakeTimestamp((int64)(lastUpdate))

userRef, err := fbClient.Ref("/users")
if err != nil {
fmt.Println("error getting userRef\n", err)
return []user.User{}, err
}

if err := userRef.Value(&userMap); err != nil {
fmt.Println("error getting users\n", err)
return []user.User{}, err
}

for k := range userMap {
users = append(users, userMap[k])
for _, user := range userMap {
if !filterUsers || (user.Location.TimeStamp > oldestStamp && location.InRadius(coords, user.Location, radius)) {
users = append(users, user)
}
}

return users, nil
Expand Down
13 changes: 11 additions & 2 deletions backend/location/Location.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package location
import (
"fmt"
"math"
"time"
)

// Address is a our location metric
Expand All @@ -14,12 +15,15 @@ type Address struct {

// Geolocation - latitide and longitude and last time of update
type Geolocation struct {
Accuracy float64 `json:"accuracy"`
Accuracy int64 `json:"accuracy"`
Latitude float64 `json:"latitude"`
Longitude float64 `json:"longitude"`
TimeStamp float64 `json:"timestamp"`
TimeStamp int64 `json:"timestamp"`
}

//hour in miliseconds
const MILI_HOUR = (int64)(3600000)

// QueryLocation will return the location for the given coordinates
func QueryLocation(coords string) (Address, error) {
// long := strings.Split(coords, ",")[0]
Expand Down Expand Up @@ -57,3 +61,8 @@ func Distance(lat1, lon1, lat2, lon2 float64) float64 {
h := hsin(la2-la1) + math.Cos(la1)*math.Cos(la2)*hsin(lo2-lo1)
return 2 * r * math.Asin(math.Sqrt(h))
}

//Records Timestamps
func MakeTimestamp(setback int64) int64 {
return (time.Now().UnixNano() / int64(time.Millisecond) - MILI_HOUR*(int64)(setback))
}
119 changes: 119 additions & 0 deletions backend/matching/Distance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package matching

import (
"fmt"
"io/ioutil"
"math"
"meetover/backend/user"
"strings"

"gonum.org/v1/gonum/mat"
)

// distanceThresh - minimum meaningful distance
var distanceThresh = 100.0

// getStopWords - gets the stop words from file
func getStopWords(fileName string) map[string]bool {
b, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Print(err)
}
str := string(b)
swarr := strings.Split(str, "\n")
swm := make(map[string]bool)
for _, sw := range swarr {
swm[sw] = true
}
return swm
}

// StripStopWords -
func StripStopWords(str []string) []string {
stopFile := DataDir + "stopwords.txt"
stopWords := getStopWords(stopFile)
for i, w := range str {
if _, exists := stopWords[strings.ToLower(w)]; exists {
// fmt.Println("found :" + w)
str = append(str[:i], str[i+1:]...)
}
}
return str
}

// nestedDistance - distance metric between par vectors
func nestedDistance(src []*mat.VecDense, dst []*mat.VecDense) float64 {
d := 0.0
for _, si := range src {
for _, di := range dst {
temp := mat.NewVecDense(WordModelDimension, nil)
temp.SubVec(si, di)
d += flattenVector(WordModelDimension, temp)
}
}
// fmt.Printf("distance: %f\n", d)
if d > distanceThresh {
return d
}
return math.MaxFloat64
}
func flattenVector(rows int, vec mat.Matrix) float64 {
res := 0.0
for i := 0; i < rows; i++ {
res += math.Abs(vec.At(i, 0))
}
return res
}

// parToVector converts a string representation of user to numeric vector using
// the given word embeddings model
func parToVector(userStr string, model map[string][]float64) []*mat.VecDense {
res := []*mat.VecDense{}
par := strings.Split(userStr, " ")
par = StripStopWords(par)
i := 0
for _, w := range par {
w = strings.TrimSpace(strings.ToLower(w))
if len(w) <= 1 {
continue
}
if val, found := model[w]; found {
if len(val) == WordModelDimension {
vec := mat.NewVecDense(WordModelDimension, val)
res = append(res, vec)
i++
}
}
if i > WordModelRandomParam {
break
}
}
for i < WordModelRandomParam {
w := par[random(0, len(par))]
w = strings.TrimSpace(strings.ToLower(w))
if len(w) <= 1 {
continue
}
if val, found := model[w]; found {
if len(val) == WordModelDimension {
vec := mat.NewVecDense(WordModelDimension, val)
res = append(res, vec)
i++
}
}
}
return res
}

// userToString converts the user object to a paragraph for vector translation
func userToString(u user.User) string {
var res string
res = u.MatchStatus.Greeting + " " + u.Profile.Headline + " " + u.Profile.Summary + " " + u.Profile.Industry
for _, pos := range u.Profile.Positions.Values {
res += pos.Company.Industry + " "
res += pos.Company.Name + " "
res += pos.Summary + " "
res += pos.Title
}
return res
}
Loading

0 comments on commit 23f6ac1

Please sign in to comment.