示例#1
0
 def render(self, name, value={}, attrs=None):
     if not value:
         value = ContactsField.defaults()
     return """
         <div class="contacts-list">
         </div>
         <div>
             <input type="hidden" id="id_contacts" name="%(name)s" value='%(value)s' data-key-names='%(key_names)s'>
         </div>
     """ % {
         "name": name,
         "value": mark_safe(json.dumps(value)),
         "key_names": mark_safe(json.dumps(ContactsField.key_names())),
     }
 def render(self, name, value={}, attrs=None):
     if not value:
         value = ContactsField.defaults()
     return """
         <div class="contacts-list">
         </div>
         <div>
             <input type="hidden" id="id_contacts" name="%(name)s" value='%(value)s' data-key-names='%(key_names)s'>
         </div>
     """  % {
         "name": name,
         "value": mark_safe(json.dumps(value)),
         "key_names": mark_safe(json.dumps(ContactsField.key_names())),
     }
示例#3
0
def _migrate_object(obj, custom_data=None):
    obj.contacts = ContactsField.defaults()
    obj.contacts['other'] = getattr(obj, 'contact', None) or None
    if custom_data:
        custom_data(obj)
    if obj.contacts['other']:
        obj.contacts['other'] = obj.contacts['other'].replace("**", "")
        obj.contacts = _extract_contact_info(obj.contacts)
    obj.save()
def _migrate_object(obj, custom_data=None):
    obj.contacts = ContactsField.defaults()
    obj.contacts['other'] = getattr(obj, 'contact', None) or None
    if custom_data:
        custom_data(obj)
    if obj.contacts['other']:
        obj.contacts['other'] = obj.contacts['other'].replace("**", "")
        obj.contacts = _extract_contact_info(obj.contacts)
    obj.save()
示例#5
0
def set_contato(obj):
    row_dict = obj.row_dict['Contato']

    contacts = ContactsField.defaults()
    contacts['address'] = "%s, %s - %s" % (
        row_dict['Endereço'], row_dict['Número'], row_dict['Bairro'])
    contacts['compl'] = row_dict['Complemento']
    contacts['postal_code'] = row_dict['CEP']
    contacts['city'] = "%s / %s" % (row_dict['Município'], row_dict['UF'])
    contacts['phone'] = "(%s) %s" % (row_dict['DDD'], row_dict['Telefone'])
    contacts['email'] = row_dict['E-mail']

    obj.object_dict['contacts'] = contacts
def set_contato(obj):
    row_dict = obj.row_dict['Contato']

    contacts = ContactsField.defaults()
    contacts['address'] = "%s, %s - %s" % (row_dict['Endereço'],
                                           row_dict['Número'],
                                           row_dict['Bairro'])
    contacts['compl'] = row_dict['Complemento']
    contacts['postal_code'] = row_dict['CEP']
    contacts['city'] = "%s / %s" % (row_dict['Município'], row_dict['UF'])
    contacts['phone'] = "(%s) %s" % (row_dict['DDD'], row_dict['Telefone'])
    contacts['email'] = row_dict['E-mail']

    obj.object_dict['contacts'] = contacts
示例#7
0
class Resource(GeoRefModel, BaseModel):
    """Resources model"""
    name = models.CharField(max_length=256, default=_('Resource without name'))
    # slug = models.CharField(max_length=256, blank=False, db_index=True)
    kind = models.ForeignKey(ResourceKind, null=True, blank=True)
    description = models.TextField()
    short_description = models.CharField(max_length=250, null=True, blank=True)
    contacts = ContactsField()
    tags = TaggableManager()

    community = models.ManyToManyField(Community,
                                       related_name='resources',
                                       null=True,
                                       blank=True)  # TODO remove me

    # Meta info
    creator = models.ForeignKey(User,
                                editable=False,
                                null=True,
                                related_name='created_resources')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User,
                                    editable=False,
                                    null=True,
                                    blank=True)
    last_update = models.DateTimeField(auto_now=True)

    class Map:
        title = _('Resource')
        editable = True
        background_color = '#28CB05'
        border_color = '#1D9104'
        geometries = (POLYGON, LINESTRING, POINT)
        form_view_name = 'new_resource_from_map'
        zindex = 15

    def __unicode__(self):
        return unicode(self.name)

    image = "img/resource.png"
    image_off = "img/resource-off.png"
    default_logo_url = "img/logo-resource.png"

    def files_set(self):
        """ pseudo-reverse query for retrieving Resource Files"""
        return UploadedFile.get_files_for(self)

    @property
    def home_url_params(self):
        return dict(id=self.id)

    @property
    def view_url(self):
        return reverse('view_resource', kwargs=self.home_url_params)

    @property
    def edit_url(self):
        return reverse('edit_resource', kwargs=self.home_url_params)

    @property
    def admin_url(self):
        return reverse('admin:{}_{}_change'.format(self._meta.app_label,
                                                   self._meta.module_name),
                       args=[self.id])

    @property
    def perm_id(self):
        return 'r%d' % self.id

    def save(self, *args, **kwargs):
        r_ = super(Resource, self).save(*args, **kwargs)
        index_object_for_search.send(sender=self, obj=self)
        return r_

    # ==========================================================================
    # Utils

    # def from_dict(self, data):
    #     keys = ['id', 'name', 'contact', 'geojson',  'creation_date',
    #             'is_admin', 'is_active', 'about_me']
    #     date_keys = ['creation_date']
    #     build_obj_from_dict(self, data, keys, date_keys)

    def to_dict(self):
        fields_and_defaults = [
            ('name', None),
            ('kind_id', None),
            ('description', None),
            ('short_description ', None),
            ('creator_id', None),
            ('creation_date', None),
            ('last_editor_id', None),
            ('last_update', None),
            ('geojson', {}),
            ('contacts', {}),
        ]
        dict_ = {v[0]: getattr(self, v[0], v[1]) for v in fields_and_defaults}
        dict_['tags'] = [tag.name for tag in self.tags.all()]
        return dict_
def view_contacts(contacts):
    filtered_contacts = [(key, ContactsField.key_name(key), contacts[key])
        for key in ContactsField.key_order() if contacts.get(key, None)]
    return {"contacts": filtered_contacts}
示例#9
0
class Organization(GeoRefModel, BaseModel):
    name = models.CharField(max_length=320, unique=True)
    slug = models.SlugField(max_length=320, db_index=True)  # used anywhere?
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=250, null=True, blank=True)
    logo = models.ForeignKey(UploadedFile, null=True, blank=True)
    logo_category = models.ForeignKey('OrganizationCategory', null=True,
                       blank=True, related_name='organization_category_logo')
    logo_choice = models.CharField(max_length=3, choices=LOGO_CHOICES,
                        null=True, blank=True)

    # Meta info
    creator = models.ForeignKey(User, editable=False, null=True,
                        related_name='created_organizations')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User, editable=False, null=True,
                        blank=True)
    last_update = models.DateTimeField(auto_now=True)

    community = models.ManyToManyField(Community, null=True, blank=True) # TODO remove-me

    contacts = ContactsField()

    categories = models.ManyToManyField('OrganizationCategory', null=True,
                        blank=True)
    target_audiences = models.ManyToManyField(TargetAudience, null=True,
                        blank=True)

    tags = TaggableManager()

    class Map:
        editable = True
        title = _('Organization')
        tooltip = _('Add an organization')
        background_color = '#3a61d6'
        border_color = '#1f49b2'
        geometries = (POLYGON, POINT)
        form_view_name = 'new_organization_from_map'

    @property
    def communities(self):
        from relations.models import Relation
        return [rel['target'] for rel in Relation.relations_for(self)
                if rel['target'].__class__.__name__ == 'Community']
    @property
    def related_items(self):
        return [c for c in self.communities] # + \
               # [r for r in self.supported_resources] + \
               # [p.need for p in self.supported_proposals] + \
               # [o for o in self.supported_organizations]

    @property
    def as_investor(self):
        investor, created = Investor.get_or_create_for(self)
        return investor

    def __unicode__(self):
        return unicode(self.name)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        r_ = super(Organization, self).save(*args, **kwargs)
        index_object_for_search.send(sender=self, obj=self)
        return r_

    def files_set(self):
        """ pseudo-reverse query for retrieving Organization Files"""
        return UploadedFile.get_files_for(self)

    @property
    def logo_url(self):
        if self.logo and not self.logo_category:
            return self.logo.file.url
        elif not self.logo and self.logo_category:
            return '/static/' + self.logo_category.image
        else:
            if self.logo_choice == 'CAT':
                return '/static/' + self.logo_category.image
            elif self.logo_choice == 'UP':
                return self.logo.file.url
            else:
                return '/static/img/logo.png'

    image = "img/organization.png"
    image_off = "img/organization-off.png"

    # url aliases
    @property
    def home_url_params(self):
        return dict(id=self.id)

    @property
    def view_url(self):
        return reverse('view_organization', kwargs=self.home_url_params)

    @property
    def edit_url(self):
        return reverse('edit_organization', kwargs=self.home_url_params)

    @property
    def admin_url(self):
        return reverse('admin:{}_{}_change'.format(self._meta.app_label,
            self._meta.module_name), args=[self.id])

    @property
    def related_items_url(self):
        return reverse('view_organization_related_items',
                       kwargs=self.home_url_params)

    @property
    def json(self):
        return to_json({
            'name': self.name,
            'slug': self.slug,
            'logo_url': self.logo_url,
            'view_url': self.view_url,
        })

    def perm_id(self):
        return 'o%d' % self.id

    # ==========================================================================
    # Utils

    # def from_dict(self, data):
    #     keys = ['id', 'name', 'contact', 'geojson',  'creation_date',
    #             'is_admin', 'is_active', 'about_me']
    #     date_keys = ['creation_date']
    #     build_obj_from_dict(self, data, keys, date_keys)

    def to_dict(self):
        fields_and_defaults = [
            ('name', None), ('slug', None), ('description', None),
            ('short_description ', None),
            ('creator_id', None), ('creation_date', None),
            ('last_editor_id', None), ('last_update', None),
            ('logo_id', None), ('logo_category_id', None),
            ('logo_choice', None),
            ('contacts', {}), ('geojson', {})
        ]
        dict_ = {v[0]: getattr(self, v[0], v[1]) for v in fields_and_defaults}
        dict_['tags'] = [tag.name for tag in self.tags.all()]
        dict_['target_audiences'] = [ta.name for ta in self.target_audiences.all()]
        dict_['categories'] = [cat.id for cat in self.categories.all()]
        return dict_
