class Project(models.Model): PROJECTTYPE = (('AC', 'Acceso'), ('AM', 'AMX'), ('AP', 'Aplicaciones'), ('CO', 'Core'), ('DI', 'Distribución'), ('LB', 'Laboratorio'), ('VI', 'Video')) YEARS = ((2019, '2019'), (2020, '2020')) STATUS = (('DP', 'Diseño'), ('QP', 'Cotización'), ('QA', 'SAP-Compras'), ('IP', 'Implementación'), ('CP', 'Capitalizado'), ('PR', 'Rechazado')) LABEL = ( ('Normal', 'Normal'), ('Multimedia', 'Multimedia'), ('IP+Fotónico', 'IP+Fotónico'), ) pid = models.CharField(max_length=8, editable=False) year = models.IntegerField("Año de ejecución", choices=YEARS) created = models.DateField(auto_now_add=True, editable=False) updated = models.DateTimeField(auto_now=True, editable=False) ptype = models.CharField("Tipo de proyecto", max_length=2, choices=PROJECTTYPE) name = models.CharField("Titulo", max_length=200) reference = models.CharField("Referencia", max_length=200, blank=True) owner = models.ManyToManyField(UserProfile, verbose_name="Tripulación") country = models.ForeignKey(Country, on_delete=models.CASCADE, verbose_name="Pais") label = models.CharField("Etiqueta", max_length=100, default="Normal", choices=LABEL) priority = models.IntegerField("Prioridad", default=100) objective = models.TextField("Objetivo", max_length=5000, default="#Objetivo") justify = models.TextField("Justificación", max_length=5000, default="#Justificación") status = models.CharField("Estatus", max_length=2, choices=STATUS, default='DP') wbs = models.ForeignKey(WBS, on_delete=models.CASCADE, verbose_name="WBS") background = models.TextField("Antecedentes", max_length=5000, default="#Antecedentes", blank=True, null=True) totallocations = models.IntegerField("Total de sitios", default=0) structure = models.BooleanField(default=False, editable=False) pds = models.ForeignKey(ProjectDeliverableSchema, on_delete=models.CASCADE, verbose_name="Entregables") def status_icon(self): STATUSICONS = { 'DP': 'fa-drafting-compass', 'QP': 'fa-rocket', 'QA': 'fa-shopping-basket', 'IP': 'fa-paper-plane', 'CP': 'fa-money-bill', 'PR': 'fa-ban' } if self.status: icon = STATUSICONS[self.status] else: icon = 'fa-forumbee' return icon def kanban(user): status_list = dict(Project.STATUS) projects = Project.objects.filter(owner__in=user.getareaowners()) kanban_list = [] for status_key in status_list: board = { 'id': status_key, 'title': status_list[status_key], 'class': 'bg-warning', 'item': [] } for project in projects.filter(status=status_key): board['item'].append({ 'id': project.id, 'title': project.pid, 'pid': project.pid, 'content': project.name, 'reference': project.reference, 'toggle': 'popover' }) kanban_list.append(board) kanban = { 'statuslist': list(status_list), 'structure': kanban_list } return kanban def status_card(user): dashboardcard = [{ 'status': 'bg-success', 'icon': 'fa-check-circle', 'count': 0 }, { 'status': 'bg-warning', 'icon': 'fa-exclamation-circle', 'count': 0 }, { 'status': 'bg-danger', 'icon': 'fa-life-ring', 'count': 0 }, { 'status': 'bg-primary', 'icon': 'fa-tasks', 'count': Project.objects.filter(owner__in=user.getareaowners()).count() }] return dashboardcard def save(self, *args, **kwargs): if not self.pid: projectyear = self.year if self.ptype: try: projects = Project.objects.filter( ptype=self.ptype, year=projectyear).order_by('-pid')[0] pindex = int(projects.pid[2:5]) + 1 except: pindex = 1 pindex = '{:03d}'.format(pindex) self.pid = r'%s%s-%s' % (self.ptype, pindex, str(projectyear)[2:]) else: self.full_clean() super(Project, self).save(*args, **kwargs) def createstructure(self): print("Creating loctions...") if (not self.structure) and (int(self.totallocations) > 0): for k in range(0, int(self.totallocations)): ProjectLocation.objects.create(planningref="Sitio " + '{:04d}'.format(k + 1), project=self) if (not self.structure): stages = Stage.objects.filter(wbs=self.wbs).order_by('nlevel') event = ProjectEvent locations = ProjectLocation.objects.filter(project=self) planning = [True, False] print("Sites created, creating events...") for p in planning: for s in stages: startdate = timezone.make_aware(s.startdate(self.year)) enddate = timezone.make_aware(s.enddate(self.year)) if s.ntype == "S": for k in locations: ProjectEvent.objects.create(stage=s, projectnode=k, project=self, start=startdate, end=enddate, planning=p) else: ProjectEvent.objects.create(stage=s, project=self, start=startdate, end=enddate, planning=p) self.structure = True self.save() def title(self): return r'%s %s' % (self.pid, self.reference) def resources(self): resource = [] for k in Stage.objects.filter(wbs=self.wbs).order_by('nlevel'): k_resource = { 'id': '', 'title': '', 'taskname': k.ntitle, 'children': [] } k_resource['id'] = str(k.id) k_resource['title'] = k.ntitle if k.ntype == 'S': for j in ProjectLocation.objects.filter( project=self).order_by('planningref'): j_resource = { 'id': '', 'title': '', 'taskname': k.ntitle, 'children': [] } j_resource['id'] = str(k.id) + "::" + str(j.id) j_resource['title'] = j.planningref k_resource['children'].append(j_resource) resource.append(k_resource) return resource def events(self): json_events = [] ProjectEvents = ProjectEvent.objects.filter(project=self).order_by( 'stage__nlevel', 'planning') for k in ProjectEvents: resourceid = str(k.stage.id) if k.stage.ntype == 'S': resourceid += "::" + str(k.projectnode.id) json_event = { 'id': k.id, 'resourceId': resourceid, 'start': k.start.isoformat(), 'end': k.end.isoformat(), 'title': k.name, 'color': k.color(), 'progress': k.progress, 'editable': not k.planning } json_events.append(json_event) return json_events def __str__(self): return r'%s' % (self.pid) def startdate(self): return StageGoal.objects.filter( stage__wbs=self.wbs).order_by('slot')[0].stage.startdate(self.year) def enddate(self): return StageGoal.objects.filter( stage__wbs=self.wbs).order_by('-slot')[0].stage.enddate(self.year)
class Migration(migrations.Migration): initial = True dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ] operations = [ migrations.CreateModel( name='Suppliers', fields=[ ('supplier_id', models.AutoField(primary_key=True, serialize=False)), ('supplier_name', models.CharField(max_length=200)), ('contact_firstName', models.CharField(max_length=200)), ('contact_lastName', models.CharField(max_length=200)), ('contact_title', models.CharField(max_length=200)), ('supplier_address1', models.CharField(max_length=200)), ('supplier_address2', models.CharField(max_length=200, null=True)), ('supplier_city', models.CharField(max_length=200)), ('supplier_state', models.CharField(max_length=2)), ('supplier_country', models.CharField(max_length=200)), ('supplier_email', models.EmailField(max_length=254)), ('supplier_website', models.URLField()), ], options={ 'verbose_name': 'supplier', 'verbose_name_plural': 'suppliers', 'db_table': 'suppliers', }, ), migrations.CreateModel( name='Tops', fields=[ ('product_sku', models.CharField(db_index=True, max_length=50, unique=True)), ('product_name', models.CharField(max_length=50)), ('product_color', models.CharField(max_length=50)), ('product_shortDesc', models.CharField(blank=True, max_length=50)), ('product_longDesc', models.CharField(blank=True, max_length=50)), ('product_price', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('product_weight', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('slug', models.SlugField(unique=True)), ('added_date', models.DateField()), ('top_id', models.AutoField(primary_key=True, serialize=False)), ('product_type', models.CharField(choices=[('TE', 'Tee'), ('SH', 'Shirt'), ('TT', 'Tank Top'), ('HO', 'Hoody'), ('KR', 'Kurta')], max_length=2)), ('product_size', models.CharField(choices=[('XS', 'Extra Small'), ('SM', 'Small'), ('MD', 'Medium'), ('LG', 'Large'), ('XL', 'Extra Large')], default='NA', max_length=2)), ('product_image', models.ImageField(upload_to='Tops/')), ('supplier', models.ForeignKey(default=-1, on_delete=django.db.models.deletion.CASCADE, to='inventory.Suppliers')), ], options={ 'verbose_name': 'top', 'verbose_name_plural': 'tops', 'db_table': 'tops', }, ), migrations.CreateModel( name='Shoes', fields=[ ('product_sku', models.CharField(db_index=True, max_length=50, unique=True)), ('product_name', models.CharField(max_length=50)), ('product_color', models.CharField(max_length=50)), ('product_shortDesc', models.CharField(blank=True, max_length=50)), ('product_longDesc', models.CharField(blank=True, max_length=50)), ('product_price', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('product_weight', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('slug', models.SlugField(unique=True)), ('added_date', models.DateField()), ('shoe_id', models.AutoField(primary_key=True, serialize=False)), ('product_image', models.ImageField(upload_to='Shoes')), ('product_size', models.CharField(choices=[('5', '5'), ('6', '6'), ('7', '7'), ('8', '8'), ('9', '9'), ('10', '10'), ('11', '11'), ('12', '12'), ('13', '13')], default='NA', max_length=2)), ('supplier', models.ForeignKey(default=-1, on_delete=django.db.models.deletion.CASCADE, to='inventory.Suppliers')), ], options={ 'verbose_name': 'shoe', 'verbose_name_plural': 'shoes', 'db_table': 'shoes', }, ), migrations.CreateModel( name='Inventory', fields=[ ('inventory_id', models.AutoField(primary_key=True, serialize=False)), ('product_count', models.IntegerField(default=0)), ('product_cost', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('added_at', models.DateTimeField()), ('updated_at', models.DateTimeField()), ('object_id', models.PositiveIntegerField()), ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), ], ), migrations.CreateModel( name='Bottoms', fields=[ ('product_sku', models.CharField(db_index=True, max_length=50, unique=True)), ('product_name', models.CharField(max_length=50)), ('product_color', models.CharField(max_length=50)), ('product_shortDesc', models.CharField(blank=True, max_length=50)), ('product_longDesc', models.CharField(blank=True, max_length=50)), ('product_price', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('product_weight', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('slug', models.SlugField(unique=True)), ('added_date', models.DateField()), ('bottom_id', models.AutoField(primary_key=True, serialize=False)), ('product_type', models.CharField(choices=[('PA', 'Pants'), ('PJ', 'Pajama'), ('SO', 'Shorts')], default='NA', max_length=2)), ('product_size', models.CharField(choices=[('XS', 'Extra Small'), ('SM', 'Small'), ('MD', 'Medium'), ('LG', 'Large'), ('XL', 'Extra Large')], default='NA', max_length=2)), ('product_image', models.ImageField(upload_to='Bottoms/')), ('supplier', models.ForeignKey(default=-1, on_delete=django.db.models.deletion.CASCADE, to='inventory.Suppliers')), ], options={ 'verbose_name': 'bottom', 'verbose_name_plural': 'bottoms', 'db_table': 'bottoms', }, ), migrations.CreateModel( name='Accessories', fields=[ ('product_sku', models.CharField(db_index=True, max_length=50, unique=True)), ('product_name', models.CharField(max_length=50)), ('product_color', models.CharField(max_length=50)), ('product_shortDesc', models.CharField(blank=True, max_length=50)), ('product_longDesc', models.CharField(blank=True, max_length=50)), ('product_price', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('product_weight', models.DecimalField(decimal_places=2, default=0, max_digits=6)), ('slug', models.SlugField(unique=True)), ('added_date', models.DateField()), ('accessory_id', models.AutoField(primary_key=True, serialize=False)), ('product_type', models.CharField(default=[('AC', 'accessories')], max_length=2)), ('product_image', models.ImageField(upload_to='accessories/')), ('supplier', models.ForeignKey(default=-1, on_delete=django.db.models.deletion.CASCADE, to='inventory.Suppliers')), ], options={ 'verbose_name': 'accessory', 'verbose_name_plural': 'accessories', 'db_table': 'accessories', }, ), ]
class ExportedData(Model): """ Stores references to asynchronous data export jobs being stored in the Google Cloud Platform temporary storage solution. """ __core__ = False organization = FlexibleForeignKey("sentry.Organization") user = FlexibleForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL) file = FlexibleForeignKey("sentry.File", null=True, db_constraint=False, on_delete=models.SET_NULL) date_added = models.DateTimeField(default=timezone.now) date_finished = models.DateTimeField(null=True) date_expired = models.DateTimeField(null=True, db_index=True) query_type = BoundedPositiveIntegerField( choices=ExportQueryType.as_choices()) query_info = JSONField() @property def status(self): if self.date_finished is None: return ExportStatus.Early elif self.date_expired < timezone.now(): return ExportStatus.Expired else: return ExportStatus.Valid @property def date_expired_string(self): if self.date_expired is None: return None return self.date_expired.strftime("%-I:%M %p on %B %d, %Y (%Z)") def delete_file(self): if self.file: self.file.delete() def delete(self, *args, **kwargs): self.delete_file() super(ExportedData, self).delete(*args, **kwargs) def finalize_upload(self, file, expiration=DEFAULT_EXPIRATION): self.delete_file() current_time = timezone.now() expire_time = current_time + expiration self.update(file=file, date_finished=current_time, date_expired=expire_time) self.email_success() def email_success(self): from sentry.utils.email import MessageBuilder # The following condition should never be true, but it's a safeguard in case someone manually calls this method if self.date_finished is None or self.date_expired is None or self.file is None: # TODO(Leander): Implement logging here return msg = MessageBuilder( subject="Your Download is Ready!", context={ "url": absolute_uri( reverse("sentry-data-export-details", args=[self.organization.slug, self.id])), "expiration": self.date_expired_string, }, template="sentry/emails/data-export-success.txt", html_template="sentry/emails/data-export-success.html", ) msg.send_async([self.user.email]) class Meta: app_label = "sentry" db_table = "sentry_exporteddata" __repr__ = sane_repr("query_type", "query_info")
class Migration(migrations.Migration): initial = True dependencies = [ ('auth', '0008_alter_user_username_max_length'), ] operations = [ migrations.CreateModel( name='UserProfile', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), ('email', models.EmailField(max_length=255, null=True, unique=True, verbose_name='email address')), ('password', models.CharField(max_length=128, verbose_name='password')), ('name', models.CharField(max_length=32)), ('is_active', models.BooleanField(default=True)), ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), ], options={ 'abstract': False, }, ), migrations.CreateModel( name='Host', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('hostname', models.CharField(max_length=64, verbose_name='主机')), ('ip_addr', models.GenericIPAddressField(unique=True, verbose_name='IP地址')), ('port', models.PositiveIntegerField(default=22, verbose_name='端口号')), ('enable', models.BooleanField(default=True, verbose_name='当前状态')), ], ), migrations.CreateModel( name='HostGroup', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=64, unique=True, verbose_name='主机组')), ], ), migrations.CreateModel( name='HostToUser', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('host', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='audit.Host')), ], ), migrations.CreateModel( name='HostUser', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('auth_type', models.SmallIntegerField(choices=[(0, '密码验证'), (1, '密钥验证')], default=0)), ('username', models.CharField(max_length=64, verbose_name='用户名')), ('password', models.CharField(max_length=128, verbose_name='密码')), ], ), migrations.CreateModel( name='IDC', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=64, unique=True, verbose_name='数据中心')), ], ), migrations.AlterUniqueTogether( name='hostuser', unique_together=set([('auth_type', 'username', 'password')]), ), migrations.AddField( model_name='hosttouser', name='host_user', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='audit.HostUser'), ), migrations.AddField( model_name='hostgroup', name='host_2_user', field=models.ManyToManyField(blank=True, to='audit.HostToUser'), ), migrations.AddField( model_name='host', name='IDC', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='audit.IDC', verbose_name='数据中心'), ), migrations.AddField( model_name='userprofile', name='host_2_user', field=models.ManyToManyField(blank=True, to='audit.HostToUser'), ), migrations.AddField( model_name='userprofile', name='host_groups', field=models.ManyToManyField(blank=True, to='audit.HostGroup'), ), migrations.AddField( model_name='userprofile', name='user_permissions', field=models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions'), ), migrations.AlterUniqueTogether( name='hosttouser', unique_together=set([('host', 'host_user')]), ), ]
class Article(models.Model): ''' An Article object consists of all the elements of a published article, including the product it's referring to, the main content, and Elasticsearch aggregation fields for faceted navigation. Faceting is disabled in the beginning but will be re-enabled later on when there are a sufficient number of articles. However, general navigation and sorting is still fully functional. ''' HELP_ASR = 'Aspect Ratings and Sentiments' HELP_TDA = 'Topic Distribution All' HELP_TDS = 'Topic Distribution Summarized' HELP_TSR = 'Time Series' HELP_VPR = 'Purchase Type: Verified/Unverified Pruchase' HELP_HPL = 'Review Helpfulness' HELP_RCD = 'Review Recommendation' HELP_DNT = 'Donuts: Helpful, Purchase Type, Rating Distro, Recommendation, Classification' DEFAULT_CAP = 'Please refer to <a href=/data-interpretation/>Data ' DEFAULT_CAP += 'Interpretation</a> for a brief explanation on how to ' DEFAULT_CAP += 'interpret this figure.' METADATA_TEXT = 'You can find additional figures like star rating ' METADATA_TEXT += 'distribution, review classification, and historical ' METADATA_TEXT += 'review submission trends on our metadata page.' product = models.ForeignKey(Product, related_name='product', blank=False, null=True) # ES index, snowball article_title = models.CharField(max_length=60, blank=True, null=True) # ES index, snowball content = JSONField(blank=True, null=True) # ES index, snowball # TODO: not yet indexed aspects = JSONField(blank=True, null=True) # ES index, snowball; meta_description = models.CharField(max_length=155, blank=True, null=True) # ES index, snowball #TODO: Don't need article slug anymore; use product slug instead; remove from es index slug = models.SlugField(max_length=100, blank=True, null=True, unique=True, editable=False) # ES index, snowball draft = models.BooleanField(default=True) published = models.BooleanField(default=False) download_charts = models.BooleanField(default=True) # Highcharts metadata link download_link = models.CharField(max_length=60, blank=True, null=True) metadata_text = models.TextField( blank=True, null=True, default=METADATA_TEXT) # ES index, snowball # Analysis # analysis_intro covers TDS as well so there's no separate section for it analysis_intro = models.TextField(blank=True, null=True) # ES index, snowball analysis_ASR = models.TextField(blank=True, null=True, help_text=HELP_ASR) # ES index, snowball analysis_TDS = models.TextField(blank=True, null=True, help_text=HELP_TDS) # ES index, snowball analysis_TSR = models.TextField(blank=True, null=True, help_text=HELP_TSR) # ES index, snowball analysis_DNT = models.TextField(blank=True, null=True, help_text=HELP_DNT) # ES index, snowball # Captions caption_ASR = models.TextField(blank=True, null=True, help_text=HELP_ASR, default=DEFAULT_CAP) # ES index, snowball caption_TDS = models.TextField(blank=True, null=True, help_text=HELP_TDS, default=DEFAULT_CAP) # ES index, snowball caption_TDA = models.TextField(blank=True, null=True, help_text=HELP_TDA) # ES index, snowball caption_TSR = models.TextField(blank=True, null=True, help_text=HELP_TSR) # ES index, snowball caption_DNT = models.TextField(blank=True, null=True, help_text=HELP_DNT) # ES index, snowball # Graph Controls # selectively enable/disable certain donut plots # always shown: rating distro, classification # optional: helpfulness, recommendation, purchase type; will always show two out of three disable_TSR = models.BooleanField(default=False, help_text=HELP_TSR) disable_VPR = models.BooleanField(default=True, help_text=HELP_VPR) #disabled by default disable_HPL = models.BooleanField(default=False, help_text=HELP_HPL) disable_RCD = models.BooleanField(default=False, help_text=HELP_RCD) disable_metadata = models.BooleanField(default=True) # Meta tag fields meta_image = models.ImageField(upload_to=helper.UniquePath('images'),\ blank=True, null=True) meta_image_alt_tag = models.CharField(max_length=256, blank=True, null=True) # ES index, snowball # Elasticsearch aggregation and sorting fields # Sort By options: Most Recent, Number of Reviews, Number of Features, Highest Rated # TODO: this field should be populated in detailview.py and inaccessible from the front-end adjusted_rating = models.DecimalField(default=0.0, decimal_places=1, max_digits=2) # ES index, Keyword adjusted_star_rating = models.TextField(blank=False, null=True) # ES index, Keyword review_count = models.IntegerField(default=0) # ES index, Keyword aspect_count = models.IntegerField(default=0) # ES index, Keyword # DetailView context dictionary status context_upto_date = models.BooleanField(default=False) # Timestamp created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) # Data Transfer Status data_dumped = models.BooleanField(default=False) # the name shown in dropdowns, column label, # and queryset label in the shell def __unicode__(self): return '%s' % (self.product.product_name) def save(self, *args, **kwargs): # TODO: slugs should not be updated once created self.slug = self.product.slug self.article_title = self.product.title # if not self.slug: # # we need this redundant field to fix reverse url lookup issues # self.slug = self.product.slug # Set all new articles to draft mode by default. Ensure that Draft # and Publshed aren't both true or false. If they are, set it to # draft mode. if self.draft: self.published = False elif self.published: self.draft = False else: self.draft = True self.published = False self.updated_at = datetime.datetime.now() super(Article, self).save() def date_created(self): return self.created_at.date() #date only, no time of day def date_updated(self): return self.updated_at.date() #date only, no time of day def get_excerpt(self, n=160): if self.content: return self.content[:n] def get_absolute_url(self): url = reverse('review', kwargs={'slug': self.slug}) return url def get_image_url(self): url = "/media/images/image_not_found.jpg" try: if self.product.image.url: url = self.product.image.url except ValueError: # no image found pass return url def frsku(self): return self.product.frsku def flatten_json(self): ''' Return 'flattened' json contents for Elasticsearch indexing. By flattening we mean removing any hierarchical structures and instead combining everything into a single string. ''' # TODO: parse out the aspect ratings in the future and index them; This # might take us in some interesting directions for aggregating # TODO: include all the captions and section analyses string = '' if self.content: content_list = [] nested_content_list = self.content.get(self.product.frsku) if nested_content_list: for topical_dict in nested_content_list: for aspect, content_dict in topical_dict.items(): summary = content_dict.get('summary') # the main text content_list.append(aspect) content_list.append(summary) string = ' '.join(content_list) return string def get_domain_name(self): string = self.product.product_domain.domain string += ' ' + self.product.product_domain.subdomain return string def indexing(self, index=None, bulk=False): indexable_dict = { '_id': self.pk, 'article_id': self.id, 'product_name': self.product.product_name, 'article_title': self.article_title, 'content': self.flatten_json(), 'meta_description': self.meta_description, 'article_slug': self.slug, 'product_slug': self.product.slug, 'metadata_text': self.metadata_text, 'analysis_intro': self.analysis_intro, 'analysis_ASR': self.analysis_ASR, 'analysis_TDS': self.analysis_TDS, 'analysis_TSR': self.analysis_TSR, 'analysis_DNT': self.analysis_DNT, 'caption_ASR': self.caption_ASR, 'caption_TDS': self.caption_TDS, 'caption_TDA': self.caption_TDA, 'caption_TSR': self.caption_TSR, 'caption_DNT': self.caption_DNT, 'meta_image_alt_tag': self.meta_image_alt_tag, 'adjusted_rating': self.adjusted_rating, 'adjusted_star_rating': self.adjusted_star_rating, 'review_count': self.review_count, 'aspect_count': self.aspect_count, 'date_created': self.date_created(), 'date_updated': self.date_updated(), 'lineage_tags': self.product.product_taxonomy.lineage_tags, 'taxonomy': self.product.product_taxonomy.name, 'image': str(self.get_image_url()), 'get_absolute_url': self.get_absolute_url(), 'level_0': self.product.product_taxonomy.level_0, 'level_1': self.product.product_taxonomy.level_1, 'brand': self.product.brand, 'product_domain': self.get_domain_name(), 'key_specs': self.product.key_specs, 'model_number': self.product.model_num, } index_obj = index(meta={'id': indexable_dict.pop('_id')},\ **indexable_dict) if bulk: return index_obj.to_dict(include_meta=True) return index_obj
class Category(models.Model): site = models.ForeignKey(Site, default=None, related_name='categorys', verbose_name='关联的站点') code = models.CharField(max_length=100, default='', db_index=True, unique=True, verbose_name='分类代码') name = models.CharField(max_length=100, default='', verbose_name='分类名称') page_title = models.CharField(max_length=100, blank=True, default='', verbose_name='网页标题') keywords = models.CharField(max_length=254, default='', blank=True, verbose_name='关键字') short_desc = models.CharField(max_length=1024, default='', blank=True, verbose_name='简略描述') description = models.CharField(max_length=1024, default='', blank=True, verbose_name='分类描述') sort_order = models.CharField(max_length=100, default='', verbose_name='排序序号') parent = models.ForeignKey('self', null=True, default=None, related_name='childrens', blank=True, verbose_name='上级分类') detail_template = models.CharField(max_length=254, default='', blank=True, verbose_name='商品详情页指定模板') category_template = models.CharField(max_length=254, default='', blank=True, verbose_name='分类指定模板') static_file_name = models.CharField(max_length=254, db_index=True, unique=True, null=True, blank=True, verbose_name='静态文件名(不包含路径,以html结尾)') create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间') update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间') def get_parent_stack(self): from shopcart.utils import Stack s = Stack(20); target = self while target is not None: s.push(target) target = target.parent return s def get_dirs(self): from shopcart.utils import Stack s = self.get_parent_stack() dir = '' while not s.isempty(): dir = dir + s.pop().code + '/' return dir def get_childrens(self): return self.childrens.all().order_by('-sort_order') def get_url(self): from shopcart.functions.product_util_func import get_url return get_url(self) def get_leveled_parents(self): from shopcart.utils import Stack s = self.get_parent_stack() parent_list = [] while not s.isempty(): parent_list.append(s.pop()) return parent_list def get_parent(cat): if cat.parent: return get_parent(cat.parent) else: return cat def __str__(self): return self.name class Meta: verbose_name = '商品分类' verbose_name_plural = '商品分类'
class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Address', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('street_address', models.CharField(max_length=100)), ('apartment_address', models.CharField(max_length=100)), ('country', django_countries.fields.CountryField(max_length=2)), ('zip_address', models.CharField(max_length=100)), ('address_type', models.CharField(choices=[('S', 'Shipping'), ('B', 'Billing')], max_length=1)), ('default', models.BooleanField(default=False)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'verbose_name_plural': 'Addresses', }, ), migrations.CreateModel( name='Coupon', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('code', models.CharField(max_length=15)), ('amount', models.FloatField()), ], ), migrations.CreateModel( name='Item', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=100)), ('price', models.FloatField()), ('discount_price', models.FloatField(blank=True, null=True)), ('category', models.CharField(choices=[('S', 'Shirt'), ('SW', 'Sport wear'), ('OW', 'Outwear')], max_length=2)), ('label', models.CharField(choices=[('P', 'primary'), ('S', 'secondary'), ('D', 'danger')], max_length=1)), ('slug', models.SlugField()), ('description', models.TextField()), ('image', models.ImageField(upload_to='')), ], ), migrations.CreateModel( name='Order', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('ref_code', models.CharField(max_length=20)), ('start_date', models.DateTimeField(auto_now_add=True)), ('ordered_date', models.DateTimeField()), ('ordered', models.BooleanField(default=False)), ('being_delivered', models.BooleanField(default=False)), ('received', models.BooleanField(default=False)), ('refund_requested', models.BooleanField(default=False)), ('refund_granted', models.BooleanField(default=False)), ('billing_address', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='billing_address', to='main.Address')), ('coupon', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.Coupon')), ], ), migrations.CreateModel( name='Refund', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('message', models.TextField()), ('email', models.EmailField(max_length=254)), ('accepted', models.BooleanField(default=False)), ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Order')), ], ), migrations.CreateModel( name='Payment', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('stripe_charge_id', models.CharField(max_length=50)), ('amount', models.FloatField()), ('timestamp', models.DateField(auto_now_add=True)), ('user', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='OrderItem', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('quantity', models.IntegerField(default=1)), ('ordered', models.BooleanField(default=False)), ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main.Item')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), migrations.AddField( model_name='order', name='items', field=models.ManyToManyField(to='main.OrderItem'), ), migrations.AddField( model_name='order', name='payment', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='main.Payment'), ), migrations.AddField( model_name='order', name='shipping_address', field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='shipping_address', to='main.Address'), ), migrations.AddField( model_name='order', name='user', field=models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), ), ]
class BaseTask(MPTTModel, GenericFKModel, TimeStampedModel, models.Model): """ Base abstract model class for a Task This class is meant to be extended to add Tasks to your own project. It only implements the bare minimum of what a Task could be. """ ACTIVE = "a" DEACTIVATED = "b" EXPIRED = "c" DRAFT = "d" SCHEDULED = "s" ARCHIVED = "e" STATUS_CHOICES = ( (ACTIVE, _("Active")), (DEACTIVATED, _("Deactivated")), (EXPIRED, _("Expired")), (DRAFT, _("Draft")), (SCHEDULED, _("Scheduled")), (ARCHIVED, _("Archived")), ) parent = TreeForeignKey( "self", verbose_name=_("Parent task"), null=True, blank=True, default=None, on_delete=models.SET_NULL, help_text=_("This represents the parent task."), ) name = models.CharField(_("Name"), max_length=255, help_text=_("This represents the name.")) description = models.TextField( _("Description"), blank=True, default="", help_text=_("This represents the description."), ) start = models.DateTimeField( verbose_name=_("Start"), help_text=_("This is the date and time the task starts."), ) end = models.DateTimeField( verbose_name=_("End"), null=True, blank=True, default=None, help_text=_("This is the date and time the task ends."), ) timing_rule = models.TextField( verbose_name=_("Timing Rule"), validators=[validate_rrule], null=True, blank=True, default=None, help_text=_("This stores the rrule for recurrence."), ) total_submission_target = models.IntegerField( verbose_name=_("Total Submissions Target"), null=True, blank=True, default=None, help_text=_( "This is the total number of submissions required for this task. " "Set to None if there is no Max."), ) user_submission_target = models.IntegerField( verbose_name=_("User Submissions Target"), null=True, blank=True, default=None, help_text=_( "This is the total number of submissions per user required for " "this task. Set to None if there is no Max."), ) status = models.CharField( verbose_name=_("Status"), choices=STATUS_CHOICES, default=DRAFT, max_length=1, help_text=_("The status of the Task"), ) estimated_time = models.DurationField( verbose_name=_("Estimated Time"), null=True, blank=True, default=None, help_text=_("This represents the estimated time it takes to complete" " a task"), ) # pylint: disable=no-self-use # pylint: disable=too-few-public-methods class Meta: """ This is the meta options class for BaseTask """ abstract = True
class Migration(migrations.Migration): initial = True dependencies = [ ('auth', '0009_alter_user_last_name_max_length'), ] operations = [ migrations.CreateModel( name='User', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('password', models.CharField(max_length=128, verbose_name='password')), ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), ('username', models.CharField(max_length=100, unique=True)), ('email', models.EmailField(max_length=254, unique=True)), ('first_name', models.CharField(blank=True, max_length=100, null=True)), ('last_name', models.CharField(blank=True, max_length=100, null=True)), ('profile_photo', models.ImageField(default='pic_folder/default.jpg', upload_to='pic_folder/%Y/%M/%D')), ('profile', models.TextField(blank=True, null=True)), ('is_owner', models.BooleanField(default=False, verbose_name='project_owner status')), ('is_freelancer', models.BooleanField(default=False, verbose_name='freelancer status')), ('date_created', models.DateTimeField(auto_now_add=True)), ('date_modified', models.DateTimeField(auto_now=True)), ('is_admin', models.BooleanField(default=False)), ('is_superuser', models.BooleanField(default=False)), ('is_staff', models.BooleanField(default=False)), ('is_active', models.BooleanField(default=True)), ('groups', models.ManyToManyField( blank=True, help_text= 'The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')), ('user_permissions', models.ManyToManyField( blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')), ], options={ 'abstract': False, }, ), ]
class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='IndividualUser', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text="user's full name", max_length=50)), ('email', models.EmailField(max_length=254)), ('contact', models.CharField(max_length=11)), ('created_at', models.DateTimeField()), ('updated_at', models.DateTimeField(blank=True, null=True)), ('date_of_birth', models.DateField()), ('is_trainer', models.BooleanField(default=False)), ('auth', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'abstract': False, }, ), migrations.CreateModel( name='OrganizationUser', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(help_text="user's full name", max_length=50)), ('email', models.EmailField(max_length=254)), ('contact', models.CharField(max_length=11)), ('created_at', models.DateTimeField()), ('updated_at', models.DateTimeField(blank=True, null=True)), ('is_training_institute', models.BooleanField(default=False)), ('description', models.TextField(blank=True, null=True)), ('auth', models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'abstract': False, }, ), ]
class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='Categories', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=250, unique=True)), ('seo_title', models.CharField(max_length=70)), ('seo_description', models.CharField(max_length=160)), ('slug', models.SlugField(max_length=255, unique=True)), ('categoryStatus', models.CharField(blank=True, choices=[('Active', 'Active'), ('Inactive', 'Inactive'), ('Available', 'Available')], max_length=30, null=True)), ('categoryCreated', models.DateTimeField(auto_now_add=True)), ('seo_keywords', models.CharField(max_length=160)), ('lft', models.PositiveIntegerField(editable=False)), ('rght', models.PositiveIntegerField(editable=False)), ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), ('level', models.PositiveIntegerField(editable=False)), ], options={ 'abstract': False, }, ), migrations.CreateModel( name='CourseDetails', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('courseName', models.CharField(blank=True, max_length=400, null=True)), ('courseDescription', models.TextField(blank=True, null=True)), ('courseOnline', models.BooleanField(blank=True, default=False, null=True)), ('courseImage', models.FileField(blank=True, null=True, upload_to='images/')), ('courseLive', models.BooleanField(blank=True, default=False, null=True)), ('courseOffline', models.BooleanField(blank=True, default=False, null=True)), ('courseStatus', models.CharField(blank=True, choices=[('Active', 'Active'), ('Inactive', 'Inactive'), ('Available', 'Available')], max_length=30, null=True)), ('coursePrice', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), ('promocode', models.CharField(blank=True, max_length=160, null=True)), ('priceDiscount', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), ('totalPriceDiscount', models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True)), ('courseCity', models.CharField(blank=True, max_length=200, null=True)), ('courseState', models.CharField(blank=True, max_length=200, null=True)), ('courseCountry', models.CharField(blank=True, max_length=200, null=True)), ('offlineAddress', models.TextField(blank=True, null=True)), ('offlineClassStrength', models.IntegerField(blank=True, null=True)), ('offlineTiming', models.DateTimeField(blank=True, null=True)), ('offlineWeekday', multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('Monday', 'Monday'), ('Tuesday', 'Tuesday'), ('Wednesday', 'Wednesday'), ('Thursday', 'Thursday'), ('Friday', 'Friday'), ('Saturday', 'Saturday'), ('Sunday', 'Sunday')], max_length=56, null=True)), ('onlineWeekday', multiselectfield.db.fields.MultiSelectField(blank=True, choices=[('Monday', 'Monday'), ('Tuesday', 'Tuesday'), ('Wednesday', 'Wednesday'), ('Thursday', 'Thursday'), ('Friday', 'Friday'), ('Saturday', 'Saturday'), ('Sunday', 'Sunday')], max_length=56, null=True)), ('onlineTiming', models.DateTimeField(blank=True, null=True)), ('courseBelong', models.CharField(blank=True, choices=[('Trainer', 'Trainer'), ('Intitute', 'Institute'), ('Franchise', 'Franchise')], max_length=30, null=True)), ('seo_title', models.CharField(max_length=70)), ('seo_description', models.CharField(max_length=160)), ('seo_keywords', models.CharField(max_length=160)), ('slug', models.SlugField(max_length=255, unique=True)), ('introVideo', models.FileField(blank=True, null=True, upload_to='IntroVideos/')), ('courseCreated', models.DateTimeField(auto_now_add=True)), ('courseCategory', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='inventory.Categories')), ], options={ 'ordering': ['-courseCreated'], }, ), migrations.CreateModel( name='CourseVideos', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('courseVideoName', models.CharField(blank=True, max_length=500, null=True)), ('courseVideoFile', models.FileField(blank=True, null=True, upload_to='videos/')), ('courseVideoDescription', models.TextField(blank=True, null=True)), ('courseVideoCreated', models.DateTimeField(auto_now_add=True)), ('course', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='inventory.CourseDetails')), ], ), ]
class Migration(migrations.Migration): dependencies = [ ('articles', '0001_initial'), ] operations = [ migrations.CreateModel( name='Entry', fields=[ ('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)), ('registered_time', models.DateTimeField(auto_now_add=True)), ], options={ 'verbose_name': 'Anmälning', 'verbose_name_plural': 'Anmälningar', }, ), migrations.CreateModel( name='EntryDeadline', fields=[ ('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)), ('description_sv', models.TextField(verbose_name='beskrivning')), ('entry_from', models.DateTimeField(verbose_name='anmälningsstart')), ('entry_to', models.DateTimeField(verbose_name='anmälningsslut')), ('enable_unregistration', models.BooleanField(verbose_name='kan avanmäla sig')), ], options={ 'verbose_name': 'Anmälningsperiod', 'verbose_name_plural': 'Anmälningsperioder', }, ), migrations.CreateModel( name='Event', fields=[ ('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)), ('headline', models.CharField(verbose_name='rubrik', max_length=255)), ('lead', models.TextField(verbose_name='ingress')), ('body', models.TextField(verbose_name='brödtext')), ('visible_from', models.DateTimeField()), ('visible_to', models.DateTimeField()), ('approved', models.BooleanField(verbose_name='godkänd', default=False)), ('created', models.DateTimeField(editable=False)), ('modified', models.DateTimeField(editable=False)), ('start', models.DateTimeField(verbose_name='start')), ('end', models.DateTimeField(verbose_name='s**t')), ('enable_registration', models.BooleanField(verbose_name='kan anmäla sig')), ('registration_limit', models.IntegerField(verbose_name='max antal anmälningar')), ('tags', models.ManyToManyField(to='articles.Tag', verbose_name='tag', blank=True)), ], options={ 'verbose_name_plural': 'Arrangemanger', 'verbose_name': 'Arrangemang', 'permissions': (('can_approve_article', 'Can approve article'), ), }, ), ]
class Flag(BaseModel): """A feature flag. Flags are active (or not) on a per-request basis. """ name = models.CharField(max_length=100, unique=True, help_text='The human/computer readable name.') everyone = models.NullBooleanField(blank=True, help_text=( 'Flip this flag on (Yes) or off (No) for everyone, overriding all ' 'other settings. Leave as Unknown to use normally.')) percent = models.DecimalField(max_digits=3, decimal_places=1, null=True, blank=True, help_text=( 'A number between 0.0 and 99.9 to indicate a percentage of users for ' 'whom this flag will be active.')) testing = models.BooleanField(default=False, help_text=( 'Allow this flag to be set for a session for user testing.')) superusers = models.BooleanField(default=True, help_text=( 'Flag always active for superusers?')) staff = models.BooleanField(default=False, help_text=( 'Flag always active for staff?')) authenticated = models.BooleanField(default=False, help_text=( 'Flag always active for authenticate users?')) languages = models.TextField(blank=True, default='', help_text=( 'Activate this flag for users with one of these languages (comma ' 'separated list)')) groups = models.ManyToManyField(Group, blank=True, help_text=( 'Activate this flag for these user groups.')) users = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, help_text=('Activate this flag for these users.')) rollout = models.BooleanField(default=False, help_text=( 'Activate roll-out mode?')) note = models.TextField(blank=True, help_text=( 'Note where this Flag is used.')) created = models.DateTimeField(default=datetime.now, db_index=True, help_text=('Date when this Flag was created.')) modified = models.DateTimeField(default=datetime.now, help_text=( 'Date when this Flag was last modified.')) objects = managers.FlagManager() SINGLE_CACHE_KEY = 'FLAG_CACHE_KEY' ALL_CACHE_KEY = 'ALL_FLAGS_CACHE_KEY' def flush(self): keys = [ self._cache_key(self.name), keyfmt(get_setting('FLAG_USERS_CACHE_KEY'), self.name), keyfmt(get_setting('FLAG_GROUPS_CACHE_KEY'), self.name), get_setting('ALL_FLAGS_CACHE_KEY'), ] cache.delete_many(keys) def _get_user_ids(self): cache_key = keyfmt(get_setting('FLAG_USERS_CACHE_KEY'), self.name) cached = cache.get(cache_key) if cached == CACHE_EMPTY: return set() if cached: return cached user_ids = set(self.users.all().values_list('pk', flat=True)) if not user_ids: cache.add(cache_key, CACHE_EMPTY) return set() cache.add(cache_key, user_ids) return user_ids def _get_group_ids(self): cache_key = keyfmt(get_setting('FLAG_GROUPS_CACHE_KEY'), self.name) cached = cache.get(cache_key) if cached == CACHE_EMPTY: return set() if cached: return cached group_ids = set(self.groups.all().values_list('pk', flat=True)) if not group_ids: cache.add(cache_key, CACHE_EMPTY) return set() cache.add(cache_key, group_ids) return group_ids def is_active_for_user(self, user): authed = getattr(user, 'is_authenticated', lambda: False)() if self.authenticated and authed: return True if self.staff and getattr(user, 'is_staff', False): return True if self.superusers and getattr(user, 'is_superuser', False): return True user_ids = self._get_user_ids() if hasattr(user, 'pk') and user.pk in user_ids: return True if hasattr(user, 'groups'): group_ids = self._get_group_ids() user_groups = set(user.groups.all().values_list('pk', flat=True)) if group_ids.intersection(user_groups): return True return None def _is_active_for_user(self, request): return self.is_active_for_user(request.user) def _is_active_for_language(self, request): if self.languages: languages = [ln.strip() for ln in self.languages.split(',')] if (hasattr(request, 'LANGUAGE_CODE') and request.LANGUAGE_CODE in languages): return True return None def is_active(self, request): if not self.pk: return get_setting('FLAG_DEFAULT') if get_setting('OVERRIDE'): if self.name in request.GET: return request.GET[self.name] == '1' if self.everyone: return True elif self.everyone is False: return False if self.testing: # Testing mode is on. tc = get_setting('TEST_COOKIE') % self.name if tc in request.GET: on = request.GET[tc] == '1' if not hasattr(request, 'waffle_tests'): request.waffle_tests = {} request.waffle_tests[self.name] = on return on if tc in request.COOKIES: return request.COOKIES[tc] == 'True' active_for_language = self._is_active_for_language(request) if active_for_language is not None: return active_for_language active_for_user = self._is_active_for_user(request) if active_for_user is not None: return active_for_user if self.percent and self.percent > 0: if not hasattr(request, 'waffles'): request.waffles = {} elif self.name in request.waffles: return request.waffles[self.name][0] cookie = get_setting('COOKIE') % self.name if cookie in request.COOKIES: flag_active = (request.COOKIES[cookie] == 'True') set_flag(request, self.name, flag_active, self.rollout) return flag_active if Decimal(str(random.uniform(0, 100))) <= self.percent: set_flag(request, self.name, True, self.rollout) return True set_flag(request, self.name, False, self.rollout) return False
class ProjectEventLog(models.Model): event = models.ForeignKey(ProjectEvent, on_delete=models.CASCADE) updated = models.DateField(auto_now_add=True, editable=False) progress = models.FloatField() start = models.DateTimeField() end = models.DateTimeField()
class Review(models.Model): play_store_review_id = models.CharField(max_length=255, unique=True) android_sdk_version = models.PositiveSmallIntegerField(blank=True, null=True) author_name = models.CharField(max_length=255) application = models.ForeignKey( "applications.Application", models.PROTECT, related_name="+" ) application_version = models.ForeignKey( "applications.ApplicationVersion", models.PROTECT, null=True, blank=True, related_name="+", ) review_text = models.TextField() review_language = models.CharField(max_length=30, blank=True) review_rating = models.SmallIntegerField(choices=REVIEW_RATING_CHOICES) # last modification in Playstore last_modified = models.DateTimeField() created_on = models.DateTimeField(blank=True, null=True) updated_on = models.DateTimeField(auto_now=True, null=True) assigned_to = models.OneToOneField( settings.AUTH_USER_MODEL, models.PROTECT, related_name="+", null=True, blank=True, ) assigned_to_user_at = models.DateTimeField(blank=True, null=True) objects = reviews_query.ReviewQuerySet.as_manager() class Meta: ordering = ["-created_on"] def __str__(self): return _("Review %(review_id)s by %(review_author)s") % { "review_id": self.play_store_review_id, "review_author": self.author_name, } @property def android_version(self): return android_utils.get_human_readable_android_version( self.android_sdk_version ) @property def assignment_expires_at(self): if self.assigned_to_user_at: return self.assigned_to_user_at + reviews_query.ASSIGNMENT_TIMEOUT return @transaction.atomic() def assign_to_user(self, user): # If assignment of the other reviews to the user expired, return # them to the queue to avoid raising IntegrityError. # This method should not be called if other reviews are not expired. for r in Review.objects.filter(assigned_to=user).assignment_expired(): r.return_to_the_queue() # Assign this review to the user. self.assigned_to = user self.assigned_to_user_at = timezone.now() self.save(update_fields=("assigned_to", "assigned_to_user_at")) def return_to_the_queue(self): self.assigned_to = None self.assigned_to_user_at = None self.save(update_fields=("assigned_to", "assigned_to_user_at"))
class Migration(migrations.Migration): dependencies = [ ('evaluation', '0001_initial'), ] operations = [ migrations.CreateModel( name='Epworth', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('last_update', models.DateTimeField(auto_now=True, verbose_name='Last update')), ('date', models.DateTimeField(auto_now_add=True, verbose_name='Date')), ('obs', models.TextField(max_length=500, null=True, blank=True)), ('sitting_reading', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('watching_tv', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('sitting_inactive_public', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('car_passenger', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('lying_down', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('sitting_talking', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('sitting_quietly_lunch', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('car_traffic', models.IntegerField(verbose_name='Sitting and reading', choices=[(0, 'would never doze'), (1, 'slight chance of dozing'), (2, 'moderate chance of dozing'), (3, 'high chance of dozing')])), ('patient', models.ForeignKey(verbose_name='Patient', to='evaluation.Patient')), ('period', models.ForeignKey(verbose_name='Period', to='evaluation.Period')), ], options={ 'verbose_name': 'Epworth Sleepiness', 'verbose_name_plural': 'Epwort Sleepiness', }, ), ]
class Gathering(TimeStampedModel, SoftDeletableModel, Utility): notes = GenericRelation(Note) id = models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') meet = models.ForeignKey('Meet', on_delete=models.SET(0), null=False, blank=False) start = models.DateTimeField(null=False, blank=False) finish = models.DateTimeField( null=False, blank=False, help_text="Required for user to filter by time") attendings = models.ManyToManyField('persons.Attending', through='Attendance') display_name = models.CharField(max_length=50, blank=True, null=True, help_text="02/09/2020, etc") infos = JSONField( null=True, blank=True, default=dict, help_text= 'Example: {"LG_location": "F207", "link": "https://..."}. Please keep {} here even no data' ) occurrence = models.ForeignKey(Occurrence, blank=True, null=True, on_delete=models.SET_NULL) site_type = models.ForeignKey( ContentType, on_delete=models.SET(0), help_text='location: django_content_type id for table name') site_id = models.BigIntegerField() location = GenericForeignKey('site_type', 'site_id') # from itertools import groupby # from operator import attrgetter # # ordered_program_sessions = ProgramSession.objects.order_by('program_group', 'start_at') # program_sessions_grouped_by_program_groups = { # k: list(v) # for k, v in groupby(ordered_program_sessions, attrgetter('program_group')) # } #=> {<ProgramGroup: The Rock >: [<ProgramSession: The Rock #1...>, <ProgramSession: The Rock #2...>]} def get_absolute_url(self): return reverse('gathering_detail', args=[str(self.id)]) @property def gathering_label(self): return (self.meet.display_name or '') + ' ' + (self.display_name or '') class Meta: db_table = 'occasions_gatherings' ordering = ['meet', 'start'] constraints = [ models.UniqueConstraint( fields=['meet_id', 'site_type_id', 'site_id', 'start'], name='uniq_meet_location_time') ] def __str__(self): return '%s %s %s %s' % (self.meet, self.start, self.display_name or '', self.location or '')
class WdaeUser(AbstractBaseUser, PermissionsMixin): app_label = "api" name = models.CharField(max_length=100) email = models.EmailField(unique=True) is_staff = models.BooleanField(default=False) is_active = models.BooleanField(default=False) date_joined = models.DateTimeField(null=True) USERNAME_FIELD = "email" REQUIRED_FIELDS = ["name"] DEFAULT_GROUPS_FOR_USER = ("any_user", ) SUPERUSER_GROUP = "admin" UMLIMITTED_DOWNLOAD_GROUP = "unlimitted" objects = WdaeUserManager() def get_protected_group_names(self): return self.DEFAULT_GROUPS_FOR_USER + (self.email, ) @property def protected_groups(self): return self.groups.filter(name__in=self.get_protected_group_names()) @property def has_unlimitted_download(self): return (self.groups.filter( name=self.UMLIMITTED_DOWNLOAD_GROUP).count() > 0) @property def allowed_datasets(self): return get_directly_allowed_genotype_data(self) def email_user(self, subject, message, from_email=None): if from_email is None: from_email = settings.DEFAULT_FROM_EMAIL override = None try: override = settings.EMAIL_OVERRIDE except Exception: LOGGER.debug("no email override; sending email") override = None if override: to_email = override else: to_email = self.email mail = send_mail(subject, message, from_email, [to_email]) LOGGER.info("email sent: to: <" + str(self.email) + ">") LOGGER.info("email sent: from: <" + str(from_email) + ">") LOGGER.info("email sent: subject: " + str(subject)) LOGGER.info("email sent: message: " + str(message)) return mail def get_full_name(self): return self.name def get_short_name(self): "Returns the short name for the user." return self.name def set_password(self, raw_password): super(WdaeUser, self).set_password(raw_password) has_password = bool(raw_password) if self.is_active != has_password: self.is_active = has_password def set_unusable_password(self): super(WdaeUser, self).set_unusable_password() if self.is_active: self.is_active = False def reset_password(self, by_admin=False): verif_path = _create_verif_path(self) send_reset_email(self, verif_path, by_admin) def deauthenticate(self): all_sessions = Session.objects.all() for session in all_sessions: session_data = session.get_decoded() if self.pk == session_data.get("_auth_user_id"): session.delete() def register_preexisting_user(self, name): if self.is_active: send_already_existing_email(self) else: self.date_joined = timezone.now() if name is not None and name != "": self.name = name verif_path = _create_verif_path(self) send_verif_email(self, verif_path) self.save() @staticmethod def change_password(verification_path, new_password): verif_path = VerificationPath.objects.get(path=verification_path) user = verif_path.user user.set_password(new_password) user.save() # Reset account lockout AuthenticationLog(email=user.email, time=timezone.now(), failed_attempt=0).save() verif_path.delete() return user def __str__(self): return self.email class Meta(object): db_table = "users"
class Product(models.Model): site = models.ForeignKey(Site, default=None, related_name='products', verbose_name='关联的站点') item_number = models.CharField(max_length=100, default='', db_index=True, blank=True, verbose_name='商品编号') name = models.CharField(max_length=100, default='', db_index=True, verbose_name='商品名称') type = models.CharField(max_length=20, default='B2B+B2C', verbose_name='商品类型') click_count = models.IntegerField(default=0, verbose_name='浏览次数') quantity = models.IntegerField(default=0, verbose_name='库存数量') warn_quantity = models.IntegerField(default=0, verbose_name='预警库存') price = models.FloatField(default=0.0, verbose_name='基准价格') market_price = models.FloatField(default=0.0, verbose_name='市场价') page_title = models.CharField(max_length=100, blank=True, default='', verbose_name='网页标题') keywords = models.CharField(max_length=254, default='', blank=True, verbose_name='关键字') short_desc = models.CharField(max_length=1024, default='', blank=True, verbose_name='简略描述') seo_desc = models.CharField(max_length=1024, default='', blank=True, verbose_name='SEO描述') description = models.TextField(blank=True, verbose_name='详细描述') youtube = models.CharField(max_length=1024, default='', blank=True, verbose_name='youtube视频地址') is_free_shipping = models.BooleanField(default=False, verbose_name='是否包邮') sort_order = models.IntegerField(default=0, verbose_name='排序序号') static_file_name = models.CharField(max_length=254, default=None, null=True, db_index=True, blank=True, verbose_name='静态文件名(不包含路径,以html结尾)') categorys = models.ManyToManyField(Category, verbose_name='商品分类', related_name="products") min_order_quantity = models.IntegerField(default=0, verbose_name='最小下单数量') is_publish = models.BooleanField(default=False, verbose_name='上架') detail_template = models.CharField(max_length=254, default='', blank=True, verbose_name='详情页指定模板') related_products = models.ManyToManyField('self', null=True, blank=True, related_name='parent_product', verbose_name='关联商品') weight = models.FloatField(default=0.0, verbose_name='重量,克') cuboid_long = models.FloatField(default=0.0, verbose_name='体积_长_毫米') cuboid_width = models.FloatField(default=0.0, verbose_name='体积_宽_毫米') cuboid_height = models.FloatField(default=0.0, verbose_name='体积_高_毫米') create_time = models.DateTimeField(auto_now_add=True) update_time = models.DateTimeField(auto_now=True) def get_related_products(self): return self.related_products.all() def get_one_category(self): list = self.categorys.all() if len(list) > 0: return list[0] else: return None def get_main_image(self): return self.get_images(method='single') def get_main_image_list(self): return self.get_images(method='main') def get_main_image_list_attachment(self): image_list = Album.objects.filter(item_type='attachment', item_id=self.id) image_list = list(image_list) logger.debug("获取到的list:%s" % image_list) return image_list def get_main_image_list_attachment_pdf(self): image_list = Album.objects.filter(item_type='attachment', item_id=self.id) image_list = list(image_list) new_images_list = [] # 允许上传的类型 file_allow = ['PDF'] logger.debug("获取到的list:%s" % image_list) for img in image_list: ext = img.image.split('.')[-1] logger.debug(str(ext)) if ext.upper() not in file_allow: logger.info(image_list) else: new_images_list.append(img) logger.info(img.image) return new_images_list def get_main_image_list_attachment_rar(self): image_list = Album.objects.filter(item_type='attachment', item_id=self.id) image_list = list(image_list) new_images_list = [] # 允许上传的类型 file_allow = ['RAR', 'ZIP'] logger.debug("获取到的list:%s" % image_list) for img in image_list: ext = img.image.split('.')[-1] logger.debug(str(ext)) if ext.upper() not in file_allow: logger.info(image_list) else: new_images_list.append(img) logger.info(img.image) return new_images_list def get_all_image_list(self): return self.get_images(method='all') def get_images(self, method, sort_by='sort_order'): image_list = self.images.all() if method == 'main': image_list = image_list.filter(is_show_in_product_detail=True) if sort_by == 'sort_order': image_list = sorted(image_list, key=lambda image: image.sort, reverse=True) elif sort_by == 'create_time': image_list = sorted(image_list, key=lambda image: image.create_time, reverse=True) main_image_url = self.image main_image = None for img in image_list: if img.image == main_image_url: logger.debug('Find the main image. Remove it to top.') main_image = img break # logger.debug('main_img:%s alt:%s' % (main_image,main_image.alt_value)) if main_image: image_list.remove(main_image) image_list.insert(0, main_image) if method == 'single': if len(image_list) > 0: return image_list[0] else: return None else: return image_list def get_attributes(self): pa_list = self.attributes.all() attribute_list = Attribute.objects.filter(product_attribute__in=pa_list).distinct() attribute_group_list = list(set([attr.group for attr in attribute_list])) # 用set去重后,再转回list attribute_group_list.sort(key=lambda x: x.position) # 利用position字段排序 for ag in attribute_group_list: ag.attr_list = [attr for attr in attribute_list if attr.group == ag] ag.attr_list.sort(key=lambda x: x.position) return attribute_group_list def get_product_detail_images(self): return self.images.filter(is_show_in_product_detail=True).order_by('sort') def get_url(self): from shopcart.functions.product_util_func import get_url return get_url(self) def get_stere(self, unit=None): stere_cm = self.cuboid_long * self.cuboid_width * self.cuboid_height if unit == None or unit == 'm': # 换算成立方米 return stere_cm / (1000 * 1000 * 1000) else: return stere_cm def get_weight(self, unit=None): if unit == None or unit == 'kg': # 换算成千克 return self.weight / 1000 else: return self.weight def get_min_price(self): return self.get_price_for_show('min') def get_max_price(self): return self.get_price_for_show('max') def get_price(self): return self.get_price_for_show('min-max') def has_price_range(self): if self.get_max_price() - self.get_min_price() > 0.01: return True else: return False def get_price_for_show(self, method='min'): price_min = 0.0 price_max = 0.0 price_list = [] if self.prices.all().count() > 0: for p in self.prices.all(): if p.price > 0: price_list.append(p.price) if len(price_list) > 0: price_min = min(price_list) price_max = max(price_list) else: price_min = self.price price_max = self.price else: price_min = self.price price_max = self.price if method == 'min': return price_min elif method == 'max': return price_max elif method == 'min-max': if price_max - price_min > 0.01: return '%s - %s' % (price_min, price_max) else: return price_max else: return price_min def __str__(self): return self.name class Meta: verbose_name = '商品' verbose_name_plural = '商品'
class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='MetadataFormat', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('identifier', models.CharField(help_text="Name of format. Also known as the 'metadata prefix'", max_length=1024)), ('namespace', models.CharField(help_text='XML namespace of format', max_length=1024)), ('schema', models.URLField(help_text='XML schema of format')), ('created_at', models.DateTimeField(auto_now_add=True, help_text='Creation time')), ('updated_at', models.DateTimeField(auto_now=True, help_text='Last update time')), ], ), migrations.CreateModel( name='Record', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('identifier', models.CharField(help_text='Unique identifier for this record within the repository', max_length=1024)), ('datestamp', models.DateTimeField(help_text='Datestamp of record as returned from repository')), ('xml', models.TextField(help_text='Raw record XML as returned by repository')), ('harvested_at', models.DateTimeField(help_text='When this record was last harvested from the repository')), ('created_at', models.DateTimeField(auto_now_add=True, help_text='Creation time')), ('updated_at', models.DateTimeField(auto_now=True, help_text='Last update time')), ('metadata_format', models.ForeignKey(help_text='Metadata prefix for this record', on_delete=django.db.models.deletion.CASCADE, related_name='records', to='oaipmh.MetadataFormat')), ], ), migrations.CreateModel( name='Repository', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('url', models.URLField(help_text='Endpoint URL for repository')), ('basic_auth_user', models.CharField(blank=True, help_text='Username for basic auth. If blank, no basic auth is performed.', max_length=255)), ('basic_auth_password', models.CharField(blank=True, help_text='Password for basic auth. Only used if basic_auth_user is not blank.', max_length=255)), ('last_harvested_at', models.DateTimeField(blank=True, default=None, help_text='Date and time the last harvest was performed.', null=True)), ('created_at', models.DateTimeField(auto_now_add=True, help_text='Creation time')), ('updated_at', models.DateTimeField(auto_now=True, help_text='Last update time')), ], options={ 'verbose_name_plural': 'Repositories', }, ), migrations.AddField( model_name='metadataformat', name='repository', field=models.ForeignKey(help_text='Repository these metadata formats apply to', on_delete=django.db.models.deletion.CASCADE, related_name='metadata_formats', to='oaipmh.Repository'), ), migrations.AlterUniqueTogether( name='record', unique_together={('identifier', 'metadata_format', 'datestamp')}, ), migrations.AlterUniqueTogether( name='metadataformat', unique_together={('repository', 'identifier')}, ), ]
class Tags(models.Model): name = models.CharField(max_length=20) create_time = models.DateTimeField(auto_now_add=True) def __unicode__(self): return u'%s' % (self.name)
class Migration(migrations.Migration): dependencies = [ ('usuarios', '0003_auto_20210128_1725'), ] operations = [ migrations.AlterModelOptions( name='usuario', options={}, ), migrations.AddField( model_name='usuario', name='city', field=models.CharField(blank=True, max_length=50), ), migrations.AddField( model_name='usuario', name='date_of_birth', field=models.DateField(blank=True, null=True, verbose_name='date of birth'), ), migrations.AddField( model_name='usuario', name='is_admin', field=models.BooleanField(default=False), ), migrations.AlterField( model_name='usuario', name='date_joined', field=models.DateTimeField(auto_now_add=True, verbose_name='date_joined'), ), migrations.AlterField( model_name='usuario', name='email', field=models.EmailField(max_length=60, unique=True, verbose_name='email address'), ), migrations.AlterField( model_name='usuario', name='first_name', field=models.CharField(blank=True, max_length=30), ), migrations.AlterField( model_name='usuario', name='is_active', field=models.BooleanField(default=False), ), migrations.AlterField( model_name='usuario', name='is_staff', field=models.BooleanField(default=False), ), migrations.AlterField( model_name='usuario', name='is_superuser', field=models.BooleanField(default=False), ), migrations.AlterField( model_name='usuario', name='last_login', field=models.DateTimeField(auto_now=True, verbose_name='last login'), ), migrations.AlterField( model_name='usuario', name='last_name', field=models.CharField(blank=True, max_length=30), ), migrations.AlterField( model_name='usuario', name='username', field=models.CharField(max_length=30, unique=True), ), ]
class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('module', '0001_initial'), ] operations = [ migrations.CreateModel( name='UserAssessment', fields=[ ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('created_on', models.DateTimeField(auto_now_add=True, null=True)), ('modified_on', models.DateTimeField(auto_now=True, null=True)), ('title', models.CharField(max_length=255)), ('instructions', models.TextField()), ('created_by', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='module_userassessment_created_by_related', to=settings.AUTH_USER_MODEL)), ('modified_by', models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='module_userassessment_modified_by_related', to=settings.AUTH_USER_MODEL)), ], options={ 'ordering': ['-created_on'], }, ), migrations.AlterModelOptions( name='module', options={ 'ordering': ['order'], 'verbose_name_plural': 'Modules' }, ), migrations.AddField( model_name='module', name='has_user_assessment', field=models.BooleanField(default=False), ), migrations.AddField( model_name='module', name='user_assessment', field=models.ForeignKey( null=True, on_delete=django.db.models.deletion.CASCADE, to='module.UserAssessment'), ), ]
class ResourceBase(PolymorphicModel, PermissionLevelMixin): """ Base Resource Object loosely based on ISO 19115:2003 """ VALID_DATE_TYPES = [(x.lower(), _(x)) for x in ['Creation', 'Publication', 'Revision']] date_help_text = _('reference date for the cited resource') date_type_help_text = _('identification of when a given event occurred') edition_help_text = _('version of the cited resource') abstract_help_text = _( 'brief narrative summary of the content of the resource(s)') purpose_help_text = _( 'summary of the intentions with which the resource(s) was developed') maintenance_frequency_help_text = _( 'frequency with which modifications and deletions are made to the data after ' 'it is first produced') keywords_help_text = _( 'commonly used word(s) or formalised word(s) or phrase(s) used to describe the subject ' '(space or comma-separated') regions_help_text = _('keyword identifies a location') restriction_code_type_help_text = _( 'limitation(s) placed upon the access or use of the data.') constraints_other_help_text = _( 'other restrictions and legal prerequisites for accessing and using the resource or' ' metadata') license_help_text = _('license of the dataset') language_help_text = _('language used within the dataset') category_help_text = _( 'high-level geographic data thematic classification to assist in the grouping and search of ' 'available geographic data sets.') spatial_representation_type_help_text = _( 'method used to represent geographic information in the dataset.') temporal_extent_start_help_text = _( 'time period covered by the content of the dataset (start)') temporal_extent_end_help_text = _( 'time period covered by the content of the dataset (end)') distribution_url_help_text = _( 'information about on-line sources from which the dataset, specification, or ' 'community profile name and extended metadata elements can be obtained' ) distribution_description_help_text = _( 'detailed text description of what the online resource is/does') data_quality_statement_help_text = _( 'general explanation of the data producer\'s knowledge about the lineage of a' ' dataset') # internal fields uuid = models.CharField(max_length=36) owner = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True, related_name='owned_resource', verbose_name=_("Owner")) contacts = models.ManyToManyField(settings.AUTH_USER_MODEL, through='ContactRole') title = models.CharField( _('title'), max_length=255, help_text=_('name by which the cited resource is known')) date = models.DateTimeField(_('date'), default=datetime.datetime.now, help_text=date_help_text) date_type = models.CharField(_('date type'), max_length=255, choices=VALID_DATE_TYPES, default='publication', help_text=date_type_help_text) edition = models.CharField(_('edition'), max_length=255, blank=True, null=True, help_text=edition_help_text) abstract = models.TextField(_('abstract'), blank=True, help_text=abstract_help_text) purpose = models.TextField(_('purpose'), null=True, blank=True, help_text=purpose_help_text) maintenance_frequency = models.CharField( _('maintenance frequency'), max_length=255, choices=UPDATE_FREQUENCIES, blank=True, null=True, help_text=maintenance_frequency_help_text) keywords = TaggableManager(_('keywords'), blank=True, help_text=keywords_help_text) regions = models.ManyToManyField(Region, verbose_name=_('keywords region'), blank=True, null=True, help_text=regions_help_text) restriction_code_type = models.ForeignKey( RestrictionCodeType, verbose_name=_('restrictions'), help_text=restriction_code_type_help_text, null=True, blank=True, limit_choices_to=Q(is_choice=True)) constraints_other = models.TextField(_('restrictions other'), blank=True, null=True, help_text=constraints_other_help_text) license = models.ForeignKey(License, null=True, blank=True, verbose_name=_("License"), help_text=license_help_text) language = models.CharField(_('language'), max_length=3, choices=ALL_LANGUAGES, default='eng', help_text=language_help_text) category = models.ForeignKey(TopicCategory, null=True, blank=True, limit_choices_to=Q(is_choice=True), help_text=category_help_text) spatial_representation_type = models.ForeignKey( SpatialRepresentationType, null=True, blank=True, limit_choices_to=Q(is_choice=True), verbose_name=_("spatial representation type"), help_text=spatial_representation_type_help_text) # Section 5 temporal_extent_start = models.DateTimeField( _('temporal extent start'), blank=True, null=True, help_text=temporal_extent_start_help_text) temporal_extent_end = models.DateTimeField( _('temporal extent end'), blank=True, null=True, help_text=temporal_extent_end_help_text) supplemental_information = models.TextField( _('supplemental information'), default=DEFAULT_SUPPLEMENTAL_INFORMATION, help_text=_('any other descriptive information about the dataset')) # Section 6 distribution_url = models.TextField(_('distribution URL'), blank=True, null=True, help_text=distribution_url_help_text) distribution_description = models.TextField( _('distribution description'), blank=True, null=True, help_text=distribution_description_help_text) # Section 8 data_quality_statement = models.TextField( _('data quality statement'), blank=True, null=True, help_text=data_quality_statement_help_text) # Section 9 # see metadata_author property definition below # Save bbox values in the database. # This is useful for spatial searches and for generating thumbnail images and metadata records. bbox_x0 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) bbox_x1 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) bbox_y0 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) bbox_y1 = models.DecimalField(max_digits=19, decimal_places=10, blank=True, null=True) srid = models.CharField(max_length=255, default='EPSG:4326') # CSW specific fields csw_typename = models.CharField(_('CSW typename'), max_length=32, default='gmd:MD_Metadata', null=False) csw_schema = models.CharField(_('CSW schema'), max_length=64, default='http://www.isotc211.org/2005/gmd', null=False) csw_mdsource = models.CharField(_('CSW source'), max_length=256, default='local', null=False) csw_insert_date = models.DateTimeField(_('CSW insert date'), auto_now_add=True, null=True) csw_type = models.CharField(_('CSW type'), max_length=32, default='dataset', null=False, choices=HIERARCHY_LEVELS) csw_anytext = models.TextField(_('CSW anytext'), null=True, blank=True) csw_wkt_geometry = models.TextField( _('CSW WKT geometry'), null=False, default='POLYGON((-180 -90,-180 90,180 90,180 -90,-180 -90))') # metadata XML specific fields metadata_uploaded = models.BooleanField(default=False) metadata_xml = models.TextField( null=True, default= '<gmd:MD_Metadata xmlns:gmd="http://www.isotc211.org/2005/gmd"/>', blank=True) popular_count = models.IntegerField(default=0) share_count = models.IntegerField(default=0) featured = models.BooleanField( _("Featured"), default=False, help_text=_('Should this resource be advertised in home page?')) is_published = models.BooleanField( _("Is Published"), default=True, help_text=_('Should this resource be published and searchable?')) # fields necessary for the apis thumbnail_url = models.TextField(null=True, blank=True) detail_url = models.CharField(max_length=255, null=True, blank=True) rating = models.IntegerField(default=0, null=True, blank=True) def __unicode__(self): return self.title @property def bbox(self): return [ self.bbox_x0, self.bbox_y0, self.bbox_x1, self.bbox_y1, self.srid ] @property def bbox_string(self): return ",".join([ str(self.bbox_x0), str(self.bbox_y0), str(self.bbox_x1), str(self.bbox_y1) ]) @property def geographic_bounding_box(self): return bbox_to_wkt(self.bbox_x0, self.bbox_x1, self.bbox_y0, self.bbox_y1, srid=self.srid) @property def license_light(self): a = [] if (not (self.license.name is None)) and (len(self.license.name) > 0): a.append(self.license.name) if (not (self.license.url is None)) and (len(self.license.url) > 0): a.append("(" + self.license.url + ")") return " ".join(a) @property def license_verbose(self): a = [] if (not (self.license.name_long is None)) and (len( self.license.name_long) > 0): a.append(self.license.name_long + ":") if (not (self.license.description is None)) and (len( self.license.description) > 0): a.append(self.license.description) if (not (self.license.url is None)) and (len(self.license.url) > 0): a.append("(" + self.license.url + ")") return " ".join(a) def keyword_list(self): return [kw.name for kw in self.keywords.all()] def keyword_slug_list(self): return [kw.slug for kw in self.keywords.all()] def region_name_list(self): return [region.name for region in self.regions.all()] def spatial_representation_type_string(self): if hasattr(self.spatial_representation_type, 'identifier'): return self.spatial_representation_type.identifier else: if hasattr(self, 'storeType'): if self.storeType == 'coverageStore': return 'grid' return 'vector' else: return None @property def keyword_csv(self): keywords_qs = self.get_real_instance().keywords.all() if keywords_qs: return ','.join([kw.name for kw in keywords_qs]) else: return '' def set_latlon_bounds(self, box): """ Set the four bounds in lat lon projection """ self.bbox_x0 = box[0] self.bbox_x1 = box[1] self.bbox_y0 = box[2] self.bbox_y1 = box[3] def set_bounds_from_center_and_zoom(self, center_x, center_y, zoom): """ Calculate zoom level and center coordinates in mercator. """ self.center_x = center_x self.center_y = center_y self.zoom = zoom deg_len_equator = 40075160 / 360 # covert center in lat lon def get_lon_lat(): wgs84 = Proj(init='epsg:4326') mercator = Proj(init='epsg:3857') lon, lat = transform(mercator, wgs84, center_x, center_y) return lon, lat # calculate the degree length at this latitude def deg_len(): lon, lat = get_lon_lat() return math.cos(lat) * deg_len_equator lon, lat = get_lon_lat() # taken from http://wiki.openstreetmap.org/wiki/Zoom_levels # it might be not precise but enough for the purpose distance_per_pixel = 40075160 * math.cos(lat) / 2**(zoom + 8) # calculate the distance from the center of the map in degrees # we use the calculated degree length on the x axis and the # normal degree length on the y axis assumin that it does not change # Assuming a map of 1000 px of width and 700 px of height distance_x_degrees = distance_per_pixel * 500 / deg_len() distance_y_degrees = distance_per_pixel * 350 / deg_len_equator self.bbox_x0 = lon - distance_x_degrees self.bbox_x1 = lon + distance_x_degrees self.bbox_y0 = lat - distance_y_degrees self.bbox_y1 = lat + distance_y_degrees def set_bounds_from_bbox(self, bbox): """ Calculate zoom level and center coordinates in mercator. """ self.set_latlon_bounds(bbox) minx, miny, maxx, maxy = [float(c) for c in bbox] x = (minx + maxx) / 2 y = (miny + maxy) / 2 (center_x, center_y) = forward_mercator((x, y)) xdiff = maxx - minx ydiff = maxy - miny zoom = 0 if xdiff > 0 and ydiff > 0: width_zoom = math.log(360 / xdiff, 2) height_zoom = math.log(360 / ydiff, 2) zoom = math.ceil(min(width_zoom, height_zoom)) self.zoom = zoom self.center_x = center_x self.center_y = center_y def download_links(self): """assemble download links for pycsw""" links = [] for url in self.link_set.all(): if url.link_type == 'metadata': # avoid recursion continue if url.link_type == 'html': links.append((self.title, 'Web address (URL)', 'WWW:LINK-1.0-http--link', url.url)) elif url.link_type in ('OGC:WMS', 'OGC:WFS', 'OGC:WCS'): links.append((self.title, url.name, url.link_type, url.url)) else: description = '%s (%s Format)' % (self.title, url.name) links.append((self.title, description, 'WWW:DOWNLOAD-1.0-http--download', url.url)) return links def get_tiles_url(self): """Return URL for Z/Y/X mapping clients or None if it does not exist. """ try: tiles_link = self.link_set.get(name='Tiles') except Link.DoesNotExist: return None else: return tiles_link.url def get_legend(self): """Return Link for legend or None if it does not exist. """ try: legends_link = self.link_set.get(name='Legend') except Link.DoesNotExist: return None else: return legends_link def get_legend_url(self): """Return URL for legend or None if it does not exist. The legend can be either an image (for Geoserver's WMS) or a JSON object for ArcGIS. """ legend = self.get_legend() if legend is None: return None return legend.url def get_ows_url(self): """Return URL for OGC WMS server None if it does not exist. """ try: ows_link = self.link_set.get(name='OGC:WMS') except Link.DoesNotExist: return None else: return ows_link.url def get_thumbnail_url(self): """Return a thumbnail url. It could be a local one if it exists, a remote one (WMS GetImage) for example or a 'Missing Thumbnail' one. """ local_thumbnails = self.link_set.filter(name='Thumbnail') if local_thumbnails.count() > 0: return local_thumbnails[0].url remote_thumbnails = self.link_set.filter(name='Remote Thumbnail') if remote_thumbnails.count() > 0: return remote_thumbnails[0].url return staticfiles.static(settings.MISSING_THUMBNAIL) def has_thumbnail(self): """Determine if the thumbnail object exists and an image exists""" return self.link_set.filter(name='Thumbnail').exists() def save_thumbnail(self, filename, image): thumb_folder = 'thumbs' upload_path = os.path.join(settings.MEDIA_ROOT, thumb_folder) if not os.path.exists(upload_path): os.makedirs(upload_path) #with open(os.path.join(upload_path, filename), 'w') as f: with os.fdopen( os.open(os.path.join(upload_path, filename), os.O_WRONLY | os.O_CREAT, settings.THUMBNAIL_FILE_PERMISSIONS), 'w') as f: thumbnail = File(f) thumbnail.write(image) url_path = os.path.join(settings.MEDIA_URL, thumb_folder, filename).replace('\\', '/') url = urljoin(settings.SITEURL, url_path) Link.objects.get_or_create(resource=self, url=url, defaults=dict( name='Thumbnail', extension='png', mime='image/png', link_type='image', )) ResourceBase.objects.filter(id=self.id).update(thumbnail_url=url) def set_missing_info(self): """Set default permissions and point of contacts. It is mandatory to call it from descendant classes but hard to enforce technically via signals or save overriding. """ from guardian.models import UserObjectPermission logger.debug('Checking for permissions.') # True if every key in the get_all_level_info dict is empty. no_custom_permissions = UserObjectPermission.objects.filter( content_type=ContentType.objects.get_for_model( self.get_self_resource()), object_pk=str(self.pk)).exists() if not no_custom_permissions: logger.debug( 'There are no permissions for this object, setting default perms.' ) self.set_default_permissions() if self.owner: user = self.owner else: user = ResourceBase.objects.admin_contact().user if self.poc is None: self.poc = user if self.metadata_author is None: self.metadata_author = user def maintenance_frequency_title(self): return [ v for i, v in enumerate(UPDATE_FREQUENCIES) if v[0] == self.maintenance_frequency ][0][1].title() def language_title(self): return [ v for i, v in enumerate(ALL_LANGUAGES) if v[0] == self.language ][0][1].title() def _set_poc(self, poc): # reset any poc assignation to this resource ContactRole.objects.filter(role='pointOfContact', resource=self).delete() # create the new assignation ContactRole.objects.create(role='pointOfContact', resource=self, contact=poc) def _get_poc(self): try: the_poc = ContactRole.objects.get(role='pointOfContact', resource=self).contact except ContactRole.DoesNotExist: the_poc = None return the_poc poc = property(_get_poc, _set_poc) def _set_metadata_author(self, metadata_author): # reset any metadata_author assignation to this resource ContactRole.objects.filter(role='author', resource=self).delete() # create the new assignation ContactRole.objects.create(role='author', resource=self, contact=metadata_author) def _get_metadata_author(self): try: the_ma = ContactRole.objects.get(role='author', resource=self).contact except ContactRole.DoesNotExist: the_ma = None return the_ma metadata_author = property(_get_metadata_author, _set_metadata_author) objects = ResourceBaseManager() class Meta: # custom permissions, # add, change and delete are standard in django-guardian permissions = ( ('view_resourcebase', 'Can view resource'), ('change_resourcebase_permissions', 'Can change resource permissions'), ('download_resourcebase', 'Can download resource'), ('publish_resourcebase', 'Can publish resource'), ('change_resourcebase_metadata', 'Can change resource metadata'), )
class Product(models.Model): ''' Stores everything having to do with a product. Products are added in the front end and all appropriate fields are populated in the backend. Populated fields that are required by Elasticsearch are also passed to the search index automatically by models.Article. Fields and data structures: price: not used anymore (we don't list pricing on the site) key_specs: We'll display a maximum of eight product specs; added to ES search index key_specs = first spec \n second spec \n ... eighth spec image_alt_tag: the tag given to the image and embedded in the page html ''' HELP_TEXT_NAME = ''' The name of the product is the official title of the article.<br/> It is permanently slugified and cannot be changed since it <br/> becomes part of the canonical url of this product. Make <br/> it concise and SEO-friendly. ''' HELP_TEXT_SPECS = '''Separate key specs with a semicolon (;). Max 8 specs.''' title = models.CharField(max_length=60, blank=False, null=True) product_name = models.CharField(max_length=60, blank=True, null=True, unique=True, help_text=HELP_TEXT_NAME) # ES indexable image = models.ImageField(upload_to=helper.UniquePath('images'), blank=True, null=True) image_alt_tag = models.CharField(max_length=256, blank=True, null=True) product_taxonomy = TreeForeignKey('taxonomy.ProductTaxonomy', null=True) # ES indexable, snowball product_domain = models.ForeignKey('ml.TrainingDomain', null=True) # ES indexable, snowball base_slug = models.SlugField(max_length=256, blank=True, null=True, editable=False) slug = models.SlugField(max_length=256, blank=True, null=True, unique=True, editable=False) # ES indexable, snowball # price = JSONField(blank=True, null=True) key_specs = models.TextField( blank=False, null=True, help_text=HELP_TEXT_SPECS) # ES indexable, snowball frsku = models.CharField(max_length=32, blank=True, null=True) model_num = models.CharField(max_length=256, blank=False, null=True) # ES indexable, Keyword # TODO: these are only test fields for faceting and filtering brand = models.CharField(max_length=256, blank=False, null=True) # ES indexable, snowball # color = models.CharField(max_length=256, blank=True, null=True) # condition = models.CharField(max_length=256, blank=True, null=True) # Workflow status fields detail_crawled = models.BooleanField(default=False) detail_parsed = models.BooleanField(default=False) review_urls_queued = models.BooleanField(default=False) review_urls_crawled = models.BooleanField(default=False) reviews_parsed = models.BooleanField(default=False) reviews_analyzed = models.BooleanField(default=False) article_published = models.BooleanField(default=False) # ML fields predicted_topics_name = models.CharField(max_length=1024, blank=True, null=True) # Timestamp # remove default and set it to auto_now_add=True if we're starting with an # empty models.Product table created_at = models.DateTimeField(default=timezone.now) updated_at = models.DateTimeField(auto_now=True) # Data Transfer Status data_dumped = models.BooleanField(default=False) def __unicode__(self): string = '{}: {}'.format(self.product_name, self.frsku) if not self.product_name: string = self.temp_title return '%s' % (string) def workflow_status(self): ''' DC = Detail crawled DP = Detail parsed RQ = Review URLs queued RC = Review URLs crawled RP = Reviews parsed ML = Machine learning: reviews analyzed AP = Article published ''' status = 'DC={} DP={} RQ={} RC={} RP={} ML={} AP={}' status = status.format(\ self.detail_crawled,\ self.detail_parsed,\ self.review_urls_queued,\ self.review_urls_crawled,\ self.reviews_parsed,\ self.reviews_analyzed, self.article_published\ ) return status def _get_lda_name(self): lda_topics_name = 'LDA_PREDICTED_TOPICS_{}_iter{}_min{}_max{}_chunk{}_topics{}.csv' if self.product_domain: lda_topics_name = lda_topics_name.\ format(self.frsku,\ self.product_domain.iteration,\ self.product_domain.minimum, \ self.product_domain.maximum,\ self.product_domain.chunksize,\ self.product_domain.topic_count) return lda_topics_name def save(self, *args, **kwargs): # assign a unique internal id if not self.frsku: self.frsku = helper.get_frsku() # generate a unique slug for the product name if not self.base_slug: # TODO: change self.temp_title to self.name in production self.base_slug = common_helper.slugify(self.product_name) if (self.base_slug) and (not self.slug): self.slug = common_helper.unique_slugify(self.base_slug, Product) lda_topics_name = self._get_lda_name() self.predicted_topics_name = lda_topics_name if not self.created_at: self.created_at = datetime.datetime.now() self.updated_at = datetime.datetime.now() super(Product, self).save(*args, **kwargs) def taxonomy(self): parent = self.product_taxonomy.level_0 child = self.product_taxonomy.level_1 string = 'Unknown Taxonomy' if parent: if child: string = '{} > {}'.format(parent, child) else: string = parent return string
class Build(models.Model): """Build data.""" project = models.ForeignKey( Project, verbose_name=_('Project'), related_name='builds', ) version = models.ForeignKey( Version, verbose_name=_('Version'), null=True, related_name='builds', ) type = models.CharField( _('Type'), max_length=55, choices=BUILD_TYPES, default='html', ) state = models.CharField( _('State'), max_length=55, choices=BUILD_STATE, default='finished', ) date = models.DateTimeField(_('Date'), auto_now_add=True) success = models.BooleanField(_('Success'), default=True) setup = models.TextField(_('Setup'), null=True, blank=True) setup_error = models.TextField(_('Setup error'), null=True, blank=True) output = models.TextField(_('Output'), default='', blank=True) error = models.TextField(_('Error'), default='', blank=True) exit_code = models.IntegerField(_('Exit code'), null=True, blank=True) commit = models.CharField( _('Commit'), max_length=255, null=True, blank=True, ) _config = JSONField(_('Configuration used in the build'), default=dict) length = models.IntegerField(_('Build Length'), null=True, blank=True) builder = models.CharField( _('Builder'), max_length=255, null=True, blank=True, ) cold_storage = models.NullBooleanField( _('Cold Storage'), help_text='Build steps stored outside the database.', ) # Manager objects = BuildQuerySet.as_manager() CONFIG_KEY = '__config' class Meta: ordering = ['-date'] get_latest_by = 'date' index_together = [['version', 'state', 'type']] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._config_changed = False @property def previous(self): """ Returns the previous build to the current one. Matching the project and version. """ date = self.date or timezone.now() if self.project is not None and self.version is not None: return ( Build.objects.filter( project=self.project, version=self.version, date__lt=date, ).order_by('-date').first() ) return None @property def config(self): """ Get the config used for this build. Since we are saving the config into the JSON field only when it differs from the previous one, this helper returns the correct JSON used in this Build object (it could be stored in this object or one of the previous ones). """ if self.CONFIG_KEY in self._config: return Build.objects.get(pk=self._config[self.CONFIG_KEY])._config return self._config @config.setter def config(self, value): """ Set `_config` to value. `_config` should never be set directly from outside the class. """ self._config = value self._config_changed = True def save(self, *args, **kwargs): # noqa """ Save object. To save space on the db we only save the config if it's different from the previous one. If the config is the same, we save the pk of the object that has the **real** config under the `CONFIG_KEY` key. """ if self.pk is None or self._config_changed: previous = self.previous # yapf: disable if ( previous is not None and self._config and self._config == previous.config ): # yapf: enable previous_pk = previous._config.get(self.CONFIG_KEY, previous.pk) self._config = {self.CONFIG_KEY: previous_pk} super().save(*args, **kwargs) self._config_changed = False def __str__(self): return ugettext( 'Build {project} for {usernames} ({pk})'.format( project=self.project, usernames=' '.join( self.project.users.all().values_list('username', flat=True), ), pk=self.pk, ), ) def get_absolute_url(self): return reverse('builds_detail', args=[self.project.slug, self.pk]) @property def finished(self): """Return if build has a finished state.""" return self.state == BUILD_STATE_FINISHED @property def is_stale(self): """Return if build state is triggered & date more than 5m ago.""" mins_ago = timezone.now() - datetime.timedelta(minutes=5) return self.state == BUILD_STATE_TRIGGERED and self.date < mins_ago def using_latest_config(self): return int(self.config.get('version', '1')) == LATEST_CONFIGURATION_VERSION
class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Friend', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(default='', max_length=30)), ('category', models.CharField(default='', max_length=30)), ('social_id', models.CharField(max_length=100, null=True)), ('friendee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'db_table': 'friend', }, ), migrations.CreateModel( name='Message', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('category', models.CharField(default='', max_length=30)), ('message', models.TextField(default='')), ('time', models.DateTimeField(default=None)), ('social_id', models.CharField(max_length=100, null=True)), ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='main_app.Friend')), ('owner', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'db_table': 'message', }, ), migrations.CreateModel( name='UserProfile', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('fb_name', models.CharField(default='', max_length=30)), ('fb_token', models.TextField(default='')), ('fb_id', models.TextField(default='')), ('twitter_name', models.CharField(default='', max_length=30)), ('resource_owner_key', models.TextField(default='')), ('resource_owner_secret', models.TextField(default='')), ('twitter_id', models.TextField(default='')), ('last_query', models.DateTimeField(null=True)), ('last_fetch', models.DateTimeField(null=True)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], options={ 'db_table': 'user_profile', }, ), migrations.AlterUniqueTogether( name='userprofile', unique_together=set([('user',)]), ), ]
class Version(models.Model): """A version for a given application""" application = models.ForeignKey(Application) title = models.CharField(max_length=100) version = models.CharField(blank=True, null=True, max_length=10) short_version = models.CharField(blank=True, null=True, max_length=50) dsa_signature = models.CharField(blank=True, null=True, max_length=80) length = models.CharField(blank=True, null=True, max_length=20) release_notes = models.TextField(blank=True, null=True) minimum_system_version = models.CharField(blank=True, null=True, max_length=10) published = models.DateTimeField(auto_now_add=True) update = models.FileField(upload_to='sparkle/') active = models.BooleanField(default=False) def __str__(self): return self.title def save(self, *args, **kwargs): super(Version, self).save(*args, **kwargs) path = self.update.path update = False # if there is no dsa signature and a private key is provided in the settings if not self.dsa_signature and SPARKLE_PRIVATE_KEY_PATH and os.path.exists( SPARKLE_PRIVATE_KEY_PATH): command = 'openssl dgst -sha1 -binary < "%s" | openssl dgst -dss1 -sign "%s" | openssl enc -base64' % ( path, SPARKLE_PRIVATE_KEY_PATH) process = os.popen(command) self.dsa_signature = process.readline().strip() process.close() update = True # if there is no length and it is a zip file # extract it to a tempdir and calculate the length # also parse the plist file for versions if not self.length and path.endswith('.zip'): zip_file = zipfile.ZipFile(path) tempdir = tempfile.mkdtemp() files = zip_file.namelist() start_path = None for f in files: if f.endswith('/'): d = os.path.join(tempdir, f) if not start_path: start_path = d os.makedirs(d) else: zip_file.extract(f, tempdir) info_plist = os.path.join(start_path, 'Contents/Info.plist') if os.path.exists(info_plist): with open(info_plist, 'rb') as f: plist = plistlib.load(f) if not self.version and 'CFBundleVersion' in plist: self.version = plist.get('CFBundleVersion') if not self.short_version and 'CFBundleShortVersionString' in plist: self.short_version = plist.get( 'CFBundleShortVersionString') if not self.minimum_system_version and 'LSMinimumSystemVersion' in plist: self.minimum_system_version = plist.get( 'LSMinimumSystemVersion') shutil.rmtree(tempdir) if not self.length: update = True self.length = os.path.getsize(path) if update: super(Version, self).save(*args, **kwargs)
class Migration(migrations.Migration): initial = True dependencies = [ ('users', '0001_initial'), ] operations = [ migrations.CreateModel( name='Service', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(blank=True, default=None, max_length=50, null=True, verbose_name='Название')), ('description', models.TextField(blank=True, default=None, null=True, verbose_name='Описание')), ('is_active', models.BooleanField(default=True, verbose_name='Активный')), ('created', models.DateTimeField(auto_now_add=True, verbose_name='Создан')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Изменен')), ], options={ 'verbose_name': 'Услуга', 'verbose_name_plural': 'Услуги', }, ), migrations.CreateModel( name='ServiceCategory', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(blank=True, default=None, max_length=50, null=True, verbose_name='Название')), ('description', models.TextField(blank=True, default=None, null=True, verbose_name='Описание')), ('on_home_page', models.BooleanField(default=True, verbose_name='На главной')), ('is_active', models.BooleanField(default=True, verbose_name='Активный')), ('created', models.DateTimeField(auto_now_add=True, verbose_name='Создан')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Изменен')), ], options={ 'verbose_name': 'Категория услуги', 'verbose_name_plural': 'Категории услуг', }, ), migrations.CreateModel( name='ServiceProfessional', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('duration_hours', models.DecimalField(blank=True, decimal_places=1, default=None, max_digits=3, null=True, verbose_name='Продолжительность (ч.)')), ('price', models.DecimalField(blank=True, decimal_places=2, default=None, max_digits=10, null=True, verbose_name='Стоимость (руб.)')), ('description', models.TextField(blank=True, default=None, null=True, verbose_name='Описание')), ('is_active', models.BooleanField(default=True, verbose_name='Активный')), ('created', models.DateTimeField(auto_now_add=True, verbose_name='Создан')), ('updated', models.DateTimeField(auto_now=True, verbose_name='Изменен')), ('professional', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.ProfileCompany')), ('service', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='services.Service')), ], options={ 'verbose_name': 'Услуга профессионала', 'verbose_name_plural': 'Услуги профессионалов', }, ), migrations.AddField( model_name='service', name='category', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='services.ServiceCategory'), ), ]
class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Dataset', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.TextField()), ('source', models.TextField()), ('description', models.TextField()), ('order', models.IntegerField(default=999)), ('references', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), null=True, size=None)), ('stored_at', models.CharField(choices=[('LOCAL_POSTGRES', 'Local PostgreSQL instance'), ('UBITECH_POSTGRES', "UBITECH's PostgreSQL instance at http://212.101.173.21"), ('UBITECH_PRESTO', "UBITECH's PRESTO instance"), ('UBITECH_SOLR', 'Solr instance at http://212.101.173.50:8983')], default='LOCAL_POSTGRES', max_length=32)), ('table_name', models.CharField(max_length=200)), ('private', models.BooleanField(default=False)), ('spatialEast', models.CharField(max_length=200, null=True)), ('spatialSouth', models.CharField(max_length=200, null=True)), ('spatialNorth', models.CharField(max_length=200, null=True)), ('spatialWest', models.CharField(max_length=200, null=True)), ('temporalCoverageBegin', models.DateTimeField(null=True)), ('temporalCoverageEnd', models.DateTimeField(null=True)), ('license', models.CharField(max_length=200, null=True)), ('observations', models.CharField(max_length=200, null=True)), ('publisher', models.TextField()), ('category', models.CharField(max_length=200, null=True)), ('image_uri', models.TextField(default='/static/img/logo.png')), ('sample_rows', django.contrib.postgres.fields.jsonb.JSONField(null=True)), ('number_of_rows', models.CharField(max_length=200, null=True)), ('size_in_gb', models.FloatField(null=True)), ('update_frequency', models.CharField(default='-', max_length=200)), ('last_updated', models.DateTimeField(null=True)), ('metadata', django.contrib.postgres.fields.jsonb.JSONField(default={})), ('hascoverage_img', models.BooleanField(default=False)), ('arguments', django.contrib.postgres.fields.jsonb.JSONField(default={})), ], options={ 'ordering': ['-id'], }, ), migrations.CreateModel( name='Organization', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.TextField()), ('description', models.TextField()), ], ), migrations.CreateModel( name='Vessel_Identifier', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('column_name', models.CharField(max_length=200)), ('values_list', django.contrib.postgres.fields.jsonb.JSONField()), ('dataset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='vessel_identifiers', to='aggregator.Dataset')), ], ), migrations.CreateModel( name='Variable', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=256)), ('title', models.CharField(max_length=256)), ('unit', models.CharField(max_length=256)), ('description', models.TextField(null=True)), ('sameAs', models.CharField(max_length=256, null=True)), ('dataType', models.CharField(max_length=256, null=True)), ('original_column_name', models.CharField(max_length=256, null=True)), ('scale_factor', models.FloatField(default=1)), ('add_offset', models.FloatField(default=0)), ('cell_methods', django.contrib.postgres.fields.ArrayField(base_field=models.TextField(), null=True, size=None)), ('type_of_analysis', models.TextField(blank=True, default=None, null=True)), ('distribution', django.contrib.postgres.fields.ArrayField(base_field=models.FloatField(), blank=True, default=None, null=True, size=7)), ('dataset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='variables', to='aggregator.Dataset')), ], options={ 'ordering': ['title'], }, ), migrations.CreateModel( name='JoinOfDatasets', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('view_name', models.CharField(max_length=100)), ('dataset_first', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='first', to='aggregator.Dataset')), ('dataset_second', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='second', to='aggregator.Dataset')), ], ), migrations.CreateModel( name='Dimension', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=256)), ('title', models.CharField(max_length=256)), ('unit', models.CharField(max_length=256)), ('description', models.TextField(null=True)), ('sameAs', models.CharField(max_length=256, null=True)), ('dataType', models.CharField(max_length=256, null=True)), ('original_column_name', models.CharField(max_length=256, null=True)), ('min', models.DecimalField(blank=True, decimal_places=50, default=None, max_digits=100, null=True)), ('max', models.DecimalField(blank=True, decimal_places=50, default=None, max_digits=100, null=True)), ('step', models.DecimalField(blank=True, decimal_places=50, default=None, max_digits=100, null=True)), ('axis', models.TextField(blank=True, default=None, null=True)), ('non_filterable', models.BooleanField(default=False)), ('variable', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dimensions', to='aggregator.Variable')), ], options={ 'ordering': ['pk'], }, ), migrations.CreateModel( name='DatasetAccessRequest', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('status', models.CharField(choices=[('open', 'open'), ('accepted', 'accepted'), ('rejected', 'rejected')], default='open', max_length=20)), ('creation_date', models.DateTimeField(default=datetime.datetime(2020, 2, 17, 14, 50, 48, 724320))), ('response_date', models.DateTimeField(null=True)), ('resource', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='resource', to='aggregator.Dataset')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='DatasetAccess', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('start', models.DateField()), ('end', models.DateField()), ('valid', models.BooleanField()), ('dataset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='aggregator.Dataset')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ], ), migrations.AddField( model_name='dataset', name='access_list', field=models.ManyToManyField(through='aggregator.DatasetAccess', to=settings.AUTH_USER_MODEL), ), migrations.AddField( model_name='dataset', name='joined_with_dataset', field=models.ManyToManyField(related_name='joined_to', through='aggregator.JoinOfDatasets', to='aggregator.Dataset'), ), migrations.AddField( model_name='dataset', name='organization', field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='datasets', to='aggregator.Organization'), ), migrations.AddField( model_name='dataset', name='owner', field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='dataset_owner', to=settings.AUTH_USER_MODEL), ), ]