Skip to content

Commit

Permalink
stash v0.18
Browse files Browse the repository at this point in the history
  • Loading branch information
o-fl0w committed Feb 26, 2023
1 parent 1f85132 commit a3a86a8
Show file tree
Hide file tree
Showing 24 changed files with 616 additions and 253 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ Stash-VR listens on port `9666`, use docker port binding to change local port, e
* `HEATMAP_HEIGHT_PX`
* Default: 0 (use height of heatmap)
* Manually set height of all heatmaps. If not set, height of the heatmap retrieved from Stash will be used, currently 15 by default.
* `DISABLE_PLAY_COUNT`
* Default: `false`
* Disable incrementing Stash play count for scenes. Will otherwise send request to Stash to increment play count when video is played in HereSphere.
* `FORCE_HTTPS`
* Default: `false`
* Force Stash-VR to use HTTPS. Useful as a last resort attempt if you're having issues with Stash-VR behind a reverse proxy.
Expand Down Expand Up @@ -119,11 +122,7 @@ When the favorite-feature of HereSphere is first used Stash-VR will create a tag
**Tip:** Create a filter using that tag, so it shows up in HereSphere for quick access to favorites.

#### Rating
HereSphere uses fractions for ratings, i.e. 4.5 is a valid rating. Stash uses whole numbers.
If you set a half star in HereSphere Stash-VR will round up the rating. That is if you set a rating of 3.5 the scene will receive a rating of 4 in Stash.
In other words, click anywhere on a star to set the rating to that amount of stars.

**Exception:** To remove a rating, rate the scene 0.5 (half a star).
Ratings set in HereSphere will be converted to its equivalent in Stash (4.5 stars => 90).

#### O-counter
Increment o-count by adding a tag named `!O` (case-insensitive) in `Video Tags`.
Expand Down Expand Up @@ -179,10 +178,12 @@ When the index page of Stash-VR is loaded Stash-VR will immediately respond with
This means if changes are made in Stash and the player refreshed, it will receive the cached version built during the last (previous) request.
Just refresh again and the player should receive the latest changes. In other words, refresh twice.

### Stash version
#### Stash v0.17.x
Compatible with Stash-VR version >= v0.5.0
#### Stash v0.16.1
Compatible with Stash-VR version <= v0.4.4
### Stash version compatibility
| Stash-VR | Stash |
|---------|---------|
| v0.6.x | v0.18.x |
| v0.5.x | v0.17.x |
| v0.4.x | v0.16.x |

#### Older Stash versions
If you have issues arising from running an older version of Stash the recommended path is to upgrade Stash before attempting a fix.
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ services:
#ALLOW_SYNC_MARKERS: "true"
#DISABLE_HEATMAP: "true"
#HEATMAP_HEIGHT_PX: 45
#DISABLE_PLAY_COUNT: "true"
#LOG_LEVEL: "debug"

#FORCE_HTTPS: "true"
41 changes: 25 additions & 16 deletions internal/api/heresphere/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"io"
"net/http"
"stash-vr/internal/api/internal"
"stash-vr/internal/config"
)

type httpHandler struct {
Expand Down Expand Up @@ -53,25 +54,33 @@ func (h *httpHandler) videoDataHandler(w http.ResponseWriter, req *http.Request)
return
}

var updateVideoData updateVideoData
err = json.Unmarshal(body, &updateVideoData)
var vdReq videoDataRequest
err = json.Unmarshal(body, &vdReq)
if err != nil {
log.Ctx(ctx).Debug().Err(err).Bytes("body", body).Msg("body: unmarshal")
} else {
if updateVideoData.isUpdateRequest() {
update(ctx, h.Client, sceneId, updateVideoData)
w.WriteHeader(http.StatusOK)
return
}

if updateVideoData.isDeleteRequest() {
destroy(ctx, h.Client, sceneId)
w.WriteHeader(http.StatusOK)
return
}
log.Ctx(ctx).Error().Err(err).Bytes("body", body).Msg("body: unmarshal")
w.WriteHeader(http.StatusInternalServerError)
return
}

if vdReq.isUpdateRequest() {
update(ctx, h.Client, sceneId, vdReq)
w.WriteHeader(http.StatusOK)
return
}

data, err := buildVideoData(ctx, h.Client, baseUrl, sceneId)
if vdReq.isDeleteRequest() {
destroy(ctx, h.Client, sceneId)
w.WriteHeader(http.StatusOK)
return
}

if vdReq.isPlayRequest() && !config.Get().IsPlayCountDisabled {
incrementPlayCount(ctx, h.Client, sceneId)
}

var includeMediaSource = vdReq.NeedsMediaSource == nil || *vdReq.NeedsMediaSource

