"type": "bool", "required": False, "key": "subtotal_toggle", "label": "Create Subtotal Property?", "default": "no", }, { "type": "int", "required": False, "key": "decimals", "label": "Decimal Places for Subtotal Values", "default": "2", }, ] def transform_many(self, inputs, options): """ Throws error if lists or dicts are mapped into the 'Line-item(s) Group Name'/'inputs' field. """ options = options or {} if isinstance(inputs, (dict, list)): self.raise_exception("{}".format(self.lineitems_group_name_error)) else: outputs = self.transform(inputs, **options) return outputs register(UtilLineItemizerTransform())
output = output.replace('(', '').replace(')', '') return output def fields(self, *args, **kwargs): available_formats = { '0': '+15558001212 (E164)', '1': '+1 555-800-1212 (International)', '2': '(555) 800-1212 (National)', '3': '+1-555-800-1212 (RFC3966)', '4': '555-800-1212 (International, No Country Code)', '5': '+1 555 800 1212 (International, No Hyphens)', '6': '555 800-1212 (National, No Parenthesis)', } return [ { 'key': 'format_string', 'type': 'unicode', 'label': 'To Format', 'help_text': 'The format the phone number will be converted to.', 'required': True, 'choices': available_formats, } ] register(PhoneNumberFormattingTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform class StringLowercaseTransform(BaseTransform): category = 'string' name = 'lower_case' label = 'Lowercase' help_text = 'Convert all characters in a string to lowercase' noun = 'Text' verb = 'lowercase' def transform(self, str_input, **kwargs): return str_input.lower() if str_input else u'' register(StringLowercaseTransform())
def transform(self, str_input, use_plus=False, **kwargs): if not str_input: return u'' if use_plus: decoded_text = urllib.unquote_plus(str_input) else: decoded_text = urllib.unquote(str_input) return decoded_text def fields(self, *args, **kwargs): return [ { 'type': 'bool', 'required': False, 'key': 'use_plus', 'label': 'Convert plus to spaces?', 'help_text': 'Will convert "+" to spaces instead of converting "%20", and will _not_ convert "/".', }, ] register(StringURLDecodeTransform())
or the default value if there is none. """ return self.choose_nth(-1, inputs, default=default) def choose_nth(self, n, inputs, default=None): """ choose the n-th _truthy_ string value or the n-th non-string value or the default value if there is neither. """ try: return self.truthy_inputs(inputs)[n] except: pass return default def choose_random(self, inputs, default=None): """ choose a random _truthy_ string value or a random non-string value or the default value if there is neither. """ truthy = self.truthy_inputs(inputs) if not truthy: return default return random.choice(truthy) register(UtilChooseTransform())
index = try_parse_number(index, cls=int) try: return segments[index] except: pass return u'' def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': False, 'key': 'separator', 'label': 'Separator', 'help_text': 'Character or word separator to split the text on. (Default: `[:space:]`) For supported special characters, see: https://zapier.com/help/formatter/#special-characters)' # NOQA }, { 'type': 'unicode', 'required': False, 'key': 'index', 'label': 'Segment Index', 'help_text': 'Segment of text to return after splitting. (Default: First)', 'choices': '0|First,1|Second,-1|Last,-2|Second to Last,all|All (as Line-items),fields|All (as Separate Fields)', }, ] register(StringSplitTransform())
text_ouput = ",".join(inputs) output["text"] = text_ouput # Create Separate Fields for i, v in enumerate(inputs): output["item_" + str(i + 1)] = v output["item_last"] = v return output def fields(self, *args, **kwargs): return [{ "type": "unicode", "required": False, "key": "separator", "label": "Separator", "help_text": ("Character(s) to delimit text with. (Default: ',') " "For supported special characters, see: https://zapier.com/help/formatter/#special-characters)" ), # NOQA }] register(UtilLineItemToStringV2Transform())
'help_text': 'Provide the format that the date is converted to. For date format help, see: https://zapier.com/help/formatter/#date-time' }, { 'type': 'unicode', 'required': False, 'key': 'to_timezone', 'label': 'To Timezone', 'choices': timezones, 'default': 'UTC', 'help_text': 'Choose a timezone the date should be converted to. (Default: UTC)' }, { 'type': 'unicode', 'required': False, 'key': 'from_format', 'choices': choices, 'help_text': 'If we incorrectly interpret the incoming (input) date, set this to explicitly tell us the format. Otherwise, we will do our best to figure it out.' # NOQA }, { 'type': 'unicode', 'required': False, 'key': 'from_timezone', 'label': 'From Timezone', 'choices': timezones, 'default': 'UTC', 'help_text': 'If no timezone is provided in the incoming (input) data, set this to explicitly tell us which to use. (Default: UTC)' # NOQA }, ] register(DateFormattingTransform())
from titlecase import titlecase from transformer.registry import register from transformer.transforms.base import BaseTransform class StringTitlecaseTransform(BaseTransform): category = 'string' name = 'titlecase' label = 'Titlecase' help_text = 'Convert all characters in a string to titlecase' noun = 'Text' verb = 'titlecase' def transform(self, str_input, **kwargs): return titlecase(str_input) if str_input else u'' register(StringTitlecaseTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform class StringTrimSpaceTransform(BaseTransform): category = 'string' name = 'trim_space' label = 'Trim Whitespace' help_text = 'Removes leading and trailing whitespace.' noun = 'Text' verb = 'remove leading and trailing whitespace from' def transform(self, str_input, **kwargs): return str_input.strip() if str_input else u'' register(StringTrimSpaceTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform import inflect pluralizer = inflect.engine() class StringPluralizeTransform(BaseTransform): category = 'string' name = 'pluralize' label = 'Pluralize' help_text = 'Pluralize any English word (frog turns into frogs; child turns into children)' noun = 'Text' verb = 'make plural' def transform(self, str_input, **kwargs): return pluralizer.plural(str_input) if str_input else u'' register(StringPluralizeTransform())
('MKD', 'Macedonian Denar'), ('VUV', 'Ni-Vanuatu Vatu'), ('MRO', 'Mauritanian Ouguiya'), ('ANG', 'Dutch Guilder'), ('SZL', 'Swazi Lilangeni'), ('CVE', 'Cape Verdean Escudo'), ('SRD', 'Surinamese Dollar'), ('XPD', 'Palladium Ounce'), ('SVC', 'Salvadoran Colon'), ('BSD', 'Bahamian Dollar'), ('XDR', 'IMF Special Drawing Rights'), ('RWF', 'Rwandan Franc'), ('AWG', 'Aruban or Dutch Guilder'), ('DJF', 'Djiboutian Franc'), ('BTN', 'Bhutanese Ngultrum'), ('KMF', 'Comoran Franc'), ('WST', 'Samoan Tala'), ('SPL', 'Seborgan Luigino'), ('ERN', 'Eritrean Nakfa'), ('FKP', 'Falkland Island Pound'), ('SHP', 'Saint Helenian Pound'), ('JEP', 'Jersey Pound'), ('TMT', 'Turkmenistani Manat'), ('TVD', 'Tuvaluan Dollar'), ('IMP', 'Isle of Man Pound'), ('GGP', 'Guernsey Pound'), ('ZMW', 'Zambian Kwacha'), ] register(NumberCurrencyTransform())
""" return self.choose_nth(-1, inputs, default=default) def choose_nth(self, n, inputs, default=None): """ choose the n-th _truthy_ string value or the n-th non-string value or the default value if there is neither. """ try: return self.truthy_inputs(inputs)[n] except: pass return default def choose_random(self, inputs, default=None): """ choose a random _truthy_ string value or a random non-string value or the default value if there is neither. """ truthy = self.truthy_inputs(inputs) if not truthy: return default return random.choice(truthy) register(UtilChooseTransform())
category = 'string' name = 'default_value' label = 'Default Value' help_text = 'Return a default value if the text is empty.' noun = 'Text' verb = 'check if empty' def transform(self, str_input, default_value=u'', **kwargs): return str_input if str_input is not None and str_input != "" else default_value def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': True, 'key': 'default_value', 'label': 'Default Value', 'help_text': 'Value to return if the text is empty.' } ] def build_input_field(self): field = super(StringDefaultValueTransform, self).build_input_field() field['required'] = False return field register(StringDefaultValueTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform class StringWordCountTransform(BaseTransform): category = 'string' name = 'word_count' label = 'Word Count' help_text = 'Count the number of words in a string.' noun = 'Text' verb = 'count' def transform(self, str_input, **kwargs): if not str_input: return 0 # splits on space, tab, newline, return, formfeed return len(str_input.split()) register(StringWordCountTransform())
format_choices = ','.join(['{}|{} ({})'.format(f, f, dt.format(f)) for f in PREDEFINED_DATE_FORMATS]) return [ { 'type': 'unicode', 'required': True, 'key': 'expression', 'help_text': ( 'Provide the amount of time you would like to add or subtract to the date (negative values subtract time). ' 'Examples: `+8 hours 1 minute`, `+1 month -2 days`, `-1 day +8 hours`.' ) }, { 'type': 'unicode', 'required': True, 'key': 'to_format', 'choices': format_choices, 'help_text': 'Provide the format that the date should be converted to. For date format help, see: https://zapier.com/help/formatter/#date-time' }, { 'type': 'unicode', 'required': False, 'key': 'from_format', 'choices': format_choices, 'help_text': 'If we incorrectly interpret the incoming (input) date, set this to explicitly tell us the format. Otherwise, we will do our best to figure it out.' # NOQA }, ] register(DateManipulateTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform # Updating regex pattern from here: https://gist.github.com/gruber/8891611 URL_REGEX = r"""(?i)\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))""" # NOQA EMAIL_REGEX = r"""(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])""" class StringURLExtractTransform(BaseTransform): category = 'string' name = 'url_extract' label = 'Extract URL' help_text = 'Find and copy a web URL out of a text field. Finds the first URL only.' noun = 'Text' verb = 'find and copy a web URL from' def transform(self, str_input, **kwargs): if isinstance(str_input, basestring): # stripping e-mails from the input before we check for URLs so our regex # doesn't pick up on e-mails with 1 or more subdomains (like [email protected]) strip_emails = re.sub(EMAIL_REGEX, '', str_input) match = re.search(URL_REGEX, strip_emails) return match.group(0) if match else u'' else: return u'' register(StringURLExtractTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform class StringUppercaseTransform(BaseTransform): category = 'string' name = 'upper_case' label = 'Uppercase' help_text = 'Capitalize every character in the text' noun = 'Text' verb = 'capitalize every character' def transform(self, str_input, **kwargs): return str_input.upper() if str_input else u'' register(StringUppercaseTransform())
'key': 'format_string', 'type': 'unicode', 'label': 'To Format', 'help_text': 'The format the phone number will be converted to.', 'required': True, 'choices': available_formats, }, { 'key': 'default_region', 'type': 'unicode', 'label': 'Phone Number Country Code', 'help_text': ('The 2-letter ISO country code of the phone number. If not listed, you can select "Use a Custom Value (advanced)" ' 'and enter an ISO country code (list of 2-letter ISO country codes [here](https://countrycode.org)).'), 'required': False, 'default': 'US', 'choices': available_countries, }, { "type": "bool", "required": False, "key": "validate", "label": "Validate Phone Number?", 'help_text': ('If set to Yes, number is checked to be valid in selected country code (US is default). If invalid, number is ' 'returned unformatted. Set to No for testing and when using for formatting only.'), "default": "yes", }, ] register(PhoneNumberFormattingTransform())
category = 'string' name = 'length' label = 'Length' help_text = 'Count the number of characters in the text' noun = 'Text' verb = 'length' def transform(self, str_input, ignore_whitespace=False, **kwargs): str_input = str_input or '' if ignore_whitespace: str_input = re.sub('\W', '', str_input) return len(str_input) def fields(self, *args, **kwargs): return [{ 'type': 'bool', 'required': False, 'key': 'ignore_whitespace', 'label': 'Ignore Whitespace?', 'help_text': 'Will ignore whitespace characters, including tabs, spaces, and newlines.' }] register(StringLengthTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform from bs4 import BeautifulSoup class StringStripHtmlTransform(BaseTransform): category = 'string' name = 'strip_html' label = 'Remove HTML Tags' help_text = 'Remove every HTML tag to leave just the plain text.' noun = 'HTML' verb = 'convert to plain text' def transform(self, str_input, **kwargs): if not str_input: return u'' soup = BeautifulSoup(str_input, 'html.parser') return soup.get_text() register(StringStripHtmlTransform())
Digits 0 to 9 Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~ Character . provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively (e.g. [email protected]). These rules change for quoted strings "as..df"@example.com which allows any combination of printable ASCII characters except backslash and doublequote. """ if isinstance(str_input, basestring): match = re.search( r""" ( "( [a-zA-Z0-9!#$%&'*/=?^_`{|}~+.,)(><-]+ )" | ( (?!\.) ( [a-zA-Z0-9!#$%&'*/=?^_`{|}~+-] | (?<!\.)\. )+ (?<!\.) ) ) @ ( (\[?[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\]?) | ([a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+) ) """, str_input, re.U | re.VERBOSE) return match.group(0) if match else u'' else: return u'' register(StringEmailExtractTransform())
noun = 'Text' verb = 'find and replace values within' def transform(self, str_input, old, new=u'', **kwargs): if old: old = expand_special_chargroups(old) if new: new = expand_special_chargroups(new) return str_input.replace(old, new) if str_input and old else u'' def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': True, 'key': 'old', 'label': 'Find', 'help_text': 'To find a space, use `[:space:]`. For supported special characters, see: https://zapier.com/help/formatter/#special-characters' }, { 'type': 'unicode', 'required': False, 'key': 'new', 'label': 'Replace', 'help_text': 'Leave blank to delete the found text' }, ] register(StringReplaceTransform())
index = try_parse_number(index, cls=int) try: return segments[index] except: pass return u'' def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': False, 'key': 'separator', 'label': 'Separator', 'help_text': 'Character or word separator to split the text on. (Default: `[:space:]`) For supported special characters, see: https://zapier.com/help/formatter/#special-characters)' # NOQA }, { 'type': 'unicode', 'required': False, 'key': 'index', 'label': 'Segment Index', 'help_text': 'Segment of text to return after splitting. (Default: First)', 'choices': '0|First,1|Second,-1|Last,-2|Second to Last,all|All', }, ] register(StringSplitTransform())
def op_add(a, b): """ operator for add """ if isinstance(a, basestring) or isinstance(b, basestring): raise TypeError('add operation requires numeric operands') return operator.add(a, b) class NumberSpreadsheetStyleFormulaTransform(BaseTransform): category = 'number' name = 'spreadsheet_formula' label = 'Spreadsheet-Style Formula' help_text = 'Transform a number with a spreadsheet-style formula.' def transform(self, formula): return evaluate(formula) def all_fields(self, *args, **kwargs): input_field = self.build_input_field() input_field['required'] = True input_field['label'] = 'Formula' input_field['help_text'] = ( 'Spreadsheet-style formula to evaluate. Example: `ROUNDUP(100.1231, 2) * 100`. ' 'For more help and examples, see: https://zapier.com/help/formatter/#numbers' ) return [self.build_help_field(), input_field] register(NumberSpreadsheetStyleFormulaTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform class StringCapitalizeTransform(BaseTransform): category = 'string' name = 'capitalize' label = 'Capitalize' help_text = 'Capitalize the first character of every word.' noun = 'Text' verb = 'capitalize' def transform(self, str_input, **kwargs): return str_input.title() if str_input else u'' register(StringCapitalizeTransform())
import re from transformer.registry import register from transformer.transforms.base import BaseTransform class StringEmailExtractTransform(BaseTransform): category = 'string' name = 'email_extract' label = 'Extract Email Address' help_text = 'Find and copy an email address out of a text field. Finds the first email address only.' noun = 'Text' verb = 'find and copy an email address from' def transform(self, str_input, **kwargs): if isinstance(str_input, basestring): match = re.search(r'[\w\.-]+@[\w\.-]+\.[\w\.-]+', str_input) return match.group(0) if match else u'' else: return u'' register(StringEmailExtractTransform())
offset = try_parse_number(offset, cls=int, default=None) if not isinstance(offset, (int, long)): self.raise_exception('offset must be a number') if str_input and find: pos = str_input.find(find, offset) return pos def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': False, 'key': 'find', 'label': 'Find', 'help_text': 'Value to find in the text' }, { 'type': 'int', 'required': False, 'key': 'offset', 'label': 'Skip Characters', 'help_text': 'Will skip the first N characters in the text.' }, ] register(StringFindTransform())
import markdown from transformer.util import to_unicode_or_bust from transformer.registry import register from transformer.transforms.base import BaseTransform class StringMarkdownHTMLTransform(BaseTransform): category = 'string' name = 'markdown' label = 'Convert Markdown to HTML' help_text = 'Convert Markdown text into valid HTML' noun = 'Markdown text' verb = 'convert to HTML' def transform(self, str_input, **kwargs): return markdown.markdown(to_unicode_or_bust(str_input)) if str_input else u'' register(StringMarkdownHTMLTransform())
op = options.get('operation') if not op or op not in self._operations: self.raise_exception('Invalid Operation') operands, op_func = self._operations.get(op) # unary operations return a list if operands == 1: return map(op_func, inputs) # binary operations return an accumulated value initial, rest = inputs[0], inputs[1:] value = reduce(op_func, rest, initial) return value def all_fields(self, **kwargs): return [ self.build_help_field(), { 'type': 'unicode', 'required': True, 'key': 'operation', 'choices': 'add|Add,sub|Subtract,mul|Multiply,div|Divide,neg|Make Negative', 'help_text': 'The math operation to perform.' }, self.build_list_input_field() ] register(NumberMathTransform())
'required': False, 'key': 'inputs', 'label': 'Lookup Key', 'help_text': '{} you would like to {}.'.format(self.noun or 'Value', self.verb or 'transform') } def transform(self, input_key, table={}, fallback=u'', **kwargs): if input_key and input_key in table: return table[input_key] return fallback def fields(self, *args, **kwargs): return [ { 'type': 'dict', 'required': False, 'key': 'table', 'label': 'Lookup Table', 'help_text': 'The table that will be used for the lookup - keys on the left and values on the right.', }, { 'type': 'unicode', 'required': False, 'key': 'fallback', 'label': 'Fallback Value', 'help_text': 'The value to be used if we do not find a matching value in Lookup Table.' } ] register(UtilLookupTransform())
'unicode', 'required': False, 'key': 'from_format', 'choices': choices, 'help_text': 'If we incorrectly interpret the incoming (input) date, set this to explicitly tell us the format. Otherwise, we will do our best to figure it out.' # NOQA }, { 'type': 'unicode', 'required': False, 'key': 'from_timezone', 'label': 'From Timezone', 'choices': timezones, 'default': 'UTC', 'help_text': 'If no timezone is provided in the incoming (input) data, set this to explicitly tell us which to use. (Default: UTC)' # NOQA }, ] register(DateFormattingTransform())
return table[input_key] return fallback def fields(self, *args, **kwargs): return [{ 'type': 'dict', 'required': False, 'key': 'table', 'label': 'Lookup Table', 'help_text': 'The table that will be used for the lookup - keys on the left and values on the right.', }, { 'type': 'unicode', 'required': False, 'key': 'fallback', 'label': 'Fallback Value', 'help_text': 'The value to be used if we do not find a matching value in Lookup Table.' }] register(UtilLookupTransform())
if append_ellipsis: short_text = short_text[0:-3] + u'...' return short_text def fields(self, *args, **kwargs): return [ { 'type': 'int', 'required': True, 'key': 'max_length', 'help_text': 'The max length the text should be.' }, { 'type': 'int', 'required': False, 'key': 'offset', 'label': 'Skip Characters', 'help_text': 'Will skip the first N characters in the text.' }, { 'type': 'bool', 'required': False, 'key': 'append_ellipsis', 'label': 'Append Ellipsis?', 'help_text': 'Will shorten text by three characters and append "..." to the end.' } ] register(StringTruncateTransform())
('VUV', 'Ni-Vanuatu Vatu'), ('MRO', 'Mauritanian Ouguiya'), ('ANG', 'Dutch Guilder'), ('SZL', 'Swazi Lilangeni'), ('CVE', 'Cape Verdean Escudo'), ('SRD', 'Surinamese Dollar'), ('XPD', 'Palladium Ounce'), ('SVC', 'Salvadoran Colon'), ('BSD', 'Bahamian Dollar'), ('XDR', 'IMF Special Drawing Rights'), ('RWF', 'Rwandan Franc'), ('AWG', 'Aruban or Dutch Guilder'), ('DJF', 'Djiboutian Franc'), ('BTN', 'Bhutanese Ngultrum'), ('KMF', 'Comoran Franc'), ('WST', 'Samoan Tala'), ('SPL', 'Seborgan Luigino'), ('ERN', 'Eritrean Nakfa'), ('FKP', 'Falkland Island Pound'), ('SHP', 'Saint Helenian Pound'), ('JEP', 'Jersey Pound'), ('TMT', 'Turkmenistani Manat'), ('TVD', 'Tuvaluan Dollar'), ('IMP', 'Isle of Man Pound'), ('GGP', 'Guernsey Pound'), ('ZMW', 'Zambian Kwacha'), ] register(NumberCurrencyTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform import re class StringNumberExtractTransform(BaseTransform): category = 'string' name = 'number_extract' label = 'Extract Number' help_text = 'Find and copy a number in text.' noun = 'Text' verb = 'find and copy a number from' def transform(self, str_input, **kwargs): if not str_input: return u'' match = re.search(r'[+-]?[0-9]+(?:,[0-9]+)*(?:\.[0-9]+)?', str_input) return match.group(0) if match else u'' register(StringNumberExtractTransform())
def superheroize(name): a = ['Admiral', 'Air', 'Alpha', 'Ambush', 'Android', 'Aqua', 'Arch', 'Armadillo', 'Astro', 'Atomic', 'Azure', 'Battle', 'Bee', 'Beta', 'Bionic', 'Blue', 'Brain', 'Bronze', 'Brother', 'Caped', 'Captain', 'Captain', 'Chameleon', 'Cobalt', 'Colossal', 'Comet', 'Commander', 'Commodore', 'Composite', 'Compu', 'Copper', 'Cosmic', 'Crimson', 'Cyber', 'Danger', 'Dare', 'Dark', 'Dawn', 'Death', 'Delta', 'Detective', 'Digi', 'Doc', 'Doctor', 'Dragon', 'Dream', 'Duke', 'Dynamo', 'Earth', 'Elasti', 'Electra', 'Element', 'Emerald', 'Fighting', 'Fire', 'Flaming', 'Fly', 'Flying', 'Forgotten', 'Freedom', 'Frog', 'Future', 'Gamma', 'General', 'Ghost', 'Giant', 'Gold', 'Golden', 'Green', 'Grey', 'Hawk', 'Hour', 'Human', 'Hyper', 'Ice', 'Insect', 'Invisible', 'Iron', 'Jade', 'Jet', 'Karate', 'Laser', 'Lieutenant', 'Light', 'Lightning', 'Lion', 'Living', 'Machine', 'Mad', 'Magna', 'Magnetic', 'Major', 'Mammoth', 'Manga', 'Martian', 'Masked', 'Mega', 'Metal', 'Meteor', 'Micro', 'Mighty', 'Millennium', 'Mind', 'Miracle', 'Moon', 'Night', 'Nuclear', 'Obsidian', 'Omega', 'Onyx', 'Orange', 'Phantom', 'Platinum', 'Platypus', 'Power', 'Psychic', 'Purple', 'Q', 'Quick', 'Quin', 'Racoon', 'Radioactive', 'Rainbow', 'Red', 'Ring', 'Robo', 'Robot', 'Rocket', 'Ruby', 'Samurai', 'Sand', 'Sarge', 'Scarab', 'Scarlet', 'Sea', 'Seagoing', 'Secret', 'Sergeant', 'Shadow', 'Shatter', 'Shining', 'Shrinking', 'Silent', 'Silver', 'Sky', 'Snow', 'Space', 'Speed', 'Spider', 'Squirrel', 'Star', 'Steel', 'Stone', 'Sub', 'Suicide', 'Sun', 'Super', 'Super', 'Supreme', 'Techni', 'Terra', 'Thunder', 'Tiger', 'Time', 'Tomorrow', 'Turbo', 'Ultra', 'Valiant', 'Vector', 'War', 'Warrior', 'Water', 'White', 'Wild', 'Wind', 'Wing', 'Winged', 'Winter', 'Wolf', 'Wombat', 'Wonder', 'X', 'Y', 'Yellow', 'Z'] b = ['A', 'Aardvark', 'America', 'Android', 'Apostle', 'Armadillo', 'Arrow', 'Atom', 'Avenger', 'Bat', 'Bee', 'Beetle', 'Bird', 'Blade', 'Blaze', 'Blur', 'Bolt', 'Brain', 'Bullet', 'Bulk', 'Canary', 'Carrot', 'Cavalier', 'Centurion', 'Chameleon', 'Champion', 'Claw', 'Comet', 'Condor', 'Corona', 'Crystal', 'Crusader', 'Cyborg', 'Dazzler', 'Defender', 'Detective', 'Dragon', 'Droid', 'Duke', 'Dusk', 'Eagle', 'Engineer', 'Enigma', 'Eye', 'Falcon', 'Fang', 'Flame', 'Flare', 'Flash', 'Flea', 'Fly', 'Fury', 'Fighter', 'Fire', 'Ghost', 'Glider', 'Glory', 'Goliath', 'Guardian', 'Guardsman', 'Giant', 'Hammer', 'Harrier', 'Hawk', 'Hornet', 'Hulk', 'Hurricane', 'Inferno', 'Jet', 'Justice', 'Knight', 'Lantern', 'Liberator', 'Light', 'Lightning', 'Lion', 'Longshore', 'Machine', 'Mariner', 'Marvel', 'Mask', 'Maximus', 'Midget', 'Mime', 'Miracle', 'Mouse', 'Nimbus', 'Ninja', 'Nova', 'One', 'Paladin', 'Panther', 'Person', 'Phantom', 'Photon', 'Platypus', 'Prime', 'Prodigy', 'Protector', 'Q', 'Quasar', 'Racer', 'Racoon', 'Rage', 'Ranger', 'Ray', 'Ricochet', 'Rider', 'Robot', 'Rocket', 'Sailor', 'Samurai', 'Savage', 'Scarab', 'Scout', 'Shadow', 'Shield', 'Shogun', 'Shrike', 'Singer', 'Skier', 'Soarer', 'Spear', 'Specter', 'Speedster', 'Spider', 'Squid', 'Squirrel', 'Stalker', 'Star', 'Storm', 'Surfer', 'Sword', 'Sidekick', 'Torpedo', 'Tiger', 'Titan', 'Torch', 'Tornado', 'Torpedo', 'Valkyrie', 'Victory', 'Viking', 'Virtuoso', 'Vision', 'Walker', 'Warrior', 'Wasp', 'Wave', 'Wing', 'Wizard', 'Wolf', 'Wonder', 'Worm', 'X', 'Y', 'Yak', 'Z', 'Zero'] if not name: return '' name = 'zapier-' + re.sub(r'\s|\W|\d', '', name) digest = md5.md5(name).hexdigest() hash = [int(digest[:16], 16), int(digest[16:], 16)] x = abs(hash[0]) y = abs(hash[1]) return a[x % len(a)] + ' ' + b[y % len(b)] class StringSuperheroTransform(BaseTransform): category = 'string' name = 'superhero' label = 'Superhero Name' help_text = 'Convert a name into the name of a Superhero.' noun = 'Name' verb = 'convert to a Superhero' def transform(self, str_input, **kwargs): return superheroize(str_input) register(StringSuperheroTransform())
# -*- coding: utf-8 -*- import re from transformer.registry import register from transformer.transforms.base import BaseTransform # Regex via http://daringfireball.net/2010/07/improved_regex_for_matching_urls URL_REGEX = r"""(?i)\b((?:https?:(?:/{1,3}|[a-z0-9%])|[a-z0-9.\-]+[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)/)(?:[^\s()<>{}\[\]]+|\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\))+(?:\([^\s()]*?\([^\s()]+\)[^\s()]*?\)|\([^\s]+?\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’])|(?:(?<!@)[a-z0-9]+(?:[.\-][a-z0-9]+)*[.](?:com|net|org|edu|gov|mil|aero|asia|biz|cat|coop|info|int|jobs|mobi|museum|name|post|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|Ja|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)\b/?(?!@)))""" # NOQA class StringURLExtractTransform(BaseTransform): category = 'string' name = 'url_extract' label = 'Extract URL' help_text = 'Find and copy a web URL out of a text field. Finds the first URL only.' noun = 'Text' verb = 'find and copy a web URL from' def transform(self, str_input, **kwargs): if isinstance(str_input, basestring): match = re.search(URL_REGEX, str_input) return match.group(0) if match else u'' else: return u'' register(StringURLExtractTransform())
text_input = options.get('append_text') is_list = isinstance(text_input, list) append_text = text_input if is_list else text_input.split(',') # hacky way if we have one element, but it's nothing, might as well return the append string if len(inputs) == 1 and not inputs[0]: return append_text return inputs + append_text def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': False, 'key': 'append_text', 'label': 'Text to append', 'help_text': ( 'Text that you wish to add to the end of the line-item field. ' 'Supports line-items.' ), }, ] register(UtilAppendTransform())
from unidecode import unidecode from transformer.registry import register from transformer.transforms.base import BaseTransform class StringEncodeasciiTransform(BaseTransform): category = 'string' name = 'encode_ascii' label = 'Convert to ASCII' help_text = 'Replace all non-ASCII characters.' noun = 'Text' verb = 'convert to ASCII' def transform(self, str_input, **kwargs): return unidecode(str_input) if str_input else u'' register(StringEncodeasciiTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform import re class StringNumberExtractTransform(BaseTransform): category = 'string' name = 'number_extract' label = 'Extract Number' help_text = 'Find and copy a number in text.' noun = 'Text' verb = 'find and copy a number from' def transform(self, str_input, **kwargs): if not str_input: return u'' match = re.search(r'[-+]?[\d,]+[\.]?\d*', str_input) return match.group(0) if match else u'' register(StringNumberExtractTransform())
def op_add(a, b): """ operator for add """ if isinstance(a, basestring) or isinstance(b, basestring): raise TypeError('add operation requires numeric operands') return operator.add(a, b) class NumberSpreadsheetStyleFormulaTransform(BaseTransform): category = 'number' name = 'spreadsheet_formula' label = 'Spreadsheet-Style Formula' help_text = 'Transform a number with a spreadsheet-style formula.' def transform(self, formula): return evaluate(formula) def all_fields(self, *args, **kwargs): input_field = self.build_input_field() input_field['required'] = True input_field['label'] = 'Formula' input_field['help_text'] = ( 'Spreadsheet-style formula to evaluate. Example: `ROUNDUP(100.1231, 2) * 100`. ' 'For more help and examples, see: https://zapier.com/help/formatter/#numbers' ) return [ self.build_help_field(), input_field ] register(NumberSpreadsheetStyleFormulaTransform())
old = expand_special_chargroups(old) if new: new = expand_special_chargroups(new) return str_input.replace(old, new) if str_input and old else u'' def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': True, 'key': 'old', 'label': 'Find', 'help_text': 'To find a space, use `[:space:]`. For supported special characters, see: https://zapier.com/help/formatter/#special-characters' }, { 'type': 'unicode', 'required': False, 'key': 'new', 'label': 'Replace', 'help_text': 'Leave blank to delete the found text' }, ] register(StringReplaceTransform())
from transformer.registry import register from transformer.transforms.base import BaseTransform class UtilStringToLineItemTransform(BaseTransform): category = 'util' name = 'string_to_lineitem' label = 'Text to Line-item' help_text = ( 'Convert comma delimited text to a line-item. \'a,b,c,d\' becomes [a,b,c,d]. More on line-items ' '[here](https://zapier.com/help/formatter/#how-use-line-items-formatter).' ) noun = 'Text' verb = 'Convert' def transform(self, str_input, **kwargs): if not str_input: return u'' segments = str_input.split(',') return segments register(UtilStringToLineItemTransform())
) }, { 'type': 'unicode', 'required': True, 'key': 'to_format', 'choices': format_choices, 'help_text': 'Provide the format that the date should be converted to. For date format help, see: https://zapier.com/help/formatter/#date-time' }, { 'type': 'unicode', 'required': False, 'key': 'from_format', 'choices': format_choices, 'help_text': 'If we incorrectly interpret the incoming (input) date, set this to explicitly tell us the format. Otherwise, we will do our best to figure it out.' # NOQA }, ] register(DateManipulateTransform())
import html2text from transformer.util import to_unicode_or_bust from transformer.registry import register from transformer.transforms.base import BaseTransform class StringHTMLMarkdownTransform(BaseTransform): category = 'string' name = 'htmlmarkdown' label = 'Convert HTML to Markdown' help_text = 'Convert valid HTML to Markdown text' noun = 'HTML' verb = 'convert to Markdown' def transform(self, str_input, **kwargs): if not str_input: return u'' markdown = html2text.html2text(to_unicode_or_bust(str_input)) markdown = markdown.strip('\n') return markdown register(StringHTMLMarkdownTransform())
groups = match.groups() for idx, val in enumerate(groups): result[idx] = val if len(groups) < 1: result[0] = str_input[match.start():match.end()] result.update(match.groupdict()) return result def fields(self, *args, **kwargs): return [ { 'type': 'unicode', 'required': True, 'key': 'pattern', 'label': 'Pattern', 'help_text': 'Enter a [Python Regular Expression](https://developers.google.com/edu/python/regular-expressions) to find the first match for, e.g. `f[o]+ (bar)`.' }, ] register(StringPatternExtractTransform())
def fields(self, *args, **kwargs): return [ { "type": "bool", "required": False, "key": "forced_header", "label": "Force First Row as Header Row", "default": "no", "help_text": ( "By default, Import CSV File will try to determine if your file has a header row. " "If you find in your Test Step that this did not work (the header field will be False), you can force it here by selecting yes." ), # NOQA }, { "type": "unicode", "required": False, "key": "forced_dialect", "choices": "default|Detect Automatically,comma|Comma Delimited,semicolon|Semicolon Delimited,excel|Excel Comma Delimited,excel-tab|Excel Tab Delimited,one|One Column", "label": "Type of CSV File", "default": "default", "help_text": ( "By default, Import CSV File will try to detect the type of your file. " "If you find in your Test Step that your file was not recognized correctly, you can force it here by selecting your file type." ), # NOQA }, ] register(UtilImportCSVTransform())
# -*- coding: utf-8 -*- import re from transformer.registry import register from transformer.transforms.base import BaseTransform # Regex based on second script in question here (https://stackoverflow.com/questions/3868753/find-phone-numbers-in-python-script) # Tweaked to accept international phone numbers, including 2 digit country codes and area codes, along with area codes that begin with a 0: https://gist.github.com/maguay/f3a46f578568a608413530e27b78af88 URL_REGEX = r"""(?:(?:\+?([1-9]|[0-9][0-9]|[0-9][0-9][0-9])\s*(?:[.-]\s*)?)?(?:\(\s*([2-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9])\s*\)|([0-9][1-9]|[0-9]1[02-9]|[2-9][02-8]1|[2-9][02-8][02-9]))\s*(?:[.-]\s*)?)?([2-9]1[02-9]|[2-9][02-9]1|[2-9][02-9]{2})\s*(?:[.-]\s*)?([0-9]{4})(?:\s*(?:#|x\.?|ext\.?|extension)\s*(\d+))?""" class StringPhoneExtractTransform(BaseTransform): category = 'string' name = 'phone_extract' label = 'Extract Phone Number' help_text = 'Find and copy a complete phone number out of a text field. Finds the first phone number only.' noun = 'Text' verb = 'find and copy a phone number from' def transform(self, str_input, **kwargs): if isinstance(str_input, basestring): match = re.search(URL_REGEX, str_input) return match.group(0) if match else u'' else: return u'' register(StringPhoneExtractTransform())
import bs4 import markdown from transformer.registry import register from transformer.transforms.base import BaseTransform class StringMarkdownHTMLTransform(BaseTransform): category = 'string' name = 'markdown' label = 'Convert Markdown to HTML' help_text = 'Convert Markdown text into valid HTML' noun = 'Markdown text' verb = 'convert to HTML' def transform(self, str_input, **kwargs): return markdown.markdown(self.to_unicode_or_bust(str_input)) if str_input else u'' def to_unicode_or_bust(self, obj, encoding='utf-8'): try: if isinstance(obj, basestring): if not isinstance(obj, unicode): obj = unicode(obj, encoding) return obj except: return bs4.UnicodeDammit(obj, is_html=False).unicode_markup register(StringMarkdownHTMLTransform())