Handle sort in rss
authorChocobozzz <me@florianbigard.com>
Tue, 17 Apr 2018 08:56:27 +0000 (10:56 +0200)
committerChocobozzz <me@florianbigard.com>
Tue, 17 Apr 2018 08:56:27 +0000 (10:56 +0200)
client/src/app/shared/video/abstract-video-list.ts
client/src/app/shared/video/sort-field.type.ts
client/src/app/shared/video/video.service.ts
client/src/app/videos/+video-watch/comment/video-comment.service.ts
client/src/app/videos/+video-watch/comment/video-comments.component.ts
client/src/app/videos/video-list/video-local.component.ts
client/src/app/videos/video-list/video-recently-added.component.ts
client/src/app/videos/video-list/video-trending.component.ts
server/controllers/api/users.ts
server/controllers/feeds.ts
server/models/video/video.ts

index c1c07e6284061d117853c9f5d6678017efb2a212..7f2cf2d7eec20fb2ee33a001b7796eddc1753e12 100644 (file)
@@ -9,7 +9,7 @@ import { fromEvent } from 'rxjs/observable/fromEvent'
 import { Subscription } from 'rxjs/Subscription'
 import { AuthService } from '../../core/auth'
 import { ComponentPagination } from '../rest/component-pagination.model'
-import { SortField } from './sort-field.type'
+import { VideoSortField } from './sort-field.type'
 import { Video } from './video.model'
 
 export abstract class AbstractVideoList implements OnInit, OnDestroy {
@@ -23,8 +23,8 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
     itemsPerPage: 10,
     totalItems: null
   }
-  sort: SortField = '-createdAt'
-  defaultSort: SortField = '-createdAt'
+  sort: VideoSortField = '-createdAt'
+  defaultSort: VideoSortField = '-createdAt'
   syndicationItems = []
 
   loadOnInit = true
