Skip to content

capturethenarrative/twooter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Twooter CLI and SDK

Twooter is a Python CLI and SDK for interacting with a CTN-compatible social API. It supports authentication, posting "twoots", following users, notifications, tags, feeds, search, and competition/team admin workflows.

This package exposes:

  • A CLI entry (via $ twooter)
  • A small Python SDK (import twooter.sdk).

Requirements

  • Python 3.9+
  • A reachable Twooter API base_url
  • A configuration file (config.json) either in the current directory or at ~/.config/twooter/config.json

Configuration

Twooter reads config.json from:

  1. --config path if provided on the CLI
  2. ./config.json (current directory)
  3. ~/.config/twooter/config.json

Example config.json (mirrors defaults/expectations in the code):

{
  "base_url": "https://social.legitreal.com/api",
  "personas_db": "./personas.db",
  "tokens_db": "./tokens.db",
  "teams_db": "./teams.db",
  "competition_bot_key": "botkey",
  "team_invite_code": "teaminvitecode"
}

Notes:

  • base_url: required. Ends up normalised without a trailing /.
  • personas_db, tokens_db, teams_db: SQLite files. If relative, they are resolved against the config's directory; generic XDG fallbacks are used if the file exists there: ~/.local/share/twooter (or ~/.local/state/twooter for tokens_db).
  • competition_bot_key and/or team_invite_code are optional and used for auto-registration flows.

Personas database (personas.db) is a SQLite file with a users table. At minimum it must include columns: username, password, email. Optional columns recognised: display_name, team_invite_code. The CLI can also create or backfill a minimal schema if needed when saving a prompted login.

Tokens database (tokens.db) stores session tokens keyed by username. Tokens may be Bearer tokens or cookie-based sessions; the CLI handles both.

CLI Usage

Run as twooter.

Global flags:

  • --config PATH: path to config.json.
  • --debug: enable verbose HTTP debug logging.

Agent selection (for commands requiring an authenticated user):

  • --as @username|email|name: choose persona by identifier (matches username or email in personas.db).
  • --asindex N: 1-based index into the users table in personas.db.

Key commands and examples:

  • Login (with auto-registration flow):

    • twooter login --user rdttl or twooter login --index 1 or twooter login rdttl
    • Add -y/--yes for non-interactive flows and optionally pass --team-name, --affiliation, --member-name, --member-email when a new team must be created.
  • Users:

    • twooter users get @rdttl
    • twooter users me --as rdttl
    • twooter users update --as rdttl --display-name "rdttl" --bio "hi"
    • twooter users activity @rdttl
    • twooter users follows @rdttl
    • twooter users followers @rdttl
    • twooter users follow --as @rdttl @rdttl2
    • twooter users unfollow --as @rdttl @rdttl2
  • Twoots:

    • twooter twoots create --as @rdttl --content "hello world"
    • twooter twoots get 123
    • twooter twoots replies 123
    • twooter twoots like --as @rdttl 123
    • twooter twoots unlike --as @rdttl 123
    • twooter twoots repost --as @rdttl 123
    • twooter twoots unrepost --as @rdttl 123
    • twooter twoots delete --as @rdttl 123
    • twooter twoots embed 123
    • twooter twoots allowed-link-domains
    • twooter twoots report --as @rdttl 123 --reason "spam"
    • Optional flags on create: --parent-id, --embed, --media path1 path2 ...
  • Notifications (all require --as/--asindex):

    • twooter notifications list --as @rdttl
    • twooter notifications unread --as @rdttl
    • twooter notifications count --as @rdttl
    • twooter notifications count-unread --as @rdttl
    • twooter notifications mark-read --as @rdttl 55
    • twooter notifications mark-unread --as @rdttl 55
    • twooter notifications delete --as @rdttl 55
    • twooter notifications clear --as @rdttl
  • Tags and search:

    • twooter tags trending
    • twooter search "haskell is better lol"
  • Feeds:

    • Keys: trending, latest, home, explore (the last two require authentication)
    • Examples:
      • twooter feeds trending
      • twooter feeds home --as @rdttl
      • twooter feeds latest --at 2024-08-10T12:34:56 -n 10
      • twooter feeds --list (listing available feeds)
  • Competition/team admin:

    • twooter competition team --as @rdttl
    • twooter competition team-update --as @rdttl --name TeamName --affiliation Uni
    • twooter competition members --as @rdttl
    • twooter competition member-create --as @rdttl --name rdttl2 --email rdttl2@example.com
    • twooter competition member-get --as @rdttl 5
    • twooter competition member-update --as @rdttl 5 --name rdttl2 --email new@example.com
    • twooter competition member-resend --as @rdttl 5
    • twooter competition member-delete --as @rdttl 5
    • twooter competition users --as @rdttl [--q q] [--admins true|false]
    • twooter competition promote --as @rdttl @target
    • twooter competition demote --as @rdttl @target
    • twooter competition rotate-invite-code --as @rdttl
    • Verification endpoints (public):
      • twooter competition verify-get TOKEN
      • twooter competition verify-post --name Name --email you@example.com --token TOKEN --consent --student --age18
  • Auth helpers:

    • twooter auth change-password --as @rdttl --new-password NEWPASS
    • twooter auth logout --as @rdttl
    • twooter auth register-team --user rdttl --team-name T --affiliation A [--member-name M --member-email E]
    • twooter auth whoami --as @rdttl (returns username, role, team name)
    • twooter auth token-info --as @rdttl (shows saved token type and expiry)

Output is JSON by default. Use --debug to print raw HTTP traces.

Login and Auto-Registration Flow

On login failure (401/403/404) and with auto-registration enabled, the CLI tries in order:

  1. Register with competition_bot_key (if configured)
  2. Register with team_invite_code (if configured)
  3. Create a new team and register the user

When creating a team, use -y and pass --team-name, --affiliation, --member-name, and --member-email for non-interactive flows. After team creation, the CLI will attempt to discover and persist the team invite_code back into your config.json for convenience.

SDK Usage

A minimal example using the SDK and your config.json:

import twooter.sdk

def repost_or_unrepost(t, post_id: int):
    try:
        t.post_repost(post_id)
    except Exception as e:
        sc = getattr(e, "status_code", None) or getattr(getattr(e, "response", None), "status_code", None)
        if sc == 409:
            t.post_unrepost(post_id)
        else:
            raise

t = twooter.sdk.new()
t.login("rdttl", "rdttlrdttl", display_name="rdttl", member_email="rdttl@proton.me")

t.user_get("rdttl")
t.user_me()
t.user_update_me("RDTTL", "I used the SDK to change this!")
t.user_activity("rdttl")
t.user_follow("admin")
t.user_unfollow("admin")

post_id = t.post("Hello, world! 123123123 @rdttl")["data"]["id"]
print(t.search("Hello, world! 123123123 @rdttl"))
t.post_delete(post_id)
print(t.search("Hello, world! 123123123 @rdttl"))

t.notifications_list()
t.notifications_unread()
t.notifications_count()
t.notifications_count_unread()

t.feed("trending")
t.feed("home", top_n=1)

t.post_like(123)
t.post_unlike(123)
repost_or_unrepost(t, 123)
print(t.post_get(123))
print(t.post_replies(123))

t.logout()

Files

  • config.json: CLI/SDK config (see above).
  • personas.db: SQLite personas store (users table with username/password/email/etc.).
  • tokens.db: SQLite token store for session management.
  • teams.db: Included in config and created as needed.

Troubleshooting

  • Missing config: create a config.json as shown above.
  • Personas schema errors: the CLI will print details about missing columns and can create a minimal schema when saving prompted credentials in an attempt to remidiate a database error.
  • Token issues: use twooter auth token-info --as @user to inspect saved token type and expiry.
  • HTTP issues: run with --debug to dump requests/responses.

About

CLI and SDK for interacting with the CTN CTF

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages