summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/fixtures/initial_data-fr.json50
-rw-r--r--ishtar_common/forms.py14
-rw-r--r--ishtar_common/forms_common.py8
-rw-r--r--ishtar_common/models.py20
-rw-r--r--ishtar_common/static/media/style.css9
-rw-r--r--ishtar_common/templates/ishtar/blocks/window_field_multiple.html2
-rw-r--r--ishtar_common/templates/ishtar/blocks/window_field_url.html2
-rw-r--r--ishtar_common/templates/ishtar/sheet_source.html43
-rw-r--r--ishtar_common/templates/welcome.html1
-rw-r--r--ishtar_common/templatetags/link_to_window.py17
-rw-r--r--ishtar_common/utils.py58
-rw-r--r--ishtar_common/views.py6
-rw-r--r--ishtar_common/wizards.py2
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...