class CarouselAdForm(ComponentForm):
    ad_account = AdAccountSelect()
    pageid = PageSelect()
    bid = BidComponent('bid', Campaign.Objective.link_clicks)

    name = forms.CharField(
        initial='Carousel Ads',
        widget=forms.TextInput(attrs={'placeholder': 'Campaign name'}))
    targeting_spec = TargetingSpec()
    site_link = forms.CharField(widget=forms.TextInput(
        attrs={'placeholder': 'Link to your site'}))
    caption = forms.CharField(initial='Caption')
    message = forms.CharField(initial='Message')
    call_to_action_type = CTASelect()
    title = forms.CharField(initial='Title 1')
    title2 = forms.CharField(initial='Title 2')
    title3 = forms.CharField(initial='Title 3')

    body = forms.CharField(initial='Body 1')
    body2 = forms.CharField(initial='Body 2')
    body3 = forms.CharField(initial='Body 3')

    url = forms.URLField(widget=forms.TextInput(
        attrs={'placeholder': 'Item 1 link'}))
    url2 = forms.URLField(widget=forms.TextInput(
        attrs={'placeholder': 'Item 2 link'}))
    url3 = forms.URLField(widget=forms.TextInput(
        attrs={'placeholder': 'Item 3 link'}))

    image = ImageInput()
    image2 = ImageInput(id='id_image2')
    image3 = ImageInput(id='id_image3')
class AccountForm(ComponentForm):

    ad_account = AdAccountSelect()
    # STATUSES = (
    #     ('False', 'Do not include ARCHIVED ad sets'),
    #     ('True', 'Include ARCHIVED ad sets'),
    # )
    # include_archived = forms.ChoiceField(
    #     widget=forms.RadioSelect,
    #     choices=PLATFORMS,
    #     initial='Android',
    #     help_text='Platform needs to match the platform in targeting above'
    # )
    include_archived = forms.BooleanField(
        label="Include archived ad sets?",
        initial=False,
        required=False,
    )
    limit = forms.DecimalField(
        label="How many ad sets to check. The more you pick, the longer it " +
        "will take.",
        min_value=1,
        max_value=50,
        required=True,
        initial=10)
Exemple #3
0
class AdCreationForm(ComponentForm):

    ad_account = AdAccountSelect()
    page = PageSelect()
    name = forms.CharField(initial='Creative Testing')

    GENDERS_CHOICES = (
        ('0', 'All'),
        ('1', 'Male'),
        ('2', 'Female'),
    )

    bid = BidComponent('bid',
                       Campaign.Objective.link_clicks)

    targeting = TargetingSpec()

    TOMORROW = datetime.date.today() + datetime.timedelta(days=1)

    start_time = DatetimePicker(
        id='id_starttime',
        initial=TOMORROW,
        required=False,
    )
    end_time = DatetimePicker(id='id_endtime', required=False)

    url = forms.URLField(
        widget=forms.TextInput(attrs={'placeholder': 'Link'}))
    title = forms.CharField(initial='Title 1')
    title2 = forms.CharField(initial='Title 2')
    body = forms.CharField(initial='Body 1')
    body2 = forms.CharField(initial='Body 2')
    image = ImageInput()
    image2 = ImageInput(id="id_image2")
    image3 = ImageInput(id="id_image3")
