166 lines
8.6 KiB
Python
166 lines
8.6 KiB
Python
from typing import Dict, List
|
|
from ...controller import Controller
|
|
from ...register import register
|
|
from ...context import Context
|
|
import requests
|
|
import yaml
|
|
import os
|
|
from ...utils import _
|
|
from ...config import get_config
|
|
|
|
|
|
class Risotto(Controller):
|
|
@register('v1.source.create')
|
|
async def source_create(self,
|
|
risotto_context: Context,
|
|
source_name: str,
|
|
source_url: str) -> Dict:
|
|
source_upsert = """INSERT INTO Source(SourceName, SourceURL) VALUES ($1, $2)
|
|
ON CONFLICT (SourceName) DO UPDATE SET SourceURL = $2
|
|
RETURNING SourceId
|
|
"""
|
|
# If given url is not 'none' (a.k.a internal source)
|
|
# Look for file releases.yml at given url
|
|
# If such a file exists, consider source a valid one and create source in database.
|
|
if source_url != 'none':
|
|
try:
|
|
releases = yaml.load(requests.get(source_url.rstrip('/') + '/releases.yml').content, Loader=yaml.SafeLoader)
|
|
except requests.exceptions.ConnectionError as err:
|
|
raise Exception(_('Invalid URL'))
|
|
except yaml.scanner.ScannerError as err:
|
|
raise Exception(_('Invalid releases.yml file'))
|
|
except:
|
|
raise Exception(_('Invalid source'))
|
|
else:
|
|
releases = {'1.0.0': {'distribution': 'last'}}
|
|
os.makedirs(os.path.join(get_config().get('source').get('root_path'), source_name), exist_ok=True)
|
|
with open(os.path.join(get_config().get('source').get('root_path'), source_name, 'releases.yml'), 'w') as release_file:
|
|
yaml.dump(releases, release_file)
|
|
source_id = await risotto_context.connection.fetchval(source_upsert,
|
|
source_name,
|
|
source_url)
|
|
return {'source_name': source_name,
|
|
'source_url': source_url,
|
|
'source_id': source_id}
|
|
|
|
@register('v1.source.describe')
|
|
async def source_describe(self,
|
|
risotto_context: Context,
|
|
source_name: str) -> Dict:
|
|
source_get = """SELECT SourceId as source_id, SourceName as source_name, SourceURL as source_url
|
|
FROM Source
|
|
WHERE SourceName = $1
|
|
"""
|
|
source = await risotto_context.connection.fetchrow(source_get,
|
|
source_name)
|
|
if not source:
|
|
raise Exception(_(f'unknown source with name {source_name}'))
|
|
return dict(source)
|
|
|
|
@register('v1.source.list')
|
|
async def source_list(self,
|
|
risotto_context: Context) -> List[Dict]:
|
|
source_list = """SELECT SourceId as source_id, SourceName as source_name, SourceURL as source_url
|
|
FROM Source
|
|
"""
|
|
result = await risotto_context.connection.fetch(source_list)
|
|
return [dict(r) for r in result]
|
|
|
|
@register('v1.source.dataset.update')
|
|
async def version_update(self,
|
|
risotto_context: Context,
|
|
source_id: int,
|
|
release_name: str):
|
|
# source.release.create is an upsert, do not using it
|
|
release_insert = """INSERT INTO Release(ReleaseName, ReleaseSourceId) VALUES ($1, $2)
|
|
RETURNING ReleaseId
|
|
"""
|
|
release_id = await risotto_context.connection.fetchval(release_insert,
|
|
release_name,
|
|
source_id)
|
|
return {'release_id': release_id,
|
|
'release_name': release_name}
|
|
|
|
@register('v1.source.release.create')
|
|
async def source_release_create(self,
|
|
risotto_context: Context,
|
|
source_name: str,
|
|
release_name: str,
|
|
release_distribution: str) -> Dict:
|
|
source_get = """SELECT SourceId as source_id, SourceName as source_name, SourceURL as source_url
|
|
FROM Source
|
|
WHERE SourceName = $1
|
|
"""
|
|
release_upsert = """INSERT INTO Release(ReleaseName, ReleaseSourceId, ReleaseDistribution) VALUES ($1, $2, $3)
|
|
ON CONFLICT (ReleaseName, ReleaseSourceId) DO UPDATE SET ReleaseName = $1
|
|
RETURNING ReleaseId
|
|
"""
|
|
source_obj = await risotto_context.connection.fetchrow(source_get,
|
|
source_name)
|
|
if not source_obj:
|
|
raise Exception(_(f'unable to find a source with name {source_name}'))
|
|
source = dict(source_obj)
|
|
release_id = await risotto_context.connection.fetchval(release_upsert,
|
|
release_name,
|
|
source['source_id'],
|
|
release_distribution)
|
|
del source['source_id']
|
|
source['release_id'] = release_id
|
|
source['release_name'] = release_name
|
|
source['release_distribution'] = release_distribution
|
|
return source
|
|
|
|
@register('v1.source.release.list')
|
|
async def release_list(self,
|
|
risotto_context,
|
|
source_name: str) -> Dict:
|
|
release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution
|
|
FROM Release, Source
|
|
WHERE Source.SourceName=$1 AND Source.SourceId=Release.ReleaseSourceId"""
|
|
result = await risotto_context.connection.fetch(release_query,
|
|
source_name)
|
|
return [dict(r) for r in result]
|
|
|
|
@register('v1.source.release.describe')
|
|
async def release_list(self,
|
|
risotto_context,
|
|
source_name: str,
|
|
release_distribution: str) -> Dict:
|
|
release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution
|
|
FROM Release, Source
|
|
WHERE Source.SourceName=$1 AND Source.SourceId=Release.ReleaseSourceId AND Release.ReleaseDistribution=$2"""
|
|
result = await risotto_context.connection.fetchrow(release_query,
|
|
source_name,
|
|
release_distribution)
|
|
if not result:
|
|
raise Exception(_(f'unknown release distribution {release_distribution} in source {source_name}'))
|
|
return dict(result)
|
|
|
|
@register('v1.source.release.get_by_id')
|
|
async def release_get_by_id(self,
|
|
risotto_context: Context,
|
|
release_id: int) -> Dict:
|
|
release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution
|
|
FROM Release, Source
|
|
WHERE Release.ReleaseId = $1 AND Source.SourceId = Release.ReleaseSourceId"""
|
|
result = await risotto_context.connection.fetchrow(release_query,
|
|
release_id)
|
|
if not result:
|
|
raise Exception(_(f'unknown release id {release_id}'))
|
|
return dict(result)
|
|
|
|
@register('v1.source.release.get_by_distribution')
|
|
async def release_get_by_distribution(self,
|
|
risotto_context: Context,
|
|
source_id: int,
|
|
release_distribution: str) -> Dict:
|
|
release_query = """SELECT ReleaseId as release_id, SourceName as source_name, SourceURL as source_url, ReleaseName as release_name, ReleaseDistribution as release_distribution
|
|
FROM Release, Source
|
|
WHERE Release.ReleaseSourceId = $1 AND Release.ReleaseDistribution = $2 AND Source.SourceId = Release.ReleaseSourceId"""
|
|
result = await risotto_context.connection.fetchrow(release_query,
|
|
source_id,
|
|
release_distribution)
|
|
if not result:
|
|
raise Exception(_(f'unknown distribution {release_distribution} with source {source_id}'))
|
|
return dict(result)
|