class HelpFile(TendenciBaseModel): """Question/Answer infromation""" LEVELS = ('basic', 'intermediate', 'advanced', 'expert') LEVEL_CHOICES = [(i, i) for i in LEVELS] slug = SlugField(_('URL Path'), unique=True) topics = models.ManyToManyField(Topic) question = models.CharField(max_length=500) answer = tinymce_models.HTMLField() level = models.CharField(choices=LEVEL_CHOICES, max_length=100, default='basic') is_faq = models.BooleanField() is_featured = models.BooleanField() is_video = models.BooleanField() syndicate = models.BooleanField(_('Include in RSS feed'), default=True) view_totals = models.PositiveIntegerField(default=0) group = models.ForeignKey(Group, null=True, default=None, on_delete=models.SET_NULL) perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = HelpFileManager() class Meta: permissions = (("view_helpfile", "Can view help file"), ) @models.permalink def get_absolute_url(self): return ("help_file.details", [self.slug]) def __unicode__(self): return self.question def level_is(self): "Template helper: {% if file.level_is.basic %}..." return dict([i, self.level == i] for i in HelpFile.LEVELS)
class Resume(TendenciBaseModel): guid = models.CharField(max_length=40) title = models.CharField(max_length=250) slug = SlugField(_('URL Path'), unique=True) description = tinymce_models.HTMLField() location = models.CharField(max_length=500, blank=True) # cannot be foreign, needs to be open 'Texas' 'All 50 States' 'US and International' skills = models.TextField(blank=True) experience = models.TextField(blank=True) awards = models.TextField(_('Awards and Certifications'), blank=True) education = models.TextField(blank=True) is_agency = models.BooleanField() # defines if the resume posting is by a third party agency #TODO: do we need these fields? #desiredlocationstate = models.CharField(max_length=50) #desiredlocationcountry = models.CharField(max_length=50) #willingtorelocate = models.BooleanField() #workschedulepreferred = models.CharField(max_length=100) #compensationdesired = models.CharField(max_length=50) #licenses = models.CharField(max_length=100) #certifications = models.CharField(max_length=100) #expertise = models.CharField(max_length=800) #languages = models.CharField(max_length=120) # date related fields list_type = models.CharField(max_length=50, default='regular') # premium or regular requested_duration = models.IntegerField(default=30) activation_dt = models.DateTimeField(null=True, blank=True) # date resume listing was activated expiration_dt = models.DateTimeField(null=True, blank=True) # date resume expires based on activation date and duration resume_url = models.CharField(max_length=300, blank=True) # link to other (fuller) resume posting resume_file = models.FileField(_('Upload your resume here'), max_length=260, upload_to=file_directory, blank=True, default="") syndicate = models.BooleanField(_('Include in RSS feed'), blank=True) #TODO: foreign contact_name = models.CharField(max_length=150, blank=True) contact_address = models.CharField(max_length=50, blank=True) contact_address2 = models.CharField(max_length=50, blank=True) contact_city = models.CharField(max_length=50, blank=True) contact_state = models.CharField(max_length=50, blank=True) contact_zip_code = models.CharField(max_length=50, blank=True) contact_country = models.CharField(max_length=50, blank=True) contact_phone = models.CharField(max_length=50, blank=True) contact_phone2 = models.CharField(max_length=50, blank=True) contact_fax = models.CharField(max_length=50, blank=True) contact_email = models.CharField(max_length=300, blank=True) contact_website = models.CharField(max_length=300, blank=True) # authority fields # allow_anonymous_view = models.BooleanField(_("Public can view")) # allow_user_view = models.BooleanField(_("Signed in user can view")) # allow_member_view = models.BooleanField() # allow_anonymous_edit = models.BooleanField() # allow_user_edit = models.BooleanField(_("Signed in user can change")) # allow_member_edit = models.BooleanField() # create_dt = models.DateTimeField(auto_now_add=True) # update_dt = models.DateTimeField(auto_now=True) # creator = models.ForeignKey(User, related_name="%(class)s_creator", editable=False, null=True, on_delete=models.SET_NULL) # creator_username = models.CharField(max_length=50, null=True) # owner = models.ForeignKey(User, related_name="%(class)s_owner", null=True, on_delete=models.SET_NULL) # owner_username = models.CharField(max_length=50, null=True) # status = models.BooleanField("Active", default=True) # status_detail = models.CharField(max_length=50, default='active') meta = models.OneToOneField(MetaTags, null=True) tags = TagField(blank=True) perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = ResumeManager() class Meta: permissions = (("view_resume", _("Can view resume")),) def get_meta(self, name): """ This method is standard across all models that are related to the Meta model. Used to generate dynamic meta information niche to this model. """ return ResumeMeta().get_meta(self, name) @models.permalink def get_absolute_url(self): return ("resume", [self.slug]) def save(self, *args, **kwargs): self.guid = self.guid or uuid.uuid1() super(Resume, self).save(*args, **kwargs) def __unicode__(self): return self.title def is_pending(self): return self.status == 0 and self.status_detail == 'pending'
class BasePage(TendenciBaseModel): guid = models.CharField(max_length=40) title = models.CharField(max_length=500, blank=True) slug = SlugField(_('URL Path')) header_image = models.ForeignKey('HeaderImage', null=True) content = tinymce_models.HTMLField() view_contact_form = models.BooleanField() design_notes = models.TextField(_('Design Notes'), blank=True) syndicate = models.BooleanField(_('Include in RSS feed')) template = models.CharField(_('Template'), max_length=50, blank=True) tags = TagField(blank=True) meta = models.OneToOneField(MetaTags, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") class Meta: abstract = True def save(self, *args, **kwargs): if not self.guid: self.guid = str(uuid.uuid1()) super(BasePage, self).save(*args, **kwargs) if self.header_image: if self.is_public(): set_s3_file_permission(self.header_image.file, public=True) else: set_s3_file_permission(self.header_image.file, public=False) def __unicode__(self): return self.title def get_header_image_url(self): if not self.header_image: return '' if self.is_public(): return self.header_image.file.url return reverse('page.header_image', args=[self.id]) def is_public(self): return all([ self.allow_anonymous_view, self.status, self.status_detail in ['active'] ]) @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items @property def version(self): if self.status and self.status_detail: return self.status_detail + '-' + str(self.pk) + ' ' + str( self.create_dt) elif not self.status: return 'deleted-' + str(self.pk) + ' ' + str(self.create_dt) return ''
class News(TendenciBaseModel): guid = models.CharField(max_length=40) slug = SlugField(_('URL Path'), unique=True) timezone = TimeZoneField(_('Time Zone')) headline = models.CharField(max_length=200, blank=True) summary = models.TextField(blank=True) body = tinymce_models.HTMLField() source = models.CharField(max_length=300, blank=True) first_name = models.CharField(_('First Name'), max_length=100, blank=True) last_name = models.CharField(_('Last Name'), max_length=100, blank=True) phone = models.CharField(max_length=50, blank=True) fax = models.CharField(max_length=50, blank=True) email = models.CharField(max_length=120, blank=True) website = models.CharField(max_length=300, blank=True) release_dt = models.DateTimeField(_('Release Date/Time'), null=True, blank=True) syndicate = models.BooleanField(_('Include in RSS feed'), default=True) design_notes = models.TextField(_('Design Notes'), blank=True) group = models.ForeignKey(Group, null=True, default=None, on_delete=models.SET_NULL) tags = TagField(blank=True) #for podcast feeds enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True) # for podcast feeds enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True) # for podcast feeds enclosure_length = models.IntegerField(_('Enclosure Length'), default=0) # for podcast feeds use_auto_timestamp = models.BooleanField(_('Auto Timestamp')) # html-meta tags meta = models.OneToOneField(MetaTags, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = NewsManager() class Meta: permissions = (("view_news", "Can view news"), ) verbose_name_plural = "News" def get_meta(self, name): """ This method is standard across all models that are related to the Meta model. Used to generate dynamic meta information niche to this model. """ return NewsMeta().get_meta(self, name) @models.permalink def get_absolute_url(self): return ("news.detail", [self.slug]) def __unicode__(self): return self.headline def save(self, *args, **kwargs): if not self.id: self.guid = str(uuid.uuid1()) super(News, self).save(*args, **kwargs) @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items
class Directory(TendenciBaseModel): guid = models.CharField(max_length=40) slug = SlugField(_('URL Path'), unique=True) timezone = TimeZoneField(_('Time Zone')) headline = models.CharField(max_length=200, blank=True) summary = models.TextField(blank=True) body = tinymce_models.HTMLField() source = models.CharField(max_length=300, blank=True) logo = models.FileField(max_length=260, upload_to=file_directory, help_text=_('Company logo. Only jpg, gif, or png images.'), blank=True) first_name = models.CharField(_('First Name'), max_length=100, blank=True) last_name = models.CharField(_('Last Name'), max_length=100, blank=True) address = models.CharField(_('Address'), max_length=100, blank=True) address2 = models.CharField(_('Address 2'), max_length=100, blank=True) city = models.CharField(_('City'), max_length=50, blank=True) state = models.CharField(_('State'), max_length=50, blank=True) zip_code = models.CharField(_('Zip Code'), max_length=50, blank=True) country = models.CharField(_('Country'), max_length=50, blank=True) phone = models.CharField(max_length=50, blank=True) phone2 = models.CharField(_('Phone 2'), max_length=50, blank=True) fax = models.CharField(_('Fax'), max_length=50, blank=True) email = models.CharField(_('Email'), max_length=120, blank=True) email2 = models.CharField(_('Email 2'), max_length=120, blank=True) website = models.CharField(max_length=300, blank=True) renewal_notice_sent = models.BooleanField(default=False) list_type = models.CharField(_('List Type'), max_length=50, blank=True) requested_duration = models.IntegerField(_('Requested Duration'), default=0) pricing = models.ForeignKey('DirectoryPricing', null=True) activation_dt = models.DateTimeField(_('Activation Date/Time'), null=True, blank=True) expiration_dt = models.DateTimeField(_('Expiration Date/Time'), null=True, blank=True) invoice = models.ForeignKey(Invoice, blank=True, null=True) payment_method = models.CharField(_('Payment Method'), max_length=50, blank=True) syndicate = models.BooleanField(_('Include in RSS feed'), default=True) design_notes = models.TextField(_('Design Notes'), blank=True) admin_notes = models.TextField(_('Admin Notes'), blank=True) tags = TagField(blank=True) # for podcast feeds enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True) enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True) enclosure_length = models.IntegerField(_('Enclosure Length'), default=0) # html-meta tags meta = models.OneToOneField(MetaTags, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = DirectoryManager() class Meta: permissions = (("view_directory","Can view directory"),) verbose_name = "Directory" verbose_name_plural = "Directories" def get_meta(self, name): """ This method is standard across all models that are related to the Meta model. Used to generate dynamic methods coupled to this instance. """ return DirectoryMeta().get_meta(self, name) @models.permalink def get_absolute_url(self): return ("directory", [self.slug]) @models.permalink def get_renew_url(self): return ("directory.renew", [self.id]) def __unicode__(self): return self.headline def save(self, *args, **kwargs): if not self.id: self.guid = str(uuid.uuid1()) super(Directory, self).save(*args, **kwargs) if self.logo: if self.is_public(): set_s3_file_permission(self.logo.name, public=True) else: set_s3_file_permission(self.logo.name, public=False) def is_public(self): return all([self.allow_anonymous_view, self.status, self.status_detail in ['active']]) def get_logo_url(self): if not self.logo: return '' if self.is_public(): return self.logo.url return reverse('directory.logo', args=[self.id]) # Called by payments_pop_by_invoice_user in Payment model. def get_payment_description(self, inv): """ The description will be sent to payment gateway and displayed on invoice. If not supplied, the default description will be generated. """ return 'Tendenci Invoice %d for Directory: %s (%d).' % ( inv.id, self.headline, inv.object_id, ) def make_acct_entries(self, user, inv, amount, **kwargs): """ Make the accounting entries for the directory sale """ from tendenci.apps.accountings.models import Acct, AcctEntry, AcctTran from tendenci.apps.accountings.utils import make_acct_entries_initial, make_acct_entries_closing ae = AcctEntry.objects.create_acct_entry(user, 'invoice', inv.id) if not inv.is_tendered: make_acct_entries_initial(user, ae, amount) else: # payment has now been received make_acct_entries_closing(user, ae, amount) # #CREDIT directory SALES acct_number = self.get_acct_number() acct = Acct.objects.get(account_number=acct_number) AcctTran.objects.create_acct_tran(user, ae, acct, amount*(-1)) def get_acct_number(self, discount=False): if discount: return 464400 else: return 404400 def auto_update_paid_object(self, request, payment): """ Update the object after online payment is received. """ if not request.user.profile.is_superuser: self.status_detail = 'paid - pending approval' self.save() def age(self): return datetime.now() - self.create_dt @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items def renew_window(self): days = get_setting('module', 'directories', 'renewaldays') days = int(days) if datetime.now() + timedelta(days) > self.expiration_dt: return True else: return False
class BaseJob(TendenciBaseModel): guid = models.CharField(max_length=40) title = models.CharField(max_length=250) slug = SlugField(_('URL Path'), unique=True) description = tinymce_models.HTMLField() list_type = models.CharField(max_length=50) # premium or regular code = models.CharField(max_length=50, blank=True) # internal job-code location = models.CharField( max_length=500, null=True, blank=True ) # cannot be foreign, needs to be open 'Texas' 'All 50 States' 'US and International' skills = models.TextField(blank=True) experience = models.TextField(blank=True) education = models.TextField(blank=True) level = models.CharField( max_length=50, blank=True) # e.g. entry, part-time, permanent, contract period = models.CharField(max_length=50, blank=True) # full time, part time, contract is_agency = models.BooleanField( ) # defines if the job posting is by a third party agency contact_method = models.TextField( blank=True ) # preferred method - email, phone, fax. leave open field for user to define position_reports_to = models.CharField(max_length=200, blank=True) # manager, CEO, VP, etc salary_from = models.CharField(max_length=50, blank=True) salary_to = models.CharField(max_length=50, blank=True) computer_skills = models.TextField(blank=True) # date related fields requested_duration = models.IntegerField( ) # 30, 60, 90 days - should be relational table pricing = models.ForeignKey( 'JobPricing', null=True) # selected pricing based on requested_duration activation_dt = models.DateTimeField( null=True, blank=True) # date job listing was activated post_dt = models.DateTimeField( null=True, blank=True) # date job was posted (same as create date?) expiration_dt = models.DateTimeField( null=True, blank=True) # date job expires based on activation date and duration start_dt = models.DateTimeField( null=True, blank=True) # date job starts(defined by job poster) job_url = models.CharField( max_length=300, blank=True) # link to other (fuller) job posting syndicate = models.BooleanField(_('Include in RSS feed'), blank=True, default=True) design_notes = models.TextField(blank=True) #TODO: foreign contact_company = models.CharField(max_length=300, blank=True) contact_name = models.CharField(max_length=150, blank=True) contact_address = models.CharField(max_length=50, blank=True) contact_address2 = models.CharField(max_length=50, blank=True) contact_city = models.CharField(max_length=50, blank=True) contact_state = models.CharField(max_length=50, blank=True) contact_zip_code = models.CharField(max_length=50, blank=True) contact_country = models.CharField(max_length=50, blank=True) contact_phone = models.CharField(max_length=50, blank=True) contact_fax = models.CharField(max_length=50, blank=True) contact_email = models.CharField(max_length=300, blank=True) contact_website = models.CharField(max_length=300, blank=True) meta = models.OneToOneField(MetaTags, null=True) group = models.ForeignKey(Group, null=True, default=get_default_group, on_delete=models.SET_NULL) tags = TagField(blank=True) invoice = models.ForeignKey(Invoice, blank=True, null=True) payment_method = models.CharField(max_length=50, blank=True, default='') member_price = models.DecimalField(max_digits=20, decimal_places=2, blank=True, null=True) member_count = models.IntegerField(blank=True, null=True) non_member_price = models.DecimalField(max_digits=20, decimal_places=2, blank=True, null=True) non_member_count = models.IntegerField(blank=True, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = JobManager() class Meta: abstract = True def save(self, *args, **kwargs): if not self.id: self.guid = str(uuid.uuid1()) super(BaseJob, self).save(*args, **kwargs) def __unicode__(self): return self.title # Called by payments_pop_by_invoice_user in Payment model. def get_payment_description(self, inv): """ The description will be sent to payment gateway and displayed on invoice. If not supplied, the default description will be generated. """ return 'Tendenci Invoice %d for Job: %s (%d).' % ( inv.id, self.title, inv.object_id, ) def make_acct_entries(self, user, inv, amount, **kwargs): """ Make the accounting entries for the job sale """ from tendenci.apps.accountings.models import Acct, AcctEntry, AcctTran from tendenci.apps.accountings.utils import make_acct_entries_initial, make_acct_entries_closing ae = AcctEntry.objects.create_acct_entry(user, 'invoice', inv.id) if not inv.is_tendered: make_acct_entries_initial(user, ae, amount) else: # payment has now been received make_acct_entries_closing(user, ae, amount) # #CREDIT job SALES acct_number = self.get_acct_number() acct = Acct.objects.get(account_number=acct_number) AcctTran.objects.create_acct_tran(user, ae, acct, amount * (-1)) def get_acct_number(self, discount=False): if discount: return 462500 else: return 402500 def auto_update_paid_object(self, request, payment): """ Update the object after online payment is received. """ if not request.user.profile.is_superuser: self.status_detail = 'paid - pending approval' self.activation_dt = now_localized() self.expiration_dt = self.activation_dt + timedelta( days=self.requested_duration) self.save() @property def opt_app_label(self): return self._meta.app_label @property def opt_module_name(self): return self._meta.module_name @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items
class Group(TendenciBaseModel): name = models.CharField(_('Group Name'), max_length=255, unique=True) slug = SlugField(_('URL Path'), unique=True) guid = models.CharField(max_length=40) label = models.CharField(_('Group Label'), max_length=255, blank=True) type = models.CharField(max_length=75, blank=True, choices=(('distribution', 'Distribution'), ('security', 'Security'), ('system_generated', 'System Generated')), default='distribution') email_recipient = models.CharField(_('Recipient Email'), max_length=255, blank=True) show_as_option = models.BooleanField(_('Display Option'), default=1, blank=True) allow_self_add = models.BooleanField(_('Allow Self Add'), default=1) allow_self_remove = models.BooleanField(_('Allow Self Remove'), default=1) sync_newsletters = models.BooleanField(_('Sync for newsletters'), default=1) description = models.TextField(blank=True) auto_respond = models.BooleanField(_('Auto Responder'), default=0) auto_respond_priority = models.FloatField(_('Priority'), blank=True, default=0) notes = models.TextField(blank=True) members = models.ManyToManyField(User, through='GroupMembership') group = models.OneToOneField(AuthGroup, null=True, default=None) permissions = models.ManyToManyField(Permission, related_name='group_permissions', blank=True) # use_for_membership = models.BooleanField(_('User for Membership Only'), default=0, blank=True) objects = GroupManager() class Meta: permissions = (("view_group", "Can view group"), ) verbose_name = "Group" verbose_name_plural = "Groups" ordering = ("name", ) def __unicode__(self): return self.label or self.name @models.permalink def get_absolute_url(self): return ('group.detail', [self.slug]) def save(self, force_insert=False, force_update=False, *args, **kwargs): if not self.guid: self.guid = uuid.uuid1() if not self.slug: self.slug = slugify(self.name) # add the default entity if not self.entity: self.entity = Entity.objects.first() super(Group, self).save(force_insert, force_update, *args, **kwargs) if not self.group: # create auth group if not exists # note that the name of auth group is also unique group_name = self.get_unique_auth_group_name() self.group = AuthGroup.objects.create(name=group_name) self.save() @property def active_members(self): return GroupMembership.objects.filter(group=self, status=True, status_detail='active') def get_unique_auth_group_name(self): # get the unique name for auth group. # the max length of the name of the auth group is 80. name = self.name if not name: name = str(self.id) if len(name) > 80: name = name[:80] if AuthGroup.objects.filter(name=name).exists(): name = 'User Group %d' % self.id return name def is_member(self, user): # impersonation user = getattr(user, 'impersonated_user', user) if isinstance(user, User): return self.members.filter(id=user.id).exists() return False def add_user(self, user, **kwargs): """ add a user to the group; check for duplicates return (user, created) """ if isinstance(user, User): # first check if user exists if not self.is_member(user): params = { 'group': self, 'member': user, 'creator_id': kwargs.get('creator_id') or user.pk, 'creator_username': kwargs.get('creator_username') or user.username, 'owner_id': kwargs.get('owner_id') or user.pk, 'owner_username': kwargs.get('owner_username') or user.username, 'status': kwargs.get('status') or True, 'status_detail': kwargs.get('status_detail') or 'active' } try: GroupMembership.objects.create(**params) except IntegrityError: return user, False return user, True # created return user, False
class Group(TendenciBaseModel): name = models.CharField(_('Group Name'), max_length=255, unique=True) slug = SlugField(_('URL Path'), unique=True) guid = models.CharField(max_length=40) label = models.CharField(_('Group Label'), max_length=255, blank=True) type = models.CharField(max_length=75, blank=True, choices=( ('distribution', 'Distribution'), ('security', 'Security'), ), default='distribution') email_recipient = models.CharField(_('Recipient Email'), max_length=255, blank=True) show_as_option = models.BooleanField(_('Display Option'), default=1, blank=True) allow_self_add = models.BooleanField(_('Allow Self Add'), default=1) allow_self_remove = models.BooleanField(_('Allow Self Remove'), default=1) description = models.TextField(blank=True) auto_respond = models.BooleanField(_('Auto Responder'), default=0) auto_respond_template = models.CharField( _('Auto Responder Template'), help_text=_("Auto Responder Template URL"), max_length=100, blank=True) auto_respond_priority = models.FloatField(_('Priority'), blank=True, default=0) notes = models.TextField(blank=True) members = models.ManyToManyField(User, through='GroupMembership') group = models.OneToOneField(AuthGroup, null=True, default=None, on_delete=models.SET_NULL) permissions = models.ManyToManyField(Permission, related_name='group_permissions', blank=True) # use_for_membership = models.BooleanField(_('User for Membership Only'), default=0, blank=True) objects = GroupManager() class Meta: permissions = (("view_group", "Can view group"), ) verbose_name = "Group" verbose_name_plural = "Groups" def __unicode__(self): return self.label or self.name @models.permalink def get_absolute_url(self): return ('group.detail', [self.slug]) def save(self, force_insert=False, force_update=False): if not self.id: name = self.name self.guid = uuid.uuid1() if not self.slug: self.slug = slugify(name) super(Group, self).save(force_insert, force_update) @property def active_members(self): return GroupMembership.objects.filter(group=self, status=True, status_detail='active') def is_member(self, user): # impersonation user = getattr(user, 'impersonated_user', user) return user in self.members.all() def add_user(self, user, **kwargs): """ add a user to the group; check for duplicates return (user, created) """ from django.db import IntegrityError try: GroupMembership.objects.create( **{ 'group': self, 'member': user, 'creator_id': kwargs.get('creator_id') or user.pk, 'creator_username': kwargs.get('creator_username') or user.username, 'owner_id': kwargs.get('owner_id') or user.pk, 'owner_username': kwargs.get('owner_username') or user.username, 'status': kwargs.get('status') or True, 'status_detail': kwargs.get('status_detail') or 'active', }) return user, True # created except IntegrityError: return user, False
class Article(TendenciBaseModel): CONTRIBUTOR_AUTHOR = 1 CONTRIBUTOR_PUBLISHER = 2 CONTRIBUTOR_CHOICES = ((CONTRIBUTOR_AUTHOR, 'Author'), (CONTRIBUTOR_PUBLISHER, 'Publisher')) guid = models.CharField(max_length=40) slug = SlugField(_('URL Path'), unique=True) timezone = TimeZoneField(_('Time Zone')) headline = models.CharField(max_length=200, blank=True) summary = models.TextField(blank=True) body = tinymce_models.HTMLField() source = models.CharField(max_length=300, blank=True) first_name = models.CharField(_('First Name'), max_length=100, blank=True) last_name = models.CharField(_('Last Name'), max_length=100, blank=True) contributor_type = models.IntegerField(choices=CONTRIBUTOR_CHOICES, default=CONTRIBUTOR_AUTHOR) google_profile = models.URLField(_('Google+ URL'), blank=True) phone = models.CharField(max_length=50, blank=True) fax = models.CharField(max_length=50, blank=True) email = models.CharField(max_length=120, blank=True) website = models.CharField(max_length=300, blank=True) release_dt = models.DateTimeField(_('Release Date/Time'), null=True, blank=True) # used for better performance when retrieving a list of released articles release_dt_local = models.DateTimeField(null=True, blank=True) syndicate = models.BooleanField(_('Include in RSS feed'), default=True) featured = models.BooleanField() design_notes = models.TextField(_('Design Notes'), blank=True) group = models.ForeignKey(Group, null=True, default=get_default_group, on_delete=models.SET_NULL) tags = TagField(blank=True) # for podcast feeds enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True) enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True) enclosure_length = models.IntegerField(_('Enclosure Length'), default=0) not_official_content = models.BooleanField(_('Official Content'), blank=True) # html-meta tags meta = models.OneToOneField(MetaTags, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = ArticleManager() class Meta: permissions = (("view_article", "Can view article"), ) verbose_name = "Article" verbose_name_plural = "Articles" def get_meta(self, name): """ This method is standard across all models that are related to the Meta model. Used to generate dynamic methods coupled to this instance. """ return ArticleMeta().get_meta(self, name) @models.permalink def get_absolute_url(self): return ("article", [self.slug]) @models.permalink def get_version_url(self, hash): return ("article.version", [hash]) def __unicode__(self): return self.headline def save(self, *args, **kwargs): if not self.id: self.guid = str(uuid.uuid1()) self.assign_release_dt_local() super(Article, self).save(*args, **kwargs) def assign_release_dt_local(self): """ convert release_dt to the corresponding local time example: if release_dt: 2014-05-09 03:30:00 timezone: US/Pacific settings.TIME_ZONE: US/Central then the corresponding release_dt_local will be: 2014-05-09 05:30:00 """ now = datetime.now() now_with_tz = adjust_datetime_to_timezone(now, settings.TIME_ZONE) if self.timezone and self.release_dt and self.timezone.zone != settings.TIME_ZONE: time_diff = adjust_datetime_to_timezone( now, self.timezone) - now_with_tz self.release_dt_local = self.release_dt + time_diff else: self.release_dt_local = self.release_dt def age(self): return datetime.now() - self.create_dt @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items @property def has_google_author(self): return self.contributor_type == self.CONTRIBUTOR_AUTHOR @property def has_google_publisher(self): return self.contributor_type == self.CONTRIBUTOR_PUBLISHER
class Location(TendenciBaseModel): guid = models.CharField(max_length=40) location_name = models.CharField(_('Name'), max_length=200, blank=True) slug = SlugField(_('URL Path'), unique=True) description = models.TextField(blank=True) # contact/location information contact = models.CharField(max_length=100, blank=True) address = models.CharField(max_length=100, blank=True) address2 = models.CharField(max_length=100, blank=True) city = models.CharField(max_length=100, blank=True) state = models.CharField(max_length=50, blank=True) zipcode = models.CharField(_('Zip Code'), max_length=50, blank=True) country = models.CharField(max_length=100, blank=True) phone = models.CharField(max_length=50, blank=True) fax = models.CharField(max_length=50, blank=True) email = models.CharField(max_length=120, blank=True) website = models.CharField(max_length=300, blank=True) latitude = models.FloatField(blank=True, null=True) longitude = models.FloatField(blank=True, null=True) logo = models.ForeignKey(File, null=True, default=None, help_text=_('Only jpg, gif, or png images.')) hq = models.BooleanField(_('Headquarters')) perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = LocationManager() class Meta: permissions = (("view_location", _("Can view location")), ) def __unicode__(self): return self.location_name @models.permalink def get_absolute_url(self): return ("location", [self.slug]) def get_address(self): return "%s %s %s, %s %s" % (self.address, self.address2, self.city, self.state, self.zipcode) def distance_api(self, **kwargs): import simplejson, urllib DISTANCE_BASE_URL = 'http://maps.googleapis.com/maps/api/distancematrix/json?' kwargs.update({ 'origins': kwargs.get('origin', ''), 'destinations': self.get_address(), 'sensor': 'false', }) url = '%s?%s' % (DISTANCE_BASE_URL, urllib.urlencode(kwargs)) return simplejson.load(urllib.urlopen(url)) def get_distance(self, **kwargs): """ Pings the Google Map API (DistanceMatrix). Returns the distance in miles. """ origin = kwargs.get('origin') result = distance_api(**{'origin': origin}) if result['status'] == 'OK': # return result['rows'][0]['elements'][0]['duration']['value'] return result['rows'][0]['elements'][0]['distance']['value'] return None def get_distance2(self, lat, lng): """ http://www.johndcook.com/python_longitude_latitude.html Distance in miles multiply by 3960 Distance in kilometers multiply by 6373 """ import math from time import clock, time # if we don't have latitude or longitude # we return a none type object instead of int if not all((self.latitude, self.longitude)): return None # Convert latitude and longitude to # spherical coordinates in radians. degrees_to_radians = math.pi / 180.0 # phi = 90 - latitude phi1 = (90.0 - self.latitude) * degrees_to_radians phi2 = (90.0 - lat) * degrees_to_radians # theta = longitude theta1 = self.longitude * degrees_to_radians theta2 = lng * degrees_to_radians cos = (math.sin(phi1) * math.sin(phi2) * math.cos(theta1 - theta2) + math.cos(phi1) * math.cos(phi2)) try: arc = math.acos(cos) except: arc = 0 # Remember to multiply arc by the radius of the earth # in your favorite set of units to get length. return arc * 3960 def save(self, *args, **kwargs): self.guid = self.guid or unicode(uuid.uuid1()) # update latitude and longitude if not all((self.latitude, self.longitude)): self.latitude, self.longitude = get_coordinates(self.get_address()) photo_upload = kwargs.pop('photo', None) super(Location, self).save(*args, **kwargs) if photo_upload and self.pk: image = File(content_type=ContentType.objects.get_for_model( self.__class__), object_id=self.pk, creator=self.creator, creator_username=self.creator_username, owner=self.owner, owner_username=self.owner_username) photo_upload.file.seek(0) image.file.save(photo_upload.name, photo_upload) image.save() self.logo = image self.save()
class News(TendenciBaseModel): CONTRIBUTOR_AUTHOR = 1 CONTRIBUTOR_PUBLISHER = 2 CONTRIBUTOR_CHOICES = ((CONTRIBUTOR_AUTHOR, 'Author'), (CONTRIBUTOR_PUBLISHER, 'Publisher')) guid = models.CharField(max_length=40) slug = SlugField(_('URL Path'), unique=True) timezone = TimeZoneField(_('Time Zone')) headline = models.CharField(max_length=200, blank=True) summary = models.TextField(blank=True) body = tinymce_models.HTMLField() source = models.CharField(max_length=300, blank=True) first_name = models.CharField(_('First Name'), max_length=100, blank=True) last_name = models.CharField(_('Last Name'), max_length=100, blank=True) contributor_type = models.IntegerField(choices=CONTRIBUTOR_CHOICES, default=CONTRIBUTOR_AUTHOR) google_profile = models.URLField(_('Google+ URL'), blank=True) phone = models.CharField(max_length=50, blank=True) fax = models.CharField(max_length=50, blank=True) email = models.CharField(max_length=120, blank=True) website = models.CharField(max_length=300, blank=True) thumbnail = models.ForeignKey( 'NewsImage', default=None, null=True, help_text= _('The thumbnail image can be used on your homepage or sidebar if it is setup in your theme. The thumbnail image will not display on the news page.' )) release_dt = models.DateTimeField(_('Release Date/Time'), null=True, blank=True) # used for better performance when retrieving a list of released news release_dt_local = models.DateTimeField(null=True, blank=True) syndicate = models.BooleanField(_('Include in RSS feed'), default=True) design_notes = models.TextField(_('Design Notes'), blank=True) group = models.ForeignKey(Group, null=True, default=get_default_group, on_delete=models.SET_NULL) tags = TagField(blank=True) #for podcast feeds enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True) # for podcast feeds enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True) # for podcast feeds enclosure_length = models.IntegerField(_('Enclosure Length'), default=0) # for podcast feeds use_auto_timestamp = models.BooleanField(_('Auto Timestamp')) # html-meta tags meta = models.OneToOneField(MetaTags, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = NewsManager() class Meta: permissions = (("view_news", "Can view news"), ) verbose_name_plural = "News" def get_meta(self, name): """ This method is standard across all models that are related to the Meta model. Used to generate dynamic meta information niche to this model. """ return NewsMeta().get_meta(self, name) @models.permalink def get_absolute_url(self): return ("news.detail", [self.slug]) def __unicode__(self): return self.headline def save(self, *args, **kwargs): if not self.id: self.guid = str(uuid.uuid1()) self.assign_release_dt_local() photo_upload = kwargs.pop('photo', None) super(News, self).save(*args, **kwargs) if photo_upload and self.pk: image = NewsImage(object_id=self.pk, creator=self.creator, creator_username=self.creator_username, owner=self.owner, owner_username=self.owner_username) photo_upload.file.seek(0) image.file.save(photo_upload.name, photo_upload) # save file row image.save() # save image row if self.thumbnail: self.thumbnail.delete() # delete image and file row self.thumbnail = image # set image self.save() if self.thumbnail: if self.is_public(): set_s3_file_permission(self.thumbnail.file, public=True) else: set_s3_file_permission(self.thumbnail.file, public=False) @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items def is_public(self): return all([ self.allow_anonymous_view, self.status, self.status_detail in ['active'] ]) @property def is_released(self): return self.release_dt_local <= datetime.now() @property def has_google_author(self): return self.contributor_type == self.CONTRIBUTOR_AUTHOR @property def has_google_publisher(self): return self.contributor_type == self.CONTRIBUTOR_PUBLISHER def assign_release_dt_local(self): """ convert release_dt to the corresponding local time example: if release_dt: 2014-05-09 03:30:00 timezone: US/Pacific settings.TIME_ZONE: US/Central then the corresponding release_dt_local will be: 2014-05-09 05:30:00 """ now = datetime.now() now_with_tz = adjust_datetime_to_timezone(now, settings.TIME_ZONE) if self.timezone and self.release_dt and self.timezone.zone != settings.TIME_ZONE: time_diff = adjust_datetime_to_timezone( now, self.timezone) - now_with_tz self.release_dt_local = self.release_dt + time_diff else: self.release_dt_local = self.release_dt
class News(TendenciBaseModel): guid = models.CharField(max_length=40) slug = SlugField(_('URL Path'), unique=True) timezone = TimeZoneField(_('Time Zone')) headline = models.CharField(max_length=200, blank=True) summary = models.TextField(blank=True) body = tinymce_models.HTMLField() source = models.CharField(max_length=300, blank=True) first_name = models.CharField(_('First Name'), max_length=100, blank=True) last_name = models.CharField(_('Last Name'), max_length=100, blank=True) phone = models.CharField(max_length=50, blank=True) fax = models.CharField(max_length=50, blank=True) email = models.CharField(max_length=120, blank=True) website = models.CharField(max_length=300, blank=True) thumbnail = models.ForeignKey( 'NewsImage', default=None, null=True, help_text= _('The thumbnail image can be used on your homepage or sidebar if it is setup in your theme. The thumbnail image will not display on the news page.' )) release_dt = models.DateTimeField(_('Release Date/Time'), null=True, blank=True) syndicate = models.BooleanField(_('Include in RSS feed'), default=True) design_notes = models.TextField(_('Design Notes'), blank=True) group = models.ForeignKey(Group, null=True, default=get_default_group, on_delete=models.SET_NULL) tags = TagField(blank=True) #for podcast feeds enclosure_url = models.CharField(_('Enclosure URL'), max_length=500, blank=True) # for podcast feeds enclosure_type = models.CharField(_('Enclosure Type'), max_length=120, blank=True) # for podcast feeds enclosure_length = models.IntegerField(_('Enclosure Length'), default=0) # for podcast feeds use_auto_timestamp = models.BooleanField(_('Auto Timestamp')) # html-meta tags meta = models.OneToOneField(MetaTags, null=True) categories = generic.GenericRelation(CategoryItem, object_id_field="object_id", content_type_field="content_type") perms = generic.GenericRelation(ObjectPermission, object_id_field="object_id", content_type_field="content_type") objects = NewsManager() class Meta: permissions = (("view_news", "Can view news"), ) verbose_name_plural = "News" def get_meta(self, name): """ This method is standard across all models that are related to the Meta model. Used to generate dynamic meta information niche to this model. """ return NewsMeta().get_meta(self, name) @models.permalink def get_absolute_url(self): return ("news.detail", [self.slug]) def __unicode__(self): return self.headline def save(self, *args, **kwargs): if not self.id: self.guid = str(uuid.uuid1()) photo_upload = kwargs.pop('photo', None) super(News, self).save(*args, **kwargs) if photo_upload and self.pk: image = NewsImage(object_id=self.pk, creator=self.creator, creator_username=self.creator_username, owner=self.owner, owner_username=self.owner_username) photo_upload.file.seek(0) image.file.save(photo_upload.name, photo_upload) # save file row image.save() # save image row if self.thumbnail: self.thumbnail.delete() # delete image and file row self.thumbnail = image # set image self.save() if self.thumbnail: if self.is_public(): set_s3_file_permission(self.thumbnail.file, public=True) else: set_s3_file_permission(self.thumbnail.file, public=False) @property def category_set(self): items = {} for cat in self.categories.select_related('category__name', 'parent__name'): if cat.category: items["category"] = cat.category elif cat.parent: items["sub_category"] = cat.parent return items def is_public(self): return all([ self.allow_anonymous_view, self.status, self.status_detail in ['active'] ])