|
1 # |
|
2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net> |
|
3 # All Rights Reserved. |
|
4 # |
|
5 # This software is subject to the provisions of the Zope Public License, |
|
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
10 # FOR A PARTICULAR PURPOSE. |
|
11 # |
|
12 from pyams_form.interfaces.form import IWidgetsPrefixViewletsManager |
|
13 from pyams_skin.help import ContentHelp |
|
14 from pyams_skin.interfaces import IContentHelp |
|
15 from pyams_template.template import template_config |
|
16 from pyams_utils.adapter import adapter_config |
|
17 from pyams_zmi.layer import IAdminLayer |
|
18 |
|
19 __docformat__ = 'restructuredtext' |
|
20 |
|
21 |
|
22 # import standard library |
|
23 from decimal import Decimal |
|
24 |
|
25 # import interfaces |
|
26 from pyams_file.interfaces import IVideo, IThumbnail |
|
27 from pyams_skin.interfaces.viewlet import IContextActions |
|
28 from z3c.form.interfaces import HIDDEN_MODE |
|
29 |
|
30 # import packages |
|
31 from pyams_form.form import AJAXAddForm |
|
32 from pyams_form.schema import CloseButton |
|
33 from pyams_pagelet.pagelet import pagelet_config |
|
34 from pyams_skin.layer import IPyAMSLayer |
|
35 from pyams_skin.viewlet.toolbar import ToolbarMenuDivider, ToolbarMenuItem |
|
36 from pyams_utils.schema import DottedDecimalField |
|
37 from pyams_viewlet.viewlet import viewlet_config, Viewlet |
|
38 from pyams_zmi.form import AdminDialogAddForm |
|
39 from pyramid.view import view_config |
|
40 from z3c.form import field, button |
|
41 from zope.interface import Interface |
|
42 |
|
43 from pyams_media import _ |
|
44 |
|
45 |
|
46 @viewlet_config(name='video.thumbnail.divider', context=IVideo, layer=IPyAMSLayer, view=Interface, |
|
47 manager=IContextActions, permission='manage', weight=19) |
|
48 class VideoDividerAction(ToolbarMenuDivider): |
|
49 """Video divider action""" |
|
50 |
|
51 |
|
52 # |
|
53 # Video thumbnail |
|
54 # |
|
55 |
|
56 @viewlet_config(name='video.thumbnail.action', context=IVideo, layer=IPyAMSLayer, view=Interface, |
|
57 manager=IContextActions, permission='manage', weight=20) |
|
58 class VideoThumbnailAction(ToolbarMenuItem): |
|
59 """Video thumbnail selection action""" |
|
60 |
|
61 label = _("Select thumbnail...") |
|
62 label_css_class = 'fa fa-fw fa-film' |
|
63 |
|
64 url = 'video-thumbnail.html' |
|
65 modal_target = True |
|
66 |
|
67 |
|
68 class IVideoThumbnailButtons(Interface): |
|
69 """Video thumbnail selection buttons""" |
|
70 |
|
71 close = CloseButton(name='close', title=_("Close")) |
|
72 select = button.Button(name='resize', title=_("Select thumbnail")) |
|
73 |
|
74 |
|
75 class IVideoThumbnailInfo(Interface): |
|
76 """Video thumbnail selection info""" |
|
77 |
|
78 time = DottedDecimalField(title=_("Thumbnail timestamp"), |
|
79 required=True, |
|
80 default=Decimal(5)) |
|
81 |
|
82 |
|
83 @pagelet_config(name='video-thumbnail.html', context=IVideo, layer=IPyAMSLayer, permission='manage') |
|
84 class VideoThumbnailEditForm(AdminDialogAddForm): |
|
85 """Video thumbnail selection form""" |
|
86 |
|
87 legend = _("Select video thumbnail") |
|
88 icon_css_class = 'fa fa-fw fa-film' |
|
89 |
|
90 fields = field.Fields(IVideoThumbnailInfo) |
|
91 buttons = button.Buttons(IVideoThumbnailButtons) |
|
92 ajax_handler = 'video-thumbnail.json' |
|
93 |
|
94 @property |
|
95 def title(self): |
|
96 return self.context.title or self.context.filename |
|
97 |
|
98 def updateWidgets(self, prefix=None): |
|
99 super(VideoThumbnailEditForm, self).updateWidgets(prefix) |
|
100 self.widgets['time'].mode = HIDDEN_MODE |
|
101 |
|
102 def updateActions(self): |
|
103 super(VideoThumbnailEditForm, self).updateActions() |
|
104 if 'select' in self.actions: |
|
105 self.actions['select'].addClass('btn-primary') |
|
106 |
|
107 def createAndAdd(self, data): |
|
108 thumbnailer = IThumbnail(self.context, None) |
|
109 if thumbnailer is not None: |
|
110 size = thumbnailer.get_image_size() |
|
111 time = data.get('time') |
|
112 if not isinstance(time, float): |
|
113 time = float(time) |
|
114 thumbnailer.clear_thumbnails() |
|
115 return thumbnailer.get_thumbnail('{0[0]}x{0[1]}'.format(size), 'png', time) |
|
116 |
|
117 |
|
118 @view_config(name='video-thumbnail.json', context=IVideo, request_type=IPyAMSLayer, |
|
119 permission='manage', renderer='json', xhr=True) |
|
120 class VideoThumbnailAJAXEditForm(AJAXAddForm, VideoThumbnailEditForm): |
|
121 """Video thumbnail selection form, JSON renderer""" |
|
122 |
|
123 def get_ajax_output(self, changes): |
|
124 translate = self.request.localizer.translate |
|
125 if changes: |
|
126 return {'status': 'success', |
|
127 'message': translate(_("Thumbnail selected successfully."))} |
|
128 else: |
|
129 return {'status': 'info', |
|
130 'message': translate(_("An error occurred. No created thumbnail."))} |
|
131 |
|
132 |
|
133 @viewlet_config(name='video-thumbnail-prefix', context=IVideo, layer=IAdminLayer, view=VideoThumbnailEditForm, |
|
134 manager=IWidgetsPrefixViewletsManager) |
|
135 @template_config(template='templates/video-thumbnail.pt') |
|
136 class VideoThumbnailViewletsPrefix(Viewlet): |
|
137 """Video thumbnail edit form viewlets prefix""" |
|
138 |
|
139 |
|
140 @adapter_config(context=(IVideo, IAdminLayer, VideoThumbnailEditForm), provides=IContentHelp) |
|
141 class VideoThumbnailEditFormHelpAdapter(ContentHelp): |
|
142 """Video thumbnail selection form help adapter""" |
|
143 |
|
144 message = _("""You can play the video until you display the image you want. |
|
145 |
|
146 By pausing the video and clicking on ''Select thumbnail'' button, the selected frame will be used as |
|
147 video illustration.""") |
|
148 message_format = 'rest' |