func ApiShowsPutOne(r *http.Request, enc encoder.Encoder, store Store, parms martini.Params, user User) (int, []byte) { id, err := strconv.Atoi(parms["id"]) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } show, err := store.GetShowOrRetrieve(id) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } var showPost Show body, _ := ioutil.ReadAll(r.Body) r.Body.Close() err = json.Unmarshal(body, &showPost) if err != nil { return http.StatusNotFound, encoder.Must(enc.Encode(NewError(ErrCodeNotExist, "Could not decode body"))) } userShow := UserShow{UserID: user.ID, ShowID: show.ID, Favorite: showPost.Favorite, Library: showPost.Library} err = store.UserShowUpsert(&userShow) show.Personalize(user.ID) return http.StatusOK, encoder.Must(enc.Encode(show)) }
func ApiSeasonsGetAllByShow(r *http.Request, enc encoder.Encoder, store Store, parms martini.Params) (int, []byte) { id, err := strconv.Atoi(parms["showId"]) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } else { seasons, err := store.GetSeasonsOrRetrieveByShowId(id) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } return http.StatusOK, encoder.Must(enc.Encode(seasons)) } }
func ApiUsersRegister(r *http.Request, enc encoder.Encoder, store Store) (int, []byte) { if r.URL.Query().Get("email") != "" && r.URL.Query().Get("password") != "" { db := GetDbSession() user := User{ID: uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), Email: r.URL.Query().Get("email"), Password: sha1Password(r.URL.Query().Get("password")), Token: uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen)} err := db.Insert(&user) if err != nil { log.Println(err) return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } log.Printf("Registering new user with email %s, password: %s , userid:%s, token:%s", user.Email, user.Password, user.ID, user.Token) return http.StatusOK, encoder.Must(enc.Encode(user)) } return http.StatusBadRequest, encoder.Must(enc.Encode("Missing email param")) }
func ApiEpisodesGetOneByShowAndSeasonAndEpisode(r *http.Request, enc encoder.Encoder, store Store, parms martini.Params) (int, []byte) { showId, errShow := strconv.Atoi(parms["showId"]) seasonNumber, errSeason := strconv.Atoi(parms["seasonNumber"]) episodeNumber, errEpisode := strconv.Atoi(parms["episodeNumber"]) if errShow != nil || errSeason != nil || errEpisode != nil { return http.StatusBadRequest, encoder.Must(enc.Encode("Missing show_id or season or episode")) } else { episode, err := store.GetEpisodeOrRetrieveByShowIdAndSeasonAndEpisode(showId, seasonNumber, episodeNumber) if err != nil || episode == nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } episode.Normalize() return http.StatusOK, encoder.Must(enc.Encode(episode)) } }
func ApiShowsGetOne(r *http.Request, enc encoder.Encoder, store Store, parms martini.Params, user User) (int, []byte) { id, err := strconv.Atoi(parms["id"]) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } show, err := store.GetShowOrRetrieve(id) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } show.Personalize(user.ID) return http.StatusOK, encoder.Must(enc.Encode(show)) }
func ApiEpisodesGetAllByShowAndSeason(r *http.Request, enc encoder.Encoder, store Store, parms martini.Params) (int, []byte) { showId, errShow := strconv.Atoi(parms["showId"]) seasonNumber, errSeason := strconv.Atoi(parms["seasonNumber"]) if errShow != nil || errSeason != nil { return http.StatusBadRequest, encoder.Must(enc.Encode("Missing show_id or season")) } else { episodes, err := store.GetEpisodesOrRetrieveByShowIdAndSeason(showId, seasonNumber) if err != nil { return http.StatusBadRequest, encoder.Must(enc.Encode(err)) } for _, episode := range episodes { episode.Normalize() } return http.StatusOK, encoder.Must(enc.Encode(episodes)) } }
func ApiRss(res http.ResponseWriter, w http.ResponseWriter, r *http.Request, enc encoder.Encoder, store Store) (int, []byte) { db := GetDbSession() if r.URL.Query().Get("token") == "" { return http.StatusUnauthorized, encoder.Must(enc.Encode(NewError(ErrCodeNotExist, "Error"))) } token := r.URL.Query().Get("token") user := User{} err := db.SelectOne(&user, "select * from users where token=?", token) if err != nil { return http.StatusUnauthorized, encoder.Must(enc.Encode(NewError(ErrCodeNotExist, "Error"))) } now := time.Now() feed := &feeds.Feed{ Title: "42minutes", Link: &feeds.Link{Href: "http://42minutes.tv"}, Description: "Tv Shows Etc.", Created: now, } feed.Items = []*feeds.Item{} episodesRss := []*EpisodeRss{} db.Select(&episodesRss, "SELECT shows.title AS show_title, episodes.title, episodes.season, episodes.episode, episodes.first_aired, episodes.infohash_hd720p, episodes.infohash_sd480p FROM episodes LEFT JOIN shows ON episodes.show_id = shows.id LEFT JOIN users_shows ON shows.id = users_shows.show_id WHERE users_shows.library = true") // AND users_shows.user_id = "" for _, episodeRss := range episodesRss { magnet := "" if episodeRss.InfohashHd != "" { magnet = torrentlookup.FakeMagnet(episodeRss.InfohashHd) } else if episodeRss.InfohashSd != "" { magnet = torrentlookup.FakeMagnet(episodeRss.InfohashSd) } else { continue } item := feeds.Item{ Title: fmt.Sprintf("%s S%02dE%02d", episodeRss.ShowTitle, episodeRss.Season, episodeRss.Episode), Link: &feeds.Link{Href: magnet}, Created: *episodeRss.FirstAired, } feed.Items = append(feed.Items, &item) } rss, _ := feed.ToRss() w.Header().Set("Content-Type", "application/xml; charset=utf-8") return http.StatusOK, []byte(rss) }
func ApiFilesPost(r *http.Request, enc encoder.Encoder, store Store, parms martini.Params) (int, []byte) { db := GetDbSession() token := r.Header.Get("X-API-TOKEN") user := User{} err := db.SelectOne(&user, "select * from users where token=?", token) if err != nil { return http.StatusUnauthorized, encoder.Must(enc.Encode( NewError(ErrCodeNotExist, "Error"))) } var userFiles []UserFile body, _ := ioutil.ReadAll(r.Body) r.Body.Close() err = json.Unmarshal(body, &userFiles) if err != nil { return http.StatusNotFound, encoder.Must(enc.Encode( NewError(ErrCodeNotExist, "Could not decode body"))) } for userFile_i, userFile := range userFiles { err = db.SelectOne(&userFiles[userFile_i], "select * from users_files where user_id=? and relative_path=?", userFile.UserID, userFile.RelativePath) if err == sql.ErrNoRows { userFiles[userFile_i].ID = uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen) userFiles[userFile_i].UserID = user.ID db.Insert(&userFiles[userFile_i]) // TODO Error } else if err != nil { // TODO Error } } //Temp call for testing go func(userId string) { ApiProcessFiles(userId) }(user.ID) return http.StatusOK, encoder.Must(enc.Encode(userFiles)) }
func ApiUsersLogin(r *http.Request, enc encoder.Encoder, store Store) (int, []byte) { type UserLoginRequest struct { Email string `json:"email"` Password string `json:"password"` } var ulRequest UserLoginRequest body, _ := ioutil.ReadAll(r.Body) r.Body.Close() err := json.Unmarshal(body, &ulRequest) if err != nil { return http.StatusNotFound, encoder.Must(enc.Encode(NewError(ErrCodeNotExist, "Could not decode body"))) } email := ulRequest.Email pass := ulRequest.Password if email != "" && pass != "" { db := GetDbSession() user := User{} passHash := sha1Password(pass) err := db.SelectOne(&user, "select * from users where email=? and password=? ", email, passHash) if err == nil { // TODO Create new token and store it some place // But for now simply return the existing token // user.Token = uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen) // _, err := db.Update(&user) // if err == nil { return http.StatusOK, encoder.Must(enc.Encode(user)) // } } else { return http.StatusBadRequest, encoder.Must(enc.Encode("Wrong email or password")) } } return http.StatusBadRequest, encoder.Must(enc.Encode("Missing email or pass param")) }
func ApiShowsGetAll(r *http.Request, enc encoder.Encoder, store Store, user User) (int, []byte) { db := GetDbSession() var shows []*Show if r.URL.Query().Get("name") == "" { _, err := db.Select(&shows, "SELECT shows.* FROM shows LEFT JOIN users_shows ON shows.id = users_shows.show_id WHERE users_shows.user_id = ? AND (users_shows.favorite = true OR users_shows.library = true) ORDER BY shows.title asc", user.ID) if err != nil { return http.StatusNotFound, encoder.Must(enc.Encode(NewError(ErrCodeNotExist, fmt.Sprintf("TODO error")))) } } else { name := r.URL.Query().Get("name") fmt.Println("Looking for show...", name) shows, _ = ShowFindAllByName(name, 5) if len(shows) == 0 { return http.StatusNotFound, encoder.Must(enc.Encode(NewError(ErrCodeNotExist, fmt.Sprintf("could not find Show with name '%s'", name)))) } } for show_i, _ := range shows { shows[show_i].Personalize(user.ID) } return http.StatusOK, encoder.Must(enc.Encode(shows)) }
func getBooks(enc encoder.Encoder) (int, []byte) { return http.StatusOK, encoder.Must(enc.Encode(model.BooksGetAll())) }
func RunWeb(ip string, port int, monitors map[string]interface{}) { m := martini.New() route := martini.NewRouter() // validate an api key m.Use(func(res http.ResponseWriter, req *http.Request) { authKey := req.Header.Get("AUTH_KEY") if monitors[authKey] == nil { res.WriteHeader(http.StatusUnauthorized) res.Write([]byte("Unauthorized access.")) } else { monitored, _ := monitors[authKey].(string) req.Header.Set("MONITORED", monitored) } }) // map json encoder m.Use(func(c martini.Context, w http.ResponseWriter) { c.MapTo(encoder.JsonEncoder{}, (*encoder.Encoder)(nil)) w.Header().Set("Content-Type", "application/json") }) route.Get("/dirs", func(enc encoder.Encoder, req *http.Request) (int, []byte) { defer func() { if err := recover(); err != nil { fmt.Println(err) } }() monitored := req.Header.Get("MONITORED") lastIndexed, _ := strconv.Atoi(req.FormValue("last_indexed")) result := make([]index.IndexedFile, 0) db, _ := sql.Open("sqlite3", index.SlashSuffix(monitored)+".sync/index.db") defer db.Close() psSelectDirs, _ := db.Prepare("SELECT * FROM FILES WHERE FILE_SIZE=-1 AND LAST_INDEXED>?") defer psSelectDirs.Close() rows, _ := psSelectDirs.Query(lastIndexed) defer rows.Close() for rows.Next() { file := new(index.IndexedFile) rows.Scan(&file.FilePath, &file.LastModified, &file.FileSize, &file.FileMode, &file.Status, &file.LastIndexed) result = append(result, *file) } return http.StatusOK, encoder.Must(enc.Encode(result)) }) route.Get("/files", func(enc encoder.Encoder, req *http.Request) (int, []byte) { monitored := req.Header.Get("MONITORED") lastIndexed, _ := strconv.Atoi(req.FormValue("last_indexed")) filePath := index.SlashSuffix(index.LikeSafe(req.FormValue("file_path"))) result := make([]index.IndexedFile, 0) db, _ := sql.Open("sqlite3", index.SlashSuffix(monitored)+".sync/index.db") defer db.Close() psSelectFiles, _ := db.Prepare(`SELECT * FROM FILES WHERE LAST_INDEXED>? AND FILE_SIZE>=0 AND STATUS!='updating' AND FILE_PATH LIKE ?`) defer psSelectFiles.Close() rows, _ := psSelectFiles.Query(lastIndexed, filePath+"%") defer rows.Close() for rows.Next() { file := new(index.IndexedFile) rows.Scan(&file.FilePath, &file.LastModified, &file.FileSize, &file.FileMode, &file.Status, &file.LastIndexed) result = append(result, *file) } return http.StatusOK, encoder.Must(enc.Encode(result)) }) route.Get("/file_parts", func(enc encoder.Encoder, req *http.Request) (int, []byte) { monitored := req.Header.Get("MONITORED") filePath := req.FormValue("file_path") result := make([]index.IndexedFilePart, 0) db, _ := sql.Open("sqlite3", index.SlashSuffix(monitored)+".sync/index.db") defer db.Close() psSelectFiles, _ := db.Prepare(`SELECT * FROM FILE_PARTS WHERE FILE_PATH=? ORDER BY FILE_PATH,SEQ`) defer psSelectFiles.Close() rows, _ := psSelectFiles.Query(filePath) defer rows.Close() for rows.Next() { filePart := new(index.IndexedFilePart) rows.Scan(&filePart.FilePath, &filePart.Seq, &filePart.StartIndex, &filePart.Offset, &filePart.Checksum, &filePart.ChecksumType) result = append(result, *filePart) } return http.StatusOK, encoder.Must(enc.Encode(result)) }) route.Get("/download", func(res http.ResponseWriter, req *http.Request) { monitored := req.Header.Get("MONITORED") filePath := req.FormValue("file_path") start, _ := strconv.ParseInt(req.FormValue("start"), 10, 64) length, _ := strconv.ParseInt(req.FormValue("length"), 10, 64) file, _ := os.Open(index.SlashSuffix(monitored) + filePath) defer file.Close() file.Seek(start, os.SEEK_SET) n, _ := io.CopyN(res, file, length) res.Header().Set("Content-Length", strconv.FormatInt(n, 10)) res.Header().Set("Content-Type", "application/octet-stream") }) m.Action(route.Handle) fmt.Println(http.ListenAndServe(fmt.Sprint(ip, ":", port), m)) }