Exemplo n.º 1
0
def set_errors(form, builder, fields):
    log.error("Form is not valid")
    log.debug(form.errors.as_json())
    for item in form.errors:
        if "_id" in item:
            item = item.split("_id")[0]
        # Get the widget
        if ("entry" in fields and item in fields["entry"]) or \
           ("spinbutton" in fields and item in fields["spinbutton"]):
            entry = builder.get_object(item)
            entry.get_style_context().add_class("error")
            entry.set_icon_from_icon_name(1, "error")

            item_errors = "\n".join(form.errors[item])
            entry.set_icon_tooltip_markup(1, item_errors)

            entry.connect("changed", error_field_changed)

        if "combobox" in fields and item in fields["combobox"]:
            combobox = builder.get_object(item)
            combobox.get_style_context().add_class("error-combobox")
            combobox.connect("changed", error_field_changed)

        if "textview" in fields and item in fields["textview"]:
            textview = builder.get_object(item + "_buffer")
            textview.get_style_context().add_class("error-textview")
            textview.connect("changed", error_field_changed)
    return
Exemplo n.º 2
0
    def refresh_single_grid(self, visible_child_name):
        try:
            visible_bag_id = int(visible_child_name.split("-")[-1])
        except ValueError as error:
            log.error("Wrong child name (not integer found). %s", error)
            return

        child_builder = self.children[visible_bag_id]

        grid = child_builder.get_object("grid")
        for child in grid.get_children():
            child.destroy()

        data = parser(self.params)

        # Toggle item
        toggle_row_num = None
        if self.toggled[visible_bag_id]:
            toggle_row_num = self.toggled[visible_bag_id][0] - 1

        # Reset toggled value
        self.toggled[visible_bag_id] = False

        self.build_grid(child_builder, data, visible_bag_id, toggle_row_num)
        return
Exemplo n.º 3
0
    def delete_key(self, fingerprint):
        """Delete key from the keyring.

        :param str fingerprint: The fingerprint of the key to delete.

        :return: True if the key is successfully deleted.
        :rtype: bool

        :Example:

        >>> km = KeyManager()
        >>> km.delete_key("0123456789ABCDEF0123456789ABCDEF01234567")
        True
        """
        try:
            r = self.gpg.delete_keys(fingerprint)
            if r.status != 'ok':
                raise ValueError(r.status)

        except ValueError as e:
            log.error("Key not found: %s", e)
            self.status = _('Key not found!')
            return False

        self.status = _('Key removed')
        return True
Exemplo n.º 4
0
    def import_allowance(self):
        """Import an Allowance from a YAML file.

        Update the :class:`pharmaship.inventory.models.Allowance` info or
        create it from scratch.

        :return: Allowance instance or ``False`` in case of import error.
        :rtype: models.Allowance or bool
        """
        content = get_file("inventory/allowance.yaml", self.tar)
        if not content:
            return False

        try:
            deserialized_allowance = serializers.deserialize("yaml", content)
            deserialized_allowance = list(deserialized_allowance)
        except serializers.base.DeserializationError as error:
            log.error("Cannot deserialize allowance: %s", error)
            return False

        for allowance in deserialized_allowance:
            obj = update_allowance(allowance.object, self.key['keyid'][-8:])
            break  # FUTURE: Only one allowance per file?

        return obj
