Esempio n. 1
0
    def write_line(self,
                   file_data: object,
                   full_path: str,
                   encoding: str = 'utf-8'):
        '''
        Фнукия записывает строку в файл. Если файл отсутствовал, он будет создан.

        :param file_data: данные для экспорта в файл
        :param full_path: полное имя файла
        :param encoding: кодировка
        :return:
        '''
        if not full_path.endswith('.jsonl'):
            raise ValidationError(
                "Incorrect file extension. Only '.jsonl' is available.")

        with self.mutex:
            # пишем
            try:
                with open(full_path, mode='a',
                          encoding=encoding) as file:  # Делаем экспорт
                    json.dump(file_data, file)
                    file.write('\n')
                    file.flush()

            except BaseException as miss:
                raise ProcessingError(
                    f'Line export failed.\nfull_path: {full_path}\nencoding: {encoding}'
                ) from miss

        return
Esempio n. 2
0
    def read_by_lines(self,
                      full_path: str,
                      encoding: str = 'utf-8',
                      start: int = 0,
                      stop: int = None) -> FileIterator:
        '''
        Функция отдаёт иттератор для чтения по строкам.

        :param full_path: полный путь к файлу
        :param encoding: строка, явно указывающая кодировку или None для её автоопределения
        :param start: первая строка
        :param stop: последняя строка. None - считать все
        :return: итератор по строкам FileIterator
        '''
        if not full_path.endswith('.txt'):
            raise ValidationError(
                "Incorrect file extension. Only '.jsonl' is available.")

        with self.mutex:
            if not self.check_access(path=full_path):
                raise ProcessingError('No access to file')

            # определим кодировку файла
            if encoding is None:
                encoding = self.get_encoding(full_path=full_path)

            return FileIterator(full_path=full_path,
                                encoding=encoding,
                                start=start,
                                stop=stop)
Esempio n. 3
0
    def read(self, full_path: str, save_loaded: bool = None,
             encoding: str = None) -> object:
        '''
        Функция считывания json файла

        :param full_path: полный путь к файлу
        :param save_loaded: сохранить ли загруженный файл? True - да, False - нет, None - использовать стандартную
            настройку (save_loaded)
        :param encoding: строка, явно указывающая кодировку или None для её автоопределения
        :return: считанный файл в виде JSON объекта
        '''
        if not full_path.endswith('.json'):
            raise ValidationError("Incorrect file extension. Only '.json' is available.")

        with self.mutex:
            if not self.check_access(path=full_path):
                raise ProcessingError('No access to file')

            # определим кодировку файла
            if encoding is None:
                encoding = self.get_encoding(full_path=full_path)

            # читаем
            try:
                with open(full_path, mode='r', encoding=encoding) as file:
                    result = json.load(file)
            except BaseException as miss:  # Если не получилось считать файл
                raise ProcessingError(f'File reading failed.\nfull_path: {full_path}\nencoding: {encoding}') from miss

        if (save_loaded is None and self.save_loaded) or save_loaded is True:
            self._ad_loaded(full_path=full_path,
                            data=result)

        return result
Esempio n. 4
0
    def save_loaded(self, value: bool):
        '''
        Устанавливает детектор необходимости сохранения считанных файлов

        :param value: bool значение
        :return: ничего
        '''
        if not isinstance(value, bool):
            raise ValidationError('Wrong "value" type')
        self.__save_loaded = value
        return