class AppInstallAdForm(ComponentForm):
    """
    We need these parameters for the sample script:
        account_id: AdAccountSelect
        base_name: TextInput
        message: TextInput
        image_path: ImageInput
        daily_budget: DecimalField
        page_id: PageSelect
        app_id: AppSelect
        app_name: AppSelect
        app_store_link: AppSelect
        deferred_app_link: TextInput
        bid_info: BidComponent
        targeting: TargetingSpec
    """
    ad_account = AdAccountSelect()
    name = forms.CharField(
        label='Basename for your ad',
        widget=forms.TextInput(attrs={'placeholder': 'App Install'}),
        help_text='''We will generate campaign name, adset name and ad name
        with basename.''')

    page = PageSelect(help_text='Your ad will be published from this page.')
    app = AppSelect()
    image = ImageInput(allow_empty_file=False, required=True)
    message = forms.CharField(label='Ad Message',
                              initial='Try out this awesome app!')
    app_link = forms.CharField(
        label='Deferred app link to your app',
        min_length=4,
        required=False,
        widget=forms.TextInput(attrs={'placeholder': 'example://detail/1234'}))

    targeting = TargetingSpec(initial=targeting_info_initial)
    PLATFORMS = (
        ('Android', 'Android'),
        ('iOS', 'iOS'),
    )
    platform = forms.ChoiceField(
        widget=forms.RadioSelect,
        choices=PLATFORMS,
        initial='Android',
        help_text='Platform needs to match the platform in targeting above')

    bid_info = BidComponent('bid_info', Campaign.Objective.mobile_app_installs)
    daily_budget = forms.DecimalField(min_value=1, initial=1000)

    def clean(self):
        self.cleaned_data = super(AppInstallAdForm, self).clean()

        self.cleaned_data = \
            super(AppInstallAdForm, self).validate_mobile_platform_targeting()

        return self.cleaned_data
Exemple #5
0
class CustomAudienceForm(ComponentForm):

    ad_account = AdAccountSelect()
    name = forms.CharField(max_length=50)
    description = forms.CharField(max_length=100, required=False)
    optout_link = forms.URLField()
    data_file = FileInput(
        max_length=5242880,
        allow_empty_file=False,
        help_text='''Data format: one hash per line.''',
    )
Exemple #6
0
class MacaFrequencyForm(ComponentForm):
    ad_account = AdAccountSelect()
    app = AppSelect()
    name = forms.CharField(initial='Test Mobile App Custom Audience')
    retention_days = forms.IntegerField(help_text=RETENTION_HELP,
                                        initial=180,
                                        validators=[validate_retention_days])
    event = forms.ChoiceField(choices=EVENT_CHOICES)
    period = forms.ChoiceField(choices=PERIOD_CHOICES, help_text=PERIOD_HELP)
    greater_than = forms.IntegerField(help_text=GREATER_THAN_HELP,
                                      required=False)
    less_than = forms.IntegerField(help_text=LESS_THAN_HELP, required=False)
Exemple #7
0
class TieredLookalikeForm(ComponentForm):

    TOMORROW = datetime.date.today() + datetime.timedelta(days=1)

    ad_account = AdAccountSelect()

    CA_NAME_HELP_TEXT = 'This name will be used to create ' + \
        'the lookalike audiences.'
    CA_HELP_TEXT = 'Choose a existing custom audience id as the seed ' + \
        'for the lookalike audiences.'
    """
        Information for the uploaded custom audience
    """
    lookalike_audience_name = forms.CharField(
        max_length=50,
        help_text=CA_NAME_HELP_TEXT,
    )
    """
        Choose to create based on existing custom audience
    """
    seed_id = CustomAudienceSelect()

    NAME_HELP_TEXT = 'Name for the campaign and ads.'
    """
        Created lookalike campaign information
    """
    name = forms.CharField(
        initial='Tiered lookalikes',
        max_length=50,
        help_text=NAME_HELP_TEXT,
    )
    country = CountrySelect()
    bid_info = BidComponent('bid_info', Campaign.Objective.link_clicks)

    help_text = (
        '5 bid amounts will be generated between min and max bid. This will ' +
        'replace the bid amount you chose in the bid component above.')
    bid_min = forms.IntegerField(initial=100, help_text=help_text)
    bid_max = forms.IntegerField(initial=500, help_text=help_text)

    budget_type = BudgetTypeSelect()
    budget = forms.IntegerField(initial=1000)

    start_time = DatetimePicker(id='id_starttime', initial=TOMORROW)
    end_time = DatetimePicker(id='id_endtime', required=False)

    title = forms.CharField(initial='Ad title')
    body = forms.CharField(initial='Ad body.')
    url = forms.URLField()
    image = ImageInput()