Exemplo n.º 5
0
    def test_create_molecules(self):
        required = rescue_bag.get_required(self.params)

        output = rescue_bag.create_molecules(required["molecules"].keys(),
                                             required["molecules"])

        image_field = TypeDefinition(name='image_field',
                                     included_types=(ImageFieldFile, ),
                                     excluded_types=())
        Validator.types_mapping['image_field'] = image_field

        schema_path = settings.VALIDATOR_PATH.joinpath("parsers", "rescue_bag",
                                                       "single_item.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)

        for item in output:
            result = validator.validate(output[item])
            if not result:
                log.error(validator.errors)
                log.debug(output[item])
            self.assertTrue(result)

        schema = {"data": {"type": "dict", "keysrules": {"type": "integer"}}}
        validator = Validator(schema)
        self.assertTrue(validator.validate({"data": output}))
Exemplo n.º 6
0
def export_pdf(html_string, filename):
    """Export the equipment inventory in PDF."""
    css_path = os.path.join(settings.PHARMASHIP_REPORTS, filename)
    try:
        with open(css_path, "r") as fdesc:
            css_string = fdesc.read()
    except IOError as error:
        log.error("CSS file not readable: %s", error)
        return None

    # Create a temporary file
    tmp_file = tempfile.NamedTemporaryFile(prefix="pharmaship_",
                                           suffix=".pdf",
                                           delete=False)

    font_config = FontConfiguration()
    html = HTML(string=html_string)
    css = CSS(string=css_string, font_config=font_config)
    html.write_pdf(target=tmp_file.name,
                   stylesheets=[css],
                   font_config=font_config)

    query_count_all()

    return tmp_file.name
Exemplo n.º 7
0
def get_base(type, content, model=None):
    """Return a model instance according to the type and model if provided.

    If the `model` is not provided, it is retrieved from the `type` structure.
    On some `model` (ie: :class:`pharmaship.inventory.models.RescueBagReqQty`),
    the type can be either :class:`pharmaship.inventory.models.Equipment` or
    :class:`pharmaship.inventory.models.Molecule`.

    :param type: Model class of base field (Django internal).
    :type type: models.Equipment or models.Molecule
    :param dict content: Dictionnary with all natural key fields for the\
    related base.
    :param model: Model class of base item to serialize.
    :type model: models.Equipment or models.Molecule

    :return: A model instance or ``None`` if not found.
    :rtype: models.Equipment or models.Molecule or None
    """
    if not model:
        try:
            model = type.field.related_model
        except AttributeError as error:
            log.error("Model class not found: %s", error)
            return None
    try:
        instance = model.objects.get_by_natural_key(**content)
    except model.DoesNotExist:
        log.error("%s instance does not exist.", model)
        log.debug(content)
        return None
    return instance
Exemplo n.º 8
0
    def refresh_single_grid(self, visible_child_name):
        try:
            visible_kit_id = int(visible_child_name.split("-")[-1])
        except ValueError as error:
            log.error("Wrong child name (not integer found). %s", error)
            return

        child_builder = self.children[visible_kit_id]

        grid = child_builder.get_object("grid")
        for child in grid.get_children():
            child.destroy()

        kits = models.FirstAidKit.objects.filter(id=visible_kit_id).order_by("id").prefetch_related("items")[:self.params.setting.first_aid_kit]
        data = parser(self.params, kits)

        # Toggle item
        toggle_row_num = None
        if self.toggled[visible_kit_id]:
            toggle_row_num = self.toggled[visible_kit_id][0] - 1

        # Reset toggled value
        self.toggled[visible_kit_id] = False

        self.build_grid(child_builder, data[0], toggle_row_num)

        return
Exemplo n.º 9
0
    def test_get_transactions(self):
        schema_path = settings.VALIDATOR_PATH.joinpath(
            "parsers", "rescue_bag", "get_transactions.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)

        # Test for medicines
        content_type = self.params.content_types["medicine"]
        items = models.Medicine.objects.filter(used=False).values_list(
            "id", flat=True)
        output = rescue_bag.get_transactions(content_type, items)
        result = validator.validate({"data": output})
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)

        # Test for articles
        content_type = self.params.content_types["article"]
        items = models.Article.objects.filter(used=False).values_list(
            "id", flat=True)
        output = rescue_bag.get_transactions(content_type, items)
        result = validator.validate({"data": output})
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)
Exemplo n.º 10
0
    def test_merge_bags(self):
        required = rescue_bag.get_required(self.params)

        equipments = rescue_bag.get_articles(self.params,
                                             required["equipments"],
                                             [110, 111])

        molecules = rescue_bag.get_medicines(self.params,
                                             required["molecules"], [110, 111])

        bags = models.RescueBag.objects.all()

        output = rescue_bag.merge_bags(bags, molecules, equipments)

        image_field = TypeDefinition(name='image_field',
                                     included_types=(ImageFieldFile, ),
                                     excluded_types=())
        Validator.types_mapping['image_field'] = image_field

        schema_path = settings.VALIDATOR_PATH.joinpath("parsers", "rescue_bag",
                                                       "merged_bags.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)

        result = validator.validate({"data": output})
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)
Exemplo n.º 11
0
    def save_kit(self, source, builder, kit):
        fields = {
            "entry": [
                "name"
            ],
            "combobox": [
                "location"
            ]
        }

        cleaned_data = utils.get_form_data(forms.FirstAidKitForm, builder, fields)

        if cleaned_data is None:
            return

        try:
            kit_obj = models.FirstAidKit.objects.get(id=kit["id"])
        except models.FirstAidKit.DoesNotExist as error:
            log.error("First aid kit (ID %s) not found.", error)
            return False

        kit_obj.name = cleaned_data["name"]
        kit_obj.location_id = cleaned_data["location_id"]
        kit_obj.save()

        child = self.stack.get_child_by_name("first-aid-kit-{0}".format(kit_obj.id))
        self.stack.child_set_property(child, "title", cleaned_data["name"])

        self.cancel(source, builder)