@@ -154,7 +154,7 @@ export abstract class AbstractVideoList implements OnInit, OnDestroy {
   }
 
   protected loadRouteParams (routeParams: { [ key: string ]: any }) {
-    this.sort = routeParams['sort'] as SortField || this.defaultSort
+    this.sort = routeParams['sort'] as VideoSortField || this.defaultSort
 
     if (routeParams['page'] !== undefined) {
       this.pagination.currentPage = parseInt(routeParams['page'], 10)
index 776f360f8de43f838f9dc6f44f6a317da2b294e1..2a3ae4ddd8bc1fc77d2390219b675fd163bc5a06 100644 (file)
@@ -1,4 +1,4 @@
-export type SortField = 'name' | '-name'
+export type VideoSortField = 'name' | '-name'
                       | 'duration' | '-duration'
                       | 'createdAt' | '-createdAt'
                       | 'views' | '-views'
index 4c19c37657c5c540476c4926475aeddbb71b85ff..ef8babd55a9ac9fc0ada06666967b4e76529cc59 100644 (file)
@@ -16,7 +16,7 @@ import { ComponentPagination } from '../rest/component-pagination.model'
 import { RestExtractor } from '../rest/rest-extractor.service'
 import { RestService } from '../rest/rest.service'
 import { UserService } from '../users/user.service'
-import { SortField } from './sort-field.type'
+import { VideoSortField } from './sort-field.type'
 import { VideoDetails } from './video-details.model'
 import { VideoEdit } from './video-edit.model'
 import { Video } from './video.model'
@@ -86,7 +86,7 @@ export class VideoService {
       .catch(this.restExtractor.handleError)
   }
 
-  getMyVideos (videoPagination: ComponentPagination, sort: SortField): Observable<{ videos: Video[], totalVideos: number}> {
+  getMyVideos (videoPagination: ComponentPagination, sort: VideoSortField): Observable<{ videos: Video[], totalVideos: number}> {
     const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
 
     let params = new HttpParams()
@@ -99,7 +99,7 @@ export class VideoService {
 
   getVideos (
     videoPagination: ComponentPagination,
-    sort: SortField,
+    sort: VideoSortField,
     filter?: VideoFilter
   ): Observable<{ videos: Video[], totalVideos: number}> {
     const pagination = this.restService.componentPaginationToRestPagination(videoPagination)
@@ -117,7 +117,7 @@ export class VideoService {
       .catch((res) => this.restExtractor.handleError(res))
   }
 
-  buildBaseFeedUrls () {
+  buildBaseFeedUrls (params: HttpParams) {
     const feeds = [
       {
         label: 'rss 2.0',
@@ -133,43 +133,34 @@ export class VideoService {
       }
     ]
 
+    if (params && params.keys().length !== 0) {
+      for (const feed of feeds) {
+        feed.url += '?' + params.toString()
+      }
+    }
+
     return feeds
   }
 
-  getVideoFeedUrls (filter?: VideoFilter) {
-    let params = this.restService.addRestGetParams(new HttpParams())
-    const feeds = this.buildBaseFeedUrls()
+  getVideoFeedUrls (sort: VideoSortField, filter?: VideoFilter) {
+    let params = this.restService.addRestGetParams(new HttpParams(), undefined, sort)
 
     if (filter) params = params.set('filter', filter)
 
-    if (params.keys().length !== 0) {
-      for (let item of feeds) {
-        item.url += `?${params.toString()}`
-      }
-    }
-
-    return feeds
+    return this.buildBaseFeedUrls(params)
   }
 
   getAccountFeedUrls (accountId: number) {
     let params = this.restService.addRestGetParams(new HttpParams())
-    const feeds = this.buildBaseFeedUrls()
-
     params = params.set('accountId', accountId.toString())
 
-    if (params.keys().length !== 0) {
-      for (let item of feeds) {
-        item.url += `?${params.toString()}`
-      }
-    }
-
-    return feeds
+    return this.buildBaseFeedUrls(params)
   }
 
   searchVideos (
     search: string,
     videoPagination: ComponentPagination,
-    sort: SortField
+    sort: VideoSortField
   ): Observable<{ videos: Video[], totalVideos: number}> {
     const url = VideoService.BASE_VIDEO_URL + 'search'
 
index 470af12305cc3604091b07e68caadf04bb589ece..0bf7696fe0489bd1cafb4c132a049f1312e69110 100644 (file)
@@ -14,7 +14,7 @@ import {
 import { environment } from '../../../../environments/environment'
 import { RestExtractor, RestService } from '../../../shared/rest'
 import { ComponentPagination } from '../../../shared/rest/component-pagination.model'
-import { SortField } from '../../../shared/video/sort-field.type'
+import { VideoSortField } from '../../../shared/video/sort-field.type'
 import { VideoComment } from './video-comment.model'
 
 @Injectable()
@@ -48,7 +48,7 @@ export class VideoCommentService {
   getVideoCommentThreads (
     videoId: number | string,
     componentPagination: ComponentPagination,
-    sort: SortField
+    sort: VideoSortField
   ): Observable<{ comments: VideoComment[], totalComments: number}> {
     const pagination = this.restService.componentPaginationToRestPagination(componentPagination)
 
index 711a01ba0acfa70979cfedecca765bd86df98237..a77a6e9f38e7841b532425ec65d0b307c080cfa7 100644 (file)
@@ -7,7 +7,7 @@ import { VideoCommentThreadTree } from '../../../../../../shared/models/videos/v
 import { AuthService } from '../../../core/auth'
 import { ComponentPagination } from '../../../shared/rest/component-pagination.model'
 import { User } from '../../../shared/users'
-import { SortField } from '../../../shared/video/sort-field.type'
+import { VideoSortField } from '../../../shared/video/sort-field.type'
 import { VideoDetails } from '../../../shared/video/video-details.model'
 import { VideoComment } from './video-comment.model'
 import { VideoCommentService } from './video-comment.service'
@@ -23,7 +23,7 @@ export class VideoCommentsComponent implements OnInit, OnChanges, OnDestroy {
 
   comments: VideoComment[] = []
   highlightedThread: VideoComment
-  sort: SortField = '-createdAt'
+  sort: VideoSortField = '-createdAt'
   componentPagination: ComponentPagination = {
     currentPage: 1,
     itemsPerPage: 10,
index 90eb96afeb00ca1170cf5c019faf11736d8f351b..de6552875627493c1f0be9b6c95d4d647e4f6cfb 100644 (file)
@@ -3,12 +3,10 @@ import { ActivatedRoute, Router } from '@angular/router'
 import { immutableAssign } from '@app/shared/misc/utils'
 import { NotificationsService } from 'angular2-notifications'
 import { AuthService } from '../../core/auth'
-import { PopoverModule } from 'ngx-bootstrap/popover'
 import { AbstractVideoList } from '../../shared/video/abstract-video-list'
-import { SortField } from '../../shared/video/sort-field.type'
+import { VideoSortField } from '../../shared/video/sort-field.type'
 import { VideoService } from '../../shared/video/video.service'
-import { FeedFormat } from '../../../../../shared/models/feeds/feed-format.enum'
-import * as url from 'url'
+import { VideoFilter } from '../../../../../shared/models/videos/video-query.type'
 
 @Component({
   selector: 'my-videos-local',
@@ -18,7 +16,8 @@ import * as url from 'url'
 export class VideoLocalComponent extends AbstractVideoList implements OnInit, OnDestroy {
   titlePage = 'Local videos'
   currentRoute = '/videos/local'
-  sort = '-createdAt' as SortField
+  sort = '-createdAt' as VideoSortField
+  filter: VideoFilter = 'local'
 
   constructor (protected router: Router,
                protected route: ActivatedRoute,
@@ -41,10 +40,10 @@ export class VideoLocalComponent extends AbstractVideoList implements OnInit, On
   getVideosObservable (page: number) {
     const newPagination = immutableAssign(this.pagination, { currentPage: page })
 
-    return this.videoService.getVideos(newPagination, this.sort, 'local')
+    return this.videoService.getVideos(newPagination, this.sort, this.filter)
   }
 
   generateSyndicationList () {
-    this.syndicationItems = this.videoService.getVideoFeedUrls('local')
+    this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort, this.filter)
   }
 }
index 3b8108b00650204a2852aab0f64a196b276f34e3..cca35d0f58635d39f454a6930c0840b5bcf98344 100644 (file)
@@ -4,10 +4,8 @@ import { immutableAssign } from '@app/shared/misc/utils'
 import { NotificationsService } from 'angular2-notifications'
 import { AuthService } from '../../core/auth'
 import { AbstractVideoList } from '../../shared/video/abstract-video-list'
-import { SortField } from '../../shared/video/sort-field.type'
+import { VideoSortField } from '../../shared/video/sort-field.type'
 import { VideoService } from '../../shared/video/video.service'
-import { FeedFormat } from '../../../../../shared/models/feeds/feed-format.enum'
-import * as url from 'url'
 
 @Component({
   selector: 'my-videos-recently-added',
@@ -17,7 +15,7 @@ import * as url from 'url'
 export class VideoRecentlyAddedComponent extends AbstractVideoList implements OnInit, OnDestroy {
   titlePage = 'Recently added'
   currentRoute = '/videos/recently-added'
-  sort: SortField = '-createdAt'
+  sort: VideoSortField = '-createdAt'
 
   constructor (protected router: Router,
                protected route: ActivatedRoute,
@@ -44,6 +42,6 @@ export class VideoRecentlyAddedComponent extends AbstractVideoList implements On
   }
 
   generateSyndicationList () {
-    this.syndicationItems = this.videoService.getVideoFeedUrls()
+    this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort)
   }
 }
index 6358ef91fe578c20d2713d968351e7fe7815fe0c..0c9e28216f6431db816efaeffcfae67d87704286 100644 (file)
@@ -4,7 +4,7 @@ import { immutableAssign } from '@app/shared/misc/utils'
 import { NotificationsService } from 'angular2-notifications'
 import { AuthService } from '../../core/auth'
 import { AbstractVideoList } from '../../shared/video/abstract-video-list'
-import { SortField } from '../../shared/video/sort-field.type'
+import { VideoSortField } from '../../shared/video/sort-field.type'
 import { VideoService } from '../../shared/video/video.service'
 
 @Component({
@@ -15,7 +15,7 @@ import { VideoService } from '../../shared/video/video.service'
 export class VideoTrendingComponent extends AbstractVideoList implements OnInit, OnDestroy {
   titlePage = 'Trending'
   currentRoute = '/videos/trending'
-  defaultSort: SortField = '-views'
+  defaultSort: VideoSortField = '-views'
 
   constructor (protected router: Router,
                protected route: ActivatedRoute,
@@ -41,6 +41,6 @@ export class VideoTrendingComponent extends AbstractVideoList implements OnInit,
   }
 
   generateSyndicationList () {
-    this.syndicationItems = this.videoService.getVideoFeedUrls()
+    this.syndicationItems = this.videoService.getVideoFeedUrls(this.sort)
   }
 }
index abe6b3ff70282894f3861cf592ed199c6497db27..56cbf9448a27f96bb3e7027cb895991f6f3ec650 100644 (file)
@@ -161,7 +161,7 @@ export {
 
 async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
   const user = res.locals.oauth.token.User as UserModel
-  const resultList = await VideoModel.listUserVideosForApi(user.id ,req.query.start, req.query.count, req.query.sort)
+  const resultList = await VideoModel.listAccountVideosForApi(user.Account.id ,req.query.start, req.query.count, req.query.sort)
 
   return res.json(getFormattedObjects(resultList.data, resultList.total))
 }
index b9d4c5d50024b39e6cc27ab508e62caf348cb24f..700c50ec8ac9a3260649687bc88614f968c80c5b 100644 (file)
@@ -1,6 +1,12 @@
 import * as express from 'express'
 import { CONFIG } from '../initializers'
-import { asyncMiddleware, feedsValidator } from '../middlewares'
+import {
+  asyncMiddleware,
+  feedsValidator,
+  setDefaultPagination,
+  setDefaultSort,
+  videosSortValidator
+} from '../middlewares'
 import { VideoModel } from '../models/video/video'
 import * as Feed from 'pfeed'
 import { ResultList } from '../../shared/models'
@@ -9,6 +15,8 @@ import { AccountModel } from '../models/account/account'
 const feedsRouter = express.Router()
 
 feedsRouter.get('/feeds/videos.:format',
+  videosSortValidator,
+  setDefaultSort,
   asyncMiddleware(feedsValidator),
   asyncMiddleware(generateFeed)
 )
@@ -23,26 +31,25 @@ export {
 
 async function generateFeed (req: express.Request, res: express.Response, next: express.NextFunction) {
   let feed = initFeed()
-  let feedStart = 0
-  let feedCount = 10
-  let feedSort = '-createdAt'
+  const paginationStart = 0
+  const paginationCount = 20
 
   let resultList: ResultList<VideoModel>
   const account: AccountModel = res.locals.account
 
   if (account) {
-    resultList = await VideoModel.listUserVideosForApi(
+    resultList = await VideoModel.listAccountVideosForApi(
       account.id,
-      feedStart,
-      feedCount,
-      feedSort,
+      paginationStart,
+      paginationCount,
+      req.query.sort,
       true
     )
   } else {
     resultList = await VideoModel.listForApi(
-      feedStart,
-      feedCount,
-      feedSort,
+      paginationStart,
+      paginationCount,
+      req.query.sort,
       req.query.filter,
       true
     )
@@ -100,7 +107,7 @@ function initFeed () {
       rss: `${webserverUrl}/feeds/videos.xml`
     },
     author: {
-      name: 'instance admin of ' + CONFIG.INSTANCE.NAME,
+      name: 'Instance admin of ' + CONFIG.INSTANCE.NAME,
       email: CONFIG.ADMIN.EMAIL,
       link: `${webserverUrl}/about`
     }
index 240a2b5a2584d5271d9545d79290e979f7976b22..ffb9725b4a164025c71a91a769d17e8e54997a95 100644 (file)
@@ -640,7 +640,7 @@ export class VideoModel extends Model<VideoModel> {
     })
   }
 
-  static listUserVideosForApi (userId: number, start: number, count: number, sort: string, withFiles = false) {
+  static listAccountVideosForApi (accountId: number, start: number, count: number, sort: string, withFiles = false) {
     const query: IFindOptions<VideoModel> = {
       offset: start,
       limit: count,
@@ -653,7 +653,7 @@ export class VideoModel extends Model<VideoModel> {
             {
               model: AccountModel,
               where: {
-                userId
+                id: accountId
               },
               required: true
             }