diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/fixtures/initial_data-fr.json | 50 | ||||
| -rw-r--r-- | ishtar_common/forms.py | 14 | ||||
| -rw-r--r-- | ishtar_common/forms_common.py | 8 | ||||
| -rw-r--r-- | ishtar_common/models.py | 20 | ||||
| -rw-r--r-- | ishtar_common/static/media/style.css | 9 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/window_field_multiple.html | 2 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/window_field_url.html | 2 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/sheet_source.html | 43 | ||||
| -rw-r--r-- | ishtar_common/templates/welcome.html | 1 | ||||
| -rw-r--r-- | ishtar_common/templatetags/link_to_window.py | 17 | ||||
| -rw-r--r-- | ishtar_common/utils.py | 58 | ||||
| -rw-r--r-- | ishtar_common/views.py | 6 | ||||
| -rw-r--r-- | ishtar_common/wizards.py | 2 |
13 files changed, 207 insertions, 25 deletions
diff --git a/ishtar_common/fixtures/initial_data-fr.json b/ishtar_common/fixtures/initial_data-fr.json index 24a0d7a6c..3c8aab20b 100644 --- a/ishtar_common/fixtures/initial_data-fr.json +++ b/ishtar_common/fixtures/initial_data-fr.json @@ -1190,5 +1190,55 @@ "order": 1, "txt_idx": "sampling" } + }, + { + "pk": 25, + "model": "ishtar_common.titletype", + "fields": { + "comment": null, + "available": true, + "txt_idx": "dr", + "label": "Dr." + } + }, + { + "pk": 21, + "model": "ishtar_common.titletype", + "fields": { + "comment": null, + "available": true, + "txt_idx": "mr", + "label": "M." + } + }, + { + "pk": 22, + "model": "ishtar_common.titletype", + "fields": { + "comment": null, + "available": true, + "txt_idx": "ms", + "label": "Mlle" + } + }, + { + "pk": 24, + "model": "ishtar_common.titletype", + "fields": { + "comment": null, + "available": true, + "txt_idx": "md", + "label": "Mme" + } + }, + { + "pk": 23, + "model": "ishtar_common.titletype", + "fields": { + "comment": null, + "available": true, + "txt_idx": "mr and miss", + "label": "Mr and Mrs" + } } ] diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 79ca2c360..b0e8cb43c 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -207,7 +207,12 @@ class ManageOldType(object): if prefix not in k: continue new_k = k[len(prefix) + 1:] - for val in kwargs['data'].getlist(k): + items = [] + if hasattr(kwargs['data'], 'getlist'): + items = kwargs['data'].getlist(k) + else: + items = [kwargs['data'][k]] + for val in items: if not val: continue if new_k not in self.init_data: @@ -216,7 +221,12 @@ class ManageOldType(object): if 'initial' in kwargs and kwargs['initial']: for k in kwargs['initial']: if k not in self.init_data or not self.init_data[k]: - for val in kwargs['initial'].getlist(k): + items = [] + if hasattr(kwargs['initial'], 'getlist'): + items = kwargs['initial'].getlist(k) + else: + items = [kwargs['initial'][k]] + for val in items: if not val: continue if k not in self.init_data: diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index f6889ae1f..2788283db 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -649,6 +649,7 @@ class MergeOrganizationForm(MergeForm): ###################### class SourceForm(ManageOldType, forms.Form): form_label = _(u"Documentation informations") + file_upload = True associated_models = {'source_type': models.SourceType} title = forms.CharField(label=_(u"Title"), validators=[validators.MaxLengthValidator(200)]) @@ -677,6 +678,13 @@ class SourceForm(ManageOldType, forms.Form): required=False) duplicate = forms.BooleanField(label=_(u"Has a duplicate"), required=False) + image = forms.ImageField( + label=_(u"Image"), help_text=mark_safe( + _(u"<p>Heavy images are resized to: %(width)dx%(height)d " + u"(ratio is preserved).</p>") % { + 'width': settings.IMAGE_MAX_SIZE[0], + 'height': settings.IMAGE_MAX_SIZE[1]}), + required=False, widget=widgets.ImageFileInput()) def __init__(self, *args, **kwargs): super(SourceForm, self).__init__(*args, **kwargs) diff --git a/ishtar_common/models.py b/ishtar_common/models.py index c536b64ae..087e772e7 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -331,6 +331,8 @@ class GeneralType(Cached, models.Model): @classmethod def _get_initial_types(cls, initial, type_pks): new_vals = [] + if not initial: + return [] for value in initial: try: pk = int(value) @@ -580,10 +582,21 @@ class ImageModel(models.Model): null=True) IMAGE_MAX_SIZE = settings.IMAGE_MAX_SIZE THUMB_MAX_SIZE = settings.THUMB_MAX_SIZE + IMAGE_PREFIX = '/' class Meta: abstract = True + def __init__(self, *args, **kwargs): + super(ImageModel, self).__init__(*args, **kwargs) + image = self._meta.get_field_by_name("image")[0] + IMAGE_PREFIX = self.IMAGE_PREFIX + if not IMAGE_PREFIX.endswith('/'): + IMAGE_PREFIX += u'/' + image.upload_to = IMAGE_PREFIX + thumbnail = self._meta.get_field_by_name("thumbnail")[0] + thumbnail.upload_to = IMAGE_PREFIX + "thumbs/" + def has_changed(self, field): if not self.pk: return True @@ -941,7 +954,8 @@ class IshtarSiteProfile(models.Model, Cached): homepage = models.TextField( _(u"Home page"), null=True, blank=True, help_text=_(u"Homepage of Ishtar - if not defined a default homepage " - u"will appear. Use the markdown syntax.")) + u"will appear. Use the markdown syntax. {random_image} " + u"can be used to display a random image.")) file_external_id = models.TextField( _(u"File external id"), default="{settings__ISHTAR_LOCAL_PREFIX}{year}-{numeric_reference}", @@ -2200,6 +2214,7 @@ pre_delete.connect(pre_delete_import, sender=Import) class Organization(Address, Merge, OwnPerms, ValueGetter): TABLE_COLS = ('name', 'organization_type',) + SHOW_URL = 'show-organization' name = models.CharField(_(u"Name"), max_length=500) organization_type = models.ForeignKey(OrganizationType, verbose_name=_(u"Type")) @@ -2540,7 +2555,7 @@ class Format(GeneralType): verbose_name_plural = _(u"Formats") -class Source(models.Model): +class Source(ImageModel, models.Model): title = models.CharField(_(u"Title"), max_length=300) external_id = models.CharField(_(u"External ID"), max_length=12, null=True, blank=True) @@ -2575,6 +2590,7 @@ class Source(models.Model): duplicate = models.BooleanField(_(u"Has a duplicate"), default=False) TABLE_COLS = ['title', 'source_type', 'authors', 'associated_url'] COL_LINK = ['associated_url'] + IMAGE_PREFIX = 'sources' class Meta: abstract = True diff --git a/ishtar_common/static/media/style.css b/ishtar_common/static/media/style.css index 02f4d930b..c6a151dc8 100644 --- a/ishtar_common/static/media/style.css +++ b/ishtar_common/static/media/style.css @@ -920,6 +920,11 @@ a.photo{ margin-right:auto; } +.welcome-image{ + padding: 1em; + text-align: center; +} + .dashboard table.resume th{ text-align:center; padding:0.5em; @@ -1276,6 +1281,10 @@ table.table-form td input{ border-color:#922; } +.clean-table.small { + width: auto; +} + .clean-table { margin: 10px 0 10px 0; width: 100%; diff --git a/ishtar_common/templates/ishtar/blocks/window_field_multiple.html b/ishtar_common/templates/ishtar/blocks/window_field_multiple.html index d1ee25c7b..cc817490c 100644 --- a/ishtar_common/templates/ishtar/blocks/window_field_multiple.html +++ b/ishtar_common/templates/ishtar/blocks/window_field_multiple.html @@ -1,6 +1,6 @@ {% load i18n %}{% if data.count %}{% if li %}<li>{% else %}<p>{% endif %}<label>{% trans caption %}{% trans ":"%}</label> <span class='value'>{% for d in data.all %} - {% if forloop.counter0 %}, {% endif %}{{ d }} + {% if forloop.counter0 %} ; {% endif %}{{ d }} {% endfor %}</span> {% if li %}</li>{% else %}</p>{% endif %} {% endif %} diff --git a/ishtar_common/templates/ishtar/blocks/window_field_url.html b/ishtar_common/templates/ishtar/blocks/window_field_url.html index 637366d1d..d63ebdca9 100644 --- a/ishtar_common/templates/ishtar/blocks/window_field_url.html +++ b/ishtar_common/templates/ishtar/blocks/window_field_url.html @@ -1,3 +1,3 @@ {% load i18n %}{% if link %}{% if li %}<li>{% else %}<p>{% endif %}<p><label>{% trans caption %}{% trans ":"%}</label> -<span class='value'><a target="_blank" href='{{link|safe}}'>{% if link_name %}{{link_name}}{% else %}{% trans "link" %}{% endif %}</a></span>{% if li %}</li>{% else %}</p>{% endif %} +<span class='value'><a target="_blank" href='{{link|safe}}'>{% if link_name %}{{link_name}}{% else %}{{link}}{% endif %}</a></span>{% if li %}</li>{% else %}</p>{% endif %} {% endif%} diff --git a/ishtar_common/templates/ishtar/sheet_source.html b/ishtar_common/templates/ishtar/sheet_source.html index 653087753..08406286d 100644 --- a/ishtar_common/templates/ishtar/sheet_source.html +++ b/ishtar_common/templates/ishtar/sheet_source.html @@ -4,26 +4,33 @@ {% block content %} {% block window_nav %}{% endblock %} {% block general %} -{% field "Title" item.title %} -{% field "Index" item.index %} -{% field "Source type" item.source_type %} -{% field "Format type" item.format_type %} -{% field "Scale" item.scale %} -{% field_url "Web link" item.associated_url %} -{% field_multiple "Authors" item.authors %} -{% field "Item number" item.item_number %} -{% field "Ref." item.reference %} -{% field "Internal ref." item.internal_reference %} -{% field "Creation date" item.creation_date %} -{% field "Receipt date" item.receipt_date %} -{% field "Receipt date in documentation" item.receipt_date_in_documentation %} -{% field "Has a duplicate" item.duplicate %} -{% field "Description" item.description %} -{% field "Comment" item.comment %} -{% field "Additional information" item.additional_information %} -{% endblock %} {% block related %} {% field "Related item" item.owner %} {% endblock %} + +{% if item.image %} +<a href='{{item.image.url}}' rel="prettyPhoto" title="{{item.label}}" class='photo'><img src='{{item.thumbnail.url}}'/></a> +{% endif%} + +<ul class='form-flex'> +{% field_li "Title" item.title %} +{% field_li "Index" item.index %} +{% field_li "Source type" item.source_type %} +{% field_li "Format type" item.format_type %} +{% field_li "Scale" item.scale %} +{% field_li_url "Web link" item.associated_url %} +{% field_li "Authors" item.authors|add_links:'person' %} +{% field_li "Item number" item.item_number %} +{% field_li "Ref." item.reference %} +{% field_li "Internal ref." item.internal_reference %} +{% field_li "Creation date" item.creation_date %} +{% field_li "Receipt date" item.receipt_date %} +{% field_li "Receipt date in documentation" item.receipt_date_in_documentation %} +{% field_li "Has a duplicate" item.duplicate %} +{% field_li "Description" item.description %} +{% field_li "Comment" item.comment %} +{% field_li "Additional information" item.additional_information %} +</ul> +{% endblock %} {% endblock %} diff --git a/ishtar_common/templates/welcome.html b/ishtar_common/templates/welcome.html index 42935d8f9..eb9de475e 100644 --- a/ishtar_common/templates/welcome.html +++ b/ishtar_common/templates/welcome.html @@ -2,6 +2,7 @@ {% load url from future %} <h2>{% trans "Welcome in Ishtar, open source software for management and inventory of archaeological data" %}</h2> +{{random_image}} <p>{% trans "Some useful links:" %}</p> <ul> <li><a href='https://ishtar-archeo.net' target="_blank">{% trans "Presentation site and blog" %}</a>{% trans ":"%} {% trans "stay tuned with Ishtar news!" %}</li> diff --git a/ishtar_common/templatetags/link_to_window.py b/ishtar_common/templatetags/link_to_window.py index 79666eba8..93924b77a 100644 --- a/ishtar_common/templatetags/link_to_window.py +++ b/ishtar_common/templatetags/link_to_window.py @@ -10,6 +10,8 @@ register = Library() @register.filter def link_to_window(item): + if not item: + return "" return mark_safe( u' <a class="display_details" href="#" ' u'onclick="load_window(\'{}\')">' @@ -34,6 +36,21 @@ def link_to_modify(item): return reverse(item.MODIFY_URL, args=[item.pk]) +@register.filter +def add_links(items, extra_attr=''): + html = [] + if hasattr(items, 'all'): + items = list(items.all()) + if not items: + return [] + for item in items: + item_lnk = item + if extra_attr: + item_lnk = getattr(item, extra_attr) + html.append(u"{} {}".format(unicode(item), link_to_window(item_lnk))) + return mark_safe(u" ; ".join(html)) + + @register.inclusion_tag('ishtar/blocks/modify_toolbar.html', takes_context=True) def modify_toolbar(context, item, action): diff --git a/ishtar_common/utils.py b/ishtar_common/utils.py index 9fe7a3a00..cb45d32e1 100644 --- a/ishtar_common/utils.py +++ b/ishtar_common/utils.py @@ -17,9 +17,13 @@ # See the file COPYING for details. +import random + from django.conf import settings from django.core.cache import cache -from django.utils.translation import ugettext +from django.core.urlresolvers import reverse +from django.utils.safestring import mark_safe +from django.utils.translation import ugettext_lazy as _, ugettext from django.template.defaultfilters import slugify @@ -56,3 +60,55 @@ def shortify(lbl, number=20): if len(lbl) <= number: return lbl return lbl[:number - len(SHORTIFY_STR)] + SHORTIFY_STR + + +def mode(array): + most = max(list(map(array.count, array))) + return list(set(filter(lambda x: array.count(x) == most, array))) + + +def _get_image_link(item): + return mark_safe(u""" + <div class="welcome-image"> + <img src="{}"/><br/> + <em>{} - {}</em> + <a href="#" onclick="load_window(\'{}\')"> + <i class="fa fa-info-circle" aria-hidden="true"></i> + </a> + <a href="." title="{}"> + <i class="fa fa-random" aria-hidden="true"></i> + </a><br/> + </div>""".format( + item.thumbnail.url, + unicode(item.__class__._meta.verbose_name), + unicode(item), + reverse(item.SHOW_URL, args=[item.pk, '']), + unicode(_(u"Load another random image?")))) + + +def get_random_item_image_link(): + from archaeological_operations.models import Operation + from archaeological_context_records.models import ContextRecord + from archaeological_finds.models import Find + ope_image_nb = Operation.objects.filter(image__isnull=False).count() + cr_image_nb = ContextRecord.objects.filter(image__isnull=False).count() + find_image_nb = Find.objects.filter(image__isnull=False).count() + + image_total = ope_image_nb + cr_image_nb + find_image_nb + if not image_total: + return '' + + image_nb = random.randint(0, image_total - 1) + if image_nb >= 0 and image_nb < ope_image_nb: + return _get_image_link( + Operation.objects.filter(image__isnull=False).all()[image_nb]) + if image_nb >= ope_image_nb and image_nb < (cr_image_nb + ope_image_nb): + return _get_image_link( + ContextRecord.objects.filter(image__isnull=False).all()[ + image_nb - ope_image_nb]) + if image_nb >= (cr_image_nb + ope_image_nb): + return _get_image_link( + Find.objects.filter(image__isnull=False).all()[ + image_nb - ope_image_nb - cr_image_nb]) + # should never happen except in case of deletion during the excution + return '' diff --git a/ishtar_common/views.py b/ishtar_common/views.py index 79d3054b3..ea2eda462 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -62,6 +62,7 @@ from archaeological_operations.forms import DashboardForm as DashboardFormOpe from archaeological_files.forms import DashboardForm as DashboardFormFile from ishtar_common.forms import FinalForm, FinalDeleteForm +from ishtar_common.utils import get_random_item_image_link from ishtar_common import forms_common as forms from ishtar_common import wizards from ishtar_common.models import HistoryError, PRIVATE_FIELDS, \ @@ -81,6 +82,11 @@ def index(request): profile = get_current_profile() if hasattr(profile, 'homepage') and profile.homepage: dct['homepage'] = markdown(profile.homepage) + if '{random_image}' in dct['homepage']: + dct['homepage'] = dct['homepage'].replace( + '{random_image}', get_random_item_image_link()) + else: + dct['random_image'] = get_random_item_image_link() try: return render_to_response('index.html', dct, context_instance=RequestContext(request)) diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index a42e2d8b5..7fc22f1a9 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -26,6 +26,7 @@ from django.contrib.formtools.wizard.views import NamedUrlWizardView, \ from django.contrib.sites.models import Site from django.core.exceptions import ObjectDoesNotExist from django.core.files.images import ImageFile +from django.core.files.storage import default_storage from django.core.mail import send_mail from django.db.models.fields.files import FileField from django.db.models.fields.related import ManyToManyField @@ -123,6 +124,7 @@ class Wizard(NamedUrlWizardView): wizard_templates = {} filter_owns = {} current_obj_slug = '' + file_storage = default_storage ''' # buggy and unecessary... |
