[gen] Added px.override allowing to modify PX code; bugfixes; added migration code for converting File instances to FileInfo instances.
This commit is contained in:
parent
be145be254
commit
c002b5cb59
8 changed files with 71 additions and 21 deletions
|
@ -40,6 +40,11 @@ from appy.fields.workflow import *
|
|||
from appy.gen.layout import Table
|
||||
from appy.gen.utils import No
|
||||
|
||||
# Make the following classes available here: people may need to monkey-patch
|
||||
# some PXs on thoses classes.
|
||||
from appy.gen.wrappers import AbstractWrapper as BaseObject
|
||||
from appy.gen.wrappers.ToolWrapper import ToolWrapper as BaseTool
|
||||
|
||||
class Import:
|
||||
'''Used for describing the place where to find the data to use for creating
|
||||
an object.'''
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import time
|
||||
from appy.fields.file import FileInfo
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
class Migrator:
|
||||
|
@ -11,13 +12,36 @@ class Migrator:
|
|||
self.app = installer.app
|
||||
self.tool = self.app.config.appy()
|
||||
|
||||
@staticmethod
|
||||
def migrateFileFields(obj):
|
||||
'''Ensures all file fields on p_obj are FileInfo instances.'''
|
||||
migrated = 0 # Count the number of migrated fields
|
||||
for field in obj.fields:
|
||||
if field.type != 'File': continue
|
||||
oldValue = getattr(obj, field.name)
|
||||
if oldValue and not isinstance(oldValue, FileInfo):
|
||||
# A legacy File object. Convert it to a FileInfo instance and
|
||||
# extract the binary to the filesystem.
|
||||
setattr(obj, field.name, oldValue)
|
||||
migrated += 1
|
||||
return migrated
|
||||
|
||||
def migrateTo_0_9_0(self):
|
||||
'''Migrates this DB to Appy 0.9.x.'''
|
||||
pass
|
||||
# Put all binaries to the filesystem
|
||||
tool = self.tool
|
||||
tool.log('Migrating file fields...')
|
||||
context = {'migrate': self.migrateFileFields, 'nb': 0}
|
||||
for className in tool.o.getAllClassNames():
|
||||
tool.compute(className, context=context, noSecurity=True,
|
||||
expression="ctx['nb'] += ctx['migrate'](obj)")
|
||||
tool.log('Migrated %d File field(s).' % context['nb'])
|
||||
|
||||
def run(self):
|
||||
def run(self, force=False):
|
||||
'''Executes a migration when relevant, or do it for sure if p_force is
|
||||
True.'''
|
||||
appyVersion = self.tool.appyVersion
|
||||
if not appyVersion or (appyVersion < '0.9.0'):
|
||||
if force or not appyVersion or (appyVersion < '0.9.0'):
|
||||
# Migration is required.
|
||||
startTime = time.time()
|
||||
self.migrateTo_0_9_0()
|
||||
|
|
|
@ -470,6 +470,11 @@ class ToolMixin(BaseMixin):
|
|||
if wrapper: return zopeClass.wrapperClass
|
||||
else: return zopeClass.wrapperClass.__bases__[-1]
|
||||
|
||||
def getAllClassNames(self):
|
||||
'''Returns the name of all classes within this app, including default
|
||||
Appy classes (Tool, Translation, Page, etc).'''
|
||||
return self.getProductConfig().allClassNames + [self.__class__.__name__]
|
||||
|
||||
def getCreateMeans(self, klass):
|
||||
'''Gets the different ways objects of p_klass can be created (via a web
|
||||
form, by importing external data, etc). Result is a dict whose keys
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
# ------------------------------------------------------------------------------
|
||||
import os.path, time
|
||||
import appy
|
||||
from appy.gen.mail import sendMail
|
||||
from appy.shared.utils import executeCommand
|
||||
from appy.gen.wrappers import AbstractWrapper
|
||||
from appy.px import Px
|
||||
|
||||
from appy.gen.mail import sendMail
|
||||
from appy.gen.wrappers import AbstractWrapper
|
||||
from appy.shared.utils import executeCommand
|
||||
# ------------------------------------------------------------------------------
|
||||
class ToolWrapper(AbstractWrapper):
|
||||
|
||||
|
@ -233,7 +232,7 @@ class ToolWrapper(AbstractWrapper):
|
|||
</x>
|
||||
|
||||
<!-- Predefined searches -->
|
||||
<x for="search in searchInfo.searches">
|
||||
<x for="search in searchInfo.searches" var2="field=search">
|
||||
<x if="search.type == 'group'">:search.px</x>
|
||||
<x if="search.type != 'group'">:search.pxView</x>
|
||||
</x>
|
||||
|
|
|
@ -123,7 +123,7 @@ class UserWrapper(AbstractWrapper):
|
|||
# Browse all objects of the database and update potential local roles
|
||||
# that referred to the old login.
|
||||
context = {'nb': 0, 'old': oldLogin, 'new': newLogin}
|
||||
for className in self.o.getProductConfig().allClassNames:
|
||||
for className in self.tool.o.getAllClassNames():
|
||||
self.compute(className, context=context, noSecurity=True,
|
||||
expression="ctx['nb'] += obj.o.applyUserIdChange(" \
|
||||
"ctx['old'], ctx['new'])")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue