예제 #1
0
class GeneralProductPage(ProductPage):
    template = 'buyersguide/product_page.html'

    camera_device = ExtendedYesNoField(
        help_text='Does this device have or access a camera?', )

    camera_app = ExtendedYesNoField(
        help_text='Does the app have or access a camera?', )

    microphone_device = ExtendedYesNoField(
        help_text='Does this Device have or access a microphone?', )

    microphone_app = ExtendedYesNoField(
        help_text='Does this app have or access a microphone?', )

    location_device = ExtendedYesNoField(
        help_text='Does this product access your location?', )

    location_app = ExtendedYesNoField(
        help_text='Does this app access your location?', )

    # What data does it collect?

    personal_data_collected = models.TextField(
        max_length=5000,
        blank=True,
        help_text='What kind of personal data does this product collect?')

    biometric_data_collected = models.TextField(
        max_length=5000,
        blank=True,
        help_text='What kind of biometric data does this product collect?')

    social_data_collected = models.TextField(
        max_length=5000,
        blank=True,
        help_text='What kind of social data does this product collect?')

    # How can you control your data

    how_can_you_control_your_data = models.TextField(
        max_length=5000,
        blank=True,
        help_text='How does this product let you control your data?')

    data_control_policy_is_bad = models.BooleanField(
        default=False, verbose_name='Privacy ding')

    # Company track record

    company_track_record = models.CharField(
        choices=TRACK_RECORD_CHOICES,
        default='Average',
        help_text='This company has a ... track record',
        max_length=20)

    track_record_is_bad = models.BooleanField(default=False,
                                              verbose_name='Privacy ding')

    track_record_details = models.TextField(
        max_length=5000,
        blank=True,
        help_text='Describe the track record of this company here.')

    # Offline use

    offline_capable = ExtendedYesNoField(
        help_text='Can this product be used offline?', )

    offline_use_description = models.TextField(
        max_length=5000,
        blank=True,
        help_text='Describe how this product can be used offline.')

    # Artificial Intelligence

    uses_ai = ExtendedYesNoField(help_text='Does the product use AI?')

    ai_uses_personal_data = ExtendedYesNoField(
        help_text=
        'Does the AI use your personal data to make decisions about you?')

    ai_is_transparent = ExtendedYesNoField(
        help_text='Does the company allow users to see how the AI works?')

    ai_helptext = models.TextField(
        max_length=5000,
        blank=True,
        help_text='Helpful text around AI to show on the product page',
    )

    @classmethod
    def map_import_fields(cls):
        generic_product_import_fields = super().map_import_fields()
        general_product_mappings = {
            "Has camera device": "camera_device",
            "Has camera app": "camera_app",
            "Has microphone device": "microphone_device",
            "Has microphone app": "microphone_app",
            "Has location device": "location_device",
            "Has location app": "location_app",
            "Personal data collected": "personal_data_collected",
            "Biometric data collected": "biometric_data_collected",
            "Social data collected": "social_data_collected",
            "How you can control your data": "how_can_you_control_your_data",
            "Company track record": "company_track_record",
            "Show company track record privacy ding": "track_record_is_bad",
            "Offline capable": "offline_capable",
            "Offline use": "offline_use_description",
            "Uses AI": "uses_ai",
            "AI uses personal data": "ai_uses_personal_data",
            "AI help text": "ai_helptext",
            "AI is transparent": "ai_is_transparent",
        }
        # Return the merged fields
        return {**generic_product_import_fields, **general_product_mappings}

    def get_export_fields(self):
        """
        This should be a dictionary of the fields to send to Airtable.
        Keys are the Column Names in Airtable. Values are the Wagtail values we want to send.
        """
        generic_product_data = super().get_export_fields()
        general_product_data = {
            "Has camera device": self.camera_device,
            "Has camera app": self.camera_app,
            "Has microphone device": self.microphone_device,
            "Has microphone app": self.microphone_app,
            "Has location device": self.location_device,
            "Has location app": self.location_app,
            "Personal data collected": self.personal_data_collected,
            "Biometric data collected": self.biometric_data_collected,
            "Social data collected": self.social_data_collected,
            "How you can control your data":
            self.how_can_you_control_your_data,
            "Company track record": self.company_track_record,
            "Show company track record privacy ding": self.track_record_is_bad,
            "Offline capable": self.offline_capable,
            "Offline use": self.offline_use_description,
            "Uses AI": self.uses_ai,
            "AI uses personal data": self.ai_uses_personal_data,
            "AI is transparent": self.ai_uses_personal_data,
            "AI help text": self.ai_helptext,
        }
        # Merge the two dicts together.
        data = {**generic_product_data, **general_product_data}
        return data

    # administrative panels
    content_panels = ProductPage.content_panels.copy()
    content_panels = insert_panels_after(
        content_panels,
        'Product Categories',
        [
            MultiFieldPanel([
                FieldPanel('camera_device'),
                FieldPanel('camera_app'),
                FieldPanel('microphone_device'),
                FieldPanel('microphone_app'),
                FieldPanel('location_device'),
                FieldPanel('location_app'),
            ],
                            heading='Can it snoop?',
                            classname='collapsible'),
        ],
    )

    content_panels = insert_panels_after(
        content_panels, 'What is required to sign up', [
            MultiFieldPanel(
                [
                    FieldPanel('personal_data_collected'),
                    FieldPanel('biometric_data_collected'),
                    FieldPanel('social_data_collected'),
                ],
                heading='What data does it collect',
                classname='collapsible',
            ),
        ])

    content_panels = insert_panels_after(
        content_panels,
        'How does it use this data',
        [
            MultiFieldPanel(
                [
                    FieldPanel('how_can_you_control_your_data'),
                    FieldPanel('data_control_policy_is_bad'),
                ],
                heading='How can you control your data',
                classname='collapsible',
            ),
            MultiFieldPanel([
                FieldPanel('company_track_record'),
                FieldPanel('track_record_is_bad'),
                FieldPanel('track_record_details'),
            ],
                            heading='Company track record',
                            classname='collapsible'),
            MultiFieldPanel([
                FieldPanel('offline_capable'),
                FieldPanel('offline_use_description'),
            ],
                            heading='Offline use',
                            classname='collapsible'),
        ],
    )

    content_panels = insert_panels_after(
        content_panels,
        'Security',
        [
            MultiFieldPanel([
                FieldPanel('uses_ai'),
                FieldPanel('ai_uses_personal_data'),
                FieldPanel('ai_is_transparent'),
                FieldPanel('ai_helptext'),
            ],
                            heading='Artificial Intelligence',
                            classname='collapsible'),
        ],
    )

    @property
    def product_type(self):
        return "general"

    class Meta:
        verbose_name = "General Product Page"