Exemple #8
0
class ComponentGalleryForm(ComponentForm):

    select_account = AdAccountSelect()
    select_account.JS_FILES = ['actselect.js']

    select_custom_audience = CustomAudienceSelect()
    select_custom_audience.JS_FILES = ['caselect.js']

    select_app = AppSelect()
    select_app.JS_FILES = ['app_select.js', 'app_info.jsx']

    targeting_setting = TargetingSpec()
    targeting_setting.JS_FILES = [
        'targeting_spec.js', 'targeting_composer.jsx'
    ]

    bid_setting = BidComponent('bid_setting')
    bid_setting.JS_FILES = ['bid_component.js', 'bid_composer.jsx']

    select_page = PageSelect()
    select_page.JS_FILES = ['page_select.js']

    select_lead_gen_form = LeadFormCreate()
    select_lead_gen_form.JS_FILES = ['lead_form.js', 'lead_form_select.jsx']

    select_business_manager = BusinessManagerSelect()
    select_business_manager.JS_FILES = ['business_select.js']

    select_product_catalog = ProductCatalogSelect()
    select_product_catalog.JS_FILES = ['product_catalog_select.js']

    select_product = ProductSelect()
    select_product.JS_FILES = ['product_select.js']

    def __init__(self):
        super(ComponentGalleryForm, self).__init__()

        for key, field in self.fields.items():
            field.desc = markdown.markdown(textwrap.dedent(field.__doc__))
            field.name = field.__class__.__name__
            js_modules = []
            if hasattr(field, 'JS_FILES'):
                for js_file in field.JS_FILES:
                    js_module_content = get_file_content(
                        './js_src/{0}'.format(js_file))
                    js_modules.append({
                        'name': js_file,
                        'content': js_module_content
                    })
            field.js_modules = js_modules
Exemple #9
0
class AdsReportingForm(ComponentForm):

    ad_account = AdAccountSelect()
    LAST_90_DAYS = datetime.date.today() - datetime.timedelta(days=90)
    TODAY = datetime.date.today()

    report_date = DatetimePicker(
        id='id_reportdate',
        initial=TODAY.strftime('%Y-%m-%d'),
        datetime_format='YYYY-MM-DD',
        min_date=LAST_90_DAYS.strftime('%Y-%m-%d'),
        max_date=TODAY.strftime('%Y-%m-%d'),
        help_text='Date between last 90 days and today',
    )
Exemple #10
0
class MultipleLalForm(ComponentForm):

    ad_account = AdAccountSelect()
    base_name = forms.CharField(max_length=50)
    seed_id = CustomAudienceSelect()
    country = CountrySelect()
    country_2 = CountrySelect(id='country_2', required=False)
    country_3 = CountrySelect(id='country_3', required=False)

    ratio = forms.IntegerField(
        min_value=1,
        max_value=10,
        help_text='Lookalike percentage value, from 1 to 10')
    ratio_2 = forms.IntegerField(min_value=1, max_value=10, required=False)
    ratio_3 = forms.IntegerField(min_value=1, max_value=10, required=False)
Exemple #11
0
class ProductAudienceEstimationForm(ComponentForm):

    ad_account = AdAccountSelect()
    business_manager = BusinessManagerSelect()
    product_catalog = ProductCatalogSelect()
    product_set = ProductSetSelect()
    targeting_spec = SpecSelect(specs=TARGETING_SPECS)

    def clean(self):
        self.cleaned_data = super(ProductAudienceEstimationForm, self).clean()

        self.cleaned_data = \
            super(ProductAudienceEstimationForm,
                  self).validate_mobile_platform_targeting()

        return self.cleaned_data
Exemple #12
0
class LeadAdForm(ComponentForm):

    ad_account = AdAccountSelect()
    page = PageSelect()
    lead_form = LeadFormCreate()
    name = forms.CharField(initial='My First Lead Ad')
    targeting = TargetingSpec(initial=targeting_info_initial)
    bid_info = BidComponent('bid_info', Campaign.Objective.lead_generation)
    daily_budget = forms.DecimalField(
        min_value=1,
        initial='500',
    )
    image = ImageInput(
        allow_empty_file=False,
        required=True,
    )
    message = forms.CharField(initial='My First Lead Ad')
    link = forms.CharField()
    caption = forms.CharField()
    description = forms.CharField()
