class CommentsForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ RadioButtonList('comments_engine', label_text=N_('Comment Engine'), options=comments_enable_disable, validator=comments_enable_validator, ), ListFieldSet('builtin', suppress_label=True, legend=N_('Built-in Comments:'), css_classes=['details_fieldset'], children=[ CheckBox('req_comment_approval', label_text=N_('Moderation'), help_text=N_('Require comments to be approved by an admin'), css_classes=['checkbox-inline-help'], validator=Bool(if_missing='')), TextField('akismet_key', label_text=N_('Akismet Key')), TextField('akismet_url', label_text=N_('Akismet URL')), TextArea('vulgarity_filtered_words', label_text=N_('Filtered Words'), attrs=dict(rows=3, cols=15), help_text=N_('Enter words to be filtered separated by a comma.')), ]), ListFieldSet('facebook', suppress_label=True, legend=N_('Facebook Comments:'), css_classes=['details_fieldset'], children=[ TextField('facebook_appid', label_text=N_('Application ID'), help_text=N_('See: http://www.facebook.com/developers/createapp.php')), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class fields(WidgetsList): file_id = TextField(validator=Int()) file_type = SingleSelectField(validator=file_type_validator, options=file_type_options, attrs={ 'id': None, 'autocomplete': 'off' }) duration = TextField(validator=DurationValidator, attrs={ 'id': None, 'autocomplete': 'off' }) width_height = TextField(validator=WXHValidator, attrs={ 'id': None, 'autocomplete': 'off' }) bitrate = TextField(validator=Int, attrs={ 'id': None, 'autocomplete': 'off' }) delete = SubmitButton(default=N_('Delete file'), named_button=True, css_class='file-delete', attrs={'id': None})
class UserForm(ListForm): template = 'admin/box-form.html' id = 'user-form' css_class = 'form' submit_text = None show_children_errors = True _name = 'user-form' # TODO: Figure out why this is required?? event = events.Admin.UserForm fields = [ TextField('display_name', label_text=N_('Display Name'), validator=TextField.validator(not_empty=True), maxlength=255), TextField('email_address', label_text=N_('Email Address'), validator=email_validator(not_empty=True), maxlength=255), ListFieldSet('login_details', suppress_label=True, legend=N_('Login Details:'), css_classes=['details_fieldset'], validator = Schema(chained_validators=[ FieldsMatch('password', 'confirm_password', messages={'invalidNoMatch': N_("Passwords do not match"),})] ), children=[ CheckBoxList('groups', label_text=N_('Groups'), options=lambda: Group.custom_groups(Group.group_id, Group.display_name).all()), TextField('user_name', label_text=N_('Username'), maxlength=16, validator=All(PlainText(), UniqueUsername(not_empty=True))), PasswordField('password', label_text=N_('Password'), validators=NotEmpty, maxlength=80, attrs={'autocomplete': 'off'}), PasswordField('confirm_password', label_text=N_('Confirm password'), validators=NotEmpty, maxlength=80, attrs={'autocomplete': 'off'}), ] ), SubmitButton('save', default=N_('Save'), named_button=True, css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), SubmitButton('delete', default=N_('Delete'), named_button=True, css_classes=['btn', 'btn-delete']), ]
class GroupForm(ListForm): template = 'admin/box-form.html' id = 'group-form' css_class = 'form' submit_text = None show_children_errors = True event = events.Admin.GroupForm fields = [ TextField('display_name', label_text=N_('Display Name'), validator=TextField.validator(not_empty=True), maxlength=255), TextField('group_name', label_text=N_('Groupname'), validator=All(PlainText(not_empty=True), UniqueGroupname()), maxlength=16), CheckBoxList( 'permissions', label_text=N_('Group Permissions'), css_classes=['details_fieldset'], options=lambda: DBSession.query(Permission.permission_id, Permission.description).all()), SubmitButton('save', default=N_('Save'), named_button=True, css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), SubmitButton('delete', default=N_('Delete'), named_button=True, css_classes=['btn', 'btn-delete']), ]
class NotificationsForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ ListFieldSet('email', suppress_label=True, legend=N_('Email Notifications:'), css_classes=['details_fieldset'], children=[ TextField('email_media_uploaded', validator=email_list_validator, label_text=N_('Media Uploaded'), maxlength=255), TextField('email_comment_posted', validator=email_list_validator, label_text=N_('Comment Posted'), maxlength=255), TextField('email_support_requests', validator=email_list_validator, label_text=N_('Support Requested'), maxlength=255), TextField('email_send_from', validator=email_validator, label_text=N_('Send Emails From'), maxlength=255), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class MediaForm(ListForm): template = 'admin/box-form.html' id = 'media-form' css_class = 'form' submit_text = None show_children_errors = True _name = 'media-form' # TODO: Figure out why this is required?? event = events.Admin.MediaForm fields = [ SingleSelectField('podcast', label_text=N_('Include in the Podcast'), css_classes=['dropdown-select'], help_text=N_('Optional'), options=lambda: [(None, None)] + DBSession.query(Podcast.id, Podcast.title).all()), TextField('slug', label_text=N_('Permalink'), maxlength=50), TextField('title', label_text=N_('Title'), validator=TextField.validator(not_empty=True), maxlength=255), TextField('author_name', label_text=N_('Author Name'), maxlength=50), TextField('author_email', label_text=N_('Author Email'), validator=email_validator(not_empty=True), maxlength=255), XHTMLTextArea('description', label_text=N_('Description'), attrs=dict(rows=5, cols=25)), CategoryCheckBoxList('categories', label_text=N_('Categories'), options=lambda: DBSession.query(Category.id, Category.name).all()), TextArea('tags', label_text=N_('Tags'), attrs=dict(rows=3, cols=15), help_text=N_(u'e.g.: puppies, great dane, adorable')), TextArea('notes', label_text=N_('Administrative Notes'), attrs=dict(rows=3, cols=25), container_attrs = lambda: ({'class': 'hidden'}, {})[bool(request.settings.get('wording_display_administrative_notes', ''))], default=lambda: request.settings['wording_administrative_notes']), SubmitButton('save', default=N_('Save'), named_button=True, css_classes=['btn', 'blue', 'f-rgt']), SubmitButton('delete', default=N_('Delete'), named_button=True, css_classes=['btn', 'f-lft']), ]
class APIForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ boolean_radiobuttonlist( 'api_secret_key_required', label_text=N_('Require a key to access the API')), ListFieldSet('key', suppress_label=True, legend=N_('API Key:'), css_classes=['details_fieldset'], children=[ TextField('api_secret_key', label_text=N_('Access Key')), ]), ListFieldSet('prefs', suppress_label=True, legend=N_('API Settings:'), css_classes=['details_fieldset'], children=[ TextField('api_media_max_results', label_text=N_('Max media results')), TextField('api_tree_max_depth', label_text=N_('Max tree depth')), ]), SubmitButton('save', default='Save', css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class TagForm(ListForm): template = 'admin/tags_and_categories_form.html' id = None css_classes = ['form', 'tag-form'] submit_text = None event = events.Admin.TagForm # required to support multiple named buttons to differentiate between Save & Delete? _name = 'vf' fields = [ TextField('name', label_text=N_('Name'), css_classes=['tag-name'], validator=TagNameValidator(not_empty=True)), TextField('slug', label_text=N_('Permalink'), css_classes=['tag-slug'], validator=NotEmpty), ResetButton('cancel', default=N_('Cancel'), css_classes=['btn', 'f-lft', 'btn-cancel']), SubmitButton('save', default=N_('Save'), css_classes=['f-rgt', 'btn', 'blue', 'btn-save']), ]
class fields(WidgetsList): name = TextField(validator=validators['name'], label_text=N_('Your Name:'), maxlength=50) email = TextField(validator=email_validator(not_empty=True), label_text=N_('Your Email:'), help_text=N_('(will never be published)'), maxlength=255) title = TextField(validator=validators['title'], label_text=N_('Title:'), maxlength=255) description = XHTMLTextArea(validator=validators['description'], label_text=N_('Description:'), attrs=dict(rows=5, cols=25)) url = TextField(validator=validators['url'], label_text=N_('Add a YouTube, Vimeo or Google Video URL:'), maxlength=255) file = FileField(validator=FieldStorageUploadConverter(if_missing=None, messages={'empty':N_('Oops! You forgot to enter a file.')}), label_text=N_('OR:')) submit = SubmitButton(default=N_('Submit'), css_classes=['mcore-btn', 'btn-submit'])
class LocalFileStorageForm(StorageForm): event = events.Admin.Storage.LocalFileStorageForm fields = StorageForm.fields + [ ListFieldSet('specifics', suppress_label=True, legend=N_('Options specific to Local File Storage:'), children=[ TextField('path', label_text=N_('Path to store files under'), help_text=N_('Defaults to the "data_dir" from your INI file.'), ), TextField('rtmp_server_uri', label_text=N_('RTMP Server URL'), help_text=N_('Files must be accessible under the same name as they are stored with locally.'), ), ], ) ] + StorageForm.buttons def display(self, value, engine, **kwargs): """Display the form with default values from the given StorageEngine. If the value dict is not fully populated, populate any missing entries with the values from the given StorageEngine's :attr:`_data <mediacore.lib.storage.StorageEngine._data>` dict. :param value: A (sparse) dict of values to populate the form with. :type value: dict :param engine: An instance of the storage engine implementation. :type engine: :class:`mediacore.lib.storage.StorageEngine` subclass """ specifics = value.setdefault('specifics', {}) specifics.setdefault('path', engine._data.get('path', None)) specifics.setdefault('rtmp_server_uri', engine._data.get('rtmp_server_uri', None)) return StorageForm.display(self, value, engine, **kwargs) def save_engine_params(self, engine, **kwargs): """Map validated field values to engine data. Since form widgets may be nested or named differently than the keys in the :attr:`mediacore.lib.storage.StorageEngine._data` dict, it is necessary to manually map field values to the data dictionary. :type engine: :class:`mediacore.lib.storage.StorageEngine` subclass :param engine: An instance of the storage engine implementation. :param \*\*kwargs: Validated and filtered form values. :raises formencode.Invalid: If some post-validation error is detected in the user input. This will trigger the same error handling behaviour as with the @validate decorator. """ StorageForm.save_engine_params(self, engine, **kwargs) specifics = kwargs['specifics'] engine._data['path'] = specifics['path'] or None engine._data['rtmp_server_uri'] = specifics['rtmp_server_uri'] or None
class fields(WidgetsList): name = TextField(validator=TextField.validator(not_empty=True), label_text=N_('Name')) slug = TextField(validator=NotEmpty, label_text=N_('Permalink')) parent_id = SingleSelectField(label_text=N_('Parent Category'), options=category_options) cancel = ResetButton(default=N_('Cancel'), css_classes=['btn', 'f-lft', 'btn-cancel']) save = SubmitButton(default=N_('Save'), named_button=True, css_classes=['f-rgt', 'btn', 'blue', 'btn-save'])
class PlayerPrefsForm(ListForm): template = 'admin/box-form.html' id = 'player-form' css_class = 'form playerform' submit_text = None show_children_errors = True _name = 'player-form' # TODO: Figure out why this is required?? params = ['player'] fields = [ ListFieldSet( 'general', legend=N_('General Options:'), suppress_label=True, children=[ TextField( 'display_name', label_text=N_('Display Name'), validator=TextField.validator(not_empty=True), maxlength=100, ), ], ), ] buttons = [ SubmitButton( 'save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt'], ), ] def display(self, value, player, **kwargs): """Display the form with default values from the given player. If the value dict is not fully populated, populate any missing entries with the values from the given player's :attr:`_data <mediacore.model.player.PlayerPrefs._data>` dict. :param value: A (sparse) dict of values to populate the form with. :type value: dict :param player: The player prefs mapped object to retrieve the default values from. :type player: :class:`mediacore.model.player.PlayerPrefs` subclass """ return ListForm.display(self, value, **kwargs) def save_data(self, player, **kwargs): """Map validated field values to `PlayerPrefs.data`.
class GeneralForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None event = events.Admin.Settings.GeneralForm fields = [ ListFieldSet('general', suppress_label=True, legend=N_('General Settings:'), css_classes=['details_fieldset'], children=[ TextField('general_site_name', maxlength=255, label_text=N_('Site Name')), SingleSelectField('general_site_title_display_order', label_text=N_('Display Site Name'), options=title_options, ), SingleSelectField('primary_language', label_text=N_('Default Language'), # TODO v0.9.1: Change to 'Primary Language' options=languages, ), SingleSelectField('featured_category', label_text=N_('Featured Category'), options=category_options, validator=Int(), ), RadioButtonList('rich_text_editor', label_text=N_('Rich Text Editing'), options=rich_text_editors, validator=rich_text_editors_validator, ), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class AddFileForm(ListForm): template = 'admin/media/file-add-form.html' id = 'add-file-form' submit_text = None fields = [ FileField( 'file', label_text=N_( 'Select an encoded video or audio file on your computer'), validator=FieldStorageUploadConverter(not_empty=False, label_text=N_('Upload'))), SubmitButton('add_url', default=N_('Add URL'), named_button=True, css_class='btn grey btn-add-url f-rgt'), TextField( 'url', validator=URL, suppress_label=True, attrs=lambda: { 'title': _('YouTube, Vimeo, Google Video, Amazon S3 or any other link') }, maxlength=255), ] def post_init(self, *args, **kwargs): events.Admin.AddFileForm(self)
class LoginForm(ListForm): template = 'forms/box_form.html' method = 'POST' id = 'login-form' css_class = 'form clearfix' submit_text = None # For login failures we display only a generic (bad username or password) # error message which is not related to any particular field. # However I'd like to mark the input widgets as faulty without displaying # the dummy errors (injected by LoginController programmatically as this # form is not used for credential validation) so this will prevent the error # text from being displayed. However the actual input fields will be marked # with css classes anyway. show_children_errors = False fields = [ TextField('login', label_text=N_('Username'), # 'autofocus' is actually not XHTML-compliant attrs={'autofocus': True}), PasswordField('password', label_text=N_('Password')), SubmitButton('login_button', default=N_('Login'), css_classes=['mcore-btn', 'btn-submit', 'f-rgt']) ] def post_init(self, *args, **kwargs): events.LoginForm(self)
class PostCommentSchema(Schema): name = TextField.validator( not_empty=True, maxlength=50, messages={'empty': N_('Please enter your name!')}) email = email_validator() body = XHTMLValidator(not_empty=True)
class PopularityForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ ListFieldSet('popularity', suppress_label=True, css_classes=['details_fieldset'], legend=N_('Popularity Algorithm Variables:'), children=[ TextField('popularity_decay_exponent', validator=Int(not_empty=True, min=1), label_text=N_('Decay Exponent')), TextField('popularity_decay_lifetime', validator=Int(not_empty=True, min=1), label_text=N_('Decay Lifetime')), ] ), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class SearchForm(ListForm): template = 'admin/search-form.html' id = 'nav-search' method = 'get' fields = [ TextField('search', label_text=N_('SEARCH...')), SubmitButton('go', default='Go', css_classes=['clickable nav-search-btn']), ] submit_text = None event = events.Admin.SearchForm
class AnalyticsForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ ListFieldSet('google', suppress_label=True, legend=N_('Google Analytics Details:'), css_classes=['details_fieldset'], children=[ TextField('google_analytics_uacct', maxlength=255, label_text=N_('Tracking Code')), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class UploadForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ TextField('max_upload_size', label_text=N_('Max. allowed upload file size in megabytes'), validator=MegaByteValidator(not_empty=True, min=0)), ListFieldSet('legal_wording', suppress_label=True, legend=N_('Legal Wording:'), css_classes=['details_fieldset'], children=[ XHTMLTextArea('wording_user_uploads', label_text=N_('User Uploads'), attrs=dict(rows=15, cols=25)), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class GeneralForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ ListFieldSet( 'general', suppress_label=True, legend=N_('General Settings:'), css_classes=['details_fieldset'], children=[ TextField('general_site_name', maxlength=255, label_text=N_('Site Name')), SingleSelectField( 'general_site_title_display_order', label_text=N_('Display Site Name'), options=title_options, ), SingleSelectField( 'primary_language', label_text=N_( 'Default Language' ), # TODO v0.9.1: Change to 'Primary Language' options=languages, ), SingleSelectField( 'featured_category', label_text=N_('Featured Category'), options=category_options, validator=Int(), ), RadioButtonList( 'rich_text_editor', label_text=N_('Rich Text Editing'), options=rich_text_editors, validator=rich_text_editors_validator, ), # NOTE: Commented out, pending removal in v0.9.1 if no one complains its gone. # ListFieldSet('default_wording', suppress_label=True, legend=N_('Administrative notes on Media:'), css_classes=['details_fieldset'], children=[ # CheckBox('wording_display_administrative_notes', # label_text=N_('Display notes'), # validator=Bool(if_missing='')), # TextArea('wording_administrative_notes', label_text=N_('Administrative Notes'), attrs=dict(rows=3, cols=25)), # ]), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class CommentsForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ boolean_radiobuttonlist( 'req_comment_approval', label_text=N_('Require comments to be approved by an admin')), ListFieldSet('akismet', suppress_label=True, legend=N_('Akismet Anti-Spam Details:'), css_classes=['details_fieldset'], children=[ TextField('akismet_key', label_text=N_('Akismet Key')), TextField('akismet_url', label_text=N_('Akismet URL')), ]), ListFieldSet( 'vulgarity', suppress_label=True, label_text=N_('Vulgarity Filter Settings'), css_classes=['details_fieldset'], children=[ TextArea( 'vulgarity_filtered_words', label_text=N_('Filtered Words'), attrs=dict(rows=3, cols=15), help_text=N_( 'Enter words to be filtered separated by a comma.')), ]), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
class SublimePlayerPrefsForm(PlayerPrefsForm): fields = [ TextField('script_tag', label_text=N_('Script Tag'), help_text=N_('The unique script tag given for your site.'), ), ] + PlayerPrefsForm.buttons def display(self, value, player, **kwargs): value.setdefault('script_tag', player.data.get('script_tag', '')) return PlayerPrefsForm.display(self, value, player, **kwargs) def save_data(self, player, script_tag, **kwargs): player.data['script_tag'] = script_tag or None if not script_tag and player.enabled: player.enabled = False
class SiteMapsForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None event = events.Admin.Settings.SiteMapsForm fields = [ ListFieldSet('rss', suppress_label=True, legend='', css_classes=['details_fieldset'], children=[ CheckBox('sitemaps_display', css_classes=['checkbox-left'], label_text=N_('Site Maps'), validator=Bool(if_missing='')), CheckBox('rss_display', css_classes=['checkbox-left'], label_text=N_('RSS Feeds'), validator=Bool(if_missing='')), ] ), ListFieldSet('feeds', suppress_label=True, css_classes=['details_fieldset'], legend=N_('RSS Feed Defaults:'), children=[ TextField(u'default_feed_results', validator=Int(not_empty=True, min=1, if_missing=30), label_text=N_(u'number of items'), help_text=N_(u'The number of items in the feed can be overriden per request ' U'if you add "?limit=X" to the feed URL. If the "limit" parameter ' u'is absent, the default above is used.'), ), ] ), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), ]
from tw.forms.validators import NotEmpty, FieldStorageUploadConverter from pylons import config from pylons.i18n import _ from mediacore.lib import helpers from mediacore.lib.filetypes import accepted_extensions, guess_container_format from mediacore.lib.embedtypes import parse_embed_url from mediacore.forms import ListForm, TextField, XHTMLTextArea, FileField, SubmitButton, email_validator validators = dict( description = XHTMLTextArea.validator( messages = {'empty': _('At least give it a short description...')}, not_empty = True, ), name = TextField.validator( messages = {'empty': _("You've gotta have a name!")}, not_empty = True, ), title = TextField.validator( messages = {'empty': _("You've gotta have a title!")}, not_empty = True, ), ) class EmbedURLValidator(formencode.FancyValidator): def _to_python(self, value, state): if value == '': return value embed = parse_embed_url(value) if embed: return value
class PodcastForm(ListForm): template = 'admin/box-form.html' id = 'podcast-form' css_class = 'form' submit_text = None event = events.Admin.PodcastForm # required to support multiple named buttons to differentiate between Save & Delete? _name = 'vf' explicit_options = lambda: ( ('no', ''), ('yes', _('Parental Advisory')), ('clean', _('Clean')), ) category_options = [ 'Arts', 'Arts > Design', 'Arts > Fashion & Beauty', 'Arts > Food', 'Arts > Literature', 'Arts > Performing Arts', 'Arts > Visual Arts', 'Business', 'Business > Business News', 'Business > Careers', 'Business > Investing', 'Business > Management & Marketing', 'Business > Shopping', 'Comedy', 'Education', 'Education > Education Technology', 'Education > Higher Education', 'Education > K-12', 'Education > Language Courses', 'Education > Training', 'Games & Hobbies', 'Games & Hobbies > Automotive', 'Games & Hobbies > Aviation', 'Games & Hobbies > Hobbies', 'Games & Hobbies > Other Games', 'Games & Hobbies > Video Games', 'Government & Organizations', 'Government & Organizations > Local', 'Government & Organizations > National', 'Government & Organizations > Non-Profit', 'Government & Organizations > Regional', 'Health', 'Health > Alternative Health', 'Health > Fitness & Nutrition', 'Health > Self-Help', 'Health > Sexuality', 'Kids & Family', 'Music', 'News & Politics', 'Religion & Spirituality', 'Religion & Spirituality > Buddhism', 'Religion & Spirituality > Christianity', 'Religion & Spirituality > Hinduism', 'Religion & Spirituality > Islam', 'Religion & Spirituality > Judaism', 'Religion & Spirituality > Other', 'Religion & Spirituality > Spirituality', 'Science & Medicine', 'Science & Medicine > Medicine', 'Science & Medicine > Natural Sciences', 'Science & Medicine > Social Sciences', 'Society & Culture', 'Society & Culture > History', 'Society & Culture > Personal Journals', 'Society & Culture > Philosophy', 'Society & Culture > Places & Travel', 'Sports & Recreation', 'Sports & Recreation > Amateur', 'Sports & Recreation > College & High School', 'Sports & Recreation > Outdoor', 'Sports & Recreation > Professional', 'Technology', 'Technology > Gadgets', 'Technology > Tech News', 'Technology > Podcasting', 'Technology > Software How-To', 'TV & Film', ] fields = [ TextField('slug', label_text=N_('Permalink'), validator=NotEmpty, maxlength=50), TextField('title', label_text=N_('Title'), validator=TextField.validator(not_empty=True), maxlength=50), TextField('subtitle', label_text=N_('Subtitle'), maxlength=255), TextField('author_name', label_text=N_('Author Name'), validator=TextField.validator(not_empty=True), maxlength=50), TextField('author_email', label_text=N_('Author Email'), validator=email_validator(not_empty=True), maxlength=50), XHTMLTextArea('description', label_text=N_('Description'), attrs=dict(rows=5, cols=25)), ListFieldSet('details', suppress_label=True, legend=N_('Podcast Details:'), css_classes=['details_fieldset'], children=[ SingleSelectField('explicit', label_text=N_('Explicit?'), options=explicit_options), SingleSelectField('category', label_text=N_('Category'), options=category_options), TextField('copyright', label_text=N_('Copyright'), maxlength=50), ]), ListFieldSet('feed', suppress_label=True, legend=N_('Advanced Options:'), css_classes=['details_fieldset'], template='/admin/podcasts/feed_fieldset.html', children=[ TextField('feed_url', maxlength=50, label_text=N_('Your Feed URL'), attrs={'readonly': True}), TextField('itunes_url', validator=URL, label_text=N_('iTunes URL'), maxlength=80), TextField('feedburner_url', validator=URL, label_text=N_('Feedburner URL'), maxlength=80), ]), SubmitButton('save', default=N_('Save'), named_button=True, css_classes=['btn', 'blue', 'f-rgt']), SubmitButton('delete', default=N_('Delete'), named_button=True, css_classes=['btn']), ]
# See LICENSE.txt in the main project directory, for more information. from tw.api import WidgetsList from tw.forms.validators import FieldStorageUploadConverter from mediacore.lib.i18n import N_ from mediacore.forms import ListForm, TextField, XHTMLTextArea, FileField, SubmitButton, email_validator from mediacore.plugin import events validators = dict( description = XHTMLTextArea.validator( messages = {'empty': N_('At least give it a short description...')}, not_empty = True, ), name = TextField.validator( messages = {'empty': N_("You've gotta have a name!")}, not_empty = True, ), title = TextField.validator( messages = {'empty': N_("You've gotta have a title!")}, not_empty = True, ), url = TextField.validator( if_missing = None, ), ) class UploadForm(ListForm): template = 'upload/form.html' id = 'upload-form' css_class = 'form' show_children_errors = False
class FTPStorageForm(StorageForm): fields = StorageForm.fields + [ ListFieldSet( 'ftp', suppress_label=True, legend=N_('FTP Server Details:'), children=[ TextField('server', label_text=N_('Server Hostname')), TextField('user', label_text=N_('Username')), TextField('password', label_text=N_('Password')), TextField( 'upload_dir', label_text=N_('Subdirectory on server to upload to')), TextField( 'upload_integrity_retries', label_text=N_( 'How many times should MediaCore try to verify the FTP upload before declaring it a failure?' ), validator=Int()), TextField( 'http_download_uri', label_text=N_('HTTP URL to access remotely stored files')), TextField( 'rtmp_server_uri', label_text=N_( 'RTMP Server URL to stream remotely stored files (Optional)' )), ]), ] + StorageForm.buttons def display(self, value, engine, **kwargs): """Display the form with default values from the given StorageEngine. If the value dict is not fully populated, populate any missing entries with the values from the given StorageEngine's :attr:`_data <mediacore.lib.storage.StorageEngine._data>` dict. :param value: A (sparse) dict of values to populate the form with. :type value: dict :param engine: An instance of the storage engine implementation. :type engine: :class:`mediacore.lib.storage.StorageEngine` subclass """ data = engine._data ftp = value.setdefault('ftp', {}) ftp.setdefault('server', data.get(FTP_SERVER, None)) ftp.setdefault('user', data.get(FTP_USERNAME, None)) ftp.setdefault('password', data.get(FTP_PASSWORD, None)) ftp.setdefault('upload_dir', data.get(FTP_UPLOAD_DIR, None)) ftp.setdefault('upload_integrity_retries', data.get(FTP_MAX_INTEGRITY_RETRIES, None)) ftp.setdefault('http_download_uri', data.get(HTTP_DOWNLOAD_URI, None)) ftp.setdefault('rtmp_server_uri', data.get(RTMP_SERVER_URI, None)) return StorageForm.display(self, value, engine, **kwargs) def save_engine_params(self, engine, **kwargs): """Map validated field values to engine data. Since form widgets may be nested or named differently than the keys in the :attr:`mediacore.lib.storage.StorageEngine._data` dict, it is necessary to manually map field values to the data dictionary. :type engine: :class:`mediacore.lib.storage.StorageEngine` subclass :param engine: An instance of the storage engine implementation. :param \*\*kwargs: Validated and filtered form values. :raises formencode.Invalid: If some post-validation error is detected in the user input. This will trigger the same error handling behaviour as with the @validate decorator. """ StorageForm.save_engine_params(self, engine, **kwargs) ftp = kwargs['ftp'] engine._data[FTP_SERVER] = ftp['server'] engine._data[FTP_USERNAME] = ftp['user'] engine._data[FTP_PASSWORD] = ftp['password'] engine._data[FTP_UPLOAD_DIR] = ftp['upload_dir'] engine._data[FTP_MAX_INTEGRITY_RETRIES] = ftp[ 'upload_integrity_retries'] engine._data[HTTP_DOWNLOAD_URI] = ftp['http_download_uri'] engine._data[RTMP_SERVER_URI] = ftp['rtmp_server_uri']
class SEOSettingsForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ ListFieldSet( 'general', suppress_label=True, legend=N_('General', domain='mediacore_seo'), css_classes=['details_fieldset'], children=[ TextField( 'seo_general_meta_description', label_text=N_('Site Meta Description', domain='mediacore_seo'), ), TextField( 'seo_general_meta_keywords', label_text=N_('Site Meta Keywords', domain='mediacore_seo'), help_text=N_('Comma Separated)', domain='mediacore_seo'), ), ], ), ListFieldSet( 'explore', suppress_label=True, legend=N_('Explore Page', domain='mediacore_seo'), css_classes=['details_fieldset'], children=[ TextField( 'seo_explore_page_title', label_text=N_('Page Title', domain='mediacore_seo'), ), TextField( 'seo_explore_meta_description', label_text=N_('Meta Description', domain='mediacore_seo'), ), TextField( 'seo_explore_meta_keywords', label_text=N_('Meta Keywords', domain='mediacore_seo'), help_text=N_('(Comma Separated)', domain='mediacore_seo'), ) ], ), ListFieldSet( 'podcast', suppress_label=True, legend=N_('Podcast Page', domain='mediacore_seo'), css_classes=['details_fieldset'], children=[ TextField( 'seo_podcast_page_title', label_text=N_('Page Title', domain='mediacore_seo'), ), TextField( 'seo_podcast_meta_description', label_text=N_('Meta Description', domain='mediacore_seo'), ), TextField( 'seo_podcast_meta_keywords', label_text=N_('Meta Keywords', domain='mediacore_seo'), help_text=N_('(Comma Separated)', domain='mediacore_seo'), ) ], ), ListFieldSet( 'category', suppress_label=True, legend=N_('Category Page', domain='mediacore_seo'), css_classes=['details_fieldset'], children=[ TextField( 'seo_category_page_title', label_text=N_('Page Title', domain='mediacore_seo'), ), TextField( 'seo_category_meta_description', label_text=N_('Meta Description', domain='mediacore_seo'), ), TextField( 'seo_category_meta_keywords', label_text=N_('Meta Keywords', domain='mediacore_seo'), help_text=N_('(Comma Separated)', domain='mediacore_seo'), ) ], ), ListFieldSet( 'upload', suppress_label=True, legend=N_('Upload Page', domain='mediacore_seo'), css_classes=['details_fieldset'], children=[ TextField( 'seo_upload_page_title', label_text=N_('Page Title', domain='mediacore_seo'), ), TextField( 'seo_upload_meta_description', label_text=N_('Meta Description', domain='mediacore_seo'), ), TextField( 'seo_upload_meta_keywords', label_text=N_('Meta Keywords', domain='mediacore_seo'), help_text=N_('(Comma Separated)', domain='mediacore_seo'), ) ], ), ListFieldSet( 'options', suppress_label=True, legend=N_('Options', domain='mediacore_seo'), css_classes=['details_fieldset'], children=[ CheckBox( 'seo_options_noindex_categories', label_text=N_('Enable NOINDEX for Categories', domain='mediacore_seo'), validator=Bool(if_missing=''), ), CheckBox( 'seo_options_noindex_rss', label_text=N_('Enable NOINDEX for RSS', domain='mediacore_seo'), validator=Bool(if_missing=''), ), # XXX: Argh toscawidgets will mark the fieldset as invalid (missing) # when neither of the above checkboxes are checked, unless # we ensure some 'options' value is always passed. HiddenField('dummy_field', default='1'), ], ), SubmitButton('save', default=N_('Save', domain='mediacore_seo'), named_button=True, suppress_label=True, css_classes=['btn', 'btn-save']), ]
class AppearanceForm(ListForm): template = 'admin/box-form.html' id = 'settings-form' css_class = 'form' submit_text = None fields = [ ListFieldSet('general', suppress_label=True, legend=N_('General'), css_classes=['details_fieldset'], children=[ FileField('appearance_logo', label_text=N_('Logo'), validator=FieldStorageUploadConverter(not_empty=False, label_text=N_('Upload Logo')), css_classes=[], default=lambda: app_globals.settings.get('appearance_logo', \ 'logo.png'), template='./admin/settings/appearance_input_field.html'), FileField('appearance_background_image', label_text=N_('Background Image'), validator=FieldStorageUploadConverter(not_empty=False, label_text=N_('Upload Background')), css_classes=[], default=lambda: app_globals.settings.get('appearance_background_image', \ 'bg_image.png'), template='./admin/settings/appearance_input_field.html'), TextField('appearance_background_color', maxlength=255, label_text=N_('Background color'), validator=Regex(hex_validation_regex, strip=True)), TextField('appearance_link_color', maxlength=255, label_text=N_('Link color'), validator=Regex(hex_validation_regex, strip=True)), TextField('appearance_visited_link_color', maxlength=255, label_text=N_('Visited Link color'), validator=Regex(hex_validation_regex, strip=True)), TextField('appearance_text_color', maxlength=255, validator=Regex(hex_validation_regex, strip=True), label_text=N_('Text color')), TextField('appearance_heading_color', maxlength=255, label_text=N_('Heading color'), validator=Regex(hex_validation_regex, strip=True)), SingleSelectField('appearance_navigation_bar_color', label_text=N_('Color Scheme'), options=navbar_colors), ] ), ListFieldSet('options', suppress_label=True, legend=N_('Options'), css_classes=['details_fieldset'], children=[ CheckBox('appearance_enable_cooliris', css_classes=['checkbox-left'], label_text=N_('Enable Cooliris on the Explore Page'), validator=Bool(if_missing='')), CheckBox('appearance_enable_featured_items', label_text=N_('Enable Featured Items on the Explore Page'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_enable_podcast_tab', label_text=N_('Enable Podcast Tab'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_enable_user_uploads', label_text=N_('Enable User Uploads'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_enable_widescreen_view', label_text=N_('Enable widescreen media player by default'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_display_logo', label_text=N_('Display Logo'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_display_background_image', label_text=N_('Display Background Image'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_display_mediacore_footer', label_text=N_('Display MediaCore Footer'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), CheckBox('appearance_display_mediacore_credits', label_text=N_('Display MediaCore Credits in Footer'), css_classes=['checkbox-left'], validator=Bool(if_missing='')), ], template='./admin/settings/appearance_list_fieldset.html', ), ListFieldSet('advanced', suppress_label=True, legend=N_('Advanced'), css_classes=['details_fieldset'], children=[ TextArea('appearance_custom_css', label_text=N_('Custom CSS'), attrs=dict(rows=15, cols=25)), TextArea('appearance_custom_header_html', label_text=N_('Custom Header HTML'), attrs=dict(rows=15, cols=25)), TextArea('appearance_custom_footer_html', label_text=N_('Custom Footer HTML'), attrs=dict(rows=15, cols=25)), ], ), SubmitButton('save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt']), SubmitButton('reset', default=N_('Reset to Defaults'), css_classes=['btn', 'btn-cancel', 'reset-confirm']), ]
from tw.api import WidgetsList, CSSLink import formencode from tw.forms.validators import NotEmpty, FieldStorageUploadConverter from pylons import config from mediacore.lib import helpers from mediacore.lib.filetypes import external_embedded_containers from mediacore.forms import ListForm, TextField, XHTMLTextArea, FileField, SubmitButton, email_validator validators = dict( description = XHTMLTextArea.validator( messages = {'empty': 'At least give it a short description...'}, not_empty = True, ), name = TextField.validator( messages = {'empty': "You've gotta have a name!"}, not_empty = True, ), tags = TextField.validator( not_empty = False, ), title = TextField.validator( messages = {'empty': "You've gotta have a title!"}, not_empty = True, ), ) class EmbedURLValidator(formencode.FancyValidator): def _to_python(self, value, state): if value: for info in external_embedded_containers.itervalues(): match = info['pattern'].match(value)
class StorageForm(ListForm): template = 'admin/box-form.html' id = 'storage-form' css_class = 'form storageform' submit_text = None show_children_errors = True _name = 'storage-form' # TODO: Figure out why this is required?? params = ['engine'] fields = [ ListFieldSet( 'general', legend=N_('General Options:'), suppress_label=True, children=[ TextField( 'display_name', label_text=N_('Display Name'), validator=TextField.validator(not_empty=True), maxlength=100, ), ], ), ] buttons = [ SubmitButton( 'save', default=N_('Save'), css_classes=['btn', 'btn-save', 'blue', 'f-rgt'], ), ] def display(self, value, engine, **kwargs): """Display the form with default values from the given StorageEngine. If the value dict is not fully populated, populate any missing entries with the values from the given StorageEngine's :attr:`_data <mediacore.lib.storage.StorageEngine._data>` dict. :param value: A (sparse) dict of values to populate the form with. :type value: dict :param engine: An instance of the storage engine implementation. :type engine: :class:`mediacore.lib.storage.StorageEngine` subclass """ general = value.setdefault('general', {}) if not general.get('display_name', None): general['display_name'] = engine.display_name return ListForm.display(self, value, engine=engine, **kwargs) def save_engine_params(self, engine, general, **kwargs): """Map validated field values to engine data. Since form widgets may be nested or named differently than the keys in the :attr:`mediacore.lib.storage.StorageEngine._data` dict, it is necessary to manually map field values to the data dictionary. :type engine: :class:`mediacore.lib.storage.StorageEngine` subclass :param engine: An instance of the storage engine implementation. :param \*\*kwargs: Validated and filtered form values. :raises formencode.Invalid: If some post-validation error is detected in the user input. This will trigger the same error handling behaviour as with the @validate decorator. """ engine.display_name = general['display_name']