<s> import re <EOL> import json <EOL> import unicodedata <EOL> from cStringIO import StringIO <EOL> from functools import partial <EOL> import xlwt <EOL> from webob import exc <EOL> from nagare . database import session <EOL> from nagare . i18n import _ , format_date <EOL> from nagare import component , log , security , var <EOL> from kansha import title <EOL> from kansha . card import Card <EOL> from kansha . user import usermanager <EOL> from kansha . services import ActionLog <EOL> from kansha . column import comp as column <EOL> from kansha . user . comp import PendingUser <EOL> from kansha . toolbox import popin , overlay <EOL> from kansha . card_addons . label import Label <EOL> from kansha . authentication . database import forms <EOL> from kansha import events , exceptions , validator <EOL> from . boardconfig import BoardConfig <EOL> from . excel_export import ExcelExport <EOL> from . templates import SaveTemplateTask <EOL> from . models import DataBoard , DataBoardMember <EOL> BOARD_PRIVATE = <NUM_LIT:0> <EOL> BOARD_PUBLIC = <NUM_LIT:1> <EOL> VOTES_OFF = <NUM_LIT:0> <EOL> VOTES_MEMBERS = <NUM_LIT:1> <EOL> VOTES_PUBLIC = <NUM_LIT:2> <EOL> COMMENTS_OFF = <NUM_LIT:0> <EOL> COMMENTS_MEMBERS = <NUM_LIT:1> <EOL> COMMENTS_PUBLIC = <NUM_LIT:2> <EOL> WEIGHTING_OFF = <NUM_LIT:0> <EOL> WEIGHTING_FREE = <NUM_LIT:1> <EOL> WEIGHTING_LIST = <NUM_LIT:2> <EOL> class Board ( events . EventHandlerMixIn ) : <EOL> """<STR_LIT>""" <EOL> MAX_SHOWN_MEMBERS = <NUM_LIT:4> <EOL> background_max_size = <NUM_LIT:3> * <NUM_LIT> <EOL> def __init__ ( self , id_ , app_title , app_banner , theme , card_extensions , search_engine_service , <EOL> assets_manager_service , mail_sender_service , services_service , <EOL> load_children = True ) : <EOL> """<STR_LIT>""" <EOL> self . model = '<STR_LIT>' <EOL> self . app_title = app_title <EOL> self . app_banner = app_banner <EOL> self . theme = theme <EOL> self . mail_sender = mail_sender_service <EOL> self . id = id_ <EOL> self . assets_manager = assets_manager_service <EOL> self . search_engine = search_engine_service <EOL> self . _services = services_service <EOL> self . board_extensions = { <EOL> '<STR_LIT>' : self , <EOL> '<STR_LIT>' : self , <EOL> '<STR_LIT>' : self , <EOL> '<STR_LIT>' : self , <EOL> '<STR_LIT>' : self <EOL> } <EOL> self . card_extensions = card_extensions . set_configurators ( self . board_extensions ) <EOL> self . action_log = ActionLog ( self ) <EOL> self . version = self . data . version <EOL> self . modal = component . Component ( popin . Empty ( ) ) <EOL> self . card_matches = set ( ) <EOL> self . last_search = u'<STR_LIT>' <EOL> self . columns = [ ] <EOL> self . archive_column = None <EOL> if load_children : <EOL> self . load_children ( ) <EOL> self . overlay_add_members = component . Component ( <EOL> overlay . Overlay ( lambda r : ( r . i ( class_ = '<STR_LIT>' ) , r . span ( _ ( u'<STR_LIT:+>' ) , class_ = '<STR_LIT:count>' ) ) , <EOL> lambda r : component . Component ( self ) . render ( r , model = '<STR_LIT>' ) , <EOL> dynamic = True , cls = '<STR_LIT>' ) ) <EOL> self . new_member = component . Component ( usermanager . NewMember ( self . autocomplete_method ) ) <EOL> self . update_members ( ) <EOL> def many_user_render ( h , number ) : <EOL> return h . span ( <EOL> h . i ( class_ = '<STR_LIT>' ) , <EOL> h . span ( number , class_ = '<STR_LIT:count>' ) , <EOL> title = _ ( "<STR_LIT>" ) % number ) <EOL> self . see_all_members = component . Component ( overlay . Overlay ( lambda r : many_user_render ( r , len ( self . all_members ) - self . MAX_SHOWN_MEMBERS ) , <EOL> lambda r : component . Component ( self ) . render ( r , model = '<STR_LIT>' ) , <EOL> dynamic = False , cls = '<STR_LIT>' ) ) <EOL> self . see_all_members_compact = component . Component ( overlay . Overlay ( lambda r : many_user_render ( r , len ( self . all_members ) ) , <EOL> lambda r : component . Component ( self ) . render ( r , model = '<STR_LIT>' ) , <EOL> dynamic = False , cls = '<STR_LIT>' ) ) <EOL> self . comp_members = component . Component ( self ) <EOL> self . icons = { '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( '<STR_LIT>' ) ) ) , <EOL> '<STR_LIT>' : component . Component ( Icon ( '<STR_LIT>' , _ ( "<STR_LIT>" ) ) ) , <EOL> } <EOL> self . title = component . Component ( <EOL> title . EditableTitle ( self . get_title ) ) . on_answer ( self . set_title ) <EOL> self . must_reload_search = False <EOL> @ classmethod <EOL> def get_id_by_uri ( cls , uri ) : <EOL> board = DataBoard . get_by_uri ( uri ) <EOL> board_id = None <EOL> if board is not None : <EOL> board_id = board . id <EOL> return board_id <EOL> @ classmethod <EOL> def exists ( cls , ** kw ) : <EOL> return DataBoard . exists ( ** kw ) <EOL> def add_list ( self ) : <EOL> new_column_editor = column . NewColumnEditor ( len ( self . columns ) ) <EOL> answer = self . modal . call ( popin . Modal ( new_column_editor ) ) <EOL> if answer : <EOL> index , title , nb_cards = answer <EOL> self . create_column ( index , title , nb_cards if nb_cards else None ) <EOL> def edit_description ( self ) : <EOL> description_editor = BoardDescription ( self . get_description ( ) ) <EOL> answer = self . modal . call ( popin . Modal ( description_editor ) ) <EOL> if answer is not None : <EOL> self . set_description ( answer ) <EOL> def save_template ( self , comp ) : <EOL> save_template_editor = SaveTemplateTask ( self . get_title ( ) , <EOL> self . get_description ( ) , <EOL> partial ( self . save_as_template , comp ) ) <EOL> self . modal . call ( popin . Modal ( save_template_editor ) ) <EOL> def show_actionlog ( self ) : <EOL> self . modal . call ( popin . Modal ( self . action_log ) ) <EOL> def show_preferences ( self ) : <EOL> preferences = BoardConfig ( self ) <EOL> self . modal . call ( popin . Modal ( preferences ) ) <EOL> def save_as_template ( self , comp , title , description , shared ) : <EOL> data = ( title , description , shared ) <EOL> return self . emit_event ( comp , events . NewTemplateRequested , data ) <EOL> def copy ( self , owner ) : <EOL> """<STR_LIT>""" <EOL> new_data = self . data . copy ( ) <EOL> if self . data . background_image : <EOL> new_data . background_image = self . assets_manager . copy ( self . data . background_image ) <EOL> new_board = self . _services ( Board , new_data . id , self . app_title , self . app_banner , self . theme , self . card_extensions , load_children = False ) <EOL> new_board . add_member ( owner , '<STR_LIT>' ) <EOL> assert ( self . columns or self . data . is_template ) <EOL> cols = [ col ( ) for col in self . columns if not col ( ) . is_archive ] <EOL> for column in cols : <EOL> new_column = new_board . create_column ( - <NUM_LIT:1> , column . get_title ( ) ) <EOL> new_column . update ( column ) <EOL> return new_board <EOL> def on_event ( self , comp , event ) : <EOL> result = None <EOL> if event . is_ ( events . ColumnDeleted ) : <EOL> result = self . delete_column ( event . data ) <EOL> elif event . is_ ( events . CardArchived ) : <EOL> result = self . archive_card ( event . emitter ) <EOL> elif event . is_ ( events . SearchIndexUpdated ) : <EOL> result = self . set_reload_search ( ) <EOL> elif event . is_ ( events . CardDisplayed ) : <EOL> if self . must_reload_search : <EOL> self . reload_search ( ) <EOL> result = '<STR_LIT>' <EOL> else : <EOL> result = '<STR_LIT>' <EOL> return result <EOL> def switch_view ( self ) : <EOL> self . model = '<STR_LIT>' if self . model == '<STR_LIT>' else '<STR_LIT>' <EOL> def load_children ( self ) : <EOL> columns = [ ] <EOL> for c in self . data . columns : <EOL> col = self . _services ( <EOL> column . Column , c . id , self , self . card_extensions , <EOL> self . action_log , data = c ) <EOL> if col . is_archive : <EOL> self . archive_column = col <EOL> columns . append ( component . Component ( col ) ) <EOL> self . columns = columns <EOL> def increase_version ( self ) : <EOL> refresh = False <EOL> self . version += <NUM_LIT:1> <EOL> self . data . increase_version ( ) <EOL> if self . data . version - self . version != <NUM_LIT:0> : <EOL> self . refresh ( ) <EOL> self . version = self . data . version <EOL> refresh = True <EOL> return refresh <EOL> def refresh ( self ) : <EOL> print "<STR_LIT>" <EOL> print "<STR_LIT>" <EOL> self . load_children ( ) <EOL> @ property <EOL> def all_members ( self ) : <EOL> return self . managers + self . members + self . pending <EOL> def update_members ( self ) : <EOL> """<STR_LIT>""" <EOL> data = self . data <EOL> members = [ dbm . member for dbm in data . board_members ] <EOL> members = [ member for member in set ( members ) - set ( data . managers ) ] <EOL> members . sort ( key = lambda m : ( m . fullname , m . email ) ) <EOL> self . members = [ component . Component ( BoardMember ( usermanager . UserManager . get_app_user ( member . username , data = member ) , self , '<STR_LIT>' ) ) <EOL> for member in members ] <EOL> self . managers = [ component . Component ( BoardMember ( usermanager . UserManager . get_app_user ( member . username , data = member ) , self , '<STR_LIT>' if len ( data . managers ) != <NUM_LIT:1> else '<STR_LIT>' ) ) <EOL> for member in data . managers ] <EOL> self . pending = [ component . Component ( BoardMember ( PendingUser ( token . token ) , self , '<STR_LIT>' ) ) <EOL> for token in data . pending ] <EOL> def set_title ( self , title ) : <EOL> """<STR_LIT>""" <EOL> self . data . title = title <EOL> def get_title ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . data . title <EOL> def mark_as_template ( self , template = True ) : <EOL> self . data . is_template = template <EOL> def count_columns ( self ) : <EOL> """<STR_LIT>""" <EOL> return len ( self . columns ) <EOL> @ security . permissions ( '<STR_LIT>' ) <EOL> def create_column ( self , index , title , nb_cards = None ) : <EOL> """<STR_LIT>""" <EOL> if index < <NUM_LIT:0> : <EOL> index = index + len ( self . columns ) + <NUM_LIT:1> <EOL> if title == '<STR_LIT>' : <EOL> return False <EOL> col = self . data . create_column ( index , title , nb_cards ) <EOL> col_obj = self . _services ( <EOL> column . Column , col . id , self , <EOL> self . card_extensions , self . action_log ) <EOL> self . columns . insert ( <EOL> index , component . Component ( col_obj ) ) <EOL> self . increase_version ( ) <EOL> return col_obj <EOL> @ security . permissions ( '<STR_LIT>' ) <EOL> def delete_column ( self , col_comp ) : <EOL> """<STR_LIT>""" <EOL> self . columns . remove ( col_comp ) <EOL> col_comp ( ) . delete ( ) <EOL> self . increase_version ( ) <EOL> return popin . Empty ( ) <EOL> @ security . permissions ( '<STR_LIT>' ) <EOL> def update_card_position ( self , data ) : <EOL> data = json . loads ( data ) <EOL> cols = { } <EOL> for col in self . columns : <EOL> cols [ col ( ) . id ] = ( col ( ) , col ) <EOL> orig , __ = cols [ data [ '<STR_LIT>' ] ] <EOL> dest , dest_comp = cols [ data [ '<STR_LIT>' ] ] <EOL> card_comp = orig . remove_card_by_id ( data [ '<STR_LIT>' ] ) <EOL> dest . insert_card_comp ( dest_comp , data [ '<STR_LIT:index>' ] , card_comp ) <EOL> card = card_comp ( ) <EOL> values = { '<STR_LIT>' : orig . get_title ( ) , <EOL> '<STR_LIT:to>' : dest . get_title ( ) , <EOL> '<STR_LIT>' : card . get_title ( ) } <EOL> self . action_log . for_card ( card ) . add_history ( <EOL> security . get_user ( ) , <EOL> u'<STR_LIT>' , values ) <EOL> card . add_to_index ( self . search_engine , self . id , update = True ) <EOL> self . search_engine . commit ( ) <EOL> session . flush ( ) <EOL> @ security . permissions ( '<STR_LIT>' ) <EOL> def update_column_position ( self , data ) : <EOL> data = json . loads ( data ) <EOL> cols = [ ] <EOL> found = None <EOL> for col in self . columns : <EOL> if col ( ) . id == data [ '<STR_LIT:list>' ] : <EOL> found = col <EOL> else : <EOL> cols . append ( col ) <EOL> cols . insert ( data [ '<STR_LIT:index>' ] , found ) <EOL> for i , col in enumerate ( cols ) : <EOL> col ( ) . change_index ( i ) <EOL> self . columns = cols <EOL> session . flush ( ) <EOL> @ property <EOL> def visibility ( self ) : <EOL> return self . data . visibility <EOL> def is_public ( self ) : <EOL> return self . visibility == BOARD_PUBLIC <EOL> def set_visibility ( self , visibility ) : <EOL> """<STR_LIT>""" <EOL> if self . comments_allowed == COMMENTS_PUBLIC : <EOL> self . allow_comments ( COMMENTS_MEMBERS ) <EOL> if self . votes_allowed == VOTES_PUBLIC : <EOL> self . allow_votes ( VOTES_MEMBERS ) <EOL> self . data . visibility = visibility <EOL> @ property <EOL> def archived ( self ) : <EOL> return self . data . archived <EOL> @ property <EOL> def show_archive ( self ) : <EOL> return self . data . show_archive <EOL> @ show_archive . setter <EOL> def show_archive ( self , value ) : <EOL> self . data . show_archive = value <EOL> self . set_reload_search ( ) <EOL> def archive_card ( self , card ) : <EOL> """<STR_LIT>""" <EOL> self . archive_column . append_card ( card ) <EOL> self . archive_column . refresh ( ) <EOL> @ property <EOL> def weighting_cards ( self ) : <EOL> return self . data . weighting_cards <EOL> def activate_weighting ( self , weighting_type ) : <EOL> if weighting_type == WEIGHTING_FREE : <EOL> self . data . weighting_cards = <NUM_LIT:1> <EOL> elif weighting_type == WEIGHTING_LIST : <EOL> self . data . weighting_cards = <NUM_LIT:2> <EOL> for col in self . columns : <EOL> col = col ( ) . data <EOL> for card in col . cards : <EOL> card . weight = '<STR_LIT>' <EOL> for card in self . archive_column . cards : <EOL> card . weight = '<STR_LIT>' <EOL> @ property <EOL> def weights ( self ) : <EOL> return self . data . weights <EOL> @ weights . setter <EOL> def weights ( self , weights ) : <EOL> self . data . weights = weights <EOL> def deactivate_weighting ( self ) : <EOL> self . data . weighting_cards = <NUM_LIT:0> <EOL> self . data . weights = '<STR_LIT>' <EOL> def delete_clicked ( self , comp ) : <EOL> return self . emit_event ( comp , events . BoardDeleted ) <EOL> def delete ( self ) : <EOL> """<STR_LIT>""" <EOL> assert ( self . columns ) <EOL> for column in self . columns : <EOL> column ( ) . delete ( purge = True ) <EOL> self . data . delete_history ( ) <EOL> self . data . delete_members ( ) <EOL> session . refresh ( self . data ) <EOL> self . data . delete ( ) <EOL> return True <EOL> def archive ( self , comp = None ) : <EOL> """<STR_LIT>""" <EOL> self . data . archived = True <EOL> if comp : <EOL> self . emit_event ( comp , events . BoardArchived ) <EOL> return True <EOL> def restore ( self , comp = None ) : <EOL> """<STR_LIT>""" <EOL> self . data . archived = False <EOL> if comp : <EOL> self . emit_event ( comp , events . BoardRestored ) <EOL> return True <EOL> def leave ( self , comp = None ) : <EOL> """<STR_LIT>""" <EOL> user = security . get_user ( ) <EOL> for member in self . members : <EOL> m_user = member ( ) . user ( ) . data <EOL> if ( m_user . username , m_user . source ) == ( user . data . username , user . data . source ) : <EOL> board_member = member ( ) <EOL> break <EOL> else : <EOL> board_member = None <EOL> self . data . remove_member ( board_member ) <EOL> if user . is_manager ( self ) : <EOL> self . data . remove_manager ( board_member ) <EOL> if not self . columns : <EOL> self . load_children ( ) <EOL> for column in self . columns : <EOL> column ( ) . remove_board_member ( user ) <EOL> if comp : <EOL> self . emit_event ( comp , events . BoardLeft ) <EOL> return True <EOL> def export ( self ) : <EOL> return ExcelExport ( self ) . download ( ) <EOL> @ property <EOL> def labels ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ self . _services ( Label , data ) for data in self . data . labels ] <EOL> @ property <EOL> def data ( self ) : <EOL> """<STR_LIT>""" <EOL> return DataBoard . get ( self . id ) <EOL> def allow_comments ( self , v ) : <EOL> """<STR_LIT>""" <EOL> self . data . comments_allowed = v <EOL> def allow_votes ( self , v ) : <EOL> """<STR_LIT>""" <EOL> self . data . votes_allowed = v <EOL> @ property <EOL> def comments_allowed ( self ) : <EOL> return self . data . comments_allowed <EOL> @ property <EOL> def votes_allowed ( self ) : <EOL> return self . data . votes_allowed <EOL> def get_description ( self ) : <EOL> return self . data . description <EOL> def set_description ( self , value ) : <EOL> self . data . description = value <EOL> def last_manager ( self , member ) : <EOL> """<STR_LIT>""" <EOL> return self . data . last_manager ( member ) <EOL> def has_member ( self , user ) : <EOL> """<STR_LIT>""" <EOL> return self . data . has_member ( user ) <EOL> def has_manager ( self , user ) : <EOL> """<STR_LIT>""" <EOL> return self . data . has_manager ( user ) <EOL> def add_member ( self , new_member , role = '<STR_LIT>' ) : <EOL> """<STR_LIT>""" <EOL> self . data . add_member ( new_member , role ) <EOL> def remove_pending ( self , member ) : <EOL> self . pending = [ p for p in self . pending if p ( ) != member ] <EOL> self . remove_invitation ( member . username ) <EOL> def remove_manager ( self , manager ) : <EOL> self . managers = [ p for p in self . managers if p ( ) != manager ] <EOL> self . data . remove_manager ( manager ) <EOL> def remove_member ( self , member ) : <EOL> self . members = [ p for p in self . members if p ( ) != member ] <EOL> self . data . remove_member ( member ) <EOL> def remove_board_member ( self , member ) : <EOL> """<STR_LIT>""" <EOL> if self . last_manager ( member ) : <EOL> raise exceptions . KanshaException ( _ ( "<STR_LIT>" ) ) <EOL> log . info ( '<STR_LIT>' % ( member , ) ) <EOL> remove_method = { '<STR_LIT>' : self . remove_pending , <EOL> '<STR_LIT>' : self . remove_manager , <EOL> '<STR_LIT>' : self . remove_member } <EOL> remove_method [ member . role ] ( member ) <EOL> if not self . columns : <EOL> self . load_children ( ) <EOL> for c in self . columns : <EOL> c ( ) . remove_board_member ( member ) <EOL> def change_role ( self , member , new_role ) : <EOL> """<STR_LIT>""" <EOL> log . info ( '<STR_LIT>' % ( member , new_role ) ) <EOL> if self . last_manager ( member ) : <EOL> raise exceptions . KanshaException ( _ ( "<STR_LIT>" ) ) <EOL> self . data . change_role ( member , new_role ) <EOL> self . update_members ( ) <EOL> def remove_invitation ( self , email ) : <EOL> """<STR_LIT>""" <EOL> for token in self . data . pending : <EOL> if token . username == email : <EOL> token . delete ( ) <EOL> session . flush ( ) <EOL> break <EOL> def invite_members ( self , emails , application_url ) : <EOL> """<STR_LIT>""" <EOL> for email in set ( emails ) : <EOL> invitation = forms . EmailInvitation ( self . app_title , self . app_banner , self . theme , email , security . get_user ( ) . data , self . data , application_url ) <EOL> invitation . send_email ( self . mail_sender ) <EOL> def resend_invitation ( self , pending_member , application_url ) : <EOL> """<STR_LIT>""" <EOL> email = pending_member . username <EOL> invitation = forms . EmailInvitation ( self . app_title , self . app_banner , self . theme , email , security . get_user ( ) . data , self . data , application_url ) <EOL> invitation . send_email ( self . mail_sender ) <EOL> self . pending = [ component . Component ( BoardMember ( PendingUser ( token . token ) , self , "<STR_LIT>" ) ) <EOL> for token in set ( self . data . pending ) ] <EOL> def autocomplete_method ( self , v ) : <EOL> """<STR_LIT>""" <EOL> users = usermanager . UserManager . search ( v ) <EOL> results = [ ] <EOL> for user in users : <EOL> if user . is_validated ( ) and user . email not in [ m ( ) . email for m in self . all_members ] : <EOL> results . append ( user ) <EOL> return results <EOL> def get_last_activity ( self ) : <EOL> return self . action_log . get_last_activity ( ) <EOL> def get_friends ( self , user ) : <EOL> """<STR_LIT>""" <EOL> already_in = set ( [ m ( ) . email for m in self . all_members ] ) <EOL> best_friends = user . best_friends ( already_in , <NUM_LIT:5> ) <EOL> self . _best_friends = [ component . Component ( usermanager . UserManager . get_app_user ( u . username ) , "<STR_LIT>" ) for u in best_friends ] <EOL> return self . _best_friends <EOL> def get_member_stats ( self ) : <EOL> """<STR_LIT>""" <EOL> member_stats = { } <EOL> for c in self . columns : <EOL> column_member_stats = c ( ) . get_member_stats ( ) <EOL> for username in column_member_stats : <EOL> member_stats [ username ] = member_stats . get ( username , <NUM_LIT:0> ) + column_member_stats [ username ] <EOL> return member_stats <EOL> def get_available_user_ids ( self ) : <EOL> """<STR_LIT>""" <EOL> return set ( dbm . member . id for dbm in self . data . board_members ) <EOL> def get_pending_user_ids ( self ) : <EOL> return set ( user . id for user in self . data . get_pending_users ( ) ) <EOL> def set_background_image ( self , new_file ) : <EOL> """<STR_LIT>""" <EOL> if new_file is not None : <EOL> fileid = self . assets_manager . save ( new_file . file . read ( ) , <EOL> metadata = { '<STR_LIT:filename>' : new_file . filename , <EOL> '<STR_LIT>' : new_file . type } ) <EOL> self . data . background_image = fileid <EOL> else : <EOL> self . data . background_image = None <EOL> def set_background_position ( self , position ) : <EOL> self . data . background_position = position <EOL> @ property <EOL> def background_image_url ( self ) : <EOL> img = self . data . background_image <EOL> try : <EOL> return self . assets_manager . get_image_url ( img , include_filename = False ) if img else None <EOL> except IOError : <EOL> log . warning ( '<STR_LIT>' , img , self . id ) <EOL> return None <EOL> @ property <EOL> def background_image_position ( self ) : <EOL> return self . data . background_position or '<STR_LIT>' <EOL> @ property <EOL> def title_color ( self ) : <EOL> return self . data . title_color <EOL> def set_title_color ( self , value ) : <EOL> self . data . title_color = value or u'<STR_LIT>' <EOL> def search ( self , query ) : <EOL> self . last_search = query <EOL> if query : <EOL> condition = Card . schema . match ( query ) & ( Card . schema . board_id == self . id ) <EOL> if not self . show_archive : <EOL> condition &= ( Card . schema . archived == False ) <EOL> self . card_matches = set ( doc . _id for ( _ , doc ) in self . search_engine . search ( condition ) ) <EOL> if not self . card_matches : <EOL> self . card_matches . add ( None ) <EOL> else : <EOL> self . card_matches = set ( ) <EOL> @ staticmethod <EOL> def get_all_board_ids ( ) : <EOL> return DataBoard . get_all_board_ids ( ) <EOL> @ staticmethod <EOL> def get_templates_for ( user_username , user_source ) : <EOL> return DataBoard . get_templates_for ( user_username , user_source , BOARD_PUBLIC ) <EOL> def set_reload_search ( self ) : <EOL> self . must_reload_search = True <EOL> def reload_search ( self ) : <EOL> self . must_reload_search = False <EOL> return self . search ( self . last_search ) <EOL> class Icon ( object ) : <EOL> def __init__ ( self , icon , title = None ) : <EOL> """<STR_LIT>""" <EOL> self . icon = icon <EOL> self . title = title <EOL> class BoardDescription ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , description ) : <EOL> """<STR_LIT>""" <EOL> self . description = var . Var ( description ) <EOL> def commit ( self , comp ) : <EOL> description = self . description ( ) . strip ( ) <EOL> if description : <EOL> description = validator . clean_text ( description ) <EOL> comp . answer ( description ) <EOL> def cancel ( self , comp ) : <EOL> comp . answer ( None ) <EOL> class BoardMember ( object ) : <EOL> def __init__ ( self , user , board , role ) : <EOL> self . user = component . Component ( user ) <EOL> self . role = role <EOL> self . board = board <EOL> @ property <EOL> def data ( self ) : <EOL> member = DataBoardMember . query <EOL> member = member . filter_by ( board = self . board . data ) <EOL> member = member . filter_by ( member = self . get_user_data ( ) ) <EOL> return member . first ( ) <EOL> def delete ( self ) : <EOL> session . delete ( self . data ) <EOL> session . flush ( ) <EOL> @ property <EOL> def username ( self ) : <EOL> return self . user ( ) . username <EOL> @ property <EOL> def email ( self ) : <EOL> return self . user ( ) . email <EOL> def dispatch ( self , action , application_url ) : <EOL> if action == '<STR_LIT>' : <EOL> self . board . remove_board_member ( self ) <EOL> elif action == '<STR_LIT>' : <EOL> self . board . change_role ( self , '<STR_LIT>' if self . role == '<STR_LIT>' else '<STR_LIT>' ) <EOL> elif action == '<STR_LIT>' : <EOL> self . board . resend_invitation ( self , application_url ) <EOL> def get_user_data ( self ) : <EOL> return self . user ( ) . data </s>