示例#10
0
class Community(GeoRefModel, BaseModel):
    name = models.CharField(max_length=256, blank=False)
    # Auto-generated url slug. It's not editable via ModelForm.
    slug = models.SlugField(max_length=256, blank=False, db_index=True)
    population = models.IntegerField(null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    short_description = models.CharField(max_length=250, null=True, blank=True)
    contacts = ContactsField()
    tags = TaggableManager()

    # Meta info
    creator = models.ForeignKey(User,
                                editable=False,
                                null=True,
                                related_name='created_communities')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User,
                                    editable=False,
                                    null=True,
                                    blank=True)
    last_update = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.name

    class Map:
        title = _('Community')
        editable = True
        background_color = '#ffc166'
        border_color = '#ff2e2e'
        geometries = (POLYGON, )
        form_view_name = 'new_community'
        min_zoom_geometry = 10
        max_zoom_geometry = 100
        #min_zoom_point = 0
        #max_zoom_point = 0
        #min_zoom_icon = 0
        #max_zoom_icon = 0
        zindex = 5

    class Meta:
        verbose_name = "community"
        verbose_name_plural = "communities"

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        r_ = super(Community, self).save(*args, **kwargs)
        index_object_for_search.send(sender=self, obj=self)
        return r_

    image = "img/community.png"
    image_off = "img/community-off.png"
    default_logo_url = "img/logo-community.png"

    # TODO: order communities from the database
    def closest_communities(self, max=3, radius=Distance(km=25)):
        center = self.geometry.centroid
        unordered = Community.objects.filter(polys__distance_lte=(center,
                                                                  radius))
        closest = sorted(unordered, key=lambda c: c.geometry.distance(center))
        return closest[1:(max + 1)]

    # url aliases
    @property
    def view_url(self):
        return reverse('view_community', kwargs={'id': self.id})

    @property
    def edit_url(self):
        return reverse('edit_community', kwargs={'id': self.id})

    @property
    def admin_url(self):
        return reverse('admin:{}_{}_change'.format(self._meta.app_label,
                                                   self._meta.module_name),
                       args=[self.id])

    @property
    def perm_id(self):
        return 'c%d' % self.id

    # ==========================================================================
    # Utils

    # def from_dict(self, data):
    #     keys = ['id', 'name', 'contact', 'geojson',  'creation_date',
    #             'is_admin', 'is_active', 'about_me']
    #     date_keys = ['creation_date']
    #     build_obj_from_dict(self, data, keys, date_keys)

    def to_dict(self):
        fields_and_defaults = [('name', None), ('slug', None),
                               ('population', None), ('description', None),
                               ('short_description ', None),
                               ('creator_id', None), ('creation_date', None),
                               ('last_editor_id', None), ('last_update', None),
                               ('geojson', {}), ('contacts', {})]
        dict_ = {v[0]: getattr(self, v[0], v[1]) for v in fields_and_defaults}
        dict_['tags'] = [tag.name for tag in self.tags.all()]
        return dict_
示例#11
0
def view_contacts(contacts):
    filtered_contacts = [(key, ContactsField.key_name(key), contacts[key])
                         for key in ContactsField.key_order()
                         if contacts.get(key, None)]
    return {"contacts": filtered_contacts}
示例#12
0
class Proposal(models.Model):
    """A proposed solution for solving a need"""
    class Meta:
        verbose_name = "proposal"
        verbose_name_plural = "proposals"

    title = models.CharField(max_length=256)
    description = models.TextField()
    short_description = models.CharField(max_length=250, null=True, blank=True)

    number = models.IntegerField(null=False, blank=True, editable=False)

    contacts = ContactsField()
    tags = TaggableManager()

    # Meta info
    creator = models.ForeignKey(User,
                                editable=False,
                                null=True,
                                related_name='created_proposals')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User,
                                    editable=False,
                                    null=True,
                                    blank=True)
    last_update = models.DateTimeField(auto_now=True)

    # Relationships
    need = models.ForeignKey(Need, related_name='proposals')

    # TODO: Also: organizations = model.ManyToManyField(Organization)
    cost = models.DecimalField(decimal_places=2,
                               max_digits=14,
                               null=True,
                               blank=True)
    report = models.TextField(null=True, blank=True)

    investments = generic.GenericRelation(
        Investment,
        content_type_field='grantee_content_type',
        object_id_field='grantee_object_id')
    #dummy? readding to data charge to work
    realizers = models.ManyToManyField(User, related_name='user_realizers')

    @property
    def name(self):
        return self.title

    @property
    def community(self):
        return self.need.community

    @property
    def geometry(self):
        return self.need.geometry

    def save(self, *args, **kwargs):
        if not self.id:
            # auto numbering a need's proposals
            self.number = Proposal.objects.filter(need=self.need).count() + 1
        super(Proposal, self).save(*args, **kwargs)

    def __unicode__(self):
        return unicode(self.title)

    # Url aliases
    @property
    def home_url_params(self):
        return dict(id=self.id)

    @property
    def view_url(self):
        return reverse('view_proposal', kwargs=self.home_url_params)

    @property
    def edit_url(self):
        return reverse('edit_proposal', kwargs=self.home_url_params)

    @property
    def admin_url(self):
        return reverse('admin:{}_{}_change'.format(self._meta.app_label,
                                                   self._meta.module_name),
                       args=[self.id])

    @property
    def new_investment_url(self):
        return reverse('new_investment') + '?type=proposal&obj={id}'.format(
            id=self.id)

    @property
    def perm_id(self):
        return 'p%d' % self.id
