def verify_diff(diff, screen): """ Verifies that all the channels in the diff have been correctly added to/removed from the bundle""" for (channel_id, subscribed) in diff.items(): if subscribed: assert Channel.get(channel_id) in screen.subscribed_channels else: assert Channel.get(channel_id) not in screen.subscribed_channels
def post(self, channel_id): channel = Channel.get(int(channel_id)) form = self.form try: if form.action == 'add-channel-to-bundles': bundles_diff = json.loads(form.pop('diff', '{}')) for bundle_id, part_of in bundles_diff.items(): bundle = ChannelBundle.get(int(bundle_id)) if part_of: try: bundle.add_channel(channel) except ValueError: raise ImmediateFeedback(form.action, 'bundle_cycle', bundle.name) else: bundle.remove_channel(channel) add_feedback(form.action, 'ok') except ImmediateFeedback: pass form.was_bundle = type( channel ) == ChannelBundle # Hack to display the bundles tab instead form.data_edit = json.dumps([b.id for b in channel.bundles]) form.channel_id = channel_id form.name = channel.name store_form(form) resp.seeother('/channels')
def get(self, id, user_id): channel_id = int(id) chan = Channel.get(channel_id) user_id = int(user_id) user = User.get(user_id) st = "You just receive a request of subscription for channel " + chan.name + ". Could you please subscribe " + str( user.fullname) + " (" + user.email + ") to this channel." for admin in chan.get_admins(): web.sendmail(web.config.smtp_sendername, admin.email, 'Request for subscription to a channel', st, headers={'Content-Type': 'text/html;charset=utf-8'}) resp.seeother('/channels')
def get(self, channel_id): channel = Channel.get(channel_id) current_user = User.get(self.session['user']['id']) screens_of_current_user = Screen.get_visible_screens_of(current_user) subscriptions = current_user.get_subscriptions_of_owned_screens() last_by = { sub.screen.id: { 'user': sub.created_by.readable_name, 'channel_name': sub.channel.name, 'plugin_channel': hasattr(sub.channel, 'plugin') } for sub in subscriptions if sub.channel.id == channel.id } screen_names = {s.id: s.name for s in screens_of_current_user} return self.renderer.channel_subscriptions( channel=channel, possible_screens=screens_of_current_user, user=current_user, subscriptions=subscriptions, last_by=last_by, screen_names=screen_names)
def GET(self, channel_id, secret): """ Render the capsules of this channel. """ try: channel = Channel.get(channel_id) if channel.secret != secret: raise web.forbidden() except SQLObjectNotFound: raise web.notfound() channel_capsules = [] already_added_channels = set() for plugin_channel in channel.flatten(keep_disabled_channels=True): if plugin_channel.id not in already_added_channels: if plugin_channel.plugin.activated == 'yes': for capsule in self.plugin_manager.get_plugin_content( plugin_channel): if len(capsule.get_slides()) > 0: channel_capsules.append(capsule) already_added_channels.add(plugin_channel.id) return self.ictv_renderer.preview_capsules(channel_capsules, context='channel', auto_slide=True)
def post(self, screen_id): def wrong_channel(channel, subscribe, user): """ returns True if the the user wants to subscribe to the channel while its plugin is not activated or if the user tries to subscribe to the channel without being in its authorized subscribers""" return subscribe and (type(channel) is PluginChannel and channel.plugin.activated != "yes" or (subscribe and not channel.can_subscribe(user))) form = self.form try: screen = Screen.get(screen_id) u = User.get(self.session['user']['id']) # Forbid if not admin or does not own this screen if not (UserPermissions.administrator in u.highest_permission_level or screen in u.screens): logger.warning('user %s tried change subscriptions of screen %d without having the rights to do this', u.log_name, screen.id) resp.forbidden() diff = json.loads(form.diff) if diff == {}: logger.info('user %s submitted empty diff for subscriptions of screen %s', u.log_name, screen.name) raise ImmediateFeedback("subscription", 'nothing_changed') # Do the subscription/unsubscription for every channel in the diff subscribed = [] unsubscribed = [] try: changes = [(Channel.get(channel_id), subscribe) for channel_id, subscribe in diff.items()] except SQLObjectNotFound: logger.warning('user %s tried to subscribe/unsubscribe screen %d to a channel which does not exist', u.log_name, screen.id) resp.forbidden() # if somebody tries to subscribe to a channel with a disabled plugin wrong_channels = [(channel, subscribe) for channel, subscribe in changes if wrong_channel(channel, subscribe, u)] if wrong_channels: channel, subscribe = wrong_channels[0] if channel.plugin.activated != "yes": logger.warning('user %s tried to %s screen %d to channel %d with disabled plugin', u.log_name, 'subscribe' if subscribe else "unsubscribe", screen.id, channel.id) raise ImmediateFeedback("subscription", "disabled_plugin") else: logger.warning('user %s tried to subscribe screen %d to channel %d without having the right to do this', u.log_name, screen.id, channel.id) resp.forbidden() for channel, subscribe in changes: if subscribe: screen.subscribe_to(u, channel) subscribed.append(str(channel.id)) else: screen.unsubscribe_from(u, channel) unsubscribed.append(str(channel.id)) if subscribed and unsubscribed: message = "user %s has subscribed screen %d to channel(s) %s and unsubscribed from channel(s) %s" % \ (u.log_name, screen.id, ', '.join(subscribed), ', '.join(unsubscribed)) else: message = "user %s has %s screen %d to channel(s) %s" % \ (u.log_name, "subscribed" if subscribed else "unsubscribed", screen.id, ', '.join(subscribed if subscribed else unsubscribed)) logger.info(message) add_feedback("subscription", 'ok') except SQLObjectNotFound: resp.notfound() except ImmediateFeedback: pass store_form(form) resp.seeother("/screens/%s/subscriptions" % screen.id)
def get(self, channel_id): channel = Channel.get(int(channel_id)) current_user = User.get(self.session['user']['id']) if channel in Channel.get_visible_channels_of(current_user): return self.render_page(channel) raise self.forbidden()
def post(self, channel_id): form = self.form u = User.get(self.session['user']['id']) subscribed = [] unsubscribed = [] if form.diff == 'diff': raise ImmediateFeedback(form.action, 'nothing_changed') try: diff = json.loads(form.diff) except (json.JSONDecodeError, ValueError): raise ImmediateFeedback(form.action, 'inconsistent_diff') try: channelid = int(channel_id) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') for k, v in diff.items(): try: sub = bool(v) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') try: screenid = int(k) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') try: channel = Channel.get(channelid) if not channel.can_subscribe(u): raise self.forbidden(message="You're not allow to do that") screen = Screen.get(screenid) if not u in screen.owners: raise self.forbidden(message="You're not allow to do that") #sub true -> New subscription #sub false -> Remove subscription if sub: screen.subscribe_to(u, channel) subscribed.append(str(channel.id)) else: screen.unsubscribe_from(u, channel) unsubscribed.append(str(channel.id)) if subscribed and unsubscribed: message = "user %s has subscribed screen %d to channel(s) %s and unsubscribed from channel(s) %s" % \ (u.log_name, screen.id, ', '.join(subscribed), ', '.join(unsubscribed)) else: message = "user %s has %s screen %d to channel(s) %s" % \ (u.log_name, "subscribed" if subscribed else "unsubscribed", screen.id, ', '.join(subscribed if subscribed else unsubscribed)) logger.info(message) add_feedback("subscription", 'ok') except SQLObjectNotFound: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') except DuplicateEntryError: # if the user has checked + unchecked the same checkbox, it will appear on the diff, # we just need to do nothing. pass except SQLObjectIntegrityError: # when there id more than one subscription matching the pair channel/screen pass resp.seeother("/channels/config/%s/subscriptions" % channel_id)
def post(self, bundle_id): def wrong_channel(channel, bundle, add): """ returns True if the channel to add is the bundle itself or if the channel is a PluginChannel with disabled plugin """ return bundle.id == channel.id or add and type(channel) is PluginChannel and channel.plugin.activated != "yes" form = self.form try: bundle = ChannelBundle.get(bundle_id) u = User.get(self.session['user']['id']) diff = json.loads(form.diff) if diff == {}: logger.info('user %s submitted empty diff for bundle management %s', u.log_name, bundle.name) raise ImmediateFeedback("manage_channels", 'nothing_changed') # Do the subscription/unsubscription for every channel in the diff contained = [] not_contained = [] try: changes = [(Channel.get(channel_id), add) for channel_id, add in diff.items()] except SQLObjectNotFound: logger.warning('user %s tried to add a channel which does not exist to bundle %d', u.log_name, bundle.id) resp.forbidden() # if somebody tries to add a channel with a disabled plugin or to add a bundle to itself wrong_channels = [(channel, add) for channel, add in changes if wrong_channel(channel, bundle, add)] if wrong_channels: channel, add = wrong_channels[0] if channel.id == bundle.id: logger.warning('user %s tried to %s bundle %d to itself', u.log_name, 'add' if add else "remove", bundle.id) raise ImmediateFeedback("manage_channels", "added_to_itself") else: logger.warning('user %s tried to %s channel %d with disabled plugin to bundle %d', u.log_name, 'add' if add else "remove", channel.id, bundle.id) raise ImmediateFeedback("manage_channels", "disabled_plugin") for channel, add in changes: if add: try: bundle.add_channel(channel) except ValueError: logger.warning("user %s has made changes in channels management of bundle %d that created a " "cycle of bundles by adding channel %d (%s)", u.log_name, bundle.id, channel.id, channel.name) form.channel_name = channel.name raise ImmediateFeedback("manage_channels", "bundle_cycle") contained.append(str(channel.id)) else: bundle.remove_channel(channel) not_contained.append(str(channel.id)) if contained and not_contained: message = "user %s has added to channel(s) %s and removed channel(s) %s to bundle %d" % \ (u.log_name, ', '.join(contained), ', '.join(not_contained), bundle.id) else: message = "user %s has %s channel(s) %s to bundle %d" % \ (u.log_name, "added" if contained else "removed", ', '.join(contained if contained else not_contained), bundle.id) logger.info(message) add_feedback("manage_channels", 'ok') except SQLObjectNotFound: resp.notfound() except ImmediateFeedback: pass store_form(form) resp.seeother("/channels/config/%s/manage_bundle" % bundle.id)
def post(self): """ Handles screen creation, editing, deletion, channel subscriptions. """ form = self.form u = User.get(self.session['user']['id']) try: if form.action == 'delete': if not u.super_admin: resp.forbidden() try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'invalid_id') try: Screen.delete(screenid) raise ImmediateFeedback(form.action, 'ok') except SQLObjectNotFound as e: raise ImmediateFeedback(form.action, 'no_id_matching') elif form.action == 'subscribe': if form.diff == 'diff': raise ImmediateFeedback(form.action, 'nothing_changed') try: diff = json.loads(form.diff) except (json.JSONDecodeError, ValueError): raise ImmediateFeedback(form.action, 'inconsistent_diff') try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') for k, v in diff.items(): try: sub = bool(v) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') try: channelid = int(k) except ValueError: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') try: channel = Channel.get(channelid) screen = Screen.get(screenid) if UserPermissions.administrator not in u.highest_permission_level and not ( channel.can_subscribe(u) and u in screen.owners): resp.forbidden() if sub: if hasattr(channel, "plugin" ) and channel.plugin.activated != 'yes': resp.forbidden() screen.subscribe_to(user=u, channel=channel) else: screen.unsubscribe_from(user=u, channel=channel) except SQLObjectNotFound: raise ImmediateFeedback(form.action, 'invalid_channel/screen_id') except DuplicateEntryError: # if the user has checked + unchecked the same checkbox, it will appear on the diff, # we just need to do nothing. pass except SQLObjectIntegrityError: # when there id more than one subscription matching the pair channel/screen # TODO: log something pass elif form.action == 'chown': if form.diff == 'diff': raise ImmediateFeedback(form.action, 'nothing_changed') try: diff = json.loads(form.diff) except (json.JSONDecodeError, ValueError): raise ImmediateFeedback(form.action, 'inconsistent_diff') try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'screenid') for k, v in diff.items(): try: own = bool(v) except ValueError: raise ImmediateFeedback(form.action, 'invalid_screen/user_id') try: userid = int(k) except ValueError: raise ImmediateFeedback(form.action, 'invalid_screen/user_id') try: screen = Screen.get(screenid) if UserPermissions.administrator not in u.highest_permission_level and u not in screen.owners: resp.forbidden() user = User.get(userid) if own: screen.safe_add_user(user) else: screen.removeUser(user) except SQLObjectNotFound: raise ImmediateFeedback(form.action, 'invalid_screen/user_id') except DuplicateEntryError: # if the user has checked + unchecked the same checkbox, it will appear on the diff, # we just need to do nothing. pass except SQLObjectIntegrityError: # when there is more than one subscription mathing the pair channel/screen # TODO: log something pass elif form.action == 'configure': screen = Screen.get(int(form.id)) screen.shuffle = form.get('shuffle') == 'on' screen.show_postit = form.get('postit') == 'on' screen.show_slide_number = form.get( 'show_slide_number') == 'on' else: building = Building.get(form.building.strip()) name = form.name.strip() form.building_name = None if not building: raise ImmediateFeedback(form.action, 'empty_building') form.building_name = building.name if not name: raise ImmediateFeedback(form.action, 'empty_name') if len(name) > Screen.sqlmeta.columns['name'].length: raise ImmediateFeedback(form.action, 'too_long_name') try: macs = { self.check_mac_address(mac) for mac in form.mac.strip().lower().split(';') if mac } except ValueError: raise ImmediateFeedback(form.action, 'invalid_mac_address') if form.action == 'create': if UserPermissions.administrator not in u.highest_permission_level: resp.forbidden() try: screen = Screen(name=form.name.strip(), building=form.building, location=form.location.strip(), comment=form.comment.strip(), orientation=form.orientation) except DuplicateEntryError: raise ImmediateFeedback(form.action, 'name_already_exists') elif form.action == 'edit': if UserPermissions.administrator not in u.highest_permission_level: resp.forbidden() try: screenid = int(form.screenid) except ValueError: raise ImmediateFeedback(form.action, 'invalid_id') screen = Screen.get(screenid) if screen is None: raise ImmediateFeedback(form.action, 'no_id_matching') try: screen.name = form.name.strip() screen.building = form.building screen.orientation = form.orientation except DuplicateEntryError: raise ImmediateFeedback(form.action, 'name_already_exists') screen.location = form.location.strip() screen.comment = form.comment.strip() else: raise NotImplementedError try: screen_macs = [ screen_mac.mac for screen_mac in screen.macs ] for mac in screen_macs: if mac not in macs: ScreenMac.selectBy(mac=mac).getOne().destroySelf() for mac in macs: if mac not in screen_macs: ScreenMac(screen=screen, mac=mac) except DuplicateEntryError: raise ImmediateFeedback(form.action, 'mac_already_exists') add_feedback(form.action, 'ok') except ImmediateFeedback: pass store_form(form) return self.render_page()
def get_content(channel_id, config=None): channel = Channel.get(channel_id) logger = get_logger('rss', channel) if not config: def get_param(x): return channel.get_config_param(x) else: def get_param(x): return config[x] url = get_param('url') parser_rules = get_param( 'parser_rules' ) # A list of rules in the form slide_element;entry_item;regexp additional_rules = get_param( 'additional_rules') # A list of rules in the form entry_item;string filter = get_param('filter') exception_rules = get_param( 'exception_rules') # A list of rules in the form entry_item;string no_slides = get_param('no_slides') time_limit = get_param('time_limit') duration = get_param('duration') * 1000 template = get_param('template') theme = get_param('theme') min_age = datetime.now() - timedelta(days=time_limit) entries = feedparser_parse( url)['entries'][:no_slides] if not config or not config.get( 'feed') else config.get('feed') capsules = [] last_entries = [] with open(cache_path, 'r+') as f: fcntl.flock(f, fcntl.LOCK_EX) cache = json.load(f, cls=DateTimeDecoder) for entry in entries: if 'published_parsed' in entry: entry_age = datetime.fromtimestamp( mktime(entry['published_parsed'])) if entry_age >= min_age: last_entries.append(entry) else: entry_hash = hash_dict(entry) if entry_hash in cache: if cache[entry_hash] >= min_age: last_entries.append(entry) else: cache[entry_hash] = datetime.now() f.seek(0) json.dump(cache, f, cls=DateTimeEncoder) f.truncate() fcntl.flock(f, fcntl.LOCK_UN) for entry in last_entries: slide_content = {} link_page = None for slide_element, entry_item, regexp in [ rule.split(';') for rule in parser_rules ]: field, input_type = slide_element.split(':') if field not in slide_content: slide_content[field] = {} if entry_item == 'link_page': if not link_page: with urllib.request.urlopen(entry.link) as response: link_page = response.read().decode(errors='ignore') entry_item += "@" + response.geturl( ) # in case of redirect(s), geturl() returns the final url of the page item = link_page else: item = deep_get(entry, *entry_item.split('.')) value = get_value(item, regexp) if input_type == 'src' and not _is_url(value): ref_url = entry.link if entry_item.startswith('link_page@'): ref_url = entry_item.split('@')[1] value = urljoin(ref_url, value) slide_content[field].update({input_type: value}) for slide_element, string in [ rule.split(';') for rule in additional_rules ]: field, input_type = slide_element.split(':') if field not in slide_content: slide_content[field] = {} if string.lower() == 'qrcode': input_type = 'qrcode' string = entry.link slide_content[field].update({input_type: string}) if len(exception_rules) == 1 and not exception_rules[0].strip(): capsules.append( RssCapsule(theme=theme, slides=[ RssSlide(content=slide_content, template=template, duration=duration) ])) else: for entry_item, regexp in [ rule.split(';') for rule in exception_rules ]: if entry_item == 'link_page': if not link_page: with urllib.request.urlopen(entry.link) as response: link_page = response.read().decode(errors='ignore') entry_item += "@" + response.geturl( ) # in case of redirect(s), geturl() returns the final url of the page item = link_page else: item = deep_get(entry, *entry_item.split('.')) value = get_value(item, regexp) if filter and value is None: capsules.append( RssCapsule(theme=theme, slides=[ RssSlide(content=slide_content, template=template, duration=duration) ])) if not filter and value is not None: capsules.append( RssCapsule(theme=theme, slides=[ RssSlide(content=slide_content, template=template, duration=duration) ])) return capsules
def POST(self): """ Handles channel creation, editing, deletion, configuration and user permissions. """ form = web.input() current_user = User.get(self.session['user']['id']) channel = None try: if form.action.startswith('create') or form.action.startswith( 'edit'): # Prepare creation or edition of channels/bundles name = form.name.strip() description = form.description if form.description and form.description.strip( ) else None enabled = form.get('enabled') == 'on' if form.subscription_right not in [ 'public', 'restricted', 'private' ]: raise ImmediateFeedback(form.action, 'invalid_subscription_right') if len(name) < 3: raise ImmediateFeedback(form.action, 'invalid_name') if form.action.startswith('create'): if UserPermissions.administrator not in current_user.highest_permission_level: logger.warning( 'user %s tried to create a channel without being admin', current_user.log_name) raise web.forbidden() try: if form.action == 'create-channel': try: plugin_id = int(form.plugin) except ValueError: raise ImmediateFeedback(form.action, 'invalid_plugin') p = Plugin.get(plugin_id) channel = PluginChannel( name=name, plugin=p, subscription_right=form.subscription_right, description=description, enabled=enabled) if p.webapp: self.plugin_manager.add_mapping(self.app, channel) elif form.action == 'create-bundle': channel = ChannelBundle( name=name, description=description, subscription_right=form.subscription_right, enabled=enabled) else: raise web.badrequest() except SQLObjectNotFound: raise ImmediateFeedback(form.action, 'invalid_plugin') except DuplicateEntryError: raise ImmediateFeedback(form.action, 'name_already_exists') logger.info('channel ' + channel.name + ' created by ' + current_user.log_name) elif form.action.startswith('edit'): if UserPermissions.administrator not in current_user.highest_permission_level: raise web.forbidden() try: form.id = int(form.id) channel = (PluginChannel if form.action == 'edit-channel' else Channel).get(form.id) except (SQLObjectNotFound, ValueError): raise ImmediateFeedback(form.action, 'invalid_id') previous_state = { 'name': channel.name, 'description': channel.description, 'subscription_right': channel.subscription_right, 'enabled': channel.enabled } new_state = { 'name': name, 'description': description, 'subscription_right': form.subscription_right, 'enabled': enabled } state_diff = dict( set(new_state.items()) - set(previous_state.items())) if form.action == 'edit-channel': try: plugin_id = int(form.plugin) p = Plugin.get(plugin_id) add_mapping = p.webapp and channel.plugin != p previous_state['plugin'] = channel.plugin new_state['plugin'] = p except (SQLObjectNotFound, ValueError): raise ImmediateFeedback(form.action, 'invalid_plugin') elif form.action == 'edit-bundle': pass # There is nothing more to edit for a bundle than a channel else: raise web.badrequest() try: channel.set(**new_state) except DuplicateEntryError: channel.set(**previous_state) # Rollback raise ImmediateFeedback(form.action, 'name_already_exists') logger.info( '[Channel %s (%d)] ' % (channel.name, channel.id) + current_user.log_name + ' edited the channel.\n' 'Previous state: %s\n' % str({ k: v for k, v in previous_state.items() if k in state_diff }) + 'New state: %s' % str(state_diff)) if form.action == 'edit-channel' and add_mapping: self.plugin_manager.add_mapping(self.app, channel) elif form.action.startswith('delete'): if not current_user.super_admin: logger.warning( 'the user %s tried to delete a channel without having the rights to do it', current_user.log_name) raise web.forbidden() try: form.id = int(form.id) channel = Channel.get(form.id) if channel.subscriptions.count( ) > 0 and 'confirm-delete' not in form: raise ImmediateFeedback( form.action, 'channel_has_subscriptions', { 'channel': { 'name': channel.name, 'id': channel.id, 'description': channel.description, 'subscription_right': channel.subscription_right }, 'plugin_id': channel.plugin.id if form.action == 'delete-channel' else None, 'subscriptions': [(s.screen.id, s.screen.name, s.screen.building.name) for s in channel.subscriptions] }) form.name = channel.name channel_name = channel.name channel.destroySelf() logger.info('the channel %s has been deleted by user %s', channel_name, current_user.log_name) except (SQLObjectNotFound, ValueError) as e: print(e) raise ImmediateFeedback(form.action, 'invalid_id') elif form.action == 'add-users-channel': try: if 'users' not in form: raise web.badrequest() form.users = json.loads(form.users) form.id = int(form.id) channel = PluginChannel.get(form.id) if not channel.has_admin( current_user ) and UserPermissions.administrator not in current_user.highest_permission_level: raise web.forbidden() form.name = channel.name for user_id, diff in form.users.items(): user_id = int(user_id) user = User.get(user_id) if 'permission' in diff: permission_level = diff['permission'] new_permission_level = UserPermissions( permission_level) old_permission_level = channel.get_channel_permissions_of( user) if new_permission_level == UserPermissions.no_permission \ and (UserPermissions.administrator in current_user.highest_permission_level or old_permission_level == UserPermissions.channel_contributor): channel.remove_permission_to_user(user) logger.info( 'permissions of user %s concerning channel %s have been removed by user %s', user.log_name, channel.name, current_user.log_name) elif (new_permission_level == UserPermissions.channel_contributor and channel.has_admin( current_user) and old_permission_level == UserPermissions.no_permission) \ or (new_permission_level in UserPermissions.channel_administrator and UserPermissions.administrator in current_user.highest_permission_level): channel.give_permission_to_user( user, new_permission_level) logger.info( 'permissions of user %s concerning channel %s have been set to %s by user %s', user.log_name, channel.name, UserPermissions.get_permission_string( new_permission_level), current_user.log_name) if 'authorized_subscriber' in diff: authorized_subscriber = diff[ 'authorized_subscriber'] if authorized_subscriber and ( user not in channel.authorized_subscribers): channel.addUser(user) logger.info( 'the user %s has been added to channel %s as authorized subscriber by user %s', user.log_name, channel.name, current_user.log_name) elif not authorized_subscriber and ( user in channel.authorized_subscribers): channel.removeUser(user) logger.info( 'the user %s has been removed from channel %s as authorized subscriber by user %s', user.log_name, channel.name, current_user.log_name) except (SQLObjectNotFound, ValueError): raise ImmediateFeedback(form.action, 'invalid_id') except (KeyError, json.JSONDecodeError): raise ImmediateFeedback(form.action, 'invalid_users') elif form.action == 'configure': try: form.id = int(form.id) channel = PluginChannel.get(form.id) pattern = re.compile(r'list\[.*\]') if UserPermissions.administrator in current_user.highest_permission_level or UserPermissions.channel_administrator in channel.get_channel_permissions_of( current_user) or channel.has_contrib(current_user): for k, v in [(k, v) for k, v in channel.plugin.channels_params.items() if channel.get_access_rights_for( k, current_user)[1]]: # Iterates on the parameters the current user can write to if v['type'] == 'bool': value = k in form and form[k] == 'on' elif v['type'] == 'int': value = int(form[k]) if not (v.get('min', float('-inf')) <= value <= v.get('max', float('inf'))): continue elif pattern.match(v['type']): inner_type = v['type'][5:-1] if inner_type == 'string': value = web.input(**{k: ['']})[k] elif pattern.match(inner_type): inner_type = inner_type[5:-1] if inner_type == 'string': delimiter = form[k + '-delimiter'] values = web.input(**{k: ['']})[k] lists = [] l = [] for v in values: if v == delimiter: lists.append(l) l = [] else: l.append(v) value = lists elif k in form: if v['type'] == 'template' and form[k] == '~': value = None else: value = form[k] else: continue if channel.get_config_param(k) != value: channel.plugin_config[k] = value logger.info( 'the %s parameter of channel %s has been changed to %s by user %s', k, channel.name, value, current_user.log_name) if current_user.super_admin: channel.cache_activated = 'cache-activated' in form and form[ 'cache-activated'] == 'on' channel.cache_validity = int( form['cache-validity'] ) if 'cache-validity' in form and form[ 'cache-validity'] else channel.cache_validity channel.keep_noncomplying_capsules = 'keep-capsules' in form and form[ 'keep-capsules'] == 'on' channel.plugin_config = channel.plugin_config # Force SQLObject update try: self.plugin_manager.invalidate_cache( channel.plugin.name, channel.id) self.plugin_manager.get_plugin( channel.plugin.name).get_content(channel.id) except MisconfiguredParameters as e: for faulty_param in e: add_feedback(form.action, faulty_param[0], faulty_param) raise web.seeother('/channels/%d' % channel.id) except Exception as e: add_feedback(form.action, 'general_error', str(e)) raise web.seeother('/channels/%d' % channel.id) else: raise web.forbidden() form.name = channel.name except (SQLObjectNotFound, ValueError): raise ImmediateFeedback(form.action, 'invalid_id') if channel: form.name = channel.name add_feedback(form.action, 'ok') except ImmediateFeedback: if channel is not None and channel.enabled: form.enabled = 'on' store_form(form) return self.render_page(current_user)