Exemplo n.º 12
0
    def add_key(self, import_file):
        """Add a key to the keyring.

        :param file-object import_file: File object containing the key data.

        :return: True if the key is successfully added.
        :rtype: bool

        :Example:

        >>> from pathlib import Path
        >>> my_key_file = Path("pharmaship.pub").open()
        >>> km = KeyManager()
        >>> km.add_key(my_key_file)
        True

        """
        key_data = import_file.read()
        r = self.gpg.import_keys(key_data)

        for item in r.results:
            if 'ok' not in item.keys():
                log.error("Signature error: %s", item["text"])
                self.status = _('Something went wrong! See detailed logs.')
                return False

        if r.imported == 0:
            log.info("Key already added.")
            self.status = _('Key already added')
        else:
            key = self.get_key(r.fingerprints[0])
            item = {"name": key['uids'][0], "fingerprint": key['fingerprint']}
            log.debug(item)
            self.status = _('Key successfully added')
        return True
Exemplo n.º 13
0
    def test_telemedical_parser(self):
        """Check conformity of parser's output.

        Proceed in two steps:
        1. Check the conformity of output items
        2. Check the conformity of output keys

        Use Cerberus for checking conformity.
        """
        output = parsers.laboratory.parser(self.params)
        schema_path = settings.VALIDATOR_PATH / "parsers" / "telemedical.json"
        schema = json.loads(schema_path.read_text())

        group_type = TypeDefinition(
            name='equipment_group',
            included_types=(models.EquipmentGroup,),
            excluded_types=()
            )
        image_field = TypeDefinition(
            name='image_field',
            included_types=(ImageFieldFile,),
            excluded_types=()
            )
        Validator.types_mapping['equipment_group'] = group_type
        Validator.types_mapping['image_field'] = image_field

        validator = Validator(schema)

        dict_result = {"data": output}
        result = validator.validate(dict_result)
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)
Exemplo n.º 14
0
    def handle(self, *args, **options):
        if "fingerprint" in options:
            regex = re.search(r"^[0-9a-fA-F]{40}$", options["fingerprint"])
            if not regex:
                log.error("Fingerprint not correct.")
                return False

        if "func" in options:
            options['func'](options)
Exemplo n.º 15
0
    def allowance(self, args):
        """Export selected `Allowance` instance in a tar file."""
        log.debug("Allowance export")

        try:
            allowance = models.Allowance.objects.get(id=args["id"])
        except models.Allowance.DoesNotExist:
            log.error("Allowance does not exists.")
            exit()

        create_archive(allowance, args["filename"])