示例#13
0
class Need(GeoRefModel, BaseModel):
    class Meta:
        verbose_name = "need"
        verbose_name_plural = "needs"

    name = models.CharField(max_length=256, blank=False)
    slug = models.CharField(max_length=256, blank=False, db_index=True)
    description = models.TextField()
    short_description = models.CharField(max_length=250, null=True, blank=True)

    # Meta info
    creator = models.ForeignKey(User,
                                editable=False,
                                null=True,
                                related_name='created_needs')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User,
                                    editable=False,
                                    null=True,
                                    blank=True)
    last_update = models.DateTimeField(auto_now=True)

    contacts = ContactsField()

    # Relationships
    community = models.ManyToManyField(
        Community,
        related_name="needs",  # TODO: remove-me
        null=True,
        blank=True)
    categories = models.ManyToManyField(NeedCategory)
    target_audiences = models.ManyToManyField(TargetAudience, blank=False)

    tags = TaggableManager()

    class Map:
        title = _('Need')
        editable = True
        background_color = '#f42c5e'
        border_color = '#d31e52'
        geometries = (POLYGON, LINESTRING, POINT)
        categories = NeedCategory.categories
        form_view_name = 'new_need_from_map'
        form_view_kwargs = {}

    def __unicode__(self):
        return unicode(self.name)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        r_ = super(Need, self).save(*args, **kwargs)
        index_object_for_search.send(sender=self, obj=self)
        return r_

    image = "img/need.png"
    image_off = "img/need-off.png"
    default_logo_url = "img/logo-need.png"

    # Url aliases
    @property
    def home_url_params(self):
        return {'id': self.id}

    @property
    def view_url(self):
        return reverse('view_need', kwargs=self.home_url_params)

    @property
    def edit_url(self):
        return reverse('edit_need', kwargs=self.home_url_params)

    @property
    def admin_url(self):
        return reverse('admin:{}_{}_change'.format(self._meta.app_label,
                                                   self._meta.module_name),
                       args=[self.id])

    @property
    def title(self):
        return self.name

    @property
    def perm_id(self):
        return 'n%d' % self.id

    # ==========================================================================
    # Utils

    # def from_dict(self, data):
    #     keys = ['id', 'name', 'contact', 'geojson',  'creation_date',
    #             'is_admin', 'is_active', 'about_me']
    #     date_keys = ['creation_date']
    #     build_obj_from_dict(self, data, keys, date_keys)

    def to_dict(self):
        fields_and_defaults = [
            ('name', None),
            ('slug', None),
            ('description', None),
            ('short_description ', None),
            ('creator_id', None),
            ('creation_date', None),
            ('last_editor_id', None),
            ('last_update', None),
            ('geojson', {}),
            ('contacts', {}),
        ]
        dict_ = {v[0]: getattr(self, v[0], v[1]) for v in fields_and_defaults}
        dict_['tags'] = [tag.name for tag in self.tags.all()]
        dict_['target_audiences'] = [
            ta.name for ta in self.target_audiences.all()
        ]
        dict_['categories'] = [cat.id for cat in self.categories.all()]
        return dict_
