def test_image_upload(self): self.client.login(username='******', password='******') content = b"a" * 1024 image = SimpleUploadedFile("image.png", content, content_type="image/png") response = self.client.post('/{}/{}/{}/manage/images/'.format(self.campaign.page.page_slug, self.campaign.pk, self.campaign.campaign_slug), {'image': image}) self.assertEqual(response.status_code, 200) images = models.CampaignImage.objects.filter(campaign=self.campaign) self.assertEqual(len(images), 1) image = images[0] response = self.client.get('/{}/{}/{}/'.format(self.campaign.page.page_slug, self.campaign.pk, self.campaign.campaign_slug)) self.assertContains(response, image.image.url, status_code=200) image.delete() images = models.CampaignImage.objects.filter(campaign=self.campaign) self.assertEqual(len(images), 0)
def test_image_upload(self): self.client.login(username='******', password='******') content = b"a" * 1024 image = SimpleUploadedFile("image.png", content, content_type="image/png") response = self.client.post('/profile/images/', {'image': image}) self.assertEqual(response.status_code, 200) images = models.UserImage.objects.filter(user=self.user.userprofile) self.assertEqual(len(images), 1) image = images[0] response = self.client.get('/profile/images/') self.assertContains(response, image.image.url, status_code=200) image.delete() images = models.UserImage.objects.filter(user=self.user.userprofile) self.assertEqual(len(images), 0)
class CVN(models.Model): cvn_file = models.FileField(_(u'PDF'), upload_to=get_cvn_path) xml_file = models.FileField(_(u'XML'), upload_to=get_cvn_path) fecha = models.DateField(_("Date of CVN")) created_at = models.DateTimeField(_("Created"), auto_now_add=True) updated_at = models.DateTimeField(_("Updated"), auto_now=True) uploaded_at = models.DateTimeField(_("Uploaded PDF"), default=datetime.datetime(2014, 10, 18)) user_profile = models.OneToOneField(UserProfile) status = models.IntegerField(_("Status"), choices=st_cvn.CVN_STATUS) is_inserted = models.BooleanField(_("Inserted"), default=False) def __init__(self, *args, **kwargs): user = kwargs.pop('user', None) pdf_path = kwargs.pop('pdf_path', None) pdf = kwargs.pop('pdf', None) super(CVN, self).__init__(*args, **kwargs) if user: self.user_profile = user.profile if pdf_path: pdf_file = open(pdf_path) pdf = pdf_file.read() if pdf and user: self.update_from_pdf(pdf, commit=False) def update_from_pdf(self, pdf, commit=True): name = 'CVN-' + self.user_profile.documento (xml, error) = fecyt.pdf2xml(pdf, name) if not error: CVN.remove_cvn_by_userprofile(self.user_profile) self.cvn_file = SimpleUploadedFile(name, pdf, content_type="application/pdf") self.initialize_fields(xml, commit) def update_from_xml(self, xml, commit=True): pdf = fecyt.xml2pdf(xml) if pdf: self.update_from_pdf(pdf, commit) def initialize_fields(self, xml, commit=True): # Warning: The filename is ignored by your extension is needed self.xml_file.save(u'fake-filename.xml', ContentFile(xml), save=False) tree_xml = etree.XML(xml) self.fecha = parse_date(tree_xml.find('Version/VersionID/Date')) self.is_inserted = False self.uploaded_at = datetime.datetime.now() self.update_status(commit) self.xml_file.close() if commit: self.save() def update_status(self, commit=True): status = self.status if self.fecha <= config.EXPIRY_DATE: self.status = st_cvn.CVNStatus.EXPIRED elif not self._is_valid_identity(): self.status = st_cvn.CVNStatus.INVALID_IDENTITY else: self.status = st_cvn.CVNStatus.UPDATED if self.status != status and commit: self.save() def _is_valid_identity(self): try: if self.xml_file.closed: self.xml_file.open() except IOError: return False xml_tree = etree.parse(self.xml_file) self.xml_file.seek(0) nif = parse_nif(xml_tree) self.xml_file.close() for character in [' ', '-']: if character in nif: nif = nif.replace(character, '') if nif.upper() == self.user_profile.documento.upper(): return True # NIF/NIE without final letter if len(nif) == 8 and nif == self.user_profile.documento[:-1]: return True return False @classmethod def get_user_pdf_ull(cls, user, start_date=None, end_date=None): if user.profile.rrhh_code is None: return None parser = CvnXmlWriter(user=user) learning = cls._insert_learning(user, parser, start_date, end_date) cargos = cls._insert_profession(st.WS_ULL_CARGOS, user, parser, start_date, end_date) contratos = cls._insert_profession(st.WS_ULL_CONTRATOS, user, parser, start_date, end_date) docencia = cls._insert_teaching(user, parser, start_date, end_date) if not learning and not cargos and not contratos and not docencia: return None xml = parser.tostring() return fecyt.xml2pdf(xml) @classmethod def _insert_learning(cls, user, parser, start_date, end_date): items = ws.get(url=st.WS_ULL_LEARNING % user.profile.id_without_control_digit, use_redis=True) counter = 0 if items is None: return counter for item in items: values = item.copy() cls._clean_data_learning(values) item_date_range = DateRange(values[u'f_expedicion'], values[u'f_expedicion']) if not item_date_range.intersect(DateRange(start_date, end_date)): continue if (u'des1_grado_titulacion' in item and item[u'des1_grado_titulacion'].upper() == u'DOCTOR'): del values[u'des1_grado_titulacion'] parser.add_learning_phd(**values) else: parser.add_learning(**values) counter += 1 return counter @staticmethod def _clean_data_learning(item): if u'f_expedicion' in item and item[u'f_expedicion'] is not None: item[u'f_expedicion'] = dateutil.parser.parse( item[u'f_expedicion']).date() else: item[u'f_expedicion'] = None @classmethod def _insert_profession(cls, ws_url, user, parser, start_date, end_date): items = ws.get(url=ws_url % user.profile.id_without_control_digit, use_redis=True) counter = 0 if items is None: return counter for item in items: values = item.copy() cls._clean_data_profession(values) if u'f_toma_posesion' in item: initial_date = values[u'f_toma_posesion'] else: initial_date = values[u'f_desde'] item_date_range = DateRange(initial_date, values[u'f_hasta']) if not item_date_range.intersect(DateRange(start_date, end_date)): continue parser.add_profession(**values) counter += 1 return counter @staticmethod def _clean_data_profession(item): if u'f_toma_posesion' in item and item[u'f_toma_posesion'] is not None: item[u'f_toma_posesion'] = dateutil.parser.parse( item[u'f_toma_posesion']).date() if u'f_desde' in item and item[u'f_desde'] is not None: item[u'f_desde'] = dateutil.parser.parse(item[u'f_desde']).date() if u'f_hasta' in item and item[u'f_hasta'] is not None: item[u'f_hasta'] = dateutil.parser.parse(item[u'f_hasta']).date() else: item[u'f_hasta'] = None if u'des1_dedicacion' in item: dedicacion = item[u'des1_dedicacion'].upper() item[u'des1_dedicacion'] = dedicacion == u'TIEMPO COMPLETO' @classmethod def _insert_teaching(cls, user, parser, start_date, end_date): items = ws.get(url=st.WS_ULL_TEACHING % user.profile.rrhh_code, use_redis=True) counter = 0 if items is None: return counter for item in items: values = item.copy() date = datetime.date(int(values[u'curso_inicio']), 1, 1) item_date_range = DateRange(date, date) if not item_date_range.intersect(DateRange(start_date, end_date)): continue parser.add_teaching(**values) counter += 1 return counter @staticmethod def create(user, xml=None): if not xml: parser = CvnXmlWriter(user=user) xml = parser.tostring() pdf = fecyt.xml2pdf(xml) if pdf is None: return None cvn = CVN(user=user, pdf=pdf) cvn.save() return cvn @classmethod def remove_cvn_by_userprofile(cls, user_profile): try: cvn_old = cls.objects.get(user_profile=user_profile) cvn_old.remove() except ObjectDoesNotExist: pass def remove(self): # Removes data related to CVN that is not on the CVN class. self._backup_pdf() try: if self.cvn_file: self.cvn_file.delete(False) # Remove PDF file except IOError as e: logger.error(str(e)) try: if self.xml_file: self.xml_file.delete(False) # Remove XML file except IOError as e: logger.error(str(e)) def _backup_pdf(self): filename = OldCvnPdf.create_filename(self.cvn_file.name, self.uploaded_at) try: old_cvn_file = SimpleUploadedFile(filename, self.cvn_file.read(), content_type="application/pdf") except IOError as e: logger.error(e.message) else: cvn_old = OldCvnPdf(user_profile=self.user_profile, cvn_file=old_cvn_file, uploaded_at=self.uploaded_at) cvn_old.save() def remove_producciones(self): Articulo.remove_by_userprofile(self.user_profile) Libro.remove_by_userprofile(self.user_profile) Capitulo.remove_by_userprofile(self.user_profile) Congreso.remove_by_userprofile(self.user_profile) Proyecto.remove_by_userprofile(self.user_profile) Convenio.remove_by_userprofile(self.user_profile) TesisDoctoral.remove_by_userprofile(self.user_profile) Patente.remove_by_userprofile(self.user_profile) def insert_xml(self): try: if self.xml_file.closed: self.xml_file.open() self.xml_file.seek(0) cvn_items = etree.parse(self.xml_file).findall('CvnItem') self._parse_cvn_items(cvn_items) self.is_inserted = True self.save() except IOError: if self.xml_file: logger.error( (u'No existe el fichero' + u' %s') % (self.xml_file.name)) else: logger.warning(u'Se requiere de un fichero CVN-XML') def _parse_cvn_items(self, cvn_items): for cvnitem in cvn_items: produccion = parse_cvnitem_to_class(cvnitem) if produccion is None: continue produccion.objects.create(cvnitem, self.user_profile) def update_document_in_path(self): # Latest CVN relative_pdf_path = get_cvn_path(self, u'fake.pdf') full_pdf_path = os_path_join(st.MEDIA_ROOT, relative_pdf_path) xml_path = get_cvn_path(self, u'fake.xml') full_xml_path = os_path_join(st.MEDIA_ROOT, xml_path) root_path = '/'.join(full_pdf_path.split('/')[:-1]) if not os_path_isdir(root_path): makedirs(root_path) if self.cvn_file.path != full_pdf_path: file_move_safe(self.cvn_file.path, full_pdf_path, allow_overwrite=True) self.cvn_file.name = relative_pdf_path if self.xml_file.path != full_xml_path: file_move_safe(self.xml_file.path, full_xml_path, allow_overwrite=True) self.xml_file.name = xml_path self.save() def __unicode__(self): return '%s ' % self.cvn_file.name.split('/')[-1] class Meta: verbose_name_plural = _("Normalized Curriculum Vitae") ordering = ['-uploaded_at', '-updated_at']