예제 #2
0
class SoftwareProductPage(ProductPage):
    template = 'buyersguide/product_page.html'

    handles_recordings_how = models.TextField(
        max_length=5000,
        blank=True,
        help_text='How does this software handle your recordings')

    recording_alert = ExtendedYesNoField(
        null=True,
        help_text='Alerts when calls are being recorded?',
    )

    recording_alert_helptext = models.TextField(max_length=5000, blank=True)
    # NullBooleanField is deprecated as of Django 3.1.
    # We're using it here primarily for a data migration, but we should
    # move to BooleanField as soon as it's safe to do so with the content we have
    medical_privacy_compliant = models.NullBooleanField(
        null=True, help_text='Compliant with US medical privacy laws?')

    medical_privacy_compliant_helptext = models.TextField(max_length=5000,
                                                          blank=True)

    # Can I control it?

    host_controls = models.TextField(max_length=5000, blank=True)
    # NullBooleanField is deprecated as of Django 3.1.
    # We're using it here primarily for a data migration, but we should
    # move to BooleanField as soon as it's safe to do so with the content we have
    easy_to_learn_and_use = models.NullBooleanField(
        null=True,
        help_text='Is it easy to learn & use the features?',
    )

    easy_to_learn_and_use_helptext = models.TextField(max_length=5000,
                                                      blank=True)

    @classmethod
    def map_import_fields(cls):
        generic_product_import_fields = super().map_import_fields()
        software_product_mappings = {
            "How it handles recording": "handles_recordings_how",
            "Recording alert": "recording_alert",
            "Recording alert help text": "recording_alert_helptext",
            "Medical privacy compliant": "medical_privacy_compliant",
            "Medical privacy compliant help text":
            "medical_privacy_compliant_helptext",
            "Host controls": "host_controls",
            "Easy to learn and use": "easy_to_learn_and_use",
            "Easy to learn and use help text":
            "easy_to_learn_and_use_helptext",
        }
        # Return the merged fields
        return {**generic_product_import_fields, **software_product_mappings}

    def get_export_fields(self):
        """
        This should be a dictionary of the fields to send to Airtable.
        Keys are the Column Names in Airtable. Values are the Wagtail values we want to send.
        """
        generic_product_data = super().get_export_fields()
        software_product_data = {
            "How it handles recording":
            self.handles_recordings_how,
            "Recording alert":
            self.recording_alert,
            "Recording alert help text":
            self.recording_alert_helptext,
            "Medical privacy compliant":
            True if self.medical_privacy_compliant else False,
            "Medical privacy compliant help text":
            self.medical_privacy_compliant_helptext,
            "Host controls":
            self.host_controls,
            "Easy to learn and use":
            True if self.easy_to_learn_and_use else False,
            "Easy to learn and use help text":
            self.easy_to_learn_and_use_helptext,
        }

        data = {**generic_product_data, **software_product_data}
        return data

    content_panels = ProductPage.content_panels.copy()
    content_panels = insert_panels_after(
        content_panels,
        'Product Categories',
        [
            MultiFieldPanel([
                FieldPanel('handles_recordings_how'),
                FieldPanel('recording_alert'),
                FieldPanel('recording_alert_helptext'),
                FieldPanel('medical_privacy_compliant'),
                FieldPanel('medical_privacy_compliant_helptext'),
            ],
                            heading='How does it handle privacy?',
                            classname='collapsible'),
            MultiFieldPanel([
                FieldPanel('host_controls'),
                FieldPanel('easy_to_learn_and_use'),
                FieldPanel('easy_to_learn_and_use_helptext'),
            ],
                            heading='Can I control it',
                            classname='collapsible'),
        ],
    )

    @property
    def product_type(self):
        return "software"

    class Meta:
        verbose_name = "Software Product Page"
예제 #3
0
class SoftwareProduct(Product):
    """
    A thing you can install on your computer and our review of it
    """

    # How does it handle privacy?

    handles_recordings_how = models.TextField(
        max_length=5000,
        blank=True,
        help_text='How does this software handle your recordings')

    recording_alert = ExtendedYesNoField(
        null=True,
        help_text='Alerts when calls are being recorded?',
    )

    recording_alert_helptext = models.TextField(max_length=5000, blank=True)

    signup_with_email = models.BooleanField(
        null=True,
        help_text='Email required to sign up?',
    )

    signup_with_phone = models.BooleanField(
        null=True,
        help_text='Phone number required to sign up?',
    )

    signup_with_third_party = models.BooleanField(
        null=True,
        help_text='Third Party account required to sign up?',
    )

    signup_methods_helptext = models.TextField(
        max_length=5000,
        blank=True,
        help_text=
        'Describe the kind of contact information requirements for signing up for this product'
    )

    medical_privacy_compliant = models.BooleanField(
        null=True, help_text='Compliant with US medical privacy laws?')

    medical_privacy_compliant_helptext = models.TextField(max_length=5000,
                                                          blank=True)

    # Can I control it?

    host_controls = models.TextField(max_length=5000, blank=True)

    easy_to_learn_and_use = models.BooleanField(
        null=True,
        help_text='Is it easy to learn & use the features?',
    )

    easy_to_learn_and_use_helptext = models.TextField(max_length=5000,
                                                      blank=True)

    # administrative panels

    panels = Product.panels.copy()

    panels = insert_panels_after(
        panels,
        'Minimum Security Standards for general products',
        [
            MultiFieldPanel([
                FieldPanel('signup_with_email'),
                FieldPanel('signup_with_phone'),
                FieldPanel('signup_with_third_party'),
                FieldPanel('signup_methods_helptext'),
            ],
                            heading='How does it handle signup?',
                            classname='collapsible'),
        ],
    )

    panels = insert_panels_after(
        panels,
        'How does it handle data sharing',
        [
            MultiFieldPanel([
                FieldPanel('handles_recordings_how'),
                FieldPanel('recording_alert'),
                FieldPanel('recording_alert_helptext'),
                FieldPanel('medical_privacy_compliant'),
                FieldPanel('medical_privacy_compliant_helptext'),
            ],
                            heading='How does it handle privacy?',
                            classname='collapsible'),
        ],
    )

    panels = insert_panels_after(
        panels,
        'How does it handle privacy?',
        [
            MultiFieldPanel([
                FieldPanel('host_controls'),
                FieldPanel('easy_to_learn_and_use'),
                FieldPanel('easy_to_learn_and_use_helptext'),
            ],
                            heading='Can I control it',
                            classname='collapsible'),
        ],
    )

    def to_dict(self):
        model_dict = super().to_dict()
        model_dict['product_type'] = 'software'
        return model_dict
class GeneralProduct(Product):
    """
    A thing you can buy in stores and our review of it
    """

    # Can it snoop on me

    camera_device = ExtendedYesNoField(
        help_text='Does this device have or access a camera?', )

    camera_app = ExtendedYesNoField(
        help_text='Does the app have or access a camera?', )

    microphone_device = ExtendedYesNoField(
        help_text='Does this Device have or access a microphone?', )

    microphone_app = ExtendedYesNoField(
        help_text='Does this app have or access a microphone?', )

    location_device = ExtendedYesNoField(
        help_text='Does this product access your location?', )

    location_app = ExtendedYesNoField(
        help_text='Does this app access your location?', )

    # What data does it collect?

    personal_data_collected = models.TextField(
        max_length=5000,
        blank=True,
        help_text='What kind of personal data does this product collect?')

    biometric_data_collected = models.TextField(
        max_length=5000,
        blank=True,
        help_text='What kind of biometric data does this product collect?')

    social_data_collected = models.TextField(
        max_length=5000,
        blank=True,
        help_text='What kind of social data does this product collect?')

    # How can you control your data

    how_can_you_control_your_data = models.TextField(
        max_length=5000,
        blank=True,
        help_text='How does this product let you control your data?')

    data_control_policy_is_bad = models.BooleanField(
        default=False, verbose_name='Privacy ding')

    # Company track record

    track_record_choices = [('Great', 'Great'), ('Average', 'Average'),
                            ('Needs Improvement', 'Needs Improvement'),
                            ('Bad', 'Bad')]

    company_track_record = models.CharField(
        choices=track_record_choices,
        default='Average',
        help_text='This company has a ... track record',
        max_length=20)

    track_record_is_bad = models.BooleanField(default=False,
                                              verbose_name='Privacy ding')

    track_record_details = models.TextField(
        max_length=5000,
        blank=True,
        help_text='Describe the track record of this company here.')

    # Offline use

    offline_capable = ExtendedYesNoField(
        help_text='Can this product be used offline?', )

    offline_use_description = models.TextField(
        max_length=5000,
        blank=True,
        help_text='Describe how this product can be used offline.')

    # Artificial Intelligence

    uses_ai = ExtendedYesNoField(help_text='Does the product use AI?')

    ai_uses_personal_data = ExtendedYesNoField(
        help_text=
        'Does the AI use your personal data to make decisions about you?')

    ai_is_transparent = ExtendedYesNoField(
        help_text='Does the company allow users to see how the AI works?')

    ai_helptext = models.TextField(
        max_length=5000,
        blank=True,
        help_text='Helpful text around AI to show on the product page',
    )

    # administrative panels

    panels = Product.panels.copy()

    panels = insert_panels_after(
        panels,
        'General Product Details',
        [
            MultiFieldPanel([
                FieldPanel('camera_device'),
                FieldPanel('camera_app'),
                FieldPanel('microphone_device'),
                FieldPanel('microphone_app'),
                FieldPanel('location_device'),
                FieldPanel('location_app'),
            ],
                            heading='Can it snoop?',
                            classname='collapsible'),
        ],
    )

    panels = insert_panels_after(panels, 'What is required to sign up', [
        MultiFieldPanel(
            [
                FieldPanel('personal_data_collected'),
                FieldPanel('biometric_data_collected'),
                FieldPanel('social_data_collected'),
            ],
            heading='What data does it collect',
            classname='collapsible',
        ),
    ])

    panels = insert_panels_after(
        panels,
        'How does it use this data',
        [
            MultiFieldPanel(
                [
                    FieldPanel('how_can_you_control_your_data'),
                    FieldPanel('data_control_policy_is_bad'),
                ],
                heading='How can you control your data',
                classname='collapsible',
            ),
            MultiFieldPanel([
                FieldPanel('company_track_record'),
                FieldPanel('track_record_is_bad'),
                FieldPanel('track_record_details'),
            ],
                            heading='Company track record',
                            classname='collapsible'),
            MultiFieldPanel([
                FieldPanel('offline_capable'),
                FieldPanel('offline_use_description'),
            ],
                            heading='Offline use',
                            classname='collapsible'),
        ],
    )

    panels = insert_panels_after(
        panels,
        'Security',
        [
            MultiFieldPanel([
                FieldPanel('uses_ai'),
                FieldPanel('ai_uses_personal_data'),
                FieldPanel('ai_is_transparent'),
                FieldPanel('ai_helptext'),
            ],
                            heading='Artificial Intelligence',
                            classname='collapsible'),
        ],
    )

    def to_dict(self):
        model_dict = super().to_dict()
        model_dict['product_type'] = 'general'
        return model_dict
