mb@mb
6 years ago
9 changed files with 233 additions and 1 deletions
@ -0,0 +1,2 @@ |
|||
*.secret |
|||
*pycache* |
@ -1,3 +1,32 @@ |
|||
# mastodon.api.prototype |
|||
|
|||
a mastodon api prototyping area |
|||
A mastodon api prototyping area, a Flask interface exploration to test toots in other environments. |
|||
|
|||
## These things are dependencies |
|||
|
|||
* Mastodon.py (```$ pip3 install Mastodon.py```) |
|||
* Flask (```$ pip3 install flask```) |
|||
|
|||
## At the first time the script is running (and the mastodon api is used ...) |
|||
|
|||
Change the ```name``` and ```instance``` in the file ```api_register_app.py```. |
|||
|
|||
And run: ```$ python3 api_register_app.py``` |
|||
|
|||
## To run it |
|||
|
|||
Change the ```api_base_url``` in ```interface.py``` to the instance that you want to use. |
|||
|
|||
And then ... |
|||
|
|||
```$ python3 interface.py``` |
|||
|
|||
Browse to localhost:5000 ! :) |
|||
|
|||
## More ... |
|||
|
|||
There are a couple of API tests in the ```mastodon_api_tests.py``` file. |
|||
|
|||
## Preview |
|||
|
|||
![](Screenshot\ from\ 2018-12-05\ 00-32-36.png) |
After Width: | Height: | Size: 907 KiB |
@ -0,0 +1,13 @@ |
|||
from mastodon import Mastodon |
|||
|
|||
# Register app - only once! |
|||
|
|||
name = 'reader' |
|||
instance = 'https://post.lurk.org' |
|||
|
|||
Mastodon.create_app( |
|||
name, |
|||
api_base_url = instance, |
|||
to_file = 'api_clientcred.secret', |
|||
scopes = 'read' |
|||
) |
@ -0,0 +1,30 @@ |
|||
#!/usr/bin/env python3 |
|||
|
|||
import flask |
|||
from mastodon import Mastodon |
|||
|
|||
""" A little test, prototype for an experimental Mastodon interface, using the Mastodon API through the Mastodon.py library. """ |
|||
|
|||
def get_timeline(): |
|||
mastodon = Mastodon( |
|||
client_id = 'api_clientcred.secret', |
|||
api_base_url = 'https://post.lurk.org' |
|||
) |
|||
timeline = mastodon.timeline_local(max_id=None, since_id=None, limit=40) |
|||
# timeline = mastodon.timeline_public(max_id=None, since_id=None, limit=40, only_media=False) |
|||
instance = mastodon.instance() |
|||
return timeline, instance |
|||
|
|||
# Create the Flask application. |
|||
APP = flask.Flask(__name__) |
|||
|
|||
@APP.route('/', methods=['GET']) |
|||
def index(): |
|||
""" Displays the index page accessible at '/' """ |
|||
content, instance = get_timeline() |
|||
html = flask.render_template('index.html', content=content, instance=instance) |
|||
return html |
|||
|
|||
if __name__ == '__main__': |
|||
APP.debug=True |
|||
APP.run(port=5000) |
@ -0,0 +1,98 @@ |
|||
#!/usr/bin/python3 |
|||
|
|||
from mastodon import Mastodon, StreamListener |
|||
from pprint import pprint |
|||
|
|||
# This is a test environment of Mastodon.py :) |
|||
# https://mastodonpy.readthedocs.io/en/stable/ |
|||
# https://github.com/halcy/Mastodon.py |
|||
|
|||
# Install Mastodon.py through pip: |
|||
# $ pip3 install Mastodon.py |
|||
|
|||
# --- |
|||
|
|||
# Register app - only once! |
|||
# Mastodon.create_app( |
|||
# 'reader', |
|||
# api_base_url = 'https://post.lurk.org', |
|||
# to_file = 'api_clientcred.secret', |
|||
# scopes = 'read' |
|||
# ) |
|||
|
|||
# --- only api_clientcred.secret is needed --- |
|||
|
|||
# Log in - either every time, or use persisted (how does persisted work ... ?) |
|||
mastodon = Mastodon( |
|||
client_id = 'api_clientcred.secret', |
|||
api_base_url = 'https://post.lurk.org' |
|||
) |
|||
|
|||
# Bits of information about my instance. |
|||
instance = mastodon.instance() |
|||
# pprint(instance) |
|||
|
|||
instance_peers = mastodon.instance_peers() |
|||
# pprint(instance_peers) |
|||
# print(len(instance_peers)) |
|||
|
|||
instance_activity = mastodon.instance_activity() |
|||
# pprint(instance_activity) |
|||
|
|||
timeline_local = mastodon.timeline_local(max_id=None, since_id=0, limit=100) |
|||
# All endpoints that are paginated have three parameters: since_id, max_id and limit. since_id allows you to specify the smallest id you want in the returned data. max_id, similarly, allows you to specify the largest. By specifying either one (generally, only one, not both) of them you can go through pages forwards and backwards. |
|||
# https://mastodonpy.readthedocs.io/en/stable/#a-note-about-pagination |
|||
# pprint(timeline_local) |
|||
# print('\nLength of the returned timeline:', len(timeline_local)) |
|||
# 40 seems to be the max for post.lurk.org |
|||
|
|||
# for toot in timeline_local: |
|||
# print(toot.content) |
|||
|
|||
timeline_public = mastodon.timeline_public(max_id=None, since_id=None, limit=100, only_media=False) |
|||
# pprint(timeline_public) |
|||
# print('\nLength of the returned timeline:', len(timeline_public)) |
|||
# 40 seems to be the max for post.lurk.org |
|||
|
|||
next_page = mastodon.fetch_next(timeline_public) |
|||
# Fetches the next page of results of a paginated request. |
|||
# pprint(next_page) |
|||
# print('\nLength of the returned timeline:', len(next_page)) |
|||
|
|||
|
|||
# --- api_usercred.secret is needed --- |
|||
|
|||
# This is only needed once, to create the api_usercred.secret |
|||
# mastodon.log_in( |
|||
# 'mail@manettaberends.nl', |
|||
# 'password', |
|||
# to_file = 'api_usercred.secret' |
|||
# ) |
|||
|
|||
# Log in with api_usercred.secret |
|||
mastodon = Mastodon( |
|||
access_token = 'api_usercred.secret', |
|||
api_base_url = 'https://post.lurk.org' |
|||
) |
|||
|
|||
# Toot from python |
|||
# mastodon.toot('Tooting from python using #mastodonpy !') |
|||
|
|||
# Account details |
|||
account = mastodon.account_verify_credentials() |
|||
# pprint(account) |
|||
|
|||
search = mastodon.search("Tooting") |
|||
# You can only search when you're logged in |
|||
# What is the range of this search? |
|||
# Is it limited to all the instances that crossed the local instance? |
|||
# It does not really pick up statutes ... Also not recent ones. |
|||
# pprint(search) |
|||
|
|||
# --- streaming.api --- |
|||
|
|||
class listener(StreamListener): |
|||
def on_update(self, status): |
|||
print(status.content) |
|||
|
|||
# mastodon.stream_public(listener(), run_async=False, timeout=300, reconnect_async=False, reconnect_async_wait_sec=5) |
@ -0,0 +1,26 @@ |
|||
body{ |
|||
background:linear-gradient(180deg, rgba(250,50,0,0.5), rgba(0,50,200,0.8)); |
|||
position: relative; |
|||
margin:1em auto; |
|||
max-width: 750px; |
|||
|
|||
} |
|||
div.status{ |
|||
padding:1em 0; |
|||
border-bottom:1px dotted black; |
|||
} |
|||
div.username{ |
|||
font-style: italic; |
|||
font-weight: bold; |
|||
float: left; |
|||
padding-right: 0.5em; |
|||
margin-top: 0.95em; |
|||
} |
|||
div.toot{ |
|||
} |
|||
div.media img{ |
|||
width: calc(50% - 4em); |
|||
margin:1em; |
|||
display: inline; |
|||
vertical-align:top; |
|||
} |
@ -0,0 +1,12 @@ |
|||
<!DOCTYPE html> |
|||
<html lang='en'> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<title>{% block title %}{% endblock %}</title> |
|||
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='css/stylesheet.css')}}" /> |
|||
</head> |
|||
<body> |
|||
{% block content %} |
|||
{% endblock %} |
|||
</body> |
|||
</html> |
@ -0,0 +1,22 @@ |
|||
{% extends "base.html" %} |
|||
|
|||
{% block content %} |
|||
<div id="content"> |
|||
<h1>Timeline explorations @ {{ instance.uri }}</h1> |
|||
<div class="stats">{{ instance.stats }}</div> |
|||
{% for status in content %} |
|||
<div class="status"> |
|||
<div class="username">{{ status.account.username }}:</div> |
|||
<div class="toot">{{ status.content | safe }}</div> <!-- http://jinja.pocoo.org/docs/2.10/templates/#safe --> |
|||
<div class="media"> |
|||
{% for media in status.media_attachments %} |
|||
{% if media.type == 'image' %} |
|||
<img src="{{ media.url }}"> |
|||
{% endif %} |
|||
{% endfor %} |
|||
</div> |
|||
</div> |
|||
{% endfor %} |
|||
</div> |
|||
|
|||
{% endblock %} |
Loading…
Reference in new issue