# AIO Ident

Simple ident protocol ([RFC 1413](https://www.rfc-editor.org/rfc/rfc1413)) parser for Python AsyncIO.

# Install

It's just as simple as

```
pip install aioident
```

Doesn't require anything external as it only relies on standard modules.

# Usage

It can connect to a host running an ident daemon.

```python
import asyncio
import aioident

async def main():
    res = await aioident.connect("someone.sometld.com", 5912, 6667) # Assumes you are running at port 6667, and the remote host originates from port 5912 ( don't ask me, it's just some TCP sorcery ;) )
    # res = await aioident.connect("someone.sometld.com", 5912, 6667, 1113) # You can also use a different ident port if needed
    if res.ok and res.type == "UNIX":
        print(f"It works! Username: {res.username}")
    else:
        print(f"It doesn't work. Response: {res.type}")

asyncio.run(main())
# It works! Username: swee
```

It can also parse an ident response that has been already made.

```python
import aioident

def test(text):
    try:
        res = aioident.parse(text)
        if res.ok:
            print(f"Is an ident response. Username is {res.username}")
        else:
            print(f"Is an ident response, but it failed. Error is {res.type}")
    except:
        print("That isn't an ident response.")

test("5912, 6667 : USERID : UNIX : swee") # Spaces are optional (not used in some identd software)
# Is an ident response. Username is swee

test("5912, 6667 : ERROR : NO-USER")
# Is an ident response, but it failed. Error is NO-USER

test("foo bar baz")
# That isn't an ident response.
```

# `Ident` class

A simple class for parsing specific parts of the ident response (like checking statuses in requests)

This class is always returned with both `aioident.connect` and `aioident.parse` however it can also be built manually.

```python
myident = aioident.Ident(5912, 6667, "USERID", "UNIX : swee") # straightforward building

myident.serverport # 5912

myident.clientport # 6667

# ^ It's easy to be confused with those two, but the "server" in this case is the identd listener.

myident.status # "USERID"

myident.data # "UNIX : swee"

# ^ Those four are the values already put in when building

myident.data_split # ["UNIX", "swee"], just splits the colons and automatically strips the spaces for each

myident.ok # True, Returns False if the status is ERROR and not USERID

myident.type # "UNIX", The type of username (usually UNIX) or the reason for error

myident.username # "swee", The username if successful and the type is UNIX. if both aren't true, then it will return None

myident.stringify # "5912, 6667 : USERID : UNIX : swee", Turns that class back into a string for a regular ident response
```

Example 2, with an error

```python
myident = aioident.Ident(5912, 6667, "ERROR", "NO-USER") # still straightforward

myident.serverport # 5912

myident.clientport # 6667

myident.status # "ERROR"

myident.data # "NO-USER"

myident.data_split # ["NO-USER"]

myident.ok # False

myident.type # "NO-USER"

myident.username # None

myident.stringify # "5912, 6667 : ERROR : NO-USER"
```
