twtxt is a decentralised, minimalist microblogging service for hackers.

Overview

twtxt

Latest version released on PyPi Build status of the master branch Test coverage Documentation Status Package license

twtxt is a decentralised, minimalist microblogging service for hackers.

So you want to get some thoughts out on the internet in a convenient and slick way while also following the gibberish of others? Instead of signing up at a closed and/or regulated microblogging platform, getting your status updates out with twtxt is as easy as putting them in a publicly accessible text file. The URL pointing to this file is your identity, your account. twtxt then tracks these text files, like a feedreader, and builds your unique timeline out of them, depending on which files you track. The format is simple, human readable, and integrates well with UNIX command line utilities.

Demo

tl;dr: twtxt is a CLI tool, as well as a format specification for self-hosted flat file based microblogging.

Features

  • A beautiful command-line interface thanks to click.
  • Asynchronous HTTP requests thanks to asyncio/aiohttp and Python 3.
  • Integrates well with existing tools (scp, cut, echo, date, etc.) and your shell.
  • Don’t like the official client? Tweet using echo -e "`date +%FT%T%:z`\tHello world!" >> twtxt.txt!

Documentation

Check out the full documentation at: http://twtxt.readthedocs.org/en/latest/

Community

Contributions

License

twtxt is released under the MIT License. See the bundled LICENSE file for details.

Comments
  • Add # for comments in Feed

    Add # for comments in Feed

    Hello,

    it would be nice, if the client ignores lines starting with #. This way the feed format would be extensible with e.g. the date of creation or other meta fields (e.g. # nickname dracoblue is a hint for clients, who get it).

    question 
    opened by DracoBlue 37
  • Include user’s twtxt nick and URL in their user-agent string

    Include user’s twtxt nick and URL in their user-agent string

    Like proposed here: https://github.com/buckket/twtxt/issues/3#issuecomment-182738604 This allows searching the webserver’s access log for one’s followers.

    Format: twtxt/1.2.3 (+https://example.com/twtxt.txt; @somebody)

    Any other suggestions for the format we should use?

    enhancement 
    opened by buckket 12
  • Resolve Nicknames, which are Domains

    Resolve Nicknames, which are Domains

    I host a twtxt file at https://dracoblue.net/twtxt.txt

    If I reply to somebody like @buckket it's not clea if other people saved him as @buckket, too. Or a different person.

    Would it be possible to have something like @example.org resolves preferably to the person who hosts https://example.org/twtxt.txt?

    enhancement 
    opened by DracoBlue 12
  • Empty loop in get_remote_tweets leads to error (variable referenced before assignment)

    Empty loop in get_remote_tweets leads to error (variable referenced before assignment)

    > twtxt timeline
    Traceback (most recent call last):
      File "/usr/bin/twtxt", line 9, in <module>
        load_entry_point('twtxt==1.2.1', 'console_scripts', 'twtxt')()
      File "/usr/lib/python3.4/site-packages/click/core.py", line 716, in __call__
        return self.main(*args, **kwargs)
      File "/usr/lib/python3.4/site-packages/click/core.py", line 696, in main
        rv = self.invoke(ctx)
      File "/usr/lib/python3.4/site-packages/click/core.py", line 1060, in invoke
        return _process_result(sub_ctx.command.invoke(sub_ctx))
      File "/usr/lib/python3.4/site-packages/click/core.py", line 889, in invoke
        return ctx.invoke(self.callback, **ctx.params)
      File "/usr/lib/python3.4/site-packages/click/core.py", line 534, in invoke
        return callback(*args, **kwargs)
      File "/usr/lib/python3.4/site-packages/click/decorators.py", line 17, in new_func
        return f(get_current_context(), *args, **kwargs)
      File "/usr/lib/python3.4/site-packages/twtxt/cli.py", line 126, in timeline
        tweets = get_remote_tweets(sources, limit, timeout, cache)
      File "/usr/lib/python3.4/site-packages/twtxt/twhttp.py", line 123, in get_remote_tweets
        return tweets
    UnboundLocalError: local variable 'tweets' referenced before assignment
    

    This started after I added a few new follow urls, I don't know which one does that, will try to find out.

    bug waiting 
    opened by kdave 11
  • Support for RSS and Atom feeds

    Support for RSS and Atom feeds

    A lot of websites already provide feeds in RSS or Atom format. Popular browsers, like Mozilla Firefox, Microsoft Internet Explorer or Safari include features to view such feeds and subscribe to them. Using the Python feedparser module twtxt could be used to subscribe to such a feed without lots of additional code.

    This would also sidestep any debate regarding embedded media, metadata etc. as those who want metadata could always just provide Atom feeds (RSS is less capable). I have written a script to convert twtxt files to Atom feeds which could be patched for more metadata if so desired: http://news.dieweltistgarnichtso.net/bin/twtxt2atom

    enhancement 
    opened by erlehmann 11
  • Increase default message size

    Increase default message size

    140 characters is an archaic limitation that twitter only used so that single tweets could fit in an SMS. it's equivalent to not allowing lines of source code over 80 characters because then they won't fit on a punch card. Even doubling it, or 256 characters, would be an awesome improvement.

    question 
    opened by ghost 9
  • Follower url works in browser, does not in twtxt

    Follower url works in browser, does not in twtxt

    HTTP:

    twtxt -v follow mdom http://www.domgoergen.com/twtxt.txt
    ...
    twtxt.twhttp DEBUG    400, message='deflate'
    

    HTTPS

    ...
    twtxt.twhttp DEBUG    hostname 'www.domgoergen.com' doesn't match either of '*.kasserver.com', 'kasserver.com'
    

    works in the browser.

    enhancement question 
    opened by kdave 8
  • Updated Docstrings

    Updated Docstrings

    Hello buckket,

    I updated the docstrings of the twtxt/config.py because all the :param where missing. Also added a docstring for models.Source and added a newline to the end of main.py to follow PEP8.

    I look forward to contribute more in the future. Altoyyr

    opened by JDurstberger 8
  • Config file sanity checking, better error reporting

    Config file sanity checking, better error reporting

    I did a stupid typo Fasle instead of False in the config. This is reported as raw python exception. It would be good to print at least the line, or eg. the expected value type. The overall config sanity could look for uknown key names.

    enhancement 
    opened by kdave 8
  • Evil escape sequences

    Evil escape sequences

    Just a warning for those of you who are writing twtxt terminal clients: Please visit https://mosh.mit.edu/ and search for “Careful terminal emulation”. While we still ought to allow unicode, we should probably think about sanitizing each tweet before displaying it.

    ~@kas

    bug enhancement 
    opened by kseistrup 8
  • Add support of Python 3.7+

    Add support of Python 3.7+

    Problem: Generator-based coroutines are deprecated and scheduled for removal in Python 3.11 (docs). Due to that, twtxt doesn't work with Python 3.7+.

    Solution: I have changed gererator-based coroutines to async-def coroutines. Other dependencies have also been updated to current versions. Important: breaking changes, won't work with Python 3.6 or lower.

    Passed tests: https://github.com/win0err/twtxt/actions/runs/2009500872 I'll create a PR with integration with GitHub Actions in a separate PR.

    Closes #140, closes #141, closes #161, closes #162, closes #163

    P.S. Please, test the changes manually.

    enhancement 
    opened by win0err 7
  • Manually changing a nick will will not be noticed by the cache

    Manually changing a nick will will not be noticed by the cache

    When changing a nick in the [followings] section of the the config file it will not be picked up by the timeline command unless the cache for that entry is marked as stale, which only happens when the twtxt file changes.

    Solution: Always used the nick specified in the config file.

    bug 
    opened by buckket 0
  • Development environment pollution / using contained venvs

    Development environment pollution / using contained venvs

    Context

    Currently, running tests and installing the app requires the developer to install packages on the host directly, polluting the system with globally installed packages. This also implies that packages installed in the global scope could pollute the working environment. It would be neat if there was more isolation between twtxt and the machine used to run tests / develop on it.

    Proposed solution

    I would be tempted to add a bootstrapping script that would create a venv in which dev requirements and the app itself would be installed. This would ensure some isolation when iterating, as well as guarantee that we don't leak dependencies into the host system when someone sets everything up to run tests, lint or play around with the package.

    Something following the general pattern of the Scripts to Rule Them All feels appealing and could feature a bootstrapping script that sets up a venv (if one doesn't already exists) and installs dependencies in it.

    This would also make it easier to enforce something like a .python-version file to explicitly state what Python version development should happen in (i.e. anything >=3.7, based on the setup.py annotations).

    As a side-benefit, it would also help standardize what is being installed in CI (since we could leverage it the frozen dev requirements instead of manually installing select packages and opening the door to human error / drift in requirements).

    I'd be happy to put that together and push it up if there's interest!

    opened by mcataford 0
  • Can't install twtxt

    Can't install twtxt

    using python installed through chocolatey. Windows 10

    Installing collected packages: twtxt
      WARNING: Failed to write executable - trying to use .deleteme logic
    ERROR: Could not install packages due to an OSError: [WinError 2] The system cannot find the file specified: 'C:\\Python310\\Scripts\\twtxt.exe' -> 'C:\\Python310\\Scripts\\twtxt.exe.deleteme'
    
    bug 
    opened by Obspogon 1
  • Suggestion: a convention for multiline statuses (line breaks)

    Suggestion: a convention for multiline statuses (line breaks)

    I would like to propose to a convention for multiline status updates or newlines in the twtxt format. The convention is backwards compatible with clients that do not support it. The conventions is: when the client sees a sequence of statuses with the same timestamp, join their text with a newline. A feed following this convention looks reasonable in a client that does not understand it as long as the client displays statues with the same timestamp in the order they appear.

    For example, twtxt currently renders

    1845-01-29T12:00:00Z	Once upon a midnight dreary, while I pondered, weak and weary,
    1845-01-29T12:00:00Z	Over many a quaint and curious volume of forgotten lore—
    1845-01-29T12:00:00Z	    While I nodded, nearly napping, suddenly there came a tapping,
    1845-01-29T12:00:00Z	As of some one gently rapping, rapping at my chamber door.
    1845-01-29T12:00:00Z	“’Tis some visitor,” I muttered, “tapping at my chamber door—
    1845-01-29T12:00:00Z	            Only this and nothing more.”
    

    as

    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    Once upon a midnight dreary, while I pondered, weak and weary,
    
    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    Over many a quaint and curious volume of forgotten lore—
    
    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    While I nodded, nearly napping, suddenly there came a tapping,
    
    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    As of some one gently rapping, rapping at my chamber door.
    
    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    “’Tis some visitor,” I muttered, “tapping at my chamber door—
    
    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    Only this and nothing more.”
    

    If support for this convention was implemented, twtxt could render the same file as

    ➤ http://127.0.0.1:8081/poe.txt (175 years ago):
    Once upon a midnight dreary, while I pondered, weak and weary,
    Over many a quaint and curious volume of forgotten lore—
    While I nodded, nearly napping, suddenly there came a tapping,
    As of some one gently rapping, rapping at my chamber door.
    “’Tis some visitor,” I muttered, “tapping at my chamber door—
    Only this and nothing more.”
    

    I have implemented the convention in my twtxt.tcl library and GUI feed reader. I have also made a page explaining it (pretty much like this issue does).

    What do you think?

    enhancement 
    opened by dbohdan 0
  • AUR package no longer working

    AUR package no longer working

    Traceback (most recent call last):
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 584, in _build_master
        ws.require(__requires__)
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 901, in require
        needed = self.resolve(parse_requirements(requirements))
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 792, in resolve
        raise VersionConflict(dist, req).with_context(dependent_req)
    pkg_resources.ContextualVersionConflict: (click 7.1.1 (/usr/lib/python3.8/site-packages), Requirement.parse('click<7,>=6.7'), {'twtxt'})
    
    During handling of the above exception, another exception occurred:
    
    Traceback (most recent call last):
      File "/usr/bin/twtxt", line 6, in <module>
        from pkg_resources import load_entry_point
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3255, in <module>
        def _initialize_master_working_set():
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3238, in _call_aside
        f(*args, **kwargs)
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 3267, in _initialize_master_working_set
        working_set = WorkingSet._build_master()
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 586, in _build_master
        return cls._build_from_requirements(__requires__)
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 599, in _build_from_requirements
        dists = ws.resolve(reqs, Environment())
      File "/usr/lib/python3.8/site-packages/pkg_resources/__init__.py", line 787, in resolve
        raise DistributionNotFound(req, requirers)
    pkg_resources.DistributionNotFound: The 'click<7,>=6.7' distribution was not found and is required by twtxt
    
    bug 
    opened by treeshateorcs 3
Releases(v1.3.1)
  • v1.3.1(Nov 12, 2022)

  • v1.3.0(Nov 12, 2022)

  • v1.2.3(Sep 28, 2017)

  • v1.2.2(Sep 26, 2017)

  • v1.2.1(Feb 16, 2016)

    • Fixed a bug in the mention handling code
    • Nicks are now case-insensitive throughout twtxt
    • Added a character_limit option, to specify when to shorten tweets
    • Added option to include user’s nick and url in twtxt’s user-agent string for greater discovery
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0(Feb 12, 2016)

    • twtxt package is now executable
    • twtxt is now available as wheel archive
    • Check status of feed before following a new source
    • Added a source option to timeline command to only show one specific source
    • Added a view command which is basically an alias for the source option
    • Added support for local caching of remote twtxt files
    • Added support for mentions, see README.rst for more information
    • Added a pre_tweet_hook option, works like post_tweet_hook
    • Added a porcelain option, styles output script-friendly
    Source code(tar.gz)
    Source code(zip)
  • v1.1.0(Feb 7, 2016)

    • Ignore status updates coming form the future.
    • Improved timestamp format by by removing microseconds and using local time.
    • Get confirmation before overwriting an existing source.
    • Allow tweet command to read from stdin. (echo "Test" | twtxt tweet)
    • Allow tweet command to accept unlimited amount of arguments. (twtxt tweet This is also valid)
    • Added an option to change the timeline sorting.
    • Added an option to specify max wait time for HTTP requests.
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Feb 7, 2016)

  • v1.0.0(Feb 7, 2016)

:snake: A simple library to fetch data from the iTunes Store API made for Python >= 3.5

itunespy itunespy is a simple library to fetch data from the iTunes Store API made for Python 3.5 and beyond. Important: Since version 1.6 itunespy no

Fran González 56 Dec 22, 2022
A Pancakeswap and Uniswap trading client (and bot) with limit orders, marker orders, stop-loss, custom gas strategies, a GUI and much more.

Pancakeswap and Uniswap trading client Adam A A Pancakeswap and Uniswap trading client (and bot) with market orders, limit orders, stop-loss, custom g

570 Mar 09, 2022
Generates a coverage badge using coverage.py and the shields.io service.

Welcome to README Coverage Badger 👋 Generates a coverage badge using coverage.py and the shields.io service. Your README file is then updated with th

Victor Miti 10 Dec 06, 2022
Maestral is an open-source Dropbox client written in Python.

Maestral - A light-weight and open-source Dropbox client for macOS and Linux

2.6k Jan 03, 2023
Fetch the details of assets hosted on AWS.

onaws onaws is a simple tool to check if an IP/hostname belongs to the AWS IP space or not. It uses the AWS IP address ranges data published by AWS to

Amal Murali 80 Dec 29, 2022
A simple and modular Discord bot with various functionalities.

All-In-Bot for Discord A simple and modular Discord bot with various functionalities. How to use the bot? Simple! Just invite the bot to your server u

Th3J0nny 3 Jan 29, 2022
A telegram string extractor bot

Made with Python3 (C) @FayasNoushad Copyright permission under MIT License License - https://github.com/FayasNoushad/String-Extract-Bot/blob/main/LIC

Fayas Noushad 12 Jul 19, 2022
A telegram media to gofile bot

GoFile-Bot A telegram media to gofile bot Made with Python3 (C) @FayasNoushad Copyright permission under MIT License License - https://github.com/Fay

Fayas Noushad 37 Nov 14, 2022
• Create Your Own YouTube Info Api.

youtube_data_api • Create Your Own YouTube Info Api. Deploy How to Use https://{ Heroku App Name }.herokuapp.com/api?link={YouTube link} In local Host

lokaman chendekar 12 Oct 02, 2022
This is a small package to interact with the OpenLigaDB API.

OpenLigaDB This is a small package to interact with the OpenLigaDB API. Installation Run the following to install: pip install openligadb Usage from o

1 Dec 31, 2021
Telegram bot using python

Telegram bot using python

Masha Kubyshina 1 Oct 11, 2021
DISCORD script to automate sending messages to a particular server

discord discord script This script sends random quotes to an discord server and tags random users on the server in the process MADE WITH LOVE BY SACS

Solomon ogu 1 Nov 06, 2021
A modified Sequential and NLP based Bot

A modified Sequential and NLP based Bot I improvised this bot a bit with some implementations as a part of my own hobby project :) Note: I do not own