示例#14
0
class User(GeoRefModel, BaseModel):
    """
    User model. Replaces django.contrib.auth, CAS and social_auth
    with our own unified solution.
    its intended to use with external login providers.

    password: is set only if not created through external providers

    """
    name = models.CharField(max_length=256, null=False)
    email = models.CharField(max_length=512, null=False, unique=True)
    about_me = models.TextField(null=True, blank=True, default='')
    password = models.CharField(max_length=256, null=False)
    contacts = ContactsField()
    creation_date = models.DateField(null=True, blank=True, auto_now_add=True)
    language = models.CharField(max_length=10, null=True, blank=True)
    # last_access = models.DateTimeField(null=True, blank=True)

    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    # Deprecated
    # verification_key = models.CharField(max_length=32, null=True)

    # Attributes used by PermissionMixin
    private_fields = ['email']
    internal_fields = ['password']

    class Map:
        editable = False
        geometries = [POINT]
        categories = ['me', 'user']
        min_zoom_geometry = 0
        max_zoom_geometry = 100
        min_zoom_point = 100
        max_zoom_point = 100
        min_zoom_icon = 100
        max_zoom_icon = 10

    @classmethod
    def calc_hash(self, s, salt=None):
        if not salt:
            salt = settings.USER_PASSWORD_SALT
        return unicode(sha1(salt + s).hexdigest())

    def set_password(self, s, salt=None):
        self.password = self.calc_hash(s, salt=salt)

    def set_language(self, language_code):
        if translation.check_for_language(language_code):
            self.language = language_code
            return True
        return False

    def verify_password(self, s, salt=None):
        return self.password == self.calc_hash(s, salt)

    def is_authenticated(self):
        return True

    def is_anonymous(self):
        return False

    def is_superuser(self):
        return self.is_admin

    def __unicode__(self):
        return unicode(self.name)

    @property
    def url(self):
        return reverse('user_view', kwargs={'id': self.id})

    @property
    def view_url(self):
        return self.url

    def files_set(self):
        """ pseudo-reverse query for retrieving Resource Files"""
        return UploadedFile.get_files_for(self)

    @property
    def avatar(self):
        url = '{}img/user-placeholder.png'.format(settings.STATIC_URL)
        files = self.files_set()
        for fl in files:
            if os.path.exists(fl.file.url[1:]):
                url = fl.file.url
                break
        return url

    def _social_auth_by_name(self, name):
        """
        Retrieve the SocialAuth entry for this User given a high level
        social provider name.
        """
        credentials = self.socialauth_set.filter(provider=PROVIDERS[name])
        return credentials.get() if credentials.exists() else None

    def google(self):
        return self._social_auth_by_name('google')

    def facebook(self):
        return self._social_auth_by_name('facebook')

    # ==================== Interface for django admin ======================= #
    def is_staff(self):
        return self.is_admin

    def has_module_perms(self, mod):
        return self.is_admin

    def has_perm(self, perm):
        return self.is_admin

    # dummy fix for django weirdness =/
    def get_and_delete_messages(self):
        pass

    # ====================  utils =========================================== #
    def from_dict(self, data):
        keys = [
            'id', 'name', 'email', 'password', 'contacts', 'geojson',
            'creation_date', 'is_admin', 'is_active', 'about_me'
        ]
        date_keys = ['creation_date']
        build_obj_from_dict(self, data, keys, date_keys)

    def to_dict(self):
        fields_and_defaults = [('id', None), ('name', None), ('email', None),
                               ('contacts', {}), ('geojson', {}), ('url', ''),
                               ('password', None), ('creation_date', None),
                               ('is_admin', False), ('is_active', False),
                               ('avatar', None), ('about_me', '')]
        dict_ = {v[0]: getattr(self, v[0], v[1]) for v in fields_and_defaults}
        return dict_

    def is_valid(self, ignore=[]):
        self.errors = {}
        valid = True

        # verify required fields
        required = ['name', 'email', 'password']
        for field in required:
            if not field in ignore and not getattr(self, field, None):
                valid, self.errors[field] = False, _('Required field')

        if not self.id:
            # new User
            if SocialAuth.objects.filter(email=self.email).exists():
                valid = False
                self.errors['email'] = _(
                    'This email is registered on our '
                    'system. You might have logged before with a social '
                    'account (Facebook or Google). Please, skip this step '
                    'and just login.')

            if User.objects.filter(email=self.email).exists():
                valid = False
                self.errors['email'] = _('Email address already in use')

        return valid

    def send_confirmation_mail(self, request):
        """ send async confirmation mail """
        key = Locker.deposit(self.id)
        verification_url = request.build_absolute_uri(
            reverse('user_verification', args=(key, )))
        send_mail_async(title=_('Welcome to MootiroMaps'),
                        receivers=[self.email],
                        message=CONFIRMATION_EMAIL_MSG.format(
                            name=self.name, verification_url=verification_url))

    def send_recovery_mail(self, request):
        """ send async recovery mail """
        key = Locker.deposit(self.id)
        recovery_url = request.build_absolute_uri(
            reverse('recover_password', args=(key, )))
        send_mail_async(title=_('Password recovery'),
                        receivers=[self.email],
                        message=RECOVERY_EMAIL_MSG.format(
                            name=self.name, recovery_url=recovery_url))

    # DEPRECATED
    # def contributions(self, page=1, num=None):
    #     """ return user's update """
    #     return get_user_updates(self, page=page, num=num)

    #### Compatibility (to be deprecated soon)
    def get_first_name(self):
        return self.name.split(' ')[0]

    def save(self, *args, **kwargs):
        r = super(User, self).save(*args, **kwargs)
        index_object_for_search.send(sender=self, obj=self)
        return r

    def projects_contributed(self):
        from komoo_project.models import Project
        return Project.get_projects_for_contributor(self)
