appy.gen: added new format 'captcha' for a String.
This commit is contained in:
parent
0d55abb239
commit
a80ef513ff
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
import re, time, copy, sys, types, os, os.path, mimetypes, string, StringIO
|
import re, time, copy, sys, types, os, os.path, mimetypes, string, StringIO, \
|
||||||
|
random
|
||||||
from appy import Object
|
from appy import Object
|
||||||
from appy.gen.layout import Table
|
from appy.gen.layout import Table
|
||||||
from appy.gen.layout import defaultFieldLayouts
|
from appy.gen.layout import defaultFieldLayouts
|
||||||
|
@ -1105,6 +1106,7 @@ class String(Type):
|
||||||
TEXT = 1
|
TEXT = 1
|
||||||
XHTML = 2
|
XHTML = 2
|
||||||
PASSWORD = 3
|
PASSWORD = 3
|
||||||
|
CAPTCHA = 4
|
||||||
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
||||||
default=None, optional=False, editDefault=False, format=LINE,
|
default=None, optional=False, editDefault=False, format=LINE,
|
||||||
show=True, page='main', group=None, layouts=None, move=0,
|
show=True, page='main', group=None, layouts=None, move=0,
|
||||||
|
@ -1115,7 +1117,9 @@ class String(Type):
|
||||||
transform='none', styles=('p','h1','h2','h3','h4'),
|
transform='none', styles=('p','h1','h2','h3','h4'),
|
||||||
allowImageUpload=True):
|
allowImageUpload=True):
|
||||||
# According to format, the widget will be different: input field,
|
# According to format, the widget will be different: input field,
|
||||||
# textarea, inline editor...
|
# textarea, inline editor... Note that there can be only one String
|
||||||
|
# field of format CAPTCHA by page, because the captcha challenge is
|
||||||
|
# stored in the session at some global key.
|
||||||
self.format = format
|
self.format = format
|
||||||
# When format is XHTML, the list of styles that the user will be able to
|
# When format is XHTML, the list of styles that the user will be able to
|
||||||
# select in the styles dropdown is defined hereafter.
|
# select in the styles dropdown is defined hereafter.
|
||||||
|
@ -1285,7 +1289,14 @@ class String(Type):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def validateValue(self, obj, value):
|
def validateValue(self, obj, value):
|
||||||
if not self.isSelect: return
|
if self.format == String.CAPTCHA:
|
||||||
|
challenge = obj.REQUEST.SESSION.get('captcha', None)
|
||||||
|
# Compute the challenge minus the char to remove
|
||||||
|
i = challenge['number']-1
|
||||||
|
text = challenge['text'][:i] + challenge['text'][i+1:]
|
||||||
|
if value != text:
|
||||||
|
return obj.translate('bad_captcha')
|
||||||
|
elif self.isSelect:
|
||||||
# Check that the value is among possible values
|
# Check that the value is among possible values
|
||||||
possibleValues = self.getPossibleValues(obj)
|
possibleValues = self.getPossibleValues(obj)
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, basestring):
|
||||||
|
@ -1348,6 +1359,26 @@ class String(Type):
|
||||||
if (layoutType == 'edit') and (self.format == String.XHTML):
|
if (layoutType == 'edit') and (self.format == String.XHTML):
|
||||||
return ('ckeditor/ckeditor.js',)
|
return ('ckeditor/ckeditor.js',)
|
||||||
|
|
||||||
|
def getCaptchaChallenge(self, session):
|
||||||
|
'''Returns a Captcha challenge in the form of a dict. At key "text",
|
||||||
|
value is a string that the user will be required to re-type, but
|
||||||
|
without 1 character whose position is at key "number". The challenge
|
||||||
|
is stored in the p_session, for the server-side subsequent check.'''
|
||||||
|
length = random.randint(5, 9) # The length of the challenge to encode
|
||||||
|
number = random.randint(1, length) # The position of the char to remove
|
||||||
|
text = '' # The challenge the user needs to type (minus one char)
|
||||||
|
for i in range(length):
|
||||||
|
j = random.randint(0, 1)
|
||||||
|
if j == 0:
|
||||||
|
chars = string.digits
|
||||||
|
else:
|
||||||
|
chars = string.letters
|
||||||
|
# Choose a char
|
||||||
|
text += chars[random.randint(0,len(chars)-1)]
|
||||||
|
res = {'text': text, 'number': number}
|
||||||
|
session['captcha'] = res
|
||||||
|
return res
|
||||||
|
|
||||||
class Boolean(Type):
|
class Boolean(Type):
|
||||||
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
||||||
default=None, optional=False, editDefault=False, show=True,
|
default=None, optional=False, editDefault=False, show=True,
|
||||||
|
@ -2636,14 +2667,17 @@ class No:
|
||||||
class WorkflowAnonymous:
|
class WorkflowAnonymous:
|
||||||
'''One-state workflow allowing anyone to consult and Manager to edit.'''
|
'''One-state workflow allowing anyone to consult and Manager to edit.'''
|
||||||
mgr = 'Manager'
|
mgr = 'Manager'
|
||||||
active = State({r:(mgr, 'Anonymous'), w:mgr, d:mgr}, initial=True)
|
o = 'Owner'
|
||||||
|
active = State({r:(mgr, 'Anonymous'), w:(mgr,o), d:(mgr,o)}, initial=True)
|
||||||
WorkflowAnonymous.__instance__ = WorkflowAnonymous()
|
WorkflowAnonymous.__instance__ = WorkflowAnonymous()
|
||||||
|
|
||||||
class WorkflowAuthenticated:
|
class WorkflowAuthenticated:
|
||||||
'''One-state workflow allowing authenticated users to consult and Manager
|
'''One-state workflow allowing authenticated users to consult and Manager
|
||||||
to edit.'''
|
to edit.'''
|
||||||
mgr = 'Manager'
|
mgr = 'Manager'
|
||||||
active = State({r:(mgr, 'Authenticated'), w:mgr, d:mgr}, initial=True)
|
o = 'Owner'
|
||||||
|
active = State({r:(mgr, 'Authenticated'), w:(mgr,o), d:(mgr,o)},
|
||||||
|
initial=True)
|
||||||
WorkflowAuthenticated.__instance__ = WorkflowAuthenticated()
|
WorkflowAuthenticated.__instance__ = WorkflowAuthenticated()
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -458,6 +458,8 @@ class ZopeGenerator(Generator):
|
||||||
msg('doc', '', msg.FORMAT_DOC),
|
msg('doc', '', msg.FORMAT_DOC),
|
||||||
msg('rtf', '', msg.FORMAT_RTF),
|
msg('rtf', '', msg.FORMAT_RTF),
|
||||||
msg('front_page_text', '', msg.FRONT_PAGE_TEXT),
|
msg('front_page_text', '', msg.FRONT_PAGE_TEXT),
|
||||||
|
msg('captcha_text', '', msg.CAPTCHA_TEXT),
|
||||||
|
msg('bad_captcha', '', msg.BAD_CAPTCHA),
|
||||||
]
|
]
|
||||||
# Create a label for every role added by this application
|
# Create a label for every role added by this application
|
||||||
for role in self.getAllUsedRoles():
|
for role in self.getAllUsedRoles():
|
||||||
|
|
|
@ -249,9 +249,11 @@ class ZopeInstaller:
|
||||||
except:
|
except:
|
||||||
# When Plone has installed PAS in acl_users this may fail. Plone
|
# When Plone has installed PAS in acl_users this may fail. Plone
|
||||||
# may still be in the way for migration purposes.
|
# may still be in the way for migration purposes.
|
||||||
users = ('admin') # We suppose there is at least a user.
|
users = ('admin',) # We suppose there is at least a user.
|
||||||
if not users:
|
if not users:
|
||||||
self.app.acl_users._doAddUser('admin', 'admin', ['Manager'], ())
|
appyTool.create('users', login='admin', firstName='admin',
|
||||||
|
name='admin', password1='admin', password2='admin',
|
||||||
|
email='admin@appyframework.org', roles=['Manager'])
|
||||||
appyTool.log('Admin user "admin" created.')
|
appyTool.log('Admin user "admin" created.')
|
||||||
|
|
||||||
# Create group "admins" if it does not exist
|
# Create group "admins" if it does not exist
|
||||||
|
|
|
@ -216,7 +216,7 @@ class Table(LayoutElement):
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
defaultPageLayouts = {
|
defaultPageLayouts = {
|
||||||
'view': Table('s|-n!-w|-b|', align="center"),
|
'view': Table('n!-w|-b|', align="center"),
|
||||||
'edit': Table('w|-b|', width=None)}
|
'edit': Table('w|-b|', width=None)}
|
||||||
defaultFieldLayouts = {'edit': 'lrv-f'}
|
defaultFieldLayouts = {'edit': 'lrv-f'}
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -938,14 +938,17 @@ class ToolMixin(BaseMixin):
|
||||||
return [f.__dict__ for f in self.getAllAppyTypes(contentType) \
|
return [f.__dict__ for f in self.getAllAppyTypes(contentType) \
|
||||||
if (f.type == 'Pod') and (f.show == 'result')]
|
if (f.type == 'Pod') and (f.show == 'result')]
|
||||||
|
|
||||||
def getUserLine(self, user):
|
def getUserLine(self):
|
||||||
'''Returns a one-line user info as shown on every page.'''
|
'''Returns a info about the currently logged user as a 2-tuple: first
|
||||||
res = [user.getId()]
|
elem is the one-line user info as shown on every page; second line is
|
||||||
rolesToShow = [r for r in user.getRoles() \
|
the URL to edit user info.'''
|
||||||
|
appyUser = self.appy().appyUser
|
||||||
|
res = [appyUser.title, appyUser.login]
|
||||||
|
rolesToShow = [r for r in appyUser.roles \
|
||||||
if r not in ('Authenticated', 'Member')]
|
if r not in ('Authenticated', 'Member')]
|
||||||
if rolesToShow:
|
if rolesToShow:
|
||||||
res.append(', '.join([self.translate(r) for r in rolesToShow]))
|
res.append(', '.join([self.translate(r) for r in rolesToShow]))
|
||||||
return ' | '.join(res)
|
return (' | '.join(res), appyUser.o.getUrl(mode='edit'))
|
||||||
|
|
||||||
def generateUid(self, className):
|
def generateUid(self, className):
|
||||||
'''Generates a UID for an instance of p_className.'''
|
'''Generates a UID for an instance of p_className.'''
|
||||||
|
|
|
@ -418,7 +418,7 @@ class BaseMixin:
|
||||||
return the result.'''
|
return the result.'''
|
||||||
page = self.REQUEST.get('page', 'main')
|
page = self.REQUEST.get('page', 'main')
|
||||||
for field in self.getAppyTypes('edit', page):
|
for field in self.getAppyTypes('edit', page):
|
||||||
if (field.type == 'String') and (field.format == 3):
|
if (field.type == 'String') and (field.format in (3,4)):
|
||||||
self.REQUEST.set(field.name, '')
|
self.REQUEST.set(field.name, '')
|
||||||
return self.ui.edit(self)
|
return self.ui.edit(self)
|
||||||
|
|
||||||
|
@ -1073,6 +1073,9 @@ class BaseMixin:
|
||||||
obj = self
|
obj = self
|
||||||
return appyType.getPossibleValues(obj, withTranslations, withBlankValue)
|
return appyType.getPossibleValues(obj, withTranslations, withBlankValue)
|
||||||
|
|
||||||
|
def getCaptchaChallenge(self, name):
|
||||||
|
return self.getAppyType(name).getCaptchaChallenge(self.REQUEST.SESSION)
|
||||||
|
|
||||||
def appy(self):
|
def appy(self):
|
||||||
'''Returns a wrapper object allowing to manipulate p_self the Appy
|
'''Returns a wrapper object allowing to manipulate p_self the Appy
|
||||||
way.'''
|
way.'''
|
||||||
|
|
|
@ -114,6 +114,10 @@ class PoMessage:
|
||||||
FORMAT_PDF = 'PDF'
|
FORMAT_PDF = 'PDF'
|
||||||
FORMAT_DOC = 'DOC'
|
FORMAT_DOC = 'DOC'
|
||||||
FORMAT_RTF = 'RTF'
|
FORMAT_RTF = 'RTF'
|
||||||
|
CAPTCHA_TEXT = 'Please type "${text}" (without the double quotes) in the ' \
|
||||||
|
'field besides, but without the character at position ' \
|
||||||
|
'${number}.'
|
||||||
|
BAD_CAPTCHA = 'The code was not correct. Please try again.'
|
||||||
|
|
||||||
def __init__(self, id, msg, default, fuzzy=False, comments=[],
|
def __init__(self, id, msg, default, fuzzy=False, comments=[],
|
||||||
niceDefault=False):
|
niceDefault=False):
|
||||||
|
|
|
@ -30,24 +30,24 @@
|
||||||
userMayAdd python: user.has_permission(addPermission, appFolder);
|
userMayAdd python: user.has_permission(addPermission, appFolder);
|
||||||
createMeans python: tool.getCreateMeans(rootClass)">
|
createMeans python: tool.getCreateMeans(rootClass)">
|
||||||
<tal:comment replace="nothing">Create a new object from a web form</tal:comment>
|
<tal:comment replace="nothing">Create a new object from a web form</tal:comment>
|
||||||
<img style="cursor:pointer"
|
<a tal:condition="python: ('form' in createMeans) and userMayAdd"
|
||||||
tal:condition="python: ('form' in createMeans) and userMayAdd"
|
tal:attributes="href python: '%s/do?action=Create&className=%s' % (toolUrl, rootClass);
|
||||||
tal:attributes="onClick python: 'href: window.location=\'%s/do?action=Create&className=%s\'' % (toolUrl, rootClass);
|
title python: _('query_create')">
|
||||||
src string: $appUrl/ui/plus.png;
|
<img tal:attributes="src string: $appUrl/ui/plus.png"/>
|
||||||
title python: _('query_create')"/>
|
</a>
|
||||||
<tal:comment replace="nothing">Create (a) new object(s) by importing data</tal:comment>
|
<tal:comment replace="nothing">Create (a) new object(s) by importing data</tal:comment>
|
||||||
<img style="cursor:pointer"
|
<a tal:condition="python: ('import' in createMeans) and userMayAdd"
|
||||||
tal:condition="python: ('import' in createMeans) and userMayAdd"
|
tal:attributes="href python: '%s/ui/import?className=%s' % (toolUrl, rootClass);
|
||||||
tal:attributes="onClick python: 'href: window.location=\'%s/ui/import?className=%s\'' % (toolUrl, rootClass);
|
title python: _('query_import')">
|
||||||
src string: $appUrl/ui/import.png;
|
<img tal:attributes="src string: $appUrl/ui/import.png"/>
|
||||||
title python: _('query_import')"/>
|
</a>
|
||||||
<tal:comment replace="nothing">Search objects of this type</tal:comment>
|
<tal:comment replace="nothing">Search objects of this type</tal:comment>
|
||||||
<img style="cursor:pointer"
|
<a tal:define="showSearch python: tool.getAttr('enableAdvancedSearchFor%s' % rootClass)"
|
||||||
tal:define="showSearch python: tool.getAttr('enableAdvancedSearchFor%s' % rootClass)"
|
|
||||||
tal:condition="showSearch"
|
tal:condition="showSearch"
|
||||||
tal:attributes="onClick python: 'href: window.location=\'%s/ui/search?className=%s\'' % (toolUrl, rootClass);
|
tal:attributes="href python: '%s/ui/search?className=%s' % (toolUrl, rootClass);
|
||||||
src string: $appUrl/ui/search.gif;
|
title python: _('search_objects')">
|
||||||
title python: _('search_objects')"/>
|
<img tal:attributes="src string: $appUrl/ui/search.gif"/>
|
||||||
|
</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -88,7 +88,8 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<tal:comment replace="nothing">The user login form for anonymous users</tal:comment>
|
<tal:comment replace="nothing">The user login form for anonymous users</tal:comment>
|
||||||
<table align="center" tal:condition="isAnon" class="login">
|
<table align="center" tal:condition="python: isAnon and ('/temp_folder/' not in req['ACTUAL_URL'])"
|
||||||
|
class="login">
|
||||||
<tr><td>
|
<tr><td>
|
||||||
<form name="loginform" method="post"
|
<form name="loginform" method="post"
|
||||||
tal:attributes="action python: tool.absolute_url() + '/performLogin'">
|
tal:attributes="action python: tool.absolute_url() + '/performLogin'">
|
||||||
|
@ -116,17 +117,23 @@
|
||||||
<img tal:attributes="src string: $appUrl/ui/home.gif"/>
|
<img tal:attributes="src string: $appUrl/ui/home.gif"/>
|
||||||
</a>
|
</a>
|
||||||
<!-- Config -->
|
<!-- Config -->
|
||||||
<img style="cursor:pointer" tal:condition="python: user.has_role('Manager')"
|
<a tal:condition="python: user.has_role('Manager')"
|
||||||
tal:attributes="onClick python: 'href: window.location=\'%s\'' % tool.getUrl(page='main', nav='');
|
tal:attributes="href python: tool.getUrl(page='main', nav='');
|
||||||
title python: _('%sTool' % appName);
|
title python: _('%sTool' % appName)">
|
||||||
src string:$appUrl/ui/appyConfig.gif"/>
|
<img tal:attributes="src string:$appUrl/ui/appyConfig.gif"/>
|
||||||
|
</a>
|
||||||
<!-- Logout -->
|
<!-- Logout -->
|
||||||
<a tal:attributes="href python: tool.absolute_url() + '/performLogout';
|
<a tal:attributes="href python: tool.absolute_url() + '/performLogout';
|
||||||
title python: _('logout')">
|
title python: _('logout')">
|
||||||
<img tal:attributes="src string: $appUrl/ui/logout.gif"/>
|
<img tal:attributes="src string: $appUrl/ui/logout.gif"/>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td align="right" tal:content="python: tool.getUserLine(user)"></td>
|
<td align="right" tal:define="userInfo tool/getUserLine">
|
||||||
|
<span tal:content="python: userInfo[0]"></span>
|
||||||
|
<a tal:attributes="href python: userInfo[1]">
|
||||||
|
<img tal:attributes="src string: $appUrl/ui/edit.gif"/>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
tal:define="fmt widget/format;
|
tal:define="fmt widget/format;
|
||||||
isSelect widget/isSelect;
|
isSelect widget/isSelect;
|
||||||
isMaster widget/slaves;
|
isMaster widget/slaves;
|
||||||
isOneLine python: fmt in (0,3);
|
isOneLine python: fmt in (0,3,4);
|
||||||
maxChars python: test(widget['maxChars'], widget['maxChars'], '')">
|
maxChars python: test(widget['maxChars'], widget['maxChars'], '')">
|
||||||
|
|
||||||
<tal:choice condition="isSelect">
|
<tal:choice condition="isSelect">
|
||||||
|
@ -49,6 +49,12 @@
|
||||||
value python: test(inRequest, requestValue, value);
|
value python: test(inRequest, requestValue, value);
|
||||||
style python: 'text-transform:%s' % widget['transform'];
|
style python: 'text-transform:%s' % widget['transform'];
|
||||||
type python: (widget['format'] == 3) and 'password' or 'text'"/>
|
type python: (widget['format'] == 3) and 'password' or 'text'"/>
|
||||||
|
<tal:comment replace="nothing">Display a captcha if required</tal:comment>
|
||||||
|
<tal:captcha condition="python: widget['format'] == 4">
|
||||||
|
<span tal:define="challenge python: contextObj.getCaptchaChallenge(name)"
|
||||||
|
tal:content="python: _('captcha_text', mapping=challenge)">
|
||||||
|
</span>
|
||||||
|
</tal:captcha>
|
||||||
</tal:line>
|
</tal:line>
|
||||||
<tal:textarea condition="python: fmt in (1,2)">
|
<tal:textarea condition="python: fmt in (1,2)">
|
||||||
<textarea tal:attributes="id name; name name;
|
<textarea tal:attributes="id name; name name;
|
||||||
|
|
|
@ -19,10 +19,11 @@ def createObject(folder, id, className, appName, wf=True):
|
||||||
obj.id = id
|
obj.id = id
|
||||||
obj._at_uid = id
|
obj._at_uid = id
|
||||||
userId = obj.getUser().getId()
|
userId = obj.getUser().getId()
|
||||||
obj.creator = userId
|
# If user is anonymous, userIs is None
|
||||||
|
obj.creator = userId or 'Anonymous User'
|
||||||
from DateTime import DateTime
|
from DateTime import DateTime
|
||||||
obj.created = DateTime()
|
obj.created = DateTime()
|
||||||
obj.__ac_local_roles__ = { userId: ['Owner'] }
|
obj.__ac_local_roles__ = { userId: ['Owner'] } # userId can be None (anon).
|
||||||
if wf: obj.notifyWorkflowCreated()
|
if wf: obj.notifyWorkflowCreated()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
|
@ -70,5 +70,9 @@ class GroupWrapper(AbstractWrapper):
|
||||||
self.log('User "%s" added to group "%s".' % \
|
self.log('User "%s" added to group "%s".' % \
|
||||||
(user.login, self.login))
|
(user.login, self.login))
|
||||||
if hasattr(self.o.aq_base, '_oldUsers'): del self.o._oldUsers
|
if hasattr(self.o.aq_base, '_oldUsers'): del self.o._oldUsers
|
||||||
|
# If the group was created by an Anonymous, Anonymous can't stay Owner
|
||||||
|
# of the object.
|
||||||
|
if None in self.o.__ac_local_roles__:
|
||||||
|
del self.o.__ac_local_roles__[None]
|
||||||
return self._callCustom('onEdit', created)
|
return self._callCustom('onEdit', created)
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -67,9 +67,13 @@ class UserWrapper(AbstractWrapper):
|
||||||
# Updates roles at the Zope level.
|
# Updates roles at the Zope level.
|
||||||
zopeUser = aclUsers.getUserById(login)
|
zopeUser = aclUsers.getUserById(login)
|
||||||
zopeUser.roles = self.roles
|
zopeUser.roles = self.roles
|
||||||
# "self" must be owned by its Zope user
|
# "self" must be owned by its Zope user.
|
||||||
if 'Owner' not in self.o.get_local_roles_for_userid(login):
|
if 'Owner' not in self.o.get_local_roles_for_userid(login):
|
||||||
self.o.manage_addLocalRoles(login, ('Owner',))
|
self.o.manage_addLocalRoles(login, ('Owner',))
|
||||||
|
# If the user was created by an Anonymous, Anonymous can't stay Owner
|
||||||
|
# of the object.
|
||||||
|
if None in self.o.__ac_local_roles__:
|
||||||
|
del self.o.__ac_local_roles__[None]
|
||||||
return self._callCustom('onEdit', created)
|
return self._callCustom('onEdit', created)
|
||||||
|
|
||||||
def getZopeUser(self):
|
def getZopeUser(self):
|
||||||
|
|
|
@ -56,7 +56,7 @@ class AbstractWrapper(object):
|
||||||
elif name == 'user':
|
elif name == 'user':
|
||||||
return self.o.getUser()
|
return self.o.getUser()
|
||||||
elif name == 'appyUser':
|
elif name == 'appyUser':
|
||||||
return self.search('User', login=self.o.getUser().getId())[0]
|
return self.search1('User', login=self.o.getUser().getId())
|
||||||
elif name == 'fields': return self.o.getAllAppyTypes()
|
elif name == 'fields': return self.o.getAllAppyTypes()
|
||||||
# Now, let's try to return a real attribute.
|
# Now, let's try to return a real attribute.
|
||||||
res = object.__getattribute__(self, name)
|
res = object.__getattribute__(self, name)
|
||||||
|
|
|
@ -198,6 +198,7 @@ class Converter:
|
||||||
# Loads the document to convert in a new hidden frame
|
# Loads the document to convert in a new hidden frame
|
||||||
prop = PropertyValue(); prop.Name = 'Hidden'; prop.Value = True
|
prop = PropertyValue(); prop.Name = 'Hidden'; prop.Value = True
|
||||||
if self.inputType == 'csv':
|
if self.inputType == 'csv':
|
||||||
|
# Give some additional params if we need to open a CSV file
|
||||||
prop2 = PropertyValue()
|
prop2 = PropertyValue()
|
||||||
prop2.Name = 'FilterFlags'
|
prop2.Name = 'FilterFlags'
|
||||||
prop2.Value = '59,34,76,1'
|
prop2.Value = '59,34,76,1'
|
||||||
|
@ -206,7 +207,6 @@ class Converter:
|
||||||
props = (prop, prop2)
|
props = (prop, prop2)
|
||||||
else:
|
else:
|
||||||
props = (prop,)
|
props = (prop,)
|
||||||
# Give some additional params if we need to open a CSV file
|
|
||||||
self.doc = self.oo.loadComponentFromURL(self.docUrl, "_blank", 0,
|
self.doc = self.oo.loadComponentFromURL(self.docUrl, "_blank", 0,
|
||||||
props)
|
props)
|
||||||
if self.inputType == 'odt':
|
if self.inputType == 'odt':
|
||||||
|
|
Loading…
Reference in a new issue