예제 #5
0
class GeneralProduct(Product):
    """
    A thing you can buy in stores and our review of it
    """

    # It uses your...

    camera_device = ExtendedYesNoField(
        help_text='Does this device have or access a camera?', )

    camera_app = ExtendedYesNoField(
        help_text='Does the app have or access a camera?', )

    microphone_device = ExtendedYesNoField(
        help_text='Does this Device have or access a microphone?', )

    microphone_app = ExtendedYesNoField(
        help_text='Does this app have or access a microphone?', )

    location_device = ExtendedYesNoField(
        help_text='Does this product access your location?', )

    location_app = ExtendedYesNoField(
        help_text='Does this app access your location?', )

    # how it handles privacy

    delete_data = models.BooleanField(  # TO BE REMOVED?
        null=True,
        help_text='Can you request data be deleted?',
    )

    delete_data_helptext = models.TextField(  # TO BE REMOVED?
        max_length=5000, blank=True)

    parental_controls = ExtendedYesNoField(
        null=True,
        help_text='Are there rules for children?',
    )

    child_rules_helptext = models.TextField(  # TO BE REMOVED?
        max_length=5000, blank=True)

    collects_biometrics = ExtendedYesNoField(
        help_text='Does this product collect biometric data?', )

    collects_biometrics_helptext = models.TextField(max_length=5000,
                                                    blank=True)

    # administrative panels

    panels = Product.panels.copy()

    panels = insert_panels_after(
        panels,
        'Minimum Security Standards for general products',
        [
            MultiFieldPanel([
                FieldPanel('camera_device'),
                FieldPanel('camera_app'),
                FieldPanel('microphone_device'),
                FieldPanel('microphone_app'),
                FieldPanel('location_device'),
                FieldPanel('location_app'),
            ],
                            heading='Can it snoop?',
                            classname='collapsible'),
        ],
    )

    panels = insert_panels_after(
        panels,
        'How does it handle data sharing',
        [
            MultiFieldPanel([
                FieldPanel('delete_data'),
                FieldPanel('delete_data_helptext'),
                FieldPanel('parental_controls'),
                FieldPanel('collects_biometrics'),
                FieldPanel('collects_biometrics_helptext'),
                FieldPanel('user_friendly_privacy_policy'),
                FieldPanel('user_friendly_privacy_policy_helptext'),
            ],
                            heading='How does it handle privacy',
                            classname='collapsible'),
        ],
    )

    def to_dict(self):
        model_dict = super().to_dict()
        model_dict['delete_data'] = tri_to_quad(self.delete_data)
        model_dict['product_type'] = 'general'
        return model_dict
예제 #6
0
class SoftwareProduct(Product):
    """
    A thing you can install on your computer and our review of it
    """

    # How does it handle privacy?

    handles_recordings_how = models.TextField(
        max_length=5000,
        blank=True,
        help_text='How does this software handle your recordings')

    recording_alert = ExtendedYesNoField(
        null=True,
        help_text='Alerts when calls are being recorded?',
    )

    recording_alert_helptext = models.TextField(max_length=5000, blank=True)

    medical_privacy_compliant = models.BooleanField(
        null=True, help_text='Compliant with US medical privacy laws?')

    medical_privacy_compliant_helptext = models.TextField(max_length=5000,
                                                          blank=True)

    # Can I control it?

    host_controls = models.TextField(max_length=5000, blank=True)

    easy_to_learn_and_use = models.BooleanField(
        null=True,
        help_text='Is it easy to learn & use the features?',
    )

    easy_to_learn_and_use_helptext = models.TextField(max_length=5000,
                                                      blank=True)

    # administrative panels

    panels = Product.panels.copy()

    panels = insert_panels_after(
        panels,
        'General Product Details',
        [
            MultiFieldPanel([
                FieldPanel('handles_recordings_how'),
                FieldPanel('recording_alert'),
                FieldPanel('recording_alert_helptext'),
                FieldPanel('medical_privacy_compliant'),
                FieldPanel('medical_privacy_compliant_helptext'),
            ],
                            heading='How does it handle privacy?',
                            classname='collapsible'),
            MultiFieldPanel([
                FieldPanel('host_controls'),
                FieldPanel('easy_to_learn_and_use'),
                FieldPanel('easy_to_learn_and_use_helptext'),
            ],
                            heading='Can I control it',
                            classname='collapsible'),
        ],
    )

    def to_dict(self):
        model_dict = super().to_dict()
        model_dict['product_type'] = 'software'
        return model_dict