first shoot
This commit is contained in:
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
include *.txt *.rst
|
||||
27
README.rst
Normal file
27
README.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
============
|
||||
Wallabag API
|
||||
============
|
||||
|
||||
Python API for Wallabagap
|
||||
|
||||
Requirements :
|
||||
==============
|
||||
* Flask == 0.10.1
|
||||
* requests == 2.5.0
|
||||
|
||||
|
||||
Installation:
|
||||
=============
|
||||
to get the project, from your virtualenv, do :
|
||||
|
||||
.. code:: python
|
||||
|
||||
git clone https://github.com/foxmask/wallabag-api/
|
||||
|
||||
TODO :
|
||||
======
|
||||
|
||||
Wait the final release of http://v2.wallabag.org to be able to use the REST API completly
|
||||
this final release should be able to provide an oauth with the exchange of the token
|
||||
|
||||
|
||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Flask==0.10.1
|
||||
requests==2.5.0
|
||||
37
setup.py
Normal file
37
setup.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from setuptools import setup, find_packages
|
||||
from wallabag_api import __version__ as version
|
||||
import os
|
||||
|
||||
|
||||
def strip_comments(l):
|
||||
return l.split('#', 1)[0].strip()
|
||||
|
||||
|
||||
def reqs(*f):
|
||||
return list(filter(None, [strip_comments(l) for l in open(
|
||||
os.path.join(os.getcwd(), *f)).readlines()]))
|
||||
|
||||
install_requires = reqs('requirements.txt')
|
||||
|
||||
setup(
|
||||
name='wallabag_api',
|
||||
version=version,
|
||||
description='Wallabag API',
|
||||
author='Olivier Demah',
|
||||
author_email='olivier@foxmask.info',
|
||||
url='https://github.com/foxmask/wallabag_api',
|
||||
download_url="https://github.com/foxmask/wallabag_api/archive/wallabag_api-"
|
||||
+ version + ".zip",
|
||||
packages=find_packages(),
|
||||
classifiers=[
|
||||
'Development Status :: 4 - Beta',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
],
|
||||
install_requires=install_requires,
|
||||
include_package_data=True,
|
||||
)
|
||||
2
wallabag_api/__init__.py
Normal file
2
wallabag_api/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
VERSION = (0, 0, 1) # PEP 386
|
||||
__version__ = ".".join([str(x) for x in VERSION])
|
||||
135
wallabag_api/wallabag.py
Normal file
135
wallabag_api/wallabag.py
Normal file
@@ -0,0 +1,135 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__author__ = 'foxmask'
|
||||
|
||||
import requests
|
||||
import logging
|
||||
|
||||
logging.basicConfig(format='%(message)s', level=logging.INFO)
|
||||
|
||||
__all__ = ['Wallabag']
|
||||
|
||||
|
||||
class Wallabag(object):
|
||||
"""
|
||||
Python Class 'Wallabag' to deal with Wallabagap REST API
|
||||
This class is able to handle any data from your Wallabagap account
|
||||
"""
|
||||
|
||||
host = ''
|
||||
api_key = ''
|
||||
user_agent = ''
|
||||
|
||||
def __init__(self, host='http://v2.wallabag.org', api_key='', user_agent="WallabagPython"):
|
||||
"""
|
||||
init variable
|
||||
:param host: string url to the official API Wallabagap
|
||||
:param api_key: string of the key provided by Wallabagap
|
||||
:param user_agent
|
||||
"""
|
||||
self.host = host
|
||||
self.api_key = api_key
|
||||
self.user_agent = user_agent
|
||||
|
||||
def get_host(self):
|
||||
"""
|
||||
get the host from which to get API
|
||||
:return host
|
||||
"""
|
||||
return self.host
|
||||
|
||||
def query(self, url, params={}, method='get'):
|
||||
"""
|
||||
Do a query to the System API
|
||||
:param url: url to the API
|
||||
:param params: a dict with all the necessary things to query the API
|
||||
:return json data
|
||||
"""
|
||||
#params = params
|
||||
params['key'] = self.api_key
|
||||
if method == 'get':
|
||||
r = requests.get(self.get_host() + url, params=params)
|
||||
elif method == 'post':
|
||||
r = requests.post(self.get_host() + url, params=params)
|
||||
elif method == 'patch':
|
||||
r = requests.patch(self.get_host() + url, params=params)
|
||||
elif method == 'delete':
|
||||
r = requests.delete(self.get_host() + url, params=params)
|
||||
return self.handle_json_response(r)
|
||||
|
||||
|
||||
def handle_json_response(self, responses):
|
||||
"""
|
||||
get the json data response
|
||||
:param responses: the json response
|
||||
:return the json data without 'root' node
|
||||
"""
|
||||
if responses.status_code != 200:
|
||||
raise Exception("Wrong status code: ", responses.status_code)
|
||||
json_data = {}
|
||||
try:
|
||||
json_data = responses.json()
|
||||
except:
|
||||
for error in json_data['errors']:
|
||||
logging.error("Wallabag: %s" % \
|
||||
json_data['errors'][error]['content'])
|
||||
return json_data
|
||||
|
||||
def get(self, token, user):
|
||||
"""
|
||||
List unread entries for the given user
|
||||
:param token: the token that identified the user to access the API
|
||||
:param user: the current user
|
||||
:return json data
|
||||
"""
|
||||
return self.get_entries(token, user)
|
||||
|
||||
def get_entries(self, token, user):
|
||||
"""
|
||||
List unread entries for the given user
|
||||
:param token: the token that identified the user to access the API
|
||||
:param user: the current user
|
||||
:return json data
|
||||
"""
|
||||
return self.query('/api/u/{user}/entries.json'.format(user=user), {'token': token}, method="get")
|
||||
|
||||
def get_entry(self, token, user, entry):
|
||||
"""
|
||||
Fetch an entry, regardless the status flags
|
||||
:param user: entry of that user
|
||||
:param entry: the entry
|
||||
:return json data
|
||||
"""
|
||||
return self.query('/api/u/{user}/entry/{entry}'.format(user=user, entry=entry),
|
||||
{'token': token}, method="get")
|
||||
|
||||
def post_entries(self, token, user, url=[], tags=[]):
|
||||
"""
|
||||
Save a new entry for the given user
|
||||
:param user: entry of that user
|
||||
:param url: the url of the note to store
|
||||
:param tags: the tags of the note to store if provided
|
||||
:return json data
|
||||
"""
|
||||
params = {'token': token, 'url': url}
|
||||
if len(tags) > 0:
|
||||
params = {'token': token, 'url': url, 'tags': tags}
|
||||
return self.query('/api/u/{user}/entries.json'.format(user=user), params, method="post")
|
||||
|
||||
def patch_entries(self, token, user, entry=[]):
|
||||
"""
|
||||
Change several properties of an entry. I.E tags, archived, starred and deleted status
|
||||
:param user: entry of that user
|
||||
:param entry: the entry to 'patch'
|
||||
:return json data
|
||||
"""
|
||||
params = {'token': token, 'entry': entry}
|
||||
return self.query('/api/u/{user}/entries.json'.format(user=user), params, method="patch")
|
||||
|
||||
def delete_entry(self, token, user, entry):
|
||||
"""
|
||||
Delete an entry
|
||||
:param user: entry of that user
|
||||
:param entry: the entry to 'delete'
|
||||
:return json data
|
||||
"""
|
||||
return self.query('/api/u/{user}/entry/{entry}'.format(user=user, entry=entry), {'token': token}, method="delete")
|
||||
44
wallabag_api/wallabag_test.py
Normal file
44
wallabag_api/wallabag_test.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import unittest
|
||||
from wallabag import Wallabag
|
||||
|
||||
|
||||
class TestWallabag(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.host = "http://localhost:5000"
|
||||
self.api_key = '12334567890'
|
||||
self.user = 'foxmask'
|
||||
|
||||
def test_get(self):
|
||||
w = Wallabag(self.host).get('ABCD', self.user)
|
||||
self.assertIsInstance(w, dict)
|
||||
|
||||
def test_get_entries(self):
|
||||
w = Wallabag(self.host).get('ABCD', self.user)
|
||||
self.assertIsInstance(w, dict)
|
||||
|
||||
def test_get_entry(self):
|
||||
w = Wallabag(self.host).get_entry('ABCD', self.user, 1)
|
||||
self.assertTrue(w, str)
|
||||
|
||||
def test_post_entries(self):
|
||||
url = ['http://foobar.com/', 'http://barfoo.com/']
|
||||
tags = ['foo', 'bar']
|
||||
w = Wallabag(self.host).post_entries('ABCD', self.user, url, tags)
|
||||
self.assertTrue(w, True)
|
||||
|
||||
def test_patch_entries(self):
|
||||
entry = []
|
||||
entry.append('fourth content')
|
||||
entry.append('fifth content')
|
||||
w = Wallabag(self.host).patch_entries('ABCD', self.user, entry)
|
||||
self.assertTrue(w, True)
|
||||
|
||||
def test_delete_entry(self):
|
||||
entry = 1
|
||||
w = Wallabag(self.host).delete_entry('ABCD', self.user, entry)
|
||||
self.assertTrue(w, True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
62
wallabag_mock.py
Normal file
62
wallabag_mock.py
Normal file
@@ -0,0 +1,62 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
__author__ = 'foxmask'
|
||||
import json
|
||||
from flask import Flask, request
|
||||
|
||||
"""
|
||||
The main purpose of this script is to replace v2.wallabag.org itself
|
||||
just run :
|
||||
python wallabag_mock.py &
|
||||
and then you can launch
|
||||
python wallabag_test.py
|
||||
|
||||
"""
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/api/u/<user>/entries.json', methods=['GET'])
|
||||
def get(user):
|
||||
my_data = dict()
|
||||
if user == 'foxmask':
|
||||
my_data['entry'] = 'first content'
|
||||
my_data['entry'] = 'second content'
|
||||
return json.dumps(my_data,encoding='utf-8')
|
||||
|
||||
@app.route('/api/u/<user>/entries.json', methods=['GET'])
|
||||
def get_entries(user):
|
||||
my_data = dict()
|
||||
if user == 'foxmask':
|
||||
my_data['entry'] = 'first content'
|
||||
my_data['entry'] = 'second content'
|
||||
return json.dumps(my_data,encoding='utf-8')
|
||||
|
||||
@app.route('/api/u/<user>/entry/<int:entry>', methods=['GET'])
|
||||
def get_entry(user, entry):
|
||||
my_data = dict()
|
||||
if user == 'foxmask' and entry == 1:
|
||||
my_data['entry'] = 'third content'
|
||||
return json.dumps(my_data,encoding='utf-8')
|
||||
|
||||
@app.route('/api/u/<user>/entries.json', methods=['POST'])
|
||||
def post_entries(user):
|
||||
if user == 'foxmask':
|
||||
return json.dumps(True)
|
||||
else:
|
||||
return json.dumps(False)
|
||||
|
||||
@app.route('/api/u/<user>/entries.json', methods=['PATCH'])
|
||||
def patch_entries(user):
|
||||
if user == 'foxmask':
|
||||
return json.dumps(True)
|
||||
else:
|
||||
return json.dumps(False)
|
||||
|
||||
@app.route('/api/u/<user>/entry/<int:entry>', methods=['DELETE'])
|
||||
def delete_entry(user, entry):
|
||||
if user == 'foxmask' and entry == 1:
|
||||
return json.dumps(True)
|
||||
else:
|
||||
return json.dumps(False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True)
|
||||
Reference in New Issue
Block a user