Browse Source

a first prototype push

master
mb@mb 5 years ago
parent
commit
21c28012c0
  1. 2
      .gitignore
  2. 31
      README.md
  3. BIN
      Screenshot from 2018-12-05 00-32-36.png
  4. 13
      api_register_app.py
  5. 30
      interface.py
  6. 98
      mastodon_api_tests.py
  7. 26
      static/css/stylesheet.css
  8. 12
      templates/base.html
  9. 22
      templates/index.html

2
.gitignore

@ -0,0 +1,2 @@
*.secret
*pycache*

31
README.md

@ -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)

BIN
Screenshot from 2018-12-05 00-32-36.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 KiB

13
api_register_app.py

@ -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'
)

30
interface.py

@ -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)

98
mastodon_api_tests.py

@ -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)

26
static/css/stylesheet.css

@ -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;
}

12
templates/base.html

@ -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>

22
templates/index.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…
Cancel
Save