Esempio n. 5
0
    def read(
        self,
        full_path: str,
        save_loaded: bool = None,
        encoding: str = 'utf-8',
        index_column_number: int = None,
        sheets_names: int or str or list = None
    ) -> pd.core.frame.DataFrame or dict:
        '''
        Функция считывания xlsx файла

        :param full_path: полный путь к файлу
        :param save_loaded: сохранить ли загруженный файл? True - да, False - нет, None - использовать стандартную
            настройку (save_loaded)
        :param encoding: строка, явно указывающая кодировку или None для её автоопределения
        :param index_column_number: имя колонки с названием индекса
        :param sheets_names: определяет листы, которые требуется считать:
            str - имя листа;
            int - номер листа (с нулевого);
            list - список из строк или чисел ([0, "Sheet5"] - возьмёт первый лист и лист с именем "Sheet5");
            None - взять все.
        :return: считанный файл в виде pd.core.frame.DataFrame; если считывался один лист, или
            dict вида {sheet_name: DataFrame}, если считывались несколько.
        '''
        if not full_path.endswith('.xlsx'):
            raise ValidationError(
                "Incorrect file extension. Only '.xlsx' is available.")

        with self.mutex:
            # определим кодировку файла
            if encoding is None:
                encoding = self.get_encoding(full_path=full_path)

            try:  # Считаем
                with open(full_path, 'rb') as file:
                    result = pd.read_excel(io=file,
                                           sheet_name=sheets_names,
                                           encoding=encoding,
                                           index_col=index_column_number,
                                           engine='xlrd')  # считаем его

            except BaseException as miss:  # Если не получилось считать файл
                raise ProcessingError(
                    f'File reading failed.\nfull_path: {full_path}\nencoding: {encoding}'
                ) from miss

        if (save_loaded is None and self.save_loaded) or save_loaded is True:
            self._ad_loaded(full_path=full_path, data=result)

        return result
Esempio n. 6
0
    def write(self,
              file_data: object,
              full_path: str,
              shift_name: bool or None = True,
              encoding: str = 'utf-8') -> bool or str:
        '''
        Фнукия записывает данные в файл jsonl

        :param file_data: данные для экспорта в файл
        :param full_path: полное имя файла
        :param shift_name: разрешена ди замена имени: True - сдвинуть имя при совпадении на "(N)",
            False - заменить файл, None - отказаться от экспорта в случае совпадения имён.
        :param encoding: кодировка
        :return: True - успешно экспортнуто, имя уникально
            False - отказ от экспорта
            str - успешно экспортнуто, имя изменено
        '''
        if not full_path.endswith('.jsonl'):
            raise ValidationError(
                "Incorrect file extension. Only '.jsonl' is available.")

        with self.mutex:
            name_shifted = False
            if self.check_access(
                    path=full_path
            ):  # если есть файл и мы не дописываем в конец
                if shift_name is None:
                    return False
                elif shift_name is True:
                    full_path = self.name_shifting(full_path=full_path,
                                                   expansion='.json')
                    name_shifted = True

            # пишем
            try:
                with open(full_path, mode='w', encoding=encoding) as file:
                    json.dump(file_data, file)
                    file.write('\n')
                    file.flush()

            except BaseException as miss:
                raise ProcessingError(
                    f'File export failed.\nfull_path: {full_path}\nencoding: {encoding}'
                ) from miss

        if name_shifted:
            return full_path
        else:
            return True
Esempio n. 7
0
    def write(self,
              file_data: object,
              full_path: str,
              shift_name: bool or None = True) -> bool or str:
        '''
        Фнукия записывает данные в json файл

        :param file_data: данные для экспорта в файл
        :param full_path: полное имя файла
        :param shift_name: разрешена ди замена имени: True - сдвинуть имя при совпадении на "(N)",
            False - заменить файл, None - отказаться от экспорта в случае совпадения имён.
        :return: True - успешно экспортнуто, имя уникально
            False - отказ от экспорта
            str - успешно экспортнуто, имя изменено
        '''
        if not full_path.endswith('.pickle'):
            raise ValidationError(
                "Incorrect file extension. Only '.pickle' is available.")

        with self.mutex:
            name_shifted = False
            if self.check_access(path=full_path):
                if shift_name is None:
                    return False
                elif shift_name is True:
                    full_path = self.name_shifting(full_path=full_path,
                                                   expansion='.json')
                    name_shifted = True

            # пишем
            try:
                with open(full_path, mode='wb') as file:
                    pickle.dump(file_data, file, pickle.HIGHEST_PROTOCOL)
                    file.flush()
            except BaseException as miss:
                raise ProcessingError(
                    f'File export failed. full_path: {full_path}') from miss

        if name_shifted:
            return full_path
        else:
            return True
