def __init__(self, *args, **kwargs): self.text_color = kwargs.pop('text_color') kwargs['color_list'] = [ ColorTuple(self.text_color, color) for color in kwargs['color_list'] ] super(IndicoSinglePalettePickerField, self).__init__(*args, **kwargs)
class Break(DescriptionMixin, ColorMixin, LocationMixin, db.Model): __tablename__ = 'breaks' __auto_table_args = {'schema': 'events'} location_backref_name = 'breaks' default_colors = ColorTuple('#202020', '#90c0f0') possible_render_modes = {RenderMode.markdown} default_render_mode = RenderMode.markdown @declared_attr def __table_args__(cls): return auto_table_args(cls) id = db.Column( db.Integer, primary_key=True ) title = db.Column( db.String, nullable=False ) duration = db.Column( db.Interval, nullable=False ) # relationship backrefs: # - timetable_entry (TimetableEntry.break_) def can_access(self, user): parent = self.timetable_entry.parent if parent: return parent.object.can_access(user) else: return self.event.can_access(user) @property def event(self): return self.timetable_entry.event if self.timetable_entry else None @property def location_parent(self): return (self.event if self.timetable_entry.parent_id is None else self.timetable_entry.parent.session_block) @property def start_dt(self): return self.timetable_entry.start_dt if self.timetable_entry else None @property def end_dt(self): return self.timetable_entry.start_dt + self.duration if self.timetable_entry else None @return_ascii def __repr__(self): return format_repr(self, 'id', _text=self.title) @locator_property def locator(self): return dict(self.event.locator, break_id=self.id)
def __init__(self, *args, **kwargs): self.text_color = kwargs.pop('text_color') kwargs['color_list'] = [ ColorTuple(self.text_color, color) for color in kwargs['color_list'] ] super().__init__(*args, **kwargs)
def _process_PATCH(self): data = request.json if set(data.viewkeys()) > {'colors'}: raise BadRequest if 'colors' in data: colors = ColorTuple(**data['colors']) if colors not in get_colors(): raise BadRequest self.break_.colors = colors
def _process_PATCH(self): data = request.json updates = {} if set(data.viewkeys()) > {'colors'}: raise BadRequest if 'colors' in data: colors = ColorTuple(**data['colors']) if colors not in get_colors(): raise BadRequest updates['colors'] = colors update_session(self.session, updates) return jsonify()
def _migrate_break_timetable_entry(self, old_entry, session_block=None): break_ = Break(title=convert_to_unicode(old_entry.title), description=convert_to_unicode(old_entry.description), duration=old_entry.duration) try: break_.colors = ColorTuple(old_entry._textColor, old_entry._color) except (AttributeError, ValueError) as e: self.print_warning('%[yellow]Break has no colors: "{}" [{}]'.format(break_.title, e)) break_.timetable_entry = TimetableEntry(event_new=self.event, start_dt=self.context._fix_naive(old_entry.startDate)) self._migrate_location(old_entry, break_) if session_block: break_.timetable_entry.parent = session_block.timetable_entry return break_.timetable_entry
def _process_PATCH(self): data = request.json updates = {} if set(data) - {'colors', 'type_id'}: raise BadRequest if 'colors' in data: colors = ColorTuple(**data['colors']) if colors not in get_colors(): raise BadRequest updates['colors'] = colors if 'type_id' in data: updates.update(self._get_session_type_updates(data['type_id'])) update_session(self.session, updates) return jsonify()
def _migrate_session(self, old_session, friendly_id=None): ac = old_session._Session__ac code = convert_to_unicode(old_session._code) if code == 'no code': code = '' session = Session(event_new=self.event, title=convert_to_unicode(old_session.title), description=convert_to_unicode(old_session.description), is_poster=(old_session._ttType == 'poster'), code=code, default_contribution_duration=old_session._contributionDuration, protection_mode=PROTECTION_MODE_MAP[ac._accessProtection]) if friendly_id is not None: session.friendly_id = friendly_id else: # migrating a zombie session; we simply give it a new friendly id self.event._last_friendly_session_id += 1 session.friendly_id = self.event._last_friendly_session_id if not self.quiet: self.print_info('%[blue!]Session%[reset] {}'.format(session.title)) self.event_ns.legacy_session_map[old_session] = session if old_session.id not in self.legacy_session_ids_used: session.legacy_mapping = LegacySessionMapping(event_new=self.event, legacy_session_id=old_session.id) self.legacy_session_ids_used.add(old_session.id) else: self.print_warning('%[yellow!]Duplicate session id; not adding legacy mapping for {}' .format(old_session.id)) # colors try: session.colors = ColorTuple(old_session._textColor, old_session._color) except (AttributeError, ValueError) as e: self.print_warning('%[yellow]Session has no colors: "{}" [{}]'.format(session.title, e)) principals = {} # managers / read access self._process_ac(SessionPrincipal, principals, ac, allow_emails=True) # coordinators for submitter in old_session._coordinators.itervalues(): self._process_principal(SessionPrincipal, principals, submitter, 'Coordinator', roles={'coordinate'}) self._process_principal_emails(SessionPrincipal, principals, getattr(old_session, '_coordinatorsEmail', []), 'Coordinator', roles={'coordinate'}, allow_emails=True) session.acl_entries = set(principals.itervalues()) return session
def process_formdata(self, valuelist): super(IndicoPalettePickerField, self).process_formdata(valuelist) self.data = ColorTuple(self.data['text'], self.data['background'])
from indico.modules.events.timetable.util import get_category_timetable from indico.modules.news.util import get_recent_news from indico.modules.users import User from indico.modules.users.models.favorites import favorite_category_table from indico.util.date_time import format_date, format_number, now_utc from indico.util.decorators import classproperty from indico.util.fs import secure_filename from indico.util.i18n import _ from indico.web.flask.templating import get_template_module from indico.web.flask.util import send_file, url_for from indico.web.rh import RH from indico.web.util import jsonify_data CALENDAR_COLOR_PALETTE = [ ColorTuple('#1F1100', '#ECC495'), ColorTuple('#0F0202', '#B9CBCA'), ColorTuple('#0D1E1F', '#C2ECEF'), ColorTuple('#000000', '#D0C296'), ColorTuple('#202020', '#EFEBC2') ] def _flat_map(func, list_): return chain.from_iterable(map(func, list_)) class RHCategoryIcon(RHDisplayCategoryBase): _category_query_options = undefer('icon'), def _check_access(self):
def get_colors(): return [ ColorTuple('#1D041F', '#EEE0EF'), ColorTuple('#253F08', '#E3F2D3'), ColorTuple('#1F1F02', '#FEFFBF'), ColorTuple('#202020', '#DFE555'), ColorTuple('#1F1D04', '#FFEC1F'), ColorTuple('#0F264F', '#DFEBFF'), ColorTuple('#EFF5FF', '#0D316F'), ColorTuple('#F1FFEF', '#1A3F14'), ColorTuple('#FFFFFF', '#5F171A'), ColorTuple('#272F09', '#D9DFC3'), ColorTuple('#FFEFFF', '#4F144E'), ColorTuple('#FFEDDF', '#6F390D'), ColorTuple('#021F03', '#8EC473'), ColorTuple('#03070F', '#92B6DB'), ColorTuple('#151515', '#DFDFDF'), ColorTuple('#1F1100', '#ECC495'), ColorTuple('#0F0202', '#B9CBCA'), ColorTuple('#0D1E1F', '#C2ECEF'), ColorTuple('#000000', '#D0C296'), ColorTuple('#202020', '#EFEBC2') ]
class Session(DescriptionMixin, ColorMixin, ProtectionManagersMixin, LocationMixin, AttachedItemsMixin, AttachedNotesMixin, db.Model): __tablename__ = 'sessions' __auto_table_args = (db.Index(None, 'friendly_id', 'event_id', unique=True), { 'schema': 'events' }) location_backref_name = 'sessions' disallowed_protection_modes = frozenset() default_colors = ColorTuple('#202020', '#e3f2d3') PRELOAD_EVENT_ATTACHED_ITEMS = True PRELOAD_EVENT_ATTACHED_NOTES = True ATTACHMENT_FOLDER_ID_COLUMN = 'session_id' description_wrapper = MarkdownText @declared_attr def __table_args__(cls): return auto_table_args(cls) id = db.Column(db.Integer, primary_key=True) #: The human-friendly ID for the session friendly_id = db.Column(db.Integer, nullable=False, default=_get_next_friendly_id) event_id = db.Column(db.Integer, db.ForeignKey('events.events.id'), index=True, nullable=False) title = db.Column(db.String, nullable=False) code = db.Column(db.String, nullable=False, default='') default_contribution_duration = db.Column(db.Interval, nullable=False, default=timedelta(minutes=20)) is_poster = db.Column(db.Boolean, nullable=False, default=False) is_deleted = db.Column(db.Boolean, nullable=False, default=False) event_new = db.relationship( 'Event', lazy=True, backref=db.backref( 'sessions', primaryjoin='(Session.event_id == Event.id) & ~Session.is_deleted', cascade='all, delete-orphan', lazy=True)) acl_entries = db.relationship('SessionPrincipal', lazy=True, cascade='all, delete-orphan', collection_class=set, backref='session') blocks = db.relationship('SessionBlock', lazy=True, cascade='all, delete-orphan', backref=db.backref('session', lazy=False)) # relationship backrefs: # - attachment_folders (AttachmentFolder.session) # - contributions (Contribution.session) # - legacy_mapping (LegacySessionMapping.session) # - note (EventNote.session) def __init__(self, **kwargs): # explicitly initialize this relationship with None to avoid # an extra query to check whether there is an object associated # when assigning a new one (e.g. during cloning) kwargs.setdefault('note', None) super(Session, self).__init__(**kwargs) @property def location_parent(self): return self.event_new @property def protection_parent(self): return self.event_new @property def session(self): """Convenience property so all event entities have it""" return self @property @memoize_request def start_dt(self): from indico.modules.events.sessions.models.blocks import SessionBlock start_dt = (self.event_new.timetable_entries.with_entities( TimetableEntry.start_dt).join('session_block').filter( TimetableEntry.type == TimetableEntryType.SESSION_BLOCK, SessionBlock.session == self).order_by( TimetableEntry.start_dt).first()) return start_dt[0] if start_dt else None @property @memoize_request def end_dt(self): sorted_blocks = sorted(self.blocks, key=attrgetter('timetable_entry.end_dt'), reverse=True) return sorted_blocks[ 0].timetable_entry.end_dt if sorted_blocks else None @property @memoize_request def conveners(self): from indico.modules.events.sessions.models.blocks import SessionBlock from indico.modules.events.sessions.models.persons import SessionBlockPersonLink return (SessionBlockPersonLink.query.join(SessionBlock).filter( SessionBlock.session_id == self.id).distinct( SessionBlockPersonLink.person_id).all()) @locator_property def locator(self): return dict(self.event_new.locator, session_id=self.id) def get_non_inheriting_objects(self): """Get a set of child objects that do not inherit protection""" return get_non_inheriting_objects(self) @return_ascii def __repr__(self): return format_repr(self, 'id', is_poster=False, is_deleted=False, _text=self.title) def can_manage_contributions(self, user, allow_admin=True): """Check whether a user can manage contributions within the session.""" from indico.modules.events.sessions.util import session_coordinator_priv_enabled if user is None: return False elif self.session.can_manage(user, allow_admin=allow_admin): return True elif (self.session.can_manage(user, 'coordinate') and session_coordinator_priv_enabled(self.event_new, 'manage-contributions')): return True else: return False def can_manage_blocks(self, user, allow_admin=True): """Check whether a user can manage session blocks. This only applies to the blocks themselves, not to contributions inside them. """ from indico.modules.events.sessions.util import session_coordinator_priv_enabled if user is None: return False # full session manager can always manage blocks. this also includes event managers and higher. elif self.session.can_manage(user, allow_admin=allow_admin): return True # session coordiator if block management is allowed elif (self.session.can_manage(user, 'coordinate') and session_coordinator_priv_enabled(self.event_new, 'manage-blocks')): return True else: return False
def _value(self): return ColorTuple(self.text_color, self.data)._asdict()
def process_formdata(self, valuelist): super().process_formdata(valuelist) self.data = ColorTuple(self.data['text'], self.data['background'])