data, err := buildVideoData(ctx, h.Client, baseUrl, sceneId, includeMediaSource)
if err != nil {
log.Ctx(ctx).Error().Err(err).Msg("build")
w.WriteHeader(http.StatusInternalServerError)
Expand Down
2 changes: 1 addition & 1 deletion internal/api/heresphere/scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func buildScan(ctx context.Context, client graphql.Client, baseUrl string) (scan
DateReleased: part.Date,
DateAdded: part.Created_at.Format("2006-01-02"),
Duration: part.Files[0].Duration,
Rating: float32(part.Rating),
Rating: float32(part.Rating100) / 20,
Favorites: part.O_counter,
IsFavorite: ContainsFavoriteTag(part.TagPartsArray),
Tags: getTags(part.SceneScanParts),
Expand Down
43 changes: 25 additions & 18 deletions internal/api/heresphere/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,34 @@ import (
"context"
"github.com/Khan/genqlient/graphql"
"github.com/rs/zerolog/log"
"math"
"stash-vr/internal/api/internal"
"stash-vr/internal/config"
"stash-vr/internal/stash"
"stash-vr/internal/stash/gql"
"strings"
)

type updateVideoData struct {
Rating *float32 `json:"rating,omitempty"`
IsFavorite *bool `json:"isFavorite,omitempty"`
Tags *[]tag `json:"tags,omitempty"`
DeleteFile *bool `json:"deleteFile,omitempty"`
type videoDataRequest struct {
Rating *float32 `json:"rating,omitempty"`
IsFavorite *bool `json:"isFavorite,omitempty"`
Tags *[]tag `json:"tags,omitempty"`
DeleteFile *bool `json:"deleteFile,omitempty"`
NeedsMediaSource *bool `json:"needsMediaSource,omitempty"`
}

func (v updateVideoData) isUpdateRequest() bool {
func (v videoDataRequest) isUpdateRequest() bool {
return v.Rating != nil || v.IsFavorite != nil || v.Tags != nil
}

func (v updateVideoData) isDeleteRequest() bool {
func (v videoDataRequest) isDeleteRequest() bool {
return v.DeleteFile != nil && *v.DeleteFile
}

func update(ctx context.Context, client graphql.Client, sceneId string, updateReq updateVideoData) {
func (v videoDataRequest) isPlayRequest() bool {
return v.NeedsMediaSource != nil && *v.NeedsMediaSource
}

func update(ctx context.Context, client graphql.Client, sceneId string, updateReq videoDataRequest) {
log.Ctx(ctx).Debug().Interface("data", updateReq).Msg("Update request")

if updateReq.Rating != nil {
Expand Down Expand Up @@ -97,6 +101,15 @@ func incrementO(ctx context.Context, client graphql.Client, sceneId string) {
log.Ctx(ctx).Debug().Interface("O-count", response.SceneIncrementO).Msg("Incremented O-count")
}

func incrementPlayCount(ctx context.Context, client graphql.Client, sceneId string) {
response, err := gql.SceneIncrementPlayCount(ctx, client, sceneId)
if err != nil {
log.Ctx(ctx).Warn().Err(err).Msg("Failed to increment play count")
return
}
log.Ctx(ctx).Debug().Interface("Play Count", response.SceneIncrementPlayCount).Msg("Incremented play count")
}

func toggleOrganized(ctx context.Context, client graphql.Client, sceneId string) {
newOrganized, err := stash.SceneToggleOrganized(ctx, client, sceneId)
if err != nil {
Expand All @@ -107,15 +120,9 @@ func toggleOrganized(ctx context.Context, client graphql.Client, sceneId string)
}

func updateRating(ctx context.Context, client graphql.Client, sceneId string, rating float32) {
var newRating int
if rating == 0.5 {
//special case to set zero rating
newRating = 0
} else {
newRating = int(math.Ceil(float64(rating)))
}
newRating := int(rating * 20)

_, err := gql.SceneUpdateRating(ctx, client, sceneId, newRating)
_, err := gql.SceneUpdateRating100(ctx, client, sceneId, newRating)
if err != nil {
log.Ctx(ctx).Warn().Err(err).Int("rating", newRating).Msg("Failed to update rating")
return
Expand Down Expand Up @@ -271,7 +278,7 @@ func parseUpdateRequestTags(ctx context.Context, client graphql.Client, tags []t
continue
}
request.performerIds = append(request.performerIds, id)
case isCategorized && (internal.LegendMovie.IsMatch(tagType) || internal.LegendOCount.IsMatch(tagType) || internal.LegendOrganized.IsMatch(tagType)):
case isCategorized && (internal.LegendMovie.IsMatch(tagType) || internal.LegendOCount.IsMatch(tagType) || internal.LegendOrganized.IsMatch(tagType) || internal.LegendPlayCount.IsMatch(tagType)):
log.Ctx(ctx).Trace().Str("request", tagReq.Name).Msg("Tag type is reserved, skipping")
continue
default:
Expand Down
1 change: 1 addition & 0 deletions internal/api/heresphere/tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func getStudio(s gql.SceneScanParts) []tag {

func getFields(s gql.SceneScanParts) []tag {
tags := []tag{
{Name: fmt.Sprintf("%s:%d", internal.LegendPlayCount.Short, s.Play_count)},
{Name: fmt.Sprintf("%s:%d", internal.LegendOCount.Short, s.O_counter)},
{Name: fmt.Sprintf("%s:%v", internal.LegendOrganized.Short, s.Organized)}}

Expand Down
11 changes: 7 additions & 4 deletions internal/api/heresphere/videodata.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ type script struct {
Url string `json:"url"`
}

func buildVideoData(ctx context.Context, client graphql.Client, baseUrl string, sceneId string) (videoData, error) {
func buildVideoData(ctx context.Context, client graphql.Client, baseUrl string, sceneId string, includeMediaSource bool) (videoData, error) {
findSceneResponse, err := gql.FindSceneFull(ctx, client, sceneId)
if err != nil {
return videoData{}, fmt.Errorf("FindSceneFull: %w", err)
Expand Down Expand Up @@ -87,7 +87,7 @@ func buildVideoData(ctx context.Context, client graphql.Client, baseUrl string,
DateReleased: s.Date,
DateAdded: s.Created_at.Format("2006-01-02"),
Duration: s.SceneScanParts.Files[0].Duration * 1000,
Rating: float32(s.Rating),
Rating: float32(s.Rating100) / 20,
Favorites: s.O_counter,
WriteFavorite: true,
WriteRating: true,
Expand All @@ -96,7 +96,10 @@ func buildVideoData(ctx context.Context, client graphql.Client, baseUrl string,

setIsFavorite(s, &vd)

setStreamSources(ctx, s, &vd)
if includeMediaSource {
setMediaSources(ctx, s, &vd)
}

set3DFormat(s, &vd)

setTags(s, &vd)
Expand Down Expand Up @@ -162,7 +165,7 @@ func set3DFormat(s gql.SceneFullParts, videoData *videoData) {
}
}

func setStreamSources(ctx context.Context, s gql.SceneFullParts, videoData *videoData) {
func setMediaSources(ctx context.Context, s gql.SceneFullParts, videoData *videoData) {
for _, stream := range stash.GetStreams(ctx, s.StreamsParts, true) {
e := media{
Name: stream.Name,
Expand Down
1 change: 1 addition & 0 deletions internal/api/internal/legend.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var (
LegendMovie = newLegend("/", "Movie")
LegendOCount = newLegend("O", "O-Count")
LegendOrganized = newLegend("Org", "Organized")
LegendPlayCount = newLegend("P", "PlayCount")
)

type Legend struct {
Expand Down
3 changes: 3 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const (
envKeyDisableHeatmap = "DISABLE_HEATMAP"
envKeyHeatmapHeightPx = "HEATMAP_HEIGHT_PX"
envKeyAllowSyncMarkers = "ALLOW_SYNC_MARKERS"
envKeyDisablePlayCount = "DISABLE_PLAY_COUNT"
)

var deprecatedEnvKeys = []string{"ENABLE_GLANCE_MARKERS", "HERESPHERE_QUICK_MARKERS", "HERESPHERE_SYNC_MARKERS", "ENABLE_HEATMAP_DISPLAY"}
Expand All @@ -34,6 +35,7 @@ type Application struct {
ForceHTTPS bool
IsHeatmapDisabled bool
HeatmapHeightPx int
IsPlayCountDisabled bool
}

var cfg Application
Expand All @@ -54,6 +56,7 @@ func Get() Application {
ForceHTTPS: getEnvOrDefaultBool(envKeyForceHTTPS, false),
IsHeatmapDisabled: getEnvOrDefaultBool(envKeyDisableHeatmap, false),
HeatmapHeightPx: getEnvOrDefaultInt(envKeyHeatmapHeightPx, 0),
IsPlayCountDisabled: getEnvOrDefaultBool(envKeyDisablePlayCount, false),
}
})
return cfg
Expand Down
2 changes: 1 addition & 1 deletion internal/sections/internal/savedfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func sectionFromSavedFilterFuncBuilder(ctx context.Context, client graphql.Clien
}

func sectionFromSavedFilter(ctx context.Context, client graphql.Client, prefix string, savedFilter gql.SavedFilterParts) (section.Section, error) {
filterQuery, err := filter.SavedFilterToSceneFilter(savedFilter)
filterQuery, err := filter.SavedFilterToSceneFilter(ctx, savedFilter)
if err != nil {
return section.Section{}, fmt.Errorf("SavedFilterToSceneFilter: %w", err)
}
Expand Down
Loading

0 comments on commit a3a86a8

Please sign in to comment.