Mercurial > p > roundup > code
comparison roundup/cgi/client.py @ 1905:dc43e339e607
Centralised conversion of user-input data to hyperdb values
(bug [SF#802405], bug [SF#817217], rfe [SF#816994])
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Tue, 11 Nov 2003 00:35:14 +0000 |
| parents | dc6f2155e5b4 |
| children | f5c804379c85 |
comparison
equal
deleted
inserted
replaced
| 1904:9445caec3ff5 | 1905:dc43e339e607 |
|---|---|
| 1 # $Id: client.py,v 1.143 2003-10-24 09:32:19 jlgijsbers Exp $ | 1 # $Id: client.py,v 1.144 2003-11-11 00:35:14 richard Exp $ |
| 2 | 2 |
| 3 __doc__ = """ | 3 __doc__ = """ |
| 4 WWW request handler (also used in the stand-alone server). | 4 WWW request handler (also used in the stand-alone server). |
| 5 """ | 5 """ |
| 6 | 6 |
| 1673 raise FormError, 'You have submitted more than one value'\ | 1673 raise FormError, 'You have submitted more than one value'\ |
| 1674 ' for the %s property'%propname | 1674 ' for the %s property'%propname |
| 1675 if value != confirm.value: | 1675 if value != confirm.value: |
| 1676 raise FormError, 'Password and confirmation text do '\ | 1676 raise FormError, 'Password and confirmation text do '\ |
| 1677 'not match' | 1677 'not match' |
| 1678 value = password.Password(value) | 1678 try: |
| 1679 | 1679 value = password.Password(value) |
| 1680 elif isinstance(proptype, hyperdb.Link): | 1680 except hyperdb.HyperdbValueError, msg: |
| 1681 # see if it's the "no selection" choice | 1681 raise FormError, msg |
| 1682 if value == '-1' or not value: | 1682 |
| 1683 # if we're creating, just don't include this property | |
| 1684 if not nodeid or nodeid.startswith('-'): | |
| 1685 continue | |
| 1686 value = None | |
| 1687 else: | |
| 1688 # handle key values | |
| 1689 link = proptype.classname | |
| 1690 if not num_re.match(value): | |
| 1691 try: | |
| 1692 value = db.classes[link].lookup(value) | |
| 1693 except KeyError: | |
| 1694 raise FormError, _('property "%(propname)s": ' | |
| 1695 '%(value)s not a %(classname)s')%{ | |
| 1696 'propname': propname, 'value': value, | |
| 1697 'classname': link} | |
| 1698 except TypeError, message: | |
| 1699 raise FormError, _('you may only enter ID values ' | |
| 1700 'for property "%(propname)s": %(message)s')%{ | |
| 1701 'propname': propname, 'message': message} | |
| 1702 elif isinstance(proptype, hyperdb.Multilink): | 1683 elif isinstance(proptype, hyperdb.Multilink): |
| 1703 # perform link class key value lookup if necessary | 1684 # convert input to list of ids |
| 1704 link = proptype.classname | 1685 try: |
| 1705 link_cl = db.classes[link] | 1686 l = hyperdb.rawToHyperdb(self.db, cl, nodeid, |
| 1706 l = [] | 1687 propname, value) |
| 1707 for entry in value: | 1688 except hyperdb.HyperdbValueError, msg: |
| 1708 if not entry: continue | 1689 raise FormError, msg |
| 1709 if not num_re.match(entry): | |
| 1710 try: | |
| 1711 entry = link_cl.lookup(entry) | |
| 1712 except KeyError: | |
| 1713 raise FormError, _('property "%(propname)s": ' | |
| 1714 '"%(value)s" not an entry of %(classname)s')%{ | |
| 1715 'propname': propname, 'value': entry, | |
| 1716 'classname': link} | |
| 1717 except TypeError, message: | |
| 1718 raise FormError, _('you may only enter ID values ' | |
| 1719 'for property "%(propname)s": %(message)s')%{ | |
| 1720 'propname': propname, 'message': message} | |
| 1721 l.append(entry) | |
| 1722 l.sort() | |
| 1723 | 1690 |
| 1724 # now use that list of ids to modify the multilink | 1691 # now use that list of ids to modify the multilink |
| 1725 if mlaction == 'set': | 1692 if mlaction == 'set': |
| 1726 value = l | 1693 value = l |
| 1727 else: | 1694 else: |
| 1751 existing.append(entry) | 1718 existing.append(entry) |
| 1752 value = existing | 1719 value = existing |
| 1753 value.sort() | 1720 value.sort() |
| 1754 | 1721 |
| 1755 elif value == '': | 1722 elif value == '': |
| 1756 # if we're creating, just don't include this property | |
| 1757 if not nodeid or nodeid.startswith('-'): | |
| 1758 continue | |
| 1759 # other types should be None'd if there's no value | 1723 # other types should be None'd if there's no value |
| 1760 value = None | 1724 value = None |
| 1761 else: | 1725 else: |
| 1762 # handle ValueErrors for all these in a similar fashion | 1726 # handle all other types |
| 1763 try: | 1727 try: |
| 1764 if isinstance(proptype, hyperdb.String): | 1728 if isinstance(proptype, hyperdb.String): |
| 1765 if (hasattr(value, 'filename') and | 1729 if (hasattr(value, 'filename') and |
| 1766 value.filename is not None): | 1730 value.filename is not None): |
| 1767 # skip if the upload is empty | 1731 # skip if the upload is empty |
| 1775 # use this info as the type/filename properties | 1739 # use this info as the type/filename properties |
| 1776 if propdef.has_key('type'): | 1740 if propdef.has_key('type'): |
| 1777 props['type'] = mimetypes.guess_type(fn)[0] | 1741 props['type'] = mimetypes.guess_type(fn)[0] |
| 1778 if not props['type']: | 1742 if not props['type']: |
| 1779 props['type'] = "application/octet-stream" | 1743 props['type'] = "application/octet-stream" |
| 1780 # finally, read the content | 1744 # finally, read the content RAW |
| 1781 value = value.value | 1745 value = value.value |
| 1782 else: | 1746 else: |
| 1783 # normal String fix the CRLF/CR -> LF stuff | 1747 value = hyperdb.rawToHyperdb(self.db, cl, |
| 1784 value = fixNewlines(value) | 1748 nodeid, propname, value) |
| 1785 | 1749 |
| 1786 elif isinstance(proptype, hyperdb.Date): | 1750 else: |
| 1787 value = date.Date(value, offset=timezone) | 1751 value = hyperdb.rawToHyperdb(self.db, cl, nodeid, |
| 1788 elif isinstance(proptype, hyperdb.Interval): | 1752 propname, value) |
| 1789 value = date.Interval(value) | 1753 except hyperdb.HyperdbValueError, msg: |
| 1790 elif isinstance(proptype, hyperdb.Boolean): | 1754 raise FormError, msg |
| 1791 value = value.lower() in ('yes', 'true', 'on', '1') | |
| 1792 elif isinstance(proptype, hyperdb.Number): | |
| 1793 value = float(value) | |
| 1794 except ValueError, msg: | |
| 1795 raise FormError, _('Error with %s property: %s')%( | |
| 1796 propname, msg) | |
| 1797 | 1755 |
| 1798 # register that we got this property | 1756 # register that we got this property |
| 1799 if value: | 1757 if value: |
| 1800 got_props[this][propname] = 1 | 1758 got_props[this][propname] = 1 |
| 1801 | 1759 |
| 1878 if not props.get('content', ''): | 1836 if not props.get('content', ''): |
| 1879 del all_props[(cn, id)] | 1837 del all_props[(cn, id)] |
| 1880 elif props.has_key('content') and not props['content']: | 1838 elif props.has_key('content') and not props['content']: |
| 1881 raise FormError, _('File is empty') | 1839 raise FormError, _('File is empty') |
| 1882 return all_props, all_links | 1840 return all_props, all_links |
| 1883 | |
| 1884 def fixNewlines(text): | |
| 1885 ''' Homogenise line endings. | |
| 1886 | |
| 1887 Different web clients send different line ending values, but | |
| 1888 other systems (eg. email) don't necessarily handle those line | |
| 1889 endings. Our solution is to convert all line endings to LF. | |
| 1890 ''' | |
| 1891 text = text.replace('\r\n', '\n') | |
| 1892 return text.replace('\r', '\n') | |
| 1893 | 1841 |
| 1894 def extractFormList(value): | 1842 def extractFormList(value): |
| 1895 ''' Extract a list of values from the form value. | 1843 ''' Extract a list of values from the form value. |
| 1896 | 1844 |
| 1897 It may be one of: | 1845 It may be one of: |
