From 4f5572b2b278ff66336972e59c9e3d63f388b83d Mon Sep 17 00:00:00 2001 From: Gustavo Fonseca Date: Thu, 18 Aug 2016 17:57:14 -0300 Subject: [PATCH 01/13] =?UTF-8?q?Cria=C3=A7=C3=A3o=20do=20atributo=20Artic?= =?UTF-8?q?leAsset.preferred=5Falt=5Ffile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acrescenta o atributo ArticleAsset.preferred_alt_file para armazenar uma versão mais leve dos arquivos TIFF. Também acrescenta a task `journalmanager.tasks.create_preferred_image_file` para criar de fato a imagem. --- ...d_field_articleasset_preferred_alt_file.py | 401 ++++++++++++++++++ scielomanager/journalmanager/models.py | 30 +- scielomanager/journalmanager/tasks.py | 85 ++++ 3 files changed, 514 insertions(+), 2 deletions(-) create mode 100644 scielomanager/journalmanager/migrations/0032_auto__add_field_articleasset_preferred_alt_file.py diff --git a/scielomanager/journalmanager/migrations/0032_auto__add_field_articleasset_preferred_alt_file.py b/scielomanager/journalmanager/migrations/0032_auto__add_field_articleasset_preferred_alt_file.py new file mode 100644 index 00000000..4c7268e7 --- /dev/null +++ b/scielomanager/journalmanager/migrations/0032_auto__add_field_articleasset_preferred_alt_file.py @@ -0,0 +1,401 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'ArticleAsset.preferred_alt_file' + db.add_column('journalmanager_articleasset', 'preferred_alt_file', + self.gf('django.db.models.fields.files.FileField')(default=u'', max_length=1024), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'ArticleAsset.preferred_alt_file' + db.delete_column('journalmanager_articleasset', 'preferred_alt_file') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'journalmanager.aheadpressrelease': { + 'Meta': {'object_name': 'AheadPressRelease', '_ormbases': ['journalmanager.PressRelease']}, + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'press_releases'", 'to': "orm['journalmanager.Journal']"}), + 'pressrelease_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.PressRelease']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.article': { + 'Meta': {'object_name': 'Article'}, + 'aid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), + 'article_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now_add': 'True', 'blank': 'True'}), + 'doi': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '2048', 'db_index': 'True'}), + 'domain_key': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '2048', 'db_index': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_aop': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'issn_epub': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'issn_ppub': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'issue': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'articles'", 'null': 'True', 'to': "orm['journalmanager.Issue']"}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'articles'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'journal_title': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}), + 'related_articles': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['journalmanager.Article']", 'null': 'True', 'through': "orm['journalmanager.ArticlesLinkage']", 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}), + 'xml': ('scielomanager.custom_fields.XMLSPSField', [], {}), + 'xml_version': ('django.db.models.fields.CharField', [], {'max_length': '9'}) + }, + 'journalmanager.articleasset': { + 'Meta': {'object_name': 'ArticleAsset'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'assets'", 'to': "orm['journalmanager.Article']"}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '1024'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'owner': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '1024'}), + 'preferred_alt_file': ('django.db.models.fields.files.FileField', [], {'default': "u''", 'max_length': '1024'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.TextField', [], {'default': "u''"}) + }, + 'journalmanager.articlecontrolattributes': { + 'Meta': {'object_name': 'ArticleControlAttributes'}, + 'article': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'control_attributes'", 'unique': 'True', 'to': "orm['journalmanager.Article']"}), + 'articles_linkage_is_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'es_is_dirty': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'es_updated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'journalmanager.articlehtmlrendition': { + 'Meta': {'unique_together': "(('article', 'lang'),)", 'object_name': 'ArticleHTMLRendition'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'htmls'", 'to': "orm['journalmanager.Article']"}), + 'build_version': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '1024'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lang': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'journalmanager.articleslinkage': { + 'Meta': {'object_name': 'ArticlesLinkage'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'link_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'referrers'", 'to': "orm['journalmanager.Article']"}), + 'link_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'referrer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'links_to'", 'to': "orm['journalmanager.Article']"}) + }, + 'journalmanager.collection': { + 'Meta': {'ordering': "['name']", 'object_name': 'Collection'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'collection': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'user_collection'", 'to': "orm['auth.User']", 'through': "orm['journalmanager.UserCollections']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}), + 'name_slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.institution': { + 'Meta': {'ordering': "['name']", 'object_name': 'Institution'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'cel': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'complement': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.issue': { + 'Meta': {'ordering': "('created', 'id')", 'object_name': 'Issue'}, + 'cover': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'ctrl_vocabulary': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'editorial_standard': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_marked_up': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'label': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'number': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}), + 'publication_end_month': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'publication_start_month': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'publication_year': ('django.db.models.fields.IntegerField', [], {}), + 'section': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Section']", 'symmetrical': 'False', 'blank': 'True'}), + 'spe_text': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'suppl_text': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'total_documents': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'default': "'regular'", 'max_length': '15'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.UseLicense']", 'null': 'True'}), + 'volume': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}) + }, + 'journalmanager.issuetitle': { + 'Meta': {'object_name': 'IssueTitle'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Issue']"}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.journal': { + 'Meta': {'ordering': "('title', 'id')", 'object_name': 'Journal'}, + 'abstract_keyword_languages': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'abstract_keyword_languages'", 'symmetrical': 'False', 'to': "orm['journalmanager.Language']"}), + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'ccn_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'through': "orm['journalmanager.Membership']", 'symmetrical': 'False'}), + 'copyrighter': ('django.db.models.fields.CharField', [], {'max_length': '254'}), + 'cover': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'enjoy_creator'", 'to': "orm['auth.User']"}), + 'ctrl_vocabulary': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'current_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'blank': 'True'}), + 'editor': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'editor_journal'", 'null': 'True', 'to': "orm['auth.User']"}), + 'editor_address': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_address_city': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'editor_address_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'editor_address_state': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'editor_address_zip': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'editor_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'editor_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_phone1': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'editor_phone2': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'editorial_standard': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'eletronic_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'final_num': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'final_vol': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'final_year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'}), + 'frequency': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index_coverage': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'init_num': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'init_vol': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'init_year': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'is_indexed_aehci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_scie': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_ssci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'languages': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Language']", 'symmetrical': 'False'}), + 'logo': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'medline_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'medline_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'blank': 'True'}), + 'notes': ('django.db.models.fields.TextField', [], {'default': "''", 'max_length': '254', 'blank': 'True'}), + 'other_previous_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}), + 'previous_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'blank': 'True'}), + 'previous_title': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'prev_title'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'print_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'pub_level': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publication_city': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publisher_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'publisher_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'publisher_state': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'scielo_issn': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'secs_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'short_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'db_index': 'True'}), + 'sponsor': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'journal_sponsor'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['journalmanager.Sponsor']"}), + 'study_areas': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals_migration_tmp'", 'null': 'True', 'to': "orm['journalmanager.StudyArea']"}), + 'subject_categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals'", 'null': 'True', 'to': "orm['journalmanager.SubjectCategory']"}), + 'subject_descriptors': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'title_iso': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'twitter_user': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'url_journal': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'url_online_submission': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.UseLicense']"}) + }, + 'journalmanager.journalmission': { + 'Meta': {'object_name': 'JournalMission'}, + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'missions'", 'to': "orm['journalmanager.Journal']"}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']", 'null': 'True'}) + }, + 'journalmanager.journaltimeline': { + 'Meta': {'object_name': 'JournalTimeline'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'statuses'", 'to': "orm['journalmanager.Journal']"}), + 'reason': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'since': ('django.db.models.fields.DateTimeField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'journalmanager.journaltitle': { + 'Meta': {'object_name': 'JournalTitle'}, + 'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'other_titles'", 'to': "orm['journalmanager.Journal']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'journalmanager.language': { + 'Meta': {'ordering': "['name']", 'object_name': 'Language'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iso_code': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}) + }, + 'journalmanager.membership': { + 'Meta': {'unique_together': "(('journal', 'collection'),)", 'object_name': 'Membership'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'reason': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'since': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'inprogress'", 'max_length': '16'}) + }, + 'journalmanager.pendedform': { + 'Meta': {'object_name': 'PendedForm'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'form_hash': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pending_forms'", 'to': "orm['auth.User']"}), + 'view_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'journalmanager.pendedvalue': { + 'Meta': {'object_name': 'PendedValue'}, + 'form': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data'", 'to': "orm['journalmanager.PendedForm']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'value': ('django.db.models.fields.TextField', [], {}) + }, + 'journalmanager.pressrelease': { + 'Meta': {'object_name': 'PressRelease'}, + 'doi': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'journalmanager.pressreleasearticle': { + 'Meta': {'object_name': 'PressReleaseArticle'}, + 'article_pid': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'press_release': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'articles'", 'to': "orm['journalmanager.PressRelease']"}) + }, + 'journalmanager.pressreleasetranslation': { + 'Meta': {'object_name': 'PressReleaseTranslation'}, + 'content': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']"}), + 'press_release': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['journalmanager.PressRelease']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'journalmanager.regularpressrelease': { + 'Meta': {'object_name': 'RegularPressRelease', '_ormbases': ['journalmanager.PressRelease']}, + 'issue': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'press_releases'", 'to': "orm['journalmanager.Issue']"}), + 'pressrelease_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.PressRelease']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.section': { + 'Meta': {'ordering': "('id',)", 'object_name': 'Section'}, + 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '21', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'legacy_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'journalmanager.sectiontitle': { + 'Meta': {'ordering': "['title']", 'object_name': 'SectionTitle'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']"}), + 'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'titles'", 'to': "orm['journalmanager.Section']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.sponsor': { + 'Meta': {'ordering': "['name']", 'object_name': 'Sponsor', '_ormbases': ['journalmanager.Institution']}, + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'symmetrical': 'False'}), + 'institution_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.Institution']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.studyarea': { + 'Meta': {'object_name': 'StudyArea'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'study_area': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.subjectcategory': { + 'Meta': {'object_name': 'SubjectCategory'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'term': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}) + }, + 'journalmanager.translateddata': { + 'Meta': {'object_name': 'TranslatedData'}, + 'field': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'translation': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.uselicense': { + 'Meta': {'ordering': "['license_code']", 'object_name': 'UseLicense'}, + 'disclaimer': ('django.db.models.fields.TextField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'license_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'reference_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.usercollections': { + 'Meta': {'unique_together': "(('user', 'collection'),)", 'object_name': 'UserCollections'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_manager': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'journalmanager.userprofile': { + 'Meta': {'object_name': 'UserProfile'}, + 'email_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'tz': ('django.db.models.fields.CharField', [], {'default': "'America/Sao_Paulo'", 'max_length': '150'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) + } + } + + complete_apps = ['journalmanager'] \ No newline at end of file diff --git a/scielomanager/journalmanager/models.py b/scielomanager/journalmanager/models.py index 3bcb1986..560c5b2a 100644 --- a/scielomanager/journalmanager/models.py +++ b/scielomanager/journalmanager/models.py @@ -31,9 +31,13 @@ from scielo_extensions import modelfields from tastypie.models import create_api_key import celery +from PIL import Image from scielomanager.utils import base28 -from scielomanager.custom_fields import ContentTypeRestrictedFileField, XMLSPSField +from scielomanager.custom_fields import ( + ContentTypeRestrictedFileField, + XMLSPSField, +) from . import modelmanagers @@ -1497,8 +1501,12 @@ class ArticleAsset(models.Model): """ article = models.ForeignKey('Article', on_delete=models.CASCADE, related_name='assets') - file = models.FileField(upload_to=make_article_directory_path('assets'), + file = models.FileField( + upload_to=make_article_directory_path('assets'), max_length=1024) + preferred_alt_file = models.FileField( + upload_to=make_article_directory_path('alt_assets'), + max_length=1024, default=u'') owner = models.CharField(max_length=1024, default=u'') use_license = models.TextField(default=u'') updated_at = models.DateTimeField(auto_now=True) @@ -1507,6 +1515,24 @@ def __repr__(self): return u'<%s id="%s" url="%s">' % (self.__class__.__name__, self.pk, self.file.url) + def is_image(self): + """Verifica se o ativo digital é uma imagem. + """ + try: + img = Image.open(self.file) + except IOError: + return False + else: + img.close() + return True + + @property + def best_file(self): + if self.preferred_alt_file: + return self.preferred_alt_file + else: + return self.file + class ArticleHTMLRendition(models.Model): """Documento HTML de uma tradução de uma instância de Article. diff --git a/scielomanager/journalmanager/tasks.py b/scielomanager/journalmanager/tasks.py index ef5b0544..3403fa59 100644 --- a/scielomanager/journalmanager/tasks.py +++ b/scielomanager/journalmanager/tasks.py @@ -15,6 +15,7 @@ from celery.utils.log import get_task_logger from django.templatetags.static import static import packtools +from PIL import Image from scielomanager.celery import app from scielomanager import connectors @@ -389,10 +390,14 @@ def create_articleasset_from_bytes(aid, filename, content, owner=None, _owner = owner or u'' _use_license = use_license or u'' + # create and save the asset asset = models.ArticleAsset(article=article, owner=_owner, use_license=_use_license) asset.file.save(filename, ContentFile(content)) + # create a preferred alternative for the asset + create_preferred_image_file.delay(asset.pk) + logger.info('New ArticleAsset %s added to Article with aid: %s.', repr(asset), aid) @@ -434,3 +439,83 @@ def create_article_html_renditions(article_pk, css_url=None, valid_only=False): return files_urls + +def convert_image_to_jpeg(filepath, mode=None, **kwargs): + """Converte a imagem no caminho `filepath` para o formato JPEG. + + Retorna um buffer com o conteúdo convertido da imagem. Pode levantar + `ValueError` caso `filepath` não seja reconhecido como uma imagem. + + :param **kwargs: (opcional) argumentos nomeados serão repassados para a + função `Image.save`, com exceção de `format` que foi pré-definido. + """ + output_buffer = io.BytesIO() + _ = kwargs.pop('format', None) + + with Image.open(filepath) as original: + if mode: + _image = original.convert(mode=mode) + else: + _image = original + + _image.save(output_buffer, format='jpeg', **kwargs) + + return output_buffer + + +@app.task +def create_preferred_image_file(asset_pk): + """Cria uma versão alternativa de `ArticleAsset.file`, preferida para o + manuseio. + + Por hora a versão preferida é o JPEG ao invés de TIFF. Para os demais + formatos não serão geradas outras versões. + + :param asset_pk: chave primária da instância de `ArticleAsset`. + """ + try: + asset = models.ArticleAsset.objects.get(pk=asset_pk) + + except models.ArticleAsset.DoesNotExist: + raise ValueError('Cannot find ArticleAsset with pk: %s' % asset_pk) + + try: + filepath = asset.file.path + except ValueError as exc: + logger.exception(exc) + logger.error('Cannot create a preferred alt file for %s. Skipping.', + filepath) + raise + + if not asset.is_image(): + logger.error('Cannot create a preferred alt file for %s. Skipping.', + filepath) + raise TypeError('Cannot create preferred alternatives for files ' + 'other than images.') + + with Image.open(asset.file.path) as _file: + if _file.format.lower() != 'tiff': + raise ValueError('Image is already in a preferred format.') + + try: + # Levanta IOError caso `filepath` não seja um arquivo de imagem. + jpeg_buffer = convert_image_to_jpeg(filepath) + except IOError as exc: + logger.exception(exc) + logger.error('Cannot create a preferred alt file for %s. Skipping.', + filepath) + raise + + _, filename = os.path.split(filepath) + filename_head, _ = os.path.splitext(filename) + + jpeg_filename = filename_head + '.jpeg' + + asset.preferred_alt_file.save(jpeg_filename, + ContentFile(jpeg_buffer.getvalue())) + + logger.info('Finished creating an alternative file for %s.', + repr(asset)) + + return asset.preferred_alt_file.url + From 0b6aba90e8faeb41d98c999dffd641f434166e20 Mon Sep 17 00:00:00 2001 From: Gustavo Fonseca Date: Wed, 24 Aug 2016 17:49:15 -0300 Subject: [PATCH 02/13] Inclui testes de unidade para as tasks --- scielomanager/journalmanager/tasks.py | 4 +- .../tests/image_test/sample_tif_image.tif | Bin 0 -> 408756 bytes .../journalmanager/tests/modelfactories.py | 15 +++ .../journalmanager/tests/tests_tasks.py | 101 ++++++++++++++++++ 4 files changed, 118 insertions(+), 2 deletions(-) create mode 100755 scielomanager/journalmanager/tests/image_test/sample_tif_image.tif diff --git a/scielomanager/journalmanager/tasks.py b/scielomanager/journalmanager/tasks.py index 3403fa59..697200f1 100644 --- a/scielomanager/journalmanager/tasks.py +++ b/scielomanager/journalmanager/tasks.py @@ -463,7 +463,7 @@ def convert_image_to_jpeg(filepath, mode=None, **kwargs): return output_buffer -@app.task +@app.task(throws=(ValueError, TypeError,)) def create_preferred_image_file(asset_pk): """Cria uma versão alternativa de `ArticleAsset.file`, preferida para o manuseio. @@ -490,7 +490,7 @@ def create_preferred_image_file(asset_pk): if not asset.is_image(): logger.error('Cannot create a preferred alt file for %s. Skipping.', filepath) - raise TypeError('Cannot create preferred alternatives for files ' + raise ValueError('Cannot create preferred alternatives for files ' 'other than images.') with Image.open(asset.file.path) as _file: diff --git a/scielomanager/journalmanager/tests/image_test/sample_tif_image.tif b/scielomanager/journalmanager/tests/image_test/sample_tif_image.tif new file mode 100755 index 0000000000000000000000000000000000000000..55ce3be02b531f336b32a502a69e398e72e29381 GIT binary patch literal 408756 zcmeF434l)3`^VoITlQp$QYIy->{+v9Cq(uoiJ39RY?=k}M_N=$J3`SS67fT*gjNbA zd$uT*z0H=f{Xg$KJe}@+-#d5S8KT}>-Z}T&=RD_}=bq(zp7WgNwrFv)=Q5ASQ`B?X zlid?SDD4W#mKJ_5)Z+;`7v@1I;cWcP17Wta@!m8!&xRrQ6bcbOU-a~Nt}tkdo(+4` z7dsn%kMNae=|9?*!*f+gjTK+q(?McLSS=xUeEi3Q2 zysXD_?r(#Lgx-;1ZTlu9CnWVv=pWXoef6-LI!DJxBn(U{=c!Vu@@=&%RjXa8dRXP^ zwX57#yGk`ro%)0N_X>}ROb+WE85JF0xAd=zmX;2Sj;LF@bG6o$TK8`h**CiR;Ka!G zgYW7PJ~$@4Rz&Ig_43piRC`cd|G3EHUSWgcV&ju)52{Th4g(pV$PmWHA5A*Wv)jJ_2xo+vw-i-7*Td%nOno)dGg|s?W z2v3NsIH*_uij^x=s;HbvSO=NZZj>0=D>)&tLqbAqJ;&Ekr=peoul)bw6xp~}a%4U4 zn=4{_FP$GqwDd`Dnv)rzO7b`>W!;bsZq6R<0?(6R<7KjX4R^-YE*4dwNjI6HLEsg zAa#cRFFAUdq)FoM?CVr?SGYQVku^$)O-O8=5D{6gs+sz)=)W>GQnhH*sBL0GpXk`g zdP(h?H4JOfq*3+CwW?PyU!_82lZ`=_)h{q2T;E*(l*HJyJ{u8UF)}vN`%02{Zy=zDI<8k#WX0s@K7Hy`{3|xA3&`7T-CE1&v%|;5RrEDbBqcW)z!-9N zO!ApBslx;PBP+IxOiD;e43BIwfGYnrFnL=?TJE)5#3v>9qII@tERBuU*0^D%+Zr@% z+^AaR#?`#7tyZlnO=?zYP_<^$hK(y%ZbB=tB{iCWJUiF$&$5lk09zxejcuF6Xr_%` zu?7wKRmcc?A1rLyG>`Un)(0%z$vb|ukG%iyv43^ewDF{Wuf(KCujK2NJ|}u}%!XR7 zI%#jPcCT>nv`{bHJBmj})T#Kl*uRQ(E>+msWYK}VG~sO|_0NA`-^h5USwL8&QTb<* zl+Y)6V6Vi;22nJ<^d=|a`1d4M)=s0`-`~r*7HWBqzNZF>Wwr-sR8*v4d&~L`vNB+; zVpj52UcpRM6m9}Rak-I_(gek&qHq%kip!0ZlqM)H6@{BXP+V@Lq%=WssVLk8g5q)` zC8Y_9OGV)(5EPdiDJe}*Tq+7TfuOkDNJ(je;!;t#2?WLEMoLN(6qky^O&};PH&RlX zptw{NZURAZxsj661jVJIa1#iM%Z-$jCMYfyg_}T7TyCVKG(mBxDBJ{s;&LM;r3s2l zMd2n86qg$*DNRsZDhfA&pt#&fNoj)OQc<`G1jXe>N=g$Hmx{toASf<3Qc{|rxKtEw z0zq-Pk&@B`#igQf69|gSjg*uoC@vL+n?O)pZlt6%L2;=l+yorOmFKUsdy(-R*c-^n zJWtJrEm~(UlXgV#^0Z&$C+%77w1}Vh^*-msAy?l1iP7=NZBml^rzCTm!yDH&DY<=b z4zZI zlFTFlN0Acxw2w?q>EEVzzi=Mr^R)FOdJ_1rk0;F2-V^Cb_M~|Fds%t%^jB)`(%3YN zO^!cXqI|tmqGOYz2(=IBhwca#JjBoVUO?>iSH?4ZdCh3#AqLK&bO_R9T#(IMs|6<)RJSOU_ zAVf+Yj%YQaG~V;4o^}yoVG#)_z3)ia>Ag+6nkB~D;u^-<=^7?Rbm$nL-1Pc(vEFy9 zSHswdFkkWQl46t7;@b|2y(96XbM$!zM22$$hZBIDmOR@k+D5faI@c<^VJ|Izy~Xyl zitHn7EZKJ8RI0CR+lR+WeA~qEJGy!~q+OSXCnogo%;A@|-WD1iA9YTA1-uX1QKp6o z$;kDR_;%4zea#1X&pn`QO7HC}*$zq>LT=@62*-)f{!Qyg zH>N!+a5hu^)PK+;?Ja*=Ty}m3rBRm9`)kv<9!k5xBF*pB!n=h`xegx0@1eM}#Ce3+8{>V_A}%V7Kj*vt z**F9Gx2Yjb_hT}I(w%@$JH6Iv)F zTcMCM+v%%$&U_Y9pHk)sNxLYp_rhyLX!aaAb6u7@Pu>vgL&p1T=N?|}3CSLkEi`** zj$An}%aJW#RUQ_~mi@XbD(7f$cdx>w?;lYmXOZV#o73?68;Z93xOdgt5+7RAC|8;1 z+yD0c@8L<+ioHJf;Ts#j&>^D9CvPNIzjAHIA0q#l_sFN~Qg$6`TK2^$kG?zRv-Lk7 zeslik8-6;{sn39sW2Y`yw(;kqHJWvf8u-|_X$zNc+I_5$Cp47OW=|_quADilr4`}2 z%2#Bk1oxLNoTJK!=Zbhs@Nv5}zg4}V_xFhpJ>RH((eR|(elL^LTYy|QR{LZvg?Qu2 zh$bDYCrAFEMetvOvVRrf%ob0+Y-xEG^3?ZiU9q=rk8j7!d1+(Kkc~$>Z5;Xj(&&_5 zK8~3bd&W~>`KCQX>L1#&=JUNJijUj5Bi^FF;Eh1k$a`WizcR#giz%{pZe<8AU!KLfI&C%=7o`fSarwyMy z_p3?I%s9De@8XJUQlGf1Q;n^gk0f08{`}jE{e1Y~*UMuX^?m2Fh?SMMFFA3l)Bif} z?{xCXelv~?Z*=nJr>nhm^r!C^&&oCJ@UY4Iw{7`oNREx8zOEG)8?&@c)AA)Mo+`Ds zZk@N!c-9RY`%Bb4Nwqr-Yf^MVQva)lwi@!$faQgjyb$$TuUX5wb{{`*&)oXE>fX}f z^IsRey?M=}txlAwIeKB`-*O&$V8N)j!n++!y?0y8%z0a*{;dD=+V-P2{FeIh@NTDG zY5n!*`;xoeTE2gD+=jb5zY$+1VZiRwYhzA-o-k#{nypXnzwSuBdb3u}E5G;M?Mqh0 zw7hHeU0W)|SMA;?by%|xCeEpHYuun6^JXQ?erC+R$aQ-+bz5-8GqXp#$F{b9vC53M zzj*uYIW2Qn-?e$nGb2~MTyl2TmyTCkdUd%;Q-5vpXRRUiHne#&vR}&3esfR1x@vID zs6Qr-+BTr>n+vL}oV>oo%d2Lut-W+Z%-$NYhnKvvKW)E*Pe0G~@dxyQS{#3;+OFMtLcHe@b5yfYp$kCz34T~Qx z`PlnE3|yGnvQ+EgGX@V?vTp9`?rTqvPF+4_TOc_^cWaW>FbsYNV zhTBh8{CVB!7xvCPF#Da&SEk18nV)xdfmO?wUbW)8WBF!wn)B7?G5dzx5?+4j#CjW2 zTMbBfXK%SjU#VaB_ybRWzI^V7n^L+ZR-Rkn=T6%ObbMsnj&>Wz4*vH2Ysbdd-@LTN z{vHXl_YB`Mq3f6<*S>o4>e^c?oCvE`VAa%p`)9qqvfR|VQPnp75?LZ{#k^dVXU{nO z{;AU2YYgqZePYixGfJHC^qu>C%a?!HKDt2s!2S6jJ3VIRyf-6;J$AU$8PEEg4lh|a zU|9PSFRN1esb`g{f71&es{(9H|Cu5_Ak$^ z+mTeE%nQ#C+i|LDc+34m7HryodUTtOsVn-;T)%DJ1OI!l;_O26ugn&;u>ATSk@N2x z{>iR6$M2o|+NqnrI=%Sklm#WDqBe~fzIjrPH^K&2N)2lozoX}d!>3BEO-+c}vbf@j zHv5M?S|lZJ`F-!bbhy^E!q*qu_WBR&-rw5e=@kPOB@L(=f7h|o&z$`1#oZ~bHh!OS z*YxMt7HD0!$_t~uj6c?8f7Mg9--L-_K!YNb?Lg!DNCjuT2OA@J3n>(rt$|Xf1h#Xk-UBT6fSu~ z$9sEh2>+q$vqx)xb)sv^1Jw^49@=Kl8P98-Ze3ZoVx_Jx@94H_>&-+M4wfn;g$q?b+0OcMY5t z6MZ`2K#2m&_I9oJ>$<83i}gHydVJM-3xECW%SF>FRr~X$1(Ds4j(omLm)~3VT`=n2 z@{x-szHoF@kJPWL?m2v_;M($?Ql1{Sr}EeRXU!ZrvES7Lb8Y68|Cb#8jdxZhLCz_|DuBybxqvR>PHF>?XsZl%Ax(b?%%cK$x^%a(O-gwWhKo(PCftOgqSa899g=1am9DLzTdOU%7N`? z=Nsu+wX)LOy3@9&EBQogM^DA=-0;BkUlu0al5#jt-(|DcCv2Yc`^=@+F8y(Mt^N0m>#%qH@y;o&`g9mt zU`CJP%Z~TixS`mlmv`UxVfV%F){h$!b9%svrQgTCb^N_zDXq5bne)z!E2n<9a{R)9 zd#_5ZQaS#$ufwMwj*Z$fa7f*5i%YdU{bScowc8ylI3s1}Q-3VGy%-+koC zuJP4gIxr(;%;4j*n0eZboOfjM#^E0iemvq-_b=XDxV~%43B49nTU4s^fn#-UA98Eo z!{t7HV8M(U^VXgUUwg(gzvq-0N@j(2H(i5v()iZVbn9Z%n zMEn?kqG_Mh_@#$;^j%!0_Ngl0O{!G4RqfNOAJ6+;joUWvNO~n@+~_l&oxkkZpSpBq zhd&aB%}PGGZE!+(^wRwA+*W_xuq_kEMQy(7*B&zu&p6Sk(a_s#)IUDpjjFGY>^*mB zx7D3K7~iGu(9y4VS+>4@$H>vA@-7&%@4LBgr;a^&_cKRh*B<*me9c|e#+Of7KJ?12 zW0o9Eoxf?o?WcM+{cz~y>8TxhK9*8rO`EAN?(O;HHrXUo zbjyi0Gh!Cs(lxcy@a9p|yI;R=Qj-On!>i_q8_;O(#IC*OOnkXYjrLJ*@iw;AdF-dt z3m=P|H2Khu@Do>Vso%NmfthPIcAfaYu|3w;Tl?E(qxQ|t`SpZNAI6_fJaNXe=8R{= z;l*v*teaD&c7?syAinu%O z{VVV8)2Qc&E^of}`FC?7fBkvU(6X_g4&1xs;hT>P|0K0}=TqGy$JeSc|J$P_pXpz# z%fT-O-M=HX#=Xbp{Q7C1GoEjD4Igo;;@$!EmNuzBW&0DO*S@tpW^VUK$L!m>FlNA< z4L@!w(lLC?iaC4drtW{^s)eU#k4~+9#xt=+tEaEcc~{(f&sX^PKZ@1M^CRcH90H`J-W;P9VGzu$8rb!v}=KR%ahZOoI=pT|uaH)mtVr&e|9 zncAk!;S$xWY#rWg-}>46o^H~m=Ae`vqZj6%-#I*XdG*fEZoE6H&7yVb$hOPv+R(1GnXuH+53a>DFd%qKH*?o!nCVWdq&4Bj-e4Odws&O)H9yf z4_7|pX|k{U%x;zEe7o=Wmu`t3GAVWIM?)XmxNz(7S#ypKo^|?zkH1QtH>OYP@$Z$*WiElZ5#qxc{cSO&=|F!p%*F15w{(^;v#|_@`=BfNWqdHd_oOj=Vma~^M z*|=oI%r|FE3#)vz$C#u4H*;#YV-a(otnyA|zEk;Qqkf$-b?BW>k9gwo#6$h=dn4Ne z+m_Y(dgk_%$2UKH&42^XbOy-o9olB?lvO=v9Iw&y@tbB3C_b&&zLj~4ZydGlKy0Ty zTVkgj*gUqzH?t4lJE`@HT~Gcr=ItIW_dU1jMD*oAtnQKks{| zZ?B*4p7?Z?n{L>6&(R?hy6oJyZC_mY`1@iOkKK6m*3LtFei{A0D?7*haj5bivlh?% zw#%yS%Tl@=>~n0`lW`q)b?#pOV3W;58}1l-w9~tTueoy9;Zx&_PMDc;yn1THyU%V- zSXBC*?bqBFo;>{G8PAzDM>;&;qD;9Po^Nqy*Hbaq*DqCYSl%+9Z;hQlvqtTy zmk)1!?=_LntQ>Z5=HZD^yLr3Q4lh|9|4@r^%RgDQzv8~$GsZ71J~wWAqdA`s|2lT= zj8}%WPnIJRYd7bEo+qb2cg9n8_+zJ^ICcH;LnqI8PX97|`;RZK-S2qIoOtTU30(zPxuVS+;dRnQxX2o*#F{Q|^bz&U=46e6(X~zu^b(xO(!Y zDmz9*wVk>mbwKLO)kQbOT)VQ=UCpLH8W%e;?vqcy>QjHl3n#ytwD{fyCkH3K)8ook zr$-InmGI{oPu+yIr+fZ7Bf8vAaVz%~A7A3DkK-29xOPIRM>{TgSH ztQ^>3OXVe-QuCB(T_p9T^*i>xQ)kt8AAC1CZv77%H;sC7|A1q)w{IOdXIk!e>!(aS zHMviGo70b+@jTkC!s&6H4-Nln^Xfw%ZaBH)WWm(oKb?A|M439%7tWkC=NZ-}-)Z)aGpm|2(#C&#sgTFKs_j_5L%SS56F{7I)?5sBial>|b^88_{3Ss6FGi z`wuLOZ{2xh_xWQtJ^E1GTeS~<{ppEoR?S^;s#*7=A3pQ$hLfku9NDoY?5E*XPZ!)f z@A!^44sSih($b>*A44GTN>z~$dU;r$bnd2el@uNr|TN5YQ~ zjvbiX-y8oM;Uc|byx~x<)QTihK*Ghn;V22;nnokxJG|kDxcCTYyk+hm5f|YNe@6K6 z0V!TpX|`5`M-GUN97uRQ;TvL8;*e3cKM5C!i|j=kNzwFO^X+HQ+T;B{JYf*YaTf;HZnQ6d|SM8_DYPvcV=Aw zUhxljJW^+GD$f-*M}BG1^5gi>pmPd(->p19ba&c23n{khueiTb{uP(-I<1Lai)_#S z71w*b$FuNJkEi&Szv6Cqm45t)$FpFyQJ-So_F}m8jE)Si;1#G|=@KZV|A3KS1#f=p z1Tn0!D1F1ctvVbZiz$g=NjOK13@dMK!~rKXie;4J)^?G7A`>HV`WM!TR>n3LuRA^> zI?Y3Abo}33H5wcOOlENK2BlpSC_Lq~r%2BVp37Gk@nk!=%9FitUQf1rCh;Uh-&?EP zofvREp3bFqOS>n`^R(Z;{e(WlZD>+-+D3w>QM(Rd;VFp&ge1H7PYzEW2J#}F61c>@ z-gA?uyr+t%hUa$A9iAqhJ3VbY9Xwq<_jG{dC-}9U2sOJQ_-drL1LkfqK2q_g(Cghfo zDj_vP>V-53X%*5gq-)51AyFamAt@pM7xHk(lOfNCObB@`WO~S)koQAA4*4=`T;p}1A%V)nmd-LoavxjHDKl`xkPi3Ew{jKZ^vVWF+UH0#@|Car9 zj{G@F=C~zC?Hny~bjcBwV_=SvImYIgnqz*B&vR_Z@l%eYIdkSLma}Zm8abQi?3%M* z&LKIU%K1vp**QPTxhChXoJVry%2guQExGFEYLly1uH;-JbB)h6GuP5wYjgdS>(9&b zURLU|Dwj3AtlMSrmpydZ*vsC&Y{_M7FWY_DiQJdxE|a@$Wtg!**tagbjZ^$&xkxP<(ZY|^E}(~9Lk$FZ|S_X^4^^{I`4ydU&{NxykF$~ zKJW2-SLC}nU!#2Y|g>ir!YVQ_(?1Cl*~?bZ4<_#cnLt zqF8LPXNt`&wy{|1mDgO^;L6A=pSW_?m20m&R{ZMXcNC8-KC1Za;v0&mmIy1+q(n@K z=SnOrvHhy-SKWNo-B%5~YSLAoUv=Q>B3Ivjb@c5kV|rRtT6F7;xmrKR?T6%A_;78~|b z*k@tCU03qD=GUcM_u6$|Uw5K(+0q?LKU8{l>Fw9&xxVK0eXf7;`cJO^?S@h}w7%j0 zZkTbymNL1^)GX7t%(ybk%N)D0?2VmoeC)=BH|{B0yljiIgUik+yX~g@H`TxC{+nLE zX??kzRUo@seViJEw9|N=GGjy*19$R*4J;{R6bw% z2IU8opHcq%3dJh4s_;;Sg%y6Octgc*6`!lPyyEFf)hfkSno?U(S4 zP~*NDFW1;qvq;UhHJ_^aMXemQ8rB+K>%&^dYgezGTzhWqUvDped(7=`-@d0#**cMR zrqtP0w{+cJbziHyvtC%e`|7<~Z)g4M>i4Sudi@{nxc-iaJEq>TyFs}I{Tj?{@Jqu= z4HFyAZ+NUx?M6czebhKx<7SOVHU7HE6-_!enb73Brlp%kHJ#D)w`SFv4QcjK^Bm1v zHh-@9rWV(<2yZdH#cy}kxO3>8pS8@_vVF@5Eq`crbF0KwAG8i_eP`OciX!s-u-jC%I*HI-SYN@+xKk$cKf3p8g_W5!`6;B zbxi5_NvDFH?&&nW)3MHtJ3rrfXP1gyhIU!m^{TGXUEk}Lt6QgTQ@b7M-lY4O?myjA z?VgeMZ0u3C$Dkfx-h0)(vG*?SS+HlXp7ZX@abM^A-oEc-uQt72?{%bii{3By{w=&w z__*->5qCtq7_m39ZshZkyZhAb^L(E@QFWtUh}zq?e&4Zu4@5VLo)GRx?A)ox; zb^kZw|GppEVCZYZLWcDo_Q~+;hd(m>rw5xo_|}L#BVtB;^-!gUo`2}@!<`@g;E`({ zdGL{4k2ZUB#>fIA6Gv`(?DoedKc4;Z=*Pc)qUsalpEx}#V$_N!D?K^($&*ioKeb|X z<+r@wxt`ZJTB&G~Hnvm2kQ|J+;87kYm1^SfSX{lbD5!(JTq;^8qp$9y^V zwy~4PmuO^r=@(eRArlY4Ou`zSZun&!*Ry zKK<>IZ$C35bVkaIy)*Bb`OQ0x-+6CV`B|^cE;jqg|9SqG^1pp^?whl5Zp*o!%&R$X z*1KiieR+Q2`J)zuEO=nSZwvb_-1%PD_tw0B=lh?0aQg@I7gbm^?ZfLnoVd8?;%AoR zS@Ot|GfM|AJ@Qfij}Cks_3^GxdVaF?(=MN`|LpG1zW%)B=U*&qy6n^C4VEwcqV5+T zep&m=_gBCBJ)pN4Xud zcUIrI`1{7+ulk|=4_kMI@7n)k(vK&9dgSN)KabsAYWMU#RrY+ix9Q$*_I2O))BgVZ zPaGI|u+YJmf4S+GcYnR(*HyoD`R%9Q6MsMR$5V$&9GZ6cw!@zsX?x_mqj5)192@m# zi9g>uUi0|!)Xu59PYgVn>*PzP%ANY)bj#D*&cyk)Ex9yezx(dHdGqFtA3uKV*s(9a z{PNPJOaJ)e53}f7w{Bg#cC8tcC1LV?EA4vq)mO=SoN?{lyEj8wyz#~x*IaW=@#4ix zl`4hv{0yc22Z?`8yH1=qVK2k6W5?`~0mqCSIdaylSpg>xCiE!*`o;bC-(S0S?bfYZ zM@B|I`skzEwr%rCX-1wpbxPj5{{D9E`t#2}P0C9;eCW_2sg_n#0!NM<$xyvgQ&Wcy z9eUesx7~T?o$tK!PKMI{cZfG^*f3(BVKyxC4npQd*Hx({T( z>kc6KKb2(n?%ha_hCOQ3sAm-Mh~eS%LgX zn3$M&9&p-dX*>YHzq?^_!!Jy6di6v0}x71q+z{|MuA9VNQSh?YBSw{PSOa z`9+x@KYo1q^5t{q&SiG9&;u2K&Cs7bc@p?RfCg#4R-rFkxbUsF-b%ijJV%Zk01xI$ z&Bb4U`Z7;RLd@k85)$5h_gy9wO33)UWXTf7z(R!zLBO~Nj0p`5jg5`<$1UJ^26-t% zbaXUX)4Ne4$mOQNOTJ8hFsW3jlH3YIMwN6+1x}#9v}w~ulISljA>Figf)79ZP&r6| zcL5F|-a<@eg@6wQKK9sSK$^I?xT~+eS|aK4^cTYXS`r3u%lHPX@bK^e(*Cnae*XDq zqz8^IR;-vvCf(mMWy%25(M|pS`|szw@NL_AcOU^UlF=uhd_qsr64tC))9mb)!m!W= z6Fzh9q5&{ONZJP;c)&t@>E2#-RodY>kLSS$AEb^_-KU>^8eHeTQXEi5GC%$F6G`gU ztxK4dQM$<)L+D4Wszj>#d-KgVr<>MJuyf~5(5)Gg?Q_0?a_ubQ{Pe*~UXU`ts?v5Qh0Oz!y>#x6FX|BBTO4cCfud+;h>2r_wI(qU=LdGh25xE2DKnFoafDowN#$jUuK(3&D}k+3;( zy5xgK*L<^Rv0Ns+0Azxl+yi44p3D~%Oc%T;BK}#Npi*ML+mtg{S|43(0cn|R^tdmW ztms+YYZ6(+NtNAfXUv!}L*+Ai^l0T{3EX$zeM-j0sO9OhWy|y_0dxWu0=Y#Eu4HJ^ zeA1Yat5&UIQX|Rv*mqEzkd%~UX6iot%{SjjbpWOAQ`sqH`c}!Xz_-&l#DFw3Edjco zPhzwOLgo)ekP2;*&^VYA07TP;ZM-=6G-%MkXGt!tNZD5sv9NOYS9tJ)u3;g@Y~Xxs zMzB_ulCVawlmwOd<(FUHtXVVBaiIxuxfjp6LwNrCa6<0fxlvJC1m*HpR7os0m7eWd z4Z94Ot1yI|(H_ARECZmtAau4C+bx&HI3HxKT6qtd1h&>zXnOJB1Vp5uE;I1*e2Ci4 zvw#2o2;V*k*eQu&`=DgWlF*wt!Bj!B^zfO`jAWNV8X><9+6;3?!{=TzN?PT^a>i~G z#g>E;JoVI5W*Hp9vuDpH6-sgkn!p}q9w!JY=4?j*8UVA*Xtz`{1kmGUXf)8tU6^2_ zVltO7LtM6O*&tvEV1H`HV2}wJVmBkrFsmxdV%B_0nCVH3A6(8;mgE=PEp1f<%dfMp zjP)b%K#9Td?w49FYpsPDGiHoEiDn0Ap%^ZEO%Ny8B`Ml4WH@Ke9Q#xEG3Z*gJxCx! z6DwPjX7VCMieRGVKKJuSDcWzw{J^qc%S`HZQQ-tEsiaf@{)^wb^4e>?ZYq6Rpjlpu zPn__<2OntDa)T3CIVwGdHpl8q{Gk1ErgW6vPSkx1cr~cHOC+*dd04RJ;YOvb9NIBfT?7AG(&{}JWGxEO&2G?8N&cnOqzrhWrnhICe|g79fw;I>V9Inh6?8c zCxD{ac5%7$g1HOUdI7u|OO?%Au}=tW-+^Mw>tpM|Wj8dlHp8M%U|OVCYLmc9)}-+l zmThQyqUsyn?LE2TnkZ8Q7^Yg>#n#PC)qBP9sLnmO8(P ziw!4m=1BX3dHzWI9Zzq$Y9sxajPee-R<<=)oP~!v$-hA^-lZib{=k4G~QKGE|Zb=@W#rxhu_HXBMsj)z;L(fJDl`T2J&{oEUPhZXiHavKfYudD_Ljim~y5w*I$Li%> zIB#ZMY&b!ev=p9AbA1<_Ymn;j>#!76dV7FD&!2XMy%o-*W$3t*@DBhd;O+@iPwWiM z1ECxeK?(fIE3c$GbldACF@h6Nm|#M$f?}J-AHBvSOz6cTR8Nuk#0khpITLVR7qe0@ z&9@{w(~uQYTULK^nI4&R+tH=LKL+S|p;ehplrh zq{E8AFsNIElP*r+w7ZN&$WzV{-~owC^5R$`BMhxYFKz*KRNO2KRxZeaCApB{M8dSc zl7#@T7?qKk$|1~h25?TnSfQ{z4W$~EUwK|l_{wT|F!uIXkvDjpA10@o+ z=V*yxLmw$|;pITil(Fr_yReYyEt+|082C8SNPFO7!wKw?OR@Q7Nu>p*F=)JlvAxo} z4=D17e@4$71%MNJ^yr}#u?NyM5%gCt!3nbXlA}h#oDCO$NhBWc6M7_8jqQEn1Uj|2 zq|jossPWg+nfe(bG;3_S(BEo8OMo47rBoA(bk`cpTx`@@SWz7ozs}fL^9n4`y?b{u zWt4N{x=^wR04I>JVZ(-6JKT@hOUp2h(X#3H0D1;tK(&Q<%9JU}%4dMplh2c?0wYNx z(~X6#-ew_AU_KQyBucf%E1*Wh;>w2Kbb)&#cWz!3lDj z64M~fB3&RY>OnbS?FJ{XTdgC2jC zlq~?9z`I~?k;c#JPco&Wp;To3$TBKm^|IguJQz?a^XMqkuKBtx;n!b(oia#A!0JX1 z_4vdIq{UWWUxWlOHgGuCpxLn&z`U94#59hy==7Le=n%o}1dxOl6 zc%J|gBR%S_heJUN0eh~q=VgiEHA&r3>hj_&Pkr77h7)v-COaAlJ=$c>s!G;npaPZ* zG%6-X9HvRxIHzDL77#3QMv=u~hoVJ`3JqE;eFaPeKFzMgum^g&iNiFPRXBn7DCR3{ zB9I*@RM)NP21Gu(me;Ax6k3MD8N~^-NyLju0DwWg!C=oXLUwbA+h_3vC&*5p=?Rl5 z*yk$~CUUY>=VJAa;!mF-$_IA1=;JaLVZI^_jJL0+wi%#Ir!+ira56805+~_Q<(uw+ zu!ZNdzGftgV(=BYV9m>Eed*@H0k(4d>OA2DiovcuS#!CE3R#5{aT+=(BC>x+8+gg6O;*qwp1!h4BDkj@*;%4 zS{jgr!Y$2O1G0P&^G=ka>EZ+uGA!u3&;S!O7*E+c1iE$WCaJLEwv(|$lBZbL*q>?) z!v#nHN(!uz5>SsutokjFvhbFTDk&$kr_Yvb$ty6Npq5&am+7#MNs|Gec#DN07)D_L zic?E5J?|UO6fCz7*S=Ah20&iY14lGZ~_CPj5Cx0m%ly>X^G4d zoFEqCcAGb1D2ZI08q=&9x>xV9$xi>yF+`=rhcg8S^IEY`_MF2dMhxqAmdJsHiA& zvkcThdxlswV?KHMjLZy9;DZHHDWvCD%s#eK9Z43oB**o>*;$T zKt-ID0HoC=KlU^B3i5V@p|clIEr11xX#e=RUcob5VH z4k!{O3;8v35eGFsty#>xe2(F=V23B0o@RDF!^|M6qi{INnt7bSxF@?>%vP*w&5CC< z%-+3nU|+^(z1&0wj1yRXN}1ibXim2z7Mx%zUHzS>7DvrAQDyFo6T~P8jIHzrMGpS!(0GIQlobImgTBpl7iF>>X3xUppkaACa65lEfxPHqT3|QFQ8SMdFkmA` ze+wl(6e#5}51ol8RUWBuG=Sn7dIx6(P^u{-ph(@PC4m*Ha(E$Q%bhBFv&x)0{%IK%1%1j_&oPZM~-LH2u zT&G(|3r>LE6e((FI|rHR7*gbsdz=70T20;YRM`?h8HnE1o|ncr-~@Ktb$iruBvzA4 z0N3=ADIYMhJkoxBzRx8AHCcjb-JP}E=G^TbCzvw=8L2-C8A%u(Ep?Y$%-gh7XlU&; zI>Nhbc=BN~csiJWXA&oD9gU3a%UIINj+I5FV=5xl zHc~S(1L8FT=1dS~yoUAo)p^AUWM|Gkh>=C8mcbs#JWdd|8~#pI=~s=AjDA~6dLIiG zQ{|{-!)U?z{3#NKn_PBp{K6+)oWKW(SR~SZ{9QaXGjf9y7+?`N@Kw}GQbL9=OkaGC zqNanUjE?_0%8`qMuSk_@h5`ZO1k;n1dviF4ve|Kh*(L2tcyKqvx8Y$=dfC2NtqpdWe0{6 z*wGNq@~bAP;&7Gi1JsEqZ)t?)#mKCw7~${**JcAOyVM|mlBk8>1&N1RXb zn%%Gmvmy>5n%pF;n?$OUG-+f9&~hk4?J#*SrpDMzNEr39Y@eZAV&1Vlm0QJ@=Nl)G z9ZOg3Q|xs*?Br$=Coq{xMttza-nHrGCPdV&Tg6no5#4E0p<$@t+z!q2w*Cx&)5QrE zK&ZK!0n>2K4NkyfR!|vBNE9Pj z7=+~lESYCcMTQy033^nS4G4dp$^yd)tV8vE`CB&H-+P8)SaXRd8P+E0Zirhr2Zj^O zN!+3rweWX&YsU#BluF5ar{kEcWS5r7-Hdd`37F7p69Rr?euFZ{Oztym9-^_#=7Ra{ zZa1|1v%c`xmdH!|1X3h_N;7D5cDn#Lf$ZwltEVC&;7^mUeKVu$S&^{CB+1NC!{<78 zPMw-X!6*dGt(cHu>LU!@{F>7@uij^pba8@DZ#foLrVh#tPM}8S3}xYFzomn#ln97b zzn#oyjQOoJ2OQ`#ZMu;G;{-kOhT%lIxws*);{;N1d_(1CuFyg9#4`+ym|f8aB^QtQwVT9e6eq9&EyX~vx=UrLU;sFQ zPAyw+D78$ZEDPt%-?GW5mRgu0x&Q7-U^qb+HRyXYUwAn9#0hB9v~8ICLG)ry0U%gQ z*3LKqVnu_(7EH)=;}i6noOPoReYhEq4H$fwzsyL&YLrDAb~xLm1DC&pSFqA4)x-%@ zA8lLKc5}FKFjMS8Rptb+5wdrOOyUGJfZNL2TOZL}5)WleD z0_|U!pYH$#u)My&aDtAO6qtP$;mJZz)Y?8hDp>OMd7Dw3!0}0yn7=);0C0kC2wGOY zKFgf>NIeJP>@dpAC@`FW(YS~U7-@0~IP4QAz)gHDN?v+C7dshZ?A<3_oIv;26N|!= zU-pHu@wP)vtqYJ?iB)3>J(2daNTgEB4QHHyB0|{O4V5)(pEv;(qL$|Z1nlQcGKmvd z%}KE{v=$bb=qXOK;%tWMu&<)C1kB@#7-LwT%IzhA6DX>A(2u37&${@GG><*1=GG@= z0Fi;=1m-e*mD<4r$lXlh6DL3*PJtx5C!TnM7}itV(ofCggww?d=(2p;$(VfbuOcUO zBu9FU`IN8&PGC1##o|x>WpV?A2rQwFy2qi09~PXz_B3M}NG1y}cKuisE98^Hi$4dm zoP-0z2`FS#AnKfD>2(piq*xM%!?iku#Y;obdSLk8AT#3jqv?iL_4*>EZ+_1Lqp_*sLT}Rg|R%+Tc0=qh=QYuEbQaLiY1jgCRMR8M%i^! znZya|QOe)GhF0HafG?Bk*ITrl7<>Ecw!*~33751!f$B(S(YjlXjr$auL|%kAL6u8c zrJ1Cr{&0eNE<$uNv&f2r_HPkdx;TM^4&7F{nPvuznU>MO0VkO1F9+u>l94DjsT5iW z&6q{+fCb`-MBAuSV=JfF-1zzOD_Bg|EWi#+uNdH{4DGLlIV0Z3{Qv2nqpz^yc|% ze}-X~iavo>XD(Fjo;Umn;UdHd>M4b?`73rtJt%YAKV}X}g!q|IOx;O!_ z%DCjO+nNQ|(ZFu5?0^#(SGAnFHZj?1SbgrPC67K*oPgTXp=&68W&+|fP0GyN?em11 z@DBhdm>)#L=+rEy+OXN}#7r{QR*2DVA)Ha1pr(cnHn#!e1PY8jwm8;fGum#OYSt*D zVFl!FT>sgb2Y?gwupUCTGYl-oA5MUqE`Go8PReE8~_{R1ww}=EXsUBAmJYX zPQb{4mM^Hu+{bbL9675tnzuux#*7(b?gH~_{1K}TmOA=7)$S7~;GRXr;zk3krl+KG zP?(s<8{K%Zv(!sn$V%BAz$^!XeME|Mc<|beA=ec*XVIV z;M06aU?+{rWbQMJ0g3Rzw$Oqr6er*V!IG8&=!d8roVTD;)%I^+l8F0Ra)*^AYfE;S zyw%UpkQZughe3~w=oBIletn+&wG@V96iQFPVoYut45(8D3kPo5q-Hd>e}F@Ag0q)4 zWvH4=Ou01D637frfEBw!@=XWO9i4)np7~1+lYA<`E#>!l8vssF-HX3{UY{8`M>62k z23RE8$*^ZL+X-QuMcB!RQH8%xe~cV^#OU3gkX5sK*>d>wu=o!ocTUcVD!^{wC(P9i z8pQsVq?jCg$kqk zHM0g<>ne%P!WnJzsf3v#bwu^oFrZ{a(oB7NW`ib6aDqZRvUBiJU^=YG(0K=yfa&;A zExYuo&wv}80BAwfE?=veO91u>;@=EGF^2m@{w9C-VL6=Wuj{EdWAbHp+rF(vM);*< zl$Hj=Cc8ar_IY`VuE74t5~Hd}yY@^~4L-M|<+LWbIM^?#hXly%0z?8*1>8*8cWEu< z4EPq6udbn3sio_-O9evN(!~k5SCaL$RK)HI&otzKhSNs&ibyjxF$ZL+dnSKb4*Q(`EQR-X8vsramAk)};x8lTctPF%nhic@Oey(u zUZe(ud@jL`pZQu4o)df)Lz^yU|2_$bL@jR~!FF)}YwpWf?5IuVzznSvp= zo^A)jCb!IlO`V||gIhdsO3BSr7!CzMbkMUdP#V)J2?de;WkD(4?{&gr0q$=LThFdK z=pI$u$<$z1KT5%T;sn!yjL)G)DlY_6m9W*`8ZfRC9uxRM#<@Ra2>hcvBOjJya>!cQngQLmz+tHw z?=#GbRm>*I1uX58hRDq01mP^2bMj(?727;;W`-^nO}e6IAq?X3S70~s8N~^@afZa~ zA4+hOqfZ)c)&0zruf8AIo7l#cv z1{t-k@z=Jc3g*@WNL9uMvv#VPM7x;oEMO*dALewA2+g@tCPV$solh5MCZ&YsxTP7d z8d1p_6%7g{N3pJ2u&`3%P4xZsc@qr7=-vMhH9nGarOSCC7aH=?I2CK=>ZM< z={b9L>Vd~RS8FHBDx3gk*0$8eS?OvofX3iqnB>fcK7ExdnVUdHae|_87VmEOLj!1} zn=mJ`Gv)70ft>tx7@8E8JB)<#)kP%3^4z{#$I&4kF_zjN$+s#nOmap(STM>#5A27X z>n`t??3}-A!_X~$LZIZLZ8Kfc&FTIu_vF(LieOn0GfVo^y*n4i`KkJZF+Z*1oJ5W2 z?50_kgh)(IGTN=wI8mEc>A!w>YjkbZVOkoP=<`8S_JNMQ3E^S~T3Q};o#9i*D`X~4 zz)b-|t2)ouQli>oUf@NTPB?jAtXvrC^`j?BPc_-Sg`OoLV>khJJ@iPdk}EG?>IRnzg* ze57G>TVJ`E9b7-jVL8a490*8VG`V>a4WlECmjDJoX4=e$#WNclzAjl|*J1i62e4sa zfL$@G02FapF7bX%{Qx`lJT?28&x{x?b!ld)GPew>K2w>NZ!CHI`9sjOvN;Yz<}!`6 z2eJ?+z+7|!%mwz0oMVt1MP-4>`CMm8H%~K)69l4A0Eh9`%vYx&l5jDVTRIfP#0aiq z7Vu{SBOh1tr+J2nWk_dyroWpdkp(GbprN8$U?N~%U}ljTG3BMJLeyOBc1LDLgmt~l zplx|%xuqDoy`Cl^k7&sV1JU85>l$JhH{6)gS+a1rMe>rVgBs0}+%grS3g9R@`f8>X zdO8Hph`Fz!S!e)gC%M>R zhSHcgfo%>(FgB`C-ty%>xoFHNDp{^FkC?urftRR`0f%&F#>{i%&Dfm6q8|Mr^k|t_ z_^`3XEpAnqB9)98jryX$MLA%%z1QM72S5veF#4*Y>SjLdWpSoza+ z`zuC9aRT$cs4o~3+|(LigSMY(RFI@)vj&vK@?3ZPrPnZAAbC2tg+Ci%bUM^lmbx&F z!bDU(aF7f5iZFStJOZpr652VDjKEkRGquUw$1;-*6uP{+&0*GdHpDemln`6Gq2xkF z4vI3$V}3#uV${^YQ7NZxJunYCs6Z`paCs{hhP3c>Rh{TVkRAq^qTe_t+E7Yszj#Wq z(KRvp(MVht2GtOq%iO1cGq1yrCm8`KjBHYyC1J@%YvGZ~zXZ8*4ng{G6*xRyH1pNj~1lE$5`QGX8Jkk#YFu{?LE@8~}$@s55%fjDs zON~hAZ=GTiqbq|FIG66rMZW>6F<~|d#g_=8Bg`XYf*q!te9baAhw0s-fpMevW=jZR zG6qr}6|%fCVjM1B3Zk%JHZ2${Uo|BXCg@RFklIHcUOj^hJ9PHE*h+Bj4!VtNdiB&Y zXu!k?8hObDSQatBvdjcQak29SHb{4^q}60(W*=5>-3Ky?6Bt0`RdS5ceJ)VSW}L;J zBvyRX8cQvJHx4DZm^jcsfGd1zAbpxIq9uR{J2Ffq!bE-nc&u0vBh00!DBr|Wla`!> zC~W|WI5P)K^07YvvxD1qO^E8AUcfkJZ}ZT|BEqMQgmNH&brVduEGMUUn?z#%XF*D4 z+JM7YP%s_1X)VYB`JhQ-m^B3}uL%@^zX~;4X7vXy8c1M2@O?-L6`b`BtUnj zg@XrlX9SNT9OCoWZq2d<5axSKAXS$N3f?Bdq;oOjm~tje@lbACE+X}vI`8ICat1dl z&c%AlA2CQkx(Ni(BNkpChJp_J)G8A_ie=YjDGh;t2Tm|+bRokT#R(kIk`AIh)MaUX z;slpzFF7(jW=sFNn4yPoPdZ#R&FL2=4HDA zM^t3~9OAht@IOey3WDle7BUXy5w}GS#%vC0FTkVo(VQ+ou>;6L3|t*fO$yH-P6$A@ znk1t*K@Ms9JA$Na?E%?baNiB>94@UGlwb@yK0V7_S{1pZODhIWSShDli}QyQ(#`t( z5o8D_=n}wEZ-bPp0PzF-N!T$Xj^&y#24?1g!YPNDl$}6i6`gd`m#a5Vn)tWc1&} z3FfYu9F@hQz>T!8YBtgoom4H~J_;bx+ z<`u*VrZh4dcE$;;EaU{==+UF$EZ;A1@RaV5`+p55APTWJb~#Tuh%WdjFbRmUnZ*^P zKUV)ioWOBKM8pUnG7%r4nb|JKB+qi*&7ZXY*?0^HFG z04}W*{@Ggp`*N345^l7G)IEq3GSdJQCtx>X=Y#DHJ%~$=rHC>ium$pe5GNo{F=_U9 zmeVfqU`$p?K-!zLX_J|ko>FmnB+yKI(S~K;f%9wj5~}|SPIB>7{Ai6BF~UyiGDb!c zyMIxa$uAfgU_f02$lxZw81e;H23gXov2cUrsiX;wR{i#di0nUEP5nX;W zll6ZyEw%^Z5rRW}DB{dZhFQ#Ya52H>m~p+88H=6&EKZA+AZ$gERQU=xK+`&YzELK zStx_I7moz~%Q!*a0)5>lhZtgBL9KU`9a+1SOE=62N1g{bSAeDh%MC35aKYe_nYnx#|Q99F)L+TmtebXN;FHC&LC(F8Qj(rQ$;2KmG=T)elPG z;*kK`b~tL|gH{-m@KGULzFR&PcJUN7SdyRwf)a2efk~4lnYLkOIHO;Fag$w;CMbcR z1peI;U~z#JI^R6P@dC#xx$Iwo`FBeoSi7JE{$&!toXqlVCVIDA!43L<*}D!_Cn$lS z1cDL>N+2kKpag;v2udI*fuIC}5(r8lD1o2^f)WTyASi*L1cDL>N+2kKpag;v2udI* zfuIC}5(r8lD1o2^f)WTyASi*L1cDL>N+2kKpag;v2udI*flF5cxWL6hI$zoNz=V*UE{7d~sgd|~(H&KDd$`Q(!eUzkfGM_k%+NcNH_>Lpjmy?gggoH%jz?Ae!G z$+NJ)Uw!qJ<;*o-vitDE5Bcm@7Ups(vSP6M{PWKXcA2N&}XVA%)>1ea^`*z|#W<4p0#{UeGT~3b-!w>XyKK>d zR?)RkC}|(0vecSyjAp1Vd^&`N$7gf-6cL|ngL8(G`y}45 zVFOMQA|oRy55?=zqsN2^6F3fO64OulDxVqiPlajfO`0^JkbnO9CuN{x(oXmiQ10Bh zk<3Nz_i6X;-IVa)!Gq^Xdiqh|#~ynu;4JuVc&&nRC=1qdpI>eZ_kC{Vz8e&HlOAOEF6O3S3ET5>+Mb75q7 zzH^ap<4V1#AoZ2XQfof+>^^s}Jxt^?mz_IzCXA1C_sK1kbhj5@e6d1>3Mz2QL-Az7 zC6b;9XvYN#>r-xL&6;K5aN%#?efM3)vA%u#(!2Sl72gxQ@x~jq{MoW)+qG-gg)f!+ z9G`vmS?1Q;Zo7@%dTu}p<3pB~4}E6Op1nkg5=_C2V0`kDg@BtZ_|R3(oHOI@RyE%|NVD3@YPzWrhMk9TD58! zsx@D-W7vVu_19l->LU2C9rKrzkQtl+O9SQ1D9Ykp8m-W{#|grO&hp-S@0qg?d;r_B z0C!NY4H`5EN=A4s%%)A7UU=aJVssY17;u7A0ksJ$ED@3Xq6UeIilP?ClW()?BfM&V z{PD+Hsq-DU`|i8RnpfaHBjzS4E$)Kdr@ELa*)NkCp(+WuoWL!Z@cn4vP^?%nZUgp+ zIB(uOongV!XzWeh8rn9Ley9z}0!Sl;rxpPhK1&i(Buc_}LWLXO9R}yH?Bx@dQbK0Q ziySA=TTy^8lGLhIOUf+2^w2x*xC8t%aNxki#6)zzpa>;k>}}k*@r)TWoW;n*&6kuV z6-XnKKJHenS_Lav8#?E!Pg(0p?w8P)$F=bP@qprlfH$p}ntA&T8#WY4qBo9nqA#DtugPlONA{oUA!ir^xFz46JH}6=oLCLph?Ij_GzAW4> z2Ap7)5Nt06vu}vJ^Ugata^#Sw{GuQ-6J|0D1VydkkBNK;V9Amt{s=7bd@Wka`R~IC zZZ={p($HH`tkL!)24|-znFE^(h7KJn5(YmztC${t{BdnF>CRJH)bkNw-;JFY>{5U}ij~Yz{3#8Y0GXVIfzNU(RS(_a_lg1KeVa4t+J^jr$-?Tgm;8q0d{!8LI z%m#5n0Mhnqm1Y4m1}VPAFf#yi^lSrW#ae$v^w-GkGe%S@=Ouwv8%Q ztf(1T0<57}-H<6`qves$TRu%FCH(i{1lEZ@tDJ5mdtM?F)NAPyI}@;66;@a{FcUcw z^K|Uku|khpFJ0pEM8HSoC@sd&7h-f<=?yvtAO3`4;1hQ1Xj1)43mE z@blA8KRGbW(4z+*e2`3C8nb~?q?|#VkRc&o48)nl3E)zB^%%DVRvo4ZECgUuxNu=- z4lI!%vwyypRH|AG3@5Byxl(GuZ+v{bLoxR3*&~!_HT{vXZ6P!l8&1F;KnliS!tSlT z{IaPnG-b+^u@eLq14DK_9MVpkHVqmS-3~PRD2NkO6dJhy{`=*vW%4tu<`&+SL<$|n_;9ug9g$7_(fajvv>OxPUa(7 zbdaeV>y#i)$h@@wDGr&$2`m+*eSZ1nmw{CQlWgITKYxCon+_&hbQkmpGe*KF+=NNy zae}jPj%atC@$jfoqogoyI=H|RQIKWpW_7`B8Des+M-A43BY{vic%P%D9*RP)$dBMUc7|9*G z8h<&;PC7J~5KdsjNLEi2+s!b-$SLL`&~tHK%%3!}JRTJmIby$^Zrcmugn)(r^wUpc zNH%BA9G4u>wPMZUo<3c+nZXIz*`~EhZzEx>NH;H^1lo&Xm9FZN4O|w*c0RJAfkR+8 zK{bPLj^u({)= zByHNX5kCB8bQhAW&r@r6E;$FKrOXZ%HQ#*mjnMofI02hamKD4s=ZaXKqEFyNgB07P zU@`v|dif1_;btjGy0_>q*rFm+?4q5CgE+xiKK`ES*howEM`MZSQ`wCzmX$FNVNwvkUf@q}~2b?eqirat$T%(PjK z6IgtaHH&e!Zq1DRg)!{_tCNJ`ky*eWnfv(6-~^NaI-z9dpy;-3+eH5S25_jEvj#pp zrh6f{p`?9U$eJ~4Mu9o-=wQDGoRg~kBRGLow&dsfDL` zE61SBm~_LKqWPoI;nx}D2XTTw0XoF%Rv_DF4rKO6Vq?r%m`v_P3g?XC1T3aF{c4`7 zrcJVCz)5W`mL$$i#aI9qR?~ zl|7ZlxWNhUzyH1zGF_b>IwGMwPdI^Mi$yvUgv0QtwbMYlIDyegkGW9=Dxzs6fYB7- z0n-JkAl?sXKOAqds2s84&>eH3TWAAmC@q*rn_!A_|$z+gOnh!r2B9M$9`Ea!1(JeJn3Tb9g^n%o{h zO(a#b-~@F0F)=YzmbQxjANb?DfX3`>O>O6&ZVU&bC;*t*y|>uFaDuKPrM@h|EM;SG z=InN*N|k(CgG0=DaAZQi77lE)a%zSlmm$<)Rf5|Gp?9`s58?#N>qz%j_H@`)^k;kH z%t77@4o@-<6*7twIO+~6C|a~=xpL(QNb?X+ICSld&RkMW)6a}B#GuZNt+h%?al)gI zK1$>R4?G}z%wM!0{v4gT!3hi_!VO1Kny=5m1;7coeUPO(D9B%>>}5+AC(s&AiCJ`3 zShllpgMdk&0fC`L8vv$LEJ!s+e7~?JWjIpD6qJ@znXK7qB>ubvi02LXJMVX7Ax@BX z!a~@7`a|pD5D>RuOxEsSflqD$-~{%z5I)_Fqr~cj2WcZ@B#eG9qYFm(=&NTc@mbD{ zMzT92Jh9lP!F24{QM2H@zg;;1|3!-y2@MkyNkr8nF;vr%1UE|Z2=$Ib+5F)IxN%%p z0113()#6n$;4M^#GKjkaUYW}QKQNrYnRF3|{OaKspchBEIS(QSi+GA3IeTf*<;u1r zS{j6Z&pr33K9D31ja(ZrGnxZH4dMj5%pGFH9|)2!Ted8d4ohGFt@{hrIxk(egh0p{ z_3UaXSVnPznOtXq%zMzqA&j(b{iVe|^2j5Wk-^N}3@c7x>4Aepm;hZkm~VO`A(Dl# zcyl$=5>6KB=gcz(^?B;p7t?o%;?bl(_#w6vBa5kRgX5mWt~z zOEb1SO81skp5g?Dk=&UN%S@?={AS4Ql|RnxRtq=N%?P_BYR0dsKjlC(CJ7U_7aDwD3?mN!+8Cyn3kp@uN&EhUFoIs6Ga7jk|s;QM|V?b;A$gUIx z9mx=9@yIR1DKEuAZ-(Lm&5tm5mMbX<&pi? z)S5b&3Sl+Ri~@f;hpSWGwO05fCOC zGc<>+Vls2VK~;Iqs#;4i%-eu*g5XT*!UlxNFf(B+6I7KAXT50r&gQ#{6Bw85pL${3 z6NR}jv=gL@6U0k1$x-7t;A*M+1;YufzqDScUz|rv%BG_P`f7`&ovj~J^6XKX?~yNU z>AOHy<|B4MM70Hh{lvYFjVuYxR6fHb*IXDX97hp?1NY+wX*glYLzNgD1%RHOpfRC z$TWjd`!3?051#nM39KW;?U;#&Ek(`RTN)nyPKAtC*@1t+I6=2Z$;f_$90Lp~fE_0Y zWP-q6D)GSP?43ytjKkdFfNBsY*kx;pL2)fU16i`!hf@o2hHg31C9mF}X^JzqfN=uW zjFN8vR!CyWrzcoV54YxD#t)bYxlL1 zA)El5(|5$qnk5&#%?wUp5h@$;yvNMXhFT;7T2p^knkKO&tWzh=*z(BvmZm7*aX@bN zx8|JId}?ZP7@*8Aw3=k@!+I3a{y91HQSz4Ut9uMZc!b%N1&fj|8Z8zJrVWhlk+D3t zXbCLkRGa`Z6m1yVDrxiSLTd}FOx|M0D0P=#hXE~MoS-Mf$pVR43d|fKS=(`fd{F{n z@+}WbDsI_cbhfwW+rGjXn^k{ao`N{RE?6@L_ch|QiqXlgn>8r|3%~NpEAoz*2r~L5 z*}!lD-BwqT&PNFXs}Y-A<{2NU9lv-A;9<)vs}V2DNehQ`ae{t7!p#x& z3yBk`2+j;utAL0wFZYLJ6elo9GM(Wu02@43e4K@3l)xB_{TcwRML2TH+`$BG|F$DT zuI@PF(b|$$XHPf!1T|l$7VHaHSm|xRI6+s6m<-6>iRjL60XTmtS)_c24NYV1zbDx->-k&6xv7W_;KGfG)lI4l(J=4O zokjH|u$Fgiu~(cud$trnejz4_zv)R8-GE-7#>rYd#R*V?gvCRMKgFY_Vr9XwkhQ&) z6PL`Ps+^Q+qN%g{%?lVOm_q?`w^m02^5t>zwc`YEohf`aa4{6I!#oQ^y;b!NOmLi{ z@n%4qS=Oqc%`7g_up0ehTzvtmpoVRB4Y0r51H%dQGHFzFI)9wABp&cDr_anbY~MI= zgA?==mHj&c&Nu@w1#56@a{JXSP%Fhq`)h+VNACs0~*x{*eOwhG;sec_`R73F~asabKw32Zq5sDv%n z5zgkC>L2O<+dK1M+m5pAUkE6JOfm&f3XB*LG9YHaFa$1`$Ph3F4Iu$U5fvyD5HMl@ z0SgLbNVq0QGz_95Az}tVCCV5@3KfAu5Jd#FoQQ=|T3`9c_e-AQskeGsz1H66+`Z53 zQ*~rgg z+RjQ;uigDRa6*xFWLnh8tX@ShSZhD#6AeR9nPsX!z~eHU;QJZRI_s=R!-8~8NFJNI z;)*Mf8F~WqjVDvL2PgPe%G~g>jT6`zz4EUjPvG=~Fl4=dC`52}wu6{iL?EnOX}da3 zK*Oblh<)553!6Hxh!fahts7!caRS8j0-S(XrZ~e&xP&oJf89n&nzb&56O*(I=m^wH5hu_ZSWa4671O_9dp^?G zmnSpdCX%}NC`lV9AVx#U4z5s}47pJe83mJkyVJ?WcFAj|~{zvE|BH7Duf_>1` zelF>4;{*ucfaxe|CKB>cok#NWbPQR;e9jAyGjKwYEz0C&8T#&=1CA#EmMYOIxIvg6 zEx-w&cilU~L?T|nWEbrM=wdLkZ5z|l0=tsuEs4a~rUxh3K_ibc-Np&@ZoLCvdV4rL zt;rK6D=sbo@`=o;1xfbOxZ{zLg*@o=u!uGMPfbMt~sM)_nS zHnSsb4JXhhdo;+$;M~KE&cBEzl#k(DTc2y3fcY+s`zO^KVyni`R(!O7|9+2%1fu4| z`H1$H;RO5B(Jai*>GU>HlqaY>#2_Rz1U0EOZGvjWc%HQr@xTfB8%c7k7%F=GB!y@F zoeI=7P z!3rI~c0yJDbC+>~cYj95(LOntMDkp60Zu^SLis6EE^D;lxswMdj#L>K(4!)f5hF`=`IjzY;hj#~ zVu!8~%@w22L&E}`z#NE5hhlK-9-JT!u&r?1Fm8uhkV9jdS+zt-?guQgao~g^Tarx7 z3*jMuY|TuAZhiJwHTx^Sy7UKlmEwAU?zC4CrCr;>jzrOpA zz8dH8#W+Fl$acj&E*SB(HqvbLT2VPFw!_gB8(D@EY+>Gzy%f8vWh$P4UUb7RwN{-= z87!T)&2av$HE=={JGd9FbU`8^s`!`cdK4An?bC{J0(KEbxi*8OO)krDcRQN!#eZ~) zTB_lH$_8QmNar;%#sD;46ech(OoT18IWMan{^;&#lEX? zHmB3M@&vvYbAv<;I5ltrn+RrL#qrww33r}i0WvMq&Ld{H%D@R`#bkmvn5%x`E1sL? zs5{wdqrd{3;B&{^OVw*+$Z{qzImioJG>Rcm^3*t?7UjlU1Mb^NU4BM+LUMnB3dg(M zYuYzAYk5L$2;nlTCvaI}rPXZd*@fv5BTSX&s8YlHMZ)YakYDK;-J4II)_g))jo zZ)pHp05bi@=OkZ0 z1w1(Kw^uw{E=4;!wctlZ)P&hNM+v^5TI}(7k}XE~;q>j@aMB3G8`|OEh9wwx=TJA1nCPPyHH%Liv8lY68YiLOt1M#B;IKh~CneLCV>+EkDoL~p> zyT%#67Bk1?0Z5dOqI*6TUnGq!qMbvrHdH)7eT>wS^)i|uxhTr_-$=k+kkB%P?MIZ2 zdv9uMNpKL>h*+{BPM}%)KvAG}jcFufaoR42#lXmUvxqxvn8Eza3n&M)@0J+?-pa*u zkgHpsko&1A$W>9ZK)3@MXMM(K!A->ks1=!vnB2e;11ChL^`u#31Qn8VR!?2Z=zN#I z>(1)2*j$|8i_Z{Z$98JzC?3QxK5-LPEej}^X*HJ+8!;BwWaDI7U<38iMEfl1!c@6# z-8368Q$3HapkluI5LYi(EGE$X>62l#EEZTj)0g0I0PJiHLp!fLkT=WbKM8=t#3LAm zLSSKaV}xU(n4P`zma^DlD-tH1a`xiEpG6lvLJ34Rp6M|KdlCtbY7 znVPe|$f|;+BH)%;$}*+Tfei=~%A~G;Qa;){(H*OY02Md^X{Spn z!MDH_FdTjz3&I~Jq65x2s4C)N%HKi_-g8`HyYc6y)_BDLo5q@)P}TX9J(u=bekaSb zFyb3xUk{Iw1UhBL$X$VxjZi>midY@gr|rYhe)Kd(CP%aEL!X|agRXTa|4LTWb`&^o zkt@m*LSAVOe7?^NME z(kbT}WJI=Y!waV9Yk;)M<`e3Ue;s2p1};YD=v~Q6gsOli`Gh3|19Ioub1OJdphx1B z=6eLhvh|w)B{&rL?kD!d>B-?8Nt)fz zC?)Oio$^L_#Yz6+pL217H-)0;IFiBSB&bLP@XS4kPuvpuoLL{d+OTFaKP}4E^h4yu z38m(46FX(sO}Y*wps+OEFHie{Q+tCPWgk?$<-%99XNay z!?OVVAQDs$;Q4xEFJ^m1)|#A;BEbvNvNx-p%994M`(hwKHAZTxNN{F^R30TBrb+eq z6J0ZF9lT}1=Zxk@m?&U!Pd*}0A9?(gErSCrPa!zhR=XI-CB5rOgUt2f1PHKtcXCRL zTE-|Z(X|NlXmbHhKy(AUn2I^W&C)!zJ0(mOI-UtHFwdI08+v+>)qN_IA}mKA0~vEDiWNPpcC3yO!yac z3c^9UV)u=9v&dBW{E>*V;;C6i%1fasFLB8FP#1DEqYTFoHYS)4NJBL<87|Duo(#4@ z$-oH>=CmK7?nix=SnoHgu%ibBEF_jEtSX{Aja7JrpsYR`_>gha_ux@2f|)F%e`prH0)@DIBw{)TeJRh?*k{86g%j-4)Yc%^ zn4nv7qFlOGa%1xqNa3J_aobp)tc5U{>(nAi#x8aOC&c!5KRp*GSO9|kZ9lb$jya)I zUdDv8a6*4CyI+#CHaLNk@9uX!dV~WQoWOr{Nt2?jffKfO!py=6==GQqC}IqNcYF8Yo1IdPCof$TT@6T zwwG`MoRJSj(GqErIitX04#DR&U*wfH;4mJe3idIv1%avCsU zl36cqgFIE#AiVkVlC>P-T43?$r+W`4Ff{pb^jzm^K8(bQ9Kd#zCA~jvxLquR->@4vqlG6Y%Mf4tj4$6{Lc}eA>eti3J>xTYWLQ zORcpFF1SF`a_`{;8gXpE&j4U5lGx66a*@ z5C{*V8_hUC&8@qE<&nS;>H(t*#RKX}OU$IaImLi^95P?53YW{WS?q&aI3C5i>t z@T2c(WOK@(fU4r5K%6T_C0oIWV&KfLUjjkv();k#$iusManLiz@Y zx29iBU+9D1BCRwA3 z*9C6TCIb(%)eZyq7VA!GS}N0}7r4FhG6(j(5C+Ano{lCqbJJLAHz`4-On$4(R&kJ!zS6 za2Y##9~>AQn9BhKo1lWb+~qF#I2?WS(b%!{#O#{e%P2oMFgP%a1DGyz8PM%6*=%9|M4GxdHo;JjkuzSJL~-ygB|ts^2Rs5ksD`-?|Q}=XK-Cz zPnAQV42BwqHimmQjc@3Q*`MVL+LylcrT%vKNT2%Dr+)RTU+u3lO0L2IHj&3Y z?r}Zuh;<|Rw3+bw5XNd32IdQ`^ZN=;$o8tT|4{y=Rcoo>uHTkX?u1$ z?pglnpZ;lrBs}eDPs2M~e=mB`i@5lSPm)lvJmnS}mZ>j%;R};A^cSEbE(SXL?6aTu zyytzr+w1<%O_xM(pkJ_jG4=5dc3SFXU57ryX?<_YhDcS_7Fu5y0Xv!3<2v(7q; zmCdh%51cp40?W&aw}=w?R9xLM{%vo2TRxMXbu#Jtp$~m1 zw;O-vGoMNF{gY!X7yi^{G$w*V^Qg$b9s6I4m!w^IN{F$O%yy2I>{N-A)S@{xa(k9}sydq*cv50^7@86#nh&dd|0Tti; z&EFg|w=s?Mz@z4EP7VRxvCDIWoGibi1z2_<1|39yFVB4DGe!Tnjk=#{jgrO*96%by z8jmE-yGup10tTyuh*?gdT2|19IMo@0(CD#ISjpJm;~G zeJtfa_OXxUkDOy@#5(CrC6MjI1f-_3uvXH@;-5&2&6A=~h;x|>-1Me5004New6t)aDrNpK(Zlu zYjl)6LZ%`5Suv7F{>dH3==CUuh|-zGgd|S6VMDR-CTHqYF3zA)og`J@P37P4hBr)> z-{}IHA*iQ2JMv00a6%`?+QnAK2?*twPCXd4O^Icd_q^vlizT`ALGzY>*{X_V=4N8< z;x>WY#pAlBWliEc|CK8@?k&XC5 zT`$84kRc0)HbOJC11FdjPVgb~3i#G6s@{wzx>O;JV`bx2A5}#m@K~w1@3d7 z`#{oL-}=^`z6MU{;ZlE@6>$Ov2AWR&NUug4@IXz~aKbBJ`ASb+5^K?vVR_{?Yd8Vj z$4zc>6Bk4ESsMcR992{@D*lS)AMk(&sAQ*%qS(kzWWM^D9|PA$dCMr!^onIEfQz`S|0HUwuagZ(up2Az+TuCivF3 zzBO>DRz`9aln%85+m+9;+8=cfPCy>z@?eHd7%bplBuy@@P`meV0y0mmsyfww7}dQ0 z{qJ9++0}|TLATQL`dD>;*!?#8 zJ@Ld7Y4DU&PHB|UBTR|ZHBf)D@UjBPdlyU<$wNe24JQB$Fwr#Y*77bGBMuj8b1_b! z5gCH^=+SlpC%|yjshu`&_a`rDt26QVp}b8v!Hq8NL($G(?v0@m!Bjk6*Z*#7NTe&tu%yy|(n04D%w-}9dL zuub3j&UY65{Cnk_6JE&(XV&_^b2x!Th8P8`w+I6@qpita^CZ!ycADjX8S;CrHDKHxNpPIKZAX zR_K`h@HwomIhu3+)U;N2S-$;)`lneBPKaeVxHV|QojFE?&`4nsiQLht zh7&M@vCAYCQQ06NM_*I)xc59^wQoC&tPv;Zq(e-tp73G`yZj9@%;eGBpWdDOaf0oF zJPBi>p^R(OW=d$SffE464|>pp+OZ8JBB<(i`U6Jy zA64XELRq39&KqA#jvYVI4s_aCo}^_Fdj15u1W&^du! zY!WA60^vz@qZ{2Q`W+xf(EPz^f~}u6nWY3}a(SFL-BC>R-~@;4pfy5A#_BO`{{>u+ zV}4A7wBa6GCxQ+ONQvRVk^<{^bj>x_#PX}BId*Zv6(4wOJq<<-P_$2=O@FPloQnnA z3&#Ws5K&Fe_~Zk+yn`@smsG;DI*}*v)L}Z1xVAlTIdHLGYsh?PNf+_wx^M!LD|N@t zg@|L;w~WFL`GXZ(OoK?_+_ZVyj}rhVe7Q_K*9C?#AvwSE))vR#b8B#>ffLx)Yr=nx zT_!64%MX3%L&||*Pe0broJF<})=S}E?1h+$dC6jqJU*z^IA5qDFcmyNNw!5MHkoW> z@hq^q`ld)BnRmVGT{SvTO|4AK_l`rY9{Yqzy#ph~Kb_XlKO)~#U+e;Ry3?IR7?IN= z0i*@turc6x%k0vA!Gz}zi8>xAK7sOnYeG3kcX`Q6UXrvQf9?UC5KTnH(iQ(D09s_x ztn^%*5F7Uf+G9W)D;Cp}I3cPz67`$~{)x283pjga(Fr=@gks1qV6ETILmu*wBIU}o zUuS2iAA%IA$Acfb3^>PdRrae|%u*jAAEu~}fxw&0J7Y^>f}`2-S1b^ct86To|h zf5wxYofeCEEcvp4aDWqmr{9rB9vM%R(PtsCj)*FQVz8Hp6A;mxFe-Abl{ZA}BHFt@ zS`U-g^BF=v+D}z!oX1ViiU|iEq{m6MX2c0LY`{5`tAz+fW%EVeLffPqc%T6mwa*AA z^AHn7oPh2?%YJ{sH4JUfi%?fgzmo7JSQ8AqFWeXy1Ws&ZG^p8;`s@ zFTe>t39iLL*px6F1o(&rz~TObZ)7rXp4Jw8hX%?cKE=(5Tf=gOfIvJ4=)!;K^;m)P z^3HLXDXKKYAe5Ihm6z_iPQRM2Hi5Tk?3c80g7rIy@wJ=uaMi8p8Y2;0vni$U zDmVeLyhg&FiLjzktoFz|)Lfi^<(S`ZF$ia^$6CHAakI4qZy|4ljb3*# z6rVDm9VdZBHLtE5BA6Nc#NM&kEUpIB@-{?y-@1~w&km~wi)VQxgzhdeqsp6FC5KS+ z?ubii8%;%=;3}PoB2KXXX)dC)I3iO}=NM?Nwy5Ocg?QMh6HyQMgR zb1oYkLu27>j4m>yKaGAz%Q&YeCUAd6N}BDR_6cs>mp7rIbLJ`u;{=?u&@cPks>uv| zMeJWYsw4VCI8)SE*{uLB<>W=2z?qIS0)NqHs?%Z3Vj`&R@m|?woWQ_AQ!(Pf!yo?e znkPua30M!p5Zyze7s2|_dA|l$->SmD$;kqG;Cy}(F;2k2kTRGm>1;CBY{U8{x~}aA zw7(c9;I6`Kp>cMr#U23=Q2eu=i1l`^d4PB4xj2Cr#BliILu(s<7HQ5iO$luxiOLHg z;gt%j?6==0{l*hn!!~alaRT40_HjguYhP6~qj3MBalP3h#H~%d#W=zC=gSU0IX%V+ z7#r}EBLiA0W-Qw-Hb|^0d6jk!5)UI=IAc?~SS#WL$AV@9Pb#W(>IGW_)<+nf~U7U$Hcj|Rk2CkxPM8v!ZF~_NH#isM zO}TnwFUV`va#%p3>dl{aZocAToG*$NP3l66Ex@~Nbzh@rjrnLiZMDm|kZu(xe8dSo zUUI0C&7~qvC=LNUkDSowk(%{*tox`(J<1&=_6)I@)10zhzF{1-bvOaUrExU|WhShW zKvL%zXxN&fLh5O48BPFc+uA3$BkJilFJqhlOwFJ6=YS|MkP~^FMr|5BDNjIW>RzIn z5~Z{AYY7J&=3VDzdwH!kPT-uy(O|uQh$xvA5hrL`=5nNn6Tn&~K8~^Ic2nlMo+q!dm+; zd=e)RO~sTaN{ZNiOh+jt78>zUOm7`d(8|oVRXn@Jp{<_gTMV1X&Wa*p`U5kp#$`6!}ogWcRefR6|D6 zi|Eqj!LiE6IwF^-t5`HzZiq_UrV_jnGkF&hNgS%3!wL2Sg>@XS80_h%pRNJ6-yOS^ z`2gBU*j4+9gwwTH?Q6xh4kuuZZ|OIY#A@SOJ>M#F3?YgN!D1K7a003~y{w~-I;z<0 zg3J|h0-vEkJ`z-WKd}PX*kCSBU*)t-}eT+;*kWF-owyiw5?a zX~zhi$XNV|vCHS%w8qlF2^7Hk#f=cAKvjDF#nm*TDK(PlXp9p8Ftmx9-hH)$S0n^@ zR#UywEe1KHSXPc7EbVR)@7UkF{Xr9FbgM0VfvWI zJVvjc@3+l20C1GxvHLV6NNx)B<*60pc%Yk8K8KE)9V0KuBC<&sgPeR_(96WfL|l2G z91Gs~)akY31bZ{_QM(r<9H^>+6V5#IO!MDHP)R$*pB$ZBvFJUaTAtFmJ4UhD&B?^E zi^Z8S;zK&ujJYuiK(F2lX91LbjgrMjUQzpT0zF#I9ie!!{r=3wI036&&72?lp&v@R zi#Va^W)kffqkV$gLA&i~$yvksNg~FI?D2$Z%M+5u*YcB{*8?H$eG-r=cG1QOl(aoF z4fdEc$HuWJ!}h?Guw2Ba#tHU|j8Tm68H|M+=@^HnsNhiDWjH}~eI{i`Yfv)x5q8da zEx{k+tMnMqChdE7o`n-Y=6WM@-)7Q#{Ao&PxgRI6yh|1uRd4OF5Og9Q0r;5*^NfTk z9ghHU>9e*G+k-rAgWGXr73^oOz4lt?Ckd+Pl*iz(Aq8^F@j#llR?Fd~3oxUZUHwC*g_pkcrLr%AKg%{3 z@6PSLHI4|akPX!P^_8)OV%j#gwKsZgLD4~e_usQ zLdWTq_AnV2NZ4-{6-n|`KM}&z98RN3v2g_0YMcNQ_zEnvH@j9$u-x_QcarzA04MNS ziQvZhI_ah7r{xKAae}P~u({1UvV8(#hx{pfoS9$43GmipMhX|z3Y;k%@S!1XGXdzH z6h4RscN!<)VCXT%{nx}K2?bSFl_E}{eAEbV(K)auX@sAA(QMOsJ~?=kX>a0O77G|B z@R>Uw`IY$(liTZ|YI&7t+s~|s6X=U$so$fSykbJJBRu?Bi3K>p9&o(J-0xsk@3C-< z7T76RhHnIHR3m&K))7%Oh1z1H&AFE#4^^)!&WKURVXh zx18TpLPx}BpiIAQiD~OeV5V+QF81Xbj&f7cuek>&M313d`33mV@bi$W^yq^dxYq^Dy@zzGgT(k}t7{1IJBOagywh6VFybBHv?kf>NZ2%dbj04K1Ri}*wbG}%|XfIW|BJbrPtT3Qn0mld}v8o}2Ffdl>pU^8|- zUHy=Y4rFZ48>w}qd?vO=ecEZK#gZUijAr#H${AuArG0gm3L~b&rV-kZO>qF%47B8pXFEArGAd%065 zxM8a1&g_8~*BrO7H*f;Ok#jWD$wQl!kmPnnkU)e7vn%injF>=8jR2=$$U;uqeO`(pTArYgXBk#5;ht? z<36AC<#PlT2_~65jXxnnA%7`}+#^0p(rdv9w8^y z)+S*EFeBHTdj8i0jB12qNR)Ww6tYTmI;R(jY-AF2QQhUANv&3lP}&}sT8L_+Xy>V? z@$zntb-Z6bWZ(pHKj0in5RnJ^_Rg zcrVGLRvePPwWf$qc;Pb6p$ zMk6u;(JW$jj`nqW7tBDmp7@941j(BPDHJQN{LwI8P3d1OLyGW20TnHrq+jr=$!3}{ z52f>BA1_+-TJN9VKjL*+6H4u7Qt*<#Dhrfd@w(aE<{ zT<9o|3N;!hs5}ce>swp|@P$l<%ufk7c(d`5P<<2$@|1w92qfctVCwP-SSnkTL4mvU zu`rw*;6-liC7i&x6#k3DNKI1{$4;6JNSsV$>`AfypL217&!?d7{$5zIqMwVrik;%N;6Q3jLL>v0blHTDFWQEVC{I~`SRt{;bEili=oiF7 zzeQ0A3n{3BC5S4TuEg76wX`zS%Aow1BeJnzr*U9j94{gcblf;t)%qS}JViBla^5O1r|0s;<<#{5Wl zI2nOF+5OcT30?;>WQDCj5QHewRM8hgC-5r8a(gGQa+7-4HR1%=$R4Cf_3TY?MQyw( zwpYbxW~7Z`{g3A21Pn#=MqqD$FYugNY=w!bKOm4koj6m&J$g>hPZ&_IkuD zu+in2)vyi$5l^jU0N+}413j42JCp<#T#9_cd$;O=sQ9#_HVsYvI${E9DONPgXH{3p zNgJL$h7&Nz2U9WXPB72H0tW~w*0AFCd+$li#R*nkDE{6cZAWGA?7W|fy zG@fs`Py#*u{nqG7@(~C#RV4069wk2+2)(li(_5q{Da=NC<8qz(M3 z3`-WKUzp4xImzECJ1iv=Aq>KN`sEQVP(7C$uuj6ye6^HoJi8BTcurx=SuakYW#%3b z6d3F&5xdLNi0fH=EZZN)a89gjXOky=Bo$&yrxhHZ1{ewQil^WPwF@3096*Q2 zGBsJ3)r?hzkBCn=DeQ$VKH{{_XU>e<~kD8~+BP1%tQB#yae{2}nX$>gvCYT%$#gO~uEqiJB2YoD3wIHVM zp=96$DKY!ap%ph^M=fuAUfeE};q1&;%%3IgyU^+AqQL<vF_Z=IYi_ zzSRWFu&U-!l@IMu!wJ~WV4{W%n*t=t;1iqDoHNB7#VSNxh5-hG1^Mg{N()=oV);Fg zsc2Ej-P3zuTw6B;MfoU3(kqT-;DjPu7H1kK6oYSIDu12mZQnlGZe{o+NTR3IY z2q%%njciLr3BZdH$+l$(+eN1$X4vSuhj{z=FN@pU)5R{Av3-J~iY2}KsXTN549F7_ zpM|7K{3&-H9D;1E$34Q=tq%M4CHHy7THBrm6fwY|Mm&h`Q9-d9w?5^xISO2-C2HQn z$cY^AbvA@e=IXKdhbgR15XcjVeZe^bkg%fGKo=7u8MZDX60^tBibm47Bz=#K_aF{O zQQGjQXwbkR8c|sM^S#yB@HZ-M(IZ7EWM4yC9=~N>BWp8$f>GfA&S%)EaS#XOoR}an z?2hQJ7{7Om_|_&B&qv01;e{8ri;br{!2wAUYT+5xBYsBlyC!YdOQN#u1XYJxn}igQ zPpka6`5gSGu;=*T;2TR!5-j=G;@hG?ls=N|ZHD9chK(+EV!1Em-X8d_jgFHndm_7@ zeK2cX$18p`$x*d4vH8R2u2yTi@>x{%IioK0hfD$=5V@UlC}To`{BaUYVxmrtRB`qa zoS?Jbg1g`+yW6M&NKP=uW-;9JjvkxCc4B$4SrCt6@*c4y2pbcgz&L!@9BlE5-JB8a zNlMm&3Ubcq!mm8aL0)ptL18As_o1>A``)fkT-Cgg$1$Ig~jt#y&W(jT|7>BJzafDn>4M zAkz`iw{cv9=D~r%frH2aRG9>FiEdLE_4Qmga1d!8T@MZn4%9fHyIHwz!v%12=FdMz zVsKz^U~pg-2kcCNJqe!37^QF_`!e0=tbRw~!GXbn9pZq3RG_KHdje+%ti>F-X@`0o z%?=I>4(x3XU?+^D1nUWxjdIi3-X822-Qd8XzyTzLT(^pBVT1=c6khij;+uZc$?eYhWHqFxyxN%^P1Nzrto7Q`xwEEN*#jMXv6`@9!6X@fRV67{$N;`@f&u;l<^WP}tM#um0+<5@&3yFRlLb zKmYUd&p#hlyyPV>VcO_2DUF?tyY^l_|M|~zeGhROiZ>P9Zf1cuz3EN9oHz31iBEi@ zkPmzP&2N75BJsKtR<(TDA3OLfU-`=K`JV5It@Yni|H)5&670cW8(Lg@?X_GV6T5Kw z?6c1CM%PzYNVDSI0|Kq}3{-2a={QS9}`#Bm>q@53b z@PlgbkN^0O8&&d0Kkx%Tpo&}!_k}Nf0b)2g5|4|GSoyl6@cX{+`|`T$%35>@3jL zXmIx*opa7PVhC~-&>90ldcezd{(~O$Ahu)RQ;{|>lB)BsgFM5Q=RNOvobHc2@<=@e zX3UM{c)$DIkGe>oiv226^I88w`NbDstnPZm5shZYqrri}fx&@8hXck5iz8$rir3ov z=}&(ezM&d;&U2oF7Go9<1rly@lbayw&nt3% zv4szR_`~XA8BRdRLv`RK2DHWYlgvvlxkTL!oRDy4{2Uw@92gv^abR_vpzZs_6Hlyl zF`0k-@yD}zbLvFG-zbd5AjKZ_s7E!*EPI54!`29oc*G+*8v#y0Ppv#V5l^4?w5N5p zwt>ai`WXU$U;gr!8|3}fU;PzjPCDtNMw!|p>$Vc#;GK(lXo%UfvS*kg~abrJIi zPKewX>A``)fx&?u4y=e1uzS}!kAS+TySxmlYR-c+0#0a%`c?53x46YI#~hP4vSJP* zag73-gwB(xdPJvyW+Cq#DZLs@{3G&`8=Hfv1}38##iWHHOjvfKG?tC(VlhsDfp@#x z-Dm{wm`P?1oG{6vQDAUjaA4CofbAAW{Q@)dKZ?DBmxSLK;Ok!Zx?&k;a#Q>r?|4W5>`&knBj&Gy6JGVI zSE-RnJTq`Y|En1#2L}cRHh}{i*>n_Q`y>894@sZ-%xAPD_MD!28e9b@y#M|07cu<% zxzByBr@Ooi@&r!hYUftBx>dU!b_CQMc_XXjAhPx-@NSsZ6ybw7bSD-FculH7+zDs3 zwxfm79Y7UZf2W9p$%${Q2Eq&ai@*4b26=CO^P89Xt73wvE>^(_cE!a{vq2<}22N=6 zXFMGo7#!F%4xDhp2`rL0j?E&>N3b`%;SIAY77H)H32%MtTRA^I{NWGR3a@{k{`9Bg z7YTZ??_06EVy5g9)DD`3TErge;;lb<1*Gg=GyzuHdFL=QV805h!#BL+9q*{s`n$jTyGCR!v@p+n<}-ir2Y)bUuN5>2PQXBs_(=Gb5T6Q$ z{K7B%!nx<3`)j}UYqg*pyl%b6fBn~gtr1E7zzGfJj7Nh5g9Dq!0r{0L^YY^q#?hOF zk#%pyam~dEEcFh#BY!uo&;EC=McAtmWX&uh#B**SprrC?8ayl7y&&TD?%^5O1(uciGeb z`mg`G(T#3I7dT?{Km~#%h#vn707L%M+54aV>7No8D+W`_gGkhH0&gFj;C^p*vzzgz z0Fa63#+1M@6-F!P%ser0Le7(sGdM6fu$dg#zkff=8v872eSEs{2b}eX599ZK@Aqn9 zJaFK^Dr20B6Ikl;4&b==fB*M?GUYKK=C5b5;<8kpPdA4SwlMUs8l#LOkV#ZEQ)9hjH`1AdR9_7~ z>simLRY4{rH_Y7bPWJyl`IA3ctGjx>V@aVOX~#WQU)XkF0ua>e zYK=p#JN?Ih{Ku#|x$wdZ{b*T&22FEAUr$UY6)SGj*eW2OSw=ulEheFf#7Utim?2{+ zUX*~eU-xb_`o(@j-Oa)Y0*#6U-e}y99IuJK-uAY)IX_7ZoRBbN{2Uw@9M~uhaND3F z{$ZK0ICNn?A}%!4I*e*Q9+vZx#hk@B;fgD+P`?-hYe#)Z6>uAshFnXruMkU zJuVTIAgCe2VP}tvi(wdJQc2)Y(9;x~zC8rtnKsgc1A_w_!T}=N*uRWGH# z##r;0H$@Vq<{tTm>4Ue)JKyzV)qD?7P4FyVU~X7vJf?qw~){KeoIe zt*b873&ABCEnse^V*HD`1hWc2OR+p#Cz~MgxYqcG^B~*0?%y;S%+kccvq%q~2wahw zt0BzQq?WHOb96cgzdyb zNUC#HbY8di+d51yFLPZ9$sBn%lp2L}cR4mt-gz1GR=_P4)% z+dh0Pr1}8fZ`QaBCm>Y!9?>u_U(29q1V=n~M}nY&Ht>iFg|@@OX{Vj0MtB!&E20gP z2Dgk-V?}}y3%IpOHw`eP@0D;ZW=j$Qo3lTm6+jVd`~%~msDcmf*9q)H`k8>81J)_7 zOCsOjJ8=TofYvOgIPSRP`pKXqzz=zaC>c0m7VAdg!GXbngU$hL+I{jOe9#Wj!#Px8 z01;vnwywXIWjFzKw$@~hf&G0IOJcW%Tjiv%#rHU?->a^=O079MCHX{&EOw#HGtWFz zb%}pyNB#>gxImfw%f8vD-t$NS57prN-uJ$qDk$PD=rAQjEpS~(CC~xxwEVlSKfxq! zcyx~>2w@>hLU&D20^}b4Sxh9cn6Ro%ign@yqFYdrkdG$m8P9k|(p2LoBeFpYW{|a# zL!MCM%*Y=c7#uk093TR%7C`*+7DO6s(~p_Gv;YKODn=b_R9}V@6!wr2#T~8DOZyQL z_@0}s@B{TG0zcIzt` zzzH=5j{L!a!GTTS00+!l-tv~Le)qc9y||QTT_mx>Yr+4CpZJLdZ7#qGoZU1K`kiZ+ zUZfBi2-iatAH_^=L(oY1H<~PZhov1W6ki?j+5? zZqphB8tlZq77=@D&DVlR1y~_f;#2rTQK2aEIDc=X2gvSYyUZFbd~8W-s{-+@c6qlu4pJ zpi;M5oTt}ZbB$Y`Ovp~v7bMwim39&{gV+?Zg0s##E9N-OZAaAQ55reyt~Y@yL0#}K zs{F>qNhp=@2bt_0%wrQoP(f0@jT4IZMdBi43Olb6NAKn;jlc^7CnRrY{2Uw@9N0h( zpmea%-YeURiCih%Kkx-O;i8K!62S!T?eC~jQXZX?8#G}Dq+&o%5#$xnWAUcf&7jEh4w4d!L?9Aw>;PmKIAeh_mS>UHV#i@k6?lR`%#B*}YROU}1_ z+qa2A)HJzRBX&UnN?v*8l`%6899Rkg9Dq%0omTOuHq`ruEAQ`|HtW-i;~%+wJ_SEZ`nu} z-~^m0)O91S(JW%_fB*Z_Aa-c&c#^mcs$a|b-OI%nU#v&`ON=JxJ0Tr9#&X5onPP1B zZsEuykHqiKb&ClMF99vl)Ir6-A!_H;Q%@~cB$InBDZ?Dd3$Sr3UeFGiyy6lf@?!kz zoDAhiQ-kcQ?b6~qHxcaQOPk9bs^YeuO>IfBbyRV;&Pj zPWe75_VLTLzLh z@`r!;hoTcDd;U~8ma79QWW48+@@&NsaxDrSH>(5!5KWr~hKW_sh-obR%LSM5k<*3& zN&G7paNtMqPm}_wfUDC5S{v6=0;Piq$iZPO>}xvPS7;5K5Scd8g9C#Do6iBA*XFv4 z6Nf>IXKm@8HSoDO0l~5kyc{#zQftT{%7NGUBoTueVL8CAipiYH@bh)AdmYka4wx8x z;t}Z$i<`3=ql<2dILEP@zwBi%)78d^@p~>j!Vu9`kr0E#fGAJk2jmrqDKO^u-4k}W z$m#JNlr(UFA<|TI0AZx?7P*;xU=gG7mi5NO_?g?M5hr z%?8H0K#QCex)Opi1m?=0I%nVnvtlF$2L=bWg#$#pWpQJtnA~$UB40I#k-%EUI2R`n zju?XZJLjBpCJ8`ze%ssL7LN=L`2Leszl{mm5!j4mmx$hh9r>7Jj!_r!Up9gsPs2}q z;uGwK#~ypE>k=V(RzL{`#cl#Tux*~3A^|#LQ0>FMH^-XY2yz(k22u{RAr{WiIGPs( z?Ch|Uj9pLwuLQclWVGKc7fk^dI?xwF4-zMwa6)8-(q!hgi>kt&j$Q^%f;9Apf{BYD z0e%#C(vzOFfB$|8eEs2>@B|SJ(}Smc4qOt7?8r~CQlKxsmt4DnoP^L@&_gV7>Nfrc zPG~S^JQ^Gr9N0__5IKhp6dyWA5^mGUNt3m1jiDXq;sj2<+8}BQ0@Kf_lbs?rr$<4+ zZslU&1pM-n;p2lq$Vc{f)D0M56y^VJp_o9F0dHx%__QaJ-G|_WY-&O{oPUjN+SS?P zbS+oS01v`q3lOOQN-=ZoX(Ti3^|Ksuc`wQBP5=hxp5DvlmtPL{SUa5y8pJhKbF${( z={5&WFe^r4aA0s?aG;X|b8!L=eXPknp$pMakQ%36m@u1qKHO2L=Zc4$Q>~ijJFy(@C1G{nW(}od@$;BU_PA$R?ly zN|3Ffc6*8BR&Mx=%}inuS{%{92}QPy%)x=dfx&?W2PSa>=4w_kI3i;1Cg12HK0+nk z_FRjFw>piPfeaei$hLYQ8&14#$HvX1ht7c$dbl*o3=Rwq3=TvN7$;nD#T7AMX$K-! z5Tu{_sh{HPhS7UovNMP3_#1W>-u7ZR`r#?iqodjOksd7i4;(najB5CvB!poIM0x)3 zKTRHupMwK~1A_yD14RxPC&(WyDI;qH!Wv*}hq8bLc9nYv-u>=((*oi9l3w=kPf1{o zI_juBJjR1HG)07-48au1LpXLFN*FjHGG(L(2L=ZQ2bvr><&;yja^ePvd%OP>0P5L1B3?r5ukvu1OCJ9U1e|#eC%T%d(ufK zwbx`f*hsKMzwm`GY!ukTkGO!FxDZ5a-os5 z92guJ92gwfY7U^YI7B=hw)!;<;s*x?2L=ZQ2L=ZY3I`5lrNcpC_~>+SU~ph?U~ph? zU|TrAUD)7+Ls{vtEpKYjIXEylFgP$cFgURL93ZCd@D1F3wvQeM2L=arlmmzDyTP0I ck5kZf|K0FSH@g1+@4ex^eTRKLO}_sAKT6*QmH+?% literal 0 HcmV?d00001 diff --git a/scielomanager/journalmanager/tests/modelfactories.py b/scielomanager/journalmanager/tests/modelfactories.py index b367a19f..c981bd63 100644 --- a/scielomanager/journalmanager/tests/modelfactories.py +++ b/scielomanager/journalmanager/tests/modelfactories.py @@ -6,6 +6,7 @@ from journalmanager import models from django.contrib.auth.models import Group +from django.core.files.base import File _HERE = os.path.dirname(os.path.abspath(__file__)) @@ -15,6 +16,10 @@ SAMPLE_XML = xml_file.read() +SAMPLE_TIFF_IMAGE = open( + os.path.join(_HERE, 'image_test', 'sample_tif_image.tif')) + + with open(os.path.join(_HERE, 'xml_samples', '0034-8910-rsp-48-2-0216_related.xml')) as xml_file: SAMPLE_XML_RELATED = xml_file.read() @@ -232,3 +237,13 @@ class ArticleFactory(factory.Factory): article_type = u'research-article' doi = u'10.1590/S0034-8910.2014048004965' + +class ArticleAssetFactory(factory.Factory): + FACTORY_FOR = models.ArticleAsset + + article = factory.SubFactory(ArticleFactory) + file = File(SAMPLE_TIFF_IMAGE) + owner = u'SciELO' + use_license = u'Creative Commons - BY' + + diff --git a/scielomanager/journalmanager/tests/tests_tasks.py b/scielomanager/journalmanager/tests/tests_tasks.py index b54acd0c..4eb53958 100644 --- a/scielomanager/journalmanager/tests/tests_tasks.py +++ b/scielomanager/journalmanager/tests/tests_tasks.py @@ -1,4 +1,5 @@ #coding: utf-8 +import os import io import copy import unittest @@ -898,3 +899,103 @@ def test_htmls_filenames_are_suffixed_with_lang(self): for url, lang in urls: self.assertTrue(url.endswith(u'-' + lang + u'.html')) + +class ConvertImageToJpegTests(TestCase): + def test_convert_gif_image_to_jpeg(self): + from PIL import Image + image_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + u'image_test', u'cover_too_heavy.gif') + + # A conversão de GIF para JPEG depende da conversão do modo para a + # profundidade de cor por pixel. Por isso do argumento `mode`. + jpeg_buff = tasks.convert_image_to_jpeg(image_path, mode='RGB') + jpeg_buff.seek(0) + + with Image.open(jpeg_buff) as img: + self.assertEquals(img.format.lower(), 'jpeg') + + def test_convert_tif_image_to_jpeg(self): + from PIL import Image + image_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + u'image_test', u'sample_tif_image.tif') + + jpeg_buff = tasks.convert_image_to_jpeg(image_path) + jpeg_buff.seek(0) + + with Image.open(jpeg_buff) as img: + self.assertEquals(img.format.lower(), 'jpeg') + + def test_convert_pdf_to_jpeg(self): + """That should raise a IOError. + """ + from PIL import Image + image_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), + u'image_test', u'logo.pdf') + + self.assertRaises(IOError, + lambda: tasks.convert_image_to_jpeg(image_path)) + + +class CreatePreferredImageFileTests(TestCase): + def setUp(self): + self.unlink_registry = [] + + def tearDown(self): + for path in self.unlink_registry: + os.unlink(path) + + def test_create_alt_image_from_tiff(self): + asset = modelfactories.ArticleAssetFactory.create() + self.assertEquals(False, bool(asset.preferred_alt_file)) + + tasks.create_preferred_image_file(asset.pk) + + modified_asset = models.ArticleAsset.objects.get(pk=asset.pk) + self.assertEquals(True, bool(modified_asset.preferred_alt_file)) + + # evitar que arquivos temporários sobrem no disco. + self.unlink_registry.append(asset.file.path) + self.unlink_registry.append(modified_asset.preferred_alt_file.path) + + def test_alt_to_tiff_is_jpeg(self): + from PIL import Image + asset = modelfactories.ArticleAssetFactory.create() + tasks.create_preferred_image_file(asset.pk) + modified_asset = models.ArticleAsset.objects.get(pk=asset.pk) + self.assertEquals('jpeg', + Image.open(modified_asset.preferred_alt_file.path).format.lower()) + + # evitar que arquivos temporários sobrem no disco. + self.unlink_registry.append(asset.file.path) + self.unlink_registry.append(modified_asset.preferred_alt_file.path) + + def test_non_images_raise_ValueError(self): + from django.core.files.base import File + SAMPLE_PDF = open(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + u'image_test', + u'logo.pdf')) + + asset = modelfactories.ArticleAssetFactory.build() + asset.file = File(SAMPLE_PDF) + + self.assertRaises(ValueError, + lambda: tasks.create_preferred_image_file(asset.pk)) + + def test_images_other_than_tiff_raise_ValueError(self): + from django.core.files.base import File + SAMPLE_PDF = open(os.path.join( + os.path.dirname(os.path.abspath(__file__)), + u'image_test', + u'cover.gif')) + + asset = modelfactories.ArticleAssetFactory.build() + asset.file = File(SAMPLE_PDF) + + self.assertRaises(ValueError, + lambda: tasks.create_preferred_image_file(asset.pk)) + + def test_missing_asset_raise_ValueError(self): + self.assertRaises(ValueError, + lambda: tasks.create_preferred_image_file(999999)) + From 9f37fd112320cd1d60d97052c34b8a32c800ca06 Mon Sep 17 00:00:00 2001 From: Gustavo Fonseca Date: Fri, 26 Aug 2016 17:20:58 -0300 Subject: [PATCH 03/13] Corrige uso incorreto da API da lib Pillow 2.3.0 que causava erros no Travis-CI. --- scielomanager/journalmanager/models.py | 1 - scielomanager/journalmanager/tasks.py | 18 +++++++++--------- .../journalmanager/tests/tests_tasks.py | 8 ++++---- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/scielomanager/journalmanager/models.py b/scielomanager/journalmanager/models.py index 560c5b2a..671e6ed8 100644 --- a/scielomanager/journalmanager/models.py +++ b/scielomanager/journalmanager/models.py @@ -1523,7 +1523,6 @@ def is_image(self): except IOError: return False else: - img.close() return True @property diff --git a/scielomanager/journalmanager/tasks.py b/scielomanager/journalmanager/tasks.py index 697200f1..8736cd14 100644 --- a/scielomanager/journalmanager/tasks.py +++ b/scielomanager/journalmanager/tasks.py @@ -452,13 +452,13 @@ def convert_image_to_jpeg(filepath, mode=None, **kwargs): output_buffer = io.BytesIO() _ = kwargs.pop('format', None) - with Image.open(filepath) as original: - if mode: - _image = original.convert(mode=mode) - else: - _image = original + original = Image.open(filepath) + if mode: + _image = original.convert(mode=mode) + else: + _image = original - _image.save(output_buffer, format='jpeg', **kwargs) + _image.save(output_buffer, format='jpeg', **kwargs) return output_buffer @@ -493,9 +493,9 @@ def create_preferred_image_file(asset_pk): raise ValueError('Cannot create preferred alternatives for files ' 'other than images.') - with Image.open(asset.file.path) as _file: - if _file.format.lower() != 'tiff': - raise ValueError('Image is already in a preferred format.') + _file = Image.open(asset.file.path) + if _file.format.lower() != 'tiff': + raise ValueError('Image is already in a preferred format.') try: # Levanta IOError caso `filepath` não seja um arquivo de imagem. diff --git a/scielomanager/journalmanager/tests/tests_tasks.py b/scielomanager/journalmanager/tests/tests_tasks.py index 4eb53958..43edb452 100644 --- a/scielomanager/journalmanager/tests/tests_tasks.py +++ b/scielomanager/journalmanager/tests/tests_tasks.py @@ -911,8 +911,8 @@ def test_convert_gif_image_to_jpeg(self): jpeg_buff = tasks.convert_image_to_jpeg(image_path, mode='RGB') jpeg_buff.seek(0) - with Image.open(jpeg_buff) as img: - self.assertEquals(img.format.lower(), 'jpeg') + img = Image.open(jpeg_buff) + self.assertEquals(img.format.lower(), 'jpeg') def test_convert_tif_image_to_jpeg(self): from PIL import Image @@ -922,8 +922,8 @@ def test_convert_tif_image_to_jpeg(self): jpeg_buff = tasks.convert_image_to_jpeg(image_path) jpeg_buff.seek(0) - with Image.open(jpeg_buff) as img: - self.assertEquals(img.format.lower(), 'jpeg') + img = Image.open(jpeg_buff) + self.assertEquals(img.format.lower(), 'jpeg') def test_convert_pdf_to_jpeg(self): """That should raise a IOError. From f7fffbc785176506708855d5a6b43c0760bf752c Mon Sep 17 00:00:00 2001 From: Fabio Batalha Date: Thu, 20 Oct 2016 15:11:11 -0200 Subject: [PATCH 04/13] Ajustes em porta do articlemeta (#1353) --- scielomanager/tools/import_data/requirements.txt | 2 +- scielomanager/tools/import_data/utils.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scielomanager/tools/import_data/requirements.txt b/scielomanager/tools/import_data/requirements.txt index 33b24515..e78ed0ae 100644 --- a/scielomanager/tools/import_data/requirements.txt +++ b/scielomanager/tools/import_data/requirements.txt @@ -1 +1 @@ --e git+https://github.com/scieloorg/xylose@1.7.5#egg=xylose +-e git+https://github.com/scieloorg/xylose@1.16.5#egg=xylose diff --git a/scielomanager/tools/import_data/utils.py b/scielomanager/tools/import_data/utils.py index 973adbec..aefc2411 100644 --- a/scielomanager/tools/import_data/utils.py +++ b/scielomanager/tools/import_data/utils.py @@ -15,13 +15,13 @@ def articlemeta_server(): try: - server = 'articlemeta.scielo.org:11720' + server = 'articlemeta.scielo.org:11620' host = server[0] port = int(server[1]) except: - logger.warning('Error defining Article Meta thrift server, assuming default server articlemeta.scielo.org:11720') + logger.warning('Error defining Article Meta thrift server, assuming default server articlemeta.scielo.org:11620') host = 'articlemeta.scielo.org' - port = 11720 + port = 11620 return clients.ArticleMeta(host, port) From 6f7e51c0be0467ac1be5932ccb5d09df4722a8b1 Mon Sep 17 00:00:00 2001 From: Jamil Atta Junior Date: Fri, 28 Oct 2016 13:34:06 -0200 Subject: [PATCH 05/13] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20do=20arquivo=20de?= =?UTF-8?q?=20tradu=C3=A7=C3=A3o=20Espanhol=20do=20SciELO=20Manager=20(#13?= =?UTF-8?q?56)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../locale/es_ES/LC_MESSAGES/django.po | 493 ++++-------------- 1 file changed, 99 insertions(+), 394 deletions(-) diff --git a/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po b/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po index 605f2c77..3fad0949 100644 --- a/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po +++ b/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po @@ -1,11 +1,12 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Translators: # fabiobatalha , 2012 -# Javani Araujo , 2016 +# javani , 2016 +# javani , 2016 # Juan Funez , 2014-2016 # maguirre21 , 2012 # mbarraza , 2012 @@ -16,14 +17,13 @@ msgstr "" "Project-Id-Version: SciELO Manager\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-10-03 17:53-0300\n" -"PO-Revision-Date: 2016-07-22 11:49+0000\n" -"Last-Translator: Javani Araujo \n" -"Language-Team: Spanish (Spain) (http://www.transifex.com/scielo/" -"scielomanager/language/es_ES/)\n" -"Language: es_ES\n" +"PO-Revision-Date: 2016-10-05 08:38+0000\n" +"Last-Translator: Gustavo Fonseca \n" +"Language-Team: Spanish (Spain) (http://www.transifex.com/scielo/scielomanager/language/es_ES/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: es_ES\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: accounts/views.py:25 @@ -36,8 +36,7 @@ msgstr "Existen errores o faltan datos." #: accounts/views.py:48 msgid "Your new password and new password confirmation must match." -msgstr "" -"La nueva contraseña y la confirmación de la nueva contraseña deben coincidir." +msgstr "La nueva contraseña y la confirmación de la nueva contraseña deben coincidir." #: accounts/views.py:57 msgid "Your current password does not match. Please try again." @@ -183,10 +182,9 @@ msgstr "Tal vez usted quiere" #: accounts/templates/accounts/unauthorized.html:10 msgid "" -"login with a more privileged account or contact support." -msgstr "" -"Inicie sesión con una cuenta de más previlegiada o " -"entre en contacto con el soporte." +"login with a more privileged account or contact " +"support." +msgstr "login" #: audit_log/helpers.py:274 #, python-format @@ -530,9 +528,7 @@ msgstr "Este número no tiene Cuerpo Editorial asociado" #: editorialmanager/templates/board/board_list_data.html:208 msgid "Cannot retrieve the Editorial Board because this journal has no Issues" -msgstr "" -"No se puede recuperar el Cuerpo Editorial porque esta revista no tiene " -"números" +msgstr "No se puede recuperar el Cuerpo Editorial porque esta revista no tiene números" #: editorialmanager/templates/board/board_member_delete.html:10 #: editorialmanager/templates/board/board_member_delete.html:14 @@ -629,7 +625,7 @@ msgstr "Idioma" #: journalmanager/templates/journalmanager/add_sponsor.html:130 #: journalmanager/templates/journalmanager/add_user.html:216 msgid "add another" -msgstr "" +msgstr "añadir otro" #: editorialmanager/templates/board/role_type_translate.html:100 #: editorialmanager/templates/journal/edit_journal.html:142 @@ -642,7 +638,7 @@ msgstr "" #: journalmanager/templates/journalmanager/add_sponsor.html:131 #: journalmanager/templates/journalmanager/add_user.html:217 msgid "remove" -msgstr "" +msgstr "quitar" #: editorialmanager/templates/includes/journal_detail_info.html:8 msgid "On-line version ISSN" @@ -669,7 +665,7 @@ msgstr "Gestionado por las colecciones" #: editorialmanager/templates/includes/journal_detail_info.html:24 msgid "Download full board as CSV file" -msgstr "Descargar este cuerpo editorial como archivo CSV" +msgstr "Descargar todo el cosejo editorial como un archivo CSV" #: editorialmanager/templates/journal/edit_journal.html:9 msgid "Edit journal" @@ -854,47 +850,19 @@ msgid "" "

\n" "

\n" " A .zip package will be downloaded, containing the\n" -" metadata files required by the Markup software.\n" +" metadata files required by the Markup software.\n" "

\n" "

\n" "

    \n" "
  • Close the Markup software
  • \n" "
  • Expand the .zip package
  • \n" -"
  • * Move all files to c:\\SciELO\\bin\\markup\\\n" +"
  • * Move all files to c:\\SciELO\\bin\\markup\\
  • \n" "
  • Reopen the Markup software et voilà!
  • \n" "
\n" "

\n" " * The default installation path.\n" " " -msgstr "" -"\n" -"

Los metadatos para el de software de margen

\n" -"

\n" -"

    \n" -"
  • Seleccione una publicación
  • \n" -"
  • Seleccione una edición
  • \n" -"
  • Da clic en el botón de descarga.
  • \n" -"
\n" -"

\n" -"

\n" -"Un paquete .zipserá descargado, conteniendo los archivos " -"del metadata requeridos por el software de Margen.\n" -"

\n" -"

\n" -"

    \n" -"
  • Cierra el software de Margen
  • \n" -"
  • Descompriime el archivo .zip
  • \n" -"
  • * Mueve todos los archivos a c:\\SciELO\\bin\\markup\\\n" -"
  • Reabre el software de margen y voilà!
  • \n" -"
\n" -"

\n" -"* La ruta de instalación por defecto." +msgstr "\n

Los metadatos para el de software de margen

\n

\n

    \n
  • Seleccione una publicación
  • \n
  • Seleccione una edición
  • \n
  • Da clic en el botón de descarga.
  • \n
\n

\n

\nUn paquete .zipserá descargado, conteniendo los archivos del metadata requeridos por el software de Margen.\n

\n

\n

    \n
  • Cierra el software de Margen
  • \n
  • Descompriime el archivo .zip
  • \n
  • * Mueve todos los archivos a c:\\SciELO\\bin\\markup\\
  • \n
  • Reabre el software de margen y voilà!
  • \n
\n

\n* La ruta de instalación por defecto." #: export/templates/export/markup_files.html:88 msgid "Please select a Journal" @@ -914,10 +882,7 @@ msgid "" "\n" " Updated about %(elapsed_time)s ago\n" " " -msgstr "" -"\n" -" Actualizado alrededor de %(elapsed_time)s atrás\n" -" " +msgstr "\n Actualizado alrededor de %(elapsed_time)s atrás\n " #: health/templates/health/overall_status.html:37 msgid "Service" @@ -945,14 +910,9 @@ msgstr "Desconectado" #: health/templates/health/overall_status.html:64 msgid "" "\n" -" Could not reach the health monitor. Keep calm and try " -"again later.\n" -" " -msgstr "" -"\n" -" El monitor de salud esta fuera de aclance. Mantanga la calma e " -"intente nuevamente más tarde.\n" +" Could not reach the health monitor. Keep calm and try again later.\n" " " +msgstr "\n El monitor de salud esta fuera de aclance. Mantanga la calma e intente nuevamente más tarde.\n " #: journalmanager/choices.py:70 #: journalmanager/templates/journalmanager/journal_list.html:50 @@ -975,9 +935,7 @@ msgstr "En proceso" #: journalmanager/forms.py:25 msgid "This email is being used by another user, please try another email." -msgstr "" -"Este correo electrónico es usado por otro usuario, por favor intente con " -"otro correo electrónico." +msgstr "Este correo electrónico es usado por otro usuario, por favor intente con otro correo electrónico." #: journalmanager/forms.py:63 msgid "Select one or more collections" @@ -989,7 +947,7 @@ msgstr "Seleccionar uno o más idiomas." #: journalmanager/forms.py:126 msgid "Abstract keyword languages" -msgstr "" +msgstr "Idioma de los resúmenes y palabras-clave" #: journalmanager/forms.py:128 msgid "Select one or more sponsors" @@ -1001,7 +959,7 @@ msgstr "Seleccionar una o más categorías" #: journalmanager/forms.py:132 msgid "Study area" -msgstr "Area de Estudio" +msgstr "Árede de estudio" #: journalmanager/forms.py:134 msgid "Select one or more study area" @@ -1015,59 +973,46 @@ msgstr "Categorías de Asunto" #: journalmanager/templates/journalmanager/add_journal.html:631 msgid "" "Journal cover image extension is not allowed! Please select another file." -msgstr "" -"La extensión de la imagen de portada de la revista, no está permitida! Por " -"favor seleccione otro archivo." +msgstr "La extensión de la imagen de portada de la revista, no está permitida! Por favor seleccione otro archivo." #: journalmanager/forms.py:192 #: journalmanager/templates/journalmanager/add_journal.html:629 -msgid "Journal cover image file size is too large! Please select another file." -msgstr "" -"El tamaño del archivo de imagen de portada de la revista, es muy grande! Por " -"favor seleccione otro archivo." +msgid "" +"Journal cover image file size is too large! Please select another file." +msgstr "El tamaño del archivo de imagen de portada de la revista, es muy grande! Por favor seleccione otro archivo." #: journalmanager/forms.py:198 msgid "" -"The image is {image_size}px pixel wide. It's supposed to be {expected_size}px" -msgstr "" -"La imagen es {image_size}px de ancho. Se supone que debe ser {expected_size}" -"px" +"The image is {image_size}px pixel wide. It's supposed to be " +"{expected_size}px" +msgstr "La imagen es {image_size}px de ancho. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:204 msgid "" -"The image is {image_size}px pixel high. It's supposed to be {expected_size}px" -msgstr "" -"La imagen es {image_size}px de altura. Se supone que debe ser {expected_size}" -"px" +"The image is {image_size}px pixel high. It's supposed to be " +"{expected_size}px" +msgstr "La imagen es {image_size}px de altura. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:215 #: journalmanager/templates/journalmanager/add_journal.html:632 msgid "" "Journal logo image extension is not allowed! Please select another file." -msgstr "" -"La extensión de la imagen del logo de la revista no está permitida! Por " -"favor seleccione otro archivo." +msgstr "La extensión de la imagen del logo de la revista no está permitida! Por favor seleccione otro archivo." #: journalmanager/forms.py:218 #: journalmanager/templates/journalmanager/add_journal.html:630 msgid "Journal logo image file size is too large! Please select another file." -msgstr "" -"La extensión de la imagen del logo de la revista es muy grande! Por favor " -"seleccione otro archivo." +msgstr "La extensión de la imagen del logo de la revista es muy grande! Por favor seleccione otro archivo." #: journalmanager/forms.py:223 msgid "" "The image is {logo_size}px pixel wide. It's supposed to be {expected_size}px" -msgstr "" -"La imagen del logo tiene {logo_size}px de ancho. Se supone que debe ser " -"{expected_size}px" +msgstr "La imagen del logo tiene {logo_size}px de ancho. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:227 msgid "" "The image is {logo_size}px pixel high. It's supposed to be {expected_size}px" -msgstr "" -"La imagen del logo tiene {logo_size}px de altura. Se supone que debe ser " -"{expected_size}px" +msgstr "La imagen del logo tiene {logo_size}px de altura. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:296 #: scielomanager/templates/registration/login.html:28 @@ -1099,8 +1044,7 @@ msgstr "Licencia de Uso" #: journalmanager/forms.py:405 msgid "You must complete at least one of two fields volume or number." -msgstr "" -"Usted debe completar por lo menos uno de los dos campos del volumen o número." +msgstr "Usted debe completar por lo menos uno de los dos campos del volumen o número." #: journalmanager/forms.py:416 journalmanager/forms.py:470 #: journalmanager/forms.py:475 journalmanager/forms.py:521 @@ -1111,17 +1055,15 @@ msgstr "Número con este Año y (Volumen o Número) ya existe para esta revista" #: journalmanager/forms.py:453 journalmanager/forms.py:508 msgid "You must complete the volume filed. Number field must be empty." -msgstr "" -"Usted debe completar el campo Volumen. El campo Número debe quedar vacío." +msgstr "Usted debe completar el campo Volumen. El campo Número debe quedar vacío." #: journalmanager/forms.py:455 journalmanager/forms.py:510 msgid "You must complete the number filed. Volume field must be empty." -msgstr "" -"Usted debe completar el campo Número. El campo Volumen debe quedar vacío." +msgstr "Usted debe completar el campo Número. El campo Volumen debe quedar vacío." #: journalmanager/forms.py:549 msgid "Legacy Code" -msgstr "Código de Licencia" +msgstr "Código anterior" #: journalmanager/forms.py:854 msgid "Please fill in at least one form" @@ -1130,13 +1072,10 @@ msgstr "Por favor complete por lo menos un formulario" #: journalmanager/models.py:44 msgid "" "If not defined, will be applied the related journal's use license. The " -"SciELO default use license is BY-NC. Please visit: http://ref.scielo.org/" -"jf5ndd (5.2.11. Política de direitos autorais) for more details." -msgstr "" -"Sí no es definida, será aplicada la licencia de uso de la revista " -"relacionada. La licencia de uso por defecto de SciELO es BY-NC. Por favor " -"visite: http://ref.scielo.org/jf5ndd (5.2.11. Política de direitos autorais) " -"para más información." +"SciELO default use license is BY-NC. Please visit: " +"http://ref.scielo.org/jf5ndd (5.2.11. Política de direitos autorais) for " +"more details." +msgstr "Sí no es definida, será aplicada la licencia de uso de la revista relacionada. La licencia de uso por defecto de SciELO es BY-NC. Por favor visite: http://ref.scielo.org/jf5ndd (5.2.11. Política de direitos autorais) para más información." #: journalmanager/models.py:288 journalmanager/models.py:1520 msgid "ISO 639-1 Language Code" @@ -1226,11 +1165,11 @@ msgstr "Licencia de Uso" #: journalmanager/models.py:528 msgid "CCN Code" -msgstr "Código SECS" +msgstr "Código CCN" #: journalmanager/models.py:529 msgid "The code of the journal at the CCN database." -msgstr "" +msgstr "El código de la revista en la base de datos CCN" #: journalmanager/models.py:534 msgid "Subject Categories" @@ -1403,7 +1342,7 @@ msgstr "¿Por qué usted está cambiando el estado de publicación?" #: journalmanager/models.py:774 msgid "Reason" -msgstr "Reason" +msgstr "Razón" #: journalmanager/models.py:780 journalmanager/models.py:836 #: journalmanager/models.py:1112 journalmanager/models.py:1213 @@ -1519,8 +1458,7 @@ msgstr "Guardado." #: journalmanager/views.py:53 msgid "Saved partially. You can continue to fill in this form later." -msgstr "" -"Guardado parcialmente. Puede continuar completando el formulario después." +msgstr "Guardado parcialmente. Puede continuar completando el formulario después." #: journalmanager/views.py:55 msgid "The pended form has been deleted." @@ -1555,8 +1493,7 @@ msgstr "Esta revista ya existe, por favor búsquela en el paso anterior" #: journalmanager/views.py:988 msgid "" "Issue created successfully, however we can not create the editorial board." -msgstr "" -"Número creado con éxito, sin embargo no podemos crear el Cuerpo Editorial." +msgstr "Número creado con éxito, sin embargo no podemos crear el Cuerpo Editorial." #: journalmanager/views.py:1088 msgid "Section removed successfully" @@ -1716,11 +1653,11 @@ msgstr "PID del artículo" #: journalmanager/templates/journalmanager/add_pressrelease.html:124 msgid "Body" -msgstr "Cuerpo" +msgstr "Cuerpo de texto" #: journalmanager/templates/journalmanager/add_pressrelease.html:127 msgid "Preview as HTML" -msgstr "Vista previa" +msgstr "Vista previa en HTML" #: journalmanager/templates/journalmanager/add_section.html:95 msgid "Section Information" @@ -1794,19 +1731,19 @@ msgstr "Versión del artículo" #: journalmanager/templates/journalmanager/article_detail.html:48 #: validator/templates/validator/preview_html.html:85 msgid "HTML preview" -msgstr "Vista previa" +msgstr "Vista previa en HTML" #: journalmanager/templates/journalmanager/article_detail.html:54 msgid "Source XML" -msgstr "" +msgstr "Source XML" #: journalmanager/templates/journalmanager/article_detail.html:68 msgid "Sorry, but the HTML preview is not available for this article." -msgstr "" +msgstr "Discúlpame, pero la previa vista en HTML no está disponible para este artículo" #: journalmanager/templates/journalmanager/article_detail.html:76 msgid "This article doesn't have a XML file." -msgstr "Este artículo no tiene XML" +msgstr "Este artículo no tiene un archivo XML" #: journalmanager/templates/journalmanager/article_list.html:5 #: journalmanager/templates/journalmanager/issue_list.html:51 @@ -1882,11 +1819,9 @@ msgstr "Cambiar usuario editor" #: journalmanager/templates/journalmanager/editor.html:52 msgid "" -"Warning! No user was selected as editor of this journal. To " -"be the editor user must be in 'Editors' group" -msgstr "" -"Atención! No se ha seleccionado un usuario editor para esta " -"revista. Para ser el usuario editor debe pertenecer al grupo: 'Editors'" +"Warning! No user was selected as editor of this journal. To" +" be the editor user must be in 'Editors' group" +msgstr "Atención! No se ha seleccionado un usuario editor para esta revista. Para ser el usuario editor debe pertenecer al grupo: 'Editors'" #: journalmanager/templates/journalmanager/home_journal.html:16 msgid "Drafts" @@ -2000,9 +1935,7 @@ msgstr "Agregar revista a mi colección" msgid "" "To insert a journal, you need to check whether the journal exists. If it " "exists just add to your collection!" -msgstr "" -"Para ingresar una revista, es necesario comprobar si ya existe. Si es que ya " -"existe sólo tiene que añadirlo a su colección!" +msgstr "Para ingresar una revista, es necesario comprobar si ya existe. Si es que ya existe sólo tiene que añadirlo a su colección!" #: journalmanager/templates/journalmanager/journal_list.html:165 msgid "Search journal" @@ -2022,7 +1955,7 @@ msgstr "ISSN electrónico" #: journalmanager/templates/journalmanager/journal_list.html:214 msgid "Collections" -msgstr "Colección" +msgstr "Colecciones" #: journalmanager/templates/journalmanager/journal_list.html:226 msgid "No journal(s) found to the term: " @@ -2068,9 +2001,7 @@ msgstr "Código" msgid "" "Hey, you can not remove the sections that are being used by at least one " "issue of this journal." -msgstr "" -"Hey, no puede remover secciones que están siendo usadas por al menos un " -"número de esta revista." +msgstr "Hey, no puede remover secciones que están siendo usadas por al menos un número de esta revista." #: journalmanager/templates/journalmanager/trash_listing.html:7 msgid "Trash" @@ -2134,9 +2065,9 @@ msgid "This journal does not have a logo" msgstr "Esta revista no tiene logo" #: journalmanager/templates/journalmanager/includes/issue_cover.html:15 -msgid "This issue does not have a cover, it will use the default journal cover" -msgstr "" -"Esta revista no tiene portada, utilizará la portada de periódico por defecto" +msgid "" +"This issue does not have a cover, it will use the default journal cover" +msgstr "Esta revista no tiene portada, utilizará la portada de periódico por defecto" #: journalmanager/templates/journalmanager/includes/issue_form_generic_field_list.html:19 msgid "Add new" @@ -2195,11 +2126,8 @@ msgid "Report" msgstr "Reporte" #: scielomanager/custom_fields.py:44 -#, fuzzy msgid "Please keep file size under {maxsize}. Current file size {filesize}" -msgstr "" -"Por favor mantenga el tamaño de los archivos menores a %(maxsize)s. Tamaño " -"actual del archivo %(filesize)s" +msgstr "Por favor mantenga el tamaño del archivo menor a {maxsize}. Tamaño actual del archivo {filesize}" #: scielomanager/custom_fields.py:50 msgid "File type not supported." @@ -2281,7 +2209,7 @@ msgstr "SciELO Style Checker" #: scielomanager/templates/footer.html:38 msgid "HTML Previewer" -msgstr "Vista previa" +msgstr "Vista previa en HTML" #: scielomanager/templates/include_press_release/ahead.html:5 #: scielomanager/templates/include_press_release/issue.html:5 @@ -2307,9 +2235,7 @@ msgstr "Por favor haga click en el link a continuación para activar su cuenta." msgid "" "\n" " This key will expire in %(expiration_days)s days.\n" -msgstr "" -"\n" -" Esta clave expirará en %(expiration_days)s dias.\n" +msgstr "\n Esta clave expirará en %(expiration_days)s dias.\n" #: scielomanager/templates/registration/login.html:9 msgid "We are under maintenance!" @@ -2340,9 +2266,7 @@ msgstr "¿Olvidó tu contraseña?" msgid "" "Your password has been reseted! You may now login in using your new " "credentials." -msgstr "" -"¡Tu contraseña ha sido restablecida! Ahora puedes iniciar sesión con tu " -"nueva información." +msgstr "¡Tu contraseña ha sido restablecida! Ahora puedes iniciar sesión con tu nueva información." #: scielomanager/templates/registration/password_reset_complete.html:9 msgid "login" @@ -2364,10 +2288,7 @@ msgstr "Este enlace ya fue utilizado para restablecer su contraseña." msgid "" "We have sent you an email with a link to reset your password. Please check " "your email and click the link to continue." -msgstr "" -"Le hemos enviado un correo electrónico con un enlace para restablecer tu " -"contraseña. Por favor, consulte su correo electrónico y haga click en el " -"vínculo para continuar." +msgstr "Le hemos enviado un correo electrónico con un enlace para restablecer tu contraseña. Por favor, consulte su correo electrónico y haga click en el vínculo para continuar." #: scielomanager/templates/registration/password_reset_done.html:9 msgid "Login" @@ -2383,30 +2304,15 @@ msgid "" "requested that your password be reset on %(site_name)s. If you do not\n" "wish to reset your password, please ignore this message.\n" "\n" -"To reset your password, please click the following link, or copy and paste " -"it\n" +"To reset your password, please click the following link, or copy and paste it\n" "into your web browser:\n" -msgstr "" -"\n" -"Saludos %(user)s,\n" -"\n" -"Has recibido este correo porque tú (o alguien más pretendiendo ser tú)\n" -"ha solicitado el restablecimiento de su contraseña en %(site_name)s. Si tú " -"no\n" -"deseas restablecer tu contraseña, por favor ignora este mensaje.\n" -"\n" -"Para restablecer tu contraseña, por favor da clic en el siguiente enlace, o " -"cópialo y pégalo\n" -"en tu navegador de internet:\n" +msgstr "\nSaludos %(user)s,\n\nHas recibido este correo porque tú (o alguien más pretendiendo ser tú)\nha solicitado el restablecimiento de su contraseña en %(site_name)s. Si tú no\ndeseas restablecer tu contraseña, por favor ignora este mensaje.\n\nPara restablecer tu contraseña, por favor da clic en el siguiente enlace, o cópialo y pégalo\nen tu navegador de internet:\n" #: scielomanager/templates/registration/password_reset_form.html:9 msgid "" "Enter your e-mail in the form below and we will send your username and " "instructions to create a new password." -msgstr "" -"Ingrese su dirección de correo electrónico en el siguiente formulario y " -"nosotros le enviaremos su usuario y las instrucciones para crear una nueva " -"contraseña." +msgstr "Ingrese su dirección de correo electrónico en el siguiente formulario y nosotros le enviaremos su usuario y las instrucciones para crear una nueva contraseña." #: scielomanager/templates/registration/password_reset_form.html:11 msgid "Reset Password" @@ -2424,9 +2330,7 @@ msgstr "Un correo electrónico de confirmación está en camino" msgid "" "Please click the activation link included in the e-mail to confirm you " "registration." -msgstr "" -"Por favor, haga click en el enlace de activación incluido en el correo " -"electrónico para confirmar la inscripción." +msgstr "Por favor, haga click en el enlace de activación incluido en el correo electrónico para confirmar la inscripción." #: scielomanager/templates/registration/registration_form.html:6 #: scielomanager/templates/registration/registration_form.html:19 @@ -2439,8 +2343,7 @@ msgstr "Por favor, corrija los siguientes errores." #: scielomanager/templates/registration/registration_form.html:12 msgid "You will receive an email with a link to activate your account." -msgstr "" -"Usted recibirá un correo electrónico con un enlace para activar su cuenta." +msgstr "Usted recibirá un correo electrónico con un enlace para activar su cuenta." #: validator/forms.py:10 #: validator/templates/validator/includes/xml_annotated.html:15 @@ -2450,33 +2353,29 @@ msgstr "Archivo" #: validator/forms.py:16 #: validator/templates/validator/includes/xml_upload_form_validation.html:25 msgid "This type of file is not allowed! Please select another file." -msgstr "" -"Este tipo de archivo no está permitido! Por favor seleccione otro archivo." +msgstr "Este tipo de archivo no está permitido! Por favor seleccione otro archivo." #: validator/forms.py:19 msgid "The file's size is too large! Please select a smaller file." -msgstr "" -"El tamaño de archivo es muy grande! Por favor seleccione otro archivo. " +msgstr "El tamaño de archivo es muy grande! Por favor seleccione otro archivo. " #: validator/templates/validator/preview_html.html:6 msgid "Packtools - SciELO HTML Previewer" -msgstr "" +msgstr "Oacktools - Vista previa en HTML" #: validator/templates/validator/preview_html.html:14 msgid "SciELO HTML Previewer" -msgstr "" +msgstr "SciELO - Vista previa en HTML" #: validator/templates/validator/preview_html.html:15 msgid "Use this tool to preview your XML file as an HTML" -msgstr "" +msgstr "Use esta herramienta para ver su archivo XML como un HTML" #: validator/templates/validator/preview_html.html:16 msgid "" "Browse to your local XML file and click 'Preview'. The results will be " "displayed below." -msgstr "" -"Busque su archivo XML localmente y haga clic en \"Validar\". Los resultados " -"aparecerán a continuación." +msgstr "Busque su archivo XML localmente y haga clic en \"Vista Previa\". Los resultados aparecerán a continuación." #: validator/templates/validator/preview_html.html:24 #: validator/templates/validator/stylechecker.html:28 @@ -2506,22 +2405,14 @@ msgstr "Vista previa" #: validator/templates/validator/stylechecker.html:68 msgid "" "\n" -" If you have any problems with the tool or with the SPS Tagging " -"Guidelines, please contact:\n" -" scielo-" -"xml@googlegroups.com.\n" -" " -msgstr "" -"\n" -" Si tiene algún problema con esta herramienta o con el SPS " -"Tagging Guidelines, por favor entre en contacto con:\n" -" scielo-" -"xml@googlegroups.com.\n" +" If you have any problems with the tool or with the SPS Tagging Guidelines, please contact:\n" +" scielo-xml@googlegroups.com.\n" " " +msgstr "\n Si tiene algún problema con esta herramienta o con el SPS Tagging Guidelines, por favor entre en contacto con:\n scielo-xml@googlegroups.com.\n " #: validator/templates/validator/preview_html.html:99 msgid "No HTML generated, is the XML file valid?" -msgstr "" +msgstr "El HTML no fue generado, ¿el archivo XML es válido?" #: validator/templates/validator/stylechecker.html:6 msgid "Packtools - Style Checker" @@ -2534,34 +2425,21 @@ msgstr "SciELO Style Checker" #: validator/templates/validator/stylechecker.html:12 msgid "" "\n" -" Use this tool to confirm whether an XML file conforms to SciELO Style " -"as defined in the SciELO Publishing Schema Tagging Guidelines.\n" -" " -msgstr "" -"\n" -" Use esta herramienta para confirmar sí un archivo XML esta conforme al " -"SciELO Style cuyas definiciones son especificadas por el SciELO Publishing " -"Schema Tagging Guidelines.\n" +" Use this tool to confirm whether an XML file conforms to SciELO Style as defined in the SciELO Publishing Schema Tagging Guidelines.\n" " " +msgstr "\n Use esta herramienta para confirmar sí un archivo XML esta conforme al SciELO Style cuyas definiciones son especificadas por el SciELO Publishing Schema Tagging Guidelines.\n " #: validator/templates/validator/stylechecker.html:17 msgid "" "\n" -" Browse to your local XML file and click \"Validate\". The results will " -"be displayed below.\n" -" " -msgstr "" -"\n" -" Busque su archivo XML localmente y haga clic en \"Validar\". Los " -"resultados aparecerán a continuación.\n" +" Browse to your local XML file and click \"Validate\". The results will be displayed below.\n" " " +msgstr "\n Busque su archivo XML localmente y haga clic en \"Validar\". Los resultados aparecerán a continuación.\n " #: validator/templates/validator/stylechecker.html:55 msgid "" "\n" -" Also validate against SciELO Brazil's specific rules. Read more.\n" +" Also validate against SciELO Brazil's specific rules. Read more.\n" " " msgstr "" @@ -2602,15 +2480,11 @@ msgstr "Atención!" msgid "" "This XML document uses a version of SciELO PS that soon will no longer be " "supported. Please consider upgrading to a newer version as soon as possible." -msgstr "" -"Este documento XML usa una versión de SciELO PS que pronto dejará de ser " -"soportada. Por favor considere actualizarlo a una versión mas nueva tan " -"pronto como sea posible." +msgstr "Este documento XML usa una versión de SciELO PS que pronto dejará de ser soportada. Por favor considere actualizarlo a una versión mas nueva tan pronto como sea posible." #: validator/templates/validator/includes/xml_annotated.html:50 msgid "If you want to know more about the support policy, please refer to" -msgstr "" -"Si usted desea conocer más sobre la política de soporte, por favor visite" +msgstr "Si usted desea conocer más sobre la política de soporte, por favor visite" #: validator/templates/validator/includes/xml_annotated.html:52 msgid "SciELO PS official documentation" @@ -2714,183 +2588,16 @@ msgstr "en las lineas anteriores" #: validator/templates/validator/includes/xml_upload_form_validation.html:30 msgid "The file size is too large! Please select a smaller file." -msgstr "" -"El tamaño de archivo es muy grande! Por favor seleccione otro archivo. " +msgstr "El tamaño de archivo es muy grande! Por favor seleccione otro archivo." #~ msgid "Lanaguages" -#~ msgstr "Idiomas" - -#~ msgid "Corpo editorial" -#~ msgstr "Cuerpo editorial" - -#~ msgid "User can't do this action: %s" -#~ msgstr "El usuario no puede realizar esta acción: %s" - -#~ msgid "User can't ACCEPT checkins, because doesn't have enough permissions" -#~ msgstr "" -#~ "El usuario no puede ACEPTAR checkins, porque no cuenta con permisos " -#~ "suficientes" - -#~ msgid "User can't REJECT checkins, because doesn't have enough permissions" -#~ msgstr "" -#~ "El usuario no puede RECHAZAR checkins, porque no cuenta con permisos " -#~ "suficientes" - -#~ msgid "" -#~ "User can't REVIEW (Level 1) checkins, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede REVISAR checkins (Nivel 1), porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't REVIEW (Level 2) checkins, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede REVISAR checkins (Nivel 2), porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't SEND checkins TO REVIEW, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede ENVIAR checkins PARA REVISIÓN, porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't SEND checkins TO PENDING, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede ENVIAR checkins PARA PENDIENTE, porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't SEND checkins TO CHECKOUT, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede ENVIAR checkins PARA CHECKOUT, porque no cuenta con " -#~ "permisos suficientes" +#~ msgstr "Languages" #~ msgid "National Code" -#~ msgstr "Código Nacional" - -#~ msgid "XML content" -#~ msgstr "Contenido del artículo" - -#~ msgid "Coleções" -#~ msgstr "Colecciones" - -#~ msgid "Titulos" -#~ msgstr "Títulos" - -#~ msgid "Packtools StyleChecker" -#~ msgstr "Packtools StyleChecker" - -#~ msgid "usage: " -#~ msgstr "uso:" - -#~ msgid ".__call__() not defined" -#~ msgstr ".__call__() no definido" - -#~ msgid "unknown parser {parser_name} (choices: {choices})" -#~ msgstr "parser desconocido {parser_name} (opciones: {choices})" - -#~ msgid "argument \"-\" with mode %r" -#~ msgstr "argumento \"-\" con modo %r" - -#~ msgid "cannot merge actions - two groups are named %r" -#~ msgstr "no es posible mezclar las acciones - dos grupos son nombrados %r" - -#~ msgid "'required' is an invalid argument for positionals" -#~ msgstr "'required' es un argumento no válido para posicionales" - -#~ msgid "" -#~ "invalid option string {option_string}: must start with a character " -#~ "{prefix_chars}" -#~ msgstr "" -#~ "opción de cadena invalida {option_string}: debe comenzar con el caracter " -#~ "{prefix_chars}" - -#~ msgid "dest= is required for options like %r" -#~ msgstr "dest= es requerido para opciones como %r" - -#~ msgid "invalid conflict_resolution value: %r" -#~ msgstr "valor conflict_resolution inválido: %r" - -#~ msgid "conflicting option string(s): %s" -#~ msgstr "opción de cadena(s): %s conflictantes" - -#~ msgid "mutually exclusive arguments must be optional" -#~ msgstr "argumentos mutuamente exclusivos debe ser opcional" - -#~ msgid "positional arguments" -#~ msgstr "argumentos posicionales" +#~ msgstr "National Code" #~ msgid "optional arguments" -#~ msgstr "argumentos opcionales" - -#~ msgid "show this help message and exit" -#~ msgstr "mostrar este mensaje de ayuda y salir" - -#~ msgid "show program's version number and exit" -#~ msgstr "mostrar número de la versión del programa y salir" - -#~ msgid "cannot have multiple subparser arguments" -#~ msgstr "no es posible tener múltiples argumentos de subparser" - -#~ msgid "unrecognized arguments: %s" -#~ msgstr "argumentos no reconocidos: %s" - -#~ msgid "not allowed with argument %s" -#~ msgstr "no permitido con argumentos %s" - -#~ msgid "ignored explicit argument %r" -#~ msgstr "argumentos explícitos ignorado: %r" - -#~ msgid "too few arguments" -#~ msgstr "muy pocos argumentos" - -#~ msgid "argument %s is required" -#~ msgstr "argumento %s es obligatorio" - -#~ msgid "one of the arguments %s is required" -#~ msgstr "uno de estos argumentos %s son obligatorios" - -#~ msgid "expected one argument" -#~ msgstr "un argumento esperado" - -#~ msgid "expected at most one argument" -#~ msgstr "a lo sumo un argumento esperado" - -#~ msgid "expected at least one argument" -#~ msgstr "al menos un argumento esperado" - -#~ msgid "expected %s argument(s)" -#~ msgstr "esperados argumento(s): %s" - -#~ msgid "ambiguous option: {arg_string} could match {options}" -#~ msgstr "opción ambigua: {arg_string} podría coincidir {options}" - -#~ msgid "unexpected option string: %s" -#~ msgstr "opción de cadena inesperada: %s" - -#~ msgid "%r is not callable" -#~ msgstr "%r no se puede llamar" - -#~ msgid "invalid {name} value: {arg_string}" -#~ msgstr "valor {name} inválid: {arg_string}" - -#~ msgid "invalid choice: {value} (choose from {choices})" -#~ msgstr "opción inválida: {value} (opciones {choices})" - -#~ msgid "{prog}: error: message\n" -#~ msgstr "{prog}: error: mensaje\n" - -#~ msgid "The file submitted is NOT XML" -#~ msgstr "Este archivo NO ES XML" - -#~ msgid "XML file excedes max upload size" -#~ msgstr "El archivo XML supera el tamaño máximo de subida permitido" +#~ msgstr "Total of Documents" #~ msgid "logout" #~ msgstr "logout" @@ -2986,11 +2693,9 @@ msgstr "" #~ msgstr "Your username and password did not match. Please try again." #~ msgid "" -#~ "Your account is not active. Please contact the SciELO or verify your e-" -#~ "mail" +#~ "Your account is not active. Please contact the SciELO or verify your e-mail" #~ msgstr "" -#~ "Your account is not active. Please contact the SciELO or verify your e-" -#~ "mail" +#~ "Your account is not active. Please contact the SciELO or verify your e-mail" #~ msgid "Please login on the system to see this page" #~ msgstr "Please login on the system to see this page" From 82bfb603cd319894d6b2679adbc288c370397a49 Mon Sep 17 00:00:00 2001 From: Bruno Melo Date: Mon, 21 Nov 2016 20:02:07 -0200 Subject: [PATCH 06/13] Corrigindo texto --- docs/dev/exporttoisis.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/dev/exporttoisis.rst b/docs/dev/exporttoisis.rst index b4cf00dc..a51bdec0 100644 --- a/docs/dev/exporttoisis.rst +++ b/docs/dev/exporttoisis.rst @@ -22,14 +22,14 @@ Para a nova versão da ferramenta de gestão de periódicos, considerando as car Introdução ---------- -As bases de dados ISIS geradas pelo Title Manager são utilizadas em dois prontos do processo de publicação da SciELO, são eles: processo de marcação e processamento para inclusão de conteúdo. +As bases de dados ISIS geradas pelo Title Manager são utilizadas em dois pontos do processo de publicação da SciELO, são eles: processo de marcação e processamento para inclusão de conteúdo. Processamento para inclusão de conteúdo ======================================= Atualmente o SciELO possui um processamento (geraPadrao.bat) para inclusão de novas revistas, fascículos e artigos na coleção. Esse processamento recebe como entrada um conjunto de bases de dados, são elas: artigo, issue, code, title. -As bases code, title e issue são únicadas para todo o processamento, significa que uma base de dados com todo o conteúdo de título, outra com todo conteúdo de code e outra com todo conteúdo de issues são geradas e gravadas em um diretório chamado serial gerando a seguinte estrutura de dados de entrada para o processamento. +As bases code, title e issue são únicas para todo o processamento, significa que uma base de dados com todo o conteúdo de título, outra com todo conteúdo de code e outra com todo conteúdo de issues são geradas e gravadas em um diretório chamado serial gerando a seguinte estrutura de dados de entrada para o processamento. .. code-block:: text @@ -74,7 +74,7 @@ Em resumo, significa que o processo de exportação de bases do SciELO Manager p Processo de Marcação ==================== -O processo de marcação de metadados de artigos nas SciELO é feito através da ferramenta Markup, que corresponde a um aplicativo VBSript embutido no Word para identificar os elementos dos artigos. Esse plugin do Word consulta algumas bases de dados ISIS geradas pela Title Manager para complementar a identificação de elementos no texto do artigo, como por exemplo: +O processo de marcação de metadados de artigos nas SciELO é feito através da ferramenta Markup, que corresponde a um aplicativo VBScript embutido no Word para identificar os elementos dos artigos. Esse plugin do Word consulta algumas bases de dados ISIS geradas pela Title Manager para complementar a identificação de elementos no texto do artigo, como por exemplo: * Identificação de seções dos fascículos (base code) @@ -334,7 +334,7 @@ Title quando mais de uma coleção compartilha mesma base title no site local. Resolver este problema criando instalações independentes para cada coleção SciELO, ex: Brasil e Saúde Pública. - Foram encontradas ocorrencias do campo v691 no arquivo sci_serial.xis entretanto parece não estar + Foram encontradas ocorrências do campo v691 no arquivo sci_serial.xis entretanto parece não estar em uso uma vez que faz referência a arquivos template (ScieloXML/collections.xis) que não estão atualizados. @@ -418,4 +418,4 @@ Title 20. Seção (130) - Excluído da aplicação. Não precisa ser mantido para compatibilidade. Nunca foi usado \ No newline at end of file + Excluído da aplicação. Não precisa ser mantido para compatibilidade. Nunca foi usado From b4cc02adff41445389a2e01c2b8df34d3441b849 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Tue, 22 Nov 2016 16:50:02 -0200 Subject: [PATCH 07/13] Update packtools from 1.3.1 to 1.3.2 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 90058441..b3065e62 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ yuicompressor jsonfield django-tastypie==0.9.16 django-htmlmin==0.7.0 -packtools==1.3.1 +packtools==1.3.2 Celery django-celery django-kombu From dfe938a796a4db84d397d1135143f49b8143823f Mon Sep 17 00:00:00 2001 From: Jamil Atta Junior Date: Wed, 23 Nov 2016 15:04:57 -0200 Subject: [PATCH 08/13] Atualizando o .po do Espanhol --- .../locale/es_ES/LC_MESSAGES/django.po | 493 ++++-------------- 1 file changed, 99 insertions(+), 394 deletions(-) diff --git a/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po b/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po index 605f2c77..3fad0949 100644 --- a/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po +++ b/scielomanager/scielomanager/locale/es_ES/LC_MESSAGES/django.po @@ -1,11 +1,12 @@ # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. -# +# # Translators: # Translators: # fabiobatalha , 2012 -# Javani Araujo , 2016 +# javani , 2016 +# javani , 2016 # Juan Funez , 2014-2016 # maguirre21 , 2012 # mbarraza , 2012 @@ -16,14 +17,13 @@ msgstr "" "Project-Id-Version: SciELO Manager\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2016-10-03 17:53-0300\n" -"PO-Revision-Date: 2016-07-22 11:49+0000\n" -"Last-Translator: Javani Araujo \n" -"Language-Team: Spanish (Spain) (http://www.transifex.com/scielo/" -"scielomanager/language/es_ES/)\n" -"Language: es_ES\n" +"PO-Revision-Date: 2016-10-05 08:38+0000\n" +"Last-Translator: Gustavo Fonseca \n" +"Language-Team: Spanish (Spain) (http://www.transifex.com/scielo/scielomanager/language/es_ES/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Language: es_ES\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: accounts/views.py:25 @@ -36,8 +36,7 @@ msgstr "Existen errores o faltan datos." #: accounts/views.py:48 msgid "Your new password and new password confirmation must match." -msgstr "" -"La nueva contraseña y la confirmación de la nueva contraseña deben coincidir." +msgstr "La nueva contraseña y la confirmación de la nueva contraseña deben coincidir." #: accounts/views.py:57 msgid "Your current password does not match. Please try again." @@ -183,10 +182,9 @@ msgstr "Tal vez usted quiere" #: accounts/templates/accounts/unauthorized.html:10 msgid "" -"login with a more privileged account or contact support." -msgstr "" -"Inicie sesión con una cuenta de más previlegiada o " -"entre en contacto con el soporte." +"login with a more privileged account or contact " +"support." +msgstr "login" #: audit_log/helpers.py:274 #, python-format @@ -530,9 +528,7 @@ msgstr "Este número no tiene Cuerpo Editorial asociado" #: editorialmanager/templates/board/board_list_data.html:208 msgid "Cannot retrieve the Editorial Board because this journal has no Issues" -msgstr "" -"No se puede recuperar el Cuerpo Editorial porque esta revista no tiene " -"números" +msgstr "No se puede recuperar el Cuerpo Editorial porque esta revista no tiene números" #: editorialmanager/templates/board/board_member_delete.html:10 #: editorialmanager/templates/board/board_member_delete.html:14 @@ -629,7 +625,7 @@ msgstr "Idioma" #: journalmanager/templates/journalmanager/add_sponsor.html:130 #: journalmanager/templates/journalmanager/add_user.html:216 msgid "add another" -msgstr "" +msgstr "añadir otro" #: editorialmanager/templates/board/role_type_translate.html:100 #: editorialmanager/templates/journal/edit_journal.html:142 @@ -642,7 +638,7 @@ msgstr "" #: journalmanager/templates/journalmanager/add_sponsor.html:131 #: journalmanager/templates/journalmanager/add_user.html:217 msgid "remove" -msgstr "" +msgstr "quitar" #: editorialmanager/templates/includes/journal_detail_info.html:8 msgid "On-line version ISSN" @@ -669,7 +665,7 @@ msgstr "Gestionado por las colecciones" #: editorialmanager/templates/includes/journal_detail_info.html:24 msgid "Download full board as CSV file" -msgstr "Descargar este cuerpo editorial como archivo CSV" +msgstr "Descargar todo el cosejo editorial como un archivo CSV" #: editorialmanager/templates/journal/edit_journal.html:9 msgid "Edit journal" @@ -854,47 +850,19 @@ msgid "" "

\n" "

\n" " A .zip package will be downloaded, containing the\n" -" metadata files required by the Markup software.\n" +" metadata files required by the Markup software.\n" "

\n" "

\n" "

    \n" "
  • Close the Markup software
  • \n" "
  • Expand the .zip package
  • \n" -"
  • * Move all files to c:\\SciELO\\bin\\markup\\\n" +"
  • * Move all files to c:\\SciELO\\bin\\markup\\
  • \n" "
  • Reopen the Markup software et voilà!
  • \n" "
\n" "

\n" " * The default installation path.\n" " " -msgstr "" -"\n" -"

Los metadatos para el de software de margen

\n" -"

\n" -"

    \n" -"
  • Seleccione una publicación
  • \n" -"
  • Seleccione una edición
  • \n" -"
  • Da clic en el botón de descarga.
  • \n" -"
\n" -"

\n" -"

\n" -"Un paquete .zipserá descargado, conteniendo los archivos " -"del metadata requeridos por el software de Margen.\n" -"

\n" -"

\n" -"

    \n" -"
  • Cierra el software de Margen
  • \n" -"
  • Descompriime el archivo .zip
  • \n" -"
  • * Mueve todos los archivos a c:\\SciELO\\bin\\markup\\\n" -"
  • Reabre el software de margen y voilà!
  • \n" -"
\n" -"

\n" -"* La ruta de instalación por defecto." +msgstr "\n

Los metadatos para el de software de margen

\n

\n

    \n
  • Seleccione una publicación
  • \n
  • Seleccione una edición
  • \n
  • Da clic en el botón de descarga.
  • \n
\n

\n

\nUn paquete .zipserá descargado, conteniendo los archivos del metadata requeridos por el software de Margen.\n

\n

\n

    \n
  • Cierra el software de Margen
  • \n
  • Descompriime el archivo .zip
  • \n
  • * Mueve todos los archivos a c:\\SciELO\\bin\\markup\\
  • \n
  • Reabre el software de margen y voilà!
  • \n
\n

\n* La ruta de instalación por defecto." #: export/templates/export/markup_files.html:88 msgid "Please select a Journal" @@ -914,10 +882,7 @@ msgid "" "\n" " Updated about %(elapsed_time)s ago\n" " " -msgstr "" -"\n" -" Actualizado alrededor de %(elapsed_time)s atrás\n" -" " +msgstr "\n Actualizado alrededor de %(elapsed_time)s atrás\n " #: health/templates/health/overall_status.html:37 msgid "Service" @@ -945,14 +910,9 @@ msgstr "Desconectado" #: health/templates/health/overall_status.html:64 msgid "" "\n" -" Could not reach the health monitor. Keep calm and try " -"again later.\n" -" " -msgstr "" -"\n" -" El monitor de salud esta fuera de aclance. Mantanga la calma e " -"intente nuevamente más tarde.\n" +" Could not reach the health monitor. Keep calm and try again later.\n" " " +msgstr "\n El monitor de salud esta fuera de aclance. Mantanga la calma e intente nuevamente más tarde.\n " #: journalmanager/choices.py:70 #: journalmanager/templates/journalmanager/journal_list.html:50 @@ -975,9 +935,7 @@ msgstr "En proceso" #: journalmanager/forms.py:25 msgid "This email is being used by another user, please try another email." -msgstr "" -"Este correo electrónico es usado por otro usuario, por favor intente con " -"otro correo electrónico." +msgstr "Este correo electrónico es usado por otro usuario, por favor intente con otro correo electrónico." #: journalmanager/forms.py:63 msgid "Select one or more collections" @@ -989,7 +947,7 @@ msgstr "Seleccionar uno o más idiomas." #: journalmanager/forms.py:126 msgid "Abstract keyword languages" -msgstr "" +msgstr "Idioma de los resúmenes y palabras-clave" #: journalmanager/forms.py:128 msgid "Select one or more sponsors" @@ -1001,7 +959,7 @@ msgstr "Seleccionar una o más categorías" #: journalmanager/forms.py:132 msgid "Study area" -msgstr "Area de Estudio" +msgstr "Árede de estudio" #: journalmanager/forms.py:134 msgid "Select one or more study area" @@ -1015,59 +973,46 @@ msgstr "Categorías de Asunto" #: journalmanager/templates/journalmanager/add_journal.html:631 msgid "" "Journal cover image extension is not allowed! Please select another file." -msgstr "" -"La extensión de la imagen de portada de la revista, no está permitida! Por " -"favor seleccione otro archivo." +msgstr "La extensión de la imagen de portada de la revista, no está permitida! Por favor seleccione otro archivo." #: journalmanager/forms.py:192 #: journalmanager/templates/journalmanager/add_journal.html:629 -msgid "Journal cover image file size is too large! Please select another file." -msgstr "" -"El tamaño del archivo de imagen de portada de la revista, es muy grande! Por " -"favor seleccione otro archivo." +msgid "" +"Journal cover image file size is too large! Please select another file." +msgstr "El tamaño del archivo de imagen de portada de la revista, es muy grande! Por favor seleccione otro archivo." #: journalmanager/forms.py:198 msgid "" -"The image is {image_size}px pixel wide. It's supposed to be {expected_size}px" -msgstr "" -"La imagen es {image_size}px de ancho. Se supone que debe ser {expected_size}" -"px" +"The image is {image_size}px pixel wide. It's supposed to be " +"{expected_size}px" +msgstr "La imagen es {image_size}px de ancho. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:204 msgid "" -"The image is {image_size}px pixel high. It's supposed to be {expected_size}px" -msgstr "" -"La imagen es {image_size}px de altura. Se supone que debe ser {expected_size}" -"px" +"The image is {image_size}px pixel high. It's supposed to be " +"{expected_size}px" +msgstr "La imagen es {image_size}px de altura. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:215 #: journalmanager/templates/journalmanager/add_journal.html:632 msgid "" "Journal logo image extension is not allowed! Please select another file." -msgstr "" -"La extensión de la imagen del logo de la revista no está permitida! Por " -"favor seleccione otro archivo." +msgstr "La extensión de la imagen del logo de la revista no está permitida! Por favor seleccione otro archivo." #: journalmanager/forms.py:218 #: journalmanager/templates/journalmanager/add_journal.html:630 msgid "Journal logo image file size is too large! Please select another file." -msgstr "" -"La extensión de la imagen del logo de la revista es muy grande! Por favor " -"seleccione otro archivo." +msgstr "La extensión de la imagen del logo de la revista es muy grande! Por favor seleccione otro archivo." #: journalmanager/forms.py:223 msgid "" "The image is {logo_size}px pixel wide. It's supposed to be {expected_size}px" -msgstr "" -"La imagen del logo tiene {logo_size}px de ancho. Se supone que debe ser " -"{expected_size}px" +msgstr "La imagen del logo tiene {logo_size}px de ancho. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:227 msgid "" "The image is {logo_size}px pixel high. It's supposed to be {expected_size}px" -msgstr "" -"La imagen del logo tiene {logo_size}px de altura. Se supone que debe ser " -"{expected_size}px" +msgstr "La imagen del logo tiene {logo_size}px de altura. Se supone que debe ser {expected_size}px" #: journalmanager/forms.py:296 #: scielomanager/templates/registration/login.html:28 @@ -1099,8 +1044,7 @@ msgstr "Licencia de Uso" #: journalmanager/forms.py:405 msgid "You must complete at least one of two fields volume or number." -msgstr "" -"Usted debe completar por lo menos uno de los dos campos del volumen o número." +msgstr "Usted debe completar por lo menos uno de los dos campos del volumen o número." #: journalmanager/forms.py:416 journalmanager/forms.py:470 #: journalmanager/forms.py:475 journalmanager/forms.py:521 @@ -1111,17 +1055,15 @@ msgstr "Número con este Año y (Volumen o Número) ya existe para esta revista" #: journalmanager/forms.py:453 journalmanager/forms.py:508 msgid "You must complete the volume filed. Number field must be empty." -msgstr "" -"Usted debe completar el campo Volumen. El campo Número debe quedar vacío." +msgstr "Usted debe completar el campo Volumen. El campo Número debe quedar vacío." #: journalmanager/forms.py:455 journalmanager/forms.py:510 msgid "You must complete the number filed. Volume field must be empty." -msgstr "" -"Usted debe completar el campo Número. El campo Volumen debe quedar vacío." +msgstr "Usted debe completar el campo Número. El campo Volumen debe quedar vacío." #: journalmanager/forms.py:549 msgid "Legacy Code" -msgstr "Código de Licencia" +msgstr "Código anterior" #: journalmanager/forms.py:854 msgid "Please fill in at least one form" @@ -1130,13 +1072,10 @@ msgstr "Por favor complete por lo menos un formulario" #: journalmanager/models.py:44 msgid "" "If not defined, will be applied the related journal's use license. The " -"SciELO default use license is BY-NC. Please visit: http://ref.scielo.org/" -"jf5ndd (5.2.11. Política de direitos autorais) for more details." -msgstr "" -"Sí no es definida, será aplicada la licencia de uso de la revista " -"relacionada. La licencia de uso por defecto de SciELO es BY-NC. Por favor " -"visite: http://ref.scielo.org/jf5ndd (5.2.11. Política de direitos autorais) " -"para más información." +"SciELO default use license is BY-NC. Please visit: " +"http://ref.scielo.org/jf5ndd (5.2.11. Política de direitos autorais) for " +"more details." +msgstr "Sí no es definida, será aplicada la licencia de uso de la revista relacionada. La licencia de uso por defecto de SciELO es BY-NC. Por favor visite: http://ref.scielo.org/jf5ndd (5.2.11. Política de direitos autorais) para más información." #: journalmanager/models.py:288 journalmanager/models.py:1520 msgid "ISO 639-1 Language Code" @@ -1226,11 +1165,11 @@ msgstr "Licencia de Uso" #: journalmanager/models.py:528 msgid "CCN Code" -msgstr "Código SECS" +msgstr "Código CCN" #: journalmanager/models.py:529 msgid "The code of the journal at the CCN database." -msgstr "" +msgstr "El código de la revista en la base de datos CCN" #: journalmanager/models.py:534 msgid "Subject Categories" @@ -1403,7 +1342,7 @@ msgstr "¿Por qué usted está cambiando el estado de publicación?" #: journalmanager/models.py:774 msgid "Reason" -msgstr "Reason" +msgstr "Razón" #: journalmanager/models.py:780 journalmanager/models.py:836 #: journalmanager/models.py:1112 journalmanager/models.py:1213 @@ -1519,8 +1458,7 @@ msgstr "Guardado." #: journalmanager/views.py:53 msgid "Saved partially. You can continue to fill in this form later." -msgstr "" -"Guardado parcialmente. Puede continuar completando el formulario después." +msgstr "Guardado parcialmente. Puede continuar completando el formulario después." #: journalmanager/views.py:55 msgid "The pended form has been deleted." @@ -1555,8 +1493,7 @@ msgstr "Esta revista ya existe, por favor búsquela en el paso anterior" #: journalmanager/views.py:988 msgid "" "Issue created successfully, however we can not create the editorial board." -msgstr "" -"Número creado con éxito, sin embargo no podemos crear el Cuerpo Editorial." +msgstr "Número creado con éxito, sin embargo no podemos crear el Cuerpo Editorial." #: journalmanager/views.py:1088 msgid "Section removed successfully" @@ -1716,11 +1653,11 @@ msgstr "PID del artículo" #: journalmanager/templates/journalmanager/add_pressrelease.html:124 msgid "Body" -msgstr "Cuerpo" +msgstr "Cuerpo de texto" #: journalmanager/templates/journalmanager/add_pressrelease.html:127 msgid "Preview as HTML" -msgstr "Vista previa" +msgstr "Vista previa en HTML" #: journalmanager/templates/journalmanager/add_section.html:95 msgid "Section Information" @@ -1794,19 +1731,19 @@ msgstr "Versión del artículo" #: journalmanager/templates/journalmanager/article_detail.html:48 #: validator/templates/validator/preview_html.html:85 msgid "HTML preview" -msgstr "Vista previa" +msgstr "Vista previa en HTML" #: journalmanager/templates/journalmanager/article_detail.html:54 msgid "Source XML" -msgstr "" +msgstr "Source XML" #: journalmanager/templates/journalmanager/article_detail.html:68 msgid "Sorry, but the HTML preview is not available for this article." -msgstr "" +msgstr "Discúlpame, pero la previa vista en HTML no está disponible para este artículo" #: journalmanager/templates/journalmanager/article_detail.html:76 msgid "This article doesn't have a XML file." -msgstr "Este artículo no tiene XML" +msgstr "Este artículo no tiene un archivo XML" #: journalmanager/templates/journalmanager/article_list.html:5 #: journalmanager/templates/journalmanager/issue_list.html:51 @@ -1882,11 +1819,9 @@ msgstr "Cambiar usuario editor" #: journalmanager/templates/journalmanager/editor.html:52 msgid "" -"Warning! No user was selected as editor of this journal. To " -"be the editor user must be in 'Editors' group" -msgstr "" -"Atención! No se ha seleccionado un usuario editor para esta " -"revista. Para ser el usuario editor debe pertenecer al grupo: 'Editors'" +"Warning! No user was selected as editor of this journal. To" +" be the editor user must be in 'Editors' group" +msgstr "Atención! No se ha seleccionado un usuario editor para esta revista. Para ser el usuario editor debe pertenecer al grupo: 'Editors'" #: journalmanager/templates/journalmanager/home_journal.html:16 msgid "Drafts" @@ -2000,9 +1935,7 @@ msgstr "Agregar revista a mi colección" msgid "" "To insert a journal, you need to check whether the journal exists. If it " "exists just add to your collection!" -msgstr "" -"Para ingresar una revista, es necesario comprobar si ya existe. Si es que ya " -"existe sólo tiene que añadirlo a su colección!" +msgstr "Para ingresar una revista, es necesario comprobar si ya existe. Si es que ya existe sólo tiene que añadirlo a su colección!" #: journalmanager/templates/journalmanager/journal_list.html:165 msgid "Search journal" @@ -2022,7 +1955,7 @@ msgstr "ISSN electrónico" #: journalmanager/templates/journalmanager/journal_list.html:214 msgid "Collections" -msgstr "Colección" +msgstr "Colecciones" #: journalmanager/templates/journalmanager/journal_list.html:226 msgid "No journal(s) found to the term: " @@ -2068,9 +2001,7 @@ msgstr "Código" msgid "" "Hey, you can not remove the sections that are being used by at least one " "issue of this journal." -msgstr "" -"Hey, no puede remover secciones que están siendo usadas por al menos un " -"número de esta revista." +msgstr "Hey, no puede remover secciones que están siendo usadas por al menos un número de esta revista." #: journalmanager/templates/journalmanager/trash_listing.html:7 msgid "Trash" @@ -2134,9 +2065,9 @@ msgid "This journal does not have a logo" msgstr "Esta revista no tiene logo" #: journalmanager/templates/journalmanager/includes/issue_cover.html:15 -msgid "This issue does not have a cover, it will use the default journal cover" -msgstr "" -"Esta revista no tiene portada, utilizará la portada de periódico por defecto" +msgid "" +"This issue does not have a cover, it will use the default journal cover" +msgstr "Esta revista no tiene portada, utilizará la portada de periódico por defecto" #: journalmanager/templates/journalmanager/includes/issue_form_generic_field_list.html:19 msgid "Add new" @@ -2195,11 +2126,8 @@ msgid "Report" msgstr "Reporte" #: scielomanager/custom_fields.py:44 -#, fuzzy msgid "Please keep file size under {maxsize}. Current file size {filesize}" -msgstr "" -"Por favor mantenga el tamaño de los archivos menores a %(maxsize)s. Tamaño " -"actual del archivo %(filesize)s" +msgstr "Por favor mantenga el tamaño del archivo menor a {maxsize}. Tamaño actual del archivo {filesize}" #: scielomanager/custom_fields.py:50 msgid "File type not supported." @@ -2281,7 +2209,7 @@ msgstr "SciELO Style Checker" #: scielomanager/templates/footer.html:38 msgid "HTML Previewer" -msgstr "Vista previa" +msgstr "Vista previa en HTML" #: scielomanager/templates/include_press_release/ahead.html:5 #: scielomanager/templates/include_press_release/issue.html:5 @@ -2307,9 +2235,7 @@ msgstr "Por favor haga click en el link a continuación para activar su cuenta." msgid "" "\n" " This key will expire in %(expiration_days)s days.\n" -msgstr "" -"\n" -" Esta clave expirará en %(expiration_days)s dias.\n" +msgstr "\n Esta clave expirará en %(expiration_days)s dias.\n" #: scielomanager/templates/registration/login.html:9 msgid "We are under maintenance!" @@ -2340,9 +2266,7 @@ msgstr "¿Olvidó tu contraseña?" msgid "" "Your password has been reseted! You may now login in using your new " "credentials." -msgstr "" -"¡Tu contraseña ha sido restablecida! Ahora puedes iniciar sesión con tu " -"nueva información." +msgstr "¡Tu contraseña ha sido restablecida! Ahora puedes iniciar sesión con tu nueva información." #: scielomanager/templates/registration/password_reset_complete.html:9 msgid "login" @@ -2364,10 +2288,7 @@ msgstr "Este enlace ya fue utilizado para restablecer su contraseña." msgid "" "We have sent you an email with a link to reset your password. Please check " "your email and click the link to continue." -msgstr "" -"Le hemos enviado un correo electrónico con un enlace para restablecer tu " -"contraseña. Por favor, consulte su correo electrónico y haga click en el " -"vínculo para continuar." +msgstr "Le hemos enviado un correo electrónico con un enlace para restablecer tu contraseña. Por favor, consulte su correo electrónico y haga click en el vínculo para continuar." #: scielomanager/templates/registration/password_reset_done.html:9 msgid "Login" @@ -2383,30 +2304,15 @@ msgid "" "requested that your password be reset on %(site_name)s. If you do not\n" "wish to reset your password, please ignore this message.\n" "\n" -"To reset your password, please click the following link, or copy and paste " -"it\n" +"To reset your password, please click the following link, or copy and paste it\n" "into your web browser:\n" -msgstr "" -"\n" -"Saludos %(user)s,\n" -"\n" -"Has recibido este correo porque tú (o alguien más pretendiendo ser tú)\n" -"ha solicitado el restablecimiento de su contraseña en %(site_name)s. Si tú " -"no\n" -"deseas restablecer tu contraseña, por favor ignora este mensaje.\n" -"\n" -"Para restablecer tu contraseña, por favor da clic en el siguiente enlace, o " -"cópialo y pégalo\n" -"en tu navegador de internet:\n" +msgstr "\nSaludos %(user)s,\n\nHas recibido este correo porque tú (o alguien más pretendiendo ser tú)\nha solicitado el restablecimiento de su contraseña en %(site_name)s. Si tú no\ndeseas restablecer tu contraseña, por favor ignora este mensaje.\n\nPara restablecer tu contraseña, por favor da clic en el siguiente enlace, o cópialo y pégalo\nen tu navegador de internet:\n" #: scielomanager/templates/registration/password_reset_form.html:9 msgid "" "Enter your e-mail in the form below and we will send your username and " "instructions to create a new password." -msgstr "" -"Ingrese su dirección de correo electrónico en el siguiente formulario y " -"nosotros le enviaremos su usuario y las instrucciones para crear una nueva " -"contraseña." +msgstr "Ingrese su dirección de correo electrónico en el siguiente formulario y nosotros le enviaremos su usuario y las instrucciones para crear una nueva contraseña." #: scielomanager/templates/registration/password_reset_form.html:11 msgid "Reset Password" @@ -2424,9 +2330,7 @@ msgstr "Un correo electrónico de confirmación está en camino" msgid "" "Please click the activation link included in the e-mail to confirm you " "registration." -msgstr "" -"Por favor, haga click en el enlace de activación incluido en el correo " -"electrónico para confirmar la inscripción." +msgstr "Por favor, haga click en el enlace de activación incluido en el correo electrónico para confirmar la inscripción." #: scielomanager/templates/registration/registration_form.html:6 #: scielomanager/templates/registration/registration_form.html:19 @@ -2439,8 +2343,7 @@ msgstr "Por favor, corrija los siguientes errores." #: scielomanager/templates/registration/registration_form.html:12 msgid "You will receive an email with a link to activate your account." -msgstr "" -"Usted recibirá un correo electrónico con un enlace para activar su cuenta." +msgstr "Usted recibirá un correo electrónico con un enlace para activar su cuenta." #: validator/forms.py:10 #: validator/templates/validator/includes/xml_annotated.html:15 @@ -2450,33 +2353,29 @@ msgstr "Archivo" #: validator/forms.py:16 #: validator/templates/validator/includes/xml_upload_form_validation.html:25 msgid "This type of file is not allowed! Please select another file." -msgstr "" -"Este tipo de archivo no está permitido! Por favor seleccione otro archivo." +msgstr "Este tipo de archivo no está permitido! Por favor seleccione otro archivo." #: validator/forms.py:19 msgid "The file's size is too large! Please select a smaller file." -msgstr "" -"El tamaño de archivo es muy grande! Por favor seleccione otro archivo. " +msgstr "El tamaño de archivo es muy grande! Por favor seleccione otro archivo. " #: validator/templates/validator/preview_html.html:6 msgid "Packtools - SciELO HTML Previewer" -msgstr "" +msgstr "Oacktools - Vista previa en HTML" #: validator/templates/validator/preview_html.html:14 msgid "SciELO HTML Previewer" -msgstr "" +msgstr "SciELO - Vista previa en HTML" #: validator/templates/validator/preview_html.html:15 msgid "Use this tool to preview your XML file as an HTML" -msgstr "" +msgstr "Use esta herramienta para ver su archivo XML como un HTML" #: validator/templates/validator/preview_html.html:16 msgid "" "Browse to your local XML file and click 'Preview'. The results will be " "displayed below." -msgstr "" -"Busque su archivo XML localmente y haga clic en \"Validar\". Los resultados " -"aparecerán a continuación." +msgstr "Busque su archivo XML localmente y haga clic en \"Vista Previa\". Los resultados aparecerán a continuación." #: validator/templates/validator/preview_html.html:24 #: validator/templates/validator/stylechecker.html:28 @@ -2506,22 +2405,14 @@ msgstr "Vista previa" #: validator/templates/validator/stylechecker.html:68 msgid "" "\n" -" If you have any problems with the tool or with the SPS Tagging " -"Guidelines, please contact:\n" -" scielo-" -"xml@googlegroups.com.\n" -" " -msgstr "" -"\n" -" Si tiene algún problema con esta herramienta o con el SPS " -"Tagging Guidelines, por favor entre en contacto con:\n" -" scielo-" -"xml@googlegroups.com.\n" +" If you have any problems with the tool or with the SPS Tagging Guidelines, please contact:\n" +" scielo-xml@googlegroups.com.\n" " " +msgstr "\n Si tiene algún problema con esta herramienta o con el SPS Tagging Guidelines, por favor entre en contacto con:\n scielo-xml@googlegroups.com.\n " #: validator/templates/validator/preview_html.html:99 msgid "No HTML generated, is the XML file valid?" -msgstr "" +msgstr "El HTML no fue generado, ¿el archivo XML es válido?" #: validator/templates/validator/stylechecker.html:6 msgid "Packtools - Style Checker" @@ -2534,34 +2425,21 @@ msgstr "SciELO Style Checker" #: validator/templates/validator/stylechecker.html:12 msgid "" "\n" -" Use this tool to confirm whether an XML file conforms to SciELO Style " -"as defined in the SciELO Publishing Schema Tagging Guidelines.\n" -" " -msgstr "" -"\n" -" Use esta herramienta para confirmar sí un archivo XML esta conforme al " -"SciELO Style cuyas definiciones son especificadas por el SciELO Publishing " -"Schema Tagging Guidelines.\n" +" Use this tool to confirm whether an XML file conforms to SciELO Style as defined in the SciELO Publishing Schema Tagging Guidelines.\n" " " +msgstr "\n Use esta herramienta para confirmar sí un archivo XML esta conforme al SciELO Style cuyas definiciones son especificadas por el SciELO Publishing Schema Tagging Guidelines.\n " #: validator/templates/validator/stylechecker.html:17 msgid "" "\n" -" Browse to your local XML file and click \"Validate\". The results will " -"be displayed below.\n" -" " -msgstr "" -"\n" -" Busque su archivo XML localmente y haga clic en \"Validar\". Los " -"resultados aparecerán a continuación.\n" +" Browse to your local XML file and click \"Validate\". The results will be displayed below.\n" " " +msgstr "\n Busque su archivo XML localmente y haga clic en \"Validar\". Los resultados aparecerán a continuación.\n " #: validator/templates/validator/stylechecker.html:55 msgid "" "\n" -" Also validate against SciELO Brazil's specific rules. Read more.\n" +" Also validate against SciELO Brazil's specific rules. Read more.\n" " " msgstr "" @@ -2602,15 +2480,11 @@ msgstr "Atención!" msgid "" "This XML document uses a version of SciELO PS that soon will no longer be " "supported. Please consider upgrading to a newer version as soon as possible." -msgstr "" -"Este documento XML usa una versión de SciELO PS que pronto dejará de ser " -"soportada. Por favor considere actualizarlo a una versión mas nueva tan " -"pronto como sea posible." +msgstr "Este documento XML usa una versión de SciELO PS que pronto dejará de ser soportada. Por favor considere actualizarlo a una versión mas nueva tan pronto como sea posible." #: validator/templates/validator/includes/xml_annotated.html:50 msgid "If you want to know more about the support policy, please refer to" -msgstr "" -"Si usted desea conocer más sobre la política de soporte, por favor visite" +msgstr "Si usted desea conocer más sobre la política de soporte, por favor visite" #: validator/templates/validator/includes/xml_annotated.html:52 msgid "SciELO PS official documentation" @@ -2714,183 +2588,16 @@ msgstr "en las lineas anteriores" #: validator/templates/validator/includes/xml_upload_form_validation.html:30 msgid "The file size is too large! Please select a smaller file." -msgstr "" -"El tamaño de archivo es muy grande! Por favor seleccione otro archivo. " +msgstr "El tamaño de archivo es muy grande! Por favor seleccione otro archivo." #~ msgid "Lanaguages" -#~ msgstr "Idiomas" - -#~ msgid "Corpo editorial" -#~ msgstr "Cuerpo editorial" - -#~ msgid "User can't do this action: %s" -#~ msgstr "El usuario no puede realizar esta acción: %s" - -#~ msgid "User can't ACCEPT checkins, because doesn't have enough permissions" -#~ msgstr "" -#~ "El usuario no puede ACEPTAR checkins, porque no cuenta con permisos " -#~ "suficientes" - -#~ msgid "User can't REJECT checkins, because doesn't have enough permissions" -#~ msgstr "" -#~ "El usuario no puede RECHAZAR checkins, porque no cuenta con permisos " -#~ "suficientes" - -#~ msgid "" -#~ "User can't REVIEW (Level 1) checkins, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede REVISAR checkins (Nivel 1), porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't REVIEW (Level 2) checkins, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede REVISAR checkins (Nivel 2), porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't SEND checkins TO REVIEW, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede ENVIAR checkins PARA REVISIÓN, porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't SEND checkins TO PENDING, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede ENVIAR checkins PARA PENDIENTE, porque no cuenta con " -#~ "permisos suficientes" - -#~ msgid "" -#~ "User can't SEND checkins TO CHECKOUT, because doesn't have enough " -#~ "permissions" -#~ msgstr "" -#~ "El usuario no puede ENVIAR checkins PARA CHECKOUT, porque no cuenta con " -#~ "permisos suficientes" +#~ msgstr "Languages" #~ msgid "National Code" -#~ msgstr "Código Nacional" - -#~ msgid "XML content" -#~ msgstr "Contenido del artículo" - -#~ msgid "Coleções" -#~ msgstr "Colecciones" - -#~ msgid "Titulos" -#~ msgstr "Títulos" - -#~ msgid "Packtools StyleChecker" -#~ msgstr "Packtools StyleChecker" - -#~ msgid "usage: " -#~ msgstr "uso:" - -#~ msgid ".__call__() not defined" -#~ msgstr ".__call__() no definido" - -#~ msgid "unknown parser {parser_name} (choices: {choices})" -#~ msgstr "parser desconocido {parser_name} (opciones: {choices})" - -#~ msgid "argument \"-\" with mode %r" -#~ msgstr "argumento \"-\" con modo %r" - -#~ msgid "cannot merge actions - two groups are named %r" -#~ msgstr "no es posible mezclar las acciones - dos grupos son nombrados %r" - -#~ msgid "'required' is an invalid argument for positionals" -#~ msgstr "'required' es un argumento no válido para posicionales" - -#~ msgid "" -#~ "invalid option string {option_string}: must start with a character " -#~ "{prefix_chars}" -#~ msgstr "" -#~ "opción de cadena invalida {option_string}: debe comenzar con el caracter " -#~ "{prefix_chars}" - -#~ msgid "dest= is required for options like %r" -#~ msgstr "dest= es requerido para opciones como %r" - -#~ msgid "invalid conflict_resolution value: %r" -#~ msgstr "valor conflict_resolution inválido: %r" - -#~ msgid "conflicting option string(s): %s" -#~ msgstr "opción de cadena(s): %s conflictantes" - -#~ msgid "mutually exclusive arguments must be optional" -#~ msgstr "argumentos mutuamente exclusivos debe ser opcional" - -#~ msgid "positional arguments" -#~ msgstr "argumentos posicionales" +#~ msgstr "National Code" #~ msgid "optional arguments" -#~ msgstr "argumentos opcionales" - -#~ msgid "show this help message and exit" -#~ msgstr "mostrar este mensaje de ayuda y salir" - -#~ msgid "show program's version number and exit" -#~ msgstr "mostrar número de la versión del programa y salir" - -#~ msgid "cannot have multiple subparser arguments" -#~ msgstr "no es posible tener múltiples argumentos de subparser" - -#~ msgid "unrecognized arguments: %s" -#~ msgstr "argumentos no reconocidos: %s" - -#~ msgid "not allowed with argument %s" -#~ msgstr "no permitido con argumentos %s" - -#~ msgid "ignored explicit argument %r" -#~ msgstr "argumentos explícitos ignorado: %r" - -#~ msgid "too few arguments" -#~ msgstr "muy pocos argumentos" - -#~ msgid "argument %s is required" -#~ msgstr "argumento %s es obligatorio" - -#~ msgid "one of the arguments %s is required" -#~ msgstr "uno de estos argumentos %s son obligatorios" - -#~ msgid "expected one argument" -#~ msgstr "un argumento esperado" - -#~ msgid "expected at most one argument" -#~ msgstr "a lo sumo un argumento esperado" - -#~ msgid "expected at least one argument" -#~ msgstr "al menos un argumento esperado" - -#~ msgid "expected %s argument(s)" -#~ msgstr "esperados argumento(s): %s" - -#~ msgid "ambiguous option: {arg_string} could match {options}" -#~ msgstr "opción ambigua: {arg_string} podría coincidir {options}" - -#~ msgid "unexpected option string: %s" -#~ msgstr "opción de cadena inesperada: %s" - -#~ msgid "%r is not callable" -#~ msgstr "%r no se puede llamar" - -#~ msgid "invalid {name} value: {arg_string}" -#~ msgstr "valor {name} inválid: {arg_string}" - -#~ msgid "invalid choice: {value} (choose from {choices})" -#~ msgstr "opción inválida: {value} (opciones {choices})" - -#~ msgid "{prog}: error: message\n" -#~ msgstr "{prog}: error: mensaje\n" - -#~ msgid "The file submitted is NOT XML" -#~ msgstr "Este archivo NO ES XML" - -#~ msgid "XML file excedes max upload size" -#~ msgstr "El archivo XML supera el tamaño máximo de subida permitido" +#~ msgstr "Total of Documents" #~ msgid "logout" #~ msgstr "logout" @@ -2986,11 +2693,9 @@ msgstr "" #~ msgstr "Your username and password did not match. Please try again." #~ msgid "" -#~ "Your account is not active. Please contact the SciELO or verify your e-" -#~ "mail" +#~ "Your account is not active. Please contact the SciELO or verify your e-mail" #~ msgstr "" -#~ "Your account is not active. Please contact the SciELO or verify your e-" -#~ "mail" +#~ "Your account is not active. Please contact the SciELO or verify your e-mail" #~ msgid "Please login on the system to see this page" #~ msgstr "Please login on the system to see this page" From acac06a602f666793c74abebee52c6b2578296b8 Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Thu, 16 Feb 2017 15:31:28 -0200 Subject: [PATCH 09/13] Update packtools from 1.3.2 to 1.3.3 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b3065e62..2451e78e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,7 @@ yuicompressor jsonfield django-tastypie==0.9.16 django-htmlmin==0.7.0 -packtools==1.3.2 +packtools==1.3.3 Celery django-celery django-kombu From 58fe5e8a9ef9baf27d950b8df8198215efa7ee02 Mon Sep 17 00:00:00 2001 From: Fabio Batalha Date: Thu, 16 Feb 2017 15:50:20 -0200 Subject: [PATCH 10/13] Articlemeta update (#1393) * Ajustes em porta do articlemeta * Ajusta porta do articlemeta --- scielomanager/tools/import_data/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scielomanager/tools/import_data/utils.py b/scielomanager/tools/import_data/utils.py index aefc2411..bb21c395 100644 --- a/scielomanager/tools/import_data/utils.py +++ b/scielomanager/tools/import_data/utils.py @@ -15,13 +15,13 @@ def articlemeta_server(): try: - server = 'articlemeta.scielo.org:11620' + server = 'articlemeta.scielo.org:11621' host = server[0] port = int(server[1]) except: logger.warning('Error defining Article Meta thrift server, assuming default server articlemeta.scielo.org:11620') host = 'articlemeta.scielo.org' - port = 11620 + port = 11621 return clients.ArticleMeta(host, port) From 8df33f324e0192b28f4d9eed4447c2ad19b24e2d Mon Sep 17 00:00:00 2001 From: Gustavo Fonseca Date: Mon, 20 Feb 2017 13:56:37 -0300 Subject: [PATCH 11/13] =?UTF-8?q?=C3=9Altima=20vers=C3=A3o=20do=20Celery?= =?UTF-8?q?=20que=20funciona=20com=20Django=201.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- requirements.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 2451e78e..f34f64e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,9 +14,7 @@ jsonfield django-tastypie==0.9.16 django-htmlmin==0.7.0 packtools==1.3.3 -Celery -django-celery -django-kombu +celery==3.1.25 defusedxml==0.4.1 cython thriftpy From 97022f31375961abbfb4ba617632c34c4d73fc9c Mon Sep 17 00:00:00 2001 From: Gustavo Fonseca Date: Mon, 20 Feb 2017 14:08:25 -0300 Subject: [PATCH 12/13] Ops, reinserindo o pacote django-celery --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index f34f64e3..02851db7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,6 +15,7 @@ django-tastypie==0.9.16 django-htmlmin==0.7.0 packtools==1.3.3 celery==3.1.25 +django-celery==3.1.16 defusedxml==0.4.1 cython thriftpy From 1f4d9d6734c76dbe5fa75674f47ba35a22ab78c2 Mon Sep 17 00:00:00 2001 From: Gustavo Fonseca Date: Fri, 17 Mar 2017 15:19:11 -0300 Subject: [PATCH 13/13] =?UTF-8?q?Exclui=20caractere=20"ponto"=20na=20repre?= =?UTF-8?q?senta=C3=A7=C3=A3o=20textual=20de=20n=C3=BAmeros=20especiais.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1302 ATENÇÃO: Esse patch inclui migração de dados. --- .../migrations/0033_update_issue_label.py | 401 ++++++++++++++++++ scielomanager/journalmanager/models.py | 3 +- .../journalmanager/tests/tests_models.py | 2 +- 3 files changed, 404 insertions(+), 2 deletions(-) create mode 100644 scielomanager/journalmanager/migrations/0033_update_issue_label.py diff --git a/scielomanager/journalmanager/migrations/0033_update_issue_label.py b/scielomanager/journalmanager/migrations/0033_update_issue_label.py new file mode 100644 index 00000000..a4425975 --- /dev/null +++ b/scielomanager/journalmanager/migrations/0033_update_issue_label.py @@ -0,0 +1,401 @@ +# -*- coding: utf-8 -*- +from south.utils import datetime_utils as datetime +from south.db import db +from south.v2 import DataMigration +from django.db import models + +class Migration(DataMigration): + + def forwards(self, orm): + "Write your forwards methods here." + # Note: Don't use "from appname.models import ModelName". + # Use orm.ModelName to refer to models in this application, + # and orm['appname.ModelName'] for models in other applications. + for spe_issue in orm.Issue.objects.filter(type='special'): + spe_issue.label = unicode(spe_issue) + spe_issue.save() + + def backwards(self, orm): + "Write your backwards methods here." + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'journalmanager.aheadpressrelease': { + 'Meta': {'object_name': 'AheadPressRelease', '_ormbases': ['journalmanager.PressRelease']}, + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'press_releases'", 'to': "orm['journalmanager.Journal']"}), + 'pressrelease_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.PressRelease']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.article': { + 'Meta': {'object_name': 'Article'}, + 'aid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}), + 'article_type': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}), + 'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now_add': 'True', 'blank': 'True'}), + 'doi': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '2048', 'db_index': 'True'}), + 'domain_key': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '2048', 'db_index': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_aop': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_visible': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'issn_epub': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'issn_ppub': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'issue': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'articles'", 'null': 'True', 'to': "orm['journalmanager.Issue']"}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'articles'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'journal_title': ('django.db.models.fields.CharField', [], {'max_length': '512', 'db_index': 'True'}), + 'related_articles': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['journalmanager.Article']", 'null': 'True', 'through': "orm['journalmanager.ArticlesLinkage']", 'blank': 'True'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}), + 'xml': ('scielomanager.custom_fields.XMLSPSField', [], {}), + 'xml_version': ('django.db.models.fields.CharField', [], {'max_length': '9'}) + }, + 'journalmanager.articleasset': { + 'Meta': {'object_name': 'ArticleAsset'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'assets'", 'to': "orm['journalmanager.Article']"}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '1024'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'owner': ('django.db.models.fields.CharField', [], {'default': "u''", 'max_length': '1024'}), + 'preferred_alt_file': ('django.db.models.fields.files.FileField', [], {'default': "u''", 'max_length': '1024'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.TextField', [], {'default': "u''"}) + }, + 'journalmanager.articlecontrolattributes': { + 'Meta': {'object_name': 'ArticleControlAttributes'}, + 'article': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'control_attributes'", 'unique': 'True', 'to': "orm['journalmanager.Article']"}), + 'articles_linkage_is_pending': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'es_is_dirty': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'es_updated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'journalmanager.articlehtmlrendition': { + 'Meta': {'unique_together': "(('article', 'lang'),)", 'object_name': 'ArticleHTMLRendition'}, + 'article': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'htmls'", 'to': "orm['journalmanager.Article']"}), + 'build_version': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '1024'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lang': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'journalmanager.articleslinkage': { + 'Meta': {'object_name': 'ArticlesLinkage'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'link_to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'referrers'", 'to': "orm['journalmanager.Article']"}), + 'link_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'referrer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'links_to'", 'to': "orm['journalmanager.Article']"}) + }, + 'journalmanager.collection': { + 'Meta': {'ordering': "['name']", 'object_name': 'Collection'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'collection': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'user_collection'", 'to': "orm['auth.User']", 'through': "orm['journalmanager.UserCollections']", 'blank': 'True', 'symmetrical': 'False', 'null': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}), + 'name_slug': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'unique': 'True', 'null': 'True', 'blank': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.institution': { + 'Meta': {'ordering': "['name']", 'object_name': 'Institution'}, + 'acronym': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '16', 'blank': 'True'}), + 'address': ('django.db.models.fields.TextField', [], {}), + 'address_complement': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}), + 'address_number': ('django.db.models.fields.CharField', [], {'max_length': '8'}), + 'cel': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'city': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'complement': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'country': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'fax': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'phone': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'state': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'zip_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.issue': { + 'Meta': {'ordering': "('created', 'id')", 'object_name': 'Issue'}, + 'cover': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'ctrl_vocabulary': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'editorial_standard': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_marked_up': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'label': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '64', 'null': 'True', 'blank': 'True'}), + 'number': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'blank': 'True'}), + 'publication_end_month': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'publication_start_month': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'publication_year': ('django.db.models.fields.IntegerField', [], {}), + 'section': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Section']", 'symmetrical': 'False', 'blank': 'True'}), + 'spe_text': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'suppl_text': ('django.db.models.fields.CharField', [], {'max_length': '15', 'null': 'True', 'blank': 'True'}), + 'total_documents': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'type': ('django.db.models.fields.CharField', [], {'default': "'regular'", 'max_length': '15'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.UseLicense']", 'null': 'True'}), + 'volume': ('django.db.models.fields.CharField', [], {'max_length': '16', 'blank': 'True'}) + }, + 'journalmanager.issuetitle': { + 'Meta': {'object_name': 'IssueTitle'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'issue': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Issue']"}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.journal': { + 'Meta': {'ordering': "('title', 'id')", 'object_name': 'Journal'}, + 'abstract_keyword_languages': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'abstract_keyword_languages'", 'symmetrical': 'False', 'to': "orm['journalmanager.Language']"}), + 'acronym': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'ccn_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'through': "orm['journalmanager.Membership']", 'symmetrical': 'False'}), + 'copyrighter': ('django.db.models.fields.CharField', [], {'max_length': '254'}), + 'cover': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'creator': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'enjoy_creator'", 'to': "orm['auth.User']"}), + 'ctrl_vocabulary': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'current_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'blank': 'True'}), + 'editor': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'editor_journal'", 'null': 'True', 'to': "orm['auth.User']"}), + 'editor_address': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_address_city': ('django.db.models.fields.CharField', [], {'max_length': '256'}), + 'editor_address_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'editor_address_state': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'editor_address_zip': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'editor_email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), + 'editor_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'editor_phone1': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'editor_phone2': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True', 'blank': 'True'}), + 'editorial_standard': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'eletronic_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'final_num': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'final_vol': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'final_year': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '4', 'blank': 'True'}), + 'frequency': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'index_coverage': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'init_num': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'init_vol': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '16', 'blank': 'True'}), + 'init_year': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'is_indexed_aehci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_scie': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_indexed_ssci': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'languages': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Language']", 'symmetrical': 'False'}), + 'logo': ('scielomanager.custom_fields.ContentTypeRestrictedFileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'medline_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'medline_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'blank': 'True'}), + 'notes': ('django.db.models.fields.TextField', [], {'default': "''", 'max_length': '254', 'blank': 'True'}), + 'other_previous_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}), + 'previous_ahead_documents': ('django.db.models.fields.IntegerField', [], {'default': '0', 'max_length': '3', 'blank': 'True'}), + 'previous_title': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'prev_title'", 'null': 'True', 'to': "orm['journalmanager.Journal']"}), + 'print_issn': ('django.db.models.fields.CharField', [], {'max_length': '9', 'db_index': 'True'}), + 'pub_level': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publication_city': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'publisher_country': ('scielo_extensions.modelfields.CountryField', [], {'max_length': '2'}), + 'publisher_name': ('django.db.models.fields.CharField', [], {'max_length': '512'}), + 'publisher_state': ('django.db.models.fields.CharField', [], {'max_length': '64'}), + 'scielo_issn': ('django.db.models.fields.CharField', [], {'max_length': '16'}), + 'secs_code': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}), + 'short_title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'db_index': 'True'}), + 'sponsor': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'journal_sponsor'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['journalmanager.Sponsor']"}), + 'study_areas': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals_migration_tmp'", 'null': 'True', 'to': "orm['journalmanager.StudyArea']"}), + 'subject_categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'journals'", 'null': 'True', 'to': "orm['journalmanager.SubjectCategory']"}), + 'subject_descriptors': ('django.db.models.fields.CharField', [], {'max_length': '1024'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'title_iso': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}), + 'twitter_user': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'url_journal': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'url_online_submission': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}), + 'use_license': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.UseLicense']"}) + }, + 'journalmanager.journalmission': { + 'Meta': {'object_name': 'JournalMission'}, + 'description': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'missions'", 'to': "orm['journalmanager.Journal']"}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']", 'null': 'True'}) + }, + 'journalmanager.journaltimeline': { + 'Meta': {'object_name': 'JournalTimeline'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'statuses'", 'to': "orm['journalmanager.Journal']"}), + 'reason': ('django.db.models.fields.TextField', [], {'default': "''"}), + 'since': ('django.db.models.fields.DateTimeField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '16'}) + }, + 'journalmanager.journaltitle': { + 'Meta': {'object_name': 'JournalTitle'}, + 'category': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'other_titles'", 'to': "orm['journalmanager.Journal']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'journalmanager.language': { + 'Meta': {'ordering': "['name']", 'object_name': 'Language'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iso_code': ('django.db.models.fields.CharField', [], {'max_length': '2'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}) + }, + 'journalmanager.membership': { + 'Meta': {'unique_together': "(('journal', 'collection'),)", 'object_name': 'Membership'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'reason': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}), + 'since': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'default': "'inprogress'", 'max_length': '16'}) + }, + 'journalmanager.pendedform': { + 'Meta': {'object_name': 'PendedForm'}, + 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}), + 'form_hash': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pending_forms'", 'to': "orm['auth.User']"}), + 'view_name': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'journalmanager.pendedvalue': { + 'Meta': {'object_name': 'PendedValue'}, + 'form': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'data'", 'to': "orm['journalmanager.PendedForm']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'value': ('django.db.models.fields.TextField', [], {}) + }, + 'journalmanager.pressrelease': { + 'Meta': {'object_name': 'PressRelease'}, + 'doi': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'journalmanager.pressreleasearticle': { + 'Meta': {'object_name': 'PressReleaseArticle'}, + 'article_pid': ('django.db.models.fields.CharField', [], {'max_length': '32', 'db_index': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'press_release': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'articles'", 'to': "orm['journalmanager.PressRelease']"}) + }, + 'journalmanager.pressreleasetranslation': { + 'Meta': {'object_name': 'PressReleaseTranslation'}, + 'content': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']"}), + 'press_release': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['journalmanager.PressRelease']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'journalmanager.regularpressrelease': { + 'Meta': {'object_name': 'RegularPressRelease', '_ormbases': ['journalmanager.PressRelease']}, + 'issue': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'press_releases'", 'to': "orm['journalmanager.Issue']"}), + 'pressrelease_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.PressRelease']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.section': { + 'Meta': {'ordering': "('id',)", 'object_name': 'Section'}, + 'code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '21', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_trashed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}), + 'journal': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Journal']"}), + 'legacy_code': ('django.db.models.fields.CharField', [], {'max_length': '16', 'null': 'True', 'blank': 'True'}), + 'updated': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}) + }, + 'journalmanager.sectiontitle': { + 'Meta': {'ordering': "['title']", 'object_name': 'SectionTitle'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Language']"}), + 'section': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'titles'", 'to': "orm['journalmanager.Section']"}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.sponsor': { + 'Meta': {'ordering': "['name']", 'object_name': 'Sponsor', '_ormbases': ['journalmanager.Institution']}, + 'collections': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['journalmanager.Collection']", 'symmetrical': 'False'}), + 'institution_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['journalmanager.Institution']", 'unique': 'True', 'primary_key': 'True'}) + }, + 'journalmanager.studyarea': { + 'Meta': {'object_name': 'StudyArea'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'study_area': ('django.db.models.fields.CharField', [], {'max_length': '256'}) + }, + 'journalmanager.subjectcategory': { + 'Meta': {'object_name': 'SubjectCategory'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'term': ('django.db.models.fields.CharField', [], {'max_length': '256', 'db_index': 'True'}) + }, + 'journalmanager.translateddata': { + 'Meta': {'object_name': 'TranslatedData'}, + 'field': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '32'}), + 'translation': ('django.db.models.fields.CharField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.uselicense': { + 'Meta': {'ordering': "['license_code']", 'object_name': 'UseLicense'}, + 'disclaimer': ('django.db.models.fields.TextField', [], {'max_length': '512', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'license_code': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'}), + 'reference_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + 'journalmanager.usercollections': { + 'Meta': {'unique_together': "(('user', 'collection'),)", 'object_name': 'UserCollections'}, + 'collection': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['journalmanager.Collection']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_default': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_manager': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'journalmanager.userprofile': { + 'Meta': {'object_name': 'UserProfile'}, + 'email_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'tz': ('django.db.models.fields.CharField', [], {'default': "'America/Sao_Paulo'", 'max_length': '150'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) + } + } + + complete_apps = ['journalmanager'] + symmetrical = True diff --git a/scielomanager/journalmanager/models.py b/scielomanager/journalmanager/models.py index 514ba07a..44792312 100644 --- a/scielomanager/journalmanager/models.py +++ b/scielomanager/journalmanager/models.py @@ -997,7 +997,8 @@ def identification(self): values.append('suppl.%s' % self.suppl_text) if self.type == 'special': - values.append('spe.%s' % self.spe_text) + _spe_text = 'spe' + self.spe_text if self.spe_text else 'spe' + values.append(_spe_text) return ' '.join([val for val in values if val]).strip().replace('ahead', 'ahead of print') diff --git a/scielomanager/journalmanager/tests/tests_models.py b/scielomanager/journalmanager/tests/tests_models.py index d4c2a63c..513b6fb0 100644 --- a/scielomanager/journalmanager/tests/tests_models.py +++ b/scielomanager/journalmanager/tests/tests_models.py @@ -158,7 +158,7 @@ def test_identification_for_ahead(self): def test_identification_for_special(self): issue = IssueFactory.create(number='1', spe_text='2', type='special') - expected = u'1 spe.2' + expected = u'1 spe2' self.assertEqual(issue.identification, expected)