Esempio n. 8
0
    def read(self, full_path: str, save_loaded: bool = None,
             encoding: str = 'utf-8',
             index_column_name: str = None,
             sep: str = ';'
             ) -> pd.core.frame.DataFrame:
        '''
        Функция считывания csv файла

        :param full_path: полный путь к файлу
        :param save_loaded: сохранить ли загруженный файл? True - да, False - нет, None - использовать стандартную
            настройку (save_loaded)
        :param encoding: строка, явно указывающая кодировку или None для её автоопределения
        :param index_column_name: имя колонки с названием индекса
        :param sep: - разделитель в файле
        :return: считанный файл
        '''
        if not full_path.endswith('.csv'):
            raise ValidationError("Incorrect file extension. Only '.csv' is available.")

        with self.mutex:
            # определим кодировку файла
            if encoding is None:
                encoding = self.get_encoding(full_path=full_path)


            try:  # Считаем
                with open(full_path, 'r', encoding=encoding) as file:
                    result = pd.read_csv(filepath_or_buffer=file,
                                         sep=sep, encoding=encoding, index_col=index_column_name,
                                         engine='python')  # считаем его

            except BaseException as miss:  # Если не получилось считать файл
                raise ProcessingError(f'File reading failed.\nfull_path: {full_path}\nencoding: {encoding}') from miss


        if (save_loaded is None and self.save_loaded) or save_loaded is True:
            self._ad_loaded(full_path=full_path,
                            data=result)

        return result
Esempio n. 9
0
    def read(self, full_path: str) -> object:
        '''
        Функция считывания json файла

        :param full_path: полный путь к файлу
        :return: считанный файл в виде JSON объекта
        '''
        if not full_path.endswith('.pickle'):
            raise ValidationError(
                "Incorrect file extension. Only '.pickle' is available.")
        with self.mutex:
            try:
                if not self.check_access(path=full_path):
                    raise ProcessingError('No access to file')

                # читаем
                with open(full_path, mode='rb') as file:
                    result = pickle.load(file)
            except BaseException as miss:
                raise ProcessingError(
                    f'File reading failed. full_path: {full_path}') from miss

        return result
Esempio n. 10
0
    def write_at_the_end(self,
                         file_data: object,
                         full_path: str,
                         encoding: str = 'utf-8',
                         new_string: bool = False):
        '''
        Фнукия дозаписывает данные в файл. Если файл отсутствовал, он будет создан.

        :param file_data: данные для экспорта в файл
        :param full_path: полное имя файла
        :param encoding: кодировка
        :param new_string: писать с новой строки
        :return:
        '''
        if not full_path.endswith('.txt'):
            raise ValidationError(
                "Incorrect file extension. Only '.jsonl' is available.")

        with self.mutex:
            if not self.check_access(path=full_path):
                raise ProcessingError('No access to file')

            # пишем
            try:
                with open(full_path, mode='a',
                          encoding=encoding) as file:  # Делаем экспорт
                    if new_string:
                        file.write('\n')
                    file.write(file_data)
                    file.flush()

            except BaseException as miss:
                raise ProcessingError(
                    f'Line export failed.\nfull_path: {full_path}\nencoding: {encoding}'
                ) from miss

        return
Esempio n. 11
0
    def write_sheet(self,
                    file_data: pd.core.frame.DataFrame
                    or pd.core.series.Series,
                    full_path: str,
                    sheet_name: str,
                    with_index: bool = True,
                    encoding: str = 'utf-8') -> True or str or None:
        '''
        Фнукия записывает лист в файл ".xlsx". Если лист отсутствовал, он будет добавлен.
        https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_excel.html

        :param file_data: данные для экспорта в файл DataFrame или Series
        :param full_path: полное имя файла
        :param sheet_name: имя листа, на который будет выполнен экспорт
        :param with_index: экспортировать ли индекс?
        :param one_list_name: имя "одного" листа. Если подан DataFrame или Series, а не словарь, то лист надо
            как-то назвать. Это его имя. Если подан словарь, в качестви имён листов будет взят индекс.
        :param encoding: кодировка файла
        :return:
        '''
        if not full_path.endswith('.xlsx'):
            raise ValidationError(
                "Incorrect file extension. Only '.xlsx' is available.")

        if isinstance(file_data, pd.core.frame.DataFrame):
            pass
        elif isinstance(
                file_data,
                pd.core.series.Series):  # Если подна series - конвертнём
            try:
                file_data = pd.DataFrame(data=file_data.tolist(),
                                         index=file_data.index)
            except BaseException as miss:
                raise ProcessingError(
                    'Series to DataFrame conversion failed. File export failed.'
                ) from miss
        else:
            raise ValidationError(
                f'file_data type must be Series or DataFrame. {type(file_data)} was passed. '
                + 'File export failed.')

        file_data = {sheet_name: file_data}

        with self.mutex:
            # Выполним экспорт
            try:
                with pd.ExcelWriter(
                        full_path,
                        mode='a') as writer:  # Делаем "писатель файла"
                    for frame_key in file_data.keys(
                    ):  # Пошли по индексу в словаре
                        if with_index:
                            if file_data[frame_key].index.name is None:
                                file_data[frame_key] = file_data[
                                    frame_key].copy(
                                    )  # берём ссылку, чтобы не изменить объект
                                file_data[
                                    frame_key].index.name = 'index'  # ставим имя индекса (чтобы оно не было пустым)

                        file_data[frame_key].to_excel(writer,
                                                      sheet_name=frame_key,
                                                      encoding=encoding,
                                                      index=with_index)
                    writer.save()
                    writer.close()

            except BaseException as miss:
                raise ProcessingError(
                    f'Sheet export failed.\nfull_path: {full_path}\nencoding: {encoding}'
                ) from miss

        return
Esempio n. 12
0
    def write(self,
              file_data: pd.core.frame.DataFrame or pd.core.series.Series
              or dict,
              full_path: str,
              shift_name: bool or None = True,
              with_index: bool = True,
              one_list_name: str = 'List1',
              encoding: str = 'utf-8') -> bool or str:
        '''
        Фнукия записывает данные в файл ".xlsx".
        https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_excel.html

        :param file_data: данные для экспорта в файл: DataFrame или Series экспортнутся на лист с именем,
            переданным в one_list_name; если же подан словарь, имена листов совпадут с индексами словаря.
        :param full_path: полное имя файла
        :param shift_name: разрешена ди замена имени: True - сдвинуть имя при совпадении на "(N)",
            False - заменить файл, None - отказаться от экспорта в случае совпадения имён.
        :param sep: разделитель в файле
        :param with_index: экспортировать ли индекс?
        :param one_list_name: имя "одного" листа. Если подан DataFrame или Series, а не словарь, то лист надо
            как-то назвать. Это его имя. Если подан словарь, в качестви имён листов будет взят индекс.
        :param encoding: кодировка файла
        :return: True - успешно экспортнуто, имя уникально
            False - отказ от экспорта
            str - успешно экспортнуто, имя изменено
        '''
        if not full_path.endswith('.xlsx'):
            raise ValidationError(
                "Incorrect file extension. Only '.xlsx' is available.")

        if isinstance(file_data, pd.core.frame.DataFrame):
            file_data = {one_list_name: file_data}
            pass
        elif isinstance(
                file_data,
                pd.core.series.Series):  # Если подна series - конвертнём
            try:
                file_data = pd.DataFrame(data=file_data.tolist(),
                                         index=file_data.index)
                file_data = {one_list_name: file_data}
            except BaseException as miss:
                raise ProcessingError(
                    'Series to DataFrame conversion failed. File export failed.'
                ) from miss

        elif isinstance(file_data, dict):
            for key in file_data.keys(
            ):  # Проверим, что каждый элемент является фреймом

                if isinstance(file_data[key],
                              pd.core.frame.DataFrame):  # Если фрейм
                    pass
                elif isinstance(
                        file_data[key],
                        pd.core.series.Series):  # Если Series - конвертнём
                    try:
                        new_data = pd.DataFrame(data=file_data[key].tolist(),
                                                index=file_data[key].index)
                        file_data[key] = new_data
                    except BaseException as miss:
                        file_data.pop(file_data[key])
                        warn(
                            f'Element "{key}" conversion Series to DataFrame failed. Error: {miss.args[0]}\nValue excluded.',
                            DeprecationWarning)
                else:  # Если говнотип
                    warn((
                        f'Element "{key}" have wrong type: {type(file_data[key])}. Value excluded.'
                        + 'Element must be Series or DataFrame.'),
                         DeprecationWarning)
                    file_data.pop(file_data[key])

            if file_data == {}:  # если словарь опустел
                raise ProcessingError(
                    'All dictionary elements were excluded due to errors.')

        else:
            raise ValidationError(
                f'file_data type must be Series or DataFrame. {type(file_data)} was passed. '
                + 'File export failed.')

        with self.mutex:
            name_shifted = False
            if self.check_access(path=full_path):
                if shift_name is None:
                    return False
                elif shift_name is True:
                    full_path = self.name_shifting(full_path=full_path,
                                                   expansion='.json')
                    name_shifted = True

            # Выполним экспорт
            try:
                with pd.ExcelWriter(
                        full_path,
                        mode='w') as writer:  # Делаем "писатель файла"
                    for frame_key in file_data.keys(
                    ):  # Пошли по индексу в словаре
                        if with_index:
                            if file_data[frame_key].index.name is None:
                                file_data[frame_key] = file_data[
                                    frame_key].copy(
                                    )  # берём ссылку, чтобы не изменить объект
                                file_data[
                                    frame_key].index.name = 'index'  # ставим имя индекса (чтобы оно не было пустым)

                        file_data[frame_key].to_excel(writer,
                                                      sheet_name=frame_key,
                                                      encoding=encoding,
                                                      index=with_index)
                    writer.save()
                    writer.close()

            except BaseException as miss:
                raise ProcessingError(
                    f'File export failed.\nfull_path: {full_path}\nencoding: {encoding}'
                ) from miss

        if name_shifted:
            return full_path
        else:
            return True
Esempio n. 13
0
    def write(self, file_data: pd.core.frame.DataFrame or pd.core.series.Series,
              full_path: str, shift_name: bool or None = True,
              sep: str = ';', with_index: bool = True,
              encoding: str = 'utf-8') -> bool or str:
        '''
        Фнукия записывает данные в файл ".csv".

        :param file_data: данные для экспорта в файл в виде фрейма или столбца
        :param full_path: полное имя файла
        :param shift_name: разрешена ди замена имени: True - сдвинуть имя при совпадении на "(N)",
            False - заменить файл, None - отказаться от экспорта в случае совпадения имён.
        :param sep: разделитель в файле
        :param with_index: экспортировать ли индекс?
        :param encoding: кодировка файла
        :return: True - успешно экспортнуто, имя уникально
            False - отказ от экспорта
            str - успешно экспортнуто, имя изменено
        '''
        if not full_path.endswith('.csv'):
            raise ValidationError("Incorrect file extension. Only '.csv' is available.")


        if isinstance(file_data, pd.core.frame.DataFrame):
            pass
        elif isinstance(file_data, pd.core.series.Series):  # Если подна series - конвертнём
            try:
                file_data = pd.DataFrame(data=file_data.tolist(), index=file_data.index)
            except BaseException as miss:
                raise ProcessingError('Series to DataFrame conversion failed. File export failed.') from miss
        else:
            raise ValidationError(f'file_data type must be Series or DataFrame. {type(file_data)} was passed. ' +
                                  'File export failed.')

        with self.mutex:
            name_shifted = False
            if self.check_access(path=full_path):
                if shift_name is None:
                    return False
                elif shift_name is True:
                    full_path = self.name_shifting(full_path=full_path, expansion='.json')
                    name_shifted = True

            # Выполним экспорт
            try:
                if with_index:
                    if file_data.index.name is None:
                        index_label = 'index'
                    else:
                        index_label = file_data.index.name
                else:
                    index_label=None

                file_data.to_csv(path_or_buf=full_path, sep=sep, encoding=encoding,
                                 index=with_index,
                                 index_label=index_label)

            except BaseException as miss:
                raise ProcessingError(f'File export failed.\nfull_path: {full_path}\nencoding: {encoding}') from miss

        if name_shifted:
            return full_path
        else:
            return True