|
/
Zope
/
gocept svn checkins
/
Archive
/
2008
/
2008-12
/
SVN: r7190 - in gocept.devtools/trunk: . gocept gocept/devtools
[
SVN: r7172 - in gocept.infrastructure/feature_syst... ]
[
SVN: r7193 - in gocept.infrastructure/feature_syst... ]
SVN: r7190 - in gocept.devtools/trunk: . gocept gocept/devtools
Christian Theune <ct(at)gocept.com> |
2008-12-07 14:15:55 |
[ FULL ]
|
Author: ctheune
Date: Sun Dec 7 14:15:53 2008
New Revision: 7190
Log:
Import code.
This package currently features a helper script to update our copyright
headers.
Added:
gocept.devtools/trunk/README.txt (contents, props changed)
gocept.devtools/trunk/bootstrap.py (contents, props changed)
gocept.devtools/trunk/buildout.cfg
gocept.devtools/trunk/gocept/
gocept.devtools/trunk/gocept/__init__.py (contents, props changed)
gocept.devtools/trunk/gocept/devtools/
gocept.devtools/trunk/gocept/devtools/__init__.py (contents, props
changed)
gocept.devtools/trunk/gocept/devtools/copyright.py (contents, props
changed)
gocept.devtools/trunk/setup.py (contents, props changed)
Modified:
gocept.devtools/trunk/ (props changed)
Added: gocept.devtools/trunk/README.txt
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/README.txt Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1,16 (at)(at)
+======================
+gocept developer tools
+======================
+
+This is a small collection of utilities to perform various minor code
+management tasks.
+
+Copyright fixing
+================
+
+The `fix-copyright` script can be used to update copyright headers of Python
+files for a given directory tree::
+
+ $ fix-copyright <pathname>
+
+It currently only applies to the gocept copyright headers.
Added: gocept.devtools/trunk/bootstrap.py
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/bootstrap.py Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1,77 (at)(at)
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 90478 2008-08-27 22:44:46Z georgyberdyshev $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+is_jython = sys.platform.startswith('java')
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+if sys.platform == 'win32':
+ def quote(c):
+ if ' ' in c:
+ return '"%s"' % c # work around spawn lamosity on windows
+ else:
+ return c
+else:
+ def quote (c):
+ return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws = pkg_resources.working_set
+
+if is_jython:
+ import subprocess
+
+ assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd',
+ quote(tmpeggs), 'zc.buildout'],
+ env=dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ).wait() == 0
+
+else:
+ assert os.spawnle(
+ os.P_WAIT, sys.executable, quote (sys.executable),
+ '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: gocept.devtools/trunk/buildout.cfg
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/buildout.cfg Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1,6 (at)(at)
+[buildout]
+develop = .
+parts = gocept.devtools
+
+[gocept.devtools]
+recipe = zc.recipe.egg
Added: gocept.devtools/trunk/gocept/__init__.py
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/gocept/__init__.py Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1,6 (at)(at)
+# namespace package boilerplate
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Added: gocept.devtools/trunk/gocept/devtools/__init__.py
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/gocept/devtools/__init__.py Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1 (at)(at)
+# Make this a Python package
Added: gocept.devtools/trunk/gocept/devtools/copyright.py
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/gocept/devtools/copyright.py Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1,65 (at)(at)
+#!/usr/bin/env python2.5
+# vim:fileencoding=utf-8
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+# TODO: support comma syntax (split 2003,2005-2006 correctly and re-append
+# without including 2004, don't always -CURRENTYEAR but eventually use , to
+# append the new year)
+
+import StringIO
+import datetime
+import os.path
+import re
+import sys
+
+TEMPLATE = '# Copyright (c) %s gocept gmbh & co. kg'
+TEMPLATE_PATTERN = re.compile('^# Copyright \(c\) ([0-9\-]+) gocept gmbh &
co. kg$')
+YEAR_PATTERN = re.compile('(19[0-9]{2}|20[0-9]{2})')
+
+
+def fix_file(filename):
+ file = open(filename, 'r').readlines()
+ output = StringIO.StringIO()
+ for line in file:
+ if not line.startswith('# Copyright'):
+ output.write(line)
+ continue
+ if not 'gocept' in line:
+ output.write(line)
+ continue
+ if line.endswith('\n'):
+ line = line[:-1]
+ trail = '\n'
+ else:
+ trail = ''
+ # This smells a lot like our copyright line. If this doesn't match our
+ # expression, bail out.
+ m = TEMPLATE_PATTERN.match(line)
+ if m is None:
+ raise ValueError('Weird copyright line', line)
+ # Find smallest year number
+ years = m.groups()[0].split('-')
+ years = [int(y) for y in years]
+ low = min(years)
+ max = datetime.date.today().year
+
+ if low == max:
+ signature = str(max)
+ else:
+ signature = '%s-%s' % (low, max)
+ line = TEMPLATE % signature
+ line = line + trail
+ output.write(line)
+ open(filename, 'w').write(output.getvalue())
+
+
+def visit(arg, dirname, names):
+ for name in names:
+ if name.endswith('.py'):
+ path = os.path.join(dirname, name)
+ print "Fixing", path
+ fix_file(path)
+
+def main():
+ os.path.walk(sys.argv[1], visit, None)
Added: gocept.devtools/trunk/setup.py
==============================================================================
--- (empty file)
+++ gocept.devtools/trunk/setup.py Sun Dec 7 14:15:53 2008
(at)(at) -0,0 +1,23 (at)(at)
+# vim:fileencoding=utf-8
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+
+from setuptools import setup, find_packages
+
+setup(
+ name='gocept.devtools',
+ version='0.1',
+ author='Christian Theune',
+ author_email='ct(at)gocept.com',
+ description='Small utilities for managing code.',
+ packages=find_packages('.'),
+ package_dir = {'': '.'},
+ include_package_data = True,
+ zip_safe=False,
+ license='ZPL',
+ namespace_packages=['gocept'],
+ entry_points="""
+ [console_scripts]
+ fix-copyright = gocept.devtools.copyright:main
+ """)
|
SVN: r7192 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-08 11:05:37 |
[ FULL ]
|
Author: sweh
Date: Mon Dec 8 11:05:36 2008
New Revision: 7192
Log:
refactor deleting of messages to use new imapapi api
add copying and moving of messages
Modified:
gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
gocept.restmail/trunk/gocept/restmail/browser/message.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml Mon Dec 8
11:05:36 2008
(at)(at) -204,6 +204,16 (at)(at)
name="delete"
attribute="delete"
/>
+
+ <browser:page
+ name="copy"
+ attribute="copy"
+ />
+
+ <browser:page
+ name="move"
+ attribute="move"
+ />
</browser:pages>
<browser:page
Modified: gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/message.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/message.py Mon Dec 8
11:05:36 2008
(at)(at) -69,9 +69,19 (at)(at)
(at)gocept.restmail.browser.json.view
def delete(self):
- message = self.context.message
- folder = message.parent
- folder.delete(message)
+ self.context.message.delete()
+ return {}
+
+ (at)gocept.restmail.browser.json.view
+ def copy(self, target):
+ """Copy message to target folder"""
+ self.context.message.copy(target)
+ return {}
+
+ (at)gocept.restmail.browser.json.view
+ def move(self, target):
+ """Move message to target folder"""
+ self.context.message.move(target)
return {}
|
SVN: r7194 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-08 15:19:46 |
[ FULL ]
|
Author: sweh
Date: Mon Dec 8 15:19:45 2008
New Revision: 7194
Log:
traverse for a folder with a given path
add copy and move view for messages
Modified:
gocept.restmail/trunk/gocept/restmail/browser/README.txt
gocept.restmail/trunk/gocept/restmail/browser/message.py
gocept.restmail/trunk/gocept/restmail/browser/traversal.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt Mon Dec 8
15:19:45 2008
(at)(at) -429,9 +429,18 (at)(at)
</body>
</html>
+
Deleting messages
-----------------
Messages can be deleted using the `(at)(at)delete` view.
XXX Test it when tests work again
+
+
+Copy and move messages
+----------------------
+
+Messages can be copied and moved using the `(at)(at)copy` and `(at)(at)move`
view.
+
+XXX Test it when tests work again
Modified: gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/message.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/message.py Mon Dec 8
15:19:45 2008
(at)(at) -13,6 +13,8 (at)(at)
import gocept.imapapi.interfaces
import gocept.restmail.interfaces
import gocept.restmail.browser.json
+import gocept.restmail.browser.traversal
+import gocept.restmail.interfaces
class MessageContainerWebAPI(object):
(at)(at) -73,15 +75,15 (at)(at)
return {}
(at)gocept.restmail.browser.json.view
- def copy(self, target):
+ def copy(self, folder_url):
"""Copy message to target folder"""
- self.context.message.copy(target)
+ self.context.message.copy(traverse(folder_url, self.context))
return {}
(at)gocept.restmail.browser.json.view
- def move(self, target):
+ def move(self, folder_url):
"""Move message to target folder"""
- self.context.message.move(target)
+ self.context.message.move(traverse(folder_url, self.context))
return {}
(at)(at) -194,3 +196,9 (at)(at)
def footer_pgp_signature(part):
"""Provide a footer representation for application/pgp-signature."""
return footer_pgp_signature_template()
+
+
+def traverse(url, context):
+ account = gocept.restmail.interfaces.IProfile(context)
+ return gocept.restmail.browser.traversal.traverse(
+ url, account, context.request)
Modified: gocept.restmail/trunk/gocept/restmail/browser/traversal.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/traversal.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/traversal.py Mon Dec 8
15:19:45 2008
(at)(at) -125,3 +125,15 (at)(at)
def account_url(context, request):
return zope.component.getMultiAdapter(
(context.aq_inner.aq_parent, request), name='absolute_url')
+
+
+def traverse(url, container, request):
+ """Traverse url and return the result.
+
+ Make sure the the object is inside the given container."""
+ container_url = zope.component.getMultiAdapter(
+ (container.aq_inner, request), name='absolute_url')() + '/'
+ if not url.startswith(container_url):
+ raise ValueError("The url doesn't point inside the given container.")
+ path = url[len(container_url):]
+ return container.restrictedTraverse(path)
|
SVN: r7197 - in gocept.restmail/trunk/gocept/restmail: . testmessages
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-08 15:53:26 |
[ FULL ]
|
Author: sweh
Date: Mon Dec 8 15:53:24 2008
New Revision: 7197
Log:
refactor broken tests, still more work to do
Added:
gocept.restmail/trunk/gocept/restmail/render.txt (contents, props changed)
- copied, changed from r7190,
gocept.restmail/trunk/gocept/restmail/draft.txt
gocept.restmail/trunk/gocept/restmail/testmessages/23-invalid-html
(contents, props changed)
- copied, changed from r7190,
gocept.restmail/trunk/gocept/restmail/testmessages/04-html
Modified:
gocept.restmail/trunk/gocept/restmail/draft.txt
gocept.restmail/trunk/gocept/restmail/tests.py
Modified: gocept.restmail/trunk/gocept/restmail/draft.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/draft.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/draft.txt Mon Dec 8 15:53:24 2008
(at)(at) -75,21 +75,14 (at)(at)
<07(at)example.org>
-
-# XXX From here on, part of the tests should be moved to a render.txt after
-# the refactoring.
-
-
Quoting the message body
========================
Converting the message parts
----------------------------
-In order to quote and display the complete message body, all parts must be
-converted into a displayable manner. That means, that all non-text parts
-(attachments, images, etc...) are substituted by a placeholder. All parts are
-then quoted with html.
+In order to quote and display the complete message body, displayable parts
must
+quoted using html. Attachments and images etc. are ignored.
For plain text and html messages, html is returned:
(at)(at) -127,7 +120,10 (at)(at)
</html>
Of multipart/alternative parts, only the most faithful one is chosen and
-quoted. Attachments are skipped and HTML is sanitized:
+quoted. Attachments are skipped and HTML is sanitized. Also, we drop anything
+that was contained in the HTML head. We think this is the right thing to do
+since normal mail clients should - in our opinion - write nothing semantically
+meaningful into the head, anyway.
>>> print get_html_text(messages[4])
<html>
(at)(at) -145,196 +141,19 (at)(at)
</html>
-Encoding
---------
-
-We have a number of messages in a mail folder named testmessages:
-
->>> print get_html_text(messages[0])
-<html>
-...I'm a message with no funny characters.
-...
-
-Correctly specified encoding works:
-
->>> print get_html_text(messages[1])
-<html>
-...I'm a message with some funny characters:[...]
|
SVN: r7224 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-09 14:23:04 |
[ FULL ]
|
Author: sweh
Date: Tue Dec 9 14:23:02 2008
New Revision: 7224
Log:
add a status flag to folder dict to differ between accounts and folders in YUI
Modified:
gocept.restmail/trunk/gocept/restmail/browser/folder.py
gocept.restmail/trunk/gocept/restmail/browser/profile.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/folder.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/folder.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/folder.py Tue Dec 9 14:23:02
2008
(at)(at) -17,6 +17,7 (at)(at)
url=zope.app.zapi.absoluteURL(folder, self.request),
children=len(folder.folders()),
name=folder.name,
+ type='inbox'
)
(at)gocept.restmail.browser.json.view
Modified: gocept.restmail/trunk/gocept/restmail/browser/profile.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/profile.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/profile.py Tue Dec 9
14:23:02 2008
(at)(at) -95,5 +95,6 (at)(at)
data.append(
{'url': zope.app.zapi.absoluteURL(account, self.request),
'children': children,
- 'name': identity.address})
+ 'name': identity.address,
+ 'type': 'account'})
return data
|
SVN: r7247 - gocept.collmex/trunk/src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-11 09:41:54 |
[ FULL ]
|
Author: wosc
Date: Thu Dec 11 09:41:52 2008
New Revision: 7247
Log:
implemented get_products and create_product
Modified:
gocept.collmex/trunk/src/gocept/collmex/README.txt
gocept.collmex/trunk/src/gocept/collmex/collmex.py
gocept.collmex/trunk/src/gocept/collmex/interfaces.py
gocept.collmex/trunk/src/gocept/collmex/model.py
gocept.collmex/trunk/src/gocept/collmex/testing.py
Modified: gocept.collmex/trunk/src/gocept/collmex/README.txt
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/README.txt (original)
+++ gocept.collmex/trunk/src/gocept/collmex/README.txt Thu Dec 11 09:41:52 2008
(at)(at) -63,6 +63,22 (at)(at)
>>> customer['Firma']
'Testkunden'
+Products: ``create_product`` and ``get_products``
+-------------------------------------------------
+
+Products are created using the ``create_product`` method:
+
+>>> product = gocept.collmex.model.Product()
+>>> product['Produktnummer'] = 'TEST'
+>>> product['Bezeichnung'] = 'Testprodukt'
+>>> product['Produktart'] = 0 # Ware
+>>> product['Verkaufs-Preis'] = 5
+>>> collmex.create_product(product)
+>>> import transaction
+>>> transaction.commit()
+>>> collmex.get_products()[0]['Bezeichnung']
+'Testprodukt'
+
Invoices: ``create_invoice`` and ``get_invoices``
-------------------------------------------------
(at)(at) -74,13 +90,11 (at)(at)
>>> item['Kunden-Nr'] = '10000'
>>> item['Rechnungsnummer'] = 100000
>>> item['Menge'] = 3
->>> item['Produktnummer'] = 'TRAFFIC'
+>>> item['Produktnummer'] = 'TEST'
>>> item['Rechnungstext'] = 'item text'
>>> item['Positionstyp'] = 0
>>> collmex.create_invoice([item])
-
-
Invoices can be looked up again, using the ``get_invoices`` method. However,
as
discussed above the invoice was only registered for addition. Querying right
now does *not* return the invoice:
(at)(at) -90,14 +104,11 (at)(at)
After committing, the invoice is found:
->>> import transaction
>>> transaction.commit()
>>> collmex.get_invoices(customer_id='10000',
... start_date=start_date)[0]['Rechnungstext']
'item text'
-
-
.. [#pre-flight-cleanup] First we need to clean up the Collmex environment:
>>> import gocept.collmex.testing
Modified: gocept.collmex/trunk/src/gocept/collmex/collmex.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/collmex.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/collmex.py Thu Dec 11 09:41:52 2008
(at)(at) -97,6 +97,7 (at)(at)
model_factory = {
'CMXINV': gocept.collmex.model.InvoiceItem,
'CMXKND': gocept.collmex.model.Customer,
+ 'CMXPRD': gocept.collmex.model.Product,
}
def __init__(self, customer_id, company_id, username, password):
(at)(at) -123,6 +124,13 (at)(at)
writer.writerow(list(item))
self.connection.register_data(data.getvalue())
+ def create_product(self, product):
+ data = StringIO.StringIO()
+ writer = csv.writer(data, dialect=CollmexDialect)
+ product['Firma'] = self.company_id
+ writer.writerow(list(product))
+ self.connection.register_data(data.getvalue())
+
def get_invoices(self, invoice_id=NULL, customer_id=NULL,
start_date=NULL, end_date=NULL):
return self._query_objects(
(at)(at) -144,6 +152,16 (at)(at)
0, self.NULL, self.NULL, self.NULL, self.NULL, self.NULL,
0, self.system_identifier)
+ def get_products(self, product_id=NULL,
+ product_group=NULL, price_group=NULL):
+ return self._query_objects(
+ 'PRODUCT_GET',
+ self.company_id,
+ product_id,
+ product_group,
+ price_group,
+ 0, self.system_identifier)
+
def _query_objects(self, function, *args):
data = StringIO.StringIO()
writer = csv.writer(data, dialect=CollmexDialect)
(at)(at) -158,8 +176,6 (at)(at)
result.append(factory(line))
return result
-
-
def _post(self, data):
data = 'LOGIN;%s;%s\n' % (self.username, self.password) + data
log.debug(data)
Modified: gocept.collmex/trunk/src/gocept/collmex/interfaces.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/interfaces.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/interfaces.py Thu Dec 11 09:41:52
2008
(at)(at) -14,6 +14,9 (at)(at)
def create_invoice(items):
"""Creates an invoice consisting of the given IInvoiceItems."""
+ def create_product(product):
+ """Creates a product for the given IProduct."""
+
def get_invoices(invoice_id=NULL, customer_id=NULL,
start_date=NULL, end_date=NULL):
"""Returns a list of IInvoiceItems maching given criteria."""
(at)(at) -21,6 +24,8 (at)(at)
def get_customers(customer_id=NULL, text=NULL):
"""Returns a list of ICustomers matching given criteria."""
+ def get_products(product_id=NULL, product_group=NULL, price_group=NULL):
+ """Returns a list of IProducts matching given criteria."""
class IModel(zope.interface.common.mapping.IFullMapping):
(at)(at) -38,8 +43,12 (at)(at)
class IInvoiceItem(IModel):
- """An invoice item from Collmex CMXINV"""
+ """An invoice item (CMXINV)"""
class ICustomer(IModel):
- """A customer CMXKND."""
+ """A customer (CMXKND)."""
+
+
+class IProduct(IModel):
+ """A product (CMXPRD)."""
Modified: gocept.collmex/trunk/src/gocept/collmex/model.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/model.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/model.py Thu Dec 11 09:41:52 2008
(at)(at) -23,7 +23,6 (at)(at)
self[self.fields[i]] = row[i]
def __iter__(self):
- result = []
for field in self.fields:
if field in self:
value = self[field]
(at)(at) -169,3 +168,38 (at)(at)
'Vermittler',
'Kostenstelle',
)
+
+
+class Product(Model):
+
+ zope.interface.implements(gocept.collmex.interfaces.IProduct)
+
+ satzart = 'CMXPRD'
+ fields = (
+ 'Satzart',
+ 'Produktnummer',
+ 'Bezeichnung',
+ 'Bezeichnung Eng',
+ 'Basismengeneinheit',
+ 'Produktgruppe',
+ 'Firma',
+ 'Steuerklassifikation',
+ 'Gewicht',
+ 'Gewicht Mengeneinheit',
+ 'Preismenge',
+ 'Produktart',
+ 'Inaktiv',
+ 'Preisgruppe',
+ 'Verkaufs-Preis',
+ 'EAN',
+ 'Hersteller',
+ 'Versandgruppe',
+ 'Mindestbestand',
+ 'Bestellmenge',
+ 'Chargenpflicht',
+ 'Beschaffungsart',
+ 'Produktionsdauer',
+ 'Lohnkosten',
+ 'Lohnkosten-Bezugsmenge',
+ 'Reserviert',
+ )
Modified: gocept.collmex/trunk/src/gocept/collmex/testing.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/testing.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/testing.py Thu Dec 11 09:41:52 2008
(at)(at) -40,18 +40,5 (at)(at)
b.getControl('Firma').value = 'Testkunden'
b.getControl('Speichern').click()
- # Beispielprodukt anlegen
- b.getLink('Warenwirtschaft').click()
- add_link = b.getLink(u'Anlegen', index=4)
- assert add_link.url.endswith('prcr')
- add_link.click() # XXX Magic number
- b.getControl('Produkt', index=1).value = 'TRAFFIC'
- b.getControl('Produkt anlegen').click()
- b.getControl('Bezeichnung').value = 'Testprodukt'
- b.getControl('Speichern').click()
- b.getLink('Verkauf', index=1).click()
- b.getControl(name='preis_1_preis').value = '5,00'
- b.getControl('Speichern').click()
-
# Explicitly close response to not leave open http objects.
b.mech_browser._response.close()
|
SVN: r7248 - gocept.collmex/trunk/src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-11 09:45:44 |
[ FULL ]
|
Author: wosc
Date: Thu Dec 11 09:45:42 2008
New Revision: 7248
Log:
implemented create_customer
Modified:
gocept.collmex/trunk/src/gocept/collmex/README.txt
gocept.collmex/trunk/src/gocept/collmex/collmex.py
gocept.collmex/trunk/src/gocept/collmex/testing.py
Modified: gocept.collmex/trunk/src/gocept/collmex/README.txt
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/README.txt (original)
+++ gocept.collmex/trunk/src/gocept/collmex/README.txt Thu Dec 11 09:45:42 2008
(at)(at) -28,10 +28,17 (at)(at)
[#pre-flight-cleanup]_ [#invalid-login]_
+>>> import transaction
+
+Customers: ``create_customer`` and ``get_customers``
+----------------------------------------------------
-Customers: ``get_customers``
-----------------------------
+>>> customer = gocept.collmex.model.Customer()
+>>> customer['Kundennummer'] = 10000
+>>> customer['Firma'] = 'Testkunden'
+>>> collmex.create_customer(customer)
+>>> transaction.commit()
Customers can be listed using the get_customers method:
(at)(at) -74,7 +81,6 (at)(at)
>>> product['Produktart'] = 0 # Ware
>>> product['Verkaufs-Preis'] = 5
>>> collmex.create_product(product)
->>> import transaction
>>> transaction.commit()
>>> collmex.get_products()[0]['Bezeichnung']
'Testprodukt'
Modified: gocept.collmex/trunk/src/gocept/collmex/collmex.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/collmex.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/collmex.py Thu Dec 11 09:45:42 2008
(at)(at) -131,6 +131,13 (at)(at)
writer.writerow(list(product))
self.connection.register_data(data.getvalue())
+ def create_customer(self, customer):
+ data = StringIO.StringIO()
+ writer = csv.writer(data, dialect=CollmexDialect)
+ customer['Firma Nr'] = self.company_id
+ writer.writerow(list(customer))
+ self.connection.register_data(data.getvalue())
+
def get_invoices(self, invoice_id=NULL, customer_id=NULL,
start_date=NULL, end_date=NULL):
return self._query_objects(
Modified: gocept.collmex/trunk/src/gocept/collmex/testing.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/testing.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/testing.py Thu Dec 11 09:45:42 2008
(at)(at) -29,16 +29,5 (at)(at)
assert 'Daten erfolgreich gel' in b.contents
- # Beispielkunden anlegen
- b.getLink('Warenwirtschaft').click()
- add_link = b.getLink(u'Anzeigen und ändern', index=2)
- assert add_link.url.endswith('cu')
- add_link.click() # XXX Magic number
- b.getLink('Anlegen').click()
- b.getControl('Kunde Nr', index=0).value = '10000'
- b.getControl('Kunde anlegen').click()
- b.getControl('Firma').value = 'Testkunden'
- b.getControl('Speichern').click()
-
# Explicitly close response to not leave open http objects.
b.mech_browser._response.close()
|
SVN: r7253 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-11 10:49:11 |
[ FULL ]
|
Author: sweh
Date: Thu Dec 11 10:49:10 2008
New Revision: 7253
Log:
list accounts even if one account is failing (bug #4569)
Modified:
gocept.restmail/trunk/gocept/restmail/browser/profile.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/profile.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/profile.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/profile.py Thu Dec 11
10:49:10 2008
(at)(at) -88,7 +88,7 (at)(at)
# (e.g. because of a wrong configuration). Available accounts
# should be listet although.
children = len(account.folders())
- except socket.gaierror:
+ except:
# XXX Log an error for the user
children = 0
identity = gocept.restmail.interfaces.IIdentity(account)
|
SVN: r7257 - in gocept.restmail/trunk/gocept/restmail: . browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-11 12:48:28 |
[ FULL ]
|
Author: sweh
Date: Thu Dec 11 12:48:27 2008
New Revision: 7257
Log:
deletion of draft messages (bug #4608)
Modified:
gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
gocept.restmail/trunk/gocept/restmail/browser/draft.py
gocept.restmail/trunk/gocept/restmail/draft.py
gocept.restmail/trunk/gocept/restmail/draft.txt
Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml Thu Dec 11
12:48:27 2008
(at)(at) -244,6 +244,11 (at)(at)
attribute="send"
/>
+ <browser:page
+ name="delete"
+ attribute="delete"
+ />
+
</browser:pages>
<browser:page
Modified: gocept.restmail/trunk/gocept/restmail/browser/draft.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/draft.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/draft.py Thu Dec 11 12:48:27
2008
(at)(at) -12,7 +12,7 (at)(at)
class WebAPI(object):
- """Web API for accounts."""
+ """Web API for drafts."""
(at)gocept.restmail.browser.json.view
def data(self):
(at)(at) -44,6 +44,10 (at)(at)
"""Update draft and send this message."""
self.context.send()
+ def delete(self):
+ """Delete draft."""
+ self.context.delete()
+
draft_header_template = gocept.restmail.browser.message.template(
'draft_snippet_header.pt')
Modified: gocept.restmail/trunk/gocept/restmail/draft.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/draft.py (original)
+++ gocept.restmail/trunk/gocept/restmail/draft.py Thu Dec 11 12:48:27 2008
(at)(at) -94,9 +94,13 (at)(at)
sent.append(message)
# 4. Delete draft
+ self.delete()
+
+ def delete(self):
self.aq_inner.getParentNode().manage_delObjects([self.getId()])
+
def new_draft(container, message=None):
id = str(uuid.uuid1())
while id in container.objectIds():
Modified: gocept.restmail/trunk/gocept/restmail/draft.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/draft.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/draft.txt Thu Dec 11 12:48:27 2008
(at)(at) -74,6 +74,14 (at)(at)
>>> print reply.references
<07(at)example.org>
+To delete a draft, simply call its delete method:
+
+>>> len(reply.aq_inner.getParentNode().objectValues())
+5
+>>> reply.delete()
+>>> len(reply.aq_inner.getParentNode().objectValues())
+4
+
Quoting the message body
========================
|
SVN: r7263 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-12 09:11:18 |
[ FULL ]
|
Author: sweh
Date: Fri Dec 12 09:11:16 2008
New Revision: 7263
Log:
fix tests
Modified:
gocept.restmail/trunk/gocept/restmail/browser/README.txt
Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt Fri Dec 12
09:11:16 2008
(at)(at) -283,6 +283,7 (at)(at)
>>> browser.open(message['structure']['url'])
>>> print browser.headers
Status: 200 OK
+Content-Disposition: attachment
Content-Length: 17
Content-Type: text/plain; charset=utf-8
>>> print browser.contents
|
SVN: r7264 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-12 09:40:05 |
[ FULL ]
|
Author: sweh
Date: Fri Dec 12 09:40:04 2008
New Revision: 7264
Log:
readd ZMI view for messages
Modified:
gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
gocept.restmail/trunk/gocept/restmail/browser/message.py
gocept.restmail/trunk/gocept/restmail/browser/zmi.txt
Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml Fri Dec 12
09:40:04 2008
(at)(at) -51,7 +51,6 (at)(at)
permission="zope2.View"
/>
- <!--
<browser:pages
for="gocept.imapapi.interfaces.IMessage"
class=".message.Message"
(at)(at) -76,7 +75,7 (at)(at)
name="manage_showParts"
template="show_parts.pt"
/>
- </browser:pages> -->
+ </browser:pages>
<!-- Publisher support for non-Zope objects -->
<adapter
Modified: gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/message.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/message.py Fri Dec 12
09:40:04 2008
(at)(at) -97,6 +97,25 (at)(at)
body=self.context.fetch(),
)
+class Message(object):
+ """View helper for messages."""
+
+ def list_parts(self):
+ """Create a flat list of all parts."""
+ stack = [self.context.aq_inner.body()]
+ while stack:
+ part = stack.pop(0)
+ yield part
+ if part['content_type'].startswith('multipart/'):
+ stack = part.parts() + stack
+
+ def body(self):
+ """Select a body part, decode it and prepare for embedding."""
+ rendered_message = gocept.restmail.interfaces.IRenderedMessage(
+ self.context.aq_inner)
+ rendered_message.annotate()
+ return IBody(rendered_message)
+
class IHeader(zope.interface.Interface):
"""A representation of a message's headers."""
Modified: gocept.restmail/trunk/gocept/restmail/browser/zmi.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/zmi.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/zmi.txt Fri Dec 12 09:40:04
2008
(at)(at) -147,9 +147,10 (at)(at)
</dl>
<BLANKLINE>
<div class="location-bar"
- style="border:1px solid grey; padding:0.5em;"><div
class="messagebody">
- <pre>Everything is ok!</pre>
- </div>
+ style="border:1px solid grey; padding:0.5em;"><div
class="messagepart">
+ <div><pre>Everything is ok!
+</pre></div>
+ <div><div class="footer">
</div>
...
|
SVN: r7265 - in gocept.restmail/trunk: . gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-12 10:29:48 |
[ FULL ]
|
Author: sweh
Date: Fri Dec 12 10:29:45 2008
New Revision: 7265
Log:
fix restmail inline tests (now all tests of the restmail package are fixed)
pin lxml to 2.1 because of a bug in the newest version 2.2alpha2
Modified:
gocept.restmail/trunk/gocept/restmail/browser/inline.txt
gocept.restmail/trunk/setup.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/inline.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/inline.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/inline.txt Fri Dec 12
10:29:45 2008
(at)(at) -27,7 +27,6 (at)(at)
>>> folder = 'http://localhost/profile/ben-example.com/+Testmessages'
-
Various combined messages
=========================
(at)(at) -36,7 +35,8 (at)(at)
>>> r = render_message(folder, '09 - AppleMail, Simple HTML with
image')
>>> print r['header']
-<dl>
+<div class="header">
+ <dl>
<dt>Subject:</dt>
<dd>09 - AppleMail, Simple HTML with image</dd>
<dt>From:</dt>
(at)(at) -45,20 +45,27 (at)(at)
<dd>Christian Theune <ct(at)gocept.com></dd>
<dt>Date:</dt>
<dd>Fri, 21 Nov 2008 10:42:12 +0100</dd>
-</dl>
+ </dl>
+</div>
>>> print r['body']
-<div class="messagebody"><div>Daa <font
class="Apple-style-span" color="#FF3728">dudel</font>
dö<img height="240" width="324" src="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/2"><div><br></div><div><br></div><div><font
class="Apple-style-span">blasdjf </font><br><div>
<div><div><div>-- </div><div>Christian
Zagrodnick ·
<a>cz(at)gocept.com</a></div><div>gocept gmbh &
co. kg · forsterstraße 29 · 06112 halle (saale)
· germany</div><div><a>http://gocept.com</a> ·
tel +49 345 1229889 0 · fax +49 345 1229889
1</div><div>Zope and Plone consulting and
development</div><br></div></div><br></div><br></div></div></div>
+<div class="messagepart">
+ <div><div>Daa <font class="Apple-style-span"
color="#FF3728">dudel</font> dö<img height="240"
width="324"
src="cid:50CDC34E-4963-4E84-9CD2-69F2BE4E4BA6"><div><br></div><div><br></div><div><font
class="Apple-style-span">blasdjf </font><br><div>
<div><div><div>-- </div><div>Christian
Zagrodnick · <a
href="mailto:cz(at)gocept.com">cz(at)gocept.com</a></div><div>gocept
gmbh & co. kg · forsterstraße 29 · 06112
halle (saale) · germany</div><div><a href="http://gocept.com">http://gocept.com</a> ·
tel +49 345 1229889 0 · fax +49 345 1229889
1</div><div>Zope and Plone consulting and
development</div><br></div></div><br></div><br></div></div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
->>> print r['attachments']
- <div class="messagebody">
- <h3>Attachments</h3>
- <ul>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/2">DSC03090.jpg</a>
(<span>image/jpeg</span> <span>213680</span>)
- </li>
- </ul>
- </div>
+>>> print r['footer']
+<div class="footer">
+ <div class="footercomponent"><h6>Attachments</h6>
+<ul>
+ <li>
+ <a href="#">DSC03090.jpg</a>
(<span>image/jpeg</span> <span>213680</span>)
+ </li>
+</ul>
+</div>
+</div>
Claws, Signed, Text attachment
(at)(at) -66,7 +73,8 (at)(at)
>>> r = render_message(folder, '10 - Claws, Signed, Text attachment')
>>> print r['header']
-<dl>
+<div class="header">
+ <dl>
<dt>Subject:</dt>
<dd>10 - Claws, Signed, Text attachment</dd>
<dt>From:</dt>
(at)(at) -75,36 +83,40 (at)(at)
<dd>ct(at)gocept.com</dd>
<dt>Date:</dt>
<dd>Fri, 21 Nov 2008 10:43:38 +0100</dd>
-</dl>
+ </dl>
+</div>
>>> print r['body'].encode('utf-8')
-<div class="messagebody">
- <pre>Moin.
+<div class="messagepart">
+ <div><pre>Moin.
Zagy sagt, ich soll Dir eine Mail mit Anhang schicken.
-Viele Grüße,
+Viele Grüße,
Thomas
--
-Thomas Lotze · tl(at)gocept.com
-gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) ·
germany
-http://gocept.com · tel +49 345 1229889 0 ·
fax +49 345 1229889 1
+Thomas Lotze · tl(at)gocept.com
+gocept gmbh & co. kg · forsterstraße 29 ·
06112 halle (saale) · germany
+http://gocept.com · tel +49 345
1229889 0 · fax +49 345 1229889 1
Zope and Plone consulting and development
-</pre>
+</pre></div>
+ <div><div class="footer">
+</div>
</div>
-<div class="messagebody signature-untrusted">
- <p>This message was digitally signed. The signature has <b>not
been
- verified</b>.
- </p>
</div>
->>> print r['attachments']
- <div class="messagebody">
- <h3>Attachments</h3>
- <ul>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/1/2">ez_setup.py</a>
(<span>text/x-python</span> <span>8509</span>)
- </li>
- </ul>
- </div>
+>>> print r['footer']
+<div class="footer">
+ <div class="footercomponent"><h6>Attachments</h6>
+<BLANKLINE>
+<ul>
+ <li>
+ <a href="#">ez_setup.py</a>
(<span>text/x-python</span> <span>8509</span>)
+ </li>
+ <li>
+ <a href="#">signature.asc</a>
(<span>application/pgp-signature</span>
<span>196</span>)
+ </li>
+</ul>
+</div>
+</div>
AppleMail, Complex HTML with many images
(at)(at) -112,7 +124,8 (at)(at)
>>> r = render_message(folder, '11 - AppleMail, Complex HTML with
many images')
>>> print r['header']
-<dl>
+<div class="header">
+ <dl>
<dt>Subject:</dt>
<dd>11 - AppleMail, Complex HTML with many images</dd>
<dt>From:</dt>
(at)(at) -121,52 +134,59 (at)(at)
<dd>Christian Theune <ct(at)gocept.com></dd>
<dt>Date:</dt>
<dd>Fri, 21 Nov 2008 10:44:57 +0100</dd>
-</dl>
+ </dl>
+</div>
>>> print r['body']
-<div class="messagebody"><div>
+<div class="messagepart">
+ <div><div>
<div>
<table width="753" class="email-body-wrap" id="email-body" align="center"
cellspacing="0" cellpadding="0" border="0"><tbody><tr><td
width="45" rowspan="2"> </td>
- <td width="663"><img width="663" height="148" alt="" src="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/2"></td>
- <td width="45" rowspan="2"> </td>
- </tr><tr><td width="663"><table width="663"
height="289" border="0" cellpadding="0"
cellspacing="0"><tbody><tr><td
width="105"> </td>
- <td width="548"><font color="#4a4533">
- <div class="AppleResizingDiv"><div>
<div><div><div>das ist bestimmt der totale hass für
jeden mailer
*GG</div><div><br></div><div>-- </div><div>Christian
Zagrodnick ·
<a>cz(at)gocept.com</a></div><div>gocept gmbh &
co. kg · forsterstraße 29 · 06112 halle (saale)
· germany</div><div><a>http://gocept.com</a> ·
tel +49 345 1229889 0 · fax +49 345 1229889
1</div><div>Zope and Plone consulting and
development</div><br></div></div><br></div></div>
- </font></td>
- <td width="100"> </td>
- </tr></tbody></table></td>
- </tr><tr><td width="753" colspan="3"><img width="753"
height="262" src="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/3"></td>
- </tr><tr><td width="753" colspan="3"><img width="753"
height="57" alt="" src="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/4"></td>
- </tr></tbody></table></div>
+ <td width="663"><img width="663" height="148" alt=""
src="cid:919A8163-52C0-4CE3-B45C-F05A1AE2FC3D/top.jpg"></td>
+ <td width="45" rowspan="2"> </td>
+ </tr><tr><td width="663"><table width="663" height="289"
border="0" cellpadding="0" cellspacing="0"><tbody><tr><td
width="105"> </td>
+ <td width="548"><font color="#4a4533">
+ <div class="AppleResizingDiv"><div>
<div><div><div>das ist bestimmt der totale hass für
jeden mailer
*GG</div><div><br></div><div>-- </div><div>Christian
Zagrodnick · <a
href="mailto:cz(at)gocept.com">cz(at)gocept.com</a></div><div>gocept
gmbh & co. kg · forsterstraße 29 · 06112
halle (saale) · germany</div><div><a href="http://gocept.com">http://gocept.com</a> ·
tel +49 345 1229889 0 · fax +49 345 1229889
1</div><div>Zope and Plone consulting and
development</div><br></div></div><br></div></div>
+ </font></td>
+ <td width="100"> </td>
+ </tr></tbody></table></td>
+ </tr><tr><td width="753" colspan="3"><img width="753"
height="262"
src="cid:919A8163-52C0-4CE3-B45C-F05A1AE2FC3D/2/Photos"></td>
+ </tr><tr><td width="753" colspan="3"><img width="753"
height="57" alt=""
src="cid:919A8163-52C0-4CE3-B45C-F05A1AE2FC3D/bottom.jpg"></td>
+ </tr></tbody></table></div>
</div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
->>> print r['attachments']
- <div class="messagebody">
- <h3>Attachments</h3>
- <ul>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/2">top.jpg</a>
(<span>image/jpeg</span> <span>27412</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/3">Photos.png</a>
(<span>image/png</span> <span>457106</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/4">bottom.jpg</a>
(<span>image/jpeg</span> <span>19046</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/5">bg_pattern.jpg</a>
(<span>image/jpeg</span> <span>103782</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/6">lbg.jpg</a>
(<span>image/jpeg</span> <span>9756</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/7">rbg.jpg</a>
(<span>image/jpeg</span> <span>9816</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2/8">bg_letter.jpg</a>
(<span>image/jpeg</span> <span>36484</span>)
- </li>
- </ul>
- </div>
+>>> print r['footer']
+<div class="footer">
+ <div class="footercomponent"><h6>Attachments</h6>
+<ul>
+ <li>
+ <a href="#">top.jpg</a> (<span>image/jpeg</span>
<span>27412</span>)
+ </li>
+ <li>
+ <a href="#">Photos.png</a> (<span>image/png</span>
<span>457106</span>)
+ </li>
+ <li>
+ <a href="#">bottom.jpg</a>
(<span>image/jpeg</span> <span>19046</span>)
+ </li>
+ <li>
+ <a href="#">bg_pattern.jpg</a>
(<span>image/jpeg</span> <span>103782</span>)
+ </li>
+ <li>
+ <a href="#">lbg.jpg</a> (<span>image/jpeg</span>
<span>9756</span>)
+ </li>
+ <li>
+ <a href="#">rbg.jpg</a> (<span>image/jpeg</span>
<span>9816</span>)
+ </li>
+ <li>
+ <a href="#">bg_letter.jpg</a>
(<span>image/jpeg</span> <span>36484</span>)
+ </li>
+</ul>
+</div>
+</div>
Evolution, multipart/mixed, inline image, gzip attachment
(at)(at) -177,7 +197,8 (at)(at)
>>> r = render_message(folder, '12 - Evolution, multipart/mixed,
inline image, gzip attachment')
>>> print r['header']
-<dl>
+<div class="header">
+ <dl>
<dt>Subject:</dt>
<dd>12 - Evolution, multipart/mixed, inline image, gzip
attachment</dd>
<dt>From:</dt>
(at)(at) -186,34 +207,42 (at)(at)
<dd>ct(at)gocept.com</dd>
<dt>Date:</dt>
<dd>Fri, 21 Nov 2008 12:10:38 +0100</dd>
-</dl>
+ </dl>
+</div>
>>> print r['body']
-<div class="messagebody"><div>
-Ich habe hier noch ein Bild beigefuegt.<br><img src="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/1/2"
align="bottom" border="0"><br><br>
+<div class="messagepart">
+ <div><div>
+Ich habe hier noch ein Bild beigefuegt.<br><img
src="cid:1227265836.18594.12.camel(at)mindy" align="bottom"
border="0"><br><br>
Viel Spass<br><br><table cellspacing="0" cellpadding="0"
width="100%"><tr><td>
<pre>
--
-Christian Theune · <a>ct(at)gocept.com</a>
+Christian Theune · <a
href="mailto:ct(at)gocept.com">ct(at)gocept.com</a>
gocept gmbh & co. kg · forsterstraße 29 ·
06112 halle (saale) · germany
-<a>http://gocept.com</a> ·
tel +49 345 1229889 7 · fax +49 345 1229889 1
+<a href="http://gocept.com">http://gocept.com</a> ·
tel +49 345 1229889 7 · fax +49 345 1229889 1
Zope and Plone consulting and development
</pre>
</td>
</tr></table></div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
->>> print r['attachments']
- <div class="messagebody">
- <h3>Attachments</h3>
- <ul>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/1/2">drawing.png</a>
(<span>image/png</span> <span>110992</span>)
- </li>
- <li>
- <a href="http://localhost/profile/ben-example.com/+Testmessages/*.../*body/2">random.zip</a>
(<span>application/zip</span> <span>104276</span>)
- </li>
- </ul>
- </div>
+>>> print r['footer']
+<div class="footer">
+ <div class="footercomponent"><h6>Attachments</h6>
+<BLANKLINE>
+<ul>
+ <li>
+ <a href="#">drawing.png</a>
(<span>image/png</span> <span>110992</span>)
+ </li>
+ <li>
+ <a href="#">random.zip</a>
(<span>application/zip</span> <span>104276</span>)
+ </li>
+</ul>
+</div>
+</div>
Claws, text/plain, UTF-8 (Japanese & German)
(at)(at) -223,9 +252,14 (at)(at)
Japanese characters and umlauts, encoded in UTF-8:
>>> r = render_message(folder, '13 - Claws, text/plain, UTF-8
(Japanese, German)')
->>> r['body']
-u'<div class="messagebody">\n <pre>Altjapanisch
(\u4e0a\u53e4\u65e5\u672c\u8a9e, j\u014dko nihongo) sp\xe4testens seit der
Nara-Zeit\r\n</pre>\n</div>\n'
-
+>>> print r['body']
+<div class="messagepart">
+ <div><pre>Altjapanisch
(上古日本語, jōko
nihongo) spätestens seit der Nara-Zeit
+</pre></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
Webmail, text/html, UTF-8 (Japanese & German)
---------------------------------------------
(at)(at) -235,7 +269,12 (at)(at)
>>> r = render_message(folder, '14 - Webmail, text/html, UTF-8
(Japanese, German)')
>>> print r['body']
-<div ... (<span class="lang"
lang="ja-Hani">上古日本語</span>,
<em>jōko nihongo</em>) spätestens seit ...
+<div class="messagepart">
+ <div><div><a href="http://de.wikipedia.org/wiki/Altjapanisch"
title="Altjapanisch" class="mw-redirect">Altjapanisch</a> (<span
class="lang"
lang="ja-Hani">上古日本語</span>,
<em>jōko nihongo</em>) spätestens seit der <a
href="http://de.wikipedia.org/wiki/Nara-Zeit"
title="Nara-Zeit">Nara-Zeit</a></div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
AppleMail, text/html, UTF-8 (many languages)
(at)(at) -246,15 +285,12 (at)(at)
>>> r = render_message(folder, '15 - AppleMail, text/html, UTF-8
(many languages)')
>>> print r['body']
-<div
-...<a>Aragonés</a>...
-...<a>العربية</a>...
-...<a>Azərbaycan</a>...
-...<a>Български</a>...
-...<a>Bosanski</a>...
-...<a>ᨅᨔ
ᨕᨘᨁᨗ</a>...
-...<a>Català</a>...
-...<a>Česky</a>...
+<div class="messagepart">
+ <div><div><font class="Apple-style-span"
color="#FF3F45">pjlk</font>j<div><br></div><div>wie
wärs
damit</div><div><br></div><div><span
class="Apple-style-span"><ul><li class="interwiki-af"><a
href="http://af.wikipedia.org/wiki/Python">Afrikaans</a></li><li
class="interwiki-an"><a href="http://an.wikipedia.org/wiki/Python">Aragonés</a></li><li
class="interwiki-ar"><a href="http://ar.wikipedia.org/wiki/%D8%A8%D8%A7%D9%8A%D8%AB%D9%88%D9%86">العربية</a></li><li
class="interwiki-az"><a href="http://az.wikipedia.org/wiki/Python">Azərbaycan</a></li><li
class="interwiki-bg"><a href="http://bg.wikipedia.org/wiki/Python">Български</a></li><li
class="interwiki-bs"><a href="http://bs.wikipedia.org/wiki/Python_programski_jezik">Bosanski</a></li><li
class="interwiki-bug"><a href="http://bug.wikipedia.org/wiki/Python">ᨅᨔ
ᨕᨘᨁᨗ</a></li><li class
="interwiki-ca"><a href="http://ca.wikipedia.org/wiki/Python">Català</a></li><li
class="interwiki-cs"><a href="http://cs.wikipedia.org/wiki/Python">Česky</a></li><li
class="interwiki-da"><a href="http://da.wikipedia.org/wiki/Python_(programmeringssprog)">Dansk</a></li><li
class="interwiki-el"><a href="http://el.wikipedia.org/wiki/Python">Ελληνικά</a></li><li
class="interwiki-en"><a href="http://en.wikipedia.org/wiki/Python_(programming_language)">English</a></li><li
class="interwiki-eo"><a href="http://eo.wikipedia.org/wiki/Python_(programlingvo)">Esperanto</a></li><li
class="interwiki-es"><a href="http://es.wikipedia.org/wiki/Python">Español</a></li><li
class="interwiki-et"><a href="http://et.wikipedia.org/wiki/Python_(programmeerimiskeel)">Eesti</a></li><li
class="interwiki-eu"><a href="http://eu.wikipedia.org/wiki/Python">Euskara</a></li><li
class="interwiki-fa"><a href="http://fa.wikipedia.org/wiki/%D8%B2%D8%A8%D8%A7
%D9%86_%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%E2%80%8C%D9%86%D9%88%DB%8C%D8%B3%DB%8C_%D9%BE%D8%A7%DB%8C%D8%AA%D9%88%D9%86">فارسی</a></li><li
class="interwiki-fi"><a href="http://fi.wikipedia.org/wiki/Python">Suomi</a></li><li
class="interwiki-fr"><a href="http://fr.wikipedia.org/wiki/Python_(langage)">Français</a></li><li
class="interwiki-gl"><a href="http://gl.wikipedia.org/wiki/Python">Galego</a></li><li
class="interwiki-he"><a href="http://he.wikipedia.org/wiki/Python">עברית</a></li><li
class="interwiki-hu"><a href="http://hu.wikipedia.org/wiki/Python_(programoz%C3%A1si_nyelv)">Magyar</a></li><li
class="interwiki-is"><a href="http://is.wikipedia.org/wiki/Python_(forritunarm%C3%A1l)">Íslenska</a></li><li
class="interwiki-it"><a href="http://it.wikipedia.org/wiki/Python">Italiano</a></li><li
class="interwiki-ja"><a href="http://ja.wikipedia.org/wiki/Python">日本語</a></li><li
class="interw
iki-ka"><a href="http://ka.wikipedia.org/wiki/%E1%83%9E%E1%83%98%E1%83%97%E1%83%9D%E1%83%9C%E1%83%98_(%E1%83%9E%E1%83%A0%E1%83%9D%E1%83%92%E1%83%A0%E1%83%90%E1%83%9B%E1%83%98%E1%83%A0%E1%83%94%E1%83%91%E1%83%98%E1%83%A1_%E1%83%94%E1%83%9C%E1%83%90)">ქართული</a></li><li
class="interwiki-ko"><a href="http://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%B4%EC%8D%AC">한국어</a></li><li
class="interwiki-la"><a href="http://la.wikipedia.org/wiki/Python">Latina</a></li><li
class="interwiki-lt"><a href="http://lt.wikipedia.org/wiki/Python">Lietuvių</a></li><li
class="interwiki-ml"><a href="http://ml.wikipedia.org/wiki/%E0%B4%AA%E0%B5%88%E0%B4%A4%E0%B5%8D%E0%B4%A4%E0%B4%A3%E0%B5%8D%E2%80%8D">മലയാളം</a></li><li
class="interwiki-ms"><a href="http://ms.wikipedia.org/wiki/Python">Bahasa
Melayu</a></li><li class="interwiki-nl"><a href="http://nl.wikipedia.org/wiki/Python_(programmeertaal)">Nederla
nds</a></li><li class="interwiki-no"><a href="http://no.wikipedia.org/wiki/Python">Norsk
(bokmål)</a></li><li class="interwiki-pl"><a
href="http://pl.wikipedia.org/wiki/Python">Polski</a></li><li
class="interwiki-pt"><a href="http://pt.wikipedia.org/wiki/Python">Português</a></li><li
class="interwiki-ro"><a href="http://ro.wikipedia.org/wiki/Python">Română</a></li><li
class="interwiki-ru FA" title="Dieser Artikel wurde als exzellent
bewertet."><a href="http://ru.wikipedia.org/wiki/Python">Русский</a></li><li
class="interwiki-simple"><a href="http://simple.wikipedia.org/wiki/Python_(programming_language)">Simple
English</a></li><li class="interwiki-sk"><a href="http://sk.wikipedia.org/wiki/Python_(programovac%C3%AD_jazyk)">Slovenčina</a></li><li
class="interwiki-sl"><a href="http://sl.wikipedia.org/wiki/Python_(programski_jezik)">Slovenščina</a></li><li
class="interwiki-sq"><a href="http://sq.wikiped
ia.org/wiki/Python">Shqip</a></li><li
class="interwiki-sr"><a href="http://sr.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D1%81%D0%BA%D0%B8_%D1%98%D0%B5%D0%B7%D0%B8%D0%BA_%D0%9F%D0%B0%D1%98%D1%82%D0%BE%D0%BD">Српски
/ Srpski</a></li><li class="interwiki-sv"><a href="http://sv.wikipedia.org/wiki/Python_(programspr%C3%A5k)">Svenska</a></li><li
class="interwiki-ta"><a href="http://ta.wikipedia.org/wiki/%E0%AE%AA%E0%AF%88%E0%AE%A4%E0%AF%8D%E0%AE%A4%E0%AF%8B%E0%AE%A9%E0%AF%8D">தமிழ்</a></li><li
class="interwiki-te"><a href="http://te.wikipedia.org/wiki/%E0%B0%AA%E0%B1%88%E0%B0%A5%E0%B0%BE%E0%B0%A8%E0%B1%8D_(%E0%B0%95%E0%B0%82%E0%B0%AA%E0%B1%8D%E0%B0%AF%E0%B1%82%E0%B0%9F%E0%B0%B0%E0%B1%8D_%E0%B0%AD%E0%B0%BE%E0%B0%B7)">తెలుగు</a></li><li
class="interwiki-th"><a href="http://th.wikipedia.org/wiki/%E0%B8%A0%E0%B8%B2%E0%B8%A9%E0%B8%B2%E0%B9%84%E0%B8%9E%E0%B8%97%E0%B8
%AD%E0%B8%99">ไทย</a></li><li
class="interwiki-tr"><a href="http://tr.wikipedia.org/wiki/Python_(programlama_dili)">Türkçe</a></li><li
class="interwiki-uk"><a href="http://uk.wikipedia.org/wiki/Python">Українська</a></li><li
class="interwiki-vi"><a href="http://vi.wikipedia.org/wiki/Python_(ng%C3%B4n_ng%E1%BB%AF_l%E1%BA%ADp_tr%C3%ACnh)">Tiếng
Việt</a></li><li class="interwiki-zh"><a
href="http://zh.wikipedia.org/wiki/Python">中文</a></li></ul><div><font
class="Apple-style-span" size="3"><span
class="Apple-style-span"><br></span></font></div></span></div><div><br><div>
<div><div><div>-- </div><div>Christian
Zagrodnick · <a
href="mailto:cz(at)gocept.com">cz(at)gocept.com</a></div><div>gocept
gmbh & co. kg · forsterstraße 29 · 06112
halle (saale) · germany</div><div><a href="http://gocept.com">http://gocept.com</a> ·
tel +49 345 122988
9 0 · fax +49 345 1229889 1</div><div>Zope and Plone
consulting and
development</div><br></div></div><br></div><br></div></div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
Artificial message, text/html, undeclared UTF-8 (Japanese & German)
(at)(at) -266,7 +302,12 (at)(at)
>>> r = render_message(folder, '16 - Artificial, text/html,
undeclared UTF-8 (Japanese, German)')
>>> print r['body']
-<div
class="messagebody"><div><p>上古日本語
<em>jōko nihongo</em></p></div></div>
+<div class="messagepart">
+
<div><div><p>上古日本語
<em>jōko nihongo</em></p></div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
Artificial message, text/html, undeclared Latin-1
(at)(at) -278,7 +319,12 (at)(at)
>>> r = render_message(folder, '17 - Artificial, text/html,
undeclared Latin-1 (German)')
>>> print r['body']
-<div
class="messagebody"><div>öäü</div></div>
+<div class="messagepart">
+ <div><div>öäü</div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
Artificial message, text/html, undeclared EUC-JP
(at)(at) -290,4 +336,9 (at)(at)
>>> r = render_message(folder, '18 - Artificial, text/html,
undeclared EUC-JP (Japanese)')
>>> print r['body']
-<div
class="messagebody"><div><p>¾å¸ÅÆüËܸì
<em>j«×ko
nihongo</em></p></div></div>
+<div class="messagepart">
+
<div><div><p>¾å¸ÅÆüËܸì
<em>j«×ko
nihongo</em></p></div></div>
+ <div><div class="footer">
+</div>
+</div>
+</div>
Modified: gocept.restmail/trunk/setup.py
==============================================================================
--- gocept.restmail/trunk/setup.py (original)
+++ gocept.restmail/trunk/setup.py Fri Dec 12 10:29:45 2008
(at)(at) -17,7 +17,7 (at)(at)
namespace_packages=['gocept'],
install_requires=[
'gocept.imapapi>0.1',
- 'lxml',
+ 'lxml==2.1',
'python-cjson',
'setuptools',
'uuid',
|
SVN: r7266 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-12 11:27:55 |
[ FULL ]
|
Author: sweh
Date: Fri Dec 12 11:27:54 2008
New Revision: 7266
Log:
add tests for copy, move and delete of messages in the MessageWebAPI
Modified:
gocept.restmail/trunk/gocept/restmail/browser/README.txt
Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt Fri Dec 12
11:27:54 2008
(at)(at) -442,12 +442,46 (at)(at)
Messages can be deleted using the `(at)(at)delete` view.
-XXX Test it when tests work again
-
+>>> len(messages)
+2
+>>> json_request(messages[0]['url']+'/(at)(at)delete', post=True)
+{}
+>>> INBOX_url = 'http://localhost/profile/ben-example.com/+INBOX'
+>>> messages = json_request(INBOX_url + '/(at)(at)messages')
+>>> len(messages)
+1
Copy and move messages
----------------------
-Messages can be copied and moved using the `(at)(at)copy` and `(at)(at)move`
view.
+Messages can be copied and moved using the `(at)(at)copy` and `(at)(at)move`
view. You must
+pass the url of the target folder.
+
+When copying, the source message will not be deleted:
-XXX Test it when tests work again
+>>> folders = json_request(INBOX_url + '/(at)(at)folders')
+>>> folders
+[{'url': 'http://localhost/profile/ben-example.com/+INBOX/+Baz',
'type': 'inbox', 'name': 'Baz', 'children': 0}]
+>>> BAZ_url = folders[0]['url']
+>>> baz_messages = json_request(BAZ_url + '/(at)(at)messages')
+>>> len(baz_messages)
+0
+>>> json_request(messages[0]['url']+'/(at)(at)copy',
folder_url=BAZ_url, post=True)
+{}
+>>> baz_messages = json_request(BAZ_url + '/(at)(at)messages')
+>>> len(baz_messages)
+1
+>>> messages = json_request(INBOX_url + '/(at)(at)messages')
+>>> len(messages)
+1
+
+Moving messages implies the deletion of the source message:
+
+>>> json_request(baz_messages[0]['url']+'/(at)(at)move',
folder_url=INBOX_url, post=True)
+{}
+>>> baz_messages = json_request(BAZ_url + '/(at)(at)messages')
+>>> len(baz_messages)
+0
+>>> messages = json_request(INBOX_url + '/(at)(at)messages')
+>>> len(messages)
+2
|
SVN: r7269 - in gocept.restmail/trunk/gocept/restmail: . browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-12 13:10:13 |
[ FULL ]
|
Author: sweh
Date: Fri Dec 12 13:10:12 2008
New Revision: 7269
Log:
add a check_connection method to account
remove bare excepts
(bug #4569)
Modified:
gocept.restmail/trunk/gocept/restmail/browser/profile.py
gocept.restmail/trunk/gocept/restmail/connection.txt
gocept.restmail/trunk/gocept/restmail/imapaccount.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/profile.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/profile.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/profile.py Fri Dec 12
13:10:12 2008
(at)(at) -6,7 +6,6 (at)(at)
import gocept.restmail.identity
import gocept.restmail.imapaccount
import gocept.restmail.browser.json
-import socket
import xml.sax.saxutils
import zope.app.zapi
(at)(at) -22,10 +21,7 (at)(at)
for account in self.context.objectValues('IMAP Account'):
identity = gocept.restmail.interfaces.IIdentity(account)
status = 'ok'
- try:
- # XXX refactor into account.check_connection()
- account.folders()
- except:
+ if not account.check_connection():
status = 'failure'
data.append(
{'status': status,
(at)(at) -83,14 +79,9 (at)(at)
"""Child listing to support tree views."""
data = []
for account in self.context.objectValues('IMAP Account'):
- try:
- # Prevent raising an exception if the server is not available
- # (e.g. because of a wrong configuration). Available accounts
- # should be listet although.
+ children = 0
+ if account.check_connection():
children = len(account.folders())
- except:
- # XXX Log an error for the user
- children = 0
identity = gocept.restmail.interfaces.IIdentity(account)
data.append(
{'url': zope.app.zapi.absoluteURL(account, self.request),
Modified: gocept.restmail/trunk/gocept/restmail/connection.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/connection.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/connection.txt Fri Dec 12 13:10:12
2008
(at)(at) -40,7 +40,7 (at)(at)
>>> create_connections(1)
Traceback (most recent call last):
-error: Maximum number of connections from user+IP exceeded
+IMAPConnectionError: Maximum number of connections from user+IP exceeded
After a request, Zope crosses a transaction boundary which causes all IMAP
connections to be closed so we can open new ones again.
(at)(at) -55,7 +55,7 (at)(at)
>>> create_connections(10)
Traceback (most recent call last):
-error: Maximum number of connections from user+IP exceeded
+IMAPConnectionError: Maximum number of connections from user+IP exceeded
>>> import transaction
>>> transaction.abort()
>>> create_connections(1)
Modified: gocept.restmail/trunk/gocept/restmail/imapaccount.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/imapaccount.py (original)
+++ gocept.restmail/trunk/gocept/restmail/imapaccount.py Fri Dec 12 13:10:12
2008
(at)(at) -10,11 +10,14 (at)(at)
from OFS.ObjectManager import ObjectManager
import UserDict
+import gocept.imapapi
import gocept.imapapi.account
import gocept.restmail.interfaces
import transaction
import zope.component
import zope.interface
+import socket
+import imaplib
class IMAPAccount(ObjectManager, PropertyManager, Item):
(at)(at) -82,6 +85,15 (at)(at)
connection.folders[name] = new_folder
return self.folders(name)[0]
+ def check_connection(self):
+ try:
+ self.folders()
+ except gocept.imapapi.IMAPServerError:
+ return False
+ except gocept.imapapi.IMAPConnectionError:
+ return False
+ return True
+
# ZMI support
isPrincipiaFolderish = True
|
SVN: r7272 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-12 15:53:50 |
[ FULL ]
|
Author: sweh
Date: Fri Dec 12 15:53:49 2008
New Revision: 7272
Log:
add a json view to MessageWebApi returning the messages source
Modified:
gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
gocept.restmail/trunk/gocept/restmail/browser/message.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml Fri Dec 12
15:53:49 2008
(at)(at) -195,6 +195,11 (at)(at)
/>
<browser:page
+ name="raw"
+ attribute="raw"
+ />
+
+ <browser:page
name="reply"
attribute="reply"
/>
Modified: gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/message.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/message.py Fri Dec 12
15:53:49 2008
(at)(at) -63,6 +63,10 (at)(at)
footer=IFooter(rendered_message))
(at)gocept.restmail.browser.json.view
+ def raw(self):
+ return {'raw': '<pre>%s</pre>' % self.context.message.raw}
+
+ (at)gocept.restmail.browser.json.view
def reply(self):
"""Create a new draft message."""
profile = gocept.restmail.interfaces.IProfile(self.context)
|
SVN: r7273 - gocept.collmex/trunk/src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-15 11:12:56 |
[ FULL ]
|
Author: wosc
Date: Mon Dec 15 11:12:55 2008
New Revision: 7273
Log:
convert values coming from Collmex to unicode
Modified:
gocept.collmex/trunk/src/gocept/collmex/model.py
Modified: gocept.collmex/trunk/src/gocept/collmex/model.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/model.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/model.py Mon Dec 15 11:12:55 2008
(at)(at) -18,9 +18,10 (at)(at)
self['Rechnungsart'] = 0 # type invoice
for i in range(len(row)):
- if row[i] == '':
- row[i] = None
- self[self.fields[i]] = row[i]
+ if row[i] == '' or row[i] is None:
+ self[self.fields[i]] = None
+ else:
+ self[self.fields[i]] = unicode(row[i], 'Windows-1252')
def __iter__(self):
for field in self.fields:
|
SVN: r7282 - in gocept.restmail/trunk/gocept/restmail: . browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-15 14:33:50 |
[ FULL ]
|
Author: sweh
Date: Mon Dec 15 14:33:49 2008
New Revision: 7282
Log:
set a message to \Answered when replying to it
show message flags in the YUI API
Modified:
gocept.restmail/trunk/gocept/restmail/browser/README.txt
gocept.restmail/trunk/gocept/restmail/browser/message.py
gocept.restmail/trunk/gocept/restmail/draft.py
gocept.restmail/trunk/gocept/restmail/imapaccount.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt Mon Dec 15
14:33:49 2008
(at)(at) -182,10 +182,12 (at)(at)
>>> messages = json_request('http://localhost/profile/ben-example.com/+INBOX/(at)(at)messages')
>>> pprint.pprint(messages)
[{'date': '02-Jul-2008 03:05:00 +0200',
+ 'flags': [],
'from': 'test(at)localhost',
'subject': 'Mail 1',
'url': 'http://localhost/profile/ben-example.com/+INBOX/*...'},
{'date': '02-Jul-2008 03:06:00 +0200',
+ 'flags': [],
'from': 'test(at)localhost',
'subject': 'Mail 2',
'url': 'http://localhost/profile/ben-example.com/+INBOX/*...'}]
(at)(at) -395,6 +397,7 (at)(at)
>>> pprint.pprint(json_request('http://localhost/profile/ben-example.com/+Sent/(at)(at)messages'))
[{'date': None,
+ 'flags': [],
'from': 'Ben Utzer <ben(at)example.com>',
'subject': 'asdf',
'url': 'http://localhost/profile/ben-example.com/+Sent/*...'}]
(at)(at) -436,6 +439,20 (at)(at)
</body>
</html>
+The original message is now flaged as ``\Seen`` and ``\Answered``:
+
+>>> pprint.pprint(json_request('http://localhost/profile/ben-example.com/+INBOX/(at)(at)messages'))
+[{'date': '02-Jul-2008 03:05:00 +0200',
+ 'flags': ['\\Answered', '\\Seen'],
+ 'from': 'test(at)localhost',
+ 'subject': 'Mail 1',
+ 'url': 'http://localhost/profile/ben-example.com/+INBOX/*...'},
+ {'date': '02-Jul-2008 03:06:00 +0200',
+ 'flags': [],
+ 'from': 'test(at)localhost',
+ 'subject': 'Mail 2',
+ 'url': 'http://localhost/profile/ben-example.com/+INBOX/*...'}]
+
Deleting messages
-----------------
Modified: gocept.restmail/trunk/gocept/restmail/browser/message.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/message.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/message.py Mon Dec 15
14:33:49 2008
(at)(at) -28,6 +28,7 (at)(at)
'from': message.headers.get('From'),
'subject': message.headers.get('Subject'),
'date': message.headers.get('Date'),
+ 'flags': message.flags
} for message in self.context.messages()]
return data
Modified: gocept.restmail/trunk/gocept/restmail/draft.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/draft.py (original)
+++ gocept.restmail/trunk/gocept/restmail/draft.py Mon Dec 15 14:33:49 2008
(at)(at) -59,6 +59,7 (at)(at)
if msgid:
self.in_reply_to = msgid
references += ' ' + msgid
+ message.message.answered() #XXX: do it when sending the draft
if references:
self.references = references
Modified: gocept.restmail/trunk/gocept/restmail/imapaccount.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/imapaccount.py (original)
+++ gocept.restmail/trunk/gocept/restmail/imapaccount.py Mon Dec 15 14:33:49
2008
(at)(at) -215,6 +215,10 (at)(at)
return self.message.headers
(at)property
+ def flags(self):
+ return self.message.flags
+
+ (at)property
def text(self):
return self.message.text
|
SVN: r7295 - gocept.restmail/trunk/gocept/restmail
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-16 11:39:29 |
[ FULL ]
|
Author: sweh
Date: Tue Dec 16 11:39:28 2008
New Revision: 7295
Log:
bugfix with specially quoted mails
Modified:
gocept.restmail/trunk/gocept/restmail/render.py
Modified: gocept.restmail/trunk/gocept/restmail/render.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/render.py (original)
+++ gocept.restmail/trunk/gocept/restmail/render.py Tue Dec 16 11:39:28 2008
(at)(at) -247,8 +247,11 (at)(at)
elif c != ' ':
break
if level:
- if line[last_quote+1] == ' ':
+ try:
+ if line[last_quote+1] == ' ':
+ line = line[last_quote+2:]
+ else:
+ line = line[last_quote+1:]
+ except IndexError:
line = line[last_quote+2:]
- else:
- line = line[last_quote+1:]
return level, line
|
SVN: r7297 - in gocept.restmail/trunk/gocept/restmail: . testmessages
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-17 08:33:57 |
[ FULL ]
|
Author: sweh
Date: Wed Dec 17 08:33:56 2008
New Revision: 7297
Log:
testcase for bugfix, if a quote does not end with a whitespace
Modified:
gocept.restmail/trunk/gocept/restmail/render.py
gocept.restmail/trunk/gocept/restmail/render.txt
gocept.restmail/trunk/gocept/restmail/testmessages/26-ascii-quoting-whitespaces
Modified: gocept.restmail/trunk/gocept/restmail/render.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/render.py (original)
+++ gocept.restmail/trunk/gocept/restmail/render.py Wed Dec 17 08:33:56 2008
(at)(at) -253,5 +253,5 (at)(at)
else:
line = line[last_quote+1:]
except IndexError:
- line = line[last_quote+2:]
+ line = ''
return level, line
Modified: gocept.restmail/trunk/gocept/restmail/render.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/render.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/render.txt Wed Dec 17 08:33:56 2008
(at)(at) -57,6 +57,12 (at)(at)
one leading space after quote
two leading spaces after quote
</pre></blockquote>
+<pre>
+no text after quote:
+</pre>
+<blockquote><pre>
+</pre></blockquote>
+
Encoding
--------
Modified:
gocept.restmail/trunk/gocept/restmail/testmessages/26-ascii-quoting-whitespaces
==============================================================================
---
gocept.restmail/trunk/gocept/restmail/testmessages/26-ascii-quoting-whitespaces (original)
+++
gocept.restmail/trunk/gocept/restmail/testmessages/26-ascii-quoting-whitespaces Wed
Dec 17 08:33:56 2008
(at)(at) -6,3 +6,6 (at)(at)
>no leading space after quote
> one leading space after quote
> two leading spaces after quote
+
+no text after quote:
+>
|
SVN: r7306 - in gocept.lockd/trunk: . gocept gocept/lockd
Christian Theune <ct(at)gocept.com> |
2008-12-17 14:32:42 |
[ FULL ]
|
Author: ctheune
Date: Wed Dec 17 14:32:40 2008
New Revision: 7306
Log:
First shot at a *very simple* lock server.
Added:
gocept.lockd/trunk/bootstrap.py (contents, props changed)
gocept.lockd/trunk/buildout.cfg
gocept.lockd/trunk/gocept/
gocept.lockd/trunk/gocept/__init__.py (contents, props changed)
gocept.lockd/trunk/gocept/lockd/
gocept.lockd/trunk/gocept/lockd/__init__.py (contents, props changed)
gocept.lockd/trunk/gocept/lockd/client.py (contents, props changed)
gocept.lockd/trunk/gocept/lockd/lockd.py (contents, props changed)
gocept.lockd/trunk/setup.py (contents, props changed)
Modified:
gocept.lockd/trunk/ (props changed)
Added: gocept.lockd/trunk/bootstrap.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/bootstrap.py Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1,55 (at)(at)
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id$
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+ import pkg_resources
+except ImportError:
+ ez = {}
+ exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+ ).read() in ez
+ ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+ import pkg_resources
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+if sys.platform == 'win32':
+ cmd = '"%s"' % cmd # work around spawn lamosity on windows
+
+ws = pkg_resources.working_set
+assert os.spawnle(
+ os.P_WAIT, sys.executable, sys.executable,
+ '-c', cmd, '-mqNxd', tmpeggs, 'zc.buildout',
+ dict(os.environ,
+ PYTHONPATH=
+ ws.find(pkg_resources.Requirement.parse('setuptools')).location
+ ),
+ ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)
Added: gocept.lockd/trunk/buildout.cfg
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/buildout.cfg Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1,22 (at)(at)
+[buildout]
+develop = .
+parts = lockd lockcmd
+
+[lockd]
+recipe = zc.recipe.egg
+eggs = gocept.lockd
+scripts = lockd=lockd
+arguments = "${lockd:host}", ${lockd:port}
+
+host = 127.0.0.1
+port = 8000
+
+[lockcmd]
+recipe = zc.recipe.egg
+eggs = gocept.lockd
+scripts = lockcmd=lockcmd
+arguments = "${lockcmd:server}"
+
+server = http://${lockd:host}:${lockd:port}/
+
+
Added: gocept.lockd/trunk/gocept/__init__.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/gocept/__init__.py Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1,10 (at)(at)
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+# $Id: __init__.py 5769 2008-05-20 08:05:02Z sweh $
+
+#namespace package boilerplate
+try:
+ __import__('pkg_resources').declare_namespace(__name__)
+except ImportError, e:
+ from pkgutil import extend_path
+ __path__ = extend_path(__path__, __name__)
Added: gocept.lockd/trunk/gocept/lockd/__init__.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/gocept/lockd/__init__.py Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1 (at)(at)
+# Make this a Python package
Added: gocept.lockd/trunk/gocept/lockd/client.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/gocept/lockd/client.py Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1,15 (at)(at)
+# vim:fileencoding=utf-8
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+import sys
+import xmlrpclib
+
+
+def main(server):
+ _, command, resource, client = sys.argv
+ assert command in ['lock', 'unlock']
+
+ s = xmlrpclib.Server(server)
+ function = getattr(s, command)
+ function(resource, client)
Added: gocept.lockd/trunk/gocept/lockd/lockd.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/gocept/lockd/lockd.py Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1,66 (at)(at)
+# vim:fileencoding=utf-8
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+import SimpleXMLRPCServer
+import os.path
+import time
+import zc.lockfile
+
+
+def run_locked(function):
+ def wrapped(self, resource, client):
+ lock = self._acquire()
+ try:
+ return function(self, resource, client)
+ finally:
+ lock.close()
+ wrapped.__name__ = function.__name__
+ return wrapped
+
+
+class Lockd(object):
+
+ def __init__(self, lockdir):
+ self.lockdir = lockdir
+ self.server_lock = os.path.join(self.lockdir, 'lockd.lock')
+
+ def _acquire(self):
+ while True:
+ try:
+ lock = zc.lockfile.LockFile('lockd.lock')
+ except zc.lockfile.LockError:
+ time.sleep(0.1)
+ continue
+ return lock
+
+ def _resource_lock_name(self, resource):
+ return os.path.join(self.lockdir, resource + '.resource.lock')
+
+ (at)run_locked
+ def lock(self, resource, client):
+ resource_lock = self._resource_lock_name(resource)
+ if os.path.exists(resource_lock):
+ client = open(resource_lock, 'r').read().strip()
+ raise Exception('Resource already locked by %r' % client)
+ open(resource_lock, 'w').write(client)
+
+ (at)run_locked
+ def unlock(self, resource, client):
+ resource_lock = self._resource_lock_name(resource)
+ if not os.path.exists(resource_lock):
+ raise Exception('Resource not locked')
+ locked_by = open(resource_lock, 'r').read().strip()
+ if client != locked_by:
+ raise Exception(
+ 'Resource locked by %r cannot be unlocked by %r' %
+ (locked_by, client))
+ os.unlink(resource_lock)
+
+
+def main(host, port):
+ server = SimpleXMLRPCServer.SimpleXMLRPCServer(
+ (host, port), allow_none=True)
+ server.register_introspection_functions()
+ server.register_instance(Lockd('/tmp/locks'))
+ server.serve_forever()
Added: gocept.lockd/trunk/setup.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/setup.py Wed Dec 17 14:32:40 2008
(at)(at) -0,0 +1,27 (at)(at)
+# vim:fileencoding=utf-8
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+from setuptools import setup, find_packages
+
+setup(name='gocept.lockd',
+ version='0.1dev',
+ description="A simple XML-RPC-based lock daemon to support fencing.",
+ author="Christian Theune",
+ author_email="ct(at)gocept.com",
+ license="ZPL 2.1",
+ package_dir={'': '.'},
+ packages=find_packages('.'),
+ include_package_data=True,
+ namespace_packages=['gocept'],
+ zip_safe=False,
+ install_requires=[
+ 'setuptools',
+ 'zc.lockfile',
+ ],
+ entry_points="""
+ [console_scripts]
+ lockd = gocept.lockd.lockd:main
+ lockcmd = gocept.lockd.client:main
+ """,
+ )
|
SVN: r7307 - in gocept.lockd/trunk: . gocept/lockd
Christian Theune <ct(at)gocept.com> |
2008-12-17 14:52:29 |
[ FULL ]
|
Author: ctheune
Date: Wed Dec 17 14:52:28 2008
New Revision: 7307
Log:
Added simple test coverage. The actual race condition of the server
isn't tested for.
Added:
gocept.lockd/trunk/gocept/lockd/README.txt (contents, props changed)
gocept.lockd/trunk/gocept/lockd/tests.py (contents, props changed)
Modified:
gocept.lockd/trunk/buildout.cfg
Modified: gocept.lockd/trunk/buildout.cfg
==============================================================================
--- gocept.lockd/trunk/buildout.cfg (original)
+++ gocept.lockd/trunk/buildout.cfg Wed Dec 17 14:52:28 2008
(at)(at) -1,6 +1,6 (at)(at)
[buildout]
develop = .
-parts = lockd lockcmd
+parts = lockd lockcmd test
[lockd]
recipe = zc.recipe.egg
(at)(at) -19,4 +19,6 (at)(at)
server = http://${lockd:host}:${lockd:port}/
-
+[test]
+recipe = zc.recipe.testrunner
+eggs = gocept.lockd
Added: gocept.lockd/trunk/gocept/lockd/README.txt
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/gocept/lockd/README.txt Wed Dec 17 14:52:28 2008
(at)(at) -0,0 +1,54 (at)(at)
+Using the lockd API
+===================
+
+lockd provides a light-weight implementation of a locking mechanism for
+long-running resources by maintaining lock files in a given directory.
+
+>>> import tempfile
+>>> lockdir = tempfile.mkdtemp()
+>>> from gocept.lockd.lockd import Lockd
+>>> daemon = Lockd(lockdir)
+
+Resources are identified by a string and clients performing the lock are
+identified by another string:
+
+>>> daemon.lock('resource1', 'client1')
+
+Once a resource is locked, it can not be locked again:
+
+>>> daemon.lock('resource1', 'client2')
+Traceback (most recent call last):
+Exception: Resource already locked by 'client1'
+
+However, other resources can be locked in parallel:
+
+>>> daemon.lock('resource2', 'client2')
+
+Clients, other than the client who locked a resource, can not unlock it:
+
+>>> daemon.unlock('resource1', 'client2')
+Traceback (most recent call last):
+Exception: Resource locked by 'client1' cannot be unlocked by 'client2'
+
+The client, who locked the resource, can unlock it again:
+
+>>> daemon.unlock('resource1', 'client1')
+
+Once unlocked, it can not be unlocked a second time:
+
+>>> daemon.unlock('resource1', 'client1')
+Traceback (most recent call last):
+Exception: Resource not locked
+
+
+IMPORTANT security note
+=======================
+
+Resource identification and client authorization are out of scope for
+lockd. It should only be used and exposed within a trusted environment.
+
+
+Cleanup:
+
+>>> import shutil
+>>> shutil.rmtree(lockdir)
Added: gocept.lockd/trunk/gocept/lockd/tests.py
==============================================================================
--- (empty file)
+++ gocept.lockd/trunk/gocept/lockd/tests.py Wed Dec 17 14:52:28 2008
(at)(at) -0,0 +1,12 (at)(at)
+# vim:fileencoding=utf-8
+# Copyright (c) 2008 gocept gmbh & co. kg
+# See also LICENSE.txt
+
+import unittest
+import doctest
+
+
+def test_suite():
+ suite = unittest.TestSuite()
+ suite.addTest(doctest.DocFileSuite('README.txt'))
+ return suite
|
SVN: r7315 - in gocept.restmail/trunk/gocept/restmail: . browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-18 09:23:57 |
[ FULL ]
|
Author: sweh
Date: Thu Dec 18 09:23:56 2008
New Revision: 7315
Log:
add a method to view the raw content of a draft message
Modified:
gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
gocept.restmail/trunk/gocept/restmail/browser/draft.py
gocept.restmail/trunk/gocept/restmail/draft.py
Modified: gocept.restmail/trunk/gocept/restmail/browser/configure.zcml
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/configure.zcml (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/configure.zcml Thu Dec 18
09:23:56 2008
(at)(at) -244,6 +244,11 (at)(at)
/>
<browser:page
+ name="raw"
+ attribute="raw"
+ />
+
+ <browser:page
name="send"
attribute="send"
/>
Modified: gocept.restmail/trunk/gocept/restmail/browser/draft.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/draft.py (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/draft.py Thu Dec 18 09:23:56
2008
(at)(at) -40,6 +40,10 (at)(at)
self.context.body = body
(at)gocept.restmail.browser.json.view
+ def raw(self):
+ return {'raw': '<pre>%s</pre>' % self.context.raw()}
+
+ (at)gocept.restmail.browser.json.view
def send(self):
"""Update draft and send this message."""
self.context.send()
Modified: gocept.restmail/trunk/gocept/restmail/draft.py
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/draft.py (original)
+++ gocept.restmail/trunk/gocept/restmail/draft.py Thu Dec 18 09:23:56 2008
(at)(at) -63,7 +63,7 (at)(at)
if references:
self.references = references
- def send(self):
+ def raw(self):
profile = gocept.restmail.interfaces.IProfile(self)
account = profile[self.account]
identity = gocept.restmail.interfaces.IIdentity(account)
(at)(at) -84,7 +84,13 (at)(at)
message['In-reply-to'] = self.in_reply_to
if self.references:
message['References'] = self.references
- message = message.as_string() # XXX Memory usage
+ return message.as_string() # XXX Memory usage
+
+ def send(self):
+ profile = gocept.restmail.interfaces.IProfile(self)
+ account = profile[self.account]
+ identity = gocept.restmail.interfaces.IIdentity(account)
+ message = self.raw()
# 2. Send via MailHost
mh = profile[identity.smtp_server]
|
SVN: r7318 - gocept.collmex/trunk/src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-18 09:39:34 |
[ FULL ]
|
Author: wosc
Date: Thu Dec 18 09:39:33 2008
New Revision: 7318
Log:
updated tests for r7273: values from Collmex are converted to unicode
Modified:
gocept.collmex/trunk/src/gocept/collmex/README.txt
Modified: gocept.collmex/trunk/src/gocept/collmex/README.txt
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/README.txt (original)
+++ gocept.collmex/trunk/src/gocept/collmex/README.txt Thu Dec 18 09:39:33 2008
(at)(at) -1,3 +1,5 (at)(at)
+coding: utf-8
+
Collmex API
===========
(at)(at) -53,22 +55,22 (at)(at)
>>> customer = customers[0]
>>> customer['Satzart']
-'CMXKND'
+u'CMXKND'
>>> customer['Kundennummer']
-'9999'
+u'9999'
>>> customer['Firma']
-'Allgemeiner Gesch\xe4ftspartner'
+u'Allgemeiner Gesch\xe4ftspartner'
The second customer is one created during test setup:
>>> customer = customers[1]
>>> customer['Satzart']
-'CMXKND'
+u'CMXKND'
>>> customer['Kundennummer']
-'10000'
+u'10000'
>>> customer['Firma']
-'Testkunden'
+u'Testkunden'
Products: ``create_product`` and ``get_products``
-------------------------------------------------
(at)(at) -83,7 +85,7 (at)(at)
>>> collmex.create_product(product)
>>> transaction.commit()
>>> collmex.get_products()[0]['Bezeichnung']
-'Testprodukt'
+u'Testprodukt'
Invoices: ``create_invoice`` and ``get_invoices``
-------------------------------------------------
(at)(at) -97,7 +99,7 (at)(at)
>>> item['Rechnungsnummer'] = 100000
>>> item['Menge'] = 3
>>> item['Produktnummer'] = 'TEST'
->>> item['Rechnungstext'] = 'item text'
+>>> item['Rechnungstext'] = u'item text – with non-ascii
characters'
>>> item['Positionstyp'] = 0
>>> collmex.create_invoice([item])
(at)(at) -113,7 +115,7 (at)(at)
>>> transaction.commit()
>>> collmex.get_invoices(customer_id='10000',
... start_date=start_date)[0]['Rechnungstext']
-'item text'
+u'item text \u2013 with non-ascii characters'
.. [#pre-flight-cleanup] First we need to clean up the Collmex environment:
|
SVN: r7319 - gocept.restmail/trunk/gocept/restmail/browser
Sebastian Wehrmann <sw(at)gocept.com> |
2008-12-18 10:02:09 |
[ FULL ]
|
Author: sweh
Date: Thu Dec 18 10:02:08 2008
New Revision: 7319
Log:
added test for r7315
Modified:
gocept.restmail/trunk/gocept/restmail/browser/README.txt
Modified: gocept.restmail/trunk/gocept/restmail/browser/README.txt
==============================================================================
--- gocept.restmail/trunk/gocept/restmail/browser/README.txt (original)
+++ gocept.restmail/trunk/gocept/restmail/browser/README.txt Thu Dec 18
10:02:08 2008
(at)(at) -372,6 +372,15 (at)(at)
'to': 'ct(at)gocept.com'}
+Retrieving the raw data of draft messages
+-----------------------------------------
+
+The draft's raw content can be retrieved:
+
+>>> pprint.pprint(json_request(draft['url']+'/(at)(at)raw'))
+{'raw': '<pre>Content-Type: text/html; charset="us-ascii"\nMIME-Version:
1.0\nContent-Transfer-Encoding: 7bit\nFrom: Ben Utzer
<ben(at)example.com>\nTo: ct(at)gocept.com\nSubject:
asdf\n\nHelloHello</pre>'}
+
+
Sending draft messages
----------------------
|
SVN: r7321 - gocept.lockd/trunk/gocept/lockd
Christian Theune <ct(at)gocept.com> |
2008-12-18 12:57:49 |
[ FULL ]
|
Author: ctheune
Date: Thu Dec 18 12:57:48 2008
New Revision: 7321
Log:
make lock directory configurable
Modified:
gocept.lockd/trunk/gocept/lockd/lockd.py
Modified: gocept.lockd/trunk/gocept/lockd/lockd.py
==============================================================================
--- gocept.lockd/trunk/gocept/lockd/lockd.py (original)
+++ gocept.lockd/trunk/gocept/lockd/lockd.py Thu Dec 18 12:57:48 2008
(at)(at) -58,9 +58,9 (at)(at)
os.unlink(resource_lock)
-def main(host, port):
+def main(host, port, directory):
server = SimpleXMLRPCServer.SimpleXMLRPCServer(
(host, port), allow_none=True)
server.register_introspection_functions()
- server.register_instance(Lockd('/tmp/locks'))
+ server.register_instance(Lockd(directory))
server.serve_forever()
|
SVN: r7335 - in gocept.collmex/trunk: . src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-19 09:16:28 |
[ FULL ]
|
Author: wosc
Date: Fri Dec 19 09:16:26 2008
New Revision: 7335
Log:
implemented caching of results
Modified:
gocept.collmex/trunk/setup.py
gocept.collmex/trunk/src/gocept/collmex/README.txt
gocept.collmex/trunk/src/gocept/collmex/collmex.py
Modified: gocept.collmex/trunk/setup.py
==============================================================================
--- gocept.collmex/trunk/setup.py (original)
+++ gocept.collmex/trunk/setup.py Fri Dec 19 09:16:26 2008
(at)(at) -24,6 +24,7 (at)(at)
license='ZPL 2.1',
namespace_packages=['gocept'],
install_requires=[
+ 'gocept.cache>=0.3',
'setuptools',
'transaction',
'zope.deprecation',
Modified: gocept.collmex/trunk/src/gocept/collmex/README.txt
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/README.txt (original)
+++ gocept.collmex/trunk/src/gocept/collmex/README.txt Fri Dec 19 09:16:26 2008
(at)(at) -117,6 +117,47 (at)(at)
... start_date=start_date)[0]['Rechnungstext']
u'item text \u2013 with non-ascii characters'
+
+Caching
+-------
+
+Results queried from Collmex are cached for the duration of the transaction.
+
+To demonstrate this, we instrument the _post() method that performs the actual
+HTTP communication to show when it is called:
+
+ >>> original_post = collmex._post
+ >>> def tracing_post(self, *args, **kw):
+ ... print 'cache miss'
+ ... return original_post(*args, **kw)
+ >>> collmex._post = tracing_post.__get__(collmex, type(collmex))
+
+The first time in an transaction is retrieved from Collmex, of course:
+
+ >>> transaction.abort()
+ >>> collmex.get_products()[0]['Bezeichnung']
+ cache miss
+ u'Testprodukt'
+
+But after that, values are cached:
+
+ >>> collmex.get_products()[0]['Bezeichnung']
+ u'Testprodukt'
+
+When the transaction ends, the cache is invalidated:
+
+ >>> transaction.commit()
+ >>> collmex.get_products()[0]['Bezeichnung']
+ cache miss
+ u'Testprodukt'
+ >>> collmex.get_products()[0]['Bezeichnung']
+ u'Testprodukt'
+
+Remove tracing instrumentation:
+
+ >>> collmex._post = original_post
+
+
.. [#pre-flight-cleanup] First we need to clean up the Collmex environment:
>>> import gocept.collmex.testing
Modified: gocept.collmex/trunk/src/gocept/collmex/collmex.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/collmex.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/collmex.py Fri Dec 19 09:16:26 2008
(at)(at) -4,6 +4,8 (at)(at)
import StringIO
import csv
+import gocept.cache.method
+import gocept.cache.property
import gocept.collmex.interfaces
import gocept.collmex.model
import gocept.collmex.utils
(at)(at) -62,7 +64,7 (at)(at)
def commit(self, transaction):
assert transaction is self._transaction
- # We need to do our work in tpc_vote as we're a single-phase-only data
+ # We need to do our work in tpc_vote as we're a single-phase-only data
# manager.
pass
(at)(at) -108,13 +110,14 (at)(at)
# Store thread-local (actually: transaction-local) information
self._local = threading.local()
+ self._local.connection = None
+ self._local.cache = None
(at)property
def connection(self):
- connection = getattr(self._local, 'connection', None)
- if connection is None:
- connection = self._local.connection = CollmexDataManager(self)
- return connection
+ if self._local.connection is None:
+ self._local.connection = CollmexDataManager(self)
+ return self._local.connection
def create_invoice(self, items):
data = StringIO.StringIO()
(at)(at) -169,6 +172,24 (at)(at)
price_group,
0, self.system_identifier)
+ def _get_cache(self):
+ if self._local.cache is None:
+ self._local.cache = {}
+ dm = gocept.cache.property.CacheDataManager(
+ self, None, transaction.get())
+ transaction.get().join(dm)
+ return self._local.cache
+
+ def _set_cache(self, cache):
+ self._local.cache = cache
+
+ _cache = property(_get_cache, _set_cache)
+
+ # hook for gocept.cache.property.CacheDataManager
+ def invalidate(self, dummy):
+ self._cache = None
+
+ (at)gocept.cache.method.memoize_on_attribute('_cache', timeout=5*60)
def _query_objects(self, function, *args):
data = StringIO.StringIO()
writer = csv.writer(data, dialect=CollmexDialect)
|
SVN: r7336 - gocept.collmex/trunk/src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-19 09:17:29 |
[ FULL ]
|
Author: wosc
Date: Fri Dec 19 09:17:28 2008
New Revision: 7336
Log:
replaced static record-type-->model dictionary with lookup
Modified:
gocept.collmex/trunk/src/gocept/collmex/collmex.py
gocept.collmex/trunk/src/gocept/collmex/model.py
Modified: gocept.collmex/trunk/src/gocept/collmex/collmex.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/collmex.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/collmex.py Fri Dec 19 09:17:28 2008
(at)(at) -96,12 +96,6 (at)(at)
system_identifier = 'gocept.collmex'
- model_factory = {
- 'CMXINV': gocept.collmex.model.InvoiceItem,
- 'CMXKND': gocept.collmex.model.Customer,
- 'CMXPRD': gocept.collmex.model.Product,
- }
-
def __init__(self, customer_id, company_id, username, password):
self.customer_id = customer_id
self.company_id = company_id
(at)(at) -198,7 +192,7 (at)(at)
result = []
for line in lines:
record_type = line[0]
- factory = self.model_factory.get(record_type)
+ factory = gocept.collmex.model.factory(record_type)
if factory is None:
continue
result.append(factory(line))
Modified: gocept.collmex/trunk/src/gocept/collmex/model.py
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/model.py (original)
+++ gocept.collmex/trunk/src/gocept/collmex/model.py Fri Dec 19 09:17:28 2008
(at)(at) -34,6 +34,16 (at)(at)
yield gocept.collmex.interfaces.NULL
+def factory(record_type):
+ """looks up Model class representing the given `record_type`."""
+
+ for class_ in globals().values():
+ if isinstance(class_, type) and issubclass(class_, Model):
+ if class_.satzart == record_type:
+ return class_
+ return None
+
+
class InvoiceItem(Model):
zope.interface.implements(gocept.collmex.interfaces.IInvoiceItem)
|
SVN: r7339 - gocept.collmex/trunk/src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-19 09:47:28 |
[ FULL ]
|
Author: wosc
Date: Fri Dec 19 09:47:27 2008
New Revision: 7339
Log:
setuptools can't deal with non-ascii descriptions
Modified:
gocept.collmex/trunk/src/gocept/collmex/README.txt
Modified: gocept.collmex/trunk/src/gocept/collmex/README.txt
==============================================================================
--- gocept.collmex/trunk/src/gocept/collmex/README.txt (original)
+++ gocept.collmex/trunk/src/gocept/collmex/README.txt Fri Dec 19 09:47:27 2008
(at)(at) -1,5 +1,3 (at)(at)
-coding: utf-8
-
Collmex API
===========
(at)(at) -99,7 +97,7 (at)(at)
>>> item['Rechnungsnummer'] = 100000
>>> item['Menge'] = 3
>>> item['Produktnummer'] = 'TEST'
->>> item['Rechnungstext'] = u'item text – with non-ascii
characters'
+>>> item['Rechnungstext'] = u'item text \u2013 with non-ascii
characters'
>>> item['Positionstyp'] = 0
>>> collmex.create_invoice([item])
|
SVN: r7345 - in gocept.collmex/tags/0.5: . src/gocept/collmex
Wolfgang Schnerring <ws(at)gocept.com> |
2008-12-19 12:12:09 |
[ FULL ]
|
Author: wosc
Date: Fri Dec 19 12:12:08 2008
New Revision: 7345
Log:
released 0.5
Modified:
gocept.collmex/tags/0.5/CHANGES.txt
gocept.collmex/tags/0.5/setup.py
gocept.collmex/tags/0.5/src/gocept/collmex/README.txt
Modified: gocept.collmex/tags/0.5/CHANGES.txt
==============================================================================
--- gocept.collmex/tags/0.5/CHANGES.txt (original)
+++ gocept.collmex/tags/0.5/CHANGES.txt Fri Dec 19 12:12:08 2008
(at)(at) -1,7 +1,7 (at)(at)
Changes
=======
-0.5 (unreleased)
+0.5 (2008-12-19)
----------------
- Values returned from Collmex are converted to unicode.
Modified: gocept.collmex/tags/0.5/setup.py
==============================================================================
--- gocept.collmex/tags/0.5/setup.py (original)
+++ gocept.collmex/tags/0.5/setup.py Fri Dec 19 12:12:08 2008
(at)(at) -7,7 +7,7 (at)(at)
setup(
name='gocept.collmex',
- version='0.5dev',
+ version='0.5',
author='gocept',
author_email='mail(at)gocept.com',
description='Python-bindings for the Collmex import/export API',
Modified: gocept.collmex/tags/0.5/src/gocept/collmex/README.txt
==============================================================================
--- gocept.collmex/tags/0.5/src/gocept/collmex/README.txt (original)
+++ gocept.collmex/tags/0.5/src/gocept/collmex/README.txt Fri Dec 19 12:12:08
2008
(at)(at) -1,5 +1,3 (at)(at)
-coding: utf-8
-
Collmex API
===========
(at)(at) -99,7 +97,7 (at)(at)
>>> item['Rechnungsnummer'] = 100000
>>> item['Menge'] = 3
>>> item['Produktnummer'] = 'TEST'
->>> item['Rechnungstext'] = u'item text – with non-ascii
characters'
+>>> item['Rechnungstext'] = u'item text \u2013 with non-ascii
characters'
>>> item['Positionstyp'] = 0
>>> collmex.create_invoice([item])
|
SVN: r7361 - gocept.webmail/trunk/gocept/webmail
Christian Theune <ct(at)gocept.com> |
2008-12-22 14:30:18 |
[ FULL ]
|
Author: ctheune
Date: Mon Dec 22 14:30:17 2008
New Revision: 7361
Log:
Remove experimental XML comparison code. See LXML for better solutions.
Removed:
gocept.webmail/trunk/gocept/webmail/xmlcompare.py
gocept.webmail/trunk/gocept/webmail/xmlcompare.txt
Modified:
gocept.webmail/trunk/gocept/webmail/tests.py
Modified: gocept.webmail/trunk/gocept/webmail/tests.py
==============================================================================
--- gocept.webmail/trunk/gocept/webmail/tests.py (original)
+++ gocept.webmail/trunk/gocept/webmail/tests.py Mon Dec 22 14:30:17 2008
(at)(at) -56,9 +56,6 (at)(at)
def test_suite():
suite = unittest.TestSuite()
return suite # XXX No tests. :(
- suite.addTest(doctest.DocFileSuite(
- 'xmlcompare.txt',
- optionflags=flags))
suite.addTest(gocept.restmail.tests.FunctionalDocFileSuite(
'README.txt',
globs=dict(Browser=zc.testbrowser.real.Browser),
|
|