main
rodzic
6a1bed1e59
commit
7543a08b62
|
@ -0,0 +1,304 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# use `pip install gql tenacity`
|
||||
|
||||
from gql import gql, Client
|
||||
from gql.transport.requests import RequestsHTTPTransport
|
||||
from gql.transport.exceptions import TransportQueryError
|
||||
from requests.exceptions import HTTPError
|
||||
from tenacity import *
|
||||
|
||||
|
||||
|
||||
# this class has been integrated in Tenacity after 7.0.0 release
|
||||
# see https://github.com/jd/tenacity/blame/c18dcfbf4b6a719f668f12fdb4999afaeef62648/tenacity/retry.py#L86
|
||||
class retry_if_not_exception_type(retry_if_exception):
|
||||
"""Retries except an exception has been raised of one or more types."""
|
||||
|
||||
def __init__(self, exception_types=Exception):
|
||||
self.exception_types = exception_types
|
||||
super(retry_if_not_exception_type, self).__init__(
|
||||
lambda e: not isinstance(e, exception_types))
|
||||
|
||||
|
||||
class BadRequest(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# ==== GQL : Events ====
|
||||
|
||||
CREATE_GQL = gql("""
|
||||
mutation createEvent($organizerActorId: ID!, $attributedToId: ID, $title: String!, $description: String!, $beginsOn: DateTime!, $endsOn: DateTime, $status: EventStatus, $visibility: EventVisibility, $joinOptions: EventJoinOptions, $draft: Boolean, $tags: [String], $picture: MediaInput, $onlineAddress: String, $phoneAddress: String, $category: String, $physicalAddress: AddressInput, $options: EventOptionsInput, $contacts: [Contact]) {
|
||||
createEvent(organizerActorId: $organizerActorId, attributedToId: $attributedToId, title: $title, description: $description, beginsOn: $beginsOn, endsOn: $endsOn, status: $status, visibility: $visibility, joinOptions: $joinOptions, draft: $draft, tags: $tags, picture: $picture, onlineAddress: $onlineAddress, phoneAddress: $phoneAddress, category: $category, physicalAddress: $physicalAddress, options: $options, contacts: $contacts) {
|
||||
id
|
||||
uuid
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
UPDATE_GQL = gql("""
|
||||
mutation updateEvent($id: ID!, $title: String, $description: String, $beginsOn: DateTime, $endsOn: DateTime, $status: EventStatus, $visibility: EventVisibility, $joinOptions: EventJoinOptions, $draft: Boolean, $tags: [String], $picture: PictureInput, $onlineAddress: String, $phoneAddress: String, $organizerActorId: ID, $attributedToId: ID, $category: String, $physicalAddress: AddressInput, $options: EventOptionsInput, $contacts: [Contact]) {
|
||||
updateEvent(eventId: $id, title: $title, description: $description, beginsOn: $beginsOn, endsOn: $endsOn, status: $status, visibility: $visibility, joinOptions: $joinOptions, draft: $draft, tags: $tags, picture: $picture, onlineAddress: $onlineAddress, phoneAddress: $phoneAddress, organizerActorId: $organizerActorId, attributedToId: $attributedToId, category: $category, physicalAddress: $physicalAddress, options: $options, contacts: $contacts) {
|
||||
id
|
||||
uuid
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
CANCEL_GQL = gql("""
|
||||
mutation updateEvent($eventId: ID!) {
|
||||
updateEvent(eventId: $eventId, status: CANCELLED) {
|
||||
id
|
||||
uuid
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
CONFIRM_GQL = gql("""
|
||||
mutation updateEvent($eventId: ID!) {
|
||||
updateEvent(eventId: $eventId, status: CONFIRMED) {
|
||||
id
|
||||
uuid
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
DELETE_GQL = gql("""
|
||||
mutation DeleteEvent($eventId: ID!) {
|
||||
deleteEvent(eventId: $eventId) {
|
||||
id
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
# ==== /GQL : Events ====
|
||||
|
||||
# ==== GQL : Actors ====
|
||||
|
||||
CREATE_USER_GQL = gql("""
|
||||
mutation createUser($email: String!, $locale: String="fr", $password: String!) {
|
||||
createUser(email: $email, locale: $locale, password: $password) {
|
||||
id
|
||||
}
|
||||
}""")
|
||||
|
||||
CREATE_GROUP_GQL = gql("""
|
||||
mutation createGroup($name: String, $preferredUsername: String!, $summary: String = "") {
|
||||
createGroup(name: $name, preferredUsername: $preferredUsername, summary: $summary) {
|
||||
id
|
||||
}
|
||||
}""")
|
||||
|
||||
CREATE_PERSON_GQL = gql("""
|
||||
mutation createPerson($name: String, $preferredUsername: String!, $summary: String = "") {
|
||||
createPerson(name: $name, preferredUsername: $preferredUsername, summary: $summary) {
|
||||
id url
|
||||
}
|
||||
}""")
|
||||
|
||||
CREATE_MEMBER_GQL = gql("""
|
||||
mutation inviteMember($groupId: ID!, $targetActorUsername: String!) {
|
||||
inviteMember(groupId: $groupId, targetActorUsername: $targetActorUsername) {
|
||||
id role
|
||||
}
|
||||
}""")
|
||||
|
||||
UPDATE_MEMBER_GQL = gql("""
|
||||
mutation updateMemberRole($memberId: ID!, $role:MemberRoleEnum!) {
|
||||
updateMember(memberId: $memberId, role: $role) {
|
||||
id role
|
||||
}
|
||||
}""")
|
||||
|
||||
# ==== /GQL : Users ====
|
||||
|
||||
# ==== GQL : credentials ====
|
||||
|
||||
LOGIN_GQL = gql("""
|
||||
mutation login($email: String!, $password: String!) {
|
||||
login(email: $email, password: $password) {
|
||||
accessToken refreshToken
|
||||
}
|
||||
}""")
|
||||
|
||||
REFRESH_TOKEN_GQL = gql("""
|
||||
mutation RefreshToken($rt:String!) {
|
||||
refreshToken(refreshToken: $rt) {
|
||||
accessToken refreshToken
|
||||
}
|
||||
}""")
|
||||
|
||||
LOGOUT_GQL = gql("""
|
||||
mutation logout($rt: String!) {
|
||||
logout(refreshToken: $rt)
|
||||
}""")
|
||||
|
||||
# ==== /GQL : credentials ====
|
||||
|
||||
# ==== GQL : identities - actors - persons and groups ====
|
||||
|
||||
PROFILES_GQL = gql("""
|
||||
query Identities { identities { ...ActorFragment } }
|
||||
fragment ActorFragment on Actor { id type preferredUsername name url}
|
||||
""")
|
||||
|
||||
GROUPS_GQL = gql("""
|
||||
query LoggedUserMemberships($membershipName: String, $page: Int, $limit: Int) {
|
||||
loggedUser {
|
||||
memberships(name: $membershipName, page: $page, limit: $limit) {
|
||||
elements {
|
||||
role
|
||||
actor { ...ActorFragment }
|
||||
parent { ...ActorFragment }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fragment ActorFragment on Actor { id type preferredUsername name }
|
||||
""")
|
||||
|
||||
|
||||
|
||||
class Mobilizon():
|
||||
__slots__ = 'client'
|
||||
|
||||
def __init__(self, endpoint, bearer=None):
|
||||
self.client = self._build_client(endpoint, bearer)
|
||||
|
||||
# events
|
||||
|
||||
def create_event(self, actor_id, variables):
|
||||
variables["organizerActorId"] = actor_id
|
||||
return self._publish(CREATE_GQL, variables)
|
||||
|
||||
def update_event(self, actor_id, variables):
|
||||
variables["organizerActorId"] = actor_id
|
||||
return self._publish(UPDATE_GQL, variables)
|
||||
|
||||
def confirm_event(self, event_id):
|
||||
variables = dict()
|
||||
variables["eventId"] = event_id
|
||||
return self._publish(CONFIRM_GQL, variables)
|
||||
|
||||
def cancel_event(self, event_id):
|
||||
variables = dict()
|
||||
variables["eventId"] = event_id
|
||||
return self._publish(CANCEL_GQL, variables)
|
||||
|
||||
def delete_event(self, actor_id, event_id):
|
||||
variables = { "actorId": actor_id,
|
||||
"eventId" : event_id }
|
||||
return self._publish(DELETE_GQL, variables)
|
||||
|
||||
# actors
|
||||
|
||||
def create_user(self, email, password):
|
||||
variables = dict()
|
||||
variables["email"] = email
|
||||
variables["password"] = password
|
||||
return self._publish(CREATE_USER_GQL, variables)
|
||||
|
||||
def create_person(self, name, preferredUsername, summary = ""):
|
||||
variables = dict()
|
||||
variables["name"] = name
|
||||
variables["preferredUsername"] = preferredUsername
|
||||
variables["summary"] = summary
|
||||
return self._publish(CREATE_PERSON_GQL, variables)['createPerson']
|
||||
|
||||
def create_group(self, name, preferredUsername, summary = ""):
|
||||
variables = dict()
|
||||
variables["name"] = name
|
||||
variables["preferredUsername"] = preferredUsername
|
||||
variables["summary"] = summary
|
||||
return self._publish(CREATE_GROUP_GQL, variables)['createGroup']
|
||||
|
||||
def create_member(self, group_id, preferredUsername):
|
||||
variables = dict()
|
||||
variables["groupId"] = group_id
|
||||
variables["targetActorUsername"] = preferredUsername
|
||||
return self._publish(CREATE_MEMBER_GQL, variables)['inviteMember']
|
||||
|
||||
def update_member(self, memberId, role):
|
||||
variables = dict()
|
||||
variables["memberId"] = memberId
|
||||
variables["role"] = role
|
||||
return self._publish(UPDATE_MEMBER_GQL, variables)['updateMember']
|
||||
|
||||
# users / credentials
|
||||
|
||||
def login(self, email, password):
|
||||
variables = dict()
|
||||
variables["email"] = email
|
||||
variables["password"] = password
|
||||
data = self._publish(LOGIN_GQL, variables)
|
||||
login = data['login']
|
||||
return login['accessToken'], login['refreshToken']
|
||||
|
||||
def logout(self, rt):
|
||||
variables = dict()
|
||||
variables["rt"] = rt
|
||||
return self._publish(LOGOUT_GQL, variables) # void
|
||||
|
||||
def refresh_token(self, refresh_token:str):
|
||||
variables = dict()
|
||||
variables = { 'rt':refresh_token }
|
||||
return self._publish(REFRESH_TOKEN_GQL, variables)
|
||||
|
||||
def user_identities(self):
|
||||
variables = dict()
|
||||
data = self._publish(PROFILES_GQL, variables)
|
||||
profiles = data['identities']
|
||||
return profiles
|
||||
|
||||
def user_memberships(self):
|
||||
variables = { "limit": 20 }
|
||||
data = self._publish(GROUPS_GQL, variables)
|
||||
memberships = data['loggedUser']['memberships']['elements']
|
||||
return memberships
|
||||
|
||||
|
||||
# interns
|
||||
|
||||
def _build_client(self, endpoint, bearer=None):
|
||||
headers = dict()
|
||||
if bearer is not None:
|
||||
headers['Authorization']='Bearer '+bearer
|
||||
transport = RequestsHTTPTransport(
|
||||
url=endpoint,
|
||||
headers=headers,
|
||||
verify=True,
|
||||
#retries=3,
|
||||
)
|
||||
return Client(transport=transport)
|
||||
|
||||
|
||||
# attempts at 0s, 2s, 4s, 8s
|
||||
@retry(reraise=True, retry=retry_if_not_exception_type(BadRequest), stop=stop_after_attempt(4), wait=wait_exponential(multiplier=2))
|
||||
def _publish(self, mutation, variables):
|
||||
try:
|
||||
r = self.client.execute(mutation, variable_values=variables)
|
||||
except HTTPError as e:
|
||||
if e.response.status_code in [400,404]:
|
||||
raise BadRequest(e)
|
||||
else:
|
||||
raise
|
||||
except TransportQueryError as e:
|
||||
raise BadRequest(e)
|
||||
except:
|
||||
raise
|
||||
return r
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
endpoint = sys.argv[1]
|
||||
bearer = sys.argv[2]
|
||||
actor_id = sys.argv[3]
|
||||
import json
|
||||
event = json.load(sys.stdin)
|
||||
r = Mobilizon(endpoint, bearer).create_event(actor_id, event)
|
||||
print(json.dumps(r))
|
Ładowanie…
Reference in New Issue