Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
django-panik-emissions
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
radiopanik
django-panik-emissions
Commits
3a520f21
Commit
3a520f21
authored
May 16, 2020
by
fred
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
check and set sound file duration at upload time
parent
056d2177
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
60 additions
and
15 deletions
+60
-15
emissions/forms.py
emissions/forms.py
+9
-0
emissions/management/commands/create-sound-files.py
emissions/management/commands/create-sound-files.py
+5
-14
emissions/models.py
emissions/models.py
+7
-1
emissions/utils.py
emissions/utils.py
+32
-0
emissions/views.py
emissions/views.py
+7
-0
No files found.
emissions/forms.py
View file @
3a520f21
...
@@ -6,6 +6,7 @@ import uuid
...
@@ -6,6 +6,7 @@ import uuid
from
django
import
forms
from
django
import
forms
from
django.forms
import
fields
from
django.forms
import
fields
from
django.forms
import
ValidationError
from
django.core.files.storage
import
DefaultStorage
from
django.core.files.storage
import
DefaultStorage
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
...
@@ -19,6 +20,7 @@ from taggit.forms import TagWidget
...
@@ -19,6 +20,7 @@ from taggit.forms import TagWidget
from
.models
import
(
Emission
,
Episode
,
Diffusion
,
Schedule
,
SoundFile
,
from
.models
import
(
Emission
,
Episode
,
Diffusion
,
Schedule
,
SoundFile
,
NewsItem
,
Absence
,
PlaylistElement
)
NewsItem
,
Absence
,
PlaylistElement
)
from
.utils
import
get_duration
from
.widgets
import
DateTimeWidget
,
DateWidget
from
.widgets
import
DateTimeWidget
,
DateWidget
...
@@ -240,6 +242,13 @@ class SoundFileForm(forms.ModelForm):
...
@@ -240,6 +242,13 @@ class SoundFileForm(forms.ModelForm):
'file'
:
JqueryFileUploadInput
(),
'file'
:
JqueryFileUploadInput
(),
}
}
def
clean
(
self
):
super
().
clean
()
if
self
.
cleaned_data
.
get
(
'file'
):
duration
=
get_duration
(
self
.
cleaned_data
[
'file'
].
file
.
name
)
if
not
duration
:
raise
ValidationError
(
_
(
'Invalid file, could not get duration.'
))
class
SoundFileEditForm
(
forms
.
ModelForm
):
class
SoundFileEditForm
(
forms
.
ModelForm
):
class
Meta
:
class
Meta
:
...
...
emissions/management/commands/create-sound-files.py
View file @
3a520f21
...
@@ -82,12 +82,8 @@ class Command(BaseCommand):
...
@@ -82,12 +82,8 @@ class Command(BaseCommand):
if
not
soundfile
.
podcastable
:
if
not
soundfile
.
podcastable
:
# get duration using initial file
# get duration using initial file
if
not
soundfile
.
duration
:
if
not
soundfile
.
duration
:
cmd
=
[
'soxi'
,
'-D'
,
soundfile
.
file
.
path
]
soundfile
.
compute_duration
()
try
:
if
soundfile
.
duration
:
soundfile
.
duration
=
int
(
float
(
subprocess
.
check_output
(
cmd
)))
except
(
ValueError
,
subprocess
.
CalledProcessError
):
pass
else
:
soundfile
.
save
()
soundfile
.
save
()
continue
continue
for
format
in
formats
.
split
(
','
):
for
format
in
formats
.
split
(
','
):
...
@@ -98,14 +94,9 @@ class Command(BaseCommand):
...
@@ -98,14 +94,9 @@ class Command(BaseCommand):
if
created
or
reset_metadata
:
if
created
or
reset_metadata
:
self
.
set_metadata
(
soundfile
,
format
)
self
.
set_metadata
(
soundfile
,
format
)
if
(
force
or
not
soundfile
.
duration
):
if
(
force
or
not
soundfile
.
duration
):
for
extension
in
(
'ogg'
,
'mp3'
):
soundfile
.
compute_duration
()
soundfile_name
=
soundfile
.
get_format_path
(
extension
)
if
soundfile
.
duration
:
if
os
.
path
.
exists
(
soundfile_name
):
soundfile
.
save
()
cmd
=
[
'soxi'
,
'-D'
,
soundfile_name
]
soundfile
.
duration
=
int
(
float
(
subprocess
.
check_output
(
cmd
)))
soundfile
.
save
()
break
def
create
(
self
,
soundfile
,
format
):
def
create
(
self
,
soundfile
,
format
):
file_path
=
soundfile
.
get_format_path
(
format
)
file_path
=
soundfile
.
get_format_path
(
format
)
...
...
emissions/models.py
View file @
3a520f21
...
@@ -17,7 +17,7 @@ from django.dispatch.dispatcher import receiver
...
@@ -17,7 +17,7 @@ from django.dispatch.dispatcher import receiver
from
ckeditor.fields
import
RichTextField
from
ckeditor.fields
import
RichTextField
from
taggit.managers
import
TaggableManager
from
taggit.managers
import
TaggableManager
from
.utils
import
maybe_resize
from
.utils
import
maybe_resize
,
get_duration
LICENSES
=
(
LICENSES
=
(
...
@@ -496,6 +496,12 @@ class SoundFile(models.Model):
...
@@ -496,6 +496,12 @@ class SoundFile(models.Model):
creation_timestamp
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
)
creation_timestamp
=
models
.
DateTimeField
(
auto_now_add
=
True
,
null
=
True
)
last_update_timestamp
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)
last_update_timestamp
=
models
.
DateTimeField
(
auto_now
=
True
,
null
=
True
)
def
compute_duration
(
self
):
for
path
in
(
self
.
get_format_path
(
'ogg'
),
self
.
get_format_path
(
'mp3'
),
self
.
file
.
path
):
self
.
duration
=
get_duration
(
path
)
if
self
.
duration
:
return
def
get_format_filename
(
self
,
format
):
def
get_format_filename
(
self
,
format
):
return
'%s_%05d__%s.%s'
%
(
return
'%s_%05d__%s.%s'
%
(
self
.
episode
.
slug
,
self
.
episode
.
slug
,
...
...
emissions/utils.py
View file @
3a520f21
from
datetime
import
datetime
,
timedelta
,
time
from
datetime
import
datetime
,
timedelta
,
time
import
os
import
os
import
subprocess
from
PIL
import
Image
from
PIL
import
Image
def
get_duration
(
filename
):
p
=
subprocess
.
Popen
([
'mediainfo'
,
'--Inform=Audio;%Duration%'
,
filename
],
close_fds
=
True
,
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
stdout
,
stderr
=
p
.
communicate
()
try
:
return
int
(
stdout
)
/
1000
except
ValueError
:
pass
# fallback on soxi
p
=
subprocess
.
Popen
([
'soxi'
,
filename
],
close_fds
=
True
,
stdin
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
)
stdout
,
stderr
=
p
.
communicate
()
for
line
in
stdout
.
splitlines
():
line
=
force_text
(
line
)
if
not
line
.
startswith
(
'Duration'
):
continue
try
:
hours
,
minutes
,
seconds
=
re
.
findall
(
r'(\d\d):(\d\d):(\d\d)'
,
line
)[
0
]
except
IndexError
:
continue
return
int
(
hours
)
*
3600
+
int
(
minutes
)
*
60
+
int
(
seconds
)
return
None
def
maybe_resize
(
image_path
):
def
maybe_resize
(
image_path
):
if
not
os
.
path
.
exists
(
image_path
):
if
not
os
.
path
.
exists
(
image_path
):
return
return
...
...
emissions/views.py
View file @
3a520f21
...
@@ -370,6 +370,13 @@ class EpisodeAddSoundFileView(CreateView):
...
@@ -370,6 +370,13 @@ class EpisodeAddSoundFileView(CreateView):
raise
PermissionDenied
()
raise
PermissionDenied
()
return
super
(
EpisodeAddSoundFileView
,
self
).
get_form
(
*
args
,
**
kwargs
)
return
super
(
EpisodeAddSoundFileView
,
self
).
get_form
(
*
args
,
**
kwargs
)
def
form_valid
(
self
,
form
):
response
=
super
().
form_valid
(
form
)
if
not
form
.
instance
.
duration
:
form
.
instance
.
compute_duration
()
form
.
instance
.
save
()
return
response
def
get_success_url
(
self
):
def
get_success_url
(
self
):
messages
.
success
(
self
.
request
,
SUCCESS_MESSAGE
)
messages
.
success
(
self
.
request
,
SUCCESS_MESSAGE
)
return
self
.
object
.
episode
.
get_absolute_url
()
return
self
.
object
.
episode
.
get_absolute_url
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment