from Products.CMFPlone.Portal import addPolicy
from Products.CMFCore.utils import getToolByName
from Products.CMFCore.Expression import Expression
from Products.CMFCore import CMFCorePermissions
from Products.CMFCore.DirectoryView import addDirectoryViews, registerDirectory
from Products.CMFPlone.CustomizationPolicy import DefaultCustomizationPolicy
import sys
class PACCustomizationPolicy(DefaultCustomizationPolicy):
""" Customize plone a bit for the Public Action Center """
def __init__(self):
pass
def log(self, msg):
sys.stderr.write(msg + '\n')
def customize(self, portal):
# Default setup takes care of most stuff
DefaultCustomizationPolicy.customize(self, portal)
# Some tweaking...
self.setup_memberdata(portal)
self.setup_skins(portal)
self.assignTitles(portal)
# Being an obnoxious Uninted Statsian here...
portal.portal_properties.site_properties._updateProperty('localTimeFormat', '%b. %d, %y')
portal.portal_properties.site_properties._updateProperty('localLongTimeFormat', '%b. %d, %y %I:%M %p')
def setup_memberdata(self, portal):
"""Add some custom properties to the memberdata tool."""
memberdata_tool=getToolByName(portal, 'portal_memberdata')
props = []
# User entered information
props.append(['birthdate', '01-01-2000', 'date'])
props.append(['first_name', '', 'string'])
props.append(['middle_name', '', 'string'])
props.append(['last_name', '', 'string'])
props.append(['address1', '', 'string'])
props.append(['address2', '', 'string'])
props.append(['city', '', 'string'])
# For now we are using PSV (pipe seperated values) to allow <option
# value="AL">Alabama</option>. In the future I hope there will be a
# more elegant solution (such as Zope properties that allow
# multi-dimensional tuples or something). It has been suggested that I
# simply code these select vocabularies into python somewhere else so I
# can properly use dicts of tuples and whatnot, but I prefere to give
# the end-administrator the opportunity to modify the values via the
# ZMI than to require any sort of python hacking on the filesystem.
# Taken from http://www.usps.com/ncsc/lookups/usps_abbreviations.html
# props.append(['us_state_options', [
# 'AL|Alabama',
# 'AK|Alaska',
# 'AS|American Samoa',
# 'AZ|Arizona',
# 'AR|Arkansas',
# 'CA|California',
# 'CO|Colorado',
# 'CT|Connecticut',
# 'DE|Deleware',
# 'DC|District of Columbia',
# 'FM|Federated States of Micronesia',
# 'FL|Florida',
# 'GA|Georgia',
# 'GU|Guam',
# 'HI|Hawaii',
# 'ID|Idaho',
# 'IL|Illinois',
# 'IN|Indiana',
# 'IA|Iowa',
# 'KS|Kansas',
# 'KY|Kentucky',
# 'LA|Louisiana',
# 'ME|Maine',
# 'MH|Marshall Islands',
# 'MD|Maryland',
# 'MA|Massachusetts',
# 'MI|Michigan',
# 'MN|Minnesota',
# 'MS|Mississippi',
# 'MO|Missouri',
# 'MT|Montana',
# 'NE|Nebraska',
# 'NV|Nevada',
# 'NH|New Hampshire',
# 'NJ|New Jersey',
# 'NM|New Mexico',
# 'NY|New York',
# 'NC|North Carolina',
# 'ND|North Dakota',
# 'MP|Northern Mariana Islands',
# 'OH|Ohio',
# 'OK|Oklahoma',
# 'OR|Oregon',
# 'PW|Palau',
# 'PA|Pennsylvania',
# 'PR|Puerto Rico',
# 'RI|Rhode Island',
# 'SC|South Carolina',
# 'SD|South Dakota',
# 'TN|Tennessee',
# 'TX|Texas',
# 'UT|Utah',
# 'VT|Vermont',
# 'VI|Vrigin Islands',
# 'VA|Virginia',
# 'WA|Washington',
# 'WV|West Virginia',
# 'WI|Wisocnsin',
# 'WY|Wyoming'
# ], 'lines'])
# props.append(['us_state', 'us_state_options', 'selection'])
props.append(['us_state', '', 'string'])
props.append(['zipcode', '', 'string'])
props.append(['county', '', 'string'])
# props.append(['country_options',[
# '0|US United States',
# '1|AF Afghanistan',
# '2|AL Albania',
# '3|DZ Algeria',
# '4|AS American Samoa',
# '5|AD Andorra',
# '6|AO Angola',
# '7|AI Anguilla',
# '8|AQ Antarctica',
# '9|AG Antigua and Barbuda',
# '10|AR Argentina',
# '11|AM Armenia',
# '12|AW Aruba',
# '13|AU Australia',
# '14|AT Austria',
# '15|AZ Azerbaijan',
# '16|BS Bahamas',
# '17|BH Bahrain',
# '18|FQ Baker Island',
# '19|BD Bangladesh',
# '20|BB Barbados',
# '21|BE Belgium',
# '22|BZ Belize',
# '23|BJ Benin',
# '24|BM Bermuda',
# '25|BT Bhutan',
# '26|BO Bolivia',
# '27|BA Bosnia and Herzegovina',
# '28|BW Botswana',
# '29|BV Bouvet Island',
# '30|BR Brazil',
# '31|IO British Indian Ocean Territory',
# '32|VG British Virgin Islands',
# '33|BN Brunei',
# '34|BG Bulgaria',
# '35|BF Burkina Faso',
# '36|BI Burundi',
# '37|BU Byelarus',
# '38|KH Cambodia',
# '39|CM Cameroon',
# '40|CA Canada',
# '41|CV Cape Verde',
# '42|KY Cayman Islands',
# '43|CF Central African Republic',
# '44|TD Chad',
# '45|CL Chile',
# '46|CN China',
# '47|CX Christmas Island',
# '48|CC Cocos (Keeling) Islands',
# '49|CO Colombia',
# '50|KM Comoros',
# '51|CG Congo',
# '52|CK Cook Islands',
# '53|CR Costa Rica',
# '54|HR Croatia',
# '55|CU Cuba',
# '56|CY Cyprus',
# '57|CZ Czech Republic',
# '58|DK Denmark',
# '59|DJ Djibouti',
# '60|DM Dominica',
# '61|DO Dominican Republic',
# '62|TP East Timor',
# '63|EC Ecuador',
# '64|EG Egypt',
# '65|SV El Salvador',
# '66|GQ Equatorial Guinea',
# '67|ER Eritrea',
# '68|EE Estonia',
# '69|ET Ethiopia',
# '70|FK Falkland Islands (Islas Malvin)',
# '71|FO Faroe Islands',
# '72|FM Federated States of Micronesia',
# '73|FJ Fiji',
# '74|FI Finland',
# '75|FR France',
# '76|FG French Guiana',
# '77|PF French Polynesia',
# '78|TF French Southern & Antarctic La',
# '79|GA Gabon',
# '80|GM Gambia',
# '81|GZ Gaza Strip',
# '82|GE Georgia',
# '83|DE Germany',
# '84|GH Ghana',
# '85|GI Gibraltar',
# '86|GO Glorioso Islands',
# '87|GR Greece',
# '88|GL Greenland',
# '89|GD Grenada',
# '90|GP Guadeloupe',
# '91|GU Guam',
# '92|GT Guatemala',
# '93|GK Guernsey',
# '94|GN Guinea',
# '95|GW Guinea-Bissau',
# '96|GY Guyana',
# '97|HT Haiti',
# '98|HM Heard Island & McDonald Island',
# '99|VA Holy See (Vatican State)',
# '100|HN Honduras',
# '101|HK Hong Kong, China',
# '102|HQ Howland Island',
# '103|HU Hungary',
# '104|IS Iceland',
# '105|IN India',
# '106|ID Indonesia',
# '107|IR Iran',
# '108|IQ Iraq',
# '109|IE Ireland',
# '110|IL Israel',
# '111|IT Italy',
# '112|CI Ivory Coast',
# '113|JM Jamaica',
# '114|JN Jan Mayen',
# '115|JP Japan',
# '116|DQ Jarvis Island',
# '117|JE Jersey',
# '118|JQ Johnston Atoll',
# '119|JO Jordan',
# '120|JU Juan De Nova Island',
# '121|KZ Kazakhstan',
# '122|KE Kenya',
# '123|KI Kiribati',
# '124|KW Kuwait',
# '125|KG Kyrgyzstan',
# '126|LA Laos',
# '127|LV Latvia',
# '128|LB Lebanon',
# '129|LS Lesotho',
# '130|LR Liberia',
# '131|LY Libya',
# '132|LI Liechtenstein',
# '133|LT Lithuania',
# '134|LU Luxembourg',
# '135|MO Macau',
# '136|MK Macedonia',
# '137|MG Madagascar',
# '138|MW Malawi',
# '139|MY Malaysia',
# '140|MV Maldives',
# '141|ML Mali',
# '142|MT Malta',
# '143|IM Man',
# '144|MH Marshall Islands',
# '145|MQ Martinique',
# '146|MR Mauritania',
# '147|MU Mauritius',
# '148|YT Mayotte',
# '149|MX Mexico',
# '150|MI Midway Islands',
# '151|MD Moldova',
# '152|MC Monaco',
# '153|MN Mongolia',
# '154|ME Montenegro',
# '155|MS Montserrat',
# '156|MA Morocco',
# '157|MZ Mozambique',
# '158|MM Myanmar (Burma)',
# '159|NA Namibia',
# '160|NR Nauru',
# '161|NP Nepal',
# '162|NL Netherlands',
# '163|AN Netherlands Antilles',
# '164|NC New Caledonia',
# '165|NZ New Zealand',
# '166|NI Nicaragua',
# '167|NE Niger',
# '168|NG Nigeria',
# '169|NU Niue',
# '170|NF Norfolk Island',
# '171|KP North Korea',
# '172|MP Northern Mariana Islands',
# '173|NO Norway',
# '174|OM Oman',
# '175|PK Pakistan',
# '176|PW Palau',
# '177|PA Panama',
# '178|PG Papua New Guinea',
# '179|PI Paracel Islands',
# '180|PY Paraguay',
# '181|PE Peru',
# '182|PH Philippines',
# '183|PN Pitcairn Islands',
# '184|PL Poland',
# '185|PT Portugal',
# '186|PR Puerto Rico',
# '187|QA Qatar',
# '188|RE Reunion',
# '189|RO Romania',
# '190|RU Russia',
# '191|RW Rwanda',
# '192|WS Samoa',
# '193|SM San Marino',
# '194|ST Sao Tome and Principe',
# '195|SA Saudi Arabia',
# '196|SN Senegal',
# '197|SS Serbia',
# '198|SC Seychelles',
# '199|SL Sierra Leone',
# '200|SG Singapore',
# '201|SK Slovakia',
# '202|SI Slovenia',
# '203|SB Solomon Islands',
# '204|SO Somalia',
# '205|ZA South Africa',
# '206|GS South Georgia and the South Seas',
# '207|KR South Korea',
# '208|ES Spain',
# '209|PG Spratly Islands',
# '210|LK Sri Lanka',
# '211|SH St. Helena',
# '212|KN St. Kitts and Nevis',
# '213|LC St. Lucia',
# '214|PM St. Pierre and Miquelon',
# '215|VC St. Vincent and the Grenadines',
# '216|SD Sudan',
# '217|SR Suriname',
# '218|SJ Svalbard',
# '219|SZ Swaziland',
# '220|SE Sweden',
# '221|CH Switzerland',
# '222|SY Syria',
# '223|TW Taiwan',
# '224|TJ Tajikistan',
# '225|TZ Tanzania',
# '226|TH Thailand',
# '227|TG Togo',
# '228|TK Tokelau',
# '229|TO Tonga',
# '230|TT Trinidad and Tobago',
# '231|TN Tunisia',
# '232|TR Turkey',
# '233|TM Turkmenistan',
# '234|TC Turks and Caicos Islands',
# '235|TV Tuvalu',
# '236|UG Uganda',
# '237|UA Ukraine',
# '238|AE United Arab Emirates',
# '239|GB United Kingdom',
# '241|UM United States Minor Outlying I',
# '242|UY Uruguay',
# '243|UZ Uzbekistan',
# '244|VU Vanuatu',
# '245|VE Venezuela',
# '246|VN Vietnam',
# '247|VI Virgin Islands',
# '248|WQ Wake Island',
# '249|WF Wallis and Futuna',
# '250|WE West Bank',
# '251|EH Western Sahara',
# '252|WA Western Samoa',
# '253|YE Yemen',
# '254|YU Yugoslavia',
# '255|CD Zaire',
# '256|ZM Zambia',
# '257|ZW Zimbabwe',
# '-1|Other',
# ], 'lines'])
# props.append(['country', 'country_options',
# 'selection'])
# props.append(['country_other', '', 'string'])
props.append(['country', '', 'string'])
props.append(['day_phone', '', 'string'])
props.append(['evening_phone', '', 'string'])
# Prefer html email over text/plain?
props.append(['html_email', '', 'boolean'])
# What field are you in?
props.append(['profession', '', 'string'])
# Employer (eg, AT&T, US Government, Bobs Big Boy...)
props.append(['organization', '', 'string'])
# Position held (eg. CTO, Janitor, Grand Inquisitor...)
props.append(['position', '', 'string'])
# Oranizations affiliated with (Phi Beta Kappa, Mensa, IWW...)
props.append(['affiliations', '', 'lines'])
# If you went to university, where did you go?
props.append(['university', '', 'string'])
# When did you or will you graduate?
props.append(['graduated', '01-01-2000', 'date'])
# Highest degree earned ...where/when
props.append(['highest_university', '', 'string'])
props.append(['highest_graduated', '01-01-2000', 'date'])
# Previous contact with legislators
# props.append(['previous_contact_options', [
# '0|No contact at all',
# "1|I've attended an event, speech or seen them at another public event",
# "2|I voted for them in the last election",
# "3|I donated money to their last election campaign",
# "4|I volunteered for, or staffed, their election campaign",
# "5|I'm personally or professionally associated with them",
# "6|I've worked closely with them on another issue"
# ], 'lines'])
# props.append(['previous_contact', 'previous_contact_options',
# 'selection'])
props.append(['previous_contact', '', 'string'])
# This belongs in PK specific setup.
# # Would you like to volunteer for...
# props.append(['volunteer_options',[
# '0|Writing form letters',
# '1|Becoming a community leader',
# '2|Sponsoring a micro-fundraiser',
# '3|Making a personal visit to my legislator',
# '4|Attending hearings',
# '5|Speaking at hearings',
# "6|Writing 'lettors to the editor'",
# '7|Volunteering in other ways for Public Knowledge (see below)'
# ], 'lines'])
# props.append(['volunteer', 'volunteer_options', 'multiple selection'])
# props.append(['volunteer_other', '', 'string'])
# Are you a registered voter?
props.append(['stat_voter', '', 'boolean'])
# Are you now or have you ever been a member of the Communist Party?
# props.append(['stat_party_options',[
# '0|Democrat',
# '6|Communist',
# '1|Green',
# '2|Independent',
# '3|Libertarian',
# '4|Republican',
# '-1|Other'
# ], 'lines'])
# props.append(['stat_party', 'stat_party_options', 'selection'])
# props.append(['stat_party_other', '', 'string'])
props.append(['stat_party', '', 'string'])
# Number of computers
props.append(['num_computers', '0', 'int'])
# Internet connection
# props.append(['stat_connection_options', [
# '0|Cable',
# '1|Dial-Up',
# '2|DSL',
# '3|Wireless',
# '-1|Other'
# ], 'lines'])
# props.append(['stat_connection', 'stat_connection_options', 'selection'])
# props.append(['stat_connection_other', '', 'string'])
props.append(['stat_connection', '', 'string'])
# Use p2p networks?
props.append(['stat_use_p2p', '', 'boolean'])
# How did you hear about us?
# props.append(['stat_hearabout_options',[
# '0|Website (enter site name below)',
# '1|News article (enter publication below)',
# '2|Search engine',
# '3|Word of mouth',
# '4|Conference or event (enter name below)'
# ], 'lines'])
# props.append(['stat_hearabout', 'stat_hearabout_options', 'selection'])
# props.append(['stat_hearabout_other', '', 'string'])
props.append(['stat_hearabout', '', 'string'])
# Some information the user won't enter:
props.append(['referrer_url', '', 'string'])
# Add the properties
for prop in props:
if hasattr(memberdata_tool, prop[0]):
self.log ("portal_memberdata '%s' is installed already." % prop[0])
else:
memberdata_tool.manage_addProperty(prop[0], prop[1], prop[2])
self.log('portal_memberdata sucessfully set up.')
def setup_skins(self, portal):
dirs = ('pac_styles',
'pac_forms')
sk_tool = getToolByName(portal, 'portal_skins')
path=[elem.strip() for elem in sk_tool.getSkinPath('Plone Default').split(',')]
for d in dirs:
try:
path.insert(path.index('custom')+1, d)
except ValueError:
path.append(d)
path=','.join(path)
sk_tool.addSkinSelection('Public Action Center', path)
addDirectoryViews(sk_tool, 'skins', globals())
sk_tool.default_skin = 'Public Action Center'
def assignTitles(self, portal):
titles = {'plone_utils':'Various Plone Utility methods',}
for o in portal.objectValues():
title=titles.get(o.getId(), None)
if title:
o.title=title
def register(context, app_state):
addPolicy('Public Action Center', PACCustomizationPolicy())