Exemple #13
0
class AppEngagementForm(ComponentForm):

    IMAGE_MIN_WIDTH = 1200
    IMAGE_MIN_HEIGHT = 627

    ad_account = AdAccountSelect()
    name = forms.CharField(
        label='Basename for your ads',
        max_length=50, required=True,
        widget=forms.TextInput(attrs={'placeholder': 'My App Engagement'}),
        help_text='''We will generate campaign name, adset name and ad name
        with basename.'''
    )
    page = PageSelect()
    image = ImageInput(
        allow_empty_file=False, required=True,
        help_text='PNG or JPG file with width=1200px, height=627px'
    )
    message = forms.CharField(
        label='Ad Message',
        max_length=90, required=True,
        initial='Try out this feature in our app!'
    )

    app = AppSelect()
    deep_link = forms.CharField(
        label='Deep link to your app action', min_length=4, required=True,
        widget=forms.TextInput(attrs={'placeholder': 'example://detail/1234'})
    )
    pixel = forms.CharField(
        label='Facebook offsite pixel id of your app',
        min_length=1, required=True,
        initial='null',
        help_text='Fill `null` to skip.'
    )

    targeting = TargetingSpec(initial=targeting_info_initial)
    PLATFORMS = (
        ('Android', 'Android'),
        ('iOS', 'iOS'),
    )
    platform = forms.ChoiceField(
        widget=forms.RadioSelect,
        choices=PLATFORMS,
        help_text='Platform needs to match the platform in targeting above'
    )

    bid_info = BidComponent('bid_info', 'MOBILE_APP_ENGAGEMENT')
    daily_budget = forms.DecimalField(
        min_value=1,
        required=True,
        initial='500',
        help_text='to bid $5.00, set 500'
    )

    def clean_image(self):
        image = self.cleaned_data.get('image')
        if not image:
            raise forms.ValidationError('Not an image!')
        else:
            w, h = get_image_dimensions(image)
            if w < AppEngagementForm.IMAGE_MIN_WIDTH:
                raise forms.ValidationError(
                    "The image is %i pixel wide. It's supposed to be >= %i." %
                    (w, AppEngagementForm.IMAGE_MIN_WIDTH)
                )
            if h < AppEngagementForm.IMAGE_MIN_HEIGHT:
                raise forms.ValidationError(
                    "The image is %i pixel high. It's supposed to be >= %i." %
                    (h, AppEngagementForm.IMAGE_MIN_HEIGHT)
                )
        return image

    def clean(self):
        self.cleaned_data = super(AppEngagementForm, self).clean()

        self.cleaned_data = \
            super(AppEngagementForm, self).validate_mobile_platform_targeting()

        return self.cleaned_data
Exemple #14
0
class AudienceNetworkOptInForm(ComponentForm):
    ad_account = AdAccountSelect()
    adset = AdSetSelect()
