{ "info": { "author": "Edvard Rejthar", "author_email": "edvard.rejthar@nic.cz", "bugtrack_url": null, "classifiers": [], "description": "# Convey\n\n[![Build Status](https://github.com/CZ-NIC/convey/actions/workflows/run-unittest.yml/badge.svg)](https://github.com/CZ-NIC/convey/actions) [![Downloads](https://pepy.tech/badge/convey)](https://pepy.tech/project/convey)\n\nSwiss knife for mutual conversion of the web related data types, like `base64` or outputs of the programs `whois`, `dig`, `curl`.\nConvenable way to quickly gather all meaningful information or to process large files that might freeze your spreadsheet processor.\n\nAny input is accepted: \n* if a **single value** input is detected, all **meaningful information** is fetched\n* multiline **base64**/**quoted_printable** string gets decoded\n* **log/XLS/XLSX/ODS file** converted to CSV \n* **CSV file** (any delimiter, header or [pandoc](https://pandoc.org/MANUAL.html#tables) table format) performs one or more actions\n 1) **Pick, delete or sort columns** (if only some columns are needed)\n 2) **Add a column** (computes one field from another \u2013 see below)\n 3) **Filter** (keep/discard rows with specific values, no duplicates) \n 4) **Split by a column** (produce separate files instead of single file; these can then be sent by generic SMTP or through OTRS)\n 5) **Change CSV dialect** (change delimiter or quoting character, remove header)\n 6) **Aggregate** (count grouped by a column, sum...)\n\nPython3.6+ required.\n\n# Table of contents\n* [Usage](#usage)\n + [Usage 1 \u2013 Single query](#usage-1--single-query)\n + [Usage 2 \u2013 CSV processor program](#usage-2--csv-processor-program)\n + [Usage 3 \u2013 Web service](#usage-3--web-service)\n* [Installation and first run](#installation-and-first-run)\n + [Prerequisities](#prerequisities)\n + [Launch as a package](#launch-as-a-package)\n + [OR launch from a directory](#or-launch-from-a-directory)\n + [Bash completion](#bash-completion)\n + [Customisation](#customisation)\n* [Computing fields](#computing-fields)\n + [Computable fields](#computable-fields)\n - [Whois module](#whois-module)\n + [Detectable fields](#detectable-fields)\n + [Overview of all methods](#overview-of-all-methods)\n + [External field how-to](#external-field-how-to)\n - [Simple custom method](#simple-custom-method)\n * [Launch an external method](#launch-an-external-method)\n * [Register an external method](#register-an-external-method)\n - [List of results possible](#list-of-results-possible)\n - [PickMethod decorator](#pickmethod-decorator)\n - [PickInput decorator](#pickinput-decorator)\n* [Web service](#web-service)\n* [Sending files](#sending-files)\n + [Arbitrary e-mail headers, \"From\" header, GPG signing](#arbitrary-e-mail-headers-from-header-gpg-signing)\n + [Dynamic templates](#dynamic-templates)\n* [Examples](#examples)\n + [URL parsing](#url-parsing)\n - [Output formats](#output-formats)\n - [Computing TLD from another column](#computing-tld-from-another-column)\n - [CSV processing](#csv-processing)\n - [File splitting](#file-splitting)\n - [CSIRT Usecase](#csirt-usecase)\n + [Custom code field](#custom-code-field)\n + [Base64 and Regular expressions](#base64-and-regular-expressions)\n + [Converting units](#converting-units)\n + [Aggregate](#aggregate)\n* [Credits](#credits)\n\n\n## Usage\n\n### Usage 1 \u2013 Single query\nCheck what happens if an IP is provided, it returns table with WHOIS-related information and scraped HTTP content.\n```bash\n$ convey 1.1.1.1 # single query input\nInput value detected: ip\n\n1.1.1.1 ...au\n\nfield value\n---------------- -----------------\nprefix 1.1.1.0-1.1.1.255\nasn as13335\nabusemail abuse@apnic.net\ncountry au\nnetname apnic-labs\ncsirt-contact -\nincident-contact au\nstatus 200\ntext DNSThe free app that makes your (much longer text...)\n```\n\n### Usage 2 \u2013 CSV processor program\nParses CSV file.\n```bash\n$ convey my-file-with-ips.csv # will trigger file parsing\nSource file: /tmp/my-file.csv\nLog lines: 200\n\nSample:\n...\n\nDelimiter character found: ','\nQuoting character: '\"'\nHeader is present: not used\n\nCould you confirm this? [y]/n\n...\n...\n```\n\n### Usage 3 \u2013 Web service\nAgain, let's provide an IP to the web service, it returns JSON with WHOIS-related information and scraped HTTP content.\n```bash\n$ convey --server # start a UWSGI session\n```\nAccess in the browser: http://localhost:26683/?q=example.com\n```json\n{\"ip\": \"93.184.216.34\", \"prefix\": \"93.184.216.0-93.184.216.255\", \"asn\": \"\", \"abusemail\": \"abuse@verizondigitalmedia.com\", \"country\": \"unknown\", \"netname\": \"edgecast-netblk-03\", \"csirt-contact\": \"-\", \"incident-contact\": \"unknown\", \"status\": 200, \"text\": \"DNSThe free app that makes your (much longer text...)\"}\n```\n\n## Installation and first run\n\n### Prerequisites\n* You'll be asked to install `dialog` library at the first run if not already present in the system.\n* If something is missing on your system, you may find help yourself with this command: \n`sudo apt install python3-pip python3-dev python3-tk git xdg-utils dialog whois dnsutils nmap curl build-essential libssl-dev libpcre3 libpcre3-dev && pip3 install setuptools wheel uwsgi && pip3 install --upgrade ipython`\n * `build-essential` is needed to build `uwsgi` and `envelope`\n * `libpcre3 libpcre3-dev` needed to suppress uWSGI warning `!!! no internal routing support, rebuild with pcre support !!!`\n * `libssl-dev` needed to be present before building `uwsgi` if you will need to use `--https`\n\n### Launch as a package:\n\n```bash\n# (optional) setup virtual environment\npython3 -m venv venv\n. venv/bin/activate\n(venv) $ ... # continue below\n\n# install from PyPi\npip3 install convey # without root use may want to use --user\n\n# (optional) alternatively, you may want to install current master from GitHub\npip3 install git+https://github.com/CZ-NIC/convey.git\n\n# launch\nconvey [filename or input text] # or try `python3 -m convey` if you're not having `.local/bin` in your executable path\n```\n\nParameter `[filename or input text]` may be the path of the CSV source file or any text that should be parsed. Note that if the text consist of a single value, program prints out all the computable information and exits; I.E. inputting a base64 string will decode it.\n\n### OR launch from a directory\n\n```bash\n# download from GitHub\ngit clone git@github.com:CZ-NIC/convey.git\ncd convey\npip3 install -r requirements.txt --user\n\n# launch\n./convey.py\n```\n\n### Bash completion\n1. Run: `apt-get install bash-completion jq`\n2. Copy: [extra/convey-autocompletion.bash](./extra/convey-autocompletion.bash) to `/etc/bash_completion.d/`\n3. Restart terminal\n\n### Customisation\n* Launch convey with [`--help`](docs/convey-help-cmd-output.md) flag to see [further options](docs/convey-help-cmd-output.md).\n* A file [`config.ini`](convey/defaults/config.ini) is automatically created in [user config folder](convey/defaults/config.ini). This file may be edited for further customisation. Access it with `convey --config`.\n> * Convey tries to open the file in the default GUI editor or in the terminal editor if GUI is not an option.\n> * If `config.ini` is present at working directory, that one is used over the one in the user config folder.\n> * Configuration is updated automatically on upgrade. \n\n## Computing fields\n\n### Computable fields\n\nSome field types are directly computable:\n\n* **abusemail** \u2013 got abuse e-mail contact from whois\n* **asn** \u2013 got from whois\n* **base64** \u2013 encode/decode\n* **cc_contact** \u2013 e-mail address corresponding with the abusemail, taken from your personal contacts_cc CSV in the format `domain,cc;cc` (mails delimited by a semicolon). Path to this file has to be specified in `config.ini \u00bb contacts_cc`.\n* **country** \u2013 country code from whois\n* **~~csirt_contact~~** \u2013 e-mail address corresponding with country code, taken from your personal contacts_abroad CSV in the format `country,abusemail`. Path to this file has to be specified in `config.ini \u00bb contacts_abroad`\n* **external** \u2013 you specify method in a custom .py file that receives the field and generates the value for you, see below\n* **hostname** \u2013 domain from url\n* **incident_contact** \u2013 if the IP comes from local country (specified in `config.ini \u00bb local_country`) the field gets *abusemail*, otherwise we get *country@@mail* where *mail* is either *abusemail* or abroad country e-mail. When splitting by this field, convey is subsequently able to send the split files to local abuse and foreign csirt contacts.\n* **ip** \u2013 translated from url\n* **netname** \u2013 got from whois\n* **prefix** \u2013 got from whois\n\n#### Whois module\n\nWhen obtaining a WHOIS record\n* We are internally calling `whois` program, detecting what servers were asked.\n* Sometimes you encounter a funny formatted *whois* response. We try to mitigate such cases and **re-ask another registry** in well known cases.\n* Since IP addresses in the same prefix share the same information we cache it to gain **maximal speed** while reducing *whois* queries.\n* Sometimes you encounter an IP that gives no information but asserts its prefix includes a large portion of the address space. All IP addresses in that portion ends labeled as unknowns. At the end of the processing you are **asked to redo unknowns** one by one to complete missing information, flushing misleading superset from the cache. \n* You may easily hit **LACNIC query rate** quota. In that case, we re-queue such lines to be queried after the quota is over if possible. At the end of the processing, you will get asked whether you wish to carefully and slowly reprocess the lines awaiting the quota lift.\n\n### Detectable fields\n\nSome of the field types we are able to auto-detect: \n\n* **ip** \u2013 standard IPv4 / IPv6 addresses\n* **cidr** \u2013 CIDR notation, ex: 127.0.0.1/32\n* **port_ip** \u2013 IPv4 in the form 1.2.3.4.port\n* **any_ip** \u2013 IPv4 garbled in the form `any text 1.2.3.4 any text`\n* **hostname** \u2013 or FQDN; 2nd or 3rd domain name\n* **url** \u2013 URL starting with http/https\n* **asn** \u2013 AS Number\n* **base64** \u2013 text encoded with base64\n* **wrong_url** \u2013 URL that has been deactivated by replacing certain chars, ex: \"hxxp://example[.]com\"\n\n### Overview of all methods\n\nCurrent field computing capacity can be get from `--show-uml` flag. Generate yours by ex: `convey --show-uml | dot -Tsvg -o /tmp/convey-methods.svg`\n\n* Dashed node: field type is auto-detectable\n* Dashed edge: field types are identical\n* Edge label: generating options asked at runtime\n* Rectangle: field category border \n\n![Methods overview](./docs/convey-methods.svg?sanitize=True)\n\n \n\n### External field how-to\n#### Simple custom method\nIf you wish to compute an **external** field, prepare a file whose contents can be as simple as this:\n\n```python3\ndef any_method(value):\n # do something\n return \"modified :)\"\n```\n\n##### Launch an external method\n* When CSV processing, hit *'Add column'* and choose *'new external... from a method in your. py file'*\n* Or in the terminal append `--field external` to your `convey` command. A dialog for a path of the Python file and desired method will appear.\n```bash\n$ convey [string_or_filepath] --field external \n```\n* You may as well directly specify the path and the callable. Since the `--field` has following syntax: \n> *FIELD[[CUSTOM]],[COLUMN],[SOURCE_TYPE],[CUSTOM],[CUSTOM]*\n \nYou may omit both *COLUMN* and *SOURCE_TYPE* writing it this way:\n \n> *FIELD,~~COLUMN,SOURCE_TYPE~~,CUSTOM,CUSTOM* \n> external,/tmp/myfile.py,any_method\n```bash\n$ convey [string_or_filepath] --field external,/tmp/myfile.py,any_method\nInput value seems to be plaintext.\nfield value\n-------- -----------------------\nexternal modified :)\n```\n\n##### Register an external method\n* You may as well hard code custom fields in the [`config.ini`](convey/config.ini.default) by providing paths to the entry point Python files delimited by a comma: `external_fields = /tmp/myfile.py, /tmp/anotherfile.py`. All the public methods in the defined files will become custom fields!\n```editorconfig\n[EXTERNAL]\nexternal_fields = /tmp/myfile.py\n```\n* If this is not needed, you may register one by one by adding new items to the `EXTERNAL` section. Delimit the method name by a colon.\n```editorconfig\n[EXTERNAL]\nany_method = /tmp/myfile.py:any_method\n```\n\n#### List of results possible\nIf you need a single call to generate multiple rows, return list, the row accepting a list will be duplicated.\n\n```python3\ndef any_method(value):\n # do something\n return [\"foo\", \"bar\"]\n```\n\nWhen convey receives multiple lists, it generates a row for each combination. Ex: If a method returns 2 items and another 3 items, you will receive 6 similar rows.\n\n#### PickMethod decorator\nShould there be multiple ways of using your generator, place them as methods of a class decorated with `PickMethod` and let the user decide at the runtime. `PickMethod` has optional `default:str` parameter that specifies the default method.\n\n```python3\nfrom convey import PickMethod\n\n@PickMethod(\"all\")\nclass any_method(PickMethod):\n def all(x):\n ''' All of them. '''\n return x\n \n def filtered(cls, x):\n ''' Filter some of them '''\n if x in country_code_set:\n return x\n```\n\n```bash\n$ convey file.csv --field any_method # user will be asked whether to use `all` or `filtered`\n$ convey file.csv --field any_method[filtered] # `filtered` sub-method will be used\n$ convey file.csv --field any_method --yes # the default `all` sub-method will be used\n```\n\n#### PickInput decorator\nIf you need a direct user entry before each processing, import `PickInput` and make your method accept *two* parameters. The latter will be set by the user and may have a default value.\n\n```python3\nfrom convey import PickInput\nimport dateutil\n\n@PickInput\ndef time_format(val, format=\"%H:%M\"):\n ''' This text will be displayed to the user.\n If running in headless mode, the default format will be \"%H:%M\" (hours:minutes). '''\n return dateutil.parser.parse(val).strftime(format)\n```\n\n```bash\n$ convey file.csv --field time_format # user will be asked for a format parameter\n$ convey file.csv --field time_format[%M] # `format` will have the value `M%`\n$ convey file.csv --field time_time --yes # the default `format` `%H:%M` will be used\n```\n\n## Web service\nWhen launched as a web service, several parameters are available:\n* `q` \u2013 search query\n* `type` \u2013 same as `--type` CLI flag\n* `field` \u2013 same as `--field` CLI flag.\n * Note that unsafe field types `code` and `external` are disabled in web service by default. You may re-allow them in `webservice_allow_unsafe_fields` config option\n * full syntax of CLI flag is supported\n > *FIELD[[CUSTOM]],[COLUMN],[SOURCE_TYPE],[CUSTOM],[CUSTOM]*\n \n Ex: `reg_s,l,L` performs regular substitution of *'l'* by *'L'*\n* `clear=web` \u2013 clears web scrapping module cache\n\nQuick deployment may be realized by a single command:\n```bash\n$ convey --server\n```\n\n* Note that convey must be installed via `pip`\n* Note that LACNIC may freeze for 300 s, hence the timeout recommendation.\n* Note that you may find your convey installation path by launching `pip3 show convey`\n* If you received or [generated](https://uwsgi-docs.readthedocs.io/en/latest/HTTPS.html#https-support-from-1-3) key and certificate, you may turn on HTTPS in `uwsgi.ini` accesible by: `convey --config uwsgi`\n* Internally, flag `--server` launches `wsgi.py` with a UWSGI session.\n ```bash\n $ uwsgi --http :26683 --http-timeout 310 --wsgi-file /home/$USER/.local/lib/python3.7/site-packages/convey/wsgi.py\n ```\n\n\nAccess: `curl http://localhost:26683/?q=example.com`\n```json\n{\"ip\": \"93.184.216.34\", \"prefix\": \"93.184.216.0-93.184.216.255\", \"asn\": \"\", \"abusemail\": \"abuse@verizondigitalmedia.com\", \"country\": \"unknown\", \"netname\": \"edgecast-netblk-03\", \"csirt-contact\": \"-\", \"incident-contact\": \"unknown\", \"status\": 200, \"text\": \"DNSThe free app that makes your (much longer text...)\"}\n```\n\nAccess: `curl http://localhost:26683/?q=example.com&field=ip`\n```json\n{\"ip\": \"93.184.216.34\"}\n```\n\nAccess: `curl http://localhost:26683?q=hello&type=country&field=reg_s,l,L`\n```json\n{\"reg_s\": \"heLLo\"}\n```\n\n## Sending files\n\nWhen you split the CSV file into chunks by an e-mail, generated files may be sent to these addresses. Look at the example of an unlocked \"send\" menu below. You see the list of the recipients, followed by a conditional list of recipients that have been already sent to. Next, an exact e-mail message is printed out, including headers. \n\nIn the menu, you may either:\n * **Send** the e-mails\n * **Limit** the messages that are being send at once; if you are not 100 % sure you want to send the the whole message bucket at once.\n * **Edit** the template. The message file will open either in the default GUI or terminal editor. The first line of the template should be `Subject: ...`, followed by a free line. Note that you may include any e-mail headers, such as `Reply-To: ...`, `Cc: ...`, etc. The e-mail will reflect all of them. You may write the message either in plain text or in the HTML.\n * **Choose** which recipients in a checkbox list will receive the message. \n * **Test** sending a message to your own address. You'll be prompted which of the messages should be delivered to you. The e-mail contents possibly modified by a dynamic template is shown just before sending.\n * **Print all e-mails** to a file to have the more granulated control over what is going to be sent.\n * **Toggle file attaching** on and off. There are use cases when you do not want the files to be sent with, the text suits fine.\n\n```bash\n *** E-mail template ***\nRecipient list (1/3): alice@example.com\nAlready sent (2/3): bob@example.com, cilia@example.com\n\nContent-Type: text/plain; charset=\"utf-8\"\nContent-Transfer-Encoding: 7bit\nMIME-Version: 1.0\nSubject: My subject\nFrom: me@example.com\nDate: Fri, 17 Jan 2020 01:36:28 +0100\n\nHello,\n\nthis is my testing message.\n\nKeen regards\n\n**************************************************\n1) Send all e-mails via localhost (1) \u2190\u2190\u2190\u2190\u2190\nl) Limit sending amount to...\ne) Edit template...\nr) Choose recipients...\nt) Send test e-mail...\np) Print e-mails to a file...\na) Attach files (toggle): True\nx) Go back...\n? \n```\n\n### Arbitrary e-mail headers, \"From\" header, GPG signing\nIn the template, you may specify any e-mail header, such as `Reply-To`, `Cc` or `From`. If `From` is not found, we take `SMTP/email_from_name` config value. If `gnupg` home is found on the default user path, we check if there is a secret key matching the `From` header and if found, e-mail will be GPG-signed. If it is going to be signed, you would see something like `Content-Type: multipart/signed; protocol=\"application/pgp-signature\";` header in the e-mail template preview.\n \n### Dynamic templates\nMessage is processed with [Jinja2](https://jinja.palletsprojects.com/en/2.10.x/) templating system by default.\n\nFew instruments are included to treat the attachment contents:\n* **attachment()** \u2013 Prints the attachment contents and prevent it to be attached.\n ```jinja2\n You will find our findings below.\n \n {{ attachment() }}\n ```\n* **row()** \u2013 Generate attachment contents fields row by row. Header skipped. \n* **amount(count=2)** \u2013 Check if the attachment has at least `count` number of lines. Header is not counted. Useful when deciding whether the are single row in the result or multiple.\n* **joined(column: int, delimiter=\", \")** \u2013 Return a column joined by delimiter\n* **first_row** \u2013 Access first line fields\n\n Example:\n ```jinja2\n {% if amount() %}\n Here is the complete list of the elements. \n {{ joined(1,\"\\n\") }}\n {% else %}\n Here is the element you had problems with: {{ first_row[1] }}\n {% endif %}\n ```\n\n## Examples\n\nIn the examples, we will use these parameters to add a field and to shorten the result. \n```bash\n# -f, --field adding field syntax: FIELD[[CUSTOM]],[COLUMN],[SOURCE_TYPE],[CUSTOM],[CUSTOM]\n# -H, --headless: just quietly print out single value, no dialog\n```\n\n### URL parsing\n\n#### Output formats\nPut any IP or URL as the argument.\n\n```bash\n$ convey example.com\nInput value detected: hostname\n\nWhois 93.184.216.34... abuse@verizondigitalmedia.com\nScrapping http://example.com...\nfield value\n---------------- ------------------------------------------------------------------------------\ncidr 93.184.216.0/24\nip 93.184.216.34\ntld com\nurl http://example.com\nabusemail abuse@verizondigitalmedia.com\ncsirt_contact -\nincident_contact abuse@verizondigitalmedia.com\nnetname edgecast-netblk-03\nprefix 93.184.216.0-93.184.216.255\na 93.184.216.34\naaaa 2606:2800:220:1:248:1893:25c8:1946\nmx 0 .\nns ['a.iana-servers.net.', 'b.iana-servers.net.']\nspf v=spf1 -all\nhttp_status 200\ntext Example Domain\n This domain is for use in illustrative examples in documents. You may use this\n domain in literature without prior coordination or asking for permission.\n More informatio\n n...\n```\n\nShould you need just the country the domain/IP is hosted in, use `--field, -f` argument\n\n```bash\n$ convey wikipedia.com -f country\nInput value detected: hostname\n\nWhois 208.80.154.232... us\nfield value\n------- -------\ncountry us\n``` \n\nUse `--headless, -H` or `--quiet, -q` flag to shorten the output (and cut down all dialogues). \n```bash\n$ convey wikipedia.com -f country -H\nus\n```\n\nFlag `--json` modifies the output.\n\n```bash\n$ convey wikipedia.com -f country -H --json\n{\"country\": \"us\"}\n```\n\n#### Computing TLD from another column\nTo compute a TLD from the abusemail that is being used for the IP domain is hosted in, add a field `abusemail` and then another field `tld`. Specifically say that the latter should source from the second column (which is `abusemail`) \u2013 either type '2' or 'abusemail'.\n\n```bash\n$ convey example.com -f abusemail -f tld,2\n$ convey example.com -f abusemail -f tld,abusemail\nInput value detected: hostname\n\nWhois 93.184.216.34... abuse@verizondigitalmedia.com\nfield value\n--------- -----------------------------\nabusemail abuse@verizondigitalmedia.com\ntld com\n\n```\n\nTo prevent `abusemail` from being output, use `--field-excluded, -fe` instead of `--field, -f`:\n```bash\n$ convey example.com -fe abusemail -f tld,2 -H\nInput value detected: hostname\n\nWhois 93.184.216.34... abuse@verizondigitalmedia.com\nfield value\n------- -------\ntld com\n```\n\nWe did not say earlier, user is asked each time whether they wish to get any `tld`, `gTLD` (ex: *com*) or `ccTLD` (ex: *cz*). You may specify it from CLI by one of those equivalent commands.\n```bash\n$ convey test.csv --fresh --field tld[gTLD]\n$ convey test.csv --fresh --field tld,,,gTLD\n\n# flag --yes or --headless will choose the default option which is *all*\n$ convey test.csv --fresh --field tld --yes\n```\n\n#### CSV processing\nShould you have a list of the object that you want to enrich of a CIDR they are hosted at, load the file `test.csv` they are located in.\n\n```csv\n# file text.csv\ndomain list\nwikipedia.com\nexample.com\n```\n\nAnd see the menu just by adding `--field cidr` argument.\n\n```bash\n$ convey test.csv -f cidr\nSource file: /tmp/ram/test.csv\nIdentified columns: \nLog lines: 3\n\nSample:\ndomain list\nwikipedia.com\nexample.com\n\nDelimiter character found: ','\nQuoting character: '\"'\nHeader is present: yes\n\nCould you confirm this? [y]/n: (HIT ENTER)\n\nSource file: /tmp/ram/test.csv, delimiter: ',', quoting: '\"', header: used\nIdentified columns: domain list (hostname)\nComputed columns: cidr (from domain list)\nLog lines: 3\n\nSample:\ndomain list\nwikipedia.com\nexample.com\n\nWhois 208.80.154.232... us\nWhois 93.184.216.34... abuse@verizondigitalmedia.com\nPreview:\ndomain list cidr from:\n (hostname) domain list\n--------------- ---------------\nwikipedia.com 208.80.152.0/22\nexample.com 93.184.216.0/24\n\nMain menu - how the file should be processed?\n1) Pick or delete columns\n2) Add a column\n3) Filter\n4) Split by a column\n5) Change CSV dialect\n6) Aggregate\np) process \u2190\u2190\u2190\u2190\u2190\n~) send (split first)\n~) show all details (process first)\nr) redo...\nc) config...\nx) exit\n? \n```\n\n#### File splitting\nWe will create an ASN field and split the file.csv by this field, without adding it into the output.\n\n```csv\n# file.csv\nwikipedia.com,443,2016-02-09T01:12:26-05:00,16019,US\nseznam.cz,25,2016-02-27T22:20:21-05:00,16019,CZ\ngoogle.com,25,2016-02-28T02:27:21-05:00,16019,US\n```\n\n```bash\n$ convey file.csv --field-excluded asn --split asn\n(...)\n** Processing completed: 3 result files in /tmp/ram/file.csv_convey1573236314\n(...)\n```\n\n```csv\n# file as14907\nwikipedia.com,443,2016-02-09T01:12:26-05:00,16019,US\n```\n\n```csv\n# file as43037\nseznam.cz,25,2016-02-27T22:20:21-05:00,16019,CZ\n```\n\n```csv\n# file as15169\ngoogle.com,25,2016-02-28T02:27:21-05:00,16019,US\n```\n\n#### CSIRT Usecase\nA CSIRT may use the tool to automate incident handling tasks. The input is any CSV we receive from partners; there is at least one column with IP addresses or URLs. We fetch whois information and produce a set of CSV grouped by country AND/OR abusemail related to IPs. These CSVs are then sent by through OTRS from within the tool. \nA most of the work is done by this command.\n```bash\nconvey --field-excluded incident_contact,source_ip --split incident_contact --yes [FILENAME]\n```\n\n### Custom code field\n\nAdding a column from custom Python code:\n```bash\n$ convey example.com -f code,\"x=x[1:5]\"\nxamp\n```\n\n### Base64 and Regular expressions\nCode there and back:\n```bash\n$ convey hello -f base64 -H # --headless conversion to base64\naGVsbG8=\n$ convey aGVsbG8= -H # automatically identifies input as base64 and produces plaintext\nhello\n```\n\nUse a `reg` column for regular expressions.\n```bash\n# start adding a new reg column wizzard that will take decoded \"hello\" as input \n$ convey aGVsbG8= -f reg\n$ convey aGVsbG8= -f reg_s,\"ll\",\"LL\" -H # substitute 'll' with 'LL'\nheLLo\n```\n\nSpecify source\n```bash\n# start adding a new reg column wizzard that will take plaintext \"aGVsbG8=\" as input \n$ convey aGVsbG8= -f reg,plaintext\n# specifying plaintext as a source type will prevent implicit convertion from base64\n$ convey aGVsbG8= -f reg_s,plaintext,\"[A-Z]\",\"!\" -H # substitute uppercase letters with '!'\na!!sb!8=\n```\n\n### Converting units\n\nWe are connected to the [pint](https://pint.readthedocs.io/en/0.9/) unit converter!\n```bash\n$ convey \"3 kg\" \nInput value detected: unit\n\nfield value\n--------- --------------------------------------------------------------------------------------------\nplaintext ['1.806642538265029e+27 atomic_mass_unit', '105.82188584874123 ounce', '96.45223970588393 ap\n othecary_ounce', '0.0703602964419822 bag', '0.05905239165666364 long_hunderweight', '0.06613\n 867865546327 US_hundredweight', '0.002952619582833182 UK_ton', '0.002952619582833182 long_to\n n', '1929.0447941176785 pennyweight', '46297.07505882429 grain', '1.7935913792661326e+27 pro\n ton_mass', '771.6179176470714 apothecary_dram', '3000.0 gram', ...]\n\n\n$ convey \"3 kg\" -f unit # launches wizzard that let's you decide what unit to convert to \n$ convey \"3 kg\" -f unit[g] -H\n3000.0 gram\n\n$ convey \"kg\" -f unit --csv-processing --headless\nkg|6.022141794216764e+26 atomic_mass_unit\nkg|0.001 metric_ton\nkg|0.0009842065276110606 UK_ton\nkg|771.6179176470714 scruple\nkg|257.2059725490238 apothecary_dram\nkg|1000.0 gram\n\n\n# You may try to specify the units with no space and quotation.\n# In the following example, convey expand all time-units it is able to compute\n# \u2013 time units will be printed out and each is base64 encoded. \n$ convey 3hours\nInput value detected: timestamp, unit\n\nfield value\n------------------- ------------------------------------------------------------------\n(...)\nbase64 ['MC4wMDQxMDY4NjM4OTc0NTAwNzcgbW9udGg=', 'MTA4MDAuMCBzZWNvbmQ=', 'MC4wMTc4NTcxNDI4NTcxNDI4NSB3ZWVr'] \nplaintext ['0.004106863897450077 month', '10800.0 second', '0.01785714285714285 week', (...)]\ntime 03:00:00\n(...)\n\n# What if\n$ convey 3hours -f urlencode\nInput value detected: timestamp, unit\n\nInput unit_expand variable unit: *you type here sec or seconds to see the wizzard* \nPreview \n| original | result | \n|------------|----------------| \n| 3hours | 10800.0 second | \n\nfield value\n--------- ----------------\nurlencode 10800.0%20second\n\n# What if we wanted to urlencode text \"3hours\" without converting it to unit first? \n# Just specify the SOURCE_TYPE to be plaintext:\n$ convey \"3hours\" -f urlencode,plaintext\nInput value detected: timestamp, unit\n\nfield value\n--------- -------\nurlencode 3hours\n\n```\n\n### Country names\nWhen specifying country code, you get country name.\n```bash\n$ convey --type country sc\nSeychelles\n```\nLots of countries can be recognized.\n```\nbash\n$ convey --type country_name Futuna\nwf\n```\nYou may get the country code from various telephone number formats. \n```bash\n$ convey +2481234567\nSeychelles\n\n$ convey \"1-541-754-3010\"\n['ca', 'us']\n\n$ convey \n```\n\n### Aggregate\n\nSyntax is `[COLUMN, FUNCTION], ..., [group-by-COLUMN]`. \nPossible functions are:\n* avg\n* sum\n* count\n* min\n* max\n* list\n* set\n\n\nLet's have a file.\n```csv\n# file.csv\ncategory,price,consumption\nbulb,100,30\nbulb,150,10\nkettle,250,70\nkettle,352,80\nbulb,120,15\n```\n\nSum the `price` column.\n```bash\n$ convey file.csv --aggregate price,sum\n sum(price)\n------------\n 972\n```\n\nGroup the `price` sum by `category`. \n```bash\n$ convey file.csv --aggregate price,sum,category\ncategory sum(price)\n--------- ------------\ntotal 972\nbulb 370\nkettle 602\n```\n\nGroup the `price` sum and the `consumption` average value by `category`.\n\n```bash\n$ convey file.csv --aggregate price,sum,consumption,avg,category\ncategory sum(price) avg(consumption)\n---------- ------------ ------------------\ntotal 972 41\nbulb 370 18.33\nkettle 602 75\n```\n\nGroup the `price` sum by `category` and list its values.\n\n```bash\n$ convey file.csv --aggregate price,sum,price,list,category\ncategory sum(price) list(price)\n---------- ------------ ---------------------\ntotal 972 (all)\nbulb 370 ['100', '150', '120']\nkettle 602 ['250', '352']\n```\n\nYou can even split while aggregating. Each file will count its own results.\n\n```bash\n$ convey file.csv --agg price,sum --split category\n\nSplit location: bulb\n sum(price)\n------------\n 370\n\nSplit location: kettle\n sum(price)\n------------\n 602\n```\n\n## Credits\n\nBrought by [CSIRT.cz](https://csirt.cz).", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/CZ-NIC/convey", "keywords": "", "license": "GNU GPLv3", "maintainer": "", "maintainer_email": "", "name": "convey", "package_url": "https://pypi.org/project/convey/", "platform": null, "project_url": "https://pypi.org/project/convey/", "project_urls": { "Homepage": "https://github.com/CZ-NIC/convey" }, "release_url": "https://pypi.org/project/convey/1.3.15/", "requires_dist": null, "requires_python": "", "summary": "CSV processing and mutual conversion of web related data types", "version": "1.3.15", "yanked": false, "yanked_reason": null }, "last_serial": 13689297, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "3990e16240ceeda6c83f6854dd66fab5", "sha256": "c52336b7cebafc7089fc6034bf6f43b8aabdd3353b76df3813e6597e2565a1e3" }, "downloads": -1, "filename": "convey-1.0.tar.gz", "has_sig": false, "md5_digest": "3990e16240ceeda6c83f6854dd66fab5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 38049, "upload_time": "2019-10-25T12:43:38", "upload_time_iso_8601": "2019-10-25T12:43:38.881430Z", "url": "https://files.pythonhosted.org/packages/41/f2/7536d85e30d41cdb04acf18a1e7fc3791381a2422ca64b2c8a710a593686/convey-1.0.tar.gz", "yanked": false, "yanked_reason": null } ], "1.1": [ { "comment_text": "", "digests": { "md5": "e93e5c2b07013b22e11fd1a71e77d762", "sha256": "a175008a0549facb217e3e5b7b0fc4d2981edfc3156f2b9817ae01d5bf129e64" }, "downloads": -1, "filename": "convey-1.1.tar.gz", "has_sig": false, "md5_digest": "e93e5c2b07013b22e11fd1a71e77d762", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41261, "upload_time": "2019-10-25T12:07:11", "upload_time_iso_8601": "2019-10-25T12:07:11.051589Z", "url": "https://files.pythonhosted.org/packages/61/29/5a41dde9498fe2170366960b72bb8f07017fbb64d3b5340b97450b138820/convey-1.1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2": [ { "comment_text": "", "digests": { "md5": "8f31c69e48e23f8d0e52a973d65684fe", "sha256": "20afe353a750c08fff3a3685520d31f1dd62c0a0c261712538ba2c7b5504920a" }, "downloads": -1, "filename": "convey-1.2.tar.gz", "has_sig": false, "md5_digest": "8f31c69e48e23f8d0e52a973d65684fe", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97938, "upload_time": "2019-11-13T11:07:09", "upload_time_iso_8601": "2019-11-13T11:07:09.720420Z", "url": "https://files.pythonhosted.org/packages/63/7a/2f261b8ab688cece30f28615bb21a757d5ba223834192e7127ddccf1d681/convey-1.2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc1": [ { "comment_text": "", "digests": { "md5": "31b90f297f7df46a9f189ff70e9bb349", "sha256": "6a70273fb0b141e8f553a942288e9cb2937ab89aa8017662ad2fe2197bde385e" }, "downloads": -1, "filename": "convey-1.2rc1.tar.gz", "has_sig": false, "md5_digest": "31b90f297f7df46a9f189ff70e9bb349", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 66235, "upload_time": "2019-10-25T12:35:26", "upload_time_iso_8601": "2019-10-25T12:35:26.065741Z", "url": "https://files.pythonhosted.org/packages/ba/e0/93ef936b081164ffda0b35c1a25c6fe6a89621323776d25fe33517a2ab41/convey-1.2rc1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc10": [ { "comment_text": "", "digests": { "md5": "96d458a27e0d6359cfbbb2243be0e2ac", "sha256": "b6b954f7af9066be990e6bdfed7132253be3f8c8fa1737a6930afab8051785e8" }, "downloads": -1, "filename": "convey-1.2rc10.tar.gz", "has_sig": false, "md5_digest": "96d458a27e0d6359cfbbb2243be0e2ac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97951, "upload_time": "2019-11-13T10:57:40", "upload_time_iso_8601": "2019-11-13T10:57:40.136158Z", "url": "https://files.pythonhosted.org/packages/3a/fd/1fb064c88a1c127263feb1be30fd26f74979ebe80d6eb10c93a5e2f12bda/convey-1.2rc10.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc2": [ { "comment_text": "", "digests": { "md5": "d36bd6474190a234cd0e5795ea312dff", "sha256": "2f4413bd6f7a63aef46f571f716021d9d3d656bd66acc5f352e9cde0154d27ec" }, "downloads": -1, "filename": "convey-1.2rc2.tar.gz", "has_sig": false, "md5_digest": "d36bd6474190a234cd0e5795ea312dff", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 73242, "upload_time": "2019-11-01T20:38:11", "upload_time_iso_8601": "2019-11-01T20:38:11.533202Z", "url": "https://files.pythonhosted.org/packages/53/f9/5157f266323d3bc080e4df10fbf73e245992249e163948a73b88fa772acd/convey-1.2rc2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc3": [ { "comment_text": "", "digests": { "md5": "b9f5c53a9dfa742223bce161f24389e0", "sha256": "e44ca758fbdaa40f7135d4f502d1de139c54ed8cebfc3555f803ddfbc7236f98" }, "downloads": -1, "filename": "convey-1.2rc3.tar.gz", "has_sig": false, "md5_digest": "b9f5c53a9dfa742223bce161f24389e0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 74383, "upload_time": "2019-11-01T23:48:53", "upload_time_iso_8601": "2019-11-01T23:48:53.520861Z", "url": "https://files.pythonhosted.org/packages/a2/b7/fc00295eac04914a3d0b654bb5abef031d8ff980e78d5f4048a92cd123dd/convey-1.2rc3.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc4": [ { "comment_text": "", "digests": { "md5": "725977ba26c96de645a76dd2fd923f7a", "sha256": "ad3369e874c29dcf328ee2428395f041031dfbd0dac605aed888bacc881b6de0" }, "downloads": -1, "filename": "convey-1.2rc4.tar.gz", "has_sig": false, "md5_digest": "725977ba26c96de645a76dd2fd923f7a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 76973, "upload_time": "2019-11-02T11:03:43", "upload_time_iso_8601": "2019-11-02T11:03:43.576365Z", "url": "https://files.pythonhosted.org/packages/d9/dd/8ebe24dadc475843897230daaadae075ec6acf9f9c87f978c8f0abe08516/convey-1.2rc4.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc5": [ { "comment_text": "", "digests": { "md5": "49af5d170a0475e27b1e2753d714a093", "sha256": "eca11ccd8ae3db4e5128ade25f7ebcef24187cf6fc792808f9969b5dc702ac02" }, "downloads": -1, "filename": "convey-1.2rc5.tar.gz", "has_sig": false, "md5_digest": "49af5d170a0475e27b1e2753d714a093", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 86061, "upload_time": "2019-11-04T22:08:17", "upload_time_iso_8601": "2019-11-04T22:08:17.520163Z", "url": "https://files.pythonhosted.org/packages/ae/56/92ae492af62300025ec6952f43e71427b6bd4694ab2fa48efee1058a558a/convey-1.2rc5.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc6": [ { "comment_text": "", "digests": { "md5": "18230f14e619c545e98b7b9f23d5d8aa", "sha256": "2a593c2899c7e32fa91ac026f067fc35e9fb559e8d7b42e39bb4cd0f81f630c9" }, "downloads": -1, "filename": "convey-1.2rc6.tar.gz", "has_sig": false, "md5_digest": "18230f14e619c545e98b7b9f23d5d8aa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 90288, "upload_time": "2019-11-06T18:47:59", "upload_time_iso_8601": "2019-11-06T18:47:59.577517Z", "url": "https://files.pythonhosted.org/packages/bc/ff/046c93f8b63825414105a97cf493308af9c88b4a1d663f9baa096b6f602a/convey-1.2rc6.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc7": [ { "comment_text": "", "digests": { "md5": "812861fba0965e58567de7b1838eb68c", "sha256": "f623e4586242dde287c8d86643ac9235d226ef9d6ea4c575d2915a4488174da5" }, "downloads": -1, "filename": "convey-1.2rc7.tar.gz", "has_sig": false, "md5_digest": "812861fba0965e58567de7b1838eb68c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 92175, "upload_time": "2019-11-08T14:36:28", "upload_time_iso_8601": "2019-11-08T14:36:28.876007Z", "url": "https://files.pythonhosted.org/packages/d9/d4/fc44f43ccc8789a33e96fc0ce37ef35af8f159159d235a7a9adee718e415/convey-1.2rc7.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc8": [ { "comment_text": "", "digests": { "md5": "bae1e6804c044c0d2693027045442da6", "sha256": "82fd1391d4f5113470f6c39782ab50fd793e028bc293a7f3fe63db7b691b5adc" }, "downloads": -1, "filename": "convey-1.2rc8.tar.gz", "has_sig": false, "md5_digest": "bae1e6804c044c0d2693027045442da6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97270, "upload_time": "2019-11-08T18:35:08", "upload_time_iso_8601": "2019-11-08T18:35:08.355126Z", "url": "https://files.pythonhosted.org/packages/c1/1b/63f9f090e0088d12381975d35aab3778459c4fb3695ec5863e906e2db153/convey-1.2rc8.tar.gz", "yanked": false, "yanked_reason": null } ], "1.2rc9": [ { "comment_text": "", "digests": { "md5": "31c6cc5ff978e1143cd18e99c54c34ac", "sha256": "0ef1313e331894ea551f7baa302faec0f7c1873ca1688b2aa91ba3cca9995e16" }, "downloads": -1, "filename": "convey-1.2rc9.tar.gz", "has_sig": false, "md5_digest": "31c6cc5ff978e1143cd18e99c54c34ac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 97913, "upload_time": "2019-11-08T18:53:07", "upload_time_iso_8601": "2019-11-08T18:53:07.431779Z", "url": "https://files.pythonhosted.org/packages/ba/47/9906bc1618b5ef8d536a3c7c2c68f78e307e7d6a6321c42a4c801acff46c/convey-1.2rc9.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3": [ { "comment_text": "", "digests": { "md5": "8cb203420cac322c1e28bd3480477883", "sha256": "a0d543380ce46f464531dc445051a0ea4a458eff5129798f05452a813d2d3ce8" }, "downloads": -1, "filename": "convey-1.3.tar.gz", "has_sig": false, "md5_digest": "8cb203420cac322c1e28bd3480477883", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 127086, "upload_time": "2020-01-28T00:44:54", "upload_time_iso_8601": "2020-01-28T00:44:54.031187Z", "url": "https://files.pythonhosted.org/packages/d6/7c/f2865e049b367cf9b231b6429bdb4bcd1b07379ad026ca536005e7b6e421/convey-1.3.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.1": [ { "comment_text": "", "digests": { "md5": "9802f449cd9f96f6bfa2481d9e5e0f7d", "sha256": "122bc36b5d7cf4217d194af91e488c272a41f883dec9c3a545e18af3eead6550" }, "downloads": -1, "filename": "convey-1.3.1.tar.gz", "has_sig": false, "md5_digest": "9802f449cd9f96f6bfa2481d9e5e0f7d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 128991, "upload_time": "2020-01-31T18:33:56", "upload_time_iso_8601": "2020-01-31T18:33:56.875591Z", "url": "https://files.pythonhosted.org/packages/6b/76/617d9356848943c5b5a35d8d0c6bc58905747189b3b6de41f4e24149cd66/convey-1.3.1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.10": [ { "comment_text": "", "digests": { "md5": "457d5480cad763b7469d3a30fb431486", "sha256": "7bb12c98f5124a539b914babda8f1e9a1cf88f049cafec4fcd77233515ba8e5e" }, "downloads": -1, "filename": "convey-1.3.10.tar.gz", "has_sig": false, "md5_digest": "457d5480cad763b7469d3a30fb431486", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 144277, "upload_time": "2021-02-10T13:17:17", "upload_time_iso_8601": "2021-02-10T13:17:17.574347Z", "url": "https://files.pythonhosted.org/packages/69/60/31f27e2cf67573a7748705522cb022c5667cfd40aa52615738419a313061/convey-1.3.10.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.11": [ { "comment_text": "", "digests": { "md5": "d7d5697f86f47592a60246b11f3ca4f8", "sha256": "064becb1e3bc2756df7e3ad195384b548d8481089b06657611f774b2f5d7794a" }, "downloads": -1, "filename": "convey-1.3.11.tar.gz", "has_sig": false, "md5_digest": "d7d5697f86f47592a60246b11f3ca4f8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 144809, "upload_time": "2021-02-12T21:06:11", "upload_time_iso_8601": "2021-02-12T21:06:11.342245Z", "url": "https://files.pythonhosted.org/packages/5b/62/bea8fd08a1121cf1e0b929f324f6c8c3ddb46d0f53319d56d990a6d33715/convey-1.3.11.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.12": [ { "comment_text": "", "digests": { "md5": "1a24b3fccd74ffe68bd0515aeb75e866", "sha256": "37ad4d352c162f29d7d89897bd28cb41e7562b23503a84fd594c26f4f3c02268" }, "downloads": -1, "filename": "convey-1.3.12.tar.gz", "has_sig": false, "md5_digest": "1a24b3fccd74ffe68bd0515aeb75e866", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 145098, "upload_time": "2021-02-16T18:30:07", "upload_time_iso_8601": "2021-02-16T18:30:07.374795Z", "url": "https://files.pythonhosted.org/packages/31/ac/d2673f689b8659dc6e7d9f819548e480c37512f696eb0f126491ba42e510/convey-1.3.12.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.13": [ { "comment_text": "", "digests": { "md5": "83decdb799247e084779bc7713b114e3", "sha256": "11ae3765780446f0ed43c687e7e91e9d64c4abf372c51a09cf2a210de769bf12" }, "downloads": -1, "filename": "convey-1.3.13.tar.gz", "has_sig": false, "md5_digest": "83decdb799247e084779bc7713b114e3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 145233, "upload_time": "2021-08-30T11:45:50", "upload_time_iso_8601": "2021-08-30T11:45:50.006728Z", "url": "https://files.pythonhosted.org/packages/82/73/ba6bc4a621bb0b9e6edb4588ec8ef011d39fbafa6d6cfde729fc41e34af5/convey-1.3.13.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.14": [ { "comment_text": "", "digests": { "md5": "862fc83fa506c7de48f9c0135d7b89f1", "sha256": "381576c20bef048e85f60ee3122c20d6767cab818a589ca91604cdd93ee7b114" }, "downloads": -1, "filename": "convey-1.3.14.tar.gz", "has_sig": false, "md5_digest": "862fc83fa506c7de48f9c0135d7b89f1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 145890, "upload_time": "2022-03-10T16:20:56", "upload_time_iso_8601": "2022-03-10T16:20:56.440175Z", "url": "https://files.pythonhosted.org/packages/8f/56/2920334f66ce4b80cd0fc0f6aa6dae510718bee326942a7a0f75d47006bc/convey-1.3.14.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.15": [ { "comment_text": "", "digests": { "md5": "49407606fc50a730dfef94cb91647694", "sha256": "0c3094a1834d40fe4038a2605abd86b1cde954be25392bf45af926ff8e616e56" }, "downloads": -1, "filename": "convey-1.3.15.tar.gz", "has_sig": false, "md5_digest": "49407606fc50a730dfef94cb91647694", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 145911, "upload_time": "2022-05-02T15:09:10", "upload_time_iso_8601": "2022-05-02T15:09:10.390466Z", "url": "https://files.pythonhosted.org/packages/97/5a/201d7b666580374aace112b5643c180cdef12079e8c1c083c2a57858c663/convey-1.3.15.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.1rc1": [ { "comment_text": "", "digests": { "md5": "0acdee6b5ad47ea2aca5760d10d8ce23", "sha256": "4735d9719b7ca0fb6d74589bd47ad92a443e90ff70342654f26088ed11a6af95" }, "downloads": -1, "filename": "convey-1.3.1rc1.tar.gz", "has_sig": false, "md5_digest": "0acdee6b5ad47ea2aca5760d10d8ce23", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 128756, "upload_time": "2020-01-28T21:46:31", "upload_time_iso_8601": "2020-01-28T21:46:31.557652Z", "url": "https://files.pythonhosted.org/packages/7e/1d/680f861c59e743ef77a6a9f50f0352d71880d83c659132a822e7cb5047fb/convey-1.3.1rc1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.1rc2": [ { "comment_text": "", "digests": { "md5": "57fe4ea90881c2eedacd386f6c4299b7", "sha256": "8c2432de2f7623661ea3c365dad90174f2c8a73cf73113994297ad9972276c0f" }, "downloads": -1, "filename": "convey-1.3.1rc2.tar.gz", "has_sig": false, "md5_digest": "57fe4ea90881c2eedacd386f6c4299b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 128794, "upload_time": "2020-01-31T13:54:26", "upload_time_iso_8601": "2020-01-31T13:54:26.097009Z", "url": "https://files.pythonhosted.org/packages/96/40/922c2cdb7590f8cfbde67e486e9750d338c7fe84d9556984088e3de2d332/convey-1.3.1rc2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.2": [ { "comment_text": "", "digests": { "md5": "0cc8d2049a7e7e6b752f72a4376824e4", "sha256": "3e4b613e8e0ce7f5b601306d3e1bdb5df4c1a8163a904adc8df2a31f8db235e4" }, "downloads": -1, "filename": "convey-1.3.2.tar.gz", "has_sig": false, "md5_digest": "0cc8d2049a7e7e6b752f72a4376824e4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 130744, "upload_time": "2020-02-05T15:56:33", "upload_time_iso_8601": "2020-02-05T15:56:33.571837Z", "url": "https://files.pythonhosted.org/packages/ad/e5/55de65b31af0bd15068d4567f8b311d0c1bcf43ffc2ec8d13e5c2c8c9a92/convey-1.3.2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.2rc1": [ { "comment_text": "", "digests": { "md5": "f8461c207959ff1edc7e941df20b6a39", "sha256": "45e4d0bc115a736b91f1bb19dbaeec5382e31bf993981ea7491ecf33402d0c38" }, "downloads": -1, "filename": "convey-1.3.2rc1.tar.gz", "has_sig": false, "md5_digest": "f8461c207959ff1edc7e941df20b6a39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 129121, "upload_time": "2020-02-03T19:16:00", "upload_time_iso_8601": "2020-02-03T19:16:00.364502Z", "url": "https://files.pythonhosted.org/packages/c2/2c/bb815d9d89670fd9f309f6c2ea2bd65f7d6dffb48f8d4e9c73d0cd900a6e/convey-1.3.2rc1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.2rc2": [ { "comment_text": "", "digests": { "md5": "61a119156c7883e13463c7e7e29a11b1", "sha256": "c1eafdd4b7df4f0cef00533600640a63393667f0930447ceaf6895568bc259d8" }, "downloads": -1, "filename": "convey-1.3.2rc2.tar.gz", "has_sig": false, "md5_digest": "61a119156c7883e13463c7e7e29a11b1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 129359, "upload_time": "2020-02-04T15:22:10", "upload_time_iso_8601": "2020-02-04T15:22:10.875106Z", "url": "https://files.pythonhosted.org/packages/c4/5e/ebed915080d6da5173e45af69512be96a182af131891ef16904492a7a607/convey-1.3.2rc2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.3": [ { "comment_text": "", "digests": { "md5": "8e8bae8f72a38325d3043c06327b9ba9", "sha256": "6130ce5ce6c4fd5e92ae78f94a4a8eec6e94c53663600778ea7fc835059aaf2b" }, "downloads": -1, "filename": "convey-1.3.3.tar.gz", "has_sig": false, "md5_digest": "8e8bae8f72a38325d3043c06327b9ba9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 130960, "upload_time": "2020-02-07T16:07:45", "upload_time_iso_8601": "2020-02-07T16:07:45.980300Z", "url": "https://files.pythonhosted.org/packages/8a/9b/3096379f39a30a65fddbee39d11c35fc6f2c23bfd1e91a974680badb5b23/convey-1.3.3.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.4": [ { "comment_text": "", "digests": { "md5": "696a481a1e3696d49f150149e5156d43", "sha256": "dbfc86431c40a8d1a48dc85b09e50869ecb9735229e62809362c58f3d67e69ed" }, "downloads": -1, "filename": "convey-1.3.4.tar.gz", "has_sig": false, "md5_digest": "696a481a1e3696d49f150149e5156d43", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 134736, "upload_time": "2020-02-17T20:45:10", "upload_time_iso_8601": "2020-02-17T20:45:10.907952Z", "url": "https://files.pythonhosted.org/packages/09/1a/44193a0a9fff5fa67f749ebb90fba67f237e2388b39d9f278e6ee863e104/convey-1.3.4.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.5": [ { "comment_text": "", "digests": { "md5": "50e1c4d9c53d4eb08e07d71d1cbc4c70", "sha256": "c617ff5623df37abe253be1b27b87633f9a079ce8443b19cf9ac8f2cd815d752" }, "downloads": -1, "filename": "convey-1.3.5.tar.gz", "has_sig": false, "md5_digest": "50e1c4d9c53d4eb08e07d71d1cbc4c70", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 137878, "upload_time": "2020-02-19T21:06:17", "upload_time_iso_8601": "2020-02-19T21:06:17.132726Z", "url": "https://files.pythonhosted.org/packages/cc/27/fd0f463330a5c1a34087534e10251668abafb2b7647a8ac2777440507e26/convey-1.3.5.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.6": [ { "comment_text": "", "digests": { "md5": "c75c4895e87006f720655f245c44d6d4", "sha256": "e2a63656431e134bdca99c66be85b842cf18c6edbe12a7c89b02df88948e1527" }, "downloads": -1, "filename": "convey-1.3.6.tar.gz", "has_sig": false, "md5_digest": "c75c4895e87006f720655f245c44d6d4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 138797, "upload_time": "2020-02-20T19:55:25", "upload_time_iso_8601": "2020-02-20T19:55:25.402784Z", "url": "https://files.pythonhosted.org/packages/35/37/77158350105214a55f0df0243f8295d471e942d3c619926cfdd1a0507c5a/convey-1.3.6.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.7": [ { "comment_text": "", "digests": { "md5": "4f5cc3d4415e45f1a83b01af71ea12b7", "sha256": "f5a05af2dd3c54eecb41def304bac02254914461228a334a96ee9333d32b0afe" }, "downloads": -1, "filename": "convey-1.3.7.tar.gz", "has_sig": false, "md5_digest": "4f5cc3d4415e45f1a83b01af71ea12b7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 139000, "upload_time": "2020-03-10T12:35:51", "upload_time_iso_8601": "2020-03-10T12:35:51.334782Z", "url": "https://files.pythonhosted.org/packages/dc/81/584534786de238f005a4b66a28c90f5b2d2796d8d831a986fc47b3b78ce9/convey-1.3.7.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.8": [ { "comment_text": "", "digests": { "md5": "be391b879418a168ace7361ddb6cd8cd", "sha256": "b143e36bf3ee903348b271347acd396c413ed5a518ec5ea38e75df3a645593ab" }, "downloads": -1, "filename": "convey-1.3.8.tar.gz", "has_sig": false, "md5_digest": "be391b879418a168ace7361ddb6cd8cd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140017, "upload_time": "2020-06-02T12:01:31", "upload_time_iso_8601": "2020-06-02T12:01:31.923904Z", "url": "https://files.pythonhosted.org/packages/5a/9c/0e1692426976708d1ba6aea6478f0158f7b51d528467113b1a8c00b0cba0/convey-1.3.8.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9": [ { "comment_text": "", "digests": { "md5": "97f64a956cb9c5dbc25d5a0a76661e62", "sha256": "6703e1b5b76e966f4eac8be691c384157955c386059bdd7b4dbcad6922472f8c" }, "downloads": -1, "filename": "convey-1.3.9.tar.gz", "has_sig": false, "md5_digest": "97f64a956cb9c5dbc25d5a0a76661e62", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 144224, "upload_time": "2021-02-09T18:56:06", "upload_time_iso_8601": "2021-02-09T18:56:06.964304Z", "url": "https://files.pythonhosted.org/packages/f9/24/bc65a374f534b5bee445aa12f7726bf065b68fd13e73fce5fa8f1cc8c2d5/convey-1.3.9.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9rc1": [ { "comment_text": "", "digests": { "md5": "505675d48165499333855e809ffd3364", "sha256": "c7819332f69acf077e84d04e2a28768462e50758770288a005102dbe5667274d" }, "downloads": -1, "filename": "convey-1.3.9rc1.tar.gz", "has_sig": false, "md5_digest": "505675d48165499333855e809ffd3364", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140349, "upload_time": "2020-06-23T15:19:50", "upload_time_iso_8601": "2020-06-23T15:19:50.127504Z", "url": "https://files.pythonhosted.org/packages/9d/5d/71e93f95e34768a1e15c24db9bff605702a9635165f008e0f80491319ca1/convey-1.3.9rc1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9rc2": [ { "comment_text": "", "digests": { "md5": "c26c87378134014ef3f676e1a20aeff0", "sha256": "13d86a5c7c41a851fa64dcead2f66ad2cee176c38bf8235154eadcd23de3fae2" }, "downloads": -1, "filename": "convey-1.3.9rc2.tar.gz", "has_sig": false, "md5_digest": "c26c87378134014ef3f676e1a20aeff0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140383, "upload_time": "2020-06-30T17:42:52", "upload_time_iso_8601": "2020-06-30T17:42:52.996365Z", "url": "https://files.pythonhosted.org/packages/45/5d/b65f48b25e24174c27f15148f7f9c3f3de1988cc4f7f01e0c82c67bbb247/convey-1.3.9rc2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9rc3": [ { "comment_text": "", "digests": { "md5": "2cba1f9c2687f62b97757ed1aa4d634e", "sha256": "686ededb89395ecd51e4773cc9b906c57c5303a81e73c16fc75d6070f955ceb3" }, "downloads": -1, "filename": "convey-1.3.9rc3.tar.gz", "has_sig": false, "md5_digest": "2cba1f9c2687f62b97757ed1aa4d634e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140290, "upload_time": "2020-09-04T17:53:42", "upload_time_iso_8601": "2020-09-04T17:53:42.307485Z", "url": "https://files.pythonhosted.org/packages/02/be/082ad288268338c1dc03e154c5fed28a2d6fc3824c89ffa10427c24bea4c/convey-1.3.9rc3.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9rc4": [ { "comment_text": "", "digests": { "md5": "1656266182c6b0421d4f48761fb2137d", "sha256": "04798b7e7b9bf951aeb5bbdb2497db34b1c9d0ade5b442f51dadabe365239d79" }, "downloads": -1, "filename": "convey-1.3.9rc4.tar.gz", "has_sig": false, "md5_digest": "1656266182c6b0421d4f48761fb2137d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140922, "upload_time": "2020-10-13T13:02:38", "upload_time_iso_8601": "2020-10-13T13:02:38.296365Z", "url": "https://files.pythonhosted.org/packages/4c/7c/bc0065be8243a912f8c768c6ea8425ad51c073ad29b95817c55b2e36b6d6/convey-1.3.9rc4.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9rc5": [ { "comment_text": "", "digests": { "md5": "895ec21282fd07dbb364e78281741c95", "sha256": "5027d5cc9462f8947853098d487cbe83622fa24184da04bc8dcf82aef783bd95" }, "downloads": -1, "filename": "convey-1.3.9rc5.tar.gz", "has_sig": false, "md5_digest": "895ec21282fd07dbb364e78281741c95", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 140939, "upload_time": "2020-10-16T19:48:18", "upload_time_iso_8601": "2020-10-16T19:48:18.969669Z", "url": "https://files.pythonhosted.org/packages/87/ed/98d00b94621e64dbce2a6c8fbefb458526358f3c971c536b4c8245393825/convey-1.3.9rc5.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3.9rc6": [ { "comment_text": "", "digests": { "md5": "51bc5f75aeeaafc38508018f5237b73c", "sha256": "0f70c8d7b7a4c55fde7fb89ae69f10216d463ff92653f7b62683953bd2e79e22" }, "downloads": -1, "filename": "convey-1.3.9rc6.tar.gz", "has_sig": false, "md5_digest": "51bc5f75aeeaafc38508018f5237b73c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 141114, "upload_time": "2020-10-26T14:18:10", "upload_time_iso_8601": "2020-10-26T14:18:10.476942Z", "url": "https://files.pythonhosted.org/packages/0c/43/43f75f2567c75aa2e44112c0f63346842facce9f046230a74753d326008b/convey-1.3.9rc6.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc1": [ { "comment_text": "", "digests": { "md5": "e1209f596d2109021488336116aafe61", "sha256": "75a3884fc517c7effc1cf61246f3cfa25db0cb79093d0fa2fa5859e4c0d1f192" }, "downloads": -1, "filename": "convey-1.3rc1.tar.gz", "has_sig": false, "md5_digest": "e1209f596d2109021488336116aafe61", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 106654, "upload_time": "2019-11-25T21:06:25", "upload_time_iso_8601": "2019-11-25T21:06:25.998223Z", "url": "https://files.pythonhosted.org/packages/0f/6f/6445df5f266804297c985579c4a5bbb5cd613f37e3d7ad7b5b22f01be60a/convey-1.3rc1.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc10": [ { "comment_text": "", "digests": { "md5": "1c04ae98d6fee5798f7d2d069b159eb0", "sha256": "704cd5c036ea8e2b3ff60f1a19daa791a269061e751e8dd9d8afc265cfd922bd" }, "downloads": -1, "filename": "convey-1.3rc10.tar.gz", "has_sig": false, "md5_digest": "1c04ae98d6fee5798f7d2d069b159eb0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 127028, "upload_time": "2020-01-27T22:25:04", "upload_time_iso_8601": "2020-01-27T22:25:04.286087Z", "url": "https://files.pythonhosted.org/packages/1a/28/8bb9f9e6a98661fec6550701b4a376c71f4c464f7f58f14115e131986813/convey-1.3rc10.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc2": [ { "comment_text": "", "digests": { "md5": "2fa477dc9245eedf0669a429470b7d67", "sha256": "9da81f07125bb2f1d6904347a350c4b9148262f5b5356598ece6b8b2660cfc27" }, "downloads": -1, "filename": "convey-1.3rc2.tar.gz", "has_sig": false, "md5_digest": "2fa477dc9245eedf0669a429470b7d67", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 108983, "upload_time": "2019-11-26T21:22:31", "upload_time_iso_8601": "2019-11-26T21:22:31.053396Z", "url": "https://files.pythonhosted.org/packages/ca/cd/397dc9f7004573d0bb00fbdd19b6f3d99a2679b93cb38f50a2e2885eccce/convey-1.3rc2.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc3": [ { "comment_text": "", "digests": { "md5": "a9391c8945f44912908ba98f559c9812", "sha256": "ec37ccb24c5b3661df2c872a8fa9756078d9ae61c58678013ffa2345b291a372" }, "downloads": -1, "filename": "convey-1.3rc3.tar.gz", "has_sig": false, "md5_digest": "a9391c8945f44912908ba98f559c9812", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 108987, "upload_time": "2019-11-26T21:25:34", "upload_time_iso_8601": "2019-11-26T21:25:34.408469Z", "url": "https://files.pythonhosted.org/packages/4e/17/93a684bc0332e88e5cc6ffc06f44864a1f21d063db8f0123fc6f69cc501b/convey-1.3rc3.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc4": [ { "comment_text": "", "digests": { "md5": "309513a7382568ee646c8c7e622608d3", "sha256": "23dd10dad8ee85a104d40977fb4556149fb8ceffaf51b0bbd5ff43ef981703e0" }, "downloads": -1, "filename": "convey-1.3rc4.tar.gz", "has_sig": false, "md5_digest": "309513a7382568ee646c8c7e622608d3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 109042, "upload_time": "2019-11-26T21:37:34", "upload_time_iso_8601": "2019-11-26T21:37:34.476617Z", "url": "https://files.pythonhosted.org/packages/ec/d8/1203c35a51cf847eeccfebe48854c59e243d0657987c55c0bc2cec44653a/convey-1.3rc4.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc5": [ { "comment_text": "", "digests": { "md5": "88c4ef7cbd5fe09b95505146bbb54267", "sha256": "9915bd0ed15cb016171f8575983a3aaa8234906a33182cd3d6a43ba4fd6d1ad7" }, "downloads": -1, "filename": "convey-1.3rc5.tar.gz", "has_sig": false, "md5_digest": "88c4ef7cbd5fe09b95505146bbb54267", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 109018, "upload_time": "2019-11-26T21:38:01", "upload_time_iso_8601": "2019-11-26T21:38:01.648660Z", "url": "https://files.pythonhosted.org/packages/09/f7/3e83bb3bad27419b79a297600e82ce6ece72f4d9e746c5137a64cd171e73/convey-1.3rc5.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc6": [ { "comment_text": "", "digests": { "md5": "fb13fa5f683400142ed97404632ec141", "sha256": "b90ad3b46fa6def1c773606056e490091368a249f3e8468641eab65012ef6792" }, "downloads": -1, "filename": "convey-1.3rc6.tar.gz", "has_sig": false, "md5_digest": "fb13fa5f683400142ed97404632ec141", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 111271, "upload_time": "2019-12-16T21:42:45", "upload_time_iso_8601": "2019-12-16T21:42:45.525569Z", "url": "https://files.pythonhosted.org/packages/b0/7c/094b12fae2733325d2ebe46603f2140d03738c7f36919a274614ac370a22/convey-1.3rc6.tar.gz", "yanked": false, "yanked_reason": null } ], "1.3rc8": [ { "comment_text": "", "digests": { "md5": "43183c583f23a8aca38b1a93290724a1", "sha256": "0361f8ee53e90c3768dd0abfef132747c435d0bd4206a2b67f349bfb256254d6" }, "downloads": -1, "filename": "convey-1.3rc8.tar.gz", "has_sig": false, "md5_digest": "43183c583f23a8aca38b1a93290724a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 118851, "upload_time": "2020-01-17T16:30:54", "upload_time_iso_8601": "2020-01-17T16:30:54.959043Z", "url": "https://files.pythonhosted.org/packages/bc/1a/c27af4e684465b926b34cb8bbc434e5e90d19d9e68a94a9106c0deb3b72f/convey-1.3rc8.tar.gz", "yanked": false, "yanked_reason": null } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "49407606fc50a730dfef94cb91647694", "sha256": "0c3094a1834d40fe4038a2605abd86b1cde954be25392bf45af926ff8e616e56" }, "downloads": -1, "filename": "convey-1.3.15.tar.gz", "has_sig": false, "md5_digest": "49407606fc50a730dfef94cb91647694", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 145911, "upload_time": "2022-05-02T15:09:10", "upload_time_iso_8601": "2022-05-02T15:09:10.390466Z", "url": "https://files.pythonhosted.org/packages/97/5a/201d7b666580374aace112b5643c180cdef12079e8c1c083c2a57858c663/convey-1.3.15.tar.gz", "yanked": false, "yanked_reason": null } ], "vulnerabilities": [] }