# encoding: utf-8 require "express_pigeon/version" require 'active_model' require 'curb-fu' require 'active_model/validations/date_format_validator' module ExpressPigeon module WebFormHelpers def express_pigeon_states { "Alaska" => "AK", "Alabama" => "AL", "Arkansas" => "AR", "Arizona" => "AZ", "California" => "CA", "Colorado" => "CO", "Connecticut" => "CT", "Delaware" => "DE", "Florida" => "FL", "Georgia" => "GA", "Hawaii" => "HI", "Iowa" => "IA", "Idaho" => "ID", "Illinois" => "IL", "Indiana" => "IN", "Kansas" => "KS", "Kentucky" => "KY", "Louisiana" => "LA", "Massachusetts" => "MA", "Maryland" => "MD", "Maine" => "ME", "Michigan" => "MI", "Minnesota" => "MN", "Missouri" => "MO", "Mississippi" => "MS", "Montana" => "MT", "North Carolina" => "NC", "North Dakota" => "ND", "Nebraska" => "NE", "New Hampshire" => "NH", "New Jersey" => "NJ", "New Mexico" => "NM", "Nevada" => "NV", "New York" => "NY", "Ohio" => "OH", "Oklahoma" => "OK", "Oregon" => "OR", "Pennsylvania" => "PA", "Rhode Island" => "RI", "South Carolina" => "SC", "South Dakota" => "SD", "Tennessee" => "TN", "Texas" => "TX", "Utah" => "UT", "Virginia" => "VA", "Vermont" => "VT", "Washington" => "WA", "Wisconsin" => "WI", "West Virginia" => "WV", "Wyoming" => "WY", } end def express_pigeon_countries { "Afghanistan" => "Afghanistan", "Albania" => "Albania", "Algeria" => "Algeria", "American Samoa" => "American Samoa", "Andorra" => "Andorra", "Angola" => "Angola", "Anguilla" => "Anguilla", "Antarctica" => "Antarctica", "Antigua and Barbuda" => "Antigua and Barbuda", "Argentina" => "Argentina", "Armenia" => "Armenia", "Aruba" => "Aruba", "Australia" => "Australia", "Austria" => "Austria", "Azerbaijan" => "Azerbaijan", "Bahamas" => "Bahamas", "Bahrain" => "Bahrain", "Bangladesh" => "Bangladesh", "Barbados" => "Barbados", "Belarus" => "Belarus", "Belgium" => "Belgium", "Belize" => "Belize", "Benin" => "Benin", "Bermuda" => "Bermuda", "Bhutan" => "Bhutan", "Bolivia" => "Bolivia", "Bosnia and Herzegovina" => "Bosnia and Herzegovina", "Botswana" => "Botswana", "Brazil" => "Brazil", "British Indian Ocean Territory" => "British Indian Ocean Territory", "Brunei" => "Brunei", "Bulgaria" => "Bulgaria", "Burkina Faso" => "Burkina Faso", "Burundi" => "Burundi", "Cambodia" => "Cambodia", "Cameroon" => "Cameroon", "Canada" => "Canada", "Cape Verde" => "Cape Verde", "Cayman Islands" => "Cayman Islands", "Central African Republic" => "Central African Republic", "Chad" => "Chad", "Chile" => "Chile", "China" => "China", "Christmas Island" => "Christmas Island", "Cocos Islands" => "Cocos Islands", "Colombia" => "Colombia", "Comoros" => "Comoros", "Congo" => "Congo", "Congo, Democratic Republic of the" => "Congo, Democratic Republic of the", "Cook Islands" => "Cook Islands", "Costa Rica" => "Costa Rica", "Croatia" => "Croatia", "Cuba" => "Cuba", "Cyprus" => "Cyprus", "Czech Republic" => "Czech Republic", "Côte d'Ivoire" => "Côte d'Ivoire", "Denmark" => "Denmark", "Djibouti" => "Djibouti", "Dominica" => "Dominica", "Dominican Republic" => "Dominican Republic", "Ecuador" => "Ecuador", "Egypt" => "Egypt", "El Salvador" => "El Salvador", "Equatorial Guinea (Guinea Ecuatorial)" => "Equatorial Guinea (Guinea Ecuatorial)", "Eritrea" => "Eritrea", "Estonia" => "Estonia", "Ethiopia" => "Ethiopia", "Falkland Islands" => "Falkland Islands", "Faroe Islands" => "Faroe Islands", "Fiji" => "Fiji", "Finland" => "Finland", "France" => "France", "French Guiana" => "French Guiana", "French Polynesia" => "French Polynesia", "French Southern Territories" => "French Southern Territories", "Gabon" => "Gabon", "Gambia" => "Gambia", "Georgia" => "Georgia", "Germany" => "Germany", "Ghana" => "Ghana", "Gibraltar" => "Gibraltar", "Greece" => "Greece", "Greenland" => "Greenland", "Grenada" => "Grenada", "Guadeloupe" => "Guadeloupe", "Guam" => "Guam", "Guatemala" => "Guatemala", "Guinea" => "Guinea", "Guinea-Bissau" => "Guinea-Bissau", "Guyana" => "Guyana", "Haiti" => "Haiti", "Honduras" => "Honduras", "Hong Kong" => "Hong Kong", "Hungary" => "Hungary", "Iceland" => "Iceland", "India" => "India", "Indonesia" => "Indonesia", "Iran" => "Iran", "Iraq" => "Iraq", "Ireland" => "Ireland", "Israel" => "Israel", "Italy" => "Italy", "Jamaica" => "Jamaica", "Japan" => "Japan", "Jordan" => "Jordan", "Kazakhstan" => "Kazakhstan", "Kenya" => "Kenya", "Kiribati" => "Kiribati", "Kuwait" => "Kuwait", "Kyrgyzstan" => "Kyrgyzstan", "Laos" => "Laos", "Latvia" => "Latvia", "Lebanon" => "Lebanon", "Lesotho" => "Lesotho", "Liberia" => "Liberia", "Libya" => "Libya", "Liechtenstein" => "Liechtenstein", "Lithuania" => "Lithuania", "Luxembourg" => "Luxembourg", "Macao" => "Macao", "Macedonia" => "Macedonia", "Madagascar" => "Madagascar", "Malawi" => "Malawi", "Malaysia" => "Malaysia", "Maldives" => "Maldives", "Mali" => "Mali", "Malta" => "Malta", "Marshall Islands" => "Marshall Islands", "Martinique" => "Martinique", "Mauritania" => "Mauritania", "Mauritius" => "Mauritius", "Mayotte" => "Mayotte", "Mexico" => "Mexico", "Micronesia" => "Micronesia", "Moldova" => "Moldova", "Monaco" => "Monaco", "Mongolia" => "Mongolia", "Montenegro" => "Montenegro", "Montserrat" => "Montserrat", "Morocco" => "Morocco", "Mozambique" => "Mozambique", "Myanmar" => "Myanmar", "Namibia" => "Namibia", "Nauru" => "Nauru", "Nepal" => "Nepal", "Netherlands Antilles" => "Netherlands Antilles", "Netherlands" => "Netherlands", "New Caledonia" => "New Caledonia", "New Zealand" => "New Zealand", "Nicaragua" => "Nicaragua", "Niger" => "Niger", "Nigeria" => "Nigeria", "Niue" => "Niue", "Norfolk Island" => "Norfolk Island", "North Korea" => "North Korea", "Northern Mariana Islands" => "Northern Mariana Islands", "Norway" => "Norway", "Oman" => "Oman", "Pakistan" => "Pakistan", "Palau" => "Palau", "Palestinian Territories" => "Palestinian Territories", "Panama" => "Panama", "Papua New Guinea" => "Papua New Guinea", "Paraguay" => "Paraguay", "Peru" => "Peru", "Philippines" => "Philippines", "Pitcairn" => "Pitcairn", "Poland" => "Poland", "Portugal" => "Portugal", "Puerto Rico" => "Puerto Rico", "Qatar" => "Qatar", "Reunion" => "Reunion", "Romania" => "Romania", "Russia" => "Russia", "Rwanda" => "Rwanda", "Saint Helena" => "Saint Helena", "Saint Kitts and Nevis" => "Saint Kitts and Nevis", "Saint Lucia" => "Saint Lucia", "Saint Pierre and Miquelon" => "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines" => "Saint Vincent and the Grenadines", "Samoa" => "Samoa", "San Marino" => "San Marino", "Saudi Arabia" => "Saudi Arabia", "Senegal" => "Senegal", "Serbia" => "Serbia", "Seychelles" => "Seychelles", "Sierra Leone" => "Sierra Leone", "Singapore" => "Singapore", "Slovakia" => "Slovakia", "Slovenia" => "Slovenia", "Solomon Islands" => "Solomon Islands", "Somalia" => "Somalia", "South Africa" => "South Africa", "South Georgia and the South Sandwich Islands" => "South Georgia and the South Sandwich Islands", "South Korea" => "South Korea", "Spain" => "Spain", "Sri Lanka" => "Sri Lanka", "Sudan" => "Sudan", "Suriname" => "Suriname", "Svalbard and Jan Mayen" => "Svalbard and Jan Mayen", "Swaziland" => "Swaziland", "Sweden" => "Sweden", "Switzerland" => "Switzerland", "Syria" => "Syria", "São Tomé and Príncipe" => "São Tomé and Príncipe", "Taiwan" => "Taiwan", "Tajikistan" => "Tajikistan", "Tanzania" => "Tanzania", "Thailand" => "Thailand", "Timor-Leste" => "Timor-Leste", "Togo" => "Togo", "Tokelau" => "Tokelau", "Tonga" => "Tonga", "Trinidad and Tobago" => "Trinidad and Tobago", "Tunisia" => "Tunisia", "Turkey" => "Turkey", "Turkmenistan" => "Turkmenistan", "Turks and Caicos Islands" => "Turks and Caicos Islands", "Tuvalu" => "Tuvalu", "Uganda" => "Uganda", "Ukraine" => "Ukraine", "United Arab Emirates" => "United Arab Emirates", "United Kingdom" => "United Kingdom", "United States minor outlying islands" => "United States minor outlying islands", "United States" => "United States", "Uruguay" => "Uruguay", "Uzbekistan" => "Uzbekistan", "Vanuatu" => "Vanuatu", "Vatican City" => "Vatican City", "Venezuela" => "Venezuela", "Vietnam" => "Vietnam", "Virgin Islands, British" => "Virgin Islands, British", "Virgin Islands, U.S." => "Virgin Islands, U.S.", "Wallis and Futuna" => "Wallis and Futuna", "Western Sahara" => "Western Sahara", "Yemen" => "Yemen", "Zambia" => "Zambia", "Zimbabwe" => "Zimbabwe", } end end module WebFormValidations def self.included(base) base.validates :guid, :presence => true base.validates :email, :presence => true, :length => 3..50, :allow_blank => false # TODO check the actual form to see whether a field is required. # # The functionality to check whether a field is actually required # hasn't been implemented yet. Go ahead and just assume they're not # required and just check bounds. base.validates :address1, :length => 0..255, :allow_blank => true base.validates :address2, :length => 0..255, :allow_blank => true base.validates :city, :length => 0..128, :allow_blank => true base.validates :company, :length => 0..128, :allow_blank => true base.validates :country, :length => 0..128, :allow_blank => true # now sure why we can put 255 chars into date of birth but that's what it is. # TODO validate and require date format, submit as MM/DD/YYYY base.validates :date_of_birth, :length => 0..255, :allow_blank => true, :date_format => true # will email_form be a submittable field? base.validates :first_name, :length => 0..50, :allow_blank => true base.validates :last_name, :length => 0..50, :allow_blank => true base.validates :phone, :length => 0..30, :allow_blank => true base.validates :state, :length => 0..48, :allow_blank => true # state is 48? base.validates :title, :length => 0..30, :allow_blank => true base.validates :zip, :length => 0..24, :allow_blank => true # zip is 24? # TODO validate state # TODO validate field sizes end end module WebFormPushable def push_to_express_pigeon! def url; "https://expresspigeon.com/subscription/add_contact"; end params = { :address1 => self.address1, :address2 => self.address2, :city => self.city, :company => self.company, :country => self.country, :date_of_birth => format_date(self.date_of_birth), :email => self.email, :first_name => self.first_name, :guid => self.guid, :last_name => self.last_name, :phone => self.phone, :state => self.state, :title => self.title, :zip => self.zip, } response = CurbFu.post({:url => url}, params) response end def format_date(date) return "" if date.blank? Chronic.parse(date).strftime("%m/%d/%Y") end end class WebForm include ActiveModel::Validations include WebFormValidations include WebFormPushable include ActiveModel::Dirty define_attribute_methods [ :address1, :address2, :city, :company, :country, :date_of_birth, :email, :first_name, :guid, :last_name, :phone, :state, :title, :zip, ] # TODO after submitting the form try to capture the response for errors? def address1 ; @address1 ; end def address2 ; @address2 ; end def city ; @city ; end def company ; @company ; end def country ; @country ; end def date_of_birth ; @date_of_birth ; end def email ; @email ; end def first_name ; @first_name ; end def guid ; @guid ; end def last_name ; @last_name ; end def phone ; @phone ; end def state ; @state ; end def title ; @title ; end def zip ; @zip ; end def address1=(val) ; address1_will_change! unless val == @address1 ; @address1 = val ; end def address2=(val) ; address2_will_change! unless val == @address2 ; @address2 = val ; end def city=(val) ; city_will_change! unless val == @city ; @city = val ; end def company=(val) ; company_will_change! unless val == @company ; @company = val ; end def country=(val) ; country_will_change! unless val == @country ; @country = val ; end def date_of_birth=(val) ; date_of_birth_will_change! unless val == @date_of_birth ; @date_of_birth = val ; end def email=(val) ; email_will_change! unless val == @email ; @email = val ; end def first_name=(val) ; first_name_will_change! unless val == @first_name ; @first_name = val ; end def guid=(val) ; guid_will_change! unless val == @guid ; @guid = val ; end def last_name=(val) ; last_name_will_change! unless val == @last_name ; @last_name = val ; end def phone=(val) ; phone_will_change! unless val == @phone ; @phone = val ; end def state=(val) ; state_will_change! unless val == @state ; @state = val ; end def title=(val) ; title_will_change! unless val == @title ; @title = val ; end def zip=(val) ; zip_will_change! unless val == @zip ; @zip = val ; end def save return false unless self.valid? response = push_to_express_pigeon! if response @previously_changed = changes @changed_attributes.clear end end private end end