dfelf


Namedfelf JSON
Version 0.2.1 PyPI version JSON
download
home_pagehttps://github.com/KrixTam/dfelf
SummaryData File Elf
upload_time2024-09-05 03:43:56
maintainerNone
docs_urlNone
authorKrix Tam
requires_python>=3.6
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # dfelf

由于日常工作需要(有时候还有写blog的需要),总是要处理一些数据文件,很多繁琐的工作希望可以有一个文件精灵来帮我处理,所以就把过去写的小工具重新整理下,形成“数据文件精灵”(“dfelf”)。

“dfelf”为“Data File Elf”的缩写。

因为日常总是需要处理如下文件:
* PDF
* CSV
* 图片

所以数据文件精灵初步设计可以支持以上三类文件的日常处理需要。

自v0.1.4版本开始支持*silent模式*,即不进行IO处理、不输出文件,相关方法中增加*silent*参数,默认值为*False*。

## 安装

> conda install -c conda-forge poppler
> 
> pip install --upgrade dfelf

## PDFFileElf

PDF文件精灵用于日常对*pdf*文件的处理应用。相关方法如下:

* **create**:抽取一个或多个PDF文件中相关页重新排列组合成一个新的PDF文件;对应的配置设定为*create*。
> PDFFileElf.create(input_obj=None, silent: bool = False, **kwargs)
* **image2pdf**:将图片文件拼接成一个PDF文件,每个图片为一页;对应的配置设定为*image2pdf*。
> PDFFileElf.image2pdf(input_obj: list = None, silent: bool = False, **kwargs)
* **to_image**:将PDF文件相关页输出成图片,每一页为一个图片,以页码为文件后续;对应的配置设定为*2image*。
> PDFFileElf.to_image(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)
* **remove**:将PDF文件中指定的页面删除后输出PDF文件;对应的配置设定为*remove*。
> PDFFileElf.remove(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)
* **extract_images**:将PDF文件中指定的页面或整个PDF文件(当*pages*配置为空*list*时,表示整个PDF文件)的图片进行提取;对应的配置设定为*extract_images*。
> PDFFileElf.extract_images(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)
* **extract_fonts**:将PDF文件中的字体导出到指定的*output*目录中。
> PDFFileElf.extract_fonts(input_obj=None, silent: bool = False, **kwargs)
* **rotate_pages**:将PDF文件中指定的页面进行顺时针旋转处理后,把处理后的PDF输出到新的PDF文件中。
> PDFFileElf.rotate_pages(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)

以下方法从0.2.0版本开始废弃,改用**create**统一实现

> * **reorganize**:抽取PDF文件中相关页重新排列组合成一个新的PDF文件;对应的配置设定为*reorganize*。
> PDFFileElf.reorganize(input_obj=None, silent: bool = False, **kwargs)
> * **merge**:将PDF文件按顺序合并为一个PDF文件;对应的配置设定为*merge*。
> PDFFileElf.merge(input_obj: list = None, silent: bool = False, **kwargs)

另外,remove_watermark未完善,0.2.0版本开始暂时不提供服务

> * **remove_watermark**:将PDF文件中指定的水印文本关键词所在的区域文本清除。
> PDFFileElf.remove_watermark(input_obj=None, silent: bool = False, **kwargs)

配置文件设定如下:

```json
{
    "create": {
        "input": [
            {
                "file": "input_filename_01",
                "pages": []
            },
            {
                "file": "input_filename_02",
                "pages": []
            }
        ],
        "output": "output_filename"
    },
    "image2pdf": {
        "images": [],
        "output": "output_filename"
    },
    "to_image": {
        "input": "input_filename",
        "output": "output_filename_prefix",
        "format": "png",
        "dpi": 200,
        "pages": [
            1
        ]
    },
    "remove": {
        "input": "input_filename",
        "output": "output_filename",
        "pages": [
            1
        ]
    },
    "extract_images": {
        "input": "input_filename",
        "output": "output_filename_prefix",
        "pages": [
            1
        ]
    },
    "remove_watermark": {
        "input": "input_filename",
        "output": "output_filename",
        "keywords": []
    },
    "extract_fonts": {
        "input": "input_filename",
        "output": "output_directory"
    },
    "rotate_pages": {
        "input": "input_filename",
        "output": "output_filename",
        "pages": [
            "1|90"
        ]
    }
}
```

> - 自v0.1.4版本开始,PDFFileElf.to_image中的**pages**设置为“[ ]”(空列表),表示全量输出,即把整个PDF文件的每一页都输出为图片。
> 
> - 自v0.1.5版本开始,支持PDFFileElf.merge
> 
> - 自v0.1.6版本开始,支持PDFFileElf.remove和PDFFileElf.extract_images
> 
> - 自v0.1.13版本开始,支持PDFFileElf.remove_watermark、PDFFileElf.extract_fonts
> 
> - 自v0.2.1版本开始,支持支持PDFFileElf.rotate_pages。
> 
> 对于PDFFileElf.extract_images的*pages*配置,若为空list,即"**\[ \]**",表示对整个文件的图片进行提取。
> 

## CSVFileElf

CSV文件精灵用于日常对*csv*文件的处理应用。相关方法如下:

* **add**:将*tags*下定义的*csv*文件,按照*key*进行匹配,补充相关字段到*base*的*csv*文件中;对应的配置设定为*add*。
> CSVFileElf.add(input_obj=None, silent: bool = False, **kwargs)
* **join**:将*files*下定义的*csv*文件,拼接到*base*的*csv*文件中;对应的配置设定为*join*。
> CSVFileElf.join(input_obj=None, silent: bool = False, **kwargs)
* **exclude**:根据*exclusion*下定义的条件(*op*支持的操作有:'=', '!=', '>', '>=', '<=', '<'),对*input*的*csv*文件内容进行剔除处理;对应的配置设定为*exclude*。
> CSVFileElf.exclude(input_obj=None, silent: bool = False, **kwargs)
* **filter**:根据*filters*下定义的条件(*op*支持的操作有:'=', '!=', '>', '>=', '<=', '<'),对*input*的*csv*文件内容进行筛选处理;对应的配置设定为*filter*。
> CSVFileElf.filter(input_obj=None, silent: bool = False, **kwargs)
* **split**:根据*key*对*input*的*csv*文件进行拆解处理;对应的配置设定为*split*。
> CSVFileElf.split(input_obj=None, silent: bool = False, **kwargs)
* **merge**:基于*on*对*input*的*csv*文件进行合并处理;对应的配置设定为*merge*。
> CSVFileElf.merge(input_obj=None, silent: bool = False, **kwargs)

配置文件设定如下:

```json
{
    'add': {
        'base': {
            'name': 'base_filename',
            'key': 'key_field',
            'drop_duplicates': False,
        },
        'output': {
            'name': 'output_filename',
            'BOM': False,
            'non-numeric': []
        },
        'tags': [
            {
                'name': 'tags_filename',
                'key': 'key_field',
                'fields': ['field A', 'field B'],
                'defaults': ['default value of field A', 'default value of field B']
            }
        ]
    },
    'join': {
        'base': 'base_filename',
        'output': {
            'name': 'output_filename',
            'BOM': False,
            'non-numeric': []
        },
        'files': [
            {
                'name': 'join_filename',
                'mappings': {}
            }
        ]
    },
    'exclude': {
        'input': 'input_filename',
        'exclusion': [
            {
                'key': 'field',
                'op': '=',
                'value': 123
            }
        ],
        'output': {
            'name': 'output_filename',
            'BOM': False,
            'non-numeric': []
        }
    },
    'filter': {
        'input': 'input_filename',
        'filters': [
            {
                'key': 'field',
                'op': '=',
                'value': 123
            }
        ],
        'output': {
            'name': 'output_filename',
            'BOM': False,
            'non-numeric': []
        }
    },
    'split': {
        'input': 'input_filename',
        'output': {
            'prefix': 'output_filename_prefix',
            'BOM': False,
            'non-numeric': []
        },
        'key': 'key_field'
    },
    'merge': {
        'input': ['input_filename_01', 'input_filename_02'],
        'output': {
            'name': 'output_filename',
            'BOM': False,
            'non-numeric': []
        },
        'on': ['field_name'],
        'mappings': {}
    }
}
```

对于输出*output*配置,如果需要输出*BOM*格式,请把*BOM*设置为*True*;若有一些字段需要表达为非数字类字段,以便于在Excel中打开处理的话,请在*non-numeric*中设置需要处理的相关字段。

> 自v0.1.7版本开始,支持CSVFileElf.merge
> 

### CSVFileElf的处理案例参考

<img src="http://krixtam.com/img/it/dfelf/wm_add.png">

<img src="http://krixtam.com/img/it/dfelf/wm_join_01.png">

<img src="http://krixtam.com/img/it/dfelf/wm_join_02.png">

<img src="http://krixtam.com/img/it/dfelf/wm_exclude.png">

<img src="http://krixtam.com/img/it/dfelf/wm_filter.png">

<img src="http://krixtam.com/img/it/dfelf/wm_split.png">

<img src="http://krixtam.com/img/it/dfelf/wm_merge.png">

## ImageFileElf

Image文件精灵用于日常对图片类文件的处理应用。相关方法如下:

* **to_favicon**:把图片转化为favicon;对应的配置设定为*favicon*。
> ImageFileElf.to_favicon(input_obj=None, silent: bool = False, **kwargs)
* **splice**:将*input*中的图片文件拼接为一张图片;对应的配置设定为*splice*。
> ImageFileElf.splice(input_obj: list = None, silent: bool = False, **kwargs)
* **watermark**:在指定的*x*、*y*坐标中增加水印文字;对应的配置设定为*watermark*。
> ImageFileElf.watermark(input_obj=None, silent: bool = False, **kwargs)
* **qrcode**:将*input*的字符串生成二维码;对应的配置设定为*qrcode*。
> ImageFileElf.qrcode(input_obj: str = None, silent: bool = False, **kwargs)
* **decode_qrcode**:将*input*的二维码图片解析成字符串,并返回;对应的配置设定为*dqrcode*。
> ImageFileElf.decode_qrcode(input_obj=None, **kwargs)
* **to_base64**:将*input*的图片转化为base64字符串,并返回;对应的配置设定为*2base64*。
> ImageFileElf.to_base64(input_obj: bytes = None, **kwargs)
* **from_base64**:将*input*的base64字符串转化为图片;对应的配置设定为*base64*。
> ImageFileElf.from_base64(input_obj: str = None, silent: bool = False, **kwargs)
* **resize**:将*input*的图片调整尺寸后输出到*output*;对应的配置设定为*resize*。
> ImageFileElf.resize(input_obj=None, silent: bool = False, **kwargs)
* **crop**:将*input*的图片按照*loaction*裁剪后输出到*output*;对应的配置设定为*crop*。当*mode*为**0**时,*location*为**left, top, right, bottom**构成的数组;当*mode*为**1**时,*location*为**left, top, width, right**构成的数组。
> ImageFileElf.crop(input_obj=None,  silent: bool = False, **kwargs)
* **fill**:将*input*的图片中*loaction*的指定区域进行马赛克或者单色填充后输出到*output*;对应的配置设定为*fill*。当*mode*为**0**时,*location*为**left, top, right, bottom**构成的数组;当*mode*为**1**时,*location*为**left, top, width, right**构成的数组。*type*为填充方式,**M**或**m**表示马赛克填充,单色填充可以用*#8012de*指定到**type**中实现。
> ImageFileElf.fill(input_obj: np.ndarray = None, silent: bool = False, **kwargs)

配置文件设定如下:

```json
{
    'favicon': {
        'size': -1,
        'input': 'input_filename'
    },
    'splice': {
        'output': 'output_filename',
        'input': [],
        'width': 700,
        'gap': 5,
        'color': '#ffffff',
        'mode': 'v'
    },
    'watermark': {
        'input': 'input_filename',
        'output': 'output_filename',
        'text': 'Krix.Tam',
        'color': 'FFFFFF',
        'font': 'arial.ttf',
        'font_size': 24,
        'x': 5,
        'y': 5,
        'alpha': 50
    },
    '2base64': {
        'input': 'input_filename',
        'css_format': False
    },
    'base64': {
        'input': 'base64 string',
        'output': 'output_filename'
    },
    'qrcode': {
        'input': 'string',
        'output': 'output_filename',
        'border': 2,
        'fill_color': "#000000",
        'back_color': "#FFFFFF"
    },
    'dqrcode': {
        'input': 'input_filename'
    },
    'resize': {
        'input': 'input_filename',
        'output': 'output_filename',
        'scale': False,
        'width': 28,
        'height': 28,
        'quality': 100,
        'dpi': 1200
    },
    'crop': {
        'input': 'input_filename',
        'output': 'output_filename',
        'mode': 0,
        'location': [0, 0, 5, 5]
    },
    'fill': {
        'input': 'input_filename',
        'output': 'output_filename',
        'mode': 0,
        'location': [0, 0, 5, 5],
        'unit': 5,
        'type': 'M'
    }
}
```

> - 自v0.1.3版本开始,有如下变更:
> 
>   - ImageFileElf.watermark对*color*参数支持值为"**auto**"的设定,表示由程序自动选择水印颜色;颜色选择方法为水印所在位置(*x, y*)区域高频使用颜色的反转颜色。
> 
>   - ImageFileElf.splice支持水平拼接(设置*mode*参数为"**H**"或"**h**",默认为垂直拼接,即*mode*参数为"**v**"或"**V**")。
> 
> - 自v0.1.4版本开始,支持ImageFileElf.crop、ImageFileElf.fill
> 
> - 自v0.1.6版本开始,ImageFileElf.splice有如下调整:
>
>   - 原配置项*images*调整为*input*,即使用与其他方法保持一致的输入配置项名称
> 
>   - 配置项*mode*除了支持水平(h或H)、垂直(v或V)外,新增自动模式,即自动水平(ah,不区分大小写)、自动垂直(av,不区分大小写)的拼接模式,此时参数*width*将会被忽略。
> 
> - 自v0.1.11版本开始,ImageFileElf.splice配置项*mode*新增:按照图片最小宽度自动垂直(xv,不区分大小写)或按照最小高度进行自动水平(xh,不区分大小写)的拼接模式,此时参数*width*将会被忽略。
> 
> - 自v0.1.12版本开始,ImageFileElf.splice新增配置项*color*,表示边框颜色,默认值为白色。
>

## 示例

```python
import os
from dfelf import CSVFileElf

df_elf = CSVFileElf()
config = {
    'base': {
        'name': os.path.join('sources', 'df1.csv'),
        'key': 'key'
    },
    'output': {
        'name': 'test_add.csv'
    },
    'tags': [
        {
            'name': os.path.join('sources', 'df3.csv'),
            'key': 'key',
            'fields': ['new_value'],
            'defaults': ['0.0']
        }
    ]
}
df_elf.add(**config)
```

下面的代码在v0.1.0版本开始,可以获得与上面代码同样的结果:

```python
import os
import pandas as pd
from dfelf import CSVFileElf

df_elf = CSVFileElf()
config = {
    'base': {
        'key': 'key'
    },
    'output': {
        'name': 'test_add.csv'
    },
    'tags': [
        {
            'name': os.path.join('sources', 'df3.csv'),
            'key': 'key',
            'fields': ['new_value'],
            'defaults': ['0.0']
        }
    ]
}
input_df = pd.read_csv(os.path.join('sources', 'df1.csv'), dtype=str)
df_elf.add(input_df, **config)
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/KrixTam/dfelf",
    "name": "dfelf",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": null,
    "author": "Krix Tam",
    "author_email": "krix.tam@qq.com",
    "download_url": null,
    "platform": null,
    "description": "# dfelf\n\n\u7531\u4e8e\u65e5\u5e38\u5de5\u4f5c\u9700\u8981\uff08\u6709\u65f6\u5019\u8fd8\u6709\u5199blog\u7684\u9700\u8981\uff09\uff0c\u603b\u662f\u8981\u5904\u7406\u4e00\u4e9b\u6570\u636e\u6587\u4ef6\uff0c\u5f88\u591a\u7e41\u7410\u7684\u5de5\u4f5c\u5e0c\u671b\u53ef\u4ee5\u6709\u4e00\u4e2a\u6587\u4ef6\u7cbe\u7075\u6765\u5e2e\u6211\u5904\u7406\uff0c\u6240\u4ee5\u5c31\u628a\u8fc7\u53bb\u5199\u7684\u5c0f\u5de5\u5177\u91cd\u65b0\u6574\u7406\u4e0b\uff0c\u5f62\u6210\u201c\u6570\u636e\u6587\u4ef6\u7cbe\u7075\u201d\uff08\u201cdfelf\u201d\uff09\u3002\n\n\u201cdfelf\u201d\u4e3a\u201cData File Elf\u201d\u7684\u7f29\u5199\u3002\n\n\u56e0\u4e3a\u65e5\u5e38\u603b\u662f\u9700\u8981\u5904\u7406\u5982\u4e0b\u6587\u4ef6\uff1a\n* PDF\n* CSV\n* \u56fe\u7247\n\n\u6240\u4ee5\u6570\u636e\u6587\u4ef6\u7cbe\u7075\u521d\u6b65\u8bbe\u8ba1\u53ef\u4ee5\u652f\u6301\u4ee5\u4e0a\u4e09\u7c7b\u6587\u4ef6\u7684\u65e5\u5e38\u5904\u7406\u9700\u8981\u3002\n\n\u81eav0.1.4\u7248\u672c\u5f00\u59cb\u652f\u6301*silent\u6a21\u5f0f*\uff0c\u5373\u4e0d\u8fdb\u884cIO\u5904\u7406\u3001\u4e0d\u8f93\u51fa\u6587\u4ef6\uff0c\u76f8\u5173\u65b9\u6cd5\u4e2d\u589e\u52a0*silent*\u53c2\u6570\uff0c\u9ed8\u8ba4\u503c\u4e3a*False*\u3002\n\n## \u5b89\u88c5\n\n> conda install -c conda-forge poppler\n> \n> pip install --upgrade dfelf\n\n## PDFFileElf\n\nPDF\u6587\u4ef6\u7cbe\u7075\u7528\u4e8e\u65e5\u5e38\u5bf9*pdf*\u6587\u4ef6\u7684\u5904\u7406\u5e94\u7528\u3002\u76f8\u5173\u65b9\u6cd5\u5982\u4e0b\uff1a\n\n* **create**\uff1a\u62bd\u53d6\u4e00\u4e2a\u6216\u591a\u4e2aPDF\u6587\u4ef6\u4e2d\u76f8\u5173\u9875\u91cd\u65b0\u6392\u5217\u7ec4\u5408\u6210\u4e00\u4e2a\u65b0\u7684PDF\u6587\u4ef6\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*create*\u3002\n> PDFFileElf.create(input_obj=None, silent: bool = False, **kwargs)\n* **image2pdf**\uff1a\u5c06\u56fe\u7247\u6587\u4ef6\u62fc\u63a5\u6210\u4e00\u4e2aPDF\u6587\u4ef6\uff0c\u6bcf\u4e2a\u56fe\u7247\u4e3a\u4e00\u9875\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*image2pdf*\u3002\n> PDFFileElf.image2pdf(input_obj: list = None, silent: bool = False, **kwargs)\n* **to_image**\uff1a\u5c06PDF\u6587\u4ef6\u76f8\u5173\u9875\u8f93\u51fa\u6210\u56fe\u7247\uff0c\u6bcf\u4e00\u9875\u4e3a\u4e00\u4e2a\u56fe\u7247\uff0c\u4ee5\u9875\u7801\u4e3a\u6587\u4ef6\u540e\u7eed\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*2image*\u3002\n> PDFFileElf.to_image(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)\n* **remove**\uff1a\u5c06PDF\u6587\u4ef6\u4e2d\u6307\u5b9a\u7684\u9875\u9762\u5220\u9664\u540e\u8f93\u51faPDF\u6587\u4ef6\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*remove*\u3002\n> PDFFileElf.remove(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)\n* **extract_images**\uff1a\u5c06PDF\u6587\u4ef6\u4e2d\u6307\u5b9a\u7684\u9875\u9762\u6216\u6574\u4e2aPDF\u6587\u4ef6\uff08\u5f53*pages*\u914d\u7f6e\u4e3a\u7a7a*list*\u65f6\uff0c\u8868\u793a\u6574\u4e2aPDF\u6587\u4ef6\uff09\u7684\u56fe\u7247\u8fdb\u884c\u63d0\u53d6\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*extract_images*\u3002\n> PDFFileElf.extract_images(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)\n* **extract_fonts**\uff1a\u5c06PDF\u6587\u4ef6\u4e2d\u7684\u5b57\u4f53\u5bfc\u51fa\u5230\u6307\u5b9a\u7684*output*\u76ee\u5f55\u4e2d\u3002\n> PDFFileElf.extract_fonts(input_obj=None, silent: bool = False, **kwargs)\n* **rotate_pages**\uff1a\u5c06PDF\u6587\u4ef6\u4e2d\u6307\u5b9a\u7684\u9875\u9762\u8fdb\u884c\u987a\u65f6\u9488\u65cb\u8f6c\u5904\u7406\u540e\uff0c\u628a\u5904\u7406\u540e\u7684PDF\u8f93\u51fa\u5230\u65b0\u7684PDF\u6587\u4ef6\u4e2d\u3002\n> PDFFileElf.rotate_pages(input_obj: pymupdf.Document = None, silent: bool = False, **kwargs)\n\n\u4ee5\u4e0b\u65b9\u6cd5\u4ece0.2.0\u7248\u672c\u5f00\u59cb\u5e9f\u5f03\uff0c\u6539\u7528**create**\u7edf\u4e00\u5b9e\u73b0\n\n> * **reorganize**\uff1a\u62bd\u53d6PDF\u6587\u4ef6\u4e2d\u76f8\u5173\u9875\u91cd\u65b0\u6392\u5217\u7ec4\u5408\u6210\u4e00\u4e2a\u65b0\u7684PDF\u6587\u4ef6\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*reorganize*\u3002\n> PDFFileElf.reorganize(input_obj=None, silent: bool = False, **kwargs)\n> * **merge**\uff1a\u5c06PDF\u6587\u4ef6\u6309\u987a\u5e8f\u5408\u5e76\u4e3a\u4e00\u4e2aPDF\u6587\u4ef6\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*merge*\u3002\n> PDFFileElf.merge(input_obj: list = None, silent: bool = False, **kwargs)\n\n\u53e6\u5916\uff0cremove_watermark\u672a\u5b8c\u5584\uff0c0.2.0\u7248\u672c\u5f00\u59cb\u6682\u65f6\u4e0d\u63d0\u4f9b\u670d\u52a1\n\n> * **remove_watermark**\uff1a\u5c06PDF\u6587\u4ef6\u4e2d\u6307\u5b9a\u7684\u6c34\u5370\u6587\u672c\u5173\u952e\u8bcd\u6240\u5728\u7684\u533a\u57df\u6587\u672c\u6e05\u9664\u3002\n> PDFFileElf.remove_watermark(input_obj=None, silent: bool = False, **kwargs)\n\n\u914d\u7f6e\u6587\u4ef6\u8bbe\u5b9a\u5982\u4e0b\uff1a\n\n```json\n{\n    \"create\": {\n        \"input\": [\n            {\n                \"file\": \"input_filename_01\",\n                \"pages\": []\n            },\n            {\n                \"file\": \"input_filename_02\",\n                \"pages\": []\n            }\n        ],\n        \"output\": \"output_filename\"\n    },\n    \"image2pdf\": {\n        \"images\": [],\n        \"output\": \"output_filename\"\n    },\n    \"to_image\": {\n        \"input\": \"input_filename\",\n        \"output\": \"output_filename_prefix\",\n        \"format\": \"png\",\n        \"dpi\": 200,\n        \"pages\": [\n            1\n        ]\n    },\n    \"remove\": {\n        \"input\": \"input_filename\",\n        \"output\": \"output_filename\",\n        \"pages\": [\n            1\n        ]\n    },\n    \"extract_images\": {\n        \"input\": \"input_filename\",\n        \"output\": \"output_filename_prefix\",\n        \"pages\": [\n            1\n        ]\n    },\n    \"remove_watermark\": {\n        \"input\": \"input_filename\",\n        \"output\": \"output_filename\",\n        \"keywords\": []\n    },\n    \"extract_fonts\": {\n        \"input\": \"input_filename\",\n        \"output\": \"output_directory\"\n    },\n    \"rotate_pages\": {\n        \"input\": \"input_filename\",\n        \"output\": \"output_filename\",\n        \"pages\": [\n            \"1|90\"\n        ]\n    }\n}\n```\n\n> - \u81eav0.1.4\u7248\u672c\u5f00\u59cb\uff0cPDFFileElf.to_image\u4e2d\u7684**pages**\u8bbe\u7f6e\u4e3a\u201c&#91; &#93;\u201d\uff08\u7a7a\u5217\u8868\uff09\uff0c\u8868\u793a\u5168\u91cf\u8f93\u51fa\uff0c\u5373\u628a\u6574\u4e2aPDF\u6587\u4ef6\u7684\u6bcf\u4e00\u9875\u90fd\u8f93\u51fa\u4e3a\u56fe\u7247\u3002\n> \n> - \u81eav0.1.5\u7248\u672c\u5f00\u59cb\uff0c\u652f\u6301PDFFileElf.merge\n> \n> - \u81eav0.1.6\u7248\u672c\u5f00\u59cb\uff0c\u652f\u6301PDFFileElf.remove\u548cPDFFileElf.extract_images\n> \n> - \u81eav0.1.13\u7248\u672c\u5f00\u59cb\uff0c\u652f\u6301PDFFileElf.remove_watermark\u3001PDFFileElf.extract_fonts\n> \n> - \u81eav0.2.1\u7248\u672c\u5f00\u59cb\uff0c\u652f\u6301\u652f\u6301PDFFileElf.rotate_pages\u3002\n> \n> \u5bf9\u4e8ePDFFileElf.extract_images\u7684*pages*\u914d\u7f6e\uff0c\u82e5\u4e3a\u7a7alist\uff0c\u5373\"**\\[ \\]**\"\uff0c\u8868\u793a\u5bf9\u6574\u4e2a\u6587\u4ef6\u7684\u56fe\u7247\u8fdb\u884c\u63d0\u53d6\u3002\n> \n\n## CSVFileElf\n\nCSV\u6587\u4ef6\u7cbe\u7075\u7528\u4e8e\u65e5\u5e38\u5bf9*csv*\u6587\u4ef6\u7684\u5904\u7406\u5e94\u7528\u3002\u76f8\u5173\u65b9\u6cd5\u5982\u4e0b\uff1a\n\n* **add**\uff1a\u5c06*tags*\u4e0b\u5b9a\u4e49\u7684*csv*\u6587\u4ef6\uff0c\u6309\u7167*key*\u8fdb\u884c\u5339\u914d\uff0c\u8865\u5145\u76f8\u5173\u5b57\u6bb5\u5230*base*\u7684*csv*\u6587\u4ef6\u4e2d\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*add*\u3002\n> CSVFileElf.add(input_obj=None, silent: bool = False, **kwargs)\n* **join**\uff1a\u5c06*files*\u4e0b\u5b9a\u4e49\u7684*csv*\u6587\u4ef6\uff0c\u62fc\u63a5\u5230*base*\u7684*csv*\u6587\u4ef6\u4e2d\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*join*\u3002\n> CSVFileElf.join(input_obj=None, silent: bool = False, **kwargs)\n* **exclude**\uff1a\u6839\u636e*exclusion*\u4e0b\u5b9a\u4e49\u7684\u6761\u4ef6\uff08*op*\u652f\u6301\u7684\u64cd\u4f5c\u6709\uff1a'=', '!=', '>', '>=', '<=', '<'\uff09\uff0c\u5bf9*input*\u7684*csv*\u6587\u4ef6\u5185\u5bb9\u8fdb\u884c\u5254\u9664\u5904\u7406\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*exclude*\u3002\n> CSVFileElf.exclude(input_obj=None, silent: bool = False, **kwargs)\n* **filter**\uff1a\u6839\u636e*filters*\u4e0b\u5b9a\u4e49\u7684\u6761\u4ef6\uff08*op*\u652f\u6301\u7684\u64cd\u4f5c\u6709\uff1a'=', '!=', '>', '>=', '<=', '<'\uff09\uff0c\u5bf9*input*\u7684*csv*\u6587\u4ef6\u5185\u5bb9\u8fdb\u884c\u7b5b\u9009\u5904\u7406\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*filter*\u3002\n> CSVFileElf.filter(input_obj=None, silent: bool = False, **kwargs)\n* **split**\uff1a\u6839\u636e*key*\u5bf9*input*\u7684*csv*\u6587\u4ef6\u8fdb\u884c\u62c6\u89e3\u5904\u7406\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*split*\u3002\n> CSVFileElf.split(input_obj=None, silent: bool = False, **kwargs)\n* **merge**\uff1a\u57fa\u4e8e*on*\u5bf9*input*\u7684*csv*\u6587\u4ef6\u8fdb\u884c\u5408\u5e76\u5904\u7406\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*merge*\u3002\n> CSVFileElf.merge(input_obj=None, silent: bool = False, **kwargs)\n\n\u914d\u7f6e\u6587\u4ef6\u8bbe\u5b9a\u5982\u4e0b\uff1a\n\n```json\n{\n    'add': {\n        'base': {\n            'name': 'base_filename',\n            'key': 'key_field',\n            'drop_duplicates': False,\n        },\n        'output': {\n            'name': 'output_filename',\n            'BOM': False,\n            'non-numeric': []\n        },\n        'tags': [\n            {\n                'name': 'tags_filename',\n                'key': 'key_field',\n                'fields': ['field A', 'field B'],\n                'defaults': ['default value of field A', 'default value of field B']\n            }\n        ]\n    },\n    'join': {\n        'base': 'base_filename',\n        'output': {\n            'name': 'output_filename',\n            'BOM': False,\n            'non-numeric': []\n        },\n        'files': [\n            {\n                'name': 'join_filename',\n                'mappings': {}\n            }\n        ]\n    },\n    'exclude': {\n        'input': 'input_filename',\n        'exclusion': [\n            {\n                'key': 'field',\n                'op': '=',\n                'value': 123\n            }\n        ],\n        'output': {\n            'name': 'output_filename',\n            'BOM': False,\n            'non-numeric': []\n        }\n    },\n    'filter': {\n        'input': 'input_filename',\n        'filters': [\n            {\n                'key': 'field',\n                'op': '=',\n                'value': 123\n            }\n        ],\n        'output': {\n            'name': 'output_filename',\n            'BOM': False,\n            'non-numeric': []\n        }\n    },\n    'split': {\n        'input': 'input_filename',\n        'output': {\n            'prefix': 'output_filename_prefix',\n            'BOM': False,\n            'non-numeric': []\n        },\n        'key': 'key_field'\n    },\n    'merge': {\n        'input': ['input_filename_01', 'input_filename_02'],\n        'output': {\n            'name': 'output_filename',\n            'BOM': False,\n            'non-numeric': []\n        },\n        'on': ['field_name'],\n        'mappings': {}\n    }\n}\n```\n\n\u5bf9\u4e8e\u8f93\u51fa*output*\u914d\u7f6e\uff0c\u5982\u679c\u9700\u8981\u8f93\u51fa*BOM*\u683c\u5f0f\uff0c\u8bf7\u628a*BOM*\u8bbe\u7f6e\u4e3a*True*\uff1b\u82e5\u6709\u4e00\u4e9b\u5b57\u6bb5\u9700\u8981\u8868\u8fbe\u4e3a\u975e\u6570\u5b57\u7c7b\u5b57\u6bb5\uff0c\u4ee5\u4fbf\u4e8e\u5728Excel\u4e2d\u6253\u5f00\u5904\u7406\u7684\u8bdd\uff0c\u8bf7\u5728*non-numeric*\u4e2d\u8bbe\u7f6e\u9700\u8981\u5904\u7406\u7684\u76f8\u5173\u5b57\u6bb5\u3002\n\n> \u81eav0.1.7\u7248\u672c\u5f00\u59cb\uff0c\u652f\u6301CSVFileElf.merge\n> \n\n### CSVFileElf\u7684\u5904\u7406\u6848\u4f8b\u53c2\u8003\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_add.png\">\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_join_01.png\">\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_join_02.png\">\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_exclude.png\">\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_filter.png\">\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_split.png\">\n\n<img src=\"http://krixtam.com/img/it/dfelf/wm_merge.png\">\n\n## ImageFileElf\n\nImage\u6587\u4ef6\u7cbe\u7075\u7528\u4e8e\u65e5\u5e38\u5bf9\u56fe\u7247\u7c7b\u6587\u4ef6\u7684\u5904\u7406\u5e94\u7528\u3002\u76f8\u5173\u65b9\u6cd5\u5982\u4e0b\uff1a\n\n* **to_favicon**\uff1a\u628a\u56fe\u7247\u8f6c\u5316\u4e3afavicon\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*favicon*\u3002\n> ImageFileElf.to_favicon(input_obj=None, silent: bool = False, **kwargs)\n* **splice**\uff1a\u5c06*input*\u4e2d\u7684\u56fe\u7247\u6587\u4ef6\u62fc\u63a5\u4e3a\u4e00\u5f20\u56fe\u7247\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*splice*\u3002\n> ImageFileElf.splice(input_obj: list = None, silent: bool = False, **kwargs)\n* **watermark**\uff1a\u5728\u6307\u5b9a\u7684*x*\u3001*y*\u5750\u6807\u4e2d\u589e\u52a0\u6c34\u5370\u6587\u5b57\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*watermark*\u3002\n> ImageFileElf.watermark(input_obj=None, silent: bool = False, **kwargs)\n* **qrcode**\uff1a\u5c06*input*\u7684\u5b57\u7b26\u4e32\u751f\u6210\u4e8c\u7ef4\u7801\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*qrcode*\u3002\n> ImageFileElf.qrcode(input_obj: str = None, silent: bool = False, **kwargs)\n* **decode_qrcode**\uff1a\u5c06*input*\u7684\u4e8c\u7ef4\u7801\u56fe\u7247\u89e3\u6790\u6210\u5b57\u7b26\u4e32\uff0c\u5e76\u8fd4\u56de\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*dqrcode*\u3002\n> ImageFileElf.decode_qrcode(input_obj=None, **kwargs)\n* **to_base64**\uff1a\u5c06*input*\u7684\u56fe\u7247\u8f6c\u5316\u4e3abase64\u5b57\u7b26\u4e32\uff0c\u5e76\u8fd4\u56de\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*2base64*\u3002\n> ImageFileElf.to_base64(input_obj: bytes = None, **kwargs)\n* **from_base64**\uff1a\u5c06*input*\u7684base64\u5b57\u7b26\u4e32\u8f6c\u5316\u4e3a\u56fe\u7247\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*base64*\u3002\n> ImageFileElf.from_base64(input_obj: str = None, silent: bool = False, **kwargs)\n* **resize**\uff1a\u5c06*input*\u7684\u56fe\u7247\u8c03\u6574\u5c3a\u5bf8\u540e\u8f93\u51fa\u5230*output*\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*resize*\u3002\n> ImageFileElf.resize(input_obj=None, silent: bool = False, **kwargs)\n* **crop**\uff1a\u5c06*input*\u7684\u56fe\u7247\u6309\u7167*loaction*\u88c1\u526a\u540e\u8f93\u51fa\u5230*output*\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*crop*\u3002\u5f53*mode*\u4e3a**0**\u65f6\uff0c*location*\u4e3a**left, top, right, bottom**\u6784\u6210\u7684\u6570\u7ec4\uff1b\u5f53*mode*\u4e3a**1**\u65f6\uff0c*location*\u4e3a**left, top, width, right**\u6784\u6210\u7684\u6570\u7ec4\u3002\n> ImageFileElf.crop(input_obj=None,  silent: bool = False, **kwargs)\n* **fill**\uff1a\u5c06*input*\u7684\u56fe\u7247\u4e2d*loaction*\u7684\u6307\u5b9a\u533a\u57df\u8fdb\u884c\u9a6c\u8d5b\u514b\u6216\u8005\u5355\u8272\u586b\u5145\u540e\u8f93\u51fa\u5230*output*\uff1b\u5bf9\u5e94\u7684\u914d\u7f6e\u8bbe\u5b9a\u4e3a*fill*\u3002\u5f53*mode*\u4e3a**0**\u65f6\uff0c*location*\u4e3a**left, top, right, bottom**\u6784\u6210\u7684\u6570\u7ec4\uff1b\u5f53*mode*\u4e3a**1**\u65f6\uff0c*location*\u4e3a**left, top, width, right**\u6784\u6210\u7684\u6570\u7ec4\u3002*type*\u4e3a\u586b\u5145\u65b9\u5f0f\uff0c**M**\u6216**m**\u8868\u793a\u9a6c\u8d5b\u514b\u586b\u5145\uff0c\u5355\u8272\u586b\u5145\u53ef\u4ee5\u7528*#8012de*\u6307\u5b9a\u5230**type**\u4e2d\u5b9e\u73b0\u3002\n> ImageFileElf.fill(input_obj: np.ndarray = None, silent: bool = False, **kwargs)\n\n\u914d\u7f6e\u6587\u4ef6\u8bbe\u5b9a\u5982\u4e0b\uff1a\n\n```json\n{\n    'favicon': {\n        'size': -1,\n        'input': 'input_filename'\n    },\n    'splice': {\n        'output': 'output_filename',\n        'input': [],\n        'width': 700,\n        'gap': 5,\n        'color': '#ffffff',\n        'mode': 'v'\n    },\n    'watermark': {\n        'input': 'input_filename',\n        'output': 'output_filename',\n        'text': 'Krix.Tam',\n        'color': 'FFFFFF',\n        'font': 'arial.ttf',\n        'font_size': 24,\n        'x': 5,\n        'y': 5,\n        'alpha': 50\n    },\n    '2base64': {\n        'input': 'input_filename',\n        'css_format': False\n    },\n    'base64': {\n        'input': 'base64 string',\n        'output': 'output_filename'\n    },\n    'qrcode': {\n        'input': 'string',\n        'output': 'output_filename',\n        'border': 2,\n        'fill_color': \"#000000\",\n        'back_color': \"#FFFFFF\"\n    },\n    'dqrcode': {\n        'input': 'input_filename'\n    },\n    'resize': {\n        'input': 'input_filename',\n        'output': 'output_filename',\n        'scale': False,\n        'width': 28,\n        'height': 28,\n        'quality': 100,\n        'dpi': 1200\n    },\n    'crop': {\n        'input': 'input_filename',\n        'output': 'output_filename',\n        'mode': 0,\n        'location': [0, 0, 5, 5]\n    },\n    'fill': {\n        'input': 'input_filename',\n        'output': 'output_filename',\n        'mode': 0,\n        'location': [0, 0, 5, 5],\n        'unit': 5,\n        'type': 'M'\n    }\n}\n```\n\n> - \u81eav0.1.3\u7248\u672c\u5f00\u59cb\uff0c\u6709\u5982\u4e0b\u53d8\u66f4\uff1a\n> \n>   - ImageFileElf.watermark\u5bf9*color*\u53c2\u6570\u652f\u6301\u503c\u4e3a\"**auto**\"\u7684\u8bbe\u5b9a\uff0c\u8868\u793a\u7531\u7a0b\u5e8f\u81ea\u52a8\u9009\u62e9\u6c34\u5370\u989c\u8272\uff1b\u989c\u8272\u9009\u62e9\u65b9\u6cd5\u4e3a\u6c34\u5370\u6240\u5728\u4f4d\u7f6e(*x, y*)\u533a\u57df\u9ad8\u9891\u4f7f\u7528\u989c\u8272\u7684\u53cd\u8f6c\u989c\u8272\u3002\n> \n>   - ImageFileElf.splice\u652f\u6301\u6c34\u5e73\u62fc\u63a5\uff08\u8bbe\u7f6e*mode*\u53c2\u6570\u4e3a\"**H**\"\u6216\"**h**\"\uff0c\u9ed8\u8ba4\u4e3a\u5782\u76f4\u62fc\u63a5\uff0c\u5373*mode*\u53c2\u6570\u4e3a\"**v**\"\u6216\"**V**\"\uff09\u3002\n> \n> - \u81eav0.1.4\u7248\u672c\u5f00\u59cb\uff0c\u652f\u6301ImageFileElf.crop\u3001ImageFileElf.fill\n> \n> - \u81eav0.1.6\u7248\u672c\u5f00\u59cb\uff0cImageFileElf.splice\u6709\u5982\u4e0b\u8c03\u6574\uff1a\n>\n>   - \u539f\u914d\u7f6e\u9879*images*\u8c03\u6574\u4e3a*input*\uff0c\u5373\u4f7f\u7528\u4e0e\u5176\u4ed6\u65b9\u6cd5\u4fdd\u6301\u4e00\u81f4\u7684\u8f93\u5165\u914d\u7f6e\u9879\u540d\u79f0\n> \n>   - \u914d\u7f6e\u9879*mode*\u9664\u4e86\u652f\u6301\u6c34\u5e73\uff08h\u6216H\uff09\u3001\u5782\u76f4\uff08v\u6216V\uff09\u5916\uff0c\u65b0\u589e\u81ea\u52a8\u6a21\u5f0f\uff0c\u5373\u81ea\u52a8\u6c34\u5e73\uff08ah\uff0c\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u3001\u81ea\u52a8\u5782\u76f4\uff08av\uff0c\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u7684\u62fc\u63a5\u6a21\u5f0f\uff0c\u6b64\u65f6\u53c2\u6570*width*\u5c06\u4f1a\u88ab\u5ffd\u7565\u3002\n> \n> - \u81eav0.1.11\u7248\u672c\u5f00\u59cb\uff0cImageFileElf.splice\u914d\u7f6e\u9879*mode*\u65b0\u589e\uff1a\u6309\u7167\u56fe\u7247\u6700\u5c0f\u5bbd\u5ea6\u81ea\u52a8\u5782\u76f4\uff08xv\uff0c\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u6216\u6309\u7167\u6700\u5c0f\u9ad8\u5ea6\u8fdb\u884c\u81ea\u52a8\u6c34\u5e73\uff08xh\uff0c\u4e0d\u533a\u5206\u5927\u5c0f\u5199\uff09\u7684\u62fc\u63a5\u6a21\u5f0f\uff0c\u6b64\u65f6\u53c2\u6570*width*\u5c06\u4f1a\u88ab\u5ffd\u7565\u3002\n> \n> - \u81eav0.1.12\u7248\u672c\u5f00\u59cb\uff0cImageFileElf.splice\u65b0\u589e\u914d\u7f6e\u9879*color*\uff0c\u8868\u793a\u8fb9\u6846\u989c\u8272\uff0c\u9ed8\u8ba4\u503c\u4e3a\u767d\u8272\u3002\n>\n\n## \u793a\u4f8b\n\n```python\nimport os\nfrom dfelf import CSVFileElf\n\ndf_elf = CSVFileElf()\nconfig = {\n    'base': {\n        'name': os.path.join('sources', 'df1.csv'),\n        'key': 'key'\n    },\n    'output': {\n        'name': 'test_add.csv'\n    },\n    'tags': [\n        {\n            'name': os.path.join('sources', 'df3.csv'),\n            'key': 'key',\n            'fields': ['new_value'],\n            'defaults': ['0.0']\n        }\n    ]\n}\ndf_elf.add(**config)\n```\n\n\u4e0b\u9762\u7684\u4ee3\u7801\u5728v0.1.0\u7248\u672c\u5f00\u59cb\uff0c\u53ef\u4ee5\u83b7\u5f97\u4e0e\u4e0a\u9762\u4ee3\u7801\u540c\u6837\u7684\u7ed3\u679c\uff1a\n\n```python\nimport os\nimport pandas as pd\nfrom dfelf import CSVFileElf\n\ndf_elf = CSVFileElf()\nconfig = {\n    'base': {\n        'key': 'key'\n    },\n    'output': {\n        'name': 'test_add.csv'\n    },\n    'tags': [\n        {\n            'name': os.path.join('sources', 'df3.csv'),\n            'key': 'key',\n            'fields': ['new_value'],\n            'defaults': ['0.0']\n        }\n    ]\n}\ninput_df = pd.read_csv(os.path.join('sources', 'df1.csv'), dtype=str)\ndf_elf.add(input_df, **config)\n```\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Data File Elf",
    "version": "0.2.1",
    "project_urls": {
        "Bug Tracker": "https://github.com/KrixTam/dfelf/issues",
        "Homepage": "https://github.com/KrixTam/dfelf"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4568e12781cf3a3f8a8ebe69b5c74ec995972995f3d88f3d0ffcb5436b4072d9",
                "md5": "d62ca1751789cb17a9a3eb430f0e2971",
                "sha256": "87c82fd914a18107655a8b8a085e2e5dd756790ccc3021d7fdcf184685a425e2"
            },
            "downloads": -1,
            "filename": "dfelf-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d62ca1751789cb17a9a3eb430f0e2971",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 7366210,
            "upload_time": "2024-09-05T03:43:56",
            "upload_time_iso_8601": "2024-09-05T03:43:56.467577Z",
            "url": "https://files.pythonhosted.org/packages/45/68/e12781cf3a3f8a8ebe69b5c74ec995972995f3d88f3d0ffcb5436b4072d9/dfelf-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-05 03:43:56",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "KrixTam",
    "github_project": "dfelf",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "dfelf"
}
        
Elapsed time: 1.11010s