Fixed redirector #15
Some checks failed
Test API before pr merge / test-lint (pull_request) Successful in 11s
Test before pr merge / test-translation-lint (pull_request) Successful in 42s
Test before pr merge / test-lint (pull_request) Failing after 44s
Test before pr merge / test-before-merge (pull_request) Successful in 1m44s
Some checks failed
Test API before pr merge / test-lint (pull_request) Successful in 11s
Test before pr merge / test-translation-lint (pull_request) Successful in 42s
Test before pr merge / test-lint (pull_request) Failing after 44s
Test before pr merge / test-before-merge (pull_request) Successful in 1m44s
This commit is contained in:
parent
16bc5d570b
commit
a913ea014f
@ -11,3 +11,4 @@ Jinja2==3.1.5
|
|||||||
python-keycloak==5.3.1
|
python-keycloak==5.3.1
|
||||||
python-multipart==0.0.20
|
python-multipart==0.0.20
|
||||||
websockets==15.0
|
websockets==15.0
|
||||||
|
sqlparse==0.5.3
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from typing import Optional, Any
|
from typing import Optional, Any
|
||||||
|
|
||||||
|
import sqlparse
|
||||||
from psycopg import sql
|
from psycopg import sql
|
||||||
from psycopg_pool import AsyncConnectionPool, PoolTimeout
|
from psycopg_pool import AsyncConnectionPool, PoolTimeout
|
||||||
|
|
||||||
@ -44,7 +45,9 @@ class PostgresPool:
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
async def _exec_sql(cursor: Any, query: str, args=None, multi=True):
|
async def _exec_sql(cursor: Any, query: str, args=None, multi=True):
|
||||||
if multi:
|
if multi:
|
||||||
queries = query.split(";")
|
queries = [
|
||||||
|
str(stmt).strip() for stmt in sqlparse.parse(query) if str(stmt).strip()
|
||||||
|
]
|
||||||
for q in queries:
|
for q in queries:
|
||||||
if q.strip() == "":
|
if q.strip() == "":
|
||||||
continue
|
continue
|
||||||
|
@ -15,7 +15,9 @@ class ShortUrlVisitDao(DbModelDaoABC[ShortUrlVisit]):
|
|||||||
|
|
||||||
async def count_by_id(self, fid: int) -> int:
|
async def count_by_id(self, fid: int) -> int:
|
||||||
result = await self._db.select_map(
|
result = await self._db.select_map(
|
||||||
f"SELECT COUNT(*) FROM {self._table_name} WHERE shortUrlId = {fid}"
|
f"""SELECT COUNT(*) FROM {self._table_name}
|
||||||
|
WHERE shortUrlId = {fid}
|
||||||
|
AND deleted = FALSE"""
|
||||||
)
|
)
|
||||||
if result is None or len(result) == 0:
|
if result is None or len(result) == 0:
|
||||||
return 0
|
return 0
|
||||||
|
@ -83,7 +83,26 @@ def _find_short_url_by_path(path: str) -> Optional[dict]:
|
|||||||
json={
|
json={
|
||||||
"query": f"""
|
"query": f"""
|
||||||
query getShortUrlByPath($path: String!) {{
|
query getShortUrlByPath($path: String!) {{
|
||||||
shortUrls(filter: {{ shortUrl: {{ equal: $path }}, deleted: {{ equal: false }}, group: {{ deleted: {{ equal: false }} }} }}) {{
|
shortUrls(filter: [{{ shortUrl: {{ equal: $path }} }}, {{ deleted: {{ equal: false }} }}, {{ group: {{ deleted: {{ equal: false }} }} }}]) {{
|
||||||
|
nodes {{
|
||||||
|
id
|
||||||
|
shortUrl
|
||||||
|
targetUrl
|
||||||
|
description
|
||||||
|
group {{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}}
|
||||||
|
domain {{
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}}
|
||||||
|
loadingScreen
|
||||||
|
deleted
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
|
||||||
|
shortUrlsWithoutGroup: shortUrls(filter: [{{ shortUrl: {{ equal: $path }} }}, {{ deleted: {{ equal: false }} }}, {{ group: {{ isNull: true }} }}]) {{
|
||||||
nodes {{
|
nodes {{
|
||||||
id
|
id
|
||||||
shortUrl
|
shortUrl
|
||||||
@ -115,14 +134,18 @@ def _find_short_url_by_path(path: str) -> Optional[dict]:
|
|||||||
"data" not in data
|
"data" not in data
|
||||||
or "shortUrls" not in data["data"]
|
or "shortUrls" not in data["data"]
|
||||||
or "nodes" not in data["data"]["shortUrls"]
|
or "nodes" not in data["data"]["shortUrls"]
|
||||||
|
or "nodes" not in data["data"]["shortUrlsWithoutGroup"]
|
||||||
):
|
):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
data = data["data"]["shortUrls"]["nodes"]
|
nodes = [
|
||||||
if len(data) == 0:
|
*data["data"]["shortUrls"]["nodes"],
|
||||||
|
*data["data"]["shortUrlsWithoutGroup"]["nodes"],
|
||||||
|
]
|
||||||
|
if len(nodes) == 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return data[0]
|
return nodes[0]
|
||||||
|
|
||||||
|
|
||||||
async def _handle_short_url(request: Request, short_url: dict):
|
async def _handle_short_url(request: Request, short_url: dict):
|
||||||
@ -145,7 +168,7 @@ async def _track_visit(r: Request, short_url: dict):
|
|||||||
f"{api_url}/graphql",
|
f"{api_url}/graphql",
|
||||||
json={
|
json={
|
||||||
"query": f"""
|
"query": f"""
|
||||||
mutation trackShortUrlVisit($id: ID!, $agent: String) {{
|
mutation trackShortUrlVisit($id: Int!, $agent: String) {{
|
||||||
shortUrl {{
|
shortUrl {{
|
||||||
trackVisit(id: $id, agent: $agent)
|
trackVisit(id: $id, agent: $agent)
|
||||||
}}
|
}}
|
||||||
|
@ -50,111 +50,113 @@ export class ShortUrlsDataService
|
|||||||
skip?: number | undefined,
|
skip?: number | undefined,
|
||||||
take?: number | undefined
|
take?: number | undefined
|
||||||
): Observable<QueryResult<ShortUrl>> {
|
): Observable<QueryResult<ShortUrl>> {
|
||||||
const query1 = this.apollo.query<{ shortUrls: QueryResult<ShortUrl> }>({
|
return this.apollo
|
||||||
query: gql`
|
.query<{
|
||||||
query getShortUrls($filter: [ShortUrlFilter], $sort: [ShortUrlSort]) {
|
shortUrls: QueryResult<ShortUrl>;
|
||||||
shortUrls(filter: $filter, sort: $sort) {
|
shortUrlsWithoutGroup: QueryResult<ShortUrl>;
|
||||||
nodes {
|
}>({
|
||||||
id
|
query: gql`
|
||||||
shortUrl
|
query getShortUrls(
|
||||||
targetUrl
|
$filter: [ShortUrlFilter]
|
||||||
description
|
$filter2: [ShortUrlFilter]
|
||||||
loadingScreen
|
$sort: [ShortUrlSort]
|
||||||
visits
|
) {
|
||||||
group {
|
shortUrls(filter: $filter, sort: $sort) {
|
||||||
|
nodes {
|
||||||
id
|
id
|
||||||
name
|
shortUrl
|
||||||
}
|
targetUrl
|
||||||
domain {
|
description
|
||||||
id
|
loadingScreen
|
||||||
name
|
visits
|
||||||
}
|
group {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
domain {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
...DB_MODEL
|
...DB_MODEL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shortUrlsWithoutGroup: shortUrls(filter: $filter2, sort: $sort) {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
shortUrl
|
||||||
|
targetUrl
|
||||||
|
description
|
||||||
|
loadingScreen
|
||||||
|
visits
|
||||||
|
group {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
domain {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
...DB_MODEL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
${DB_MODEL_FRAGMENT}
|
${DB_MODEL_FRAGMENT}
|
||||||
`,
|
`,
|
||||||
variables: {
|
variables: {
|
||||||
filter: [
|
filter: [
|
||||||
{
|
{
|
||||||
userSpace: {
|
|
||||||
id: { equal: this.sidebarService.selectedUserSpace$.value?.id },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ group: { deleted: { equal: false } } },
|
|
||||||
{
|
|
||||||
group: {
|
|
||||||
userSpace: {
|
userSpace: {
|
||||||
id: { equal: this.sidebarService.selectedUserSpace$.value?.id },
|
id: { equal: this.sidebarService.selectedUserSpace$.value?.id },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
{ group: { deleted: { equal: false } } },
|
||||||
...(filter ?? []),
|
{
|
||||||
],
|
group: {
|
||||||
sort: [{ id: SortOrder.DESC }, ...(sort ?? [])],
|
userSpace: {
|
||||||
skip,
|
id: {
|
||||||
take,
|
equal: this.sidebarService.selectedUserSpace$.value?.id,
|
||||||
},
|
},
|
||||||
});
|
},
|
||||||
|
},
|
||||||
const query2 = this.apollo.query<{ shortUrls: QueryResult<ShortUrl> }>({
|
|
||||||
query: gql`
|
|
||||||
query getShortUrls($filter: [ShortUrlFilter], $sort: [ShortUrlSort]) {
|
|
||||||
shortUrls(filter: $filter, sort: $sort) {
|
|
||||||
nodes {
|
|
||||||
id
|
|
||||||
shortUrl
|
|
||||||
targetUrl
|
|
||||||
description
|
|
||||||
loadingScreen
|
|
||||||
visits
|
|
||||||
group {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
domain {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
}
|
|
||||||
|
|
||||||
...DB_MODEL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
${DB_MODEL_FRAGMENT}
|
|
||||||
`,
|
|
||||||
variables: {
|
|
||||||
filter: [
|
|
||||||
{
|
|
||||||
userSpace: {
|
|
||||||
id: { equal: this.sidebarService.selectedUserSpace$.value?.id },
|
|
||||||
},
|
},
|
||||||
},
|
...(filter ?? []),
|
||||||
{ group: { isNull: true } },
|
],
|
||||||
...(filter ?? []),
|
filter2: [
|
||||||
],
|
{
|
||||||
sort: [{ id: SortOrder.DESC }, ...(sort ?? [])],
|
userSpace: {
|
||||||
skip,
|
id: { equal: this.sidebarService.selectedUserSpace$.value?.id },
|
||||||
take,
|
},
|
||||||
},
|
},
|
||||||
});
|
{
|
||||||
|
group: {
|
||||||
return forkJoin([query1, query2]).pipe(
|
isNull: true,
|
||||||
map(([result1, result2]) => {
|
},
|
||||||
const nodes = [
|
},
|
||||||
...result1.data.shortUrls.nodes,
|
...(filter ?? []),
|
||||||
...result2.data.shortUrls.nodes,
|
],
|
||||||
];
|
sort: [{ id: SortOrder.DESC }, ...(sort ?? [])],
|
||||||
const uniqueNodes = Array.from(
|
skip,
|
||||||
new Map(nodes.map(node => [node.id, node])).values()
|
take,
|
||||||
);
|
},
|
||||||
return { ...result1.data.shortUrls, nodes: uniqueNodes };
|
|
||||||
})
|
})
|
||||||
);
|
.pipe(
|
||||||
|
map(x => {
|
||||||
|
return {
|
||||||
|
count: x.data.shortUrls.count + x.data.shortUrlsWithoutGroup.count,
|
||||||
|
totalCount:
|
||||||
|
x.data.shortUrls.totalCount +
|
||||||
|
x.data.shortUrlsWithoutGroup.totalCount,
|
||||||
|
nodes: [
|
||||||
|
...x.data.shortUrls.nodes,
|
||||||
|
...x.data.shortUrlsWithoutGroup.nodes,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadById(id: number): Observable<ShortUrl> {
|
loadById(id: number): Observable<ShortUrl> {
|
||||||
|
Loading…
Reference in New Issue
Block a user