First attempt
This commit is contained in:
commit
89677fbeee
22 changed files with 3461 additions and 0 deletions
242
voc/c3data.py
Normal file
242
voc/c3data.py
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
import argparse
|
||||
from os import getenv, path
|
||||
import json
|
||||
|
||||
from gql import Client, gql
|
||||
from gql.transport.aiohttp import AIOHTTPTransport
|
||||
from gql.transport.exceptions import TransportQueryError
|
||||
|
||||
try:
|
||||
from .schedule import Schedule
|
||||
from .event import Event
|
||||
from .room import Room
|
||||
from .tools import load_json, write
|
||||
from . import logger
|
||||
|
||||
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.path.append('.')
|
||||
|
||||
from schedule import Schedule, Event
|
||||
from room import Room
|
||||
from tools import load_json, write
|
||||
from voc import logger
|
||||
|
||||
|
||||
|
||||
transport = AIOHTTPTransport(
|
||||
url=getenv('C3D_URL', 'https://data.c3voc.de/graphql'),
|
||||
headers={'Authorization': getenv('C3D_TOKEN', 'Basic|Bearer XXXX')}
|
||||
)
|
||||
# transport = AIOHTTPTransport(url="http://localhost:5001/graphql")
|
||||
|
||||
# Create a GraphQL client using the defined transport
|
||||
client = Client(transport=transport, fetch_schema_from_transport=True)
|
||||
|
||||
|
||||
def create_conference(schedule: Schedule):
|
||||
conference = schedule.conference()
|
||||
data = {
|
||||
'conference': {
|
||||
'acronym': conference['acronym'],
|
||||
'title': conference['title'],
|
||||
'startDate': conference['start'],
|
||||
'endDate': conference['end'],
|
||||
'daysUsingId': {
|
||||
'create': [{
|
||||
'index': day['index'],
|
||||
'startDate': day['day_start'],
|
||||
'endDate': day['day_end']
|
||||
} for day in schedule.days()]
|
||||
},
|
||||
'roomsUsingId': {
|
||||
'create': [room.graphql() for room in schedule.rooms(mode='obj')]
|
||||
}
|
||||
}
|
||||
}
|
||||
# print(json.dumps(data, indent=2))
|
||||
|
||||
try:
|
||||
result = client.execute(gql('''
|
||||
mutation createConferenceAndDaysAndRooms($input: CreateConferenceInput!) {
|
||||
createConference(input: $input) {
|
||||
conference {
|
||||
id
|
||||
rooms {
|
||||
nodes {
|
||||
guid
|
||||
slug
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'''), variable_values={'input': data})
|
||||
return result['createConference']
|
||||
|
||||
except TransportQueryError as e:
|
||||
# raise exception, error is not 'conference already exists'
|
||||
if 'duplicate key value violates unique constraint "conferences_acronym_key"' != e.errors[0]['message']:
|
||||
raise e
|
||||
|
||||
# conference already exists, so try to get required infos
|
||||
result = get_conference(conference['acronym'])
|
||||
return result
|
||||
|
||||
|
||||
def get_conference(acronym):
|
||||
return client.execute(gql('''
|
||||
query getConferenceAndRooms($acronym: String!) {
|
||||
conference: conferenceByAcronym(acronym: $acronym) {
|
||||
id
|
||||
rooms {
|
||||
nodes {
|
||||
guid
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}'''), variable_values={'acronym': acronym})
|
||||
|
||||
|
||||
def add_room(conference_id, room: Room):
|
||||
result = client.execute(gql('''
|
||||
mutation addRoom($input: UpsertRoomInput!) {
|
||||
upsertRoom(input: $input) {
|
||||
room { guid, name, slug, meta }
|
||||
}
|
||||
}'''), {'input': {'room': {
|
||||
**room.graphql(),
|
||||
'conferenceId': conference_id
|
||||
}
|
||||
}})
|
||||
|
||||
print(result)
|
||||
return result['upsertRoom']['room']['guid']
|
||||
|
||||
|
||||
def add_event(conference_id, room_id, event: Event):
|
||||
data = {
|
||||
"event": {
|
||||
**(event.graphql()),
|
||||
"conferenceId": conference_id,
|
||||
"roomId": room_id,
|
||||
"eventPeopleUsingGuid": {
|
||||
"create": [
|
||||
# TODO: add person guid
|
||||
{"personId": str(p['id']), "publicName": p.get('name') or p.get('public_name')} for p in event['persons']
|
||||
]}
|
||||
}
|
||||
}
|
||||
|
||||
query = gql('''
|
||||
mutation upsertEvent($input: UpsertEventInput!) {
|
||||
upsertEvent(input: $input) {
|
||||
clientMutationId
|
||||
}
|
||||
}
|
||||
''')
|
||||
|
||||
try:
|
||||
write('.')
|
||||
client.execute(query, {'input': data})
|
||||
except Exception as e:
|
||||
print(json.dumps(data, indent=2))
|
||||
print()
|
||||
print(e)
|
||||
print()
|
||||
|
||||
|
||||
def remove_event(event_guid):
|
||||
try:
|
||||
client.execute(gql('''
|
||||
mutation deleteEvent($guid: UUID!) {
|
||||
deleteEvent(input: {guid: $guid}) { deletedEventNodeId }
|
||||
}
|
||||
'''), {'guid': event_guid})
|
||||
except Exception as e:
|
||||
print(e)
|
||||
print()
|
||||
|
||||
|
||||
class C3data:
|
||||
conference_id = None
|
||||
room_ids = {}
|
||||
|
||||
def __init__(self, schedule: Schedule, create=False):
|
||||
result = create_conference(schedule) if create else get_conference(schedule.conference('acronym'))
|
||||
if "errors" in result:
|
||||
logger.error(result['errors'])
|
||||
if not result['conference']:
|
||||
raise "Please create conference in target system using --create"
|
||||
self.conference_id = result['conference']['id']
|
||||
|
||||
self.room_ids = {x['name']: x['guid'] for x in result['conference']['rooms']['nodes']}
|
||||
|
||||
# check for new/updated rooms
|
||||
for room in schedule.rooms(mode='obj'):
|
||||
if room.name not in self.room_ids:
|
||||
room_id = add_room(self.conference_id, room)
|
||||
self.room_ids[room.name] = room_id
|
||||
|
||||
# TODO check for new rooms and create them now
|
||||
|
||||
def upsert_event(self, event: Event):
|
||||
if event['room'] in self.room_ids:
|
||||
room_id = self.room_ids[event['room']]
|
||||
else:
|
||||
print('WARNING: Room {} does not exist, creating.'.format(event['room']))
|
||||
room_id = add_room(self.conference_id, Room(name=event['room'], guid=event.get('room_id')))
|
||||
self.room_ids[event['room']] = room_id
|
||||
add_event(self.conference_id, room_id, event)
|
||||
|
||||
def depublish_event(self, event_guid):
|
||||
remove_event(event_guid)
|
||||
|
||||
def process_changed_events(self, repo: 'Repo', options):
|
||||
changed_items = repo.index.diff('HEAD~1', 'events')
|
||||
for i in changed_items:
|
||||
write(i.change_type + ': ')
|
||||
try:
|
||||
if i.change_type == 'D':
|
||||
event_guid = path.splitext(path.basename(i.a_path))[0]
|
||||
self.depublish_event(event_guid)
|
||||
else:
|
||||
event = Event(load_json(i.a_path))
|
||||
self.upsert_event(event)
|
||||
except KeyboardInterrupt:
|
||||
break
|
||||
except Exception as e:
|
||||
print(e)
|
||||
if options.exit_when_exception_occours:
|
||||
raise e
|
||||
|
||||
|
||||
def upsert_schedule(schedule: Schedule, create=False):
|
||||
c3data = C3data(schedule, create)
|
||||
try:
|
||||
schedule.foreach_event(c3data.upsert_event)
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
|
||||
|
||||
def test():
|
||||
# schedule = Schedule.from_url('https://fahrplan.events.ccc.de/camp/2019/Fahrplan/schedule.json')
|
||||
schedule = Schedule.from_file('38C3/everything.schedule.json')
|
||||
|
||||
upsert_schedule(schedule, create=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('url', action="store", help="url or local path source schedule.json")
|
||||
parser.add_argument('--create', action="store_true", default=False)
|
||||
args = parser.parse_args()
|
||||
|
||||
schedule = Schedule.from_url(args.url) if args.url.startswith('http') else Schedule.from_file(args.url)
|
||||
upsert_schedule(schedule, create=args.create)
|
||||
|
||||
print('')
|
||||
print('done')
|
||||
Loading…
Add table
Add a link
Reference in a new issue