Exemplo n.º 16
0
def deserialize_json_file(data, tar, allowance):
    """Deserialize a JSON file contained in the tar file.

    :param dict data: Dictionnary with filename and model related. The \
    following keys must be present:

      * ``filename``: the name of the JSON file to extract from the tar \
      archive;
      * ``model``: the class of model to deserialize \
      (ie: :class:`pharmaship.inventory.models.MoleculeReqQty`).

    :param tarfile.TarFile tar: tar file archive containing the file to extract
    :param allowance: allowance instance to rattach
    :type allowance: models.Allowance

    :return: List of `model` instances.
    :rtype: list
    """
    content = get_file(data["filename"], tar)
    if not content:
        return False

    try:
        item_data = json.loads(content)
    except json.decoder.JSONDecodeError as error:
        log.error("Corrupted JSON file: %s", error)
        return False

    objects = []
    for item in item_data:
        if "content_type" not in item:
            base = get_base(type=data["model"].base, content=item["base"])
        else:
            ct = get_model(item["content_type"])
            if ct is None:
                return False
            base = get_base(type=data["model"].base,
                            content=item["base"],
                            model=ct.model_class())

        if not base:
            log.error("Base for item not found.")
            log.debug(item)
            return False

        instance = data["model"](allowance=allowance,
                                 base=base,
                                 required_quantity=item["required_quantity"])

        objects.append(instance)

    return objects
Exemplo n.º 17
0
    def test_get_required(self):
        output = rescue_bag.get_required(self.params)

        schema_path = settings.VALIDATOR_PATH.joinpath("parsers", "rescue_bag",
                                                       "get_required.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)

        result = validator.validate(output)
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)
Exemplo n.º 18
0
    def test_search(self):
        call_command("loaddata", self.assets / "test.dump.yaml")
        text = "Doli"
        params = GlobalParameters()
        output = search.search(text, params)

        schema_path = settings.VALIDATOR_PATH.joinpath("search.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)

        result = validator.validate({"data": output})
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)
Exemplo n.º 19
0
def check_tarfile(data):
    """Check that the data input is a valid Tar file.

    :param bytes data: binary string issued from GPG armor decoding containing\
    a tar file.

    :return: A Tarfile object.
    :rtype: tarfile.TarFile
    """
    try:
        tar = tarfile.open(fileobj=io.BytesIO(data), mode="r")
        return tar
    except (tarfile.ReadError, tarfile.CompressionError) as error:
        log.error("File is not a valid Tar file. %s", error)
        return False
Exemplo n.º 20
0
    def import_molecule(self):
        """Import Molecule objects from a YAML file.

        Use Django's update_or_create method for
        :class:`pharmaship.inventory.models.Molecule`.

        :return: ``True`` if successful import, ``False`` otherwise.
        :rtype: bool
        """
        content = get_file("inventory/molecule_obj.yaml", self.tar)
        if not content:
            return False

        try:
            deserialized_list = serializers.deserialize("yaml", content)
            deserialized_list = list(deserialized_list)
        except serializers.base.DeserializationError as error:
            log.error("Cannot deserialize molecule objects: %s", error)
            return False

        for molecule in deserialized_list:
            # Unique: (name, roa, dosage_form, composition)
            unique_values = {
                'name': molecule.object.name,
                'roa': molecule.object.roa,
                'dosage_form': molecule.object.dosage_form,
                'composition': molecule.object.composition,
            }
            molecule_dict = dict(unique_values)  # Hard copy
            molecule_dict['medicine_list'] = molecule.object.medicine_list
            molecule_dict['group'] = molecule.object.group
            molecule_dict['remark'] = molecule.object.remark

            # TODO: DB calls optimization
            obj, created = models.Molecule.objects.update_or_create(
                defaults=molecule_dict, **unique_values)
            # Add M2M relations
            try:
                if molecule.m2m_data['tag']:
                    obj.tag = molecule.m2m_data['tag']
                    obj.save()
            except KeyError:
                pass

            if created:
                log.debug("Created molecule: %s", obj)

        return True
