mirror of
https://github.com/lrnselfreliance/wrolpi.git
synced 2026-10-26 19:01:39 -04:00
Channel can be created with Tag.
This commit is contained in:
parent
84a173677c
commit
11dc370ed9
4 changed files with 99 additions and 63 deletions
|
|
@ -100,7 +100,7 @@ function ChannelPage({create, header}) {
|
|||
const {channel, changeValue, fetchChannel} = useChannel(channelId);
|
||||
const {SingleTag} = React.useContext(TagsContext);
|
||||
|
||||
const [tagModalOpen, setTagModalOpen] = useState(false);
|
||||
const [tagEditModalOpen, setTagEditModalOpen] = useState(false);
|
||||
const [newTagName, setNewTagName] = useState(channel ? channel.tag_name : null);
|
||||
const [moveToTagDirectory, setMoveToTagDirectory] = useState(true);
|
||||
const [newTagDirectory, setNewTagDirectory] = useState('');
|
||||
|
|
@ -147,6 +147,7 @@ function ChannelPage({create, header}) {
|
|||
name: channel.name,
|
||||
directory: channel.directory,
|
||||
url: channel.url,
|
||||
tag_name: channel.tag_name,
|
||||
};
|
||||
|
||||
setDisabled(true);
|
||||
|
|
@ -252,13 +253,13 @@ function ChannelPage({create, header}) {
|
|||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
setTagModalOpen(true);
|
||||
setTagEditModalOpen(true);
|
||||
}
|
||||
|
||||
const handleTagChannel = async () => {
|
||||
const handleTagEditChannel = async () => {
|
||||
try {
|
||||
await tagChannel(channelId, newTagName, moveToTagDirectory ? newTagDirectory : null);
|
||||
setTagModalOpen(false);
|
||||
setTagEditModalOpen(false);
|
||||
} catch (e) {
|
||||
console.error('Failed to tag channel', e);
|
||||
} finally {
|
||||
|
|
@ -269,9 +270,10 @@ function ChannelPage({create, header}) {
|
|||
}
|
||||
}
|
||||
|
||||
const handleTagSelect = async (newTagName_) => {
|
||||
const handleTagSelectMoveSuggestion = async (newTagName_) => {
|
||||
setNewTagName(newTagName_);
|
||||
try {
|
||||
// Get suggested Tag directory for this Tag and Channel.
|
||||
const videosDestination = await tagChannelInfo(channelId, newTagName_);
|
||||
setNewTagDirectory(videosDestination);
|
||||
} catch (e) {
|
||||
|
|
@ -279,53 +281,57 @@ function ChannelPage({create, header}) {
|
|||
}
|
||||
}
|
||||
|
||||
const tagModal = <Modal
|
||||
open={tagModalOpen}
|
||||
onClose={() => setTagModalOpen(false)}
|
||||
closeIcon
|
||||
>
|
||||
<ModalHeader>{channel.tag_name ? 'Modify Tag' : 'Add Tag'}</ModalHeader>
|
||||
<ModalContent>
|
||||
<Grid columns={1}>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<TagsSelector
|
||||
limit={1}
|
||||
selectedTagNames={newTagName ? [newTagName] : []}
|
||||
onAdd={handleTagSelect}
|
||||
onRemove={() => handleTagSelect(null)}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<Toggle
|
||||
label='Move to directory: '
|
||||
checked={moveToTagDirectory}
|
||||
onChange={setMoveToTagDirectory}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<Input fluid
|
||||
value={newTagDirectory}
|
||||
onChange={(e, {value}) => setNewTagDirectory(value)}
|
||||
disabled={!moveToTagDirectory}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</ModalContent>
|
||||
<ModalActions>
|
||||
<Button onClick={() => setTagModalOpen(false)}>Cancel</Button>
|
||||
<APIButton
|
||||
color='violet'
|
||||
onClick={handleTagChannel}
|
||||
obeyWROLMode={true}
|
||||
>Save</APIButton>
|
||||
</ModalActions>
|
||||
</Modal>;
|
||||
let tagEditModal;
|
||||
if (!create) {
|
||||
// User is editing the Tag of the Channel.
|
||||
tagEditModal = <Modal
|
||||
open={tagEditModalOpen}
|
||||
onClose={() => setTagEditModalOpen(false)}
|
||||
closeIcon
|
||||
>
|
||||
<ModalHeader>{channel.tag_name ? 'Modify Tag' : 'Add Tag'}</ModalHeader>
|
||||
<ModalContent>
|
||||
<Grid columns={1}>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<TagsSelector
|
||||
limit={1}
|
||||
selectedTagNames={newTagName ? [newTagName] : []}
|
||||
onAdd={handleTagSelectMoveSuggestion}
|
||||
onRemove={() => handleTagSelectMoveSuggestion(null)}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<Toggle
|
||||
label='Move to directory: '
|
||||
checked={moveToTagDirectory}
|
||||
onChange={setMoveToTagDirectory}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
<Input fluid
|
||||
value={newTagDirectory}
|
||||
onChange={(e, {value}) => setNewTagDirectory(value)}
|
||||
disabled={!moveToTagDirectory}
|
||||
/>
|
||||
</Grid.Column>
|
||||
</Grid.Row>
|
||||
</Grid>
|
||||
</ModalContent>
|
||||
<ModalActions>
|
||||
<Button onClick={() => setTagEditModalOpen(false)}>Cancel</Button>
|
||||
<APIButton
|
||||
color='violet'
|
||||
onClick={handleTagEditChannel}
|
||||
obeyWROLMode={true}
|
||||
>Save</APIButton>
|
||||
</ModalActions>
|
||||
</Modal>;
|
||||
}
|
||||
|
||||
return <>
|
||||
<BackButton/>
|
||||
|
|
@ -383,7 +389,7 @@ function ChannelPage({create, header}) {
|
|||
</FormField>
|
||||
</FormGroup>
|
||||
|
||||
{channel.tag_name && <SingleTag name={channel.tag_name}/>}
|
||||
{channel.tag_name && !create && <SingleTag name={channel.tag_name}/>}
|
||||
|
||||
<Message error
|
||||
header={messageHeader}
|
||||
|
|
@ -395,9 +401,9 @@ function ChannelPage({create, header}) {
|
|||
/>
|
||||
|
||||
<Grid stackable columns={2}>
|
||||
<Grid.Row>
|
||||
<Grid.Column>
|
||||
{!create &&
|
||||
<Grid.Row style={{marginTop: '1em'}}>
|
||||
<Grid.Column width={8}>
|
||||
{!create ?
|
||||
<>
|
||||
<APIButton
|
||||
color='red'
|
||||
|
|
@ -415,14 +421,22 @@ function ChannelPage({create, header}) {
|
|||
obeyWROLMode={true}
|
||||
style={{marginTop: '1em'}}
|
||||
>Refresh</APIButton>
|
||||
<Button
|
||||
size='small'
|
||||
onClick={handleTagModalOpen}
|
||||
color='green'
|
||||
>Tag</Button>
|
||||
{tagEditModal}
|
||||
</>
|
||||
: <>
|
||||
<TagsSelector
|
||||
limit={1}
|
||||
selectedTagNames={channel.tag_name ? [channel.tag_name] : []}
|
||||
onAdd={i => changeValue('tag_name', i)}
|
||||
onRemove={() => changeValue('tag_name', null)}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
<Button
|
||||
size='small'
|
||||
onClick={handleTagModalOpen}
|
||||
color='green'
|
||||
>Tag</Button>
|
||||
{tagModal}
|
||||
</Grid.Column>
|
||||
<Grid.Column>
|
||||
<APIButton
|
||||
|
|
|
|||
|
|
@ -426,6 +426,7 @@ export const useChannel = (channel_id) => {
|
|||
url: '',
|
||||
download_frequency: '',
|
||||
match_regex: '',
|
||||
tag_name: null,
|
||||
};
|
||||
const [fetched, setFetched] = useState(false);
|
||||
const [channel, setChannel] = useState(emptyChannel);
|
||||
|
|
|
|||
|
|
@ -549,6 +549,26 @@ async def test_tag_channel(async_client, test_session, test_directory, channel_f
|
|||
assert [i.path for i in test_session.query(Directory)] == [channel.directory, ]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_create_channel_with_tag(async_client, test_session, test_directory, tag_factory):
|
||||
"""A Channel can be created with a single Tag."""
|
||||
tag = await tag_factory()
|
||||
assert not (test_directory / 'some/deep/new/directory').exists()
|
||||
|
||||
body = dict(
|
||||
name='Channel Name',
|
||||
directory='some/deep/new/directory',
|
||||
tag_name=tag.name,
|
||||
)
|
||||
request, response = await async_client.post('/api/videos/channels', json=body)
|
||||
assert response.status_code == HTTPStatus.CREATED, response.content.decode()
|
||||
|
||||
channel = test_session.query(Channel).one()
|
||||
assert channel.tag_name == tag.name
|
||||
assert channel.directory == (test_directory / 'some/deep/new/directory')
|
||||
assert (test_directory / 'some/deep/new/directory').is_dir()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_move_channel(async_client, test_session, test_directory, channel_factory, tag_factory,
|
||||
video_factory, test_channels_config, test_download_manager, test_downloader):
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ class ChannelPostRequest:
|
|||
directory: str
|
||||
calculate_duration: Optional[bool] = None
|
||||
generate_posters: Optional[bool] = None
|
||||
url: Optional[str] = None
|
||||
source_id: Optional[str] = None
|
||||
tag_name: Optional[str] = None
|
||||
url: Optional[str] = None
|
||||
|
||||
def __post_init__(self):
|
||||
self.name = self.name.strip() or None
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue