| 115 | |
| 116 | |
| 117 | class Photo(UUIDModel, VersionedModel): |
| 118 | library = models.ForeignKey(Library, related_name='photos', on_delete=models.CASCADE) |
| 119 | visible = models.BooleanField(default=False) |
| 120 | taken_at = models.DateTimeField(null=True) |
| 121 | taken_by = models.CharField(max_length=128, blank=True, null=True) |
| 122 | aperture = models.DecimalField(max_digits=3, decimal_places=1, null=True) |
| 123 | exposure = models.CharField(max_length=8, blank=True, null=True) |
| 124 | iso_speed = models.PositiveIntegerField(null=True) |
| 125 | focal_length = models.DecimalField(max_digits=4, decimal_places=1, null=True) |
| 126 | flash = models.BooleanField(null=True) |
| 127 | metering_mode = models.CharField(max_length=64, null=True) |
| 128 | drive_mode = models.CharField(max_length=64, null=True) |
| 129 | shooting_mode = models.CharField(max_length=64, null=True) |
| 130 | camera = models.ForeignKey(Camera, related_name='photos', null=True, on_delete=models.CASCADE) |
| 131 | lens = models.ForeignKey(Lens, related_name='photos', null=True, on_delete=models.CASCADE) |
| 132 | latitude = models.DecimalField(max_digits=9, decimal_places=6, null=True) |
| 133 | longitude = models.DecimalField(max_digits=9, decimal_places=6, null=True) |
| 134 | altitude = models.DecimalField(max_digits=6, decimal_places=1, null=True) |
| 135 | star_rating = models.PositiveIntegerField( |
| 136 | help_text='assign rating to photo', verbose_name="Rating", null=True, blank=True) |
| 137 | preferred_photo_file = models.ForeignKey('PhotoFile', related_name='+', null=True, on_delete=models.SET_NULL) # File selected by the user that is the best version to be used |
| 138 | thumbnailed_version = models.PositiveIntegerField(default=0) # Version from photos.utils.thumbnails.THUMBNAILER_VERSION at time of generating the required thumbnails declared in settings.THUMBNAIL_SIZES |
| 139 | deleted = models.BooleanField(default=False) |
| 140 | |
| 141 | class Meta: |
| 142 | ordering = ['-taken_at'] |
| 143 | |
| 144 | def __str__(self): |
| 145 | return str(self.id) |
| 146 | |
| 147 | # @property |
| 148 | # def country(self): |
| 149 | # return country_from_point_field(self.location) |
| 150 | |
| 151 | def thumbnail_url(self, thumbnail): |
| 152 | return '/thumbnails/{}x{}_{}_q{}/{}.jpg'.format(thumbnail[0], thumbnail[1], thumbnail[2], thumbnail[3], self.id) |
| 153 | |
| 154 | def thumbnail_path(self, thumbnail): |
| 155 | return str(Path(settings.THUMBNAIL_ROOT) / 'photofile' / '{}x{}_{}_q{}/{}.jpg'.format(thumbnail[0], thumbnail[1], thumbnail[2], thumbnail[3], self.base_file.id)) |
| 156 | |
| 157 | @property |
| 158 | def base_file(self): |
| 159 | preferred_files = [] |
| 160 | if self.preferred_photo_file: |
| 161 | preferred_files = [self.preferred_photo_file] |
| 162 | if not preferred_files: |
| 163 | preferred_files = self.files.all().order_by('-file_modified_at') |
| 164 | if preferred_files: |
| 165 | return preferred_files[0] |
| 166 | return None |
| 167 | |
| 168 | @property |
| 169 | def base_image_path(self): |
| 170 | return self.base_file.base_image_path |
| 171 | |
| 172 | @property |
| 173 | def download_url(self): |
| 174 | library_url = self.library.get_library_path_store().url |