Exemplo n.º 21
0
def get_file(filename, tar):
    """Extract a file from a tar archive.

    :param str filename: Filename to extract from tar file.
    :param tarfile.TarFile tar: tar file instance.

    :return: Content of the file or ``False`` if the file cannot be accessed.
    :rtype: bytes or bool
    """
    try:
        fdesc = tar.extractfile(filename)
    except KeyError:
        log.error("File `%s` not found.", filename)
        return False

    return fdesc.read()
Exemplo n.º 22
0
    def check_signature(self):
        """Check the signature of the package.

        Decoded data is stored in ``self.data`` property.

        :return: ``True`` if the signature is correct, ``False`` otherwise.
        :rtype: bool
        """
        res = self.km.check_signature(self.content)
        if not res:
            log.error("Error during signature check: %s", self.km.status)
            self.status = _("Signature not validated. See detailled log.")
            return False

        # Save the result in the instance
        self.data = res
        return True
Exemplo n.º 23
0
def create_archive(allowance, file_obj):
    """Create an archive from the given `Allowance` instance.

    The response is a tar.gz file containing YAML files generated by the
    function `serialize_allowance`.
    """
    # Creating a tar.gz archive
    hashes = []

    serialized_data, equipment_list = serialize_allowance(
        allowance=allowance,
        content_types=get_content_types()
        )

    with tarfile.open(fileobj=file_obj, mode='w') as tar:
        # Processing the database
        for item in serialized_data:
            info, f = create_tarinfo(item[0], item[1])
            tar.addfile(info, f)

            hashes.append(get_hash(info.name, content=item[1]))

        # Adding the pictures of Equipment
        for item in get_pictures(equipment_list):
            picture_filename = settings.PICTURES_FOLDER / item
            log.debug(picture_filename)
            try:
                tar.add(picture_filename, arcname=PurePath("pictures", item))
            # TODO: Detail Exception
            except Exception as error:
                log.error("Error: %s", error)

            hashes.append(get_hash(PurePath("pictures", item), filename=picture_filename))

        # Add the MANIFEST
        package_content = create_package_yaml(allowance)
        info, f = create_tarinfo("package.yaml", package_content)
        tar.addfile(info, f)
        hashes.append(get_hash("package.yaml", content=package_content))

        # Add the MANIFEST
        manifest_content = create_manifest(hashes)
        info, f = create_tarinfo("MANIFEST", manifest_content)
        tar.addfile(info, f)

    return True
Exemplo n.º 24
0
    def test_parser(self):
        output = rescue_bag.parser(self.params)

        image_field = TypeDefinition(name='image_field',
                                     included_types=(ImageFieldFile, ),
                                     excluded_types=())
        Validator.types_mapping['image_field'] = image_field

        schema_path = settings.VALIDATOR_PATH.joinpath("parsers", "rescue_bag",
                                                       "rescue_bag.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)

        result = validator.validate({"data": output})
        if not result:
            log.error(validator.errors)
            log.debug(output)
        self.assertTrue(result)
Exemplo n.º 25
0
def get_template(filename, lang):
    """Return a Django template."""
    template_path = os.path.join(settings.PHARMASHIP_REPORTS, filename)

    try:
        with open(template_path, "r") as fdesc:
            template_string = fdesc.read()
    except IOError as error:
        log.error("File not readable. %s", error)
        return False

    # Force language. If not, LANGUAGE_CODE in django settings is used.
    translation.activate(lang)

    # Create Django template
    template = Template(template_string)

    return template
Exemplo n.º 26
0
def get_model(data):
    """Return the related ContentType from `data`.

    :param dict data: Dictionnary containing at least following keys:

      * ``app_label``: the application name,
      * ``name``: the name of the model

    :return: The Django ContentType instance or ``None`` if it does not exist.
    :rtype: django.contrib.contenttypes.models.ContentType or None
    """
    try:
        ct = ContentType.objects.get_by_natural_key(
            app_label=data["app_label"], model=data["name"])
    except ContentType.DoesNotExist:
        log.error("ContentType not found.")
        log.debug(data)
        return None
    return ct
Exemplo n.º 27
0
def get_hash(name, content=None, filename=None):
    """Return sha256 hash and filename for MANIFEST file."""
    if content is None and filename is None:
        return None

    m = hashlib.sha256()
    if content:
        if isinstance(content, bytes):
            m.update(content)
        else:
            m.update(bytes(content, "utf-8"))
    elif filename:
        try:
            with open(filename, 'rb') as fdesc:
                m.update(fdesc.read())
        except IOError as error:
            log.error("File %s not readable. %s", filename, error)
            return None

    return (name, m.hexdigest())
Exemplo n.º 28
0
    def import_equipment(self):
        """Import Equipment objects from a YAML file.

        Use Django's update_or_create method for
        :class:`pharmaship.inventory.models.Equipment`.

        :return: ``True`` if successful import, ``False`` otherwise.
        :rtype: bool
        """
        content = get_file("inventory/equipment_obj.yaml", self.tar)
        if not content:
            return False

        try:
            deserialized_list = serializers.deserialize("yaml", content)
            deserialized_list = list(deserialized_list)
        except serializers.base.DeserializationError as error:
            log.error("Cannot deserialize equipment objects: %s", error)
            return False

        for equipment in deserialized_list:
            # Unique: (name, packaging, perishable, consumable)
            unique_values = {
                'name': equipment.object.name,
                'packaging': equipment.object.packaging,
                'perishable': equipment.object.perishable,
                'consumable': equipment.object.consumable
            }
            equipment_dict = dict(unique_values)  # Hard copy
            equipment_dict["group"] = equipment.object.group
            equipment_dict['picture'] = equipment.object.picture
            equipment_dict['remark'] = equipment.object.remark

            # TODO: DB calls optimization
            obj, created = models.Equipment.objects.update_or_create(
                defaults=equipment_dict, **unique_values)

            if created:
                log.debug("Created equipment: %s", obj)

        return True
Exemplo n.º 29
0
    def deploy(self):
        """Propagate the import to concerned modules.

        For each module listed in the configuration, the import class
        ``update()`` method is called.

        :return: ``True`` if all updates are applied correctly, ``False``\
        otherwise
        :rtype: bool
        """
        for module in self.modules:
            import_class = load_module(module)
            if not import_class:
                self.status = _("Module import error. See detailed log.")
                return False

            data_import = import_class(tar=self.archive,
                                       conf=self.conf,
                                       key=self.km.key)

            if not (hasattr(data_import, "update")
                    and callable(data_import.update)):
                log.error("Module %s has no DataImport.update method.", module)
                self.status = _(
                    "Target module has no update method. See detailed log.")
                return False

            step_result = data_import.update()
            if not step_result:
                msg = _("Import of module {0} failed. See detailed logs."
                        ).format(module)
                log.error(msg)
            else:
                msg = _("Import of module {0} succeeded.").format(module)
                log.info(msg)

            self.import_log.append({'name': module, 'value': msg})

        self.status = _("Import success.")

        return True
Exemplo n.º 30
0
    def test_parser(self):
        kits = models.FirstAidKit.objects.all()
        output = first_aid.parser(self.params, kits)

        self.assertIsInstance(output, list)

        image_field = TypeDefinition(name='image_field',
                                     included_types=(ImageFieldFile, ),
                                     excluded_types=())
        Validator.types_mapping['image_field'] = image_field

        schema_path = settings.VALIDATOR_PATH.joinpath("parsers", "first_aid",
                                                       "first_aid_kit.json")
        schema = json.loads(schema_path.read_text())
        validator = Validator(schema)
        for item in output:
            result = validator.validate(item)
            if not result:
                log.error(validator.errors)
                log.debug(item)
            self.assertTrue(result)