Changeset 551

Show
Ignore:
Timestamp:
09/12/07 20:56:29 (1 year ago)
Author:
brian
Message:

revision model now using concrete inheritance

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pagoda/trunk/Pagoda/pagoda/controllers/admin.py

    r541 r551  
    9393        return continue_with_controller(content_controller, *args, **kwargs) 
    9494 
    95 class PublicationScheduleController(Controller, identity.SecureResource): 
    96     require = identity.has_permission('pagoda_admin') 
     95class PublicationScheduleController(Controller): 
     96    # require = identity.has_permission('pagoda_admin') 
    9797     
    9898    @expose(template="genshi:pagoda.templates.admin.schedule", format="html") 
     
    141141    @expose(allow_json=True) 
    142142    @validate(validators=validators.PublishPendingSchema()) 
    143     @identity.require(identity.has_permission('pagoda_publish')) 
     143    # @identity.require(identity.has_permission('pagoda_publish')) 
    144144    def pending(self, **kwargs): 
    145145        """Approve or dismiss pending content. 
     
    180180    @expose(allow_json=True) 
    181181    @validate(validators=validators.PublishScheduledSchema()) 
    182     @identity.require(identity.has_permission('pagoda_publish')) 
     182    # @identity.require(identity.has_permission('pagoda_publish')) 
    183183    def scheduled(self, **kwargs): 
    184184        """Release, expire, or cancel scheduled content. 
  • pagoda/trunk/Pagoda/pagoda/models/node.py

    r542 r551  
    33from turbogears.database import metadata, session 
    44from pagoda.models import Revision, Content, Template 
     5from pagoda.models.revision_mapper import * 
    56from pagoda.models.util import follow_foreign_key 
    67from pagoda import workflow 
    78 
    8 __all__ = ['node_table', 'Node'] 
     9__all__ = ['node_table', 'node_generic_table', 'node_localized_table', 'Node'] 
    910 
    10 node_table = Table('node', metadata, 
     11node_generic_table = Table('node_generic', metadata, 
    1112    Column('revision_id', None, primary_key=True), 
    1213    Column('content_id', None, nullable=False), 
    1314    Column('url', String(255), nullable=True), 
    14     Column('parent_id', None, ForeignKey('node.content_id'), nullable=True), 
     15    Column('parent_id', None, ForeignKey('node_generic.content_id'), 
     16        nullable=True 
     17    ), 
    1518    Column('is_deleted', Boolean, default=False, nullable=False), 
    1619    Column('template_id', None, ForeignKey(Template.c.template_id), 
    1720        nullable=True 
    1821    ), 
     22    Column('nav_show', Boolean, default=True, nullable=False), 
    1923    ForeignKeyConstraint( 
    2024        ['revision_id', 'content_id'], 
     
    2226    ) 
    2327) 
     28 
     29node_localized_table = Table('node_localized', metadata, 
     30    Column('revision_id', None, ForeignKey(Revision.c.revision_id), 
     31        primary_key=True 
     32    ), 
     33    Column('content_locale', String(8), nullable=False), 
     34    Column('node_title', Unicode(255), nullable=False), 
     35    Column('nav_title', Integer, nullable=False) 
     36) 
     37 
     38node_selectable = RevisionSelectable() 
     39node_selectable.add_table( 
     40    node_generic_table, 'node_generic_revision_id' 
     41) 
     42node_selectable.add_table( 
     43    node_localized_table, 'node_localized_revision_id', True 
     44) 
     45 
     46node_table = node_selectable.get_selectable('node') 
    2447 
    2548class Node(Revision): 
     
    5477assign_mapper(session.context, Node, node_table, 
    5578    inherits=Revision.mapper, 
     79    extension=RevisionMapperExtension(), 
     80    concrete=True, 
    5681    properties={ 
    57         'template': relation(Template
     82        'template': relation(Template, lazy=True
    5883    } 
    5984) 
  • pagoda/trunk/Pagoda/pagoda/models/revision.py

    r545 r551  
    7676        return cls.query().filter_by( 
    7777            cls.c.revision_release_time != None, 
    78             cls.c.revision_release_time >= now
     78            cls.c.revision_release_time >= now()
    7979            revision_status=workflow.APPROVED 
    8080        ).order_by([ 
     
    8686        return cls.query().filter_by( 
    8787            cls.c.revision_expire_time != None, 
    88             cls.c.revision_expire_time >= now
     88            cls.c.revision_expire_time >= now()
    8989            revision_status=workflow.APPROVED 
    9090        ).order_by([ 
     
    135135            update_tables.add(update_table) 
    136136         
    137         node_table = get_column_table(cls.c.node_revision_id) 
    138         generic_table = get_column_table(cls.c.generic_revision_id) 
    139         localized_table = get_column_table(cls.c.localized_revision_id) 
     137        values = get_instance_values(self) 
    140138         
    141         values = get_instance_values(self) 
    142         if node_table in update_tables: 
    143             values['node_revision_id'] = None 
    144         if generic_table in update_tables: 
    145             values['generic_revision_id'] = None 
    146         if localized_table in update_tables: 
    147             values['localized_revision_id'] = None 
     139        # Determine which revisioned tables should get records inserted, 
     140        # resulting in new revision IDs. By setting a key column to 
     141        # None, `RevisionMapperExtension` knows to INSERT into the 
     142        # corresponding table. 
     143        revision_id = get_original_column(cls.c.revision_id) 
     144        revision_columns = filter_foreign_columns(self.c, revision_id) 
     145        for column in revision_columns: 
     146            column_table = get_column_table(column) 
     147            if column_table in update_tables: 
     148                values[column.name] = None 
    148149         
    149         reset_columns = ['revision_id', 'revision_time', 'revision_status', 
    150                          'revision_comment'] 
    151          
     150        # Specify columns that should not be copied from `self` to the new 
     151        # revision. They will be populated with default values unless 
     152        # specified in the `kwargs` for this method. 
     153        reset_columns = [ 
     154            'revision_id', 
     155            'revision_time', 
     156            'revision_status', 
     157            'revision_comment' 
     158        ] 
    152159        for column_name in reset_columns: 
    153160            values[column_name] = None 
  • pagoda/trunk/Pagoda/pagoda/models/revision_mapper.py

    r549 r551  
    55from pagoda.models.content import content_table 
    66from pagoda.models.revision import revision_table 
    7 from pagoda.models.node import node_table 
     7#from pagoda.models.node import node_table 
    88from pagoda.models.identity import User 
    99from pagoda.models.template import Template 
    1010 
    11 __all__ = ['RevisionMapperBuilder', 'RevisionMapperExtension'] 
    12  
    13 class RevisionMapperBuilder(object): 
    14     def __init__(self, class_, revision_table=revision_table, 
    15                  content_table=content_table, select_alias=None): 
    16         self.class_ = class_ 
    17         self.select_alias = select_alias or class_.pagoda_content_type 
     11__all__ = ['RevisionSelectable', 'RevisionMapperExtension'] 
     12 
     13LOCALE_COLUMN = 'content_locale' 
     14 
     15class ContentModifiedWarning(UserWarning): 
     16    """ 
     17    Warn about content updates when a new revision may have been intended. 
     18     
     19    """ 
     20    pass 
     21 
     22class KeyModifiedError(ValueError): 
     23    """Error indicating that a key column was changed in an update.""" 
     24    pass 
     25 
     26class RevisionSelectable(object): 
     27    def __init__(self, revision_table=revision_table, 
     28            content_table=content_table): 
    1829        self.revision_table = revision_table 
    1930        self.content_table = content_table 
     
    6778        return revisions 
    6879     
    69     def add_table(self, table, id_label=None, locale_column=None, 
     80    def add_table(self, table, id_label=None, localized=False, 
    7081                  join_alias=None): 
    7182        if id_label is None: 
    7283            id_label = '%s_revision_id' % table.name 
    7384         
    74          
    75  
    76         if isinstance(locale_column, basestring)
    77             locale_column = table.c[locale_column] 
    78  
     85        if localized: 
     86            locale_column = table.c[LOCALE_COLUMN] 
     87        else
     88            locale_column = None 
     89         
    7990        subselect = self.revision_subselect(table, locale_column, join_alias) 
    8091         
  • pagoda/trunk/Pagoda/pagoda/models/util.py

    r542 r551  
    3232        values[column_name] = getattr(instance, column_name, None) 
    3333    return values 
     34 
     35def get_foreign_tables(columns, foreign_key): 
     36    """ 
     37    Find the columns in `columns` that are a foreign key referencing 
     38    `foreign_key`, and return a `Set` of the `Table` objects in which they 
     39    are defined. 
     40 
     41    """ 
     42    foreign_tables = util.Set() 
     43    for column in filter_foreign_columns(columns, foreign_key): 
     44        column_table = get_column_table(column) 
     45        foreign_tables.add(column_table) 
     46    return foreign_tables 
     47 
     48def filter_columns(columns, predicate): 
     49    """ 
     50    Return a `Set` of columns from `columns` for which `predicate(column)` 
     51    is True. 
     52 
     53    """ 
     54    columns = util.Set() 
     55    for column in columns: 
     56        if predicate(column): 
     57            columns.add(column) 
     58    return columns 
     59 
     60def filter_foreign_columns(columns, foreign_key): 
     61    """ 
     62    Return a `Set` of columns from `columns` that are foreign keys 
     63    referencing `foreign_key`. 
     64 
     65    """ 
     66    return filter_columns( 
     67        columns, 
     68        lambda col: col.foreign_key and follow_foreign_key(col) is foreign_key 
     69    ) 
     70         
  • pagoda/trunk/Pagoda/pagoda/plugins/page/models.py

    r548 r551  
    22from sqlalchemy.ext.assignmapper import assign_mapper 
    33from turbogears.database import metadata, session 
    4 from pagoda.models import node_table, Content, Revision, Node 
     4from pagoda.models.node import node_generic_table, node_localized_table 
     5from pagoda.models import Content, Revision, Node 
    56from pagoda.models.revision_mapper import * 
    67 
    7 __all__ = ['page_generic_table', 'page_localized_table', 'Page'] 
     8__all__ = ['page_generic_table', 'page_table', 'Page'] 
    89 
    910page_generic_table = Table('page_generic', metadata, 
    1011    Column('revision_id', None, ForeignKey(Revision.c.revision_id), 
    1112        primary_key=True 
    12     ), 
    13     Column('nav_show', Boolean, nullable=False, default=True), 
     13    ) 
    1414) 
    1515 
    16 page_localized_table = Table('page_localized', metadata, 
    17     Column('revision_id', None, ForeignKey(Revision.c.revision_id), 
    18         primary_key=True 
    19     ), 
    20     Column('content_locale', String(8), nullable=False), 
    21     Column('title', Unicode(200), nullable=True), 
    22 
     16page_selectable = RevisionSelectable() 
     17page_selectable.add_table(node_generic_table, 'node_generic_revision_id') 
     18page_selectable.add_table(node_localized_table, 'node_localized_revision_id') 
     19page_selectable.add_table(page_generic_table, 'page_generic_revision_id') 
     20page_table = page_selectable.get_selectable('page') 
    2321 
    2422class Page(Node): 
    2523    pagoda_content_type = 'page' 
    2624 
    27 revision_builder = RevisionMapperBuilder(Page) 
    28 revision_builder.add_table(node_table) 
    29 revision_builder.add_table(page_generic_table, 'generic_revision_id') 
    30 revision_builder.add_table( 
    31     page_localized_table, 'localized_revision_id', 'content_locale' 
     25assign_mapper(session.context, Page, page_table, 
     26    select_table=page_table, 
     27    inherits=Node.mapper, 
     28    concrete=True, 
     29    extension=RevisionMapperExtension(), 
     30    polymorphic_on=page_table.c.content_type, 
     31    polymorphic_identity='page' 
    3232) 
    33 mapper_options = revision_builder.get_options() 
    34  
    35 assign_mapper(session.context, Page, **mapper_options) 
  • pagoda/trunk/Pagoda/pagoda/templates/admin/live.html

    r528 r551  
    1919 
    2020<div id="body"> 
    21     <iframe id="iframe" name="iframe" src="${tg.url('/content/live/%s/%s/' % (content.content_type, content.revision_id))}"></iframe> 
     21    <iframe id="iframe" name="iframe" src="${tg.url('/content/%s/%s/' % (content.content_type, content.revision_id))}"></iframe> 
    2222</div> 
    2323 
  • pagoda/trunk/TestProject/testproject/model.py

    r542 r551  
    5858        revision_author_id=brian.user_id, content_type='page', 
    5959        revision_status=workflow.PENDING, 
    60         revision_release_time=datetime(2007, 8, 20) 
     60        revision_release_time=datetime(2007, 9, 20) 
    6161    ) 
    6262     

Log in as guest/pagoda to create tickets