Example #1
0
// NewHandler returns the handler for `flixy new`.
func NewHandler(so socketio.Socket) func(string) {
	sockid := so.Id()
	sockip := getRemoteIP(so)

	return func(jsonmsg string) {
		var data models.NewMessage

		if err := json.Unmarshal([]byte(jsonmsg), &data); err != nil {
			log.WithFields(log.Fields{
				"verb":          "flixy new",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Error(err)
		}

		log.WithFields(log.Fields{
			"verb":          "flixy new",
			"member_sockid": sockid,
			"member_remote": sockip,
		}).Debugf("client beginning new session creation", sockid)

		sid := makeNewSessionID()

		vid := data.VideoID
		if vid == 0 {
			log.WithFields(log.Fields{
				"verb":          "flixy new",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Warn("invalid video id?")

			so.Emit("flixy invalid new data", jsonmsg)
			return
		}

		time := data.Time
		nick := data.Nick
		if nick == "" {
			nick = "(no nick)"
		}

		s := models.NewSession(sid, vid, time)
		m := s.AddMember(so, nick)
		members[sockid] = m
		sessions[sid] = s

		so.Emit("flixy new session", s.GetWireSession())
		// TODO make this the new style logging :-)
		log.WithFields(log.Fields{
			"verb":          "flixy new",
			"member_sockid": sockid,
			"member_remote": sockip,
		}).Info("new session created")
	}
}
Example #2
0
// PlayHandler returns the handler for `flixy play`.
func PlayHandler(so socketio.Socket) func(string) {
	sockid := so.Id()
	sockip := getRemoteIP(so)

	return func(jsonmsg string) {
		var data models.PlayMessage

		if err := json.Unmarshal([]byte(jsonmsg), &data); err != nil {
			log.WithFields(log.Fields{
				"verb":          "flixy play",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Error(err)
			return
		}

		sid := data.SessionID

		log.WithFields(log.Fields{
			"verb":          "flixy play",
			"member_sockid": sockid,
			"member_remote": sockip,
			"session_id":    sid,
		}).Debug("user beginning session play")

		s, ok := sessions[sid]
		if !ok {
			log.WithFields(log.Fields{
				"verb":          "flixy play",
				"member_sockid": sockid,
				"member_remote": sockip,
				"invalid_sid":   sid,
			}).Warn("invalid session id")

			so.Emit("flixy invalid session id", sid)
			return
		}

		s.Play()
		log.WithFields(log.Fields{
			"verb":          "flixy play",
			"member_sockid": sockid,
			"member_remote": sockip,
		}).Debug("playing")
	}
}
Example #3
0
// JoinHandler returns the handler for `flixy join`.
func JoinHandler(so socketio.Socket) func(string) {
	sockid := so.Id()
	sockip := getRemoteIP(so)

	return func(jsonmsg string) {
		var data models.JoinMessage

		if err := json.Unmarshal([]byte(jsonmsg), &data); err != nil {
			log.WithFields(log.Fields{
				"verb":          "flixy join",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Error(err)
			return
		}

		sid := data.SessionID
		nick := data.Nick
		if nick == "" {
			nick = "(no nick)"
		}

		s, ok := sessions[sid]
		if !ok {
			log.WithFields(log.Fields{
				"verb":          "flixy join",
				"member_sockid": sockid,
				"member_remote": sockip,
				"invalid_sid":   sid,
			}).Warn("invalid session id")

			so.Emit("flixy invalid session id", sid)
			return
		}

		s.AddMember(so, nick)

		log.WithFields(log.Fields{
			"verb":          "flixy play",
			"member_sockid": sockid,
			"member_remote": sockip,
			"session_id":    sid,
		}).Debug("joining a session")
	}
}
Example #4
0
// SeekHandler returns the handler for `flixy seek`.
func SeekHandler(so socketio.Socket) func(string) {
	sockid := so.Id()
	sockip := getRemoteIP(so)

	return func(jsonmsg string) {
		var data models.SeekMessage

		if err := json.Unmarshal([]byte(jsonmsg), &data); err != nil {
			log.WithFields(log.Fields{
				"verb":          "flixy seek",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Error(err)
			return
		}

		sid := data.SessionID
		ts := data.Time

		s, ok := sessions[sid]
		if !ok {
			log.WithFields(log.Fields{
				"verb":          "flixy seek",
				"member_sockid": sockid,
				"member_remote": sockip,
				"invalid_sid":   sid,
			}).Warn("invalid session id")
			so.Emit("flixy invalid session id", sid)
			return
		}

		log.WithFields(log.Fields{
			"verb":          "flixy seek",
			"member_sockid": sockid,
			"member_remote": sockip,
			"session":       sid,
		}).Debug("setting time")
		s.SetTime(ts)
	}
}
Example #5
0
// SyncHandler returns the handler for `flixy get sync`.
func SyncHandler(so socketio.Socket) func(string) {
	sockid := so.Id()
	sockip := getRemoteIP(so)

	return func(jsonmsg string) {
		var data models.GetSyncMessage

		if err := json.Unmarshal([]byte(jsonmsg), &data); err != nil {
			log.WithFields(log.Fields{
				"verb":          "flixy get sync",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Error(err)
			return
		}

		sid := data.SessionID

		s, ok := sessions[sid]
		if !ok {
			log.WithFields(log.Fields{
				"verb":          "flixy get sync",
				"member_sockid": sockid,
				"member_remote": sockip,
				"invalid_sid":   sid,
			}).Warn("invalid session id")
			so.Emit("flixy invalid session id", sid)
			return
		}

		log.WithFields(log.Fields{
			"verb":          "flixy get sync",
			"member_sockid": sockid,
			"member_remote": sockip,
		}).Debug("getting sync state")
		so.Emit("flixy sync", s.GetWireSession())
	}
}
Example #6
0
func TestLogstashFormatter(t *testing.T) {
	assert := assert.New(t)

	lf := LogstashFormatter{Type: "abc"}

	fields := logrus.Fields{
		"message": "def",
		"level":   "ijk",
		"type":    "lmn",
		"one":     1,
		"pi":      3.14,
		"bool":    true,
	}

	entry := logrus.WithFields(fields)
	entry.Message = "msg"
	entry.Level = logrus.InfoLevel

	b, _ := lf.Format(entry)

	var data map[string]interface{}
	dec := json.NewDecoder(bytes.NewReader(b))
	dec.UseNumber()
	dec.Decode(&data)

	// base fields
	assert.Equal(json.Number("1"), data["@version"])
	assert.NotEmpty(data["@timestamp"])
	assert.Equal("abc", data["type"])
	assert.Equal("msg", data["message"])
	assert.Equal("info", data["level"])

	// substituted fields
	assert.Equal("def", data["fields.message"])
	assert.Equal("ijk", data["fields.level"])
	assert.Equal("lmn", data["fields.type"])

	// formats
	assert.Equal(json.Number("1"), data["one"])
	assert.Equal(json.Number("3.14"), data["pi"])
	assert.Equal(true, data["bool"])
}
Example #7
0
File: main.go Project: flixy/flixy
// main is the entry point to the flixy server.
func main() {
	log.Info("Starting flixy!")

	server, err := socketio.NewServer(nil)
	if err != nil {
		log.Fatal(err)
	}

	// TODO can/should this be moved to its own function? it might make the
	// architecture of the various other handlers simpler, if implemented
	// in the right way.
	server.On("connection", func(so socketio.Socket) {
		sockid := so.Id()
		sockip := getRemoteIP(so)

		so.On("flixy get sync", SyncHandler(so))
		so.On("flixy new", NewHandler(so))
		so.On("flixy pause", PauseHandler(so))
		so.On("flixy play", PlayHandler(so))
		so.On("flixy join", JoinHandler(so))
		so.On("flixy seek", SeekHandler(so))

		log.WithFields(log.Fields{
			"member_sockid": sockid,
			"member_remote": sockip,
		}).Info("connected")
	})

	// TODO move this to its own handler (we're all grown up now!!!!)
	server.On("disconnection", func(so socketio.Socket) {
		sockid := so.Id()
		sockip := getRemoteIP(so)

		m, ok := members[sockid]
		if !ok {
			log.WithFields(log.Fields{
				"verb":          "disconnection",
				"member_sockid": sockid,
				"member_remote": sockip,
			}).Warn("member never in a session disconnected")

			// If a socket has never been a member, then it has no
			// sessions to be removed from, and thus we have
			// nothing further to do.
			return
		}

		log.Infof("%v disconnected", sockid)
		delete(members, sockid)

		s := m.Session

		// TODO this could be a lot prettier. I wish it could go in the
		// `RemoveMember` func itself, but I can't actually think of
		// how to remove a session from within its own context.
		numLeft := s.RemoveMember(sockid)

		// NOTE what happens if a user connects to the session here?
		if numLeft == 0 {
			sid := s.SessionID
			delete(sessions, sid)
		}
	})

	// TODO this should probably go to its own handler, too.
	server.On("error", func(so socketio.Socket, err error) {
		// TODO how can this even happen?
		log.Error("error:", err)
	})

	mux := http.NewServeMux()
	api := routes.New()

	// TODO remove this
	api.Get("/status", func(w http.ResponseWriter, r *http.Request) {
		// print status here
		// this is just for debugging for now, we need more in-depth stuff soon
		enc := json.NewEncoder(w)
		wms := make(map[string]models.WireSession)

		for k, v := range sessions {
			wms[k] = v.GetWireSession()
		}
		enc.Encode(wms)
	})

	// `/sessions/:sid` will 302 the user to the proper Netflix URL if it's
	// a valid SID, setting the session ID in the URL as it does so. It
	// will *also* return the session as a JSON object.
	api.Get("/sessions/:sid", func(w http.ResponseWriter, r *http.Request) {
		params := r.URL.Query()
		session, present := sessions[params.Get(":sid")]
		if !present {
			w.WriteHeader(404)
			return
		}

		w.Header().Set("Location", session.GetNetflixURL())
		w.WriteHeader(302)
		routes.ServeJson(w, session.GetWireSession())
	})

	mux.Handle("/socket.io/", server)
	mux.Handle("/", api)

	n := negroni.New()
	n.Use(negronilogrus.NewCustomMiddleware(loglevel, &log.TextFormatter{}, "web"))
	n.Use(negroni.NewRecovery())
	middleware.Inject(n)
	n.UseHandler(mux)
	n.Run(fmt.Sprintf("%s:%d", opts.Host, opts.Port))
}