Exemple #15
0
class AutobotConfigEditorForm(ComponentForm):

    ad_account = AdAccountSelect(
        help_text='* Only one ad account is supported through the config UI.')

    app = AppSelect(help_text='Select your application in the pop up')

    name = forms.CharField(label='Name',
                           max_length=128,
                           required=True,
                           initial='My Autobot config')

    page = PageSelect(help_text='Select your Page in the pop up')

    PLATFORMS = (
        ('Android', 'Android'),
        ('iOS', 'iOS'),
        ('Canvas', 'Canvas'),
    )

    access_token = forms.CharField(label='System Token',
                                   max_length=201,
                                   required=True,
                                   initial='- system access token -',
                                   help_text="Paste system access token.")

    adset_life = forms.IntegerField(
        label='Ad Set Life',
        required=True,
        max_value=180,
        min_value=1,
        initial=14,
    )

    lifetime_budget = forms.IntegerField(
        label='Lifetime Budget',
        required=True,
        max_value=1000000,
        min_value=0,
        initial=7500,
    )

    age_min = forms.IntegerField(
        label='Age Minimum',
        required=True,
        max_value=65,
        min_value=13,
        initial=18,
    )

    interests = InterestSelect(
        required=False,
        help_text='Type interest to lookup or find suggestions.')

    min_purchase_percentage = forms.DecimalField(
        label='Minimum purchase (%)',
        required=True,
        max_value=1.00,
        min_value=0.00,
        decimal_places=2,
        initial=0.25,
        help_text="""Autobot will automatically include all countries that have
        purchase values exceeding this percentage.""")

    forced_countries = CountrySelect(
        id='id_forced_countres_select',
        multiple=True,
        required=False,
    )

    ignored_countries = CountrySelect(
        id='id_ignore_countries_select',
        multiple=True,
        required=False,
    )

    margin_requirement = forms.DecimalField(
        label='Margin Requirement',
        required=True,
        max_value=2.00,
        min_value=0.00,
        decimal_places=2,
        initial=1.15,
        help_text="""Scales the bid Autobot creates; intended to account for
        any overhead incurred between purchase value and actual profit.""")

    scale_targeting_type = forms.CharField(
        label='Scale Targeting',
        initial='''{"INTEREST": 0.7, "LOOKALIKE": 1.0, \
"WIDE_LOOKALIKE": 0.9, "BROAD": 0}''',
        help_text="""
        Multiplies the bid Autobot creates based on the type of ad
        being run. INTEREST of 1 means full bid, while BROAD 0.25 means 1/4 for
        broad targeting.
        The options are INTEREST, LOOKALIKE, WIDE_LOOKALIKE, and BROAD""")

    platforms = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple(
        attrs={'id': 'id_platform_select'}),
                                          choices=PLATFORMS,
                                          initial=(PLATFORMS[0]))

    # https://developers.facebook.com/docs/marketing-api/targeting-specs/v2.7
    ANDROID_VERSIONS = (
        (2.0, '2.0'),
        (2.1, '2.1'),
        (2.2, '2.2'),
        (2.3, '2.3'),
        (3.0, '3.0'),
        (3.1, '3.1'),
        (3.2, '3.2'),
        (4.0, '4.0'),
        (4.1, '4.1'),
        (4.2, '4.2'),
        (4.3, '4.3'),
        (4.4, '4.4'),
        (5.0, '5.0'),
        (5.1, '5.1'),
    )
    IOS_VERSIONS = (
        (2.0, '2.0'),
        (3.0, '3.0'),
        (4.0, '4.0'),
        (4.3, '4.3'),
        (5.0, '5.0'),
        (6.0, '6.0'),
        (7.0, '7.0'),
        (8.0, '8.0'),
        (9.0, '9.0'),
    )

    android_version = forms.ChoiceField(label='Android Minimum Version',
                                        choices=ANDROID_VERSIONS,
                                        initial=4.1,
                                        required=False)
    ios_version = forms.ChoiceField(label='iOS Minimum Version',
                                    choices=IOS_VERSIONS,
                                    initial=8.0,
                                    required=False)

    asset_feed = AssetFeed(initial=asset_feed_initial)

    MISC_JSON = '''
    {
        "create_ads": false,
        "user_adclusters": [],
        "pltv_days": [0, 28, 90, 182, 365, 545],
        "pltv_days_strings": ["1d", "28d", "90d", "6mo", "1yr", "18 mo"],
        "lal_ratio_by_country": { "default": 0.05 },
        "lal_source_audience_by_country": { "default": 25 }
    }
    '''

    misc = forms.CharField(
        label='Miscellaneous Settings',
        widget=forms.Textarea,
        initial=MISC_JSON,
    )

    settings_file = forms.CharField(
        label='Output Logging File',
        max_length=128,
        required=True,
        initial="autobot_output.json",
        help_text="Where Autobot will trace output at runtime.")

    save_filename = forms.CharField(label='Save Config as',
                                    max_length=128,
                                    required=True,
                                    initial="autobot_config.json")

    def __init__(self, *args, **kwargs):
        super(AutobotConfigEditorForm, self).__init__(*args, **kwargs)

        js = """
          const name = document.getElementById('id_name');
          const app = document.getElementById('id_app_select');
          if (name && app) {
            try {
                const info = JSON.parse(app.value);
                if (info.name != name.value)
                    name.value = info.name;
            } catch(err) {}
          }
        """
        self.fields['app'].widget.attrs.update({'onblur': js})

    def clean(self):
        self.cleaned_data = super(AutobotConfigEditorForm, self).clean()

        if 'access_token' in self.cleaned_data:
            access_token = self.cleaned_data['access_token']

            url = construct_url('https://graph.facebook.com/v2.7/me',
                                {'access_token': access_token})
            try:
                urllib2.urlopen(url).read()
            except urllib2.HTTPError:
                raise ValidationError('Invalid access token.')

        return self.cleaned_data
