class Post(RandomSlugModel, TimeStampedModel): UNIT_CHOICES = ( ('pound', 'POUND'), ('gallon', 'GALLON'), ('each', 'EACH'), ) # todo: custom queryset to get active posts objects = PostManager() owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE) # todo: Remove activatormodel? title = models.CharField(max_length=300) body = models.TextField(max_length=5000) # TODO: Use autocomplete_initial=True and specify preset tags? tags = TagField(max_count=10, force_lowercase=True, space_delimiter=False, blank=True) price = models.DecimalField(max_digits=7, decimal_places=2) unit = models.CharField(max_length=80, choices=UNIT_CHOICES, default='each') # location = models.CharField(max_length=5) def get_absolute_url(self): return reverse('board:detail', kwargs={'slug': self.slug}) def __str__(self): return self.title + " - $" + str(self.price)
class Blog(ThingWithTopics): body = MarkdownxField(blank=True) type = TagField(blank=False, to=Types, help_text="eg: blog-post, podcast") #topics = TagField(blank=True, to=TopicTags) def get_authors(self): names = [a.name for a in self.authors.all()] return ", ".join(names) def get_preview(self): ret = "" truncated = False for bit in self.body.replace('\r', '').split('\n\n'): if len(ret)>400: truncated = True break ret += '\n\n' + bit if truncated: ret += '\n\n[Read more...](%s)'%self.get_absolute_url() return ret def get_absolute_url(self): return '/blog/%s/%d/%s/'%(self.published_at.strftime("%Y/%m"), self.pk, slugify(self.title))
class Blog(models.Model): BLOG = 'BL' GALLERY = 'GL' FOLDER_CHOICES = ((BLOG, 'Blog'), (GALLERY, 'Gallery')) welcome_image = models.ImageField(upload_to='blog_welcome', blank=True) author = models.ForeignKey(Profile) folder = models.CharField(max_length=2, choices=FOLDER_CHOICES, default=BLOG, blank=False) series = models.ForeignKey(Series, blank=True, null=True) title = models.CharField(max_length=150) description = models.TextField(blank=True) tags = TagField(force_lowercase=True, max_count=8) content = models.TextField(blank=True) hidden_message = models.CharField(max_length=100, blank=True, null=True) publishable = models.BooleanField(default=False) slug = models.SlugField(unique=True, max_length=255, blank=True) create_date = models.DateTimeField(default=datetime.now, blank=True) pub_date = models.DateTimeField(blank=True, null=True) pos_responses = models.PositiveIntegerField(default=0) neg_responses = models.PositiveIntegerField(default=0) def __str__(self): return self.title def save(self, *args, **kwargs): if (not self.slug): self.slug = unique_slug_generator(self, 'title') if (self.publishable): self.pub_date = datetime.now() super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
class Post(models.Model): title = models.CharField(max_length=120, blank=False) slug = models.SlugField() public = models.BooleanField( default=True, help_text="If unchecked, only logged-in users can see this page") author = models.CharField(max_length=50, blank=False) date = models.DateField() image = FileBrowseField(max_length=200, directory="images/posts", format='Image', blank=True, null=True) content = HTMLField(max_length=65535, blank=False, null=True) excerpt = models.TextField(max_length=350, blank=False) categories = models.ManyToManyField('PostCategory', related_name='posts', blank=True) tags = TagField() class Meta: ordering = [ 'date', ] def __str__(self): return "{}, by {}".format(self.title, self.author) def get_absolute_url(self): return reverse('post', kwargs={'post_slug': self.slug})
class UserTool(StateMachineMixin, TitleDescriptionModel, TimeStampedModel): """A tool owned by a User""" user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name="tools") description = models.TextField(blank=True) state = models.CharField( max_length=10, choices=ToolStates._zip("value", "label"), default=ToolStates.none.value, editable=False, ) taxonomies = TagField(to=ToolTaxonomy, blank=True, related_name="tools") visibility = models.PositiveSmallIntegerField( _("Visibility"), choices=ToolVisibility._zip("value", "label"), default=ToolVisibility.public.value, help_text=_("The level of user visibility for this tool"), ) clearance = models.PositiveSmallIntegerField( _("Clearance"), choices=ToolClearance._zip("value", "label"), default=ToolClearance.none.value, help_text=_("Who is allowed to use this tool"), ) objects = UserToolQuerySet.as_manager() class StateMachine: auto_transitions = False send_event = True states = [{"name": state.value} for state in ToolStates] transitions = [{ "trigger": trigger, "source": source, "dest": dest } for trigger, source, dest in ToolTransitions._zip( "name", "source", "dest")] after_state_change = "record_transition" def __str__(self): return self.title def get_absolute_url(self): return reverse("tools:detail", kwargs={"pk": self.pk}) def record_transition(self, event): if not event.kwargs.get("skip_save", False): self.save() self.history.create( user=event.kwargs.get("user"), action=ToolTransitions(event.event.name, "name").value, ) class Meta: ordering = ("-created", ) get_latest_by = "created" verbose_name = _("Tool") verbose_name_plural = _("Tools")
class MovePrivateData(Entity): move = models.ForeignKey(Move, on_delete=models.CASCADE) notes = models.TextField() tags = TagField( force_lowercase=True, max_count=10, space_delimiter=False, blank=True ) def __str__(self): # noqa return "Notes by %s on %s" % (self.owner, self.move)
class ThingWithTopics(BaseThing): related = models.ManyToManyField('self', blank=True) topics = TagField(blank=True, to=TopicTags, related_name="things") def get_attachments(self): ret = [] for rel in self.related.all(): if rel.dataset: ret.append(rel) return ret
class TestModel(models.Model): name = models.CharField(max_length=200) test = TagField() for_inline = models.ForeignKey('self', null=True, blank=True, related_name='inline_test_models') def __str__(self): return self.name
class Page(MPTTModel): parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') slug = models.SlugField(max_length=100, blank=True) url = models.CharField(max_length=100, blank=True, editable=False) redirect_to = models.CharField(max_length=250, blank=True) menu_title = models.CharField(max_length=150, blank=True) show_in_home_menu = models.BooleanField(default=False) show_in_primary_menu = models.BooleanField(default=False) show_in_secondary_menu = models.BooleanField(default=False) show_in_footer_menu = models.BooleanField(default=False) meta_title = models.CharField(max_length=150, blank=True) image = models.ImageField(blank=True, null=True) overlay_text = models.CharField(max_length=150, blank=True) overlay_url = models.URLField(max_length=200, blank=True) introduction = MarkdownxField(blank=True) page_type = models.CharField(max_length=150, blank=True, choices=[['', 'Static page'], ['papers', 'Papers'], ['blog', 'Blog'], ['topic', 'Topic']]) body = MarkdownxField(blank=True, null=True) colour_scheme = models.CharField(max_length=150, blank=True, choices=[['', ''], ['green', 'Green'], ['orange', 'Orange'], ['blue', 'Blue'], ['red', 'Red']]) topics = TagField(blank=True, to=TopicTags, related_name="pages") types = TagField(blank=True, to=Types) def save(self, *args, **kwargs): if self.parent is None: self.url = '' else: self.url = self.parent.url + '/' + self.slug return super(Page, self).save(*args, **kwargs) def __str__(self): if not self.parent: return self.menu_title or "Home" return "[%s] %s"%(self.url, self.menu_title)
class FeedSource(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) feed = models.ForeignKey(Feed, on_delete=models.CASCADE) #FIXME: Deletion title = models.CharField(max_length=200) show_on_frontpage = models.BooleanField(default=True) tags = TagField() def __str__(self): return self.title class Meta: ordering = ["title"] unique_together = (("user", "feed"))
class Move(Entity): name = models.CharField(max_length=200, unique=False) slug = models.CharField(max_length=200, unique=False) link = models.URLField(blank=True, null=True) start_time_ms = models.IntegerField(blank=True, null=True) end_time_ms = models.IntegerField(blank=True, null=True) description = models.TextField() source_move_list = models.ForeignKey("movelists.MoveList", on_delete=models.CASCADE, related_name="sourced_moves") tags = TagField(force_lowercase=True, max_count=10, space_delimiter=False) def __str__(self): # noqa return self.name
class Event(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(max_length=200) ranking = models.IntegerField() summary = models.TextField() # TODO: Foreign Key relationship with articles lastedited = models.DateTimeField(auto_now=False, auto_now_add=False) dateadded = models.DateTimeField(auto_now=False, auto_now_add=False) clicktraffic = models.PositiveIntegerField() articles = models.ManyToManyField("scraper.Article", related_name="events") needs_summary = models.BooleanField(default=True) num_tags = models.IntegerField(default=0) tags = TagField() class Meta(): app_label = 'summarize'
class Author(models.Model): name = models.CharField(max_length=50, blank=True) slug = models.CharField(max_length=50, blank=True, editable=False) institution = models.CharField(max_length=150, blank=True) image = models.ImageField(blank=True, null=True) url = models.URLField(max_length=200, blank=True) topics = TagField(blank=True, to=TopicTags) def get_absolute_url(self): return '/authors/%s/'%self.slug def save(self, *args, **kwargs): self.slug = slugify(self.name) return super(Author, self).save(*args, **kwargs) def __str__(self): return self.name
class MoveList(Entity): description = models.TextField() is_private = models.BooleanField(default=False) moves = models.ManyToManyField(Move, through=MoveList2Move) name = models.CharField(max_length=200) role = models.CharField( max_length=200, blank=True, choices=[("", "default"), ("drafts", "drafts"), ("trash", "trash")], default="", ) slug = models.CharField(max_length=200) tags = TagField( force_lowercase=True, max_count=10, space_delimiter=False, blank=True ) def __str__(self): # noqa return self.name
class Series(models.Model): title = models.CharField(max_length=150) genre = TagField(force_lowercase=True, max_count=6) description = models.TextField(blank=True, null=True) creator = models.ForeignKey(Profile, blank=True, null=True) #tags = TagField(force_lowercase = True, max_count = 10) create_date = models.DateTimeField(default=datetime.now, blank=True) slug = models.SlugField(unique=True, max_length=100, blank=True) image = models.ImageField(upload_to='series_images', blank=True, null=True) def __str__(self): return self.title def save(self, *args, **kwargs): if (not self.slug): self.slug = unique_slug_generator(self, 'title') super(Series, self).save(*args, **kwargs) # Call the "real" save() method.
class Document(models.Model): file = models.FileField(u"Fichier", max_length=200, upload_to='docs/%Y/%m/%d/') title = models.CharField(u"Titre", max_length=200) tags = TagField( DocumentTags, verbose_name=u"Mots-clés", blank=True, help_text="Entrez une liste de mots-clés séparés par des virgules") visible = models.BooleanField(u"Visible", default=True) def __str__(self): return self.title def text(self): parsed = parser.from_file(self.file.path) return parsed['content']
class Song(TimeStampedModel): title = models.CharField(max_length=255, blank=True) title_eng = models.CharField(max_length=255, blank=True) text = RichTextField(blank=True) text_eng = RichTextField(blank=True) chords = RichTextField(blank=True) presentation = models.FileField(upload_to=pres_path, blank=True) text_file = models.FileField(upload_to=text_path, blank=True) category = models.ManyToManyField(Category, blank=True) author = models.CharField(max_length=100, blank=True, default='') is_translated = models.BooleanField(blank=True, default=True) translator = TagField( max_count=6, initial=['Фурманов', 'Зуев', 'Иваник', 'Куга', 'Жданов', 'Герасимович'], blank=True, ) main_key = models.CharField(max_length=2, choices=CHORDS, default="E", blank=True) difficult = models.CharField(max_length=6, choices=DIFFICULT, default="easy", blank=True) chordsFile1 = models.FileField(upload_to=chords_path, blank=True) chordKey1 = models.CharField(max_length=2, choices=CHORDS, default="E", blank=True) chordsFile2 = models.FileField(upload_to=chords_path, blank=True) chordKey2 = models.CharField(max_length=2, choices=CHORDS, default="E", blank=True) ytb_id1 = models.CharField(max_length=100, blank=True) ytb_id2 = models.CharField(max_length=100, blank=True) ytb_id3 = models.CharField(max_length=100, blank=True) user = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING) class Meta: ordering = ['id'] def __str__(self): if self.title_eng: return f"{self.title} | {self.title_eng}" else: return self.title
class Article(models.Model): headline = models.CharField(max_length=200) machine_name = models.CharField(max_length=40) author = models.CharField(max_length=50) teaser = RichTextUploadingField(null=True) body = RichTextUploadingField() pub_date = models.DateTimeField('date published') header_image = models.FileField(upload_to='banners/%Y/%m/%d/', null=True) header_image_small = models.FileField(upload_to='banners_small/%Y/%m/%d/', null=True) tags = TagField() def __str__(self): return self.headline def get_absolute_url(self): from django.urls import reverse return reverse('blog:article', args=[str(self.machine_name)])
class Event(Model): user = ForeignKey(settings.AUTH_USER_MODEL, default=1) content_type = ForeignKey(ContentType, default=DEFAULT_EVENT_CONTENT_TYPE_ID, limit_choices_to=EVENT_CONTENT_TYPE_CHOICES, on_delete=CASCADE) object_id = PositiveIntegerField(default=1) types = TagField(EventType, verbose_name=_('Event Type'), help_text=_('You can create new event type here')) name = CharField(max_length=120, unique=False, verbose_name=_('Name')) context = TextField(verbose_name=_('Context')) date = DateField(auto_now=False, default=timezone.now().today, verbose_name=_('Date')) share = BooleanField(default=False, verbose_name=_('Shared Event')) update_time = DateTimeField(auto_now=True, null=True, blank=True, verbose_name=_('Updated')) class Meta: verbose_name = _('Event') verbose_name_plural = _('Events') def __str__(self): return str(self.name) def __unicode__(self): return str(self.name)
class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) pen_name = models.CharField(max_length=100, unique=True) bio_summary = models.TextField(max_length=1000, blank=True) bio_full = models.TextField(blank=True) designation = models.CharField(max_length=100, blank=True, null=True) interests = TagField(force_lowercase=True, max_count=10) birth_date = models.DateField(null=True, blank=True) image = models.ImageField(upload_to="profile_images", blank=True) slug = models.SlugField(max_length=100, unique=True) def __str__(self): return ((self.user.first_name + " " + self.user.last_name + " | " + self.pen_name)) def save(self, *args, **kwargs): if (not self.slug): self.slug = unique_slug_generator(self, 'user.username') self.pen_name = self.user.username super(Profile, self).save(*args, **kwargs) # Call the "real" save() method. class Meta: permissions = (("is_moderator", "Can Moderate Others"), )
class Story(BaseModel): """ """ class Meta: get_latest_by = 'created_at' ordering = ['priority', '-title'] indexes = [ models.Index(fields=['title', 'priority']), models.Index(fields=['title']), ] verbose_name = 'story' verbose_name_plural = 'stories' epic = models.ForeignKey(Epic, null=True, blank=True, on_delete=models.SET_NULL) priority = models.PositiveIntegerField(default=0) points = models.PositiveIntegerField(default=0) state = models.ForeignKey(StoryState, on_delete=models.SET_NULL, null=True, blank=True) sprint = models.ForeignKey('sprints.Sprint', null=True, blank=True, on_delete=models.SET_NULL) requester = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='requested_tasks') assignee = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL, related_name='assigned_tasks') workspace = models.ForeignKey('workspaces.Workspace', on_delete=models.CASCADE) tags = TagField(blank=True) history = HistoricalRecords() def get_absolute_url(self): return reverse('stories:story-detail', args=[self.workspace.slug, str(self.id)]) def is_done(self): if self.state.stype == StateModel.STATE_DONE: return True return False def duplicate(self): cloned = copy.copy(self) cloned.pk = None cloned.title = 'Copy of ' + self.title cloned.save() for task in self.task_set.all(): task.duplicate(story=cloned) for tag in self.tags.values_list('name', flat=True): cloned.tags.add(tag)
class Case(Model): """案件 * state: 案件狀態, 預設值為未成案 * uuid: 案件編號(uuid4) * type: 案件類別 * region: 使用者所在選區 * title: 標題 * content: 案件內容 * location: 相關地址 * username: 使用者名字 * mobile: 手機 * email: 信箱 * address: 地址 * open_time: 成案日期 * close_time: 結案日期 * update_time: 上次更新時間 """ state = FSMField(default=State.DRAFT, verbose_name=_('Case State'), choices=State.CHOICES) uuid = UUIDField(default=uuid.uuid4, verbose_name=_('UUID'), unique=True) number = CharField(max_length=6, default='-', null=True, blank=True, verbose_name=_('Case Number')) type = ForeignKey('cases.Type', on_delete=CASCADE, related_name='cases', verbose_name=_('Case Type')) region = ForeignKey('cases.Region', on_delete=CASCADE, related_name='cases', verbose_name=_('User Region')) title = CharField(max_length=255, verbose_name=_('Case Title')) content = TextField(verbose_name=_('Content')) location = CharField(null=True, blank=True, max_length=255, verbose_name=_('Location')) username = CharField(max_length=50, verbose_name=_('Username')) mobile = CharField(max_length=10, null=True, blank=True, verbose_name=_('Mobile')) email = EmailField(null=True, blank=True, verbose_name=_('Email')) address = CharField(null=True, blank=True, max_length=255, verbose_name=_('Address')) open_time = DateTimeField(null=True, blank=True, verbose_name=_('Opened Time')) close_time = DateTimeField(null=True, blank=True, verbose_name=_('Closed Time')) create_time = DateTimeField(auto_now_add=True, null=True, blank=True, verbose_name=_('Created Time')) update_time = DateTimeField(auto_now=True, null=True, blank=True, verbose_name=_('Updated Time')) disapprove_info = TextField(null=True, blank=True, verbose_name=_('Disapprove Info')) note = TextField(null=True, blank=True, verbose_name=_('Case Notes')) tags = TagField(blank=True, verbose_name=_('Tags'), verbose_name_plural=_('Tags')) objects = CaseQuerySet.as_manager() class Meta: verbose_name = _('Case') verbose_name_plural = _('Cases') ordering = ('id', ) def save(self, *args, **kwargs): created = self.pk is None super(Case, self).save(*args, **kwargs) if created: self.number = str(self.pk).zfill(6) self.save() self.move_file() # 搬移暫存檔案 self.confirm(template_name='收件通知') # 發送確認信 new_case_notify(self) # 發送slack通知 def __str__(self): return self.number def to_dict(self): """用於新增CaseHistory""" return { 'state': self.state, 'title': self.title, 'type': self.type, 'region': self.region, 'content': self.content, 'location': self.location, 'username': self.username, 'mobile': self.mobile, 'email': self.email, 'address': self.address, } def move_file(self): case = Case.objects.get(uuid=self.uuid) objs = TempFile.objects.filter(case_uuid=self.uuid) for i in objs: file = TEMP_STORAGE.open(i.file.name) case_file = CaseFile() case_file.case = case case_file.file = file case_file.save()
class MarkdownPost(models.Model): objects = MarkdownPostManager() title = models.CharField(max_length=250, unique=True) slug = models.SlugField( max_length=250, unique=True, help_text='SEO Friendly name that is unique for use in URL') teaser = ContentMarkdownField( null=True, blank=True, field_image_prefix='post/teaser', help_text=mark_safe( 'Markdown Reference: <a href="https://commonmark.org/help/">https://commonmark.org/help/</a>' )) content = ContentMarkdownField( field_image_prefix='post/content', help_text=mark_safe( 'Markdown Reference: <a href="https://commonmark.org/help/">https://commonmark.org/help/</a>' )) author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True) # image = FilerImageField(null=True, blank=True) publish_date = models.DateTimeField(default=timezone.now) expire_date = models.DateTimeField(null=True, blank=True) categories = TagField( to=BlogCategory, blank=True, help_text= "Splits on commas and spaces; hierarchy is defined by paths. " "Collectively known as a 'content taxonomy'. This is often used as headings or to organize" "different blog content." "Ex: 'sports/nfl' 'sports/mlb' 'tech/sofware/linux'" "NOTE: unlike tags, categories should be well thought out beforehand and not change often" ) tags = TagField( to=BlogTag, blank=True, help_text= "Splits on commas and spaces; tags will be displayed to the public and used to " "pull a set of posts to show. For example, you could tag posts with 'docker' " "'zfs' then the plugin will show these at the bottom for visitors to use if there" "are more posts with that tag.") properties = TagField( to=BlogProperty, blank=True, help_text= "Splits on commas and spaces; like tags but not displayed to the public." "For example, you could tag posts with 'homepage' and or " "'hidden' then pull all posts tagged 'homepage' but not 'hidden'") created_date = models.DateTimeField(auto_now_add=True, editable=False) modified_date = models.DateTimeField(auto_now=True, editable=False) modified_by = models.CharField(max_length=255, null=True, blank=True) class Meta: ordering = ['-publish_date', 'title'] def __str__(self): return str(self.title) def get_absolute_url(self): return reverse("blog_detail", kwargs={"slug": self.slug}) def as_json(self): return serializers.serialize('json', [self])[0]
class Source(CommentableModel): run = models.ForeignKey( Run, on_delete=models.CASCADE, null=True, ) related = models.ManyToManyField('self', through='RelatedSource', symmetrical=False, through_fields=('from_source', 'to_source')) name = models.CharField(max_length=100) new = models.BooleanField(default=False, help_text='New Source.') tags = TagField( space_delimiter=False, autocomplete_view="vast_pipeline:source_tags_autocomplete", autocomplete_settings={"width": "100%"}, ) # average fields calculated from the source measurements wavg_ra = models.FloatField( help_text='The weighted average right ascension (Deg).') wavg_dec = models.FloatField( help_text='The weighted average declination (Deg).') wavg_uncertainty_ew = models.FloatField( help_text=('The weighted average uncertainty in the east-' 'west (RA) direction (Deg).')) wavg_uncertainty_ns = models.FloatField( help_text=('The weighted average uncertainty in the north-' 'south (Dec) direction (Deg).')) avg_flux_int = models.FloatField( help_text='The average integrated flux value.') avg_flux_peak = models.FloatField(help_text='The average peak flux value.') max_flux_peak = models.FloatField(help_text='The maximum peak flux value.') min_flux_peak = models.FloatField(help_text='The minimum peak flux value.') max_flux_int = models.FloatField( help_text='The maximum integrated flux value.') min_flux_int = models.FloatField( help_text='The minimum integrated flux value.') min_flux_int_isl_ratio = models.FloatField( help_text='The minimum integrated island flux ratio value.') min_flux_peak_isl_ratio = models.FloatField( help_text='The minimum peak island flux ratio value.') avg_compactness = models.FloatField(help_text='The average compactness.') min_snr = models.FloatField( help_text='The minimum signal-to-noise ratio value of the detections.') max_snr = models.FloatField( help_text='The maximum signal-to-noise ratio value of the detections.') # metrics v_int = models.FloatField(help_text='V metric for int flux.') v_peak = models.FloatField(help_text='V metric for peak flux.') eta_int = models.FloatField(help_text='Eta metric for int flux.') eta_peak = models.FloatField(help_text='Eta metric for peak flux.') new_high_sigma = models.FloatField( help_text=('The largest sigma value for the new source' ' if it was placed in previous image.')) n_neighbour_dist = models.FloatField( help_text='Distance to the nearest neighbour (deg)') vs_abs_significant_max_int = models.FloatField( default=0.0, help_text= ('Maximum value of all measurement pair variability t-statistics for int' ' flux that exceed variability.source_aggregate_pair_metrics_min_abs_vs in' ' the pipeline run configuration.')) m_abs_significant_max_int = models.FloatField( default=0.0, help_text= ('Maximum absolute value of all measurement pair modulation indices for int' ' flux that exceed variability.source_aggregate_pair_metrics_min_abs_vs in' ' the pipeline run configuration.')) vs_abs_significant_max_peak = models.FloatField( default=0.0, help_text= ('Maximum absolute value of all measurement pair variability t-statistics for' ' peak flux that exceed variability.source_aggregate_pair_metrics_min_abs_vs' ' in the pipeline run configuration.')) m_abs_significant_max_peak = models.FloatField( default=0.0, help_text= ('Maximum absolute value of all measurement pair modulation indices for ' ' peak flux that exceed variability.source_aggregate_pair_metrics_min_abs_vs' ' in the pipeline run configuration.')) # total metrics to report in UI n_meas = models.IntegerField(help_text='total measurements of the source') n_meas_sel = models.IntegerField( help_text='total selavy extracted measurements of the source') n_meas_forced = models.IntegerField( help_text='total force extracted measurements of the source') n_rel = models.IntegerField( help_text='total relations of the source with other sources') n_sibl = models.IntegerField(help_text='total siblings of the source') objects = SourceQuerySet.as_manager() def __str__(self): return self.name
class UserTool(StateMachineMixin, TitleDescriptionModel, TimeStampedModel): """A tool owned by a User""" States = ToolStates Transitions = ToolTransitions class Visibility(Catalog): _attrs = "value", "label", "card_class" private = 0, _("Private"), "tool-private border-danger" cleared = 1, _("Cleared Users"), "tool-cleared-only border-success" public = 2, _("Public"), "tool-public" class Clearance(Catalog): _attrs = "value", "label" none = 0, _("Available to all") owner = 1, _("Owner cleared users only") cleared = 2, _("Cleared users can approve anyone") user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT, related_name="tools") description = MarkdownxField(blank=True) state = models.CharField( max_length=10, choices=States._zip("value", "label"), default=States.none.value, editable=False, ) taxonomies = TagField(to=ToolTaxonomy, blank=True, related_name="tools") visibility = models.PositiveSmallIntegerField( _("Visibility"), choices=Visibility._zip("value", "label"), default=Visibility.public.value, help_text=_("The level of user visibility for this tool"), ) clearance = models.PositiveSmallIntegerField( _("Clearance"), choices=Clearance._zip("value", "label"), default=Clearance.none.value, help_text=_("Who is allowed to clear a user to use this tool"), ) objects = UserToolQuerySet.as_manager() class Meta: ordering = ("-created", ) get_latest_by = "created" verbose_name = _("Tool") verbose_name_plural = _("Tools") class StateMachine(StateMachineMixin.StateMachine): states = [{"name": state.value} for state in ToolStates] transitions = [{ "trigger": trigger, "source": source, "dest": dest } for trigger, source, dest in ToolTransitions._zip( "name", "source", "dest")] after_state_change = "record_transition" def __str__(self): return self.title def get_absolute_url(self): return reverse("tools:detail", kwargs={"pk": self.pk}) def record_transition(self, event): if not event.kwargs.get("skip_save", False): self.save() self.history.create(user=event.kwargs.get("user"), action=self.Transitions(event.event.name, "name").value) def check_clearance(self, user): return self.permissions.filter(cleared_user=user).exists() def user_can_grant_clearance(self, user): """See if we're allowed to grant clearance""" level = self.Clearance(self.clearance) if level == self.Clearance.none: return True if level == self.Clearance.owner: return self.user == user if level == self.Clearance.cleared: return self.user == user or self.check_clearance(user) def user_can_borrow(self, user): return self._meta.model.objects.borrowable_to_user(user).filter( pk=self.pk).exists() def prepare_borrow(self, event): """Do validation before allowing a user to borrow a tool""" user = event.kwargs.get("user") if not self.user_can_borrow(user): raise ToolClearanceException( "%s isn't allowed to borrow this tool" % user) # Is this needed? if not self.is_available(): raise ToolAvailabilityException() @property def cover_photo(self): try: return self.photos.latest() except ToolPhoto.DoesNotExist: return None
class Epic(ModelWithProgress): """ """ class Meta: get_latest_by = 'created_at' ordering = ['priority', '-title'] indexes = [ models.Index(fields=['title', 'priority']), models.Index(fields=['title']), ] verbose_name = 'epic' verbose_name_plural = 'epics' priority = models.PositiveIntegerField(default=0) state = models.ForeignKey(EpicState, on_delete=models.SET_NULL, null=True, blank=True) owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL) workspace = models.ForeignKey('workspaces.Workspace', on_delete=models.CASCADE) tags = TagField(blank=True) history = HistoricalRecords() def get_absolute_url(self): return reverse('stories:epic-detail', args=[self.workspace.slug, str(self.id)]) def is_done(self): if self.state.stype == StateModel.STATE_DONE: return True return False def duplicate(self): cloned = copy.copy(self) cloned.pk = None cloned.title = 'Copy of ' + self.title cloned.save() for tag in self.tags.values_list('name', flat=True): cloned.tags.add(tag) def update_state(self): # set epic as started when it has one or more started stories if Story.objects.filter(state__stype=StoryState.STATE_STARTED, epic=self).count() > 0: if self.state.stype != EpicState.STATE_STARTED: self.state = EpicState.objects.filter( stype=EpicState.STATE_STARTED)[0] elif Story.objects.filter(state__stype=StoryState.STATE_UNSTARTED, epic=self).count() == self.story_count: if self.state.stype != EpicState.STATE_UNSTARTED: self.state = EpicState.objects.filter( stype=EpicState.STATE_UNSTARTED)[0] self.save()