video-constant-manager-factory.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import { ConstantManager } from '@peertube/peertube-models'
  2. import { logger } from '@server/helpers/logger.js'
  3. import {
  4. VIDEO_CATEGORIES,
  5. VIDEO_LANGUAGES,
  6. VIDEO_LICENCES,
  7. VIDEO_PLAYLIST_PRIVACIES,
  8. VIDEO_PRIVACIES
  9. } from '@server/initializers/constants.js'
  10. type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy'
  11. type VideoConstant = Record<number | string, string>
  12. type UpdatedVideoConstant = {
  13. [name in AlterableVideoConstant]: {
  14. [ npmName: string]: {
  15. added: VideoConstant[]
  16. deleted: VideoConstant[]
  17. }
  18. }
  19. }
  20. const constantsHash: { [key in AlterableVideoConstant]: VideoConstant } = {
  21. language: VIDEO_LANGUAGES,
  22. licence: VIDEO_LICENCES,
  23. category: VIDEO_CATEGORIES,
  24. privacy: VIDEO_PRIVACIES,
  25. playlistPrivacy: VIDEO_PLAYLIST_PRIVACIES
  26. }
  27. export class VideoConstantManagerFactory {
  28. private readonly updatedVideoConstants: UpdatedVideoConstant = {
  29. playlistPrivacy: { },
  30. privacy: { },
  31. language: { },
  32. licence: { },
  33. category: { }
  34. }
  35. constructor (
  36. private readonly npmName: string
  37. ) {}
  38. public resetVideoConstants (npmName: string) {
  39. const types: AlterableVideoConstant[] = [ 'language', 'licence', 'category', 'privacy', 'playlistPrivacy' ]
  40. for (const type of types) {
  41. this.resetConstants({ npmName, type })
  42. }
  43. }
  44. private resetConstants (parameters: { npmName: string, type: AlterableVideoConstant }) {
  45. const { npmName, type } = parameters
  46. const updatedConstants = this.updatedVideoConstants[type][npmName]
  47. if (!updatedConstants) return
  48. for (const added of updatedConstants.added) {
  49. delete constantsHash[type][added.key]
  50. }
  51. for (const deleted of updatedConstants.deleted) {
  52. constantsHash[type][deleted.key] = deleted.label
  53. }
  54. delete this.updatedVideoConstants[type][npmName]
  55. }
  56. public createVideoConstantManager<K extends number | string>(type: AlterableVideoConstant): ConstantManager<K> {
  57. const { npmName } = this
  58. return {
  59. addConstant: (key: K, label: string) => this.addConstant({ npmName, type, key, label }),
  60. deleteConstant: (key: K) => this.deleteConstant({ npmName, type, key }),
  61. getConstantValue: (key: K) => constantsHash[type][key],
  62. getConstants: () => constantsHash[type] as Record<K, string>,
  63. resetConstants: () => this.resetConstants({ npmName, type })
  64. }
  65. }
  66. private addConstant<T extends string | number> (parameters: {
  67. npmName: string
  68. type: AlterableVideoConstant
  69. key: T
  70. label: string
  71. }) {
  72. const { npmName, type, key, label } = parameters
  73. const obj = constantsHash[type]
  74. if (obj[key]) {
  75. logger.warn('Cannot add %s %s by plugin %s: key already exists.', type, npmName, key)
  76. return false
  77. }
  78. if (!this.updatedVideoConstants[type][npmName]) {
  79. this.updatedVideoConstants[type][npmName] = {
  80. added: [],
  81. deleted: []
  82. }
  83. }
  84. this.updatedVideoConstants[type][npmName].added.push({ key, label } as VideoConstant)
  85. obj[key] = label
  86. return true
  87. }
  88. private deleteConstant<T extends string | number> (parameters: {
  89. npmName: string
  90. type: AlterableVideoConstant
  91. key: T
  92. }) {
  93. const { npmName, type, key } = parameters
  94. const obj = constantsHash[type]
  95. if (!obj[key]) {
  96. logger.warn('Cannot delete %s by plugin %s: key %s does not exist.', type, npmName, key)
  97. return false
  98. }
  99. if (!this.updatedVideoConstants[type][npmName]) {
  100. this.updatedVideoConstants[type][npmName] = {
  101. added: [],
  102. deleted: []
  103. }
  104. }
  105. const updatedConstants = this.updatedVideoConstants[type][npmName]
  106. const alreadyAdded = updatedConstants.added.find(a => a.key === key)
  107. if (alreadyAdded) {
  108. updatedConstants.added.filter(a => a.key !== key)
  109. } else if (obj[key]) {
  110. updatedConstants.deleted.push({ key, label: obj[key] } as VideoConstant)
  111. }
  112. delete obj[key]
  113. return true
  114. }
  115. }