fav.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. package model
  2. import (
  3. "errors"
  4. "fmt"
  5. "sort"
  6. "strings"
  7. "go-common/library/time"
  8. )
  9. const (
  10. // default name of folder
  11. InitFolderName = "默认收藏夹"
  12. // state
  13. StateNormal = int8(0)
  14. StateIsDel = int8(1)
  15. // attr bit bit from left
  16. AttrBitPublic = uint(0)
  17. AttrBitDefault = uint(1)
  18. AttrBitAudit = uint(2)
  19. AttrBitAdminDelete = uint(3)
  20. AttrBitName = uint(4)
  21. AttrBitDesc = uint(5)
  22. AttrBitCover = uint(6)
  23. AttrBitSensitive = uint(7)
  24. AttrIsPublic = int32(0) // 公开
  25. AttrIsDefault = int32(0) // 默认
  26. // foler attr
  27. AttrBitPrivate = int32(1)
  28. AttrBitNoDefault = int32(1) << AttrBitDefault
  29. AttrBitNeedAudit = int32(1) << AttrBitAudit
  30. AttrBitHitSensitive = int32(1) << AttrBitSensitive
  31. AttrDefaultPublic = 0 // binary 0 / int 0
  32. AttrDefaultNoPublic = AttrBitPrivate // binary 01 / int 1
  33. AttrNormalPublic = AttrBitNoDefault // binary 10 / int 2
  34. AttrNormalNoPublic = AttrBitNoDefault | AttrBitPrivate // binary 11 / int 3
  35. // limit
  36. DefaultFolderLimit = 50000
  37. NormalFolderLimit = 999
  38. // cache
  39. CacheNotFound = -1
  40. // max type
  41. TypeMax = 20
  42. // sort field
  43. SortPubtime = "pubtime"
  44. SortMtime = "mtime"
  45. SortView = "view"
  46. )
  47. func (r *Resource) ResourceID() int64 {
  48. return r.Oid*100 + int64(r.Typ)
  49. }
  50. func IsMediaList(typ int32) bool {
  51. return typ == int32(TypeVideo) || typ == int32(TypeMusicNew)
  52. }
  53. type Favorite struct {
  54. ID int64 `json:"id"`
  55. Oid int64 `json:"oid"`
  56. Mid int64 `json:"mid"`
  57. Fid int64 `json:"fid"`
  58. Type int8 `json:"type"`
  59. State int8 `json:"state"`
  60. CTime time.Time `json:"ctime"`
  61. MTime time.Time `json:"mtime"`
  62. Sequence uint64 `json:"sequence"`
  63. }
  64. func (f *Favorite) ResourceID() int64 {
  65. return int64(f.Oid)*100 + int64(f.Type)
  66. }
  67. type Favorites struct {
  68. Page struct {
  69. Num int `json:"num"`
  70. Size int `json:"size"`
  71. Count int `json:"count"`
  72. } `json:"page"`
  73. List []*Favorite `json:"list"`
  74. }
  75. type User struct {
  76. ID int64 `json:"id"`
  77. Oid int64 `json:"oid"`
  78. Mid int64 `json:"mid"`
  79. Type int8 `json:"type"`
  80. State int8 `json:"state"`
  81. CTime time.Time `json:"ctime"`
  82. MTime time.Time `json:"mtime"`
  83. }
  84. type UserList struct {
  85. Page struct {
  86. Num int `json:"num"`
  87. Size int `json:"size"`
  88. Total int `json:"total"`
  89. } `json:"page"`
  90. List []*User `json:"list"`
  91. }
  92. // AttrVal get attr val by bit.
  93. func (f *Folder) AttrVal(bit uint) int32 {
  94. return (f.Attr >> bit) & int32(1)
  95. }
  96. // AttrSet set attr value by bit.
  97. func (f *Folder) AttrSet(v int32, bit uint) {
  98. f.Attr = f.Attr&(^(1 << bit)) | (v << bit)
  99. }
  100. // IsDefault return true if folder is default.
  101. func (f *Folder) IsDefault() bool {
  102. return f.Attr&AttrBitNoDefault == int32(0)
  103. }
  104. // IsPublic return true if folder is public.
  105. func (f *Folder) IsPublic() bool {
  106. return f.AttrVal(AttrBitPublic) == AttrIsPublic
  107. }
  108. // Access return true if the user has the access permission to the folder.
  109. func (f *Folder) Access(mid int64) bool {
  110. return f.IsPublic() || f.Mid == mid
  111. }
  112. // IsLimited return true if folder count is eq or gt conf limit.
  113. func (f *Folder) IsLimited(cnt int, defaultLimit int, normalLimit int) bool {
  114. switch f.IsDefault() {
  115. case true:
  116. return f.Count+cnt > defaultLimit
  117. case false:
  118. return f.Count+cnt > normalLimit
  119. }
  120. return true
  121. }
  122. func (f *Folder) MediaID() int64 {
  123. return f.ID*100 + f.Mid%100
  124. }
  125. func CheckArg(tp int8, oid int64) error {
  126. if tp <= 0 || oid <= 0 {
  127. return errors.New("negative number and zero not allowed")
  128. }
  129. return CheckType(tp)
  130. }
  131. func CheckType(typ int8) error {
  132. if typ < Article || typ > TypeMax {
  133. return errors.New("type code out of range")
  134. }
  135. return nil
  136. }
  137. // CompleteURL adds host on path.
  138. func CompleteURL(path string) (url string) {
  139. if path == "" {
  140. // url = "http://static.hdslb.com/images/transparent.gif"
  141. return
  142. }
  143. url = path
  144. if strings.Index(path, "//") == 0 || strings.Index(path, "http://") == 0 || strings.Index(path, "https://") == 0 {
  145. return
  146. }
  147. url = "https://i0.hdslb.com" + url
  148. return
  149. }
  150. // CleanURL cuts host.
  151. func CleanURL(url string) (path string) {
  152. path = url
  153. if strings.Index(url, "//") == 0 {
  154. path = url[14:]
  155. } else if strings.Index(url, "http://") == 0 {
  156. path = url[19:]
  157. } else if strings.Index(url, "https://") == 0 {
  158. path = url[20:]
  159. }
  160. return
  161. }
  162. // Folders .
  163. type Folders []*Folder
  164. func (f Folders) Len() int { return len(f) }
  165. func (f Folders) Less(i, j int) bool {
  166. if f[i].IsDefault() {
  167. return true
  168. }
  169. if f[j].IsDefault() {
  170. return false
  171. }
  172. if f[i].ID > f[j].ID {
  173. return true
  174. }
  175. return false
  176. }
  177. func (f Folders) Swap(i, j int) { f[i], f[j] = f[j], f[i] }
  178. // FolderSort folder index.
  179. type FolderSort struct {
  180. ID int64 `json:"id"`
  181. Type int8 `json:"type"`
  182. Mid int64 `json:"mid"`
  183. Sort []int64 `json:"sort"`
  184. Map map[int64]struct{} `json:"-"`
  185. CTime time.Time `json:"ctime"`
  186. MTime time.Time `json:"mtime"`
  187. }
  188. // Index return index for fids.
  189. func (f *FolderSort) Index() []byte {
  190. var (
  191. i int
  192. v int64
  193. fs = f.Sort
  194. n = len(fs) * 8
  195. b = make([]byte, n)
  196. )
  197. for i = 0; i < n; i += 8 {
  198. v = fs[i/8]
  199. b[i] = byte(v >> 56)
  200. b[i+1] = byte(v >> 48)
  201. b[i+2] = byte(v >> 40)
  202. b[i+3] = byte(v >> 32)
  203. b[i+4] = byte(v >> 24)
  204. b[i+5] = byte(v >> 16)
  205. b[i+6] = byte(v >> 8)
  206. b[i+7] = byte(v)
  207. }
  208. return b
  209. }
  210. // SetIndex set sort fids.
  211. func (f *FolderSort) SetIndex(b []byte) (err error) {
  212. var (
  213. i int
  214. id int64
  215. n = len(b)
  216. ids = make([]int64, n/8)
  217. )
  218. if len(b)%8 != 0 {
  219. err = fmt.Errorf("invalid sort index:%v", b)
  220. return
  221. }
  222. f.Map = make(map[int64]struct{}, n)
  223. for i = 0; i < n; i += 8 {
  224. id = int64(b[i+7]) |
  225. int64(b[i+6])<<8 |
  226. int64(b[i+5])<<16 |
  227. int64(b[i+4])<<24 |
  228. int64(b[i+3])<<32 |
  229. int64(b[i+2])<<40 |
  230. int64(b[i+1])<<48 |
  231. int64(b[i])<<56
  232. ids[i/8] = id
  233. f.Map[id] = struct{}{}
  234. }
  235. f.Sort = ids
  236. return
  237. }
  238. // ToBytes return []byte for ids.
  239. func ToBytes(ids []int64) []byte {
  240. var (
  241. i int
  242. v int64
  243. n = len(ids) * 8
  244. b = make([]byte, n)
  245. )
  246. for i = 0; i < n; i += 8 {
  247. v = ids[i/8]
  248. b[i] = byte(v >> 56)
  249. b[i+1] = byte(v >> 48)
  250. b[i+2] = byte(v >> 40)
  251. b[i+3] = byte(v >> 32)
  252. b[i+4] = byte(v >> 24)
  253. b[i+5] = byte(v >> 16)
  254. b[i+6] = byte(v >> 8)
  255. b[i+7] = byte(v)
  256. }
  257. return b
  258. }
  259. // ToInt64s bytes to int64s.
  260. func ToInt64s(b []byte) (ids []int64, err error) {
  261. var (
  262. i int
  263. id int64
  264. n = len(b)
  265. )
  266. ids = make([]int64, n/8)
  267. if len(b)%8 != 0 {
  268. err = fmt.Errorf("invalid bytes:%v", b)
  269. return
  270. }
  271. for i = 0; i < n; i += 8 {
  272. id = int64(b[i+7]) |
  273. int64(b[i+6])<<8 |
  274. int64(b[i+5])<<16 |
  275. int64(b[i+4])<<24 |
  276. int64(b[i+3])<<32 |
  277. int64(b[i+2])<<40 |
  278. int64(b[i+1])<<48 |
  279. int64(b[i])<<56
  280. ids[i/8] = id
  281. }
  282. return
  283. }
  284. // SortFolders sort the favorites by index.
  285. func (f *FolderSort) SortFolders(fs map[int64]*Folder, isSelf bool) (res []*Folder, update bool) {
  286. var (
  287. ok bool
  288. id int64
  289. sorted []int64
  290. fav *Folder
  291. idx = f.Sort
  292. )
  293. res = make([]*Folder, 0, len(fs))
  294. if len(f.Sort) == 0 {
  295. for _, fav = range fs {
  296. if !isSelf && !fav.IsPublic() {
  297. continue
  298. }
  299. res = append(res, fav)
  300. }
  301. sort.Sort(Folders(res))
  302. return
  303. }
  304. if len(idx) != len(fs) {
  305. sorted = append(sorted, idx[0])
  306. for id = range fs {
  307. if _, ok = f.Map[id]; !ok {
  308. sorted = append(sorted, id)
  309. }
  310. }
  311. for _, id := range idx[1:] {
  312. if _, ok = fs[id]; ok {
  313. sorted = append(sorted, id)
  314. }
  315. }
  316. update = true
  317. f.Sort = sorted
  318. }
  319. for _, id = range f.Sort {
  320. if fav, ok = fs[id]; ok {
  321. if !isSelf && !fav.IsPublic() {
  322. continue
  323. }
  324. res = append(res, fav)
  325. }
  326. }
  327. return
  328. }