Jay Desale 2 Jan 07, 2022
Data from popular CS:GO website hltv.org

Welcome to hltv-data 👋 🎮 Data from popular CS:GO website hltv.org Install pip install hltv-data Usage The public methods can be reached using HLTVCl

Dariusz Choruży 28 Dec 23, 2022
A multi-platform HTTP(S) Reverse Shell Server and Client in Python 3

Phantom - A multi-platform HTTP(S) Reverse Shell Server and Client Phantom is a multi-platform HTTP(S) Reverse Shell server and client in Python 3. Bi

85 Nov 18, 2022
股票量化

StockQuant Gary-Hertel 请勿提交issue!可以加入交流群与其他朋友一起自学交流,加微信mzjimmy 一、配置文件的设置 启动框架需要先导入必要的模块,并且载入一次配置文件! 配置文件是一个json格式的文件config.json,在docs文件夹中有模板

218 Dec 25, 2022
Buy early bsc gems with custom gas fee, slippage, amount. Auto approve token after buy

Buy early bsc gems with custom gas fee, slippage, amount. Auto approve token after buy. Sell buyed token with custom gas fee, slippage, amount. And more.

Jesus Crypto 206 May 01, 2022
🤖 A discord bot for Dota2 community

BOTA BOT-A is a free Discord Dota 2 bot which provides comprehensive Information of every Dota 2 characters and exciting features for the community. P

Bendang 23 Jun 29, 2022
TwitterBot-ImageCollector - Twitter bot that collects images from likes saves the image

TwitterBot-ImageCollector Bot de Twitter que recolecta imagenes a partir de los

Gx3 Studios 4 Jun 01, 2022
A tool that ensures consistent string quotes in your Python code.

pyquotes Single quotes are superior. And if you disagree, there's an option for this as well. In any case, quotes should be consistent throughout the

Adrian 9 Sep 13, 2022