示例#15
0
class Project(BaseModel, geomodels.Model):
    name = models.CharField(max_length=1024)
    slug = models.SlugField(max_length=1024)
    description = models.TextField()
    short_description = models.CharField(max_length=250, null=True, blank=True)

    tags = TaggableManager()

    contributors = models.ManyToManyField(User,
                                          null=True,
                                          blank=True,
                                          related_name='project_contributors')
    community = models.ManyToManyField(Community, null=True, blank=True)

    contacts = ContactsField()

    logo = models.ForeignKey(UploadedFile, null=True, blank=True)

    creator = models.ForeignKey(User,
                                editable=False,
                                null=True,
                                related_name='created_projects')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User,
                                    editable=False,
                                    null=True,
                                    blank=True,
                                    related_name='project_last_editor')
    last_update = models.DateTimeField(auto_now=True)

    _maptype = models.CharField(db_column='maptype',
                                max_length=32,
                                null=True,
                                default=DEFAULT_MAPTYPE,
                                editable=False)
    bounds_cache = geomodels.PolygonField(null=True,
                                          blank=True,
                                          editable=False)
    custom_bounds = geomodels.PolygonField(null=True,
                                           blank=True,
                                           editable=False)

    def __unicode__(self):
        return unicode(self.name)

    def slug_exists(self, slug):
        return Project.objects.filter(slug=slug).exists()

    def save(self, *a, **kw):
        self.slug = slugify(self.name)
        r = super(Project, self).save(*a, **kw)
        index_object_for_search.send(sender=self, obj=self)
        return r

    def partners_logo(self):
        """ pseudo-reverse query for retrieving the partners logo"""
        return UploadedFile.get_files_for(self)

    @property
    def all_contributors(self):
        seen = set()
        seen_add = seen.add
        iterable = itertools.chain(self.contributors.all(), [self.creator])
        for element in itertools.ifilterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element

    @property
    def layers(self):
        return [
            layer.to_dict()
            for layer in self.project_layers.order_by('position')
        ]

    @layers.setter
    def layers(self, data):
        for layer_ in data:
            id = layer_.get('id', None)
            if not id:  # Create new layer
                layer = Layer()
                layer.project = self
            else:
                layer = Layer.objects.get(id=int(id))

            if layer_.get('delete', False):
                # The layers is marked to be removed
                layer.delete()
            else:
                layer.from_dict(layer_)
                layer.save()

    @property
    def public(self):
        ''' Temporary property to avoid crashes. '''
        return True

    @property
    def public_discussion(self):
        ''' Temporary property to avoid crashes. '''
        return True

    def user_can_edit(self, user):
        return True

    def user_can_discuss(self, user):
        return True

    @property
    def home_url_params(self):
        return dict(id=self.id)

    @property
    def view_url(self):
        return reverse('project_view', kwargs=self.home_url_params)

    @property
    def edit_url(self):
        return reverse('project_edit', kwargs=self.home_url_params)

    @property
    def perm_id(self):
        return 'j%d' % self.id  # project, and not Proposal

    @property
    def logo_url(self):
        if self.logo:
            return self.logo.file.url
        else:
            return '{}img/project-placeholder.png'.format(settings.STATIC_URL)

    @property
    def related_objects(self):
        """Returns a queryset for the objects for a given project"""
        return ProjectRelatedObject.objects.filter(project=self)

    def filter_related_items(self, query, models):
        items = []
        for model in models:
            ct = ContentType.objects.get_for_model(model)
            obj_ids = (self.related_objects.values_list(
                "object_id", flat=True).filter(content_type=ct))
            obj = model.objects.filter(Q(pk__in=obj_ids) & query)
            for o in obj:
                items.append(o)
        return items

    def save_related_object(self, related_object, user=None, silent=False):
        ct = ContentType.objects.get_for_model(related_object)
        # Adds the object to project
        obj, created = ProjectRelatedObject.objects.get_or_create(
            content_type_id=ct.id,
            object_id=related_object.id,
            project_id=self.id)
        self._update_bounds_cache()
        if user:
            # Adds user as contributor
            self.contributors.add(user)
            # Creates update entry
            if created and not silent:
                from update.models import Update
                from update.signals import create_update
                create_update.send(sender=obj.__class__,
                                   user=user,
                                   instance=obj,
                                   type=Update.EDIT)
        return created

    @property
    def related_items(self):
        #return itertools.chain(self.all_contributors,
        #                       self.filter_related_items(Q(), get_models()))
        return self.filter_related_items(Q(), get_models())

    @property
    def bounds(self):
        if not self.bounds_cache:
            self._update_bounds_cache()
        return self.bounds_cache

    def _update_bounds_cache(self):
        # Get the project items
        items = self.related_items
        bounds = None
        for item in items:
            if not item.geometry.empty:
                if not bounds:
                    bounds = item.bounds
                else:
                    bounds = Polygon.from_bbox(
                        bounds.envelope.union(item.bounds.envelope).extent)
        self.bounds_cache = bounds
        self.save()
        return bounds

    @property
    def bbox(self):
        coords = self.bounds.coords[0]
        return [coords[0][1], coords[0][0], coords[2][1], coords[2][0]]

    @property
    def custom_bbox(self):
        if not self.custom_bounds:
            return None
        coords = self.custom_bounds.coords[0]
        return [coords[0][1], coords[0][0], coords[2][1], coords[2][0]]

    @custom_bbox.setter
    def custom_bbox(self, value):
        self.custom_bounds = Polygon.from_bbox(tuple(value))

    @property
    def maptype(self):
        return self._maptype or DEFAULT_MAPTYPE

    @maptype.setter
    def maptype(self, value):
        self._maptype = value

    @property
    def json(self):
        return to_json({
            'name':
            self.name,
            'slug':
            self.slug,
            'logo_url':
            self.logo_url,
            'view_url':
            self.view_url,
            'partners_logo': [{
                'url': logo.file.url
            } for logo in self.partners_logo()],
            'bbox':
            self.bbox,
            'custom_bbox':
            self.custom_bbox,
            'maptype':
            self.maptype,
        })

    @property
    def geojson(self):
        items = []
        for obj in self.related_items:
            if obj and not obj.is_empty():
                items.append(obj)
        return create_geojson(items)

    @classmethod
    def get_projects_for_contributor(cls, user):
        return Project.objects.filter(
            Q(contributors__in=[user]) | Q(creator=user)).distinct()

    # ==========================================================================
    # Utils

    # def from_dict(self, data):
    #     keys = ['id', 'name', 'contact', 'geojson',  'creation_date',
    #             'is_admin', 'is_active', 'about_me']
    #     date_keys = ['creation_date']
    #     build_obj_from_dict(self, data, keys, date_keys)

    def to_dict(self):
        fields_and_defaults = [
            ('name', None),
            ('slug', None),
            ('description', None),
            ('short_description ', None),
            ('creator_id', None),
            ('creation_date', None),
            ('last_editor_id', None),
            ('last_update', None),
            ('logo_id', None),
            ('contacts', {}),
            ('bounds', None),
        ]
        dict_ = {v[0]: getattr(self, v[0], v[1]) for v in fields_and_defaults}
        dict_['tags'] = [tag.name for tag in self.tags.all()]
        dict_['community'] = [comm.id for comm in self.community.all()]
        dict_['contributors'] = [cont.name for cont in self.contributors.all()]
        # TODO: related_objects
        return dict_
示例#16
0
class Investment(models.Model):
    """A donation of money (or any other stuff) for either an Organization, a
    Proposal or a Resource in the system.
    """

    CURRENCIES_CHOICES = (
        ('BRL', _('Brazilian Real (BRL)')),
        ('USD', _('US-Dollar (USD)')),
        ('EUR', _('Euro')),
    )

    name = models.CharField(max_length=256)
    # Auto-generated url slug. It's not editable via ModelForm.
    slug = models.CharField(max_length=256,
                            null=False,
                            blank=False,
                            db_index=True,
                            editable=False)
    description = models.TextField()
    short_description = models.CharField(max_length=250, null=True, blank=True)
    contacts = ContactsField()
    value = models.DecimalField(decimal_places=2,
                                max_digits=14,
                                null=True,
                                blank=True)
    currency = models.CharField(max_length=3,
                                choices=CURRENCIES_CHOICES,
                                null=True,
                                blank=True)

    date = models.DateField(null=False)
    # TODO: remove over_period. Get this info by existence of an end_date
    over_period = models.BooleanField(default=False)
    end_date = models.DateField(null=True)

    # Meta info
    creator = models.ForeignKey(User,
                                editable=False,
                                null=True,
                                related_name='created_investments')
    creation_date = models.DateTimeField(auto_now_add=True)
    last_editor = models.ForeignKey(User,
                                    editable=False,
                                    null=True,
                                    blank=True)
    last_update = models.DateTimeField(auto_now=True)

    # Relationships
    investor = models.ForeignKey(Investor,
                                 related_name="investments",
                                 null=True,
                                 blank=True)

    # Grantee generic relationship
    grantee_content_type = models.ForeignKey(ContentType, editable=False)
    grantee_object_id = models.PositiveIntegerField(editable=False)
    grantee = generic.GenericForeignKey('grantee_content_type',
                                        'grantee_object_id')

    tags = TaggableManager()

    def __unicode__(self):
        return unicode(self.name)

    @property
    def title(self):
        return self.name

    @property
    def community(self):
        return self.grantee.community

    def save(self, *args, **kwargs):
        # TODO: validate grantee as either a Proposal, a Resource or
        #       an Organization
        # TODO: validate investor as either a User or an Organization
        self.slug = slugify(self.name)
        super(Investment, self).save(*args, **kwargs)

    # Url aliases
    @property
    def view_url(self):
        return reverse('view_investment', kwargs={'id': self.id})

    @property
    def edit_url(self):
        return reverse('edit_investment', kwargs={'id': self.id})

    @property
    def perm_id(self):
        return 'i%d' % self.id

    def is_empty(self):
        return True