mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Videos near a video file without and upload date are returned as the prev/next videos.
This commit is contained in:
parent
14017d43bb
commit
9dbd43cfdd
3 changed files with 95 additions and 37 deletions
|
|
@ -59,7 +59,7 @@ export function CaptionTrack({src, ...props}) {
|
|||
return <track kind="captions" label="Portuguese" src={src} srcLang="pt" {...props}/>
|
||||
} else if (src.endsWith('.ro.vtt')) {
|
||||
return <track kind="captions" label="Romanian" src={src} srcLang="ro" {...props}/>
|
||||
} else if (src.endsWith('.ru.vtt')) {
|
||||
} else if (src.endsWith('.ru.vtt')) {
|
||||
return <track kind="captions" label="Russian" src={src} srcLang="ru" {...props}/>
|
||||
} else if (src.endsWith('.th.vtt')) {
|
||||
return <track kind="captions" label="Thai" src={src} srcLang="th" {...props}/>
|
||||
|
|
@ -194,6 +194,22 @@ function VideoPage({videoFile, prevFile, nextFile, fetchVideo, ...props}) {
|
|||
|
||||
let videoSource = <source src={videoUrl}/>;
|
||||
|
||||
let prevNextVideosSegment = <Segment><p>No related videos found.</p></Segment>;
|
||||
if (prevFile || nextFile) {
|
||||
prevNextVideosSegment = <Segment>
|
||||
<Grid columns={2} stackable>
|
||||
<Grid.Row>
|
||||
<Grid.Column textAlign='left'>
|
||||
{prevFile && <><Header as='h3'>Older</Header><VideoCard file={prevFile}/></>}
|
||||
</Grid.Column>
|
||||
<Grid.Column textAlign='left'>
|
||||
{nextFile && <><Header as='h3'>Newer</Header><VideoCard file={nextFile}/></>}
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</Segment>
|
||||
}
|
||||
|
||||
return <>
|
||||
<Container style={{margin: '1em'}}>
|
||||
<BackButton/>
|
||||
|
|
@ -245,18 +261,7 @@ function VideoPage({videoFile, prevFile, nextFile, fetchVideo, ...props}) {
|
|||
|
||||
<Tab menu={tabMenu} panes={tabPanes}/>
|
||||
|
||||
<Segment>
|
||||
<Grid columns={2} stackable>
|
||||
<Grid.Row>
|
||||
<Grid.Column textAlign='left'>
|
||||
{prevFile && <><Header as='h3'>Older</Header><VideoCard file={prevFile}/></>}
|
||||
</Grid.Column>
|
||||
<Grid.Column textAlign='left'>
|
||||
{nextFile && <><Header as='h3'>Newer</Header><VideoCard file={nextFile}/></>}
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</Segment>
|
||||
{prevNextVideosSegment}
|
||||
</Container>
|
||||
</>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -133,13 +133,12 @@ class Video(ModelHelper, Base):
|
|||
|
||||
def get_surrounding_videos(self):
|
||||
"""
|
||||
Get the previous and next videos around this video. The videos must be in the same channel.
|
||||
Get the previous and next videos around this Video. The videos must be in the same Channel.
|
||||
|
||||
Example:
|
||||
>>> vid1 = Video(id=1, upload_date=10)
|
||||
>>> vid2 = Video(id=2, upload_date=20)
|
||||
>>> vid3 = Video(id=3, upload_date=30)
|
||||
>>> vid4 = Video(id=4)
|
||||
|
||||
>>> vid1.get_surrounding_videos()
|
||||
(None, vid2)
|
||||
|
|
@ -147,38 +146,54 @@ class Video(ModelHelper, Base):
|
|||
(vid1, vid3)
|
||||
>>> vid3.get_surrounding_videos()
|
||||
(vid2, None)
|
||||
Video 4 has no upload date, so we can't place it in order.
|
||||
>>> vid4.get_surrounding_videos()
|
||||
(None, None)
|
||||
"""
|
||||
session = Session.object_session(self)
|
||||
|
||||
if not self.upload_date:
|
||||
# We can't place a video that has no upload date.
|
||||
return None, None
|
||||
|
||||
with get_db_curs() as curs:
|
||||
query = '''
|
||||
if self.upload_date:
|
||||
# Get videos next to this Video's upload date.
|
||||
stmt = '''
|
||||
WITH numbered_videos AS (
|
||||
SELECT id,
|
||||
ROW_NUMBER() OVER (ORDER BY upload_date ASC) AS row_number
|
||||
FROM video
|
||||
WHERE
|
||||
channel_id = %(channel_id)s
|
||||
AND upload_date IS NOT NULL
|
||||
)
|
||||
SELECT id
|
||||
FROM numbered_videos
|
||||
WHERE row_number IN (
|
||||
SELECT row_number+i
|
||||
FROM numbered_videos
|
||||
CROSS JOIN (SELECT -1 AS i UNION ALL SELECT 0 UNION ALL SELECT 1) n
|
||||
WHERE
|
||||
id = %(video_id)s
|
||||
)
|
||||
'''
|
||||
else:
|
||||
# No videos near this Video with upload dates, recommend the files next to this Video.
|
||||
# Only recommend videos in the same Channel (or similarly without a Channel).
|
||||
channel_where = 'WHERE v.channel_id = %(channel_id)s' if self.channel_id \
|
||||
else 'WHERE v.channel_id IS NULL'
|
||||
stmt = f'''
|
||||
WITH numbered_videos AS (
|
||||
SELECT id,
|
||||
ROW_NUMBER() OVER (ORDER BY upload_date ASC) AS row_number
|
||||
FROM video
|
||||
WHERE
|
||||
channel_id = %(channel_id)s
|
||||
AND upload_date IS NOT NULL
|
||||
SELECT v.id, ROW_NUMBER() OVER (ORDER BY fg.primary_path) AS row_number
|
||||
FROM
|
||||
video v
|
||||
LEFT JOIN file_group fg on fg.id = v.file_group_id
|
||||
{channel_where}
|
||||
)
|
||||
|
||||
SELECT id
|
||||
FROM numbered_videos
|
||||
WHERE row_number IN (
|
||||
SELECT row_number+i
|
||||
FROM numbered_videos
|
||||
CROSS JOIN (SELECT -1 AS i UNION ALL SELECT 0 UNION ALL SELECT 1) n
|
||||
WHERE
|
||||
id = %(video_id)s
|
||||
)
|
||||
'''
|
||||
curs.execute(query, dict(channel_id=self.channel_id, video_id=self.id))
|
||||
'''
|
||||
curs.execute(stmt, dict(channel_id=self.channel_id, video_id=self.id))
|
||||
|
||||
results = [i[0] for i in curs.fetchall()]
|
||||
|
||||
# Assign the returned ID's to their respective positions relative to the ID that matches the video_id.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import pytest
|
|||
from modules.videos.models import Video
|
||||
from modules.videos.video.lib import get_video_for_app
|
||||
from wrolpi.dates import now
|
||||
from wrolpi.errors import WROLModeEnabled
|
||||
|
||||
|
||||
def test_get_video_prev_next(test_session, channel_factory, video_factory):
|
||||
|
|
@ -41,7 +40,7 @@ def test_get_video_prev_next(test_session, channel_factory, video_factory):
|
|||
(1, (None, 'vid2')),
|
||||
(2, ('vid1', 'vid4')),
|
||||
(4, ('vid2', None)), # 7 has no upload_date, so it doesn't come after 4.
|
||||
(7, (None, None)), # 7 has no upload_date, so we don't know the order of it.
|
||||
(7, ('vid4', None)), # 7 has no upload_date, so we get the video next to it's file.
|
||||
# Channel 3 has only one video.
|
||||
(9, (None, None)),
|
||||
# Channel 2 was inserted out of order.
|
||||
|
|
@ -49,7 +48,8 @@ def test_get_video_prev_next(test_session, channel_factory, video_factory):
|
|||
(3, ('vid5', 'vid6')),
|
||||
(8, ('vid6', None)),
|
||||
# Channel 4's videos have no upload date, so we don't know what is previous/next.
|
||||
(10, (None, None)),
|
||||
(10, (None, 'vid11')),
|
||||
(11, ('vid10', None)),
|
||||
]
|
||||
|
||||
for id_, (prev_title, next_title) in tests:
|
||||
|
|
@ -70,6 +70,44 @@ def test_get_video_prev_next(test_session, channel_factory, video_factory):
|
|||
raise AssertionError(f'Assert failed for {id_=} {prev_title=} {next_title=}') from e
|
||||
|
||||
|
||||
def test_get_video_prev_next_no_upload_date(test_session, video_factory, channel_factory):
|
||||
"""
|
||||
Previous and Next Videos should be those next to a Video file when videos do not have upload dates.
|
||||
"""
|
||||
channel1, channel2 = channel_factory(), channel_factory()
|
||||
vid0, vid1, vid2, vid3, vid4, vid5 = video_factory(channel2.id, title='vid0'), \
|
||||
video_factory(channel1.id, title='vid1'), \
|
||||
video_factory(channel1.id, title='vid2'), \
|
||||
video_factory(channel1.id, title='vid3'), \
|
||||
video_factory(title='vid4'), \
|
||||
video_factory(title='vid5')
|
||||
test_session.commit()
|
||||
|
||||
# Channel 2 has only 1 video.
|
||||
prev, next_ = vid0.get_surrounding_videos()
|
||||
assert prev is None
|
||||
assert next_ is None
|
||||
|
||||
# Channel 1 has 3 videos, finally getting surrounding videos.
|
||||
prev, next_ = vid1.get_surrounding_videos()
|
||||
assert prev is None
|
||||
assert next_ == vid2
|
||||
prev, next_ = vid2.get_surrounding_videos()
|
||||
assert prev == vid1
|
||||
assert next_ == vid3
|
||||
prev, next_ = vid3.get_surrounding_videos()
|
||||
assert prev == vid2
|
||||
assert next_ is None
|
||||
|
||||
# Videos without a channel
|
||||
prev, next_ = vid4.get_surrounding_videos()
|
||||
assert prev is None
|
||||
assert next_ is vid5
|
||||
prev, next_ = vid5.get_surrounding_videos()
|
||||
assert prev == vid4
|
||||
assert next_ is None
|
||||
|
||||
|
||||
def test_get_video_for_app(test_session, simple_channel, simple_video):
|
||||
vid, prev, next_ = get_video_for_app(simple_video.id)
|
||||
assert vid['id'] == simple_video.id
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue