class MediaContent(models.Model): IMAGE_EXTENSIONS = ('jpg', 'png',) TEXT_EXTENSIONS = ('txt', 'docx') ALLOWED_EXTENSIONS = IMAGE_EXTENSIONS + TEXT_EXTENSIONS ident = models.CharField( verbose_name='ISCC', max_length=55, blank=True, ) title = models.CharField( verbose_name='Content Title', max_length=128, blank=False, ) extra = models.CharField( verbose_name='Extra Info', max_length=128, blank=True, default="", ) file = models.FileField( verbose_name='Media Content File', help_text='Supported file types: {}'.format(ALLOWED_EXTENSIONS), upload_to='mediafiles', blank=False, validators=[ FileExtensionValidator(allowed_extensions=ALLOWED_EXTENSIONS), ], ) name = models.CharField( verbose_name='Filename', max_length=255, ) tophash = models.CharField( verbose_name='tophash', max_length=64, blank=True, default='' ) txid = models.CharField( verbose_name='Transaction-ID', help_text='Blockchain TX-ID of registered ISCC', max_length=64, blank=True, default='' ) class Meta: verbose_name = 'Media Content' verbose_name_plural = 'Media Contents' def __str__(self): return self.title def natural_key(self): return str(self) def register(self): # Register ISCC data = { 'json': { 'title': self.title, 'tophash': self.tophash, } } if self.extra: data['json']['extra'] = self.extra client = get_client() txid = client.publish( settings.STREAM_ISCC, key_or_keys=list(self.ident.split('-')), data_hex_or_data_obj=data ) return txid def clean(self): super().clean() if self.txid: raise ValidationError('Cannot change registered entry') if not self.pk and self.file: if not self.file.name.lower().endswith(self.ALLOWED_EXTENSIONS): raise ValidationError('Please provide a supported format: {}'.format( self.ALLOWED_EXTENSIONS)) basename, ext = os.path.splitext(self.file.name) # Store original file name self.name = self.file.name # Save with sanitized uuid as filename self.file.name = u''.join([str(uuid.uuid4()), ext.lower()]) def save(self, *args, **kwargs): mid, title, extra = iscc.meta_id(self.title, self.extra) if self.ident: new_ident = [mid] + list(self.ident.split('-')[1:]) self.ident = '-'.join(new_ident) if self.file: new_upload = isinstance(self.file.file, UploadedFile) if new_upload: # Generate ISCC filename, file_extension = splitext(self.file.name) ext = file_extension.lower().lstrip('.') data = self.file.open('rb').read() if ext in self.TEXT_EXTENSIONS: if ext == 'docx': text = docx2txt.process(BytesIO(data)) print(text) else: text = self.file.open().read() cid = iscc.content_id_text(text) elif ext in self.IMAGE_EXTENSIONS: cid = iscc.content_id_image(BytesIO(data)) did = iscc.data_id(data) iid, self.tophash = iscc.instance_id(data) iscc_code = '-'.join((mid, cid, did, iid)) self.ident = iscc_code super(MediaContent, self).save(*args, **kwargs)
class MissingChild(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE, null=True) full_name = models.CharField( max_length=60, help_text="Fullname should be in the format :- First Name Last Name") child_aadhar_no = models.BigIntegerField( verbose_name='Aadhar no.', blank=True, null=True, validators=[ MinValueValidator(200000000000), MaxValueValidator(999999999999) ]) GENDER = (('M', 'Male'), ('F', 'Female'), ('T', 'Transgender')) gender = models.CharField(max_length=1, choices=GENDER, default=None, null=True) age = models.PositiveIntegerField( help_text= "Age of the child as of now [ in year(s) ]. Note :- Please don't type the unit i.e., year(s).", validators=[MinValueValidator(1), MaxValueValidator(12)]) father_name = models.CharField(max_length=60, verbose_name="Father's name") mother_name = models.CharField(max_length=60, verbose_name="Mother's name") nationality = models.CharField(max_length=60) mother_tongue = models.CharField(max_length=60, blank=True) child_image = models.ImageField( upload_to='missing_child_images', help_text= "Image must contains front face. It should be in .jpg or .png format having size range [ 1 MB - 5 MB ].", validators=[ FileExtensionValidator(allowed_extensions=['jpg', 'png']), validate_image_size ]) residential_address = models.CharField( max_length=255, help_text= "Permanent address should be entered containing house no. , road name , village / town name , post office / police station name." ) district = models.CharField(max_length=60) state = models.CharField(max_length=30) pincode = models.PositiveIntegerField( validators=[MinValueValidator(110001), MaxValueValidator(999999)]) parent_mobile_no = PhoneNumberField(max_length=13) parent_email = models.EmailField(max_length=50, blank=True) parent_aadhar_no = models.BigIntegerField(validators=[ MinValueValidator(200000000000), MaxValueValidator(999999999999) ]) missing_from_place = models.CharField(max_length=60) police_station_nearby_missing_place = models.CharField(max_length=60) missing_from_date = models.DateField() missing_from_time = models.TimeField() MISSING_CAUSE = (('R', 'Runaway'), ('L', 'Lost'), ('T', 'Trafficked'), ('K', 'Kidnapped'), ('Nl', 'Not listed')) missing_cause = models.CharField(max_length=2, choices=MISSING_CAUSE, default=None, null=True) additional_info = models.TextField( max_length=500, verbose_name= "Detailed Information related to event of Missing (in 500 words)") height = models.DecimalField( max_digits=3, decimal_places=2, help_text= "Height should be in [ M feet(s) . N inch(es) OR M feet(s) ] format. For example, 4.10 resembles 4 feet 10 inches in our database. Note :- Please don't type the units i.e., feet(s) & inch(es).", validators=[MinValueValidator(2.6), MaxValueValidator(5)]) weight = models.PositiveIntegerField( help_text= "Weight should be in kg(s) only. Omit the gram(s) if any present. For example, if wish to enter is 21.5 kg(s), just type 21 and omit the decimal part which is in gram(s). Note :- Please don't type the unit i.e., kg(s).", validators=[MinValueValidator(10), MaxValueValidator(80)]) COMPLEXION = (('D', 'Dark'), ('F', 'Fair'), ('Vf', 'Very fair')) complexion = models.CharField(max_length=2, choices=COMPLEXION, default=None, null=True) BUILD = (('F', 'Fat'), ('N', 'Normal'), ('T', 'Thin')) build = models.CharField(max_length=1, choices=BUILD, default=None, null=True) EYE_COLOR = (('Nm', 'Normal'), ('Bl', 'Blue'), ('Br', 'Brown'), ('R', 'Reddish'), ('G', 'Green'), ('Nl', 'Not listed')) eye_color = models.CharField(max_length=2, choices=EYE_COLOR, default=None, null=True) HAIR_COLOR = (('Br', 'Brown'), ('Cb', 'Curly black'), ('Bl', 'Black'), ('Nl', 'Not listed')) hair_color = models.CharField(max_length=2, choices=HAIR_COLOR, default=None, null=True) upper_wearing_apparel = models.CharField( max_length=60, verbose_name="Wearing Upper Apparel", blank=True) lower_wearing_apparel = models.CharField( max_length=60, verbose_name="Wearing Lower Apparel", blank=True) footwear = models.CharField(max_length=60, blank=True) identification_marks = models.CharField(max_length=100, blank=True) DEFORMITIES = (('D', 'Deaf'), ('B', 'Blind'), ('Se', 'Squint eyes'), ('Fe', 'Finger(s) extra'), ('G', 'Goitre'), ('Hm', 'Hand missing'), ('Lm', 'Leg missing'), ('Nl', 'Not listed')) deformities = models.CharField(max_length=2, choices=DEFORMITIES, default=None, null=True) habits = models.CharField(max_length=100, blank=True) class Meta: verbose_name_plural = "Missing Child Info" def __str__(self): return f"(ID = {self.id}) ---> {self.user.username} ' s Child Info (ForeignKey User ID = {self.user_id})" def save(self, *args, **kwargs): super().save(*args, **kwargs) img = Image.open(self.child_image.path) if img.width > 1600 or img.height > 1600: output_size = (1600, 1600) img.thumbnail(output_size, Image.LANCZOS) img.save(self.child_image.path)
class ExpInitDataMultiForm(FormFieldPopoverMixin, MultiFormMixin): initDataFile = forms.FileField( label="Initialization file [.json]", validators=[FileExtensionValidator(['json'])], help_text=".json file to initialize experiment", widget=forms.FileInput(attrs={'accept': ".json"}), ) def __init__(self, exp, *args, **kwargs): self.exp = exp super(ExpInitDataMultiForm, self).__init__(*args, **kwargs) def clean_initDataFile(self): initDataFile = self.cleaned_data.get('initDataFile', None) required_plate_keys = [ 'plate_id', 'date_time', 'temperature', 'subwells' ] if initDataFile: try: if initDataFile.size >= 2.5e6: raise OverflowError data_json = "" for c in initDataFile.chunks(): data_json += str(c, encoding='utf-8').replace("'", "\"") data_dict = json.loads(data_json) plate_ids = data_dict.keys() existing_ids = [] exp_dest_plate_ids = [ p.rockMakerId for p in self.exp.plates.filter(isSource=False) ] for p_id in plate_ids: if Plate.objects.filter(rockMakerId=p_id).exists( ) and p_id not in exp_dest_plate_ids: existing_ids.append(p_id) if existing_ids: self.add_error( 'initDataFile', ValidationError( ('Plate with RockMaker ID %(value)s already exist(s) and are not in current experiment.' ), code='invalid', params={'value': existing_ids}, )) for p_id in plate_ids: p = data_dict[p_id] keys = p.keys() missing_keys = missing_list_elems(required_plate_keys, keys) if missing_keys: self.add_error( 'initDataFile', ValidationError( ('Plate in .json has missing keys %(value)s.'), code='invalid', params={'value': missing_keys}, )) except (ValueError, OverflowError) as e: if issubclass(type(e), ValueError): self.add_error( 'initDataFile', 'File given is not in correct .json format. Review instructions above.' ) if type(e) is OverflowError: self.add_error('initDataFile', 'File is too big!') return initDataFile
class file(models.Model): fileupload=models.FileField(upload_to='static', validators=[FileExtensionValidator(['csv'])],unique=None)
class Comment(models.Model): text = models.TextField() publish_date = models.DateTimeField(default = timezone.now) post_id = models.ManyToManyField(Post) status = models.CharField(max_length=15, choices=STATUS_CHOICES) author = models.ForeignKey('auth.User', on_delete=models.CASCADE) is_deleted = models.BooleanField(default = False) file = models.FileField(upload_to = "comments/", null=True, blank=True, validators=[validate_file_size, FileExtensionValidator(['pdf', 'jpg', 'png', 'txt'])]) history = HistoricalRecords() def publish(self, request): self.publish_date = timezone.now() self.author = request.user self.save_file() self.save() def edit(self): self.save_file() self.save() def __str__(self): return self.text def get_absolute_file_url(self): if self.file.name: file_f = FileSystemStorage() return file_f.url(self.file.name) else: return "" def save_file(self): if self.file.name: file_c = FileSystemStorage() file_c.save(self.file.name, self.file) def if_there_is_a_file_return_text(self): if self.file.name: return "ZAŁĄCZNIK" else: return "" def if_comment_have_file_icon(self): if self.file.name: return "fas fa-file"
class BusinessLine(TimeStampedModel): """ Model to save the business lines """ title = models.CharField(verbose_name=_('Title'), max_length=150, unique=True) title_ar = models.CharField(verbose_name=_('Arabic Title'), max_length=150, default='') description = models.TextField(verbose_name=_('Description')) description_ar = models.TextField(verbose_name=_('Arabic Description'), default='') site_url = models.URLField(default='', verbose_name=_('Site URL')) logo = models.ImageField( upload_to='business-lines/logos/', verbose_name=_('Logo'), validators=[ FileExtensionValidator(ALLOWED_LOGO_EXTENSIONS), validate_logo_size ], help_text=_('Accepted extensions: .png, .jpg, .svg'), ) group = models.OneToOneField(Group, related_name='business_line', on_delete=models.CASCADE, null=True) objects = BusinessLineQuerySet.as_manager() class Meta: app_label = 'applications' def __str__(self): return self.display_title @property def display_title(self): return self.title_ar if get_language( ) == ARABIC_LANGUAGE_CODE else self.title @property def display_description(self): return self.description_ar if get_language( ) == ARABIC_LANGUAGE_CODE else self.description @classmethod def is_user_business_line_admin(cls, user): """ Checks if the user is a business line admin i.e Belongs to at least one business line group Arguments: user (User): User object to check permissions for Returns: boolean: Returns True if the user is an admin and False if not """ return cls.objects.filter(group__user=user).exists() @classmethod def business_lines_for_user(cls, user): """ Return business lines based on the type of admin; all business lines in case of ADG admin and only those business lines of which the user is admin of, in case of business unit admin. Arguments: user (User): Admin to get the business lines for Returns: QuerySet: BusinessLine objects for the given user """ return BusinessLine.objects.all() if is_superuser_or_adg_admin( user) else cls.objects.filter(group__user=user) @classmethod def user_emails_for_business_line(cls, business_line_title): """ Return the emails for all those users that have chosen the given business_line in their application Args: business_line_title (str): Title of the business line to get the emails for Returns: QuerySet: Emails for all the users associated with the given business line """ return cls.objects.filter(title=business_line_title).values_list( 'userapplication__user__email', flat=True)
class Compania(models.Model): """ """ def get_upload_to(self, filename): return "logos/%s/%s" % (self.rut, filename) def get_cert_upload_to(self, filename): """ Crea un hash del nombre del certificado, antes de almacenarlo en el servidor """ #filename_base, filename_ext = os.path.splitext(filename) #hash = MD5.new() #hash.update(filename_base.encode()) return "certificados/%s/%s" % (self.rut, filename)#(hash.hexdigest(),filename_ext.lower()) owner = models.ForeignKey(User, on_delete=models.CASCADE, default=1) rut = models.CharField(max_length=128, blank=True, null=True) razon_social = models.CharField(max_length=128, blank=True, null=True) actividad_principal = models.CharField(max_length=128,choices=ACTIVIDADES, blank=True, null=True) giro = models.CharField(max_length=128,choices=ACTIVIDADES, blank=True, null=True) direccion = models.CharField(max_length=128, blank=True, null=True) comuna = models.CharField(max_length=128, choices=COMUNAS, blank=True, null=True) logo = models.FileField(upload_to=get_upload_to, blank=True, null=True) fecha_resolucion = models.DateField(blank=True, null=True) numero_resolucion = models.IntegerField(blank=True, null=True,validators=[MinValueValidator(0),MaxValueValidator(999999)]) correo_sii = models.EmailField(blank=True, null=True) pass_correo_sii = models.CharField(max_length=128, blank=True, null=True) correo_intercambio = models.EmailField(blank=True, null=True) pass_correo_intercambio = models.CharField(max_length=128, blank=True, null=True) certificado = models.FileField('Certificado', upload_to=get_cert_upload_to,validators=[FileExtensionValidator(allowed_extensions=['pfx'])], blank=False, null=True) tasa_de_iva = models.IntegerField("Tasa IVA", blank=False, null=False, default=0) pass_certificado = models.CharField(max_length=128) web = models.URLField() class Meta: """! Clase que construye los meta datos del modelo """ ordering = ('rut',) verbose_name = 'Compania' verbose_name_plural = 'Companias' def __str__(self): return self.razon_social def validar_certificado(string_archivo_pfx, password): """ Recibe un archivo de certificado .pfx y su correspondiente contrasena y retorna una tupla con la clave privada, la clave publica y el certificado extraido del mismo """ try: # Carga el archivo .pfx y muestra un error si la contrasena # es incorrecta p12 = OpenSSL.crypto.load_pkcs12(string_archivo_pfx, password) except OpenSSL.crypto.Error: raise ContrasenaDeCertificadoIncorrecta # Extraccion de clave privada private = OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, p12.get_privatekey()).decode() # Extraccion de certificado certificate = OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, p12.get_certificate()).decode().replace('\n-----END CERTIFICATE-----\n', '').replace('-----BEGIN CERTIFICATE-----\n', '') # Extraccion de clave publica public_key = OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM,p12.get_certificate().get_pubkey()).decode() return (private, certificate, public_key)
class FooterContact(models.Model): title = models.CharField(max_length=100) contact_info = RichTextField(blank=True, null=True) svgimg = models.FileField(upload_to='svgimg2', validators=[FileExtensionValidator(['svg'])])
# from apps.issues.models import current_issue from apps.contributors.models import Contributor from apps.photo import file_operations from utils.dbfuncs import TrigramWordSimilarity from utils.merge_model_objects import merge_instances from utils.model_mixins import EditURLMixin # from .exif import ExifData, extract_exif_data from .cropping.models import AutoCropImage from .imagehash import ImageHashModelMixin from .preprocess import ProcessImage from .thumbimage import ThumbImageFile logger = logging.getLogger(__name__) image_file_validator = FileExtensionValidator(['jpg', 'jpeg', 'png']) def slugify_filename(filename: str) -> Path: """make filename url safe and normalized""" slugify = Slugify(safe_chars='.-', separator='-') fn = Path(filename) stem = Path(filename).stem.split('.')[0] stem = re.sub(r'-+', '-', slugify(re.sub(r'_.{7}$', '', stem))).strip('-') suffix = ''.join(s.lower().replace('jpeg', 'jpg') for s in fn.suffixes) return Path(f'{stem}{suffix}') def upload_image_to(instance: 'ImageFile', filename: str = 'image') -> str: """Upload path based on created date and normalized file name""" if instance.pk and instance.stem:
class RespuestasExamenes(models.Model): ejercicio = models.ForeignKey(EjerciciosExamenes, on_delete=models.CASCADE) alumno = models.ForeignKey(Alumno, related_name='respuesta_examen', on_delete=models.CASCADE, null=False, blank=False) puntaje_obtenido = models.IntegerField("Puntaje", default=0) archivo_respuesta = models.FileField( "Respuesta", upload_to=get_upload_respuesta_examen, null=False, blank=False, validators=[ FileExtensionValidator(allowed_extensions=[ 'py', 'java', 'prolog', 'cpp', 'c', 'lisp', 'zip' ]) ], storage=OverwriteStorage(), max_length=500) archivo_respuesta_temporal = models.FileField( "Respuesta temporal", upload_to=get_upload_respuesta_temporal_examen, null=True, blank=True, validators=[ FileExtensionValidator(allowed_extensions=[ 'py', 'java', 'prolog', 'cpp', 'c', 'lisp', 'zip' ]) ], storage=OverwriteStorage(), max_length=500) fecha_enviado = models.DateTimeField("Fecha enviado", auto_now=True) error = models.CharField("Error", null=True, max_length=100) class Meta: verbose_name = "Respuesta de ejercicio" verbose_name_plural = "Respuesta de ejercicio" unique_together = (('ejercicio', 'alumno'), ) def __str__(self): return str(self.puntaje_obtenido) def __unicode__(self): return str(self.puntaje_obtenido) def get_absolute_url(self): return reverse("detalle_respuesta_examen", args=[ str(self.ejercicio.examen.curso.pk), str(self.ejercicio.examen.pk), str(self.pk) ]) def get_path(self): file_path = os.path.join( settings.BASE_DIR, "media", "examenes", "examen" + str(self.ejercicio.examen.id), str(self.alumno.matricula), str(self.ejercicio.ejercicio.id), ) return file_path def get_path_archivo(self, filename): file_path = os.path.join(settings.BASE_DIR, "media", "examenes", "examen" + str(self.ejercicio.examen.id), str(self.alumno.matricula), str(self.ejercicio.ejercicio.id), filename) return file_path
class Intro(models.Model): title = models.CharField(max_length=100) subtitle = models.CharField(max_length=200) svgimg = models.FileField(upload_to='svgimg', validators=[FileExtensionValidator(['svg'])])
class RespuestasPracticas(models.Model): ejercicio = models.ForeignKey(EjerciciosPracticas, on_delete=models.CASCADE) alumno = models.ForeignKey(Alumno, related_name='respuesta_practica', on_delete=models.CASCADE, null=False, blank=False) puntaje_obtenido = models.IntegerField("Puntaje", default=0) archivo_respuesta = models.FileField( "Respuesta", upload_to=get_upload_respuesta_practica, null=False, blank=False, validators=[ FileExtensionValidator(allowed_extensions=[ 'py', 'java', 'prolog', 'cpp', 'c', 'lisp', 'zip' ]) ], storage=OverwriteStorage(), max_length=500) archivo_respuesta_temporal = models.FileField( "Respuesta temporal", upload_to=get_upload_respuesta_temporal_practica, null=True, blank=True, validators=[ FileExtensionValidator(allowed_extensions=[ 'py', 'java', 'prolog', 'cpp', 'c', 'lisp', 'zip' ]) ], storage=OverwriteStorage(), max_length=500) fecha_enviado = models.DateTimeField("Fecha enviado", auto_now=True) error = models.CharField("Error", null=True, max_length=100) class Meta: verbose_name = "Respuesta de ejercicio" verbose_name_plural = "Respuesta de ejercicio" unique_together = (('ejercicio', 'alumno'), ) def __str__(self): return str(self.puntaje_obtenido) def __unicode__(self): return str(self.puntaje_obtenido) def delete(self, *args, **kwargs): if os.path.isfile(self.archivo_respuesta.path): os.remove(self.archivo_respuesta.path) super(RespuestasPracticas, self).delete(*args, **kwargs) def get_absolute_url(self): return reverse("detalle_respuesta_practica", args=[ str(self.ejercicio.practica.curso.pk), str(self.ejercicio.practica.pk), str(self.pk) ]) # obtiene la ruta donde se guardarán todos los archivos(zip, compilados) de respuesta del estudiante def get_path(self): file_path = os.path.join( settings.BASE_DIR, "media", "practicas", "practica" + str(self.ejercicio.practica.id), str(self.alumno.matricula), str(self.ejercicio.ejercicio.id), ) return file_path # obtiene la ruta de un archivo en específico, puede ser un compilado por ejemplo def get_path_archivo(self, filename): file_path = os.path.join(settings.BASE_DIR, "media", "practicas", "practica" + str(self.ejercicio.practica.id), str(self.alumno.matricula), str(self.ejercicio.ejercicio.id), filename) return file_path
class Article(models.Model): name_bsc = models.CharField( max_length=255, unique=True, verbose_name="Article Name*") # Name of the article author_names = models.ManyToManyField( Authors, help_text="Choose An Author", verbose_name="Author Names*") # Author manes article_language = models.ForeignKey( Content_Language, help_text="Article Language", verbose_name="Content Language*", default=0, # Default is tr on_delete=models.CASCADE) # Article language pub_year = models.DateField( default=datetime.date.today, help_text="Ex: June 2018", verbose_name="Published Year*") # Publish Year) # Conference Date pp = models.CharField( max_length=15, blank=True, help_text="Page Start and Page End: Ex:10-20 (Not Obligatory)", verbose_name="PP.") volume = models.IntegerField(blank=True, null=True, help_text="Cilt no - Ex: 7 (Not Obligatory)", verbose_name="Volume") issue = models.IntegerField(blank=True, null=True, help_text="Sayı - Ex: 52 (Not Obligatory)", verbose_name="Issue") page_count = models.IntegerField( verbose_name="Page Count", blank=True, null=True, help_text="Total Page Number (Not Obligatory)" ) # How many page is there journal_title = models.CharField( max_length=255, help_text="Journal Title*", verbose_name="Journal Title") # Publisher of the article publisher = models.CharField( max_length=255, blank=True, help_text="Publisher Name (Not Obligatory)", verbose_name="Publisher", ) # Publisher of the article pdf = models.FileField(upload_to='pdf/%Y/%m/%d', help_text="Article PDF (Not Obligatory)", verbose_name="PDF", blank=True, validators=[FileExtensionValidator(["pdf"])], max_length=250) section = models.ForeignKey(All_Navbar_Sections, verbose_name="Navbar Section*", on_delete=models.CASCADE) # tags = def __str__(self): return "%s" % (self.name_bsc ) # In Admin Page see the name itself not as object class Meta: verbose_name = "Article" verbose_name_plural = "Articles"
class Profile(models.Model): first_name = models.CharField(max_length=100, blank=True) last_name = models.CharField(max_length=100, blank=True) user = models.OneToOneField(User, on_delete=models.CASCADE) profile_pic = models.ImageField( upload_to='profile/', default='avatar.png', validators=[FileExtensionValidator(['png', 'jpg', 'jpeg'])]) cover_pic = models.ImageField( upload_to='cover/', default='avatar.png', validators=[FileExtensionValidator(['png', 'jpg', 'jpeg'])]) email = models.EmailField(max_length=200, default="*****@*****.**") profession = models.CharField(max_length=250, default="No profession Added") interest = models.CharField(max_length=6, choices=INTEREST, default="Male & Female") bio = models.TextField(default="No bio Added") country = models.CharField(max_length=100, blank=True) friends = models.ManyToManyField(User, related_name='friend') language = models.CharField(max_length=100, default='English') slug = models.SlugField(unique=True, blank=False) updated = models.DateTimeField(auto_now=True) created = models.DateTimeField(auto_now_add=True) @property def profileURL(self): try: url = self.profile_pic.url except: url = '' return url @property def coverURL(self): try: url = self.cover_pic.url except: url = '' return url def save(self, *args, **kwargs): exist = False if self.first_name and self.last_name: to_slug = slugify(str(self.first_name) + '' + str(self.last_name)) exist = Profile.objects.filter(slug=to_slug) while exist: to_slug = slugify(str(to_slug) + '' + str(generate_code)) exist = Profile.objects.filter(slug=to_slug) else: to_slug = slugify(str(self.user)) self.slug = to_slug super().save(*args, **kwargs) def __str__(self): return str(self.user)
class File(models.Model): ALLOWED_FILE_TYPES = ("png", "jpg", "jpeg", "pdf") FILE_TYPE_CHOICES = (('jpg', 'JPG'), ('png', 'PNG'), ('pdf', 'PDF'), ('txt', 'TXT'), ("jpeg", "JPEG")) input_files_path = "transactions/files/input_files/" converted_files_path = "transactions/files/converted_files/" input_file = models.FileField( upload_to=input_files_path, validators=[ FileExtensionValidator(allowed_extensions=ALLOWED_FILE_TYPES), ]) converted_file = models.FileField( upload_to=converted_files_path, validators=[ FileExtensionValidator(allowed_extensions=ALLOWED_FILE_TYPES), ], blank=True, null=True) uuid = models.UUIDField(default=uuid.uuid4, unique=True) pages = models.PositiveSmallIntegerField(blank=True, null=True) has_error = models.BooleanField(default=False) file_type = models.CharField(max_length=3, choices=FILE_TYPE_CHOICES, blank=True) @property def get_file_ext(self): if self.converted_file: return self.converted_file.name[( self.converted_file.name.rfind(".") + 1):].lower() else: return self.input_file.name[(self.input_file.name.rfind(".") + 1):].lower() @property def get_pure_name(self): return self.input_file.name[(self.input_file.name.rfind("/") + 1):self.input_file.name.rfind(".")] @property def get_pdf_path(self): return self.converted_files_path + self.get_pure_name + ".pdf" @property def get_jpg_path_temp(self): return MEDIA_PATH + self.input_files_path + self.get_pure_name + '.jpg' @property def get_pdf_path_raw(self): return MEDIA_PATH + self.get_pdf_path @property def convert_input_file(self): if self.file_type == "pdf": return converters.pdf_converter(self) elif self.file_type == "png": return converters.png_converter(self) elif self.file_type == "jpg": return converters.jpg_converter(self) elif self.file_type == "jpeg": return converters.jpeg_converter(self) else: pass @property def get_file_url(self): return SITE_DOMAIN_NAKED + self.converted_file.url @property def count_pdf_pages(self): pdf = PdfFileReader(open(self.converted_file.path, 'rb')) return pdf.getNumPages() def assign_pages(self): pages = self.count_pdf_pages if self.pages != pages: self.pages = pages self.save() @property def temp_method(self): return self.get_pure_name def save(self, *args, **kwargs): if self.file_type != self.get_file_ext: self.file_type = self.get_file_ext super().save() if not self.converted_file: converted = self.convert_input_file if not converted: self.has_error = True super().save() else: super().save() if self.converted_file and not self.pages: self.assign_pages() super().save()
class ReportBase(models.Model): """ Base class for uploading html templates """ class Meta: abstract = True def save(self, *args, **kwargs): # Increment revision number self.revision += 1 super().save() def __str__(self): return "{n} - {d}".format(n=self.name, d=self.description) @classmethod def getSubdir(cls): return '' def rename_file(self, filename): # Function for renaming uploaded file filename = os.path.basename(filename) return os.path.join('report', 'report_template', self.getSubdir(), filename) @property def extension(self): return os.path.splitext(self.template.name)[1].lower() @property def template_name(self): """ Returns the file system path to the template file. Required for passing the file to an external process """ template = self.template.name template = template.replace('/', os.path.sep) template = template.replace('\\', os.path.sep) template = os.path.join(settings.MEDIA_ROOT, template) return template name = models.CharField( blank=False, max_length=100, verbose_name=_('Name'), help_text=_('Template name'), ) template = models.FileField( upload_to=rename_template, verbose_name=_('Template'), help_text=_("Report template file"), validators=[ FileExtensionValidator(allowed_extensions=['html', 'htm']) ], ) description = models.CharField(max_length=250, verbose_name=_('Description'), help_text=_("Report template description")) revision = models.PositiveIntegerField( default=1, verbose_name=_("Revision"), help_text=_("Report revision number (auto-increments)"), editable=False, )
def validate_file_extension(value): return FileExtensionValidator(["png"])(value)
class Thabloid(models.Model): """Model representing a Thabloid.""" year = models.IntegerField( verbose_name="academic year", validators=[MinValueValidator(1990)] ) issue = models.IntegerField() file = models.FileField( upload_to=thabloid_filename, validators=[FileExtensionValidator(["txt", "pdf", "jpg", "jpeg", "png"])], ) class Meta: """Meta class for Thabloid model.""" unique_together = ( "year", "issue", ) ordering = ("-year", "-issue") def __str__(self): """Return string representation of a Thabloid object.""" return "Thabloid {}-{}, #{}".format(self.year, self.year + 1, self.issue) def page_url(self, page=None, second_page=None): """Return path of Thabloid pages image.""" if page is None: page = "%03d.png" elif second_page is None: page = "{:03}.png".format(page) else: page = "{:03}-{:03}.png".format(page, second_page) dst, _ = os.path.splitext(self.file.name) return os.path.join(os.path.dirname(dst), "pages", os.path.basename(dst), page) @property def cover(self): """Return first page as cover.""" return self.page_url(1) def pagesets(self, count): """Return list of pages to should be shown together.""" if count < 1: return [] pageiter = iter(range(2, count)) return [(1, None)] + list(zip_longest(pageiter, pageiter)) @property def pages(self): """Return urls of pages that should be shown together.""" pages = os.listdir( os.path.join(settings.MEDIA_ROOT, os.path.dirname(self.page_url())) ) count = len(pages) * 2 - 1 return map(lambda p: self.page_url(p[0], p[1]), pagesets(count)) def get_absolute_url(self): """Get url of Thabloid.""" return reverse( "thabloid:pages", kwargs={"year": self.year, "issue": self.issue} ) def post_extract(self): """Save extracted pages to disk.""" pages = os.listdir( os.path.join(settings.MEDIA_ROOT, os.path.dirname(self.page_url())) ) pages = [self.page_url(i + 1) for i in range(len(pages))] pages = sorted(pages) pages = pages[1:-1] count = int(len(pages) / 2) dirname = os.path.join(settings.MEDIA_ROOT, os.path.dirname(self.page_url())) for i in range(0, count): i = i * 2 spread_left = os.path.join(settings.MEDIA_ROOT, pages[i]) spread_right = os.path.join(settings.MEDIA_ROOT, pages[i + 1]) result = Image.new("RGB", (2100, 1485)) img_left = Image.open(spread_left) result.paste(img_left, (0, 0, 1050, 1485)) img_right = Image.open(spread_right) result.paste(img_right, (1050, 0, 2100, 1485)) filename = ( os.path.splitext(os.path.basename(spread_left))[0] + "-" + os.path.splitext(os.path.basename(spread_right))[0] + ".png" ) result.save(os.path.join(dirname, filename), "PNG") os.remove(spread_left) os.remove(spread_right) def extract_thabloid_pages(self, wait): """Extract the pages of a Thabloid using Ghostscript.""" dst = os.path.join(settings.MEDIA_ROOT, self.page_url()) name = thabloid_filename(self, self.file.name) src = os.path.join(settings.MEDIA_ROOT, name) try: # Remove potential remainders shutil.rmtree(os.path.dirname(dst)) except FileNotFoundError: pass os.makedirs(os.path.dirname(dst), exist_ok=True) thread = PopenAndCall( self.post_extract, [ "gs", "-o", dst, "-g1050x1485", "-dPDFFitPage", "-dTextAlphaBits=4", "-sDEVICE=png16m", "-f", src, ], stdout=subprocess.DEVNULL, ) if wait: thread.join() def save(self, *args, wait=False, **kwargs): """Save Thabloid to disk.""" new_file = False if self.pk is None: new_file = True else: old = Thabloid.objects.get(pk=self.pk) old_dir = os.path.join(settings.MEDIA_ROOT, old.page_url()) old_dir = os.path.dirname(old_dir) if self.file != old.file: new_file = True elif self.year != old.year or self.issue != old.issue: self.file.name = thabloid_filename(self, self.file.name) new_dir = os.path.join(settings.MEDIA_ROOT, self.page_url()) new_dir = os.path.dirname(new_dir) try: shutil.rmtree(new_dir) except FileNotFoundError: pass os.rename(old_dir, new_dir) os.rename( os.path.join(settings.MEDIA_ROOT, old.file.name), os.path.join(settings.MEDIA_ROOT, self.file.name), ) if new_file: filename = thabloid_filename(self, self.file.name) src = os.path.join(settings.MEDIA_ROOT, filename) # Removes the .pdf file if it already exists try: os.remove(src) except FileNotFoundError: pass super().save(*args, **kwargs) if new_file: self.extract_thabloid_pages(wait)
class Trail(models.Model): # FIXME Set editable option for other fields id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) pub_date = models.DateTimeField(_('Date published')) is_draft = models.BooleanField(_('Draft'), default=True) is_private = models.BooleanField(_('Private'), default=True, help_text=_('Only you can see this trail.')) # Info name = models.CharField(_('Title'), max_length=255, blank=True) description = models.TextField(_('Description'), blank=True, help_text=_('Markdown is partially supported.')) tracks = JSONField(null=True) # Files file = models.FileField(_('GPX file'), upload_to=trail_directory_path, validators=[FileExtensionValidator(['gpx'])]) thumbnail = models.ImageField(upload_to=trail_directory_path, null=True) hero = models.ImageField(upload_to=trail_directory_path, null=True) class Meta: ordering = ['-pub_date', 'name'] def __str__(self): return self.name
class Administrativo(models.Model): nombre = models.CharField("Nombre", max_length=50, validators=[ MinLengthValidator( 3, "La longitud mínima del nombre es de 3 caracteres."), MaxLengthValidator( 50, "La longitud máxima del nombre es de 50 caracteres."), RegexValidator('^([A-ZÁÉÍÓÚ]{1}[a-zñáéíóú]+[\\s]*)+$', "Formato de nombre incorrecto, favor de veriicarlo.",)], error_messages={ 'required': "El nombre es requerido, favor de completarlo."} ) primer_apellido = models.CharField( "Primer apellido", max_length=50, validators=[ MinLengthValidator( 3, "La longitud mínima del primer apellido es de 3 caracteres."), MaxLengthValidator( 50, "La longitud máxima del primer apellido es de 50 caracteres."), RegexValidator('^([A-ZÁÉÍÓÚ]{1}[a-zñáéíóú]+[\\s]*)+$', "Formato del primer apellido incorrecto," + " favor de veriicarlo.") ]) segundo_apellido = models.CharField( "Segundo apellido", max_length=50, blank=True, validators=[ MinLengthValidator( 3, "La longitud mínima del segundo apellido es de 3 caracteres." ), MaxLengthValidator( 50, "La longitud máxima del segundo apellido es de 50 caracteres." ), RegexValidator('^([A-ZÁÉÍÓÚ]{1}[a-zñáéíóú]+[\\s]*)+$', "Formato del segundo apellido incorrecto," + " favor de veriicarlo.") ]) foto = models.ImageField( 'Foto', upload_to='usuarios', blank=True, null=True, validators=[ FileExtensionValidator(['png', 'jpeg', 'jpg'], "Formato de imagen inválido.") ]) telefono = models.CharField("Teléfono", max_length=10, validators=[ RegexValidator('^[0-9]{10,10}$', "Formato del número de teléfono incorrecto."), MinLengthValidator( 10, "El número telefónico debe contener 10 dígitos."), MaxLengthValidator( 10, "El número telefónico debe contener 10 dígitos."), ]) usuario = models.OneToOneField( User, verbose_name="Usuario", on_delete=models.CASCADE, error_messages={ 'required': "El usuario es requerida, favor de indicar sus datos." }) def clean(self): pattern = re.compile("^[a-zA-Z]{8,20}$") count = 0 dic = {'username': [], 'email': [], 'password': []} try: if not self.usuario.username: dic['username'].append('El usuario es requerido.') count += 1 if not pattern.match(self.usuario.username): dic['username'].append( 'El nombre de usuario no sigue el formato solicitado,' + ' favor de verificarlo.') count += 1 if not self.usuario.email or not self.usuario.email.strip(): dic['email'].append('El correo electrónico es requerido.') count += 1 except Exception: count = 0 if count > 0: raise ValidationError(dic) def __str__(self): return self.nombre + ' ' + self.primer_apellido
class Service(models.Model): # URL part. Django accepts only exactly 'slug' field in urls.py slug = models.SlugField( max_length=16, blank=False, null=False, unique=True, verbose_name='Фрагмент URL на английском (навсегда)') name = models.CharField(max_length=64, blank=False, null=False, unique=True, verbose_name='Название') announcements = BBCodeTextField(blank=True, null=True, verbose_name='Объявления') instruction = BBCodeTextField( blank=True, null=True, verbose_name='Инструкция и подробное описание') image = DefaultImageField(blank=False, null=False) timestep = models.TimeField( blank=False, null=False, verbose_name='Минимальное время использования (шаг времени)') max_continuous_orders = models.PositiveSmallIntegerField( blank=False, null=False, default=1, verbose_name='Максимум непрерывных заказов на одну машинку') default_price = models.PositiveSmallIntegerField( blank=True, null=True, verbose_name='Цена по-умолчанию за шаг времени', default=0) edited = models.DateTimeField( auto_now=True, verbose_name='Последнее редактирование этих данных') is_active = models.BooleanField(default=True, blank=False, null=False, verbose_name='Работает') default_works_from = models.TimeField( blank=False, null=False, default=datetime.time(0, 0, 0), verbose_name='Начало рабочего времени по-умолчанию') default_works_to = models.TimeField( blank=False, null=False, default=datetime.time(00, 00, 00), verbose_name='Конец рабочего времени по-умолчанию') days_to_show = models.PositiveSmallIntegerField( default=3, validators=[MinValueValidator(1)], blank=False, null=False, verbose_name='Дней на заказ') time_after_now = models.TimeField( blank=False, null=False, default=datetime.time(0, 20, 0), verbose_name='Времени на запись после начала') time_margin_start = models.TimeField( blank=False, null=False, default=datetime.time(0, 0, 0), verbose_name='Время на вход до заказа') time_margin_end = models.TimeField( blank=False, null=False, default=datetime.time(0, 0, 0), verbose_name='Время на вход после заказа') late_cancel_multiplicator = models.FloatField( blank=False, null=False, validators=[MinValueValidator(0)], default=1.0, verbose_name='На сколько умножить при поздней отмене') working_times = GenericRelation(WorkingTime, content_type_field='content_type', object_id_field='object_id') working_time_exceptions = GenericRelation( WorkingTimeException, content_type_field='content_type', object_id_field='object_id') responsible_user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, blank=True, null=True, verbose_name='Ответственное лицо') responsible_room = models.CharField(max_length=32, blank=True, null=True, verbose_name='Комната ответственного') request_document = models.FileField( validators=[ FileExtensionValidator(allowed_extensions=[ 'doc', 'docx', 'pdf', 'odt', 'png', 'jpg', 'jpeg' ]) ], blank=True, null=True, verbose_name='Служебка (doc/docx/pdf/odt/png/jpg/jpeg)') is_single_item = models.BooleanField(default=False, blank=False, null=False, verbose_name='Один предмет сервиса') is_finished_hidden = models.BooleanField( default=True, blank=False, null=False, verbose_name='Скрывать прошедшие интервалы') order = models.PositiveSmallIntegerField(default=0, blank=False, null=False, verbose_name='Порядок показа') disable_lock = models.BooleanField(default=False, blank=False, null=False, verbose_name='ОТКЛЮЧИТЬ ЗАМКИ') def get_time_margin_start(self): t = self.time_margin_start if t == datetime.time.min: return None if t.hour: return t.strftime('%H:%M:%S') else: return t.strftime('%M:%S') def get_time_margin_end(self): t = self.time_margin_end if t == datetime.time.min: return None if t.hour: return t.strftime('%H:%M:%S') else: return t.strftime('%M:%S') def is_time_margin_end(self): return self.time_margin_end != datetime.time.min def get_absolute_url(self): return reverse('service:service', args=[self.slug]) def __str__(self): return self.name # Return { 'works_from', 'works_to', 'is_weekend', 'is_exception' } # 'is_exception' means that Item can apply only its own exceptions # or None if not working def get_working_time(self, day): # is_active is immediate if not self.is_active: return None if isinstance(day, datetime.datetime): day = day.date() if not isinstance(day, datetime.date): raise TypeError('day must be datetime.date') # PRIORITY (extended: see Item): Service[default] < # < Service[working_time] < Service[exception] # exception wte_service = get_working_time_exception_query(self, day) if wte_service.exists(): exception = wte_service.first() dt = to_dt(day, exception.works_from, exception.works_to) return { 'works_from': dt['start'], 'works_to': dt['end'], 'is_weekend': exception.is_weekend, 'is_exception': True } # working_time wt_service = get_working_time_query(self, day) if wt_service.exists(): working_time = wt_service.first() dt = to_dt(day, working_time.works_from, working_time.works_to) return { 'works_from': dt['start'], 'works_to': dt['end'], 'is_weekend': working_time.is_weekend, 'is_exception': False } # default dt = to_dt(day, self.default_works_from, self.default_works_to) return { 'works_from': dt['start'], 'works_to': dt['end'], 'is_weekend': False, 'is_exception': False } # Return {'date','datestr', # 'is_weekend': bool, # 'items': {'name': { # 'is_open','price','rowspan', # 'time':[TimetableInterval] # } # } # 'timetable': [TimetableInterval] # } # or None if not working def get_timetable(self, date, user): # is_active is immediate if not self.is_active: return None weekdays = [ 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье' ] s = '{0} {1}'.format(weekdays[date.weekday()], date.strftime('%d.%m')) service_working_time = self.get_working_time(date) if service_working_time['is_weekend']: return { 'date': s, 'is_weekend': True, 'items': None, 'timetable': None } timetables = TimetableList(self.timestep) # key = '' means 'service timetable' => it will be ignored service_timetable = Timetable(self.timestep, start=service_working_time['works_from'], first=service_working_time['works_from'], last=service_working_time['works_to'], end=service_working_time['works_to']) #print(' Adding service {0}'.format(service_timetable)) timetables.add_timetable({'': service_timetable}) for t in list(self.items.all()): #print('# Next') item_timetable_info = t.get_timetable(date) if not t.is_active or item_timetable_info['is_weekend']: #print('weekend') item_timetable = service_timetable item_timetable.is_open = False else: #print('own for {0}'.format(t.name)) item_timetable = item_timetable_info['timetable'] #print(item_timetable) #print(' Adding {0}'.format(item_timetable)) timetables.add_timetable({t.name: item_timetable}, item_timetable_info['is_exception'] if item_timetable_info else False) # Start check if all items are closed is_not_all_weekend = False # need to be called, because the result uses copy() final_timetables = timetables.get_timetables() for k in final_timetables: #if k: # print(str(final_timetables[k].is_open)) if k and final_timetables[k].is_open: is_not_all_weekend = True break if not is_not_all_weekend: return { 'date': s, 'is_weekend': True, 'items': None, 'timetable': None } # End check if all items are closed timetables.clear_closed_rows() #print(str(timetables._timetables)) #print(timetables) #print(final_timetables) final_timetables = timetables.get_timetables() #for t in final_timetables.values(): # print('Stored start({0}) and end({1})'.format(t.start, t.end)) now = timezone.now() if self.is_finished_hidden and date == timezone.now().date(): timetables.crop_start(now, leave_head_cell=True, floor_crop=True) final_timetables = timetables.get_timetables() result = {'date': s, 'is_weekend': False, 'items': {}} # Database needs to order properly for it in list(self.items.all()): t = final_timetables[it.name] lst = t.gen_head(now) lst.extend( t.gen_list_limited(self.max_continuous_orders, 'user', user, now)) lst.extend(t.gen_tail(now)) result['items'][it.name] = { 'is_open': t.is_open, 'price': it.get_price(), 'rowspan': t.timesteps_num, 'time': lst } lst = final_timetables[''].gen_head(now) lst.extend(final_timetables[''].gen_list(now)) lst.extend(final_timetables[''].gen_tail(now)) result['timetable'] = lst return result # Return [{'date','datestr', # 'is_weekend': bool, # 'items': {'name': ...} # }] # or None if not working def gen_timetable_layout(self, user): # is_active is immediate if not self.is_active: return None result = [] now = timezone.now().date() for i in range(self.days_to_show): result.append( self.get_timetable(now + datetime.timedelta(days=i), user)) return result # TODO: delete def get_timetable_list(self): # cleans trailing 'closed' marks def clean_starting(time_lst): # Flag to 'break' double loop clean_flag = True index = 0 result = {} while clean_flag == True: for it in time_lst.values(): if (it['time'] and 'closed' not in it['time'][index] and 'weekend' not in it['time'][index]): clean_flag = False if index == 0: result['time_start'] = it['time'][0]['time_start'] else: result['time_end'] = it['time'][-1]['time_end'] if clean_flag == True: for it in time_lst.values(): del it['time'][index] else: if index == 0: # in Python [-1] returns last element index = -1 clean_flag = True else: return result def get_closed_for_gdc(lst, result_lst): num = 0 for l in lst: if 'closed' in l: num += 1 elif num != 0: result_lst.append( types.SimpleNamespace(t_steps_per_order=num)) num = 0 if num != 0: result_lst.append(types.SimpleNamespace(t_steps_per_order=num)) def final_prepare_first_day(final_lst, latest_time): # Removes leading passed cells # 'latest_time' is used in 'weekend' case if not final_lst or not final_lst[0]['items']: return # First day lst = final_lst[0] earliest_time = None now = timezone.now().time() # Weekends have no 'time_start' or 'time_end' weekend_lst = [] # Find the earliest time for it in list(lst['items'].values()): if it['time'] and 'weekend' not in it['time'][0]: t_list = it['time'] for t in t_list: if ((t['time_end'] > now or t['time_end'] == datetime.time(0, 0, 0)) and (earliest_time == None or earliest_time > t['time_start'])): earliest_time = t['time_start'] break if not earliest_time: earliest_time = datetime.time(23, 59, 59) # Remove all before 'earliest' for i in range(len(lst['time_layout'])): if lst['time_layout'][i]['time_start'] >= earliest_time: lst['time_layout'] = lst['time_layout'][i:] break td = ( datetime.datetime.combine(datetime.date.min, self.time_step) - datetime.datetime.min) # Fill [earliest, next time_start] # with 'closed' cells with duration=1 for k in lst['items']: t = lst['items'][k]['time'] # Empty case if not t: t_start = datetime.datetime.combine( datetime.date.min, earliest_time) while t_start < datetime.datetime.combine( datetime.datetime.min, latest_time): t.append({ 'time_start': t_start.time(), 'time_end': (t_start + td).time(), 'closed': True }) t_start += td elif 'weekend' not in t[0]: for i in range(len(t)): if t[i]['time_start'] >= earliest_time: t = t[i:] t_start = datetime.datetime.combine( datetime.date.min, t[0]['time_start']) while (t_start >= datetime.datetime.min + td and (t_start - td).time() >= earliest_time): t.insert( 0, { 'time_start': (t_start - td).time(), 'time_end': t[0]['time_start'], 'closed': True }) t_start = datetime.datetime.combine( datetime.date.min, t[0]['time_start']) break lst['items'][k]['time'] = t else: # A big single cell lst['items'][k]['time'] = [{ 'weekend': True, 'time_start': earliest_time, 'time_end': latest_time }] # collect available_time from all Items items = {} for item in list(self.items.all().order_by('name')): items[item.name] = item.get_available_time() weekdays = [ 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота', 'Воскресенье' ] # timedelta is available for datetime only now = timezone.now() # To be used in final_prepare_first_day latest_time_first_day = None # start generating result result_lst = [] for i in range(self.days_to_show): result_lst.append({ 'day': '{0} {1}'.format( weekdays[(now + datetime.timedelta(days=i)).date().weekday()], (now + datetime.timedelta(days=i)).strftime('%d.%m')), 'dateyear': str((now + datetime.timedelta(days=i)).date()), 'items': {}, 'time_layout': [] }) # This is used twice: # First: item names to create time layout # Second: time layout tmp_lst = [] for name, value in items.items(): result_lst[i]['items'][name] = {} result_lst[i]['items'][name]['time'] = items[name][i] # If not set, 'weekend' case will not be set result_lst[i]['items'][name]['rowspan'] = 1 if 'weekend' not in items[name][i][0].keys(): tmp_lst.append(name) if not tmp_lst: result_lst[i]['global_weekend'] = True else: # get gcd to make cells smaller if all of them are big tmp_lst = list(self.items.all().filter(name__in=tmp_lst)) for m in result_lst[i]['items'].values(): get_closed_for_gdc(m['time'], tmp_lst) res = tmp_lst[0].t_steps_per_order for c in tmp_lst[1:]: res = gcd(res, c.t_steps_per_order) for it in tmp_lst: # we have poisoned tmp_lst in get_closed_for_gcd if hasattr(it, 'name'): result_lst[i]['items'][it.name]['rowspan'] = int( it.t_steps_per_order / res) # erase trailing 'closed' time_start_end = clean_starting(result_lst[i]['items']) # generate time_layout td = (datetime.datetime.combine(datetime.date.min, self.time_step) - datetime.datetime.min) * res t_start = datetime.datetime.combine( datetime.date.min, time_start_end['time_start']) t_end = datetime.datetime.combine(datetime.date.min, time_start_end['time_end']) if t_end.time() == datetime.time(0, 0, 0): t_end += datetime.timedelta(days=1) tmp_lst = [] while t_start + td <= t_end: tmp_lst.append({ 'time_start': t_start.time(), 'time_end': (t_start + td).time() }) t_start += td result_lst[i]['time_layout'] = tmp_lst if i == 0: # latest in layout latest_time_first_day = tmp_lst[-1]['time_end'] # Make first day smaller if 'global_weekend' not in result_lst[0]: final_prepare_first_day(result_lst, latest_time_first_day) return result_lst # Return [{}] # Return {item_name: {price, timesteps_per_order}} def get_item_info(self): result = {} for it in self.items.all(): result[it.name] = { 'price': it.get_price(), 'timesteps_per_order': self.t_steps_per_order } return result_lst def clean(self): #if self.default_works_to < self.default_works_from: # raise ValidationError('Please, set working times in 1 day') if self.is_single_item and self.items.count() != 1: raise ValidationError( 'If is_single_item is set, their count must be = 1 too') # Django doesn`t call full_clean (clean_fields, clean, validate_unique) # no save() by default def save(self, *args, **kwargs): self.full_clean() return super(Service, self).save(*args, **kwargs) def __str__(self): return self.name class Meta: verbose_name = 'Сервис' verbose_name_plural = 'Сервисы' ordering = ['order']
class Video(models.Model): id = models.AutoField(primary_key=True) title = models.CharField(blank=True, max_length=100, default='') title_id = models.CharField(blank=True, max_length=10, default='') rx_title = models.CharField(blank=True, max_length=100, default='') media = models.FileField( upload_to='library', validators=[FileExtensionValidator(['mp4', 'mkv'])]) cover = models.CharField(blank=True, max_length=250, default='') year = models.CharField(blank=True, max_length=12, default='') rating = models.CharField(blank=True, max_length=4, default='') plot = models.TextField(blank=True, max_length=1500, default='') genre1 = models.CharField(blank=True, max_length=20, default='') genre2 = models.CharField(blank=True, max_length=20, default='') genre3 = models.CharField(blank=True, max_length=20, default='') popularity = models.CharField(blank=True, max_length=10, default='') is_published = models.BooleanField(default=True) mpaa_rating = models.IntegerField(blank=True, default=0) list_date = models.DateTimeField(default=datetime.now, blank=True) tagline = models.TextField(blank=True, max_length=200, default='') actor1 = models.CharField(blank=True, max_length=100, default='') actor2 = models.CharField(blank=True, max_length=100, default='') actor3 = models.CharField(blank=True, max_length=100, default='') actor4 = models.CharField(blank=True, max_length=100, default='') actor5 = models.CharField(blank=True, max_length=100, default='') actor6 = models.CharField(blank=True, max_length=100, default='') budget = models.IntegerField(blank=True, default=0) kwords0 = models.CharField(blank=True, max_length=60, default='') kwords1 = models.CharField(blank=True, max_length=60, default='') kwords2 = models.CharField(blank=True, max_length=60, default='') kwords3 = models.CharField(blank=True, max_length=60, default='') kwords4 = models.CharField(blank=True, max_length=60, default='') kwords5 = models.CharField(blank=True, max_length=60, default='') kwords6 = models.CharField(blank=True, max_length=60, default='') kwords7 = models.CharField(blank=True, max_length=60, default='') kwords8 = models.CharField(blank=True, max_length=60, default='') kwords9 = models.CharField(blank=True, max_length=60, default='') bonus_tag1 = models.CharField(blank=True, max_length=30, default='') bonus_tag2 = models.CharField(blank=True, max_length=30, default='') # def save(self, *args, **kwargs): def save(self, *args, **kwargs): if self.title: r = requests.get( f'https://api.themoviedb.org/3/search/movie?api_key=c81378bff6e0ed65976caaace3ea2306&language=en-US&query={self.title}&page=1&include_adult=false' ) try: self.title_id = r.json()['results'][0]['id'] except: self.title_id = '' try: self.rx_title = r.json()['results'][0]['title'] except: self.rx_title = '' try: self.cover = r.json()['results'][0]['poster_path'] except: self.cover = '/sH6030EbSzOUTFFZrpnTdSpeNP0.jpg' try: self.year = r.json()['results'][0]['release_date'] except: self.year = '' try: self.rating = r.json()['results'][0]['vote_average'] except: self.rating = '' try: self.plot = r.json()['results'][0]['overview'] except: self.plot = '' try: self.popularity = r.json()['results'][0]['popularity'] except: self.popularity = '' x = requests.get( f'https://api.themoviedb.org/3/movie/{self.title_id}?api_key=c81378bff6e0ed65976caaace3ea2306&language=en-US&append_to_response=credits' ) try: self.tagline = x.json()['tagline'] except: self.tagline = '' try: self.genre1 = x.json()['genres'][0]['name'] except: self.genre1 = '' try: self.genre2 = x.json()['genres'][1]['name'] except: self.genre2 = '' try: self.genre3 = x.json()['genres'][2]['name'] except: self.genre3 = '' try: self.actor1 = x.json()['credits']['cast'][0]['name'] except: self.actor1 = '' try: self.actor2 = x.json()['credits']['cast'][1]['name'] except: self.actor2 = '' try: self.actor3 = x.json()['credits']['cast'][2]['name'] except: self.actor3 = '' try: self.actor4 = x.json()['credits']['cast'][3]['name'] except: self.actor4 = '' try: self.actor5 = x.json()['credits']['cast'][4]['name'] except: self.actor5 = '' try: self.actor6 = x.json()['credits']['cast'][5]['name'] except: self.actor6 = '' try: self.budget = x.json()['budget'] except: self.budget = 0 x = requests.get( f'https://api.themoviedb.org/3/movie/{self.title_id}/keywords?api_key=c81378bff6e0ed65976caaace3ea2306' ) try: self.kwords0 = x.json()['keywords'][0]['name'] except: self.kwords0 = '' try: self.kwords1 = x.json()['keywords'][1]['name'] except: self.kwords1 = '' try: self.kwords2 = x.json()['keywords'][2]['name'] except: self.kwords2 = '' try: self.kwords3 = x.json()['keywords'][3]['name'] except: self.kwords3 = '' try: self.kwords4 = x.json()['keywords'][4]['name'] except: self.kwords4 = '' try: self.kwords5 = x.json()['keywords'][5]['name'] except: self.kwords5 = '' try: self.kwords6 = x.json()['keywords'][6]['name'] except: self.kwords6 = '' try: self.kwords7 = x.json()['keywords'][7]['name'] except: self.kwords7 = '' try: self.kwords8 = x.json()['keywords'][8]['name'] except: self.kwords8 = '' try: self.kwords9 = x.json()['keywords'][9]['name'] except: self.kwords9 = '' elif self.title_id: x = requests.get( f'https://api.themoviedb.org/3/movie/{self.title_id}?api_key=c81378bff6e0ed65976caaace3ea2306&language=en-US&append_to_response=credits' ) try: self.rx_title = x.json()['original_title'] except: self.rx_title = '' try: self.cover = x.json()['poster_path'] except: self.cover = '/sH6030EbSzOUTFFZrpnTdSpeNP0.jpg' try: self.year = x.json()['release_date'] except: self.year = '' try: self.rating = x.json()['vote_average'] except: self.rating = '' try: self.plot = x.json()['overview'] except: self.plot = '' try: self.popularity = x.json()['popularity'] except: self.popularity = '' try: self.tagline = x.json()['tagline'] except: self.tagline = '' try: self.genre1 = x.json()['genres'][0]['name'] except: self.genre1 = '' try: self.genre2 = x.json()['genres'][1]['name'] except: self.genre2 = '' try: self.genre3 = x.json()['genres'][2]['name'] except: self.genre3 = '' try: self.actor1 = x.json()['credits']['cast'][0]['name'] except: self.actor1 = '' try: self.actor2 = x.json()['credits']['cast'][1]['name'] except: self.actor2 = '' try: self.actor3 = x.json()['credits']['cast'][2]['name'] except: self.actor3 = '' try: self.actor4 = x.json()['credits']['cast'][3]['name'] except: self.actor4 = '' try: self.actor5 = x.json()['credits']['cast'][4]['name'] except: self.actor5 = '' try: self.actor6 = x.json()['credits']['cast'][5]['name'] except: self.actor6 = '' try: self.budget = x.json()['budget'] except: self.budget = 0 x = requests.get( f'https://api.themoviedb.org/3/movie/{self.title_id}/keywords?api_key=c81378bff6e0ed65976caaace3ea2306' ) try: self.kwords0 = x.json()['keywords'][0]['name'] except: self.kwords0 = '' try: self.kwords1 = x.json()['keywords'][1]['name'] except: self.kwords1 = '' try: self.kwords2 = x.json()['keywords'][2]['name'] except: self.kwords2 = '' try: self.kwords3 = x.json()['keywords'][3]['name'] except: self.kwords3 = '' try: self.kwords4 = x.json()['keywords'][4]['name'] except: self.kwords4 = '' try: self.kwords5 = x.json()['keywords'][5]['name'] except: self.kwords5 = '' try: self.kwords6 = x.json()['keywords'][6]['name'] except: self.kwords6 = '' try: self.kwords7 = x.json()['keywords'][7]['name'] except: self.kwords7 = '' try: self.kwords8 = x.json()['keywords'][8]['name'] except: self.kwords8 = '' try: self.kwords9 = x.json()['keywords'][9]['name'] except: self.kwords9 = '' super().save(*args, **kwargs) def get_absolute_url(self): return reverse('video', args=[str(self.id)])
class LabelTemplate(models.Model): """ Base class for generic, filterable labels. """ class Meta: abstract = True # Each class of label files will be stored in a separate subdirectory SUBDIR = "label" @property def template(self): return self.label.path def __str__(self): return "{n} - {d}".format(n=self.name, d=self.description) name = models.CharField( blank=False, max_length=100, verbose_name=_('Name'), help_text=_('Label name'), ) description = models.CharField( max_length=250, blank=True, null=True, verbose_name=_('Description'), help_text=_('Label description'), ) label = models.FileField( upload_to=rename_label, unique=True, blank=False, null=False, verbose_name=_('Label'), help_text=_('Label template file'), validators=[FileExtensionValidator(allowed_extensions=['html'])], ) enabled = models.BooleanField( default=True, verbose_name=_('Enabled'), help_text=_('Label template is enabled'), ) def get_record_data(self, items): """ Return a list of dict objects, one for each item. """ return [] def render_to_file(self, filename, items, **kwargs): """ Render labels to a PDF file """ records = self.get_record_data(items) writer = LabelWriter(self.template) writer.write_labels(records, filename) def render(self, items, **kwargs): """ Render labels to an in-memory PDF object, and return it """ records = self.get_record_data(items) writer = LabelWriter(self.template) buffer = io.BytesIO() writer.write_labels(records, buffer) return buffer
class UploadModelForm(forms.Form): name = forms.CharField(max_length=50) yaml_file = forms.FileField( validators=[FileExtensionValidator(allowed_extensions=["yaml"])])
class Post(models.Model): publisher = models.ForeignKey('auth.User', on_delete=models.CASCADE, related_name='publisher_article_set') author = models.ForeignKey('auth.User', on_delete=models.CASCADE, related_name='author_article_set', blank=True, null=True) title = models.CharField(max_length=150) status = models.CharField(max_length=15, choices=STATUS_CHOICES, default = 'nowy') text = models.TextField() start_date = models.DateTimeField() publish_date = models.DateTimeField() modify_date = models.DateTimeField(blank=True, null=True) QM_id = models.DecimalField(max_digits=20, decimal_places=0, blank=True, null=True) tictet_number = models.CharField(max_length = 30, blank = True, null = True) is_deleted = models.BooleanField(default = False) long_term = models.BooleanField(default = False) change = models.TextField(max_length = 20, blank=True, null=True) file = models.FileField( upload_to = "", null=True, blank=True, validators=[validate_file_size, FileExtensionValidator(list_of_extensions)]) history = HistoricalRecords() def publish(self, request, start_date, start_time, status): self.publish_date = timezone.now() self.modify_date = timezone.now() self.publisher = request.user if status != "do podjęcia": self.author = request.user self.change = "Stworzyłem" self.start_date = start_date + ' ' + start_time self.save_file() self.save() def edit(self, start_date, change, status): self.start_date = start_date self.modify_date = timezone.now() self.change = change if status == "do podjęcia": self.author = None self.save_file() self.save() def author_change(self, new_post_author, change): self.modify_date = timezone.now() self.author = User.objects.get(username=new_post_author) self.change = change self.save() def __str__(self): return self.title def get_absolute_file_url(self): if self.file.name: file_f = FileSystemStorage() return file_f.url(self.file.name) else: return "" def save_file(self): if self.file.name: file_f = FileSystemStorage() file_f.save(self.file.name, self.file) def if_there_is_a_file_return_text(self): file_f = FileSystemStorage() if file_f.url(self.file.name) == "/media/": return "" else: return "załącznik" def if_post_have_file_icon(self): if self.file.name: return "fas fa-file" def get_ticket_number_icon(self): if self.tictet_number: return "fas fa-book-open" def get_ticket_number(self): if self.tictet_number: return self.tictet_number else: return "" def get_author(self): if self.author: return self.author else: return "" def get_Qm_id(self): if self.QM_id: return self.QM_id else: return "" def get_QM_id_icon(self): if self.QM_id: return "fas fa-lightbulb" else: return ""
(RegexValidator('[0-9]+'), '1234', None), (RegexValidator(re.compile('[0-9]+')), '1234', None), (RegexValidator('.*'), '', None), (RegexValidator(re.compile('.*')), '', None), (RegexValidator('.*'), 'xxxxx', None), (RegexValidator('x'), 'y', ValidationError), (RegexValidator(re.compile('x')), 'y', ValidationError), (RegexValidator('x', inverse_match=True), 'y', None), (RegexValidator(re.compile('x'), inverse_match=True), 'y', None), (RegexValidator('x', inverse_match=True), 'x', ValidationError), (RegexValidator(re.compile('x'), inverse_match=True), 'x', ValidationError), (RegexValidator('x', flags=re.IGNORECASE), 'y', ValidationError), (RegexValidator('a'), 'A', ValidationError), (RegexValidator('a', flags=re.IGNORECASE), 'A', None), (FileExtensionValidator(['txt']), ContentFile('contents', name='fileWithUnsupportedExt.jpg'), ValidationError), (FileExtensionValidator(['txt']), ContentFile('contents', name='fileWithUnsupportedExt.JPG'), ValidationError), (FileExtensionValidator(['txt']), ContentFile('contents', name='fileWithNoExtension'), ValidationError), (FileExtensionValidator(['']), ContentFile('contents', name='fileWithAnExtension.txt'), ValidationError), (FileExtensionValidator([]), ContentFile('contents', name='file.txt'), ValidationError), (FileExtensionValidator(['']), ContentFile('contents', name='fileWithNoExtension'), None), (FileExtensionValidator(['txt']), ContentFile('contents', name='file.txt'), None),
from django.core.validators import FileExtensionValidator from rest_framework import validators from utils.regex import REGEX_PHONE def validate_phone(phone): if not REGEX_PHONE.match(phone): raise validators.ValidationError('手机号不合法') ZipFileExtensionValidator = FileExtensionValidator(['zip'])
def test_file_extension_equality(self): self.assertEqual(FileExtensionValidator(), FileExtensionValidator()) self.assertEqual(FileExtensionValidator(['txt']), FileExtensionValidator(['txt'])) self.assertEqual(FileExtensionValidator(['TXT']), FileExtensionValidator(['txt'])) self.assertEqual(FileExtensionValidator(['TXT', 'png']), FileExtensionValidator(['txt', 'png'])) self.assertEqual( FileExtensionValidator(['txt']), FileExtensionValidator(['txt'], code='invalid_extension')) self.assertNotEqual(FileExtensionValidator(['txt']), FileExtensionValidator(['png'])) self.assertNotEqual(FileExtensionValidator(['txt']), FileExtensionValidator(['png', 'jpg'])) self.assertNotEqual( FileExtensionValidator(['txt']), FileExtensionValidator(['txt'], code='custom_code')) self.assertNotEqual( FileExtensionValidator(['txt']), FileExtensionValidator(['txt'], message='custom error message'))
class CreateSrcPlatesMultiForm(FormFieldPopoverMixin, MultiFormMixin): numSrcPlates = forms.IntegerField( required=False, label="Number of plates", help_text="Number of plates you wish to create") plateLibDataFile = forms.FileField( required=False, label="Source plate(s) file [.csv]", help_text=".csv file defining where compounds are in plate", validators=[FileExtensionValidator(['csv'])], widget=forms.FileInput(attrs={'accept': ".csv"})) # templateSrcPlates = forms.ModelMultipleChoiceField( # queryset=Plate.objects.none(), # required=False, label="Template source plates", # help_text="Source plates marked as 'template' from which to import") templateSrcPlates = GroupedMutlipleModelChoiceField( queryset=Plate.objects.none(), required=False, label="Template source plates", help_text="Source plates marked as 'template' from which to import", choices_groupby='experiment', ) def __init__(self, exp, *args, **kwargs): template_qs = kwargs.pop('template_src_plates_qs') super().__init__(*args, **kwargs) if template_qs: self.fields['templateSrcPlates'].queryset = template_qs # make from crispy self.helper = FormHelper() self.helper.layout = Layout( Div( Div(HTML(""" <h5 class="form-option-title collapse-btn collapsed" data-toggle="collapse" data-target="#option1-content"> Option 1: Import .csv file </h5> """), css_class='card-header'), Div( Div(Row( Column('numSrcPlates', css_class='col'), Column('plateLibDataFile', css_class='col'), css_class='form-row align-items-start', ), css_class='card-body'), css_class='collapse', id='option1-content', ), css_class="card form-option", ), Div( Div(HTML(""" <h5 class="form-option-title collapse-btn collapsed" data-toggle="collapse" data-target="#option2-content"> Option 2: Copy from templates </h5> """), css_class='card-header'), Div( Div(Row( Column('templateSrcPlates', css_class='col'), css_class='form-row align-items-start', ), css_class='card-body'), css_class='collapse', id='option2-content', ), css_class="card form-option", ), HTML("""<br>"""), Column('action', css_class='hidden'), Submit('submit', 'Submit')) def checkOptionOneValid(self): f = self.cleaned_data.get('plateLibDataFile') numSrcPlates = self.cleaned_data.get('numSrcPlates') headers_required = ['zinc_id', 'well', 'plate_idx'] plate_idxs = [] #list of unique plate_idx's if f: try: if f.size >= 2.5e6: raise OverflowError headers = [] content = [] for c in f.chunks(): reader = csv.reader(str(c, encoding='utf-8').split('\n'), delimiter=',') headers = next(reader) headers_map = dict([(v, i) for i, v in enumerate(headers)]) try: content.extend(headers) for row in reader: plate_idx = int(row[headers_map['plate_idx']]) if plate_idx not in plate_idxs: plate_idxs.append(plate_idx) content.extend(row) except KeyError: pass # will be handled with headers_missing list below headers_missing = list( compress( headers_required, list( map(lambda h: not (h in headers), headers_required)))) if headers_missing: self.add_error( 'plateLibDataFile', ValidationError( ('Missing .csv headers %(value)s'), code='invalid', params={'value': headers_missing}, )) if [x + 1 for x in range(numSrcPlates) ] != [x for x in sorted(plate_idxs)]: self.add_error( 'plateLibDataFile', 'Range of number of plates should match set of unique plate_idx' ) f.open( ) #have to reopen file after validation...or just send file contents except (ValueError, OverflowError) as e: if type(e) is OverflowError: self.add_error('plateLibDataFile', 'File is too big!') def clean(self): cd = super().clean() numSrcPlates = cd.get('numSrcPlates', None) plateLibDataFile = cd.get('plateLibDataFile', None) templateSrcPlates = cd.get('templateSrcPlates', None) optionOneValid = all([numSrcPlates, plateLibDataFile]) optionTwoValid = all([templateSrcPlates]) if optionOneValid and optionTwoValid: self.add_error(None, "Please only fill out one option.") elif (not (optionOneValid) and not (optionTwoValid)): self.add_error( None, 'Invalid form. Please choose only ONE of Option 1 or Option 2 and make sure all fields for whichever option are filled.' ) else: self.checkOptionOneValid() return cd
class Order(models.Model): ORDER_STATUS_CHOICES = (("NP", "Payment Pending"), ("PL", "Order Placed"), ("RS", "Ready To Ship"), ("SH", "Shipped"), ("CN", "Cancelled")) user = models.ForeignKey(User, on_delete=models.CASCADE) items = models.ManyToManyField("carts_app.CartItem", blank=True) shipping_charges = models.DecimalField(max_digits=7, decimal_places=2, default=100.00) other_charges = models.DecimalField(max_digits=7, decimal_places=2, default=0.00) sub_total = models.DecimalField(max_digits=7, decimal_places=2, default=0.00) total_amount = models.DecimalField(max_digits=7, decimal_places=2, default=0.00) txn_id = models.CharField(verbose_name="Order Id", max_length=32, default=txn_id_generator) delivery_expected = models.DateField(blank=True, null=True) bill = models.FileField(upload_to="orders/bills/", blank=True, null=True, validators=[ FileExtensionValidator(allowed_extensions=[ 'pdf', ]), ]) line_1 = models.CharField(max_length=264, blank=True) line_2 = models.CharField(max_length=264, blank=True) locality = models.CharField(max_length=64, blank=True) zip_code = models.CharField(max_length=6, blank=True) phone = models.CharField(max_length=13, blank=True) bill_sms_sent = models.BooleanField(default=False) shipped_sms_sent = models.BooleanField(default=False) placed_sms_sent = models.BooleanField(default=False) rs_sms_sent = models.BooleanField(default=False) created_on = models.DateTimeField(auto_now_add=True) status = models.CharField(max_length=2, choices=ORDER_STATUS_CHOICES, default="NP") is_payed = models.BooleanField(default=False) def __str__(self): return "{} - {} Rupees".format(self.user.phone, self.total_amount) @property def get_address_text(self): return "{}, {}, {}, {}".format(self.line_1, self.line_2, self.locality, self.zip_code) @property def get_delivery_expected(self): if self.delivery_expected: return self.delivery_expected.strftime("%d %b, %Y") else: return "Expected Delivery Date will be informed soon" @property def get_absolute_url(self): return reverse_lazy("orders:detail", kwargs={"pk": str(self.id)}) @property def get_created_date(self): return self.created_on.strftime("%d %b, %Y") @property def get_status(self): return self.get_status_display() @property def get_bill_download_link(self): if self.bill: return reverse_lazy("orders:bill_download", kwargs={"txn_id": self.txn_id}) else: return "" @property def get_create_payment_url(self): return reverse_lazy("payments:paytm_create_payment", kwargs={'txn_id': self.txn_id}) @property def get_admin_email_message(self): return "Order placed with amount {amount} with order id {order_id} on {date}\n\nOrder Details :-\n\n" \ "\tOrder Id = {order_id}\n\tShipping Charges{sh_charges}\n\tSub Total = {sub_total}" \ "\n\tTotal Ammount = {amount}\n\tDate & Time = {date}\n\nVisit Administration Panel on {url}" \ " to check details of order.\nThank You.".format(amount=self.total_amount, order_id=self.txn_id, date=self.created_on, sh_charges=self.shipping_charges, sub_total=self.sub_total, url=str(settings.SITE_DOMAIN + '/admin/orders/order/{}/change/'.format(self.id))) def send_bill_sms(self): url = "http://2factor.in/API/V1/{}/ADDON_SERVICES/SEND/TSMS".format( settings.API_KEY_2FA) data = { "From": "ALPHAH", "To": str(self.user.phone), "TemplateName": "BILL_SMS", "VAR1": str(self.user.get_short_name), "VAR2": str(self.txn_id), "VAR3": str(self.total_amount), "VAR4": str(settings.SITE_DOMAIN) + str(self.get_bill_download_link), "VAR5": str(self.get_delivery_expected), "VAR6": str(settings.SITE_DOMAIN) + str(self.get_absolute_url), } response = requests.post(url, data=data) response_dict = json.loads(response.content) print("BILL SMS : ", response_dict) if response_dict['Status'] == "Success": self.bill_sms_sent = True self.save() def send_shipped_sms(self): pass def send_placed_sms(self): url = "http://2factor.in/API/V1/{}/ADDON_SERVICES/SEND/TSMS".format( settings.API_KEY_2FA) data = { "From": "ALPHAH", "To": str(self.user.phone), "TemplateName": "PLACED_SMS", "VAR1": str(self.user.get_short_name), "VAR2": str(self.txn_id), "VAR3": str(self.total_amount), "VAR4": str(settings.SITE_DOMAIN) + str(self.get_absolute_url), } response = requests.post(url, data=data) response_dict = json.loads(response.content) if response_dict['Status'] == "Success": self.placed_sms_sent = True self.save() def send_rs_sms(self): url = "http://2factor.in/API/V1/{}/ADDON_SERVICES/SEND/TSMS".format( settings.API_KEY_2FA) data = { "From": "ALPHAH", "To": str(self.user.phone), "TemplateName": "PLACED_SMS", "VAR1": str(self.user.get_short_name), "VAR2": str(self.txn_id), "VAR3": str(self.total_amount), "VAR4": str(settings.SITE_DOMAIN) + str(self.get_absolute_url), } response = requests.post(url, data=data) response_dict = json.loads(response.content) if response_dict['Status'] == "Success": self.rs_sms_sent = True self.save() def save(self, force_insert=False, force_update=False, using=None, update_fields=None): if not self.placed_sms_sent and self.status == "PL": self.send_placed_sms() if not self.bill_sms_sent and self.bill and self.delivery_expected: self.send_bill_sms() if not self.rs_sms_sent and self.status == "RS": self.send_rs_sms() return super().save() def send_email_to_admin(self): subject = "New Order placed on www.alphahub.in" send_mail(subject=subject, message=self.get_admin_email_message, from_email=settings.EMAIL_FROM, recipient_list=[ settings.ADMIN_EMAIL, ]) return True