Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 4,542 Bytes
f70dd7e 8f2b05f 1185ec1 38d787b f70dd7e 29f166e f70dd7e 29f166e f70dd7e 29f166e f70dd7e 29f166e f70dd7e 29f166e f70dd7e 29f166e f70dd7e 29f166e f70dd7e 8f2b05f 99dcdd2 8f2b05f 99dcdd2 8f2b05f e657a34 be5bb51 e657a34 8f2b05f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
"use server"
import { developerMode } from "@/app/config"
import { WhoAmIUser, whoAmI } from "@/huggingface/hub/src"
import { VideoRating } from "@/types/general"
import { redis } from "./redis";
export async function getStatsForVideos(videoIds: string[]): Promise<Record<string, { numberOfViews: number; numberOfLikes: number; numberOfDislikes: number}>> {
if (!Array.isArray(videoIds)) {
return {}
}
try {
const stats: Record<string, { numberOfViews: number; numberOfLikes: number; numberOfDislikes: number; }> = {}
const listOfRedisIDs: string[] = []
for (const videoId of videoIds) {
listOfRedisIDs.push(`videos:${videoId}:stats:views`)
listOfRedisIDs.push(`videos:${videoId}:stats:likes`)
listOfRedisIDs.push(`videos:${videoId}:stats:dislikes`)
stats[videoId] = {
numberOfViews: 0,
numberOfLikes: 0,
numberOfDislikes: 0,
}
}
const listOfRedisValues = await redis.mget<number[]>(...listOfRedisIDs)
let v = 0
for (let i = 0; i < listOfRedisValues.length; i += 3) {
stats[videoIds[v++]] = {
numberOfViews: listOfRedisValues[i] || 0,
numberOfLikes: listOfRedisValues[i + 1] || 0,
numberOfDislikes: listOfRedisValues[i + 2] || 0
}
}
return stats
} catch (err) {
return {}
}
}
export async function watchVideo(videoId: string): Promise<number> {
if (developerMode) {
const stats = await getStatsForVideos([videoId])
return stats[videoId].numberOfViews
}
try {
const result = await redis.incr(`videos:${videoId}:stats:views`)
return result
} catch (err) {
return 0
}
}
export async function getVideoRating(videoId: string, apiKey?: string): Promise<VideoRating> {
let numberOfLikes = 0
let numberOfDislikes = 0
let isLikedByUser = false
let isDislikedByUser = false
try {
// update video likes counter
numberOfLikes = (await redis.get<number>(`videos:${videoId}:stats:likes`)) || 0
numberOfDislikes = (await redis.get<number>(`videos:${videoId}:stats:dislikes`)) || 0
} catch (err) {
}
// optional: determine if the user liked or disliked the content
if (apiKey) {
try {
const credentials = { accessToken: apiKey }
const user = await whoAmI({ credentials }) as unknown as WhoAmIUser
const isLiked = await redis.get<boolean>(`users:${user.id}:activity:videos:${videoId}:liked`)
if (isLiked !== null) {
isLikedByUser = !!isLiked
isDislikedByUser = !isLiked
}
} catch (err) {
console.error("failed to get user like status")
}
}
return {
isLikedByUser,
isDislikedByUser,
numberOfLikes,
numberOfDislikes,
}
}
export async function rateVideo(videoId: string, liked: boolean, apiKey: string): Promise<VideoRating> {
// note: we want the like to throw an exception if it failed
let numberOfLikes = 0
let numberOfDislikes = 0
let isLikedByUser = false
let isDislikedByUser = false
const credentials = { accessToken: apiKey }
const user = await whoAmI({ credentials }) as unknown as WhoAmIUser
const hasLiked = await redis.get<boolean>(`users:${user.id}:activity:videos:${videoId}:liked`)
const hasAlreadyRatedTheSame = hasLiked !== null && liked === hasLiked
if (hasAlreadyRatedTheSame) {
return {
numberOfLikes: await redis.get(`videos:${videoId}:stats:likes`) || 0,
numberOfDislikes: await redis.get(`videos:${videoId}:stats:dislikes`) || 0,
isLikedByUser: liked,
isDislikedByUser: !liked
}
}
const hasAlreadyRatedAndDifferently = hasLiked !== null && liked !== hasLiked
await redis.set(`users:${user.id}:activity:videos:${videoId}:liked`, liked)
isLikedByUser = liked
isDislikedByUser = !liked
// if user has already rated the content, and it's different from the desired value,
// then we need to undo the rating
try {
if (liked) {
// update video likes counter
numberOfLikes = await redis.incr(`videos:${videoId}:stats:likes`)
if (hasAlreadyRatedAndDifferently) {
numberOfDislikes = await redis.decr(`videos:${videoId}:stats:dislikes`)
}
} else {
numberOfDislikes = await redis.incr(`videos:${videoId}:stats:dislikes`)
if (hasAlreadyRatedAndDifferently) {
numberOfLikes = await redis.decr(`videos:${videoId}:stats:likes`)
}
}
} catch (err) {
} finally {
return {
numberOfLikes,
numberOfDislikes,
isLikedByUser,
isDislikedByUser,
}
}
}
|