diff --git a/ram/bookshelf/admin.py b/ram/bookshelf/admin.py index 808caf5..abae703 100644 --- a/ram/bookshelf/admin.py +++ b/ram/bookshelf/admin.py @@ -263,10 +263,6 @@ class CatalogAdmin(SortableAdminBase, admin.ModelAdmin): ) return form - @admin.display(description="Scales") - def get_scales(self, obj): - return "/".join(s.scale for s in obj.scales.all()) - def download_csv(modeladmin, request, queryset): header = [ "Catalog", @@ -292,10 +288,10 @@ class CatalogAdmin(SortableAdminBase, admin.ModelAdmin): for property in obj.property.all() ) data.append([ - obj.__str__, + obj.__str__(), obj.manufacturer.name, obj.years, - obj.get_scales, + obj.get_scales(), obj.ISBN, dict(settings.LANGUAGES)[obj.language], obj.number_of_pages, diff --git a/ram/bookshelf/models.py b/ram/bookshelf/models.py index 59a879c..6fbb3cf 100644 --- a/ram/bookshelf/models.py +++ b/ram/bookshelf/models.py @@ -35,6 +35,7 @@ class Author(models.Model): def __str__(self): return f"{self.last_name}, {self.first_name}" + @property def short_name(self): return f"{self.last_name} {self.first_name[0]}." @@ -131,7 +132,7 @@ class Book(BaseBook): @property def authors_list(self): - return ", ".join(a.short_name() for a in self.authors.all()) + return ", ".join(a.short_name for a in self.authors.all()) def get_absolute_url(self): return reverse( @@ -152,7 +153,7 @@ class Catalog(BaseBook): ordering = ["manufacturer", "publication_year"] def __str__(self): - scales = self.get_scales + scales = self.get_scales() return "%s %s %s" % (self.manufacturer.name, self.years, scales) def get_absolute_url(self): @@ -161,6 +162,6 @@ class Catalog(BaseBook): kwargs={"selector": "catalog", "uuid": self.uuid} ) - @property def get_scales(self): return "/".join([s.scale for s in self.scales.all()]) + get_scales.short_description = "Scales" diff --git a/ram/consist/models.py b/ram/consist/models.py index 79a9d75..b97b375 100644 --- a/ram/consist/models.py +++ b/ram/consist/models.py @@ -79,15 +79,19 @@ class ConsistItem(models.Model): def preview(self): return self.rolling_stock.image.first().image_thumbnail(100) + @property def type(self): return self.rolling_stock.rolling_class.type + @property def address(self): return self.rolling_stock.address + @property def company(self): - return self.rolling_stock.company() + return self.rolling_stock.company + @property def era(self): return self.rolling_stock.era diff --git a/ram/metadata/admin.py b/ram/metadata/admin.py index 7f4970e..81ec1a8 100644 --- a/ram/metadata/admin.py +++ b/ram/metadata/admin.py @@ -1,6 +1,7 @@ from django.contrib import admin from adminsortable2.admin import SortableAdminMixin +from ram.admin import publish, unpublish from metadata.models import ( Property, Decoder, @@ -10,6 +11,7 @@ from metadata.models import ( Company, Tag, RollingStockType, + GenericDocument, ) @@ -70,3 +72,20 @@ class RollingStockTypeAdmin(SortableAdminMixin, admin.ModelAdmin): list_display = ("__str__",) list_filter = ("type", "category") search_fields = ("type", "category") + + +@admin.register(GenericDocument) +class GenericDocumentAdmin(admin.ModelAdmin): + readonly_fields = ("size",) + list_display = ( + "__str__", + "description", + "private", + "size", + "download", + ) + search_fields = ( + "description", + "file", + ) + actions = [publish, unpublish] diff --git a/ram/metadata/migrations/0021_genericdocument.py b/ram/metadata/migrations/0021_genericdocument.py new file mode 100644 index 0000000..16283a2 --- /dev/null +++ b/ram/metadata/migrations/0021_genericdocument.py @@ -0,0 +1,40 @@ +# Generated by Django 5.1.4 on 2025-01-17 09:31 + +import ram.utils +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("metadata", "0020_alter_decoderdocument_unique_together_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="GenericDocument", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("description", models.CharField(blank=True, max_length=128)), + ( + "file", + models.FileField( + storage=ram.utils.DeduplicatedStorage(), upload_to="files/" + ), + ), + ("private", models.BooleanField(default=False)), + ("tags", models.ManyToManyField(blank=True, to="metadata.tag")), + ], + options={ + "verbose_name_plural": "Generic Documents", + }, + ), + ] diff --git a/ram/metadata/models.py b/ram/metadata/models.py index cde8761..23fe45f 100644 --- a/ram/metadata/models.py +++ b/ram/metadata/models.py @@ -236,6 +236,13 @@ class Tag(models.Model): ) +class GenericDocument(Document): + tags = models.ManyToManyField(Tag, blank=True) + + class Meta: + verbose_name_plural = "Generic Documents" + + @receiver(models.signals.pre_save, sender=Manufacturer) @receiver(models.signals.pre_save, sender=Company) @receiver(models.signals.pre_save, sender=Scale) diff --git a/ram/ram/__init__.py b/ram/ram/__init__.py index 994ca4d..a995164 100644 --- a/ram/ram/__init__.py +++ b/ram/ram/__init__.py @@ -1,4 +1,4 @@ from ram.utils import git_suffix -__version__ = "0.15.6" +__version__ = "0.16.0" __version__ += git_suffix(__file__) diff --git a/ram/ram/models.py b/ram/ram/models.py index 9720b00..63d7c65 100644 --- a/ram/ram/models.py +++ b/ram/ram/models.py @@ -37,9 +37,19 @@ class Document(models.Model): def __str__(self): return "{0}".format(os.path.basename(self.file.name)) + @property def filename(self): return self.__str__() + @property + def size(self): + kb = self.file.size / 1024.0 + if kb < 1024: + size = "{0} KB".format(round(kb)) + else: + size = "{0} MB".format(round(kb / 1024.0)) + return size + def download(self): return mark_safe( 'Link'.format(self.file.url) diff --git a/ram/roster/admin.py b/ram/roster/admin.py index b6e4edd..388852a 100644 --- a/ram/roster/admin.py +++ b/ram/roster/admin.py @@ -72,11 +72,13 @@ class RollingStockJournalInline(admin.TabularInline): @admin.register(RollingStockDocument) class RollingStockDocumentAdmin(admin.ModelAdmin): + readonly_fields = ("size",) list_display = ( "__str__", "rolling_stock", "description", "private", + "size", "download", ) search_fields = ( @@ -213,6 +215,7 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin): def download_csv(modeladmin, request, queryset): header = [ + "Name", "Company", "Identifier", "Road Number", @@ -239,6 +242,7 @@ class RollingStockAdmin(SortableAdminBase, admin.ModelAdmin): for property in obj.property.all() ) data.append([ + obj.__str__(), obj.rolling_class.company.name, obj.rolling_class.identifier, obj.road_number, diff --git a/ram/roster/models.py b/ram/roster/models.py index fc6804d..3d5217d 100644 --- a/ram/roster/models.py +++ b/ram/roster/models.py @@ -125,9 +125,11 @@ class RollingStock(BaseModel): def preview(self): return self.image.first().image_thumbnail(350) + @property def country(self): return str(self.rolling_class.company.country) + @property def company(self): return str(self.rolling_class.company)