class CarouselAppAdForm(ComponentForm):

    ad_account = AdAccountSelect()
    name = forms.CharField(
        label='Basename for your ads',
        max_length=50,
        required=True,
        widget=forms.TextInput(
            attrs={'placeholder': 'Carousel App Install Ad'}),
        help_text='''We will generate campaign name, adset name and ad name
        with basename.''')
    message = forms.CharField(label='Ad Message',
                              max_length=90,
                              required=True,
                              initial='Try out this new app!')
    daily_budget = forms.DecimalField(min_value=1, required=True, initial=1000)
    bid_info = BidComponent('bid_info', Campaign.Objective.mobile_app_installs)
    targeting = TargetingSpec(
        initial=targeting_info_initial,
        help_text='You need to choose mobile platform and a placement type' +
        ' that has mobile, and the platform should match with below')

    PLATFORMS = (
        ('Android', 'Android'),
        ('iOS', 'iOS'),
    )
    platform = forms.ChoiceField(
        widget=forms.RadioSelect,
        choices=PLATFORMS,
        initial='Android',
        help_text='Platform needs to match the platform in targeting above')

    appinfo_fbpage_id = PageSelect(
        help_text='The page from which the ad is posted')

    app = AppSelect(help_text='Select your application in the pop up')

    # The carousel contains 3 images
    image_1 = ImageInput(
        label='Image 1',
        allow_empty_file=False,
        required=True,
        help_text='PNG or JPG file with width=1200px, height=627px')
    link_title_1 = forms.CharField(
        help_text='Title message for image 1',
        widget=forms.TextInput(attrs={'placeholder': 'My App Name'}))
    deep_link_1 = forms.CharField(
        help_text='Deep link for image 1',
        required=False,
        widget=forms.TextInput(attrs={'placeholder': 'example://product/123'}))
    image_2 = ImageInput(
        id='id_image_2',
        label='Image 2',
        allow_empty_file=False,
        required=True,
        help_text='PNG or JPG file with width=1200px, height=627px')
    link_title_2 = forms.CharField(
        help_text='Title message for image 2',
        widget=forms.TextInput(attrs={'placeholder': 'My App Name'}))
    deep_link_2 = forms.CharField(
        help_text='Deep link for image 2',
        required=False,
        widget=forms.TextInput(attrs={'placeholder': 'example://product/123'}))
    image_3 = ImageInput(
        id='id_image_3',
        label='Image 3',
        allow_empty_file=False,
        required=True,
        help_text='PNG or JPG file with width=1200px, height=627px')
    link_title_3 = forms.CharField(
        help_text='Title message for image 3',
        widget=forms.TextInput(attrs={'placeholder': 'My App Name'}))
    deep_link_3 = forms.CharField(
        help_text='Deep link for image 3',
        required=False,
        widget=forms.TextInput(attrs={'placeholder': 'example://product/123'}))

    def clean(self):
        self.cleaned_data = super(CarouselAppAdForm, self).clean()

        self.cleaned_data = \
            super(CarouselAppAdForm, self).validate_mobile_platform_targeting()

        return self.cleaned_data