mirror of
https://github.com/nexus-stc/hyperboria
synced 2024-11-30 06:52:55 +01:00
Merge pull request #28 from the-superpirate/master
- feat(nexus): Bump versions
This commit is contained in:
commit
7daa6184d5
3
.gitignore
vendored
3
.gitignore
vendored
@ -21,6 +21,3 @@ node_modules/
|
||||
|
||||
# Telethon session files
|
||||
*.session
|
||||
|
||||
# IPFS collection for Cognitron
|
||||
bafykbzacebzohi352bddfunaub5rgqv5b324nejk5v6fltjh45be5ykw5jsjg/
|
||||
|
31
README.md
31
README.md
@ -10,26 +10,16 @@ into [`internal Protobuf format`](nexus/models) and to landing converted data in
|
||||
|
||||
## Prerequisite
|
||||
|
||||
Install system packages for various OSes:
|
||||
```shell script
|
||||
sudo ./repository/install-packages.sh
|
||||
```
|
||||
|
||||
### Ubuntu 20.04
|
||||
|
||||
#### Docker
|
||||
[Installation Guide](https://docs.docker.com/engine/install/ubuntu/)
|
||||
|
||||
#### System Compilers
|
||||
```shell script
|
||||
sudo apt-get install -y --no-install-recommends g++ python3.9 protobuf-compiler libprotobuf-dev libev-perl
|
||||
```
|
||||
|
||||
#### Bazel Build System
|
||||
[Installation Guide](https://docs.bazel.build/versions/master/install-ubuntu.html) or _one-liner_:
|
||||
```shell script
|
||||
sudo apt install curl gnupg
|
||||
curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg
|
||||
sudo mv bazel.gpg /etc/apt/trusted.gpg.d/
|
||||
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | sudo tee /etc/apt/sources.list.d/bazel.list
|
||||
sudo apt update && sudo apt install bazel
|
||||
```
|
||||
|
||||
#### IPFS
|
||||
[Installation Guide](https://docs.ipfs.io/install/)
|
||||
|
||||
@ -38,17 +28,6 @@ sudo apt update && sudo apt install bazel
|
||||
#### Docker
|
||||
[Installation Guide](https://docs.docker.com/docker-for-mac/install/)
|
||||
|
||||
#### System Compilers
|
||||
```shell script
|
||||
brew install llvm protobuf python3.9
|
||||
```
|
||||
|
||||
#### Bazel Build System
|
||||
[Installation Guide](https://docs.bazel.build/versions/master/install-os-x.html) or _one-liner_:
|
||||
```shell script
|
||||
brew install bazel
|
||||
```
|
||||
|
||||
#### IPFS
|
||||
[Installation Guide](https://docs.ipfs.io/install/)
|
||||
|
||||
|
66
WORKSPACE
66
WORKSPACE
@ -26,8 +26,8 @@ http_archive(
|
||||
|
||||
http_archive(
|
||||
name = "build_bazel_rules_nodejs",
|
||||
sha256 = "f533eeefc8fe1ddfe93652ec50f82373d0c431f7faabd5e6323f6903195ef227",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.3.0/rules_nodejs-3.3.0.tar.gz"],
|
||||
sha256 = "1134ec9b7baee008f1d54f0483049a97e53a57cd3913ec9d6db625549c98395a",
|
||||
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.4.0/rules_nodejs-3.4.0.tar.gz"],
|
||||
)
|
||||
|
||||
http_archive(
|
||||
@ -119,6 +119,39 @@ pip_install(
|
||||
requirements = "//rules/python:requirements.txt",
|
||||
)
|
||||
|
||||
# Proto / gRPC
|
||||
|
||||
http_archive(
|
||||
name = "rules_proto_grpc",
|
||||
sha256 = "7954abbb6898830cd10ac9714fbcacf092299fda00ed2baf781172f545120419",
|
||||
strip_prefix = "rules_proto_grpc-3.1.1",
|
||||
urls = ["https://github.com/rules-proto-grpc/rules_proto_grpc/archive/3.1.1.tar.gz"],
|
||||
)
|
||||
|
||||
load("@rules_proto_grpc//:repositories.bzl", "rules_proto_grpc_repos", "rules_proto_grpc_toolchains")
|
||||
|
||||
rules_proto_grpc_toolchains()
|
||||
|
||||
rules_proto_grpc_repos()
|
||||
|
||||
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
|
||||
|
||||
rules_proto_dependencies()
|
||||
|
||||
rules_proto_toolchains()
|
||||
|
||||
load("@rules_proto_grpc//js:repositories.bzl", "js_repos")
|
||||
|
||||
js_repos()
|
||||
|
||||
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
|
||||
|
||||
grpc_deps()
|
||||
|
||||
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
|
||||
|
||||
grpc_extra_deps()
|
||||
|
||||
# Java
|
||||
|
||||
load("//rules/java:artifacts.bzl", "maven_fetch_remote_artifacts")
|
||||
@ -234,32 +267,3 @@ rules_misc_setup_internal()
|
||||
load("//rules/misc:install.bzl", "rules_misc_install_internal")
|
||||
|
||||
rules_misc_install_internal()
|
||||
|
||||
# Proto / gRPC
|
||||
|
||||
http_archive(
|
||||
name = "rules_proto_grpc",
|
||||
sha256 = "7954abbb6898830cd10ac9714fbcacf092299fda00ed2baf781172f545120419",
|
||||
strip_prefix = "rules_proto_grpc-3.1.1",
|
||||
urls = ["https://github.com/rules-proto-grpc/rules_proto_grpc/archive/3.1.1.tar.gz"],
|
||||
)
|
||||
|
||||
load("@rules_proto_grpc//:repositories.bzl", "rules_proto_grpc_repos", "rules_proto_grpc_toolchains")
|
||||
|
||||
rules_proto_grpc_toolchains()
|
||||
|
||||
rules_proto_grpc_repos()
|
||||
|
||||
load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
|
||||
|
||||
rules_proto_dependencies()
|
||||
|
||||
rules_proto_toolchains()
|
||||
|
||||
load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
|
||||
|
||||
grpc_deps()
|
||||
|
||||
load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
|
||||
|
||||
grpc_extra_deps()
|
||||
|
@ -57,27 +57,30 @@ class ChatManagerService(ChatManagerServicer, BaseService):
|
||||
chat.is_system_messaging_enabled,
|
||||
chat.is_discovery_enabled,
|
||||
)
|
||||
.returning('*')
|
||||
.on_conflict('chat_id')
|
||||
.do_nothing()
|
||||
).get_sql()
|
||||
async with self.pool_holder.pool.acquire() as session:
|
||||
result = await session.execute(query)
|
||||
chat = await result.fetchone()
|
||||
return self.enrich_chat(ChatPb(**chat))
|
||||
await session.execute(query)
|
||||
return await self._get_chat(session=session, chat_id=request.chat_id, context=context)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def get_chat(self, request, context, metadata):
|
||||
async def _get_chat(self, session, chat_id, context):
|
||||
query = (
|
||||
PostgreSQLQuery
|
||||
.from_(self.chats_table)
|
||||
.select('*')
|
||||
.where(self.chats_table.chat_id == request.chat_id)
|
||||
.where(self.chats_table.chat_id == chat_id)
|
||||
).get_sql()
|
||||
result = await session.execute(query)
|
||||
chat = await result.fetchone()
|
||||
if chat is None:
|
||||
await context.abort(StatusCode.NOT_FOUND, 'not_found')
|
||||
return self.enrich_chat(ChatPb(**chat))
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def get_chat(self, request, context, metadata):
|
||||
async with self.pool_holder.pool.acquire() as session:
|
||||
result = await session.execute(query)
|
||||
chat = await result.fetchone()
|
||||
if chat is None:
|
||||
await context.abort(StatusCode.NOT_FOUND, 'not_found')
|
||||
return self.enrich_chat(ChatPb(**chat))
|
||||
return await self._get_chat(session=session, chat_id=request.chat_id, context=context)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def list_chats(self, request, context, metadata):
|
||||
|
@ -14,14 +14,26 @@ from library.logging import error_log
|
||||
class AioGrpcServer(AioRootThing):
|
||||
def __init__(self, address, port):
|
||||
super().__init__()
|
||||
self.address = address
|
||||
self.port = port
|
||||
self.server = aio.server()
|
||||
self.server.add_insecure_port(f'{address}:{port}')
|
||||
|
||||
async def start(self):
|
||||
logging.getLogger('debug').info({
|
||||
'action': 'starting',
|
||||
'address': self.address,
|
||||
'mode': 'grpc',
|
||||
'port': self.port,
|
||||
})
|
||||
await self.server.start()
|
||||
await self.server.wait_for_termination()
|
||||
|
||||
async def stop(self):
|
||||
logging.getLogger('debug').info({
|
||||
'action': 'stopping',
|
||||
'mode': 'grpc',
|
||||
})
|
||||
await self.server.stop(None)
|
||||
|
||||
|
||||
@ -50,21 +62,21 @@ def aiogrpc_request_wrapper(log=True):
|
||||
self.statbox(
|
||||
action='enter',
|
||||
mode=func.__name__,
|
||||
request_id=metadata['request-id'],
|
||||
request_id=metadata.get('request-id'),
|
||||
)
|
||||
r = await func(self, request, context, metadata)
|
||||
if log:
|
||||
self.statbox(
|
||||
action='exit',
|
||||
mode=func.__name__,
|
||||
request_id=metadata['request-id'],
|
||||
request_id=metadata.get('request-id'),
|
||||
)
|
||||
return r
|
||||
except aio.AbortError:
|
||||
raise
|
||||
except Exception as e:
|
||||
serialized_request = MessageToDict(request, preserving_proto_field_name=True)
|
||||
error_log(e, request=serialized_request, request_id=metadata['request-id'])
|
||||
error_log(e, request=serialized_request, request_id=metadata.get('request-id'))
|
||||
if e.__class__ in self.error_mapping:
|
||||
await context.abort(*self.error_mapping[e.__class__])
|
||||
raise e
|
||||
@ -80,20 +92,20 @@ def aiogrpc_streaming_request_wrapper(func):
|
||||
self.statbox(
|
||||
action='enter',
|
||||
mode=func.__name__,
|
||||
request_id=metadata['request-id'],
|
||||
request_id=metadata.get('request-id'),
|
||||
)
|
||||
async for item in func(self, request, context, metadata):
|
||||
yield item
|
||||
self.statbox(
|
||||
action='exit',
|
||||
mode=func.__name__,
|
||||
request_id=metadata['request-id'],
|
||||
request_id=metadata.get('request-id'),
|
||||
)
|
||||
except aio.AbortError:
|
||||
raise
|
||||
except Exception as e:
|
||||
serialized_request = MessageToDict(request, preserving_proto_field_name=True)
|
||||
error_log(e, request=serialized_request, request_id=metadata['request-id'])
|
||||
error_log(e, request=serialized_request, request_id=metadata.get('request-id'))
|
||||
if e.__class__ in self.error_mapping:
|
||||
await context.abort(*self.error_mapping[e.__class__])
|
||||
raise e
|
||||
|
@ -4,7 +4,10 @@ import os.path
|
||||
from types import ModuleType
|
||||
|
||||
import yaml
|
||||
from izihawa_utils.common import smart_merge_dicts
|
||||
from izihawa_utils.common import (
|
||||
smart_merge_dicts,
|
||||
unflatten,
|
||||
)
|
||||
from jinja2 import Template
|
||||
from library.configurator.exceptions import UnknownConfigFormatError
|
||||
|
||||
@ -42,7 +45,7 @@ class RichDict(dict):
|
||||
|
||||
|
||||
class Configurator(RichDict):
|
||||
def __init__(self, configs: list):
|
||||
def __init__(self, configs: list, env_prefix: str = None, env_key_separator: str = '.'):
|
||||
"""
|
||||
Create Configurator object
|
||||
|
||||
@ -54,12 +57,16 @@ class Configurator(RichDict):
|
||||
self._by_basenames = {}
|
||||
self._omitted_files = []
|
||||
|
||||
env_config = {}
|
||||
env_config_var = os.environ.get('CONFIGURATOR', '')
|
||||
if env_config_var:
|
||||
env_config = yaml.safe_load(env_config_var)
|
||||
env_dict = {}
|
||||
|
||||
for config in ([os.environ] + configs + [env_config]):
|
||||
if env_prefix:
|
||||
env_prefix = env_prefix.lower()
|
||||
for name, value in os.environ.items():
|
||||
if name.lower().startswith(env_prefix):
|
||||
env_dict[name[len(env_prefix):].lstrip('_')] = value
|
||||
env_dict = unflatten(env_dict, sep=env_key_separator)
|
||||
|
||||
for config in ([os.environ] + configs + [env_dict]):
|
||||
file_found = self.update(config)
|
||||
if not file_found:
|
||||
self._omitted_files.append(config)
|
||||
|
@ -7,7 +7,7 @@
|
||||
- ✅ [`cognitron`](cognitron) - bundled app for IPFS, search server and web frontend
|
||||
- ✅ [`hub`](hub) - downloading & sending
|
||||
- ✅ [`ingest`](ingest) - retrieving metadata from external APIs and putting it onto Kafka
|
||||
- 🛑 `meta_api` - rescoring and merging API for Summa backends
|
||||
- ✅ [`meta_api`](meta_api) - rescoring and merging API for Summa backends
|
||||
- ✅ [`models`](models) - shared Protobuf models
|
||||
- ✅ [`nlptools`](nlptools) - text routines
|
||||
- ✅ [`pipe`](pipe) - processing pipeline based on Kafka
|
||||
|
@ -9,7 +9,7 @@ def get_config():
|
||||
'nexus/bot/configs/%s.yaml?' % env.type,
|
||||
'nexus/bot/configs/logging.yaml',
|
||||
'nexus/bot/configs/promotions.yaml',
|
||||
])
|
||||
], env_prefix='NEXUS_BOT')
|
||||
|
||||
|
||||
config = get_config()
|
||||
|
@ -45,7 +45,7 @@ hub:
|
||||
url:
|
||||
idm:
|
||||
url:
|
||||
log_path: '/var/log/nexus-bot/{{ ENV_TYPE }}'
|
||||
log_path: '/var/log/nexus-bot'
|
||||
meta_api:
|
||||
url:
|
||||
telegram:
|
||||
@ -57,7 +57,7 @@ telegram:
|
||||
bot_external_name: libgen_scihub_bot
|
||||
# Internal bot name used in logging
|
||||
bot_name: nexus-bot
|
||||
bot_token: '{{ BOT_TOKEN }}'
|
||||
bot_token:
|
||||
# WARNING! Potentially buggy telethon option. Sometimes it goes mad and overload users with tons of messages
|
||||
# Collect missed messages at startup time and answer to them
|
||||
catch_up: false
|
||||
@ -65,7 +65,7 @@ telegram:
|
||||
copyright_infringement_account:
|
||||
# Telethon database for keeping cache
|
||||
database:
|
||||
session_id: '/usr/lib/nexus-bot/{{ ENV_TYPE }}/session.db'
|
||||
session_id: '/usr/lib/nexus-bot/session.db'
|
||||
# Enabled handlers
|
||||
handlers:
|
||||
- nexus.bot.handlers.admin.AdminHandler
|
||||
|
1
nexus/cognitron/.gitignore
vendored
Normal file
1
nexus/cognitron/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
data
|
@ -10,8 +10,8 @@ Follow the [root guide](../../README.md) to install Docker, IPFS and Bazel (opti
|
||||
|
||||
```shell script
|
||||
export COLLECTION=bafykbzacebzohi352bddfunaub5rgqv5b324nejk5v6fltjh45be5ykw5jsjg
|
||||
export COLLECTION_PATH=$(realpath $COLLECTION)
|
||||
ipfs get $COLLECTION && ipfs pin add $COLLECTION
|
||||
ipfs get $COLLECTION -o data && ipfs pin add $COLLECTION
|
||||
export DATA_PATH=$(realpath ./data)
|
||||
```
|
||||
|
||||
#### 2. Launch Nexus Cognitron
|
||||
@ -32,6 +32,6 @@ By default this script is just printing documents.
|
||||
|
||||
```shell script
|
||||
bazel run -c opt installer -- iterate \
|
||||
--data-filepath $COLLECTION_PATH/index/scitech \
|
||||
--data-filepath $DATA_PATH/index/scitech \
|
||||
--schema-filepath schema/scitech.yaml
|
||||
```
|
||||
|
@ -1,11 +1,12 @@
|
||||
---
|
||||
|
||||
http:
|
||||
bind_addr: 0.0.0.0:80
|
||||
address: 0.0.0.0
|
||||
keep_alive_secs: 75
|
||||
max_body_size_mb: 32
|
||||
port: 80
|
||||
workers: 48
|
||||
log_path: /var/log/nexus-cognitron/{{ ENV_TYPE }}
|
||||
log_path: /var/log/nexus-cognitron
|
||||
search_engine:
|
||||
auto_commit: false
|
||||
data_path: /nexus-cognitron/summa
|
||||
|
@ -1,22 +1,44 @@
|
||||
---
|
||||
|
||||
services:
|
||||
nexus-cognitron-web:
|
||||
depends_on:
|
||||
- summa
|
||||
environment:
|
||||
ENV_TYPE: production
|
||||
NEXUS_COGNITRON_WEB_IPFS_GATEWAY: https://cloudflare-ipfs.com
|
||||
NEXUS_COGNITRON_WEB_SEARCH_API: http://localhost:50000
|
||||
NEXUS_COGNITRON_WEB_ipfs.gateway.url: https://cloudflare-ipfs.com
|
||||
NEXUS_COGNITRON_WEB_meta_api.url: http://nexus-meta-api:8080
|
||||
image: thesuperpirate/cognitron-web:latest
|
||||
ports:
|
||||
- "3000:80"
|
||||
- '3000:80'
|
||||
nexus-meta-api:
|
||||
depends_on:
|
||||
- summa
|
||||
environment:
|
||||
ENV_TYPE: development
|
||||
NEXUS_META_API_grpc.address: '0.0.0.0'
|
||||
NEXUS_META_API_grpc.port: 9090
|
||||
NEXUS_META_API_summa.url: 'http://summa:8082'
|
||||
image: thesuperpirate/meta-api:latest
|
||||
ports:
|
||||
- '9090:9090'
|
||||
nexus-meta-api-envoy:
|
||||
depends_on:
|
||||
- nexus-meta-api
|
||||
image: envoyproxy/envoy-dev:latest
|
||||
ports:
|
||||
- '8080:8080'
|
||||
- '9901:9901'
|
||||
volumes:
|
||||
- './nexus-meta-api-envoy.yaml:/etc/envoy/envoy.yaml'
|
||||
summa:
|
||||
environment:
|
||||
ENV_TYPE: production
|
||||
SUMMA_debug: 'true'
|
||||
SUMMA_http.address: '0.0.0.0'
|
||||
SUMMA_http.port: '8082'
|
||||
image: izihawa/summa:latest
|
||||
ports:
|
||||
- "50000:80"
|
||||
- '8082:8082'
|
||||
volumes:
|
||||
- '${COLLECTION_PATH}:/summa'
|
||||
- '${DATA_PATH}:/summa/data'
|
||||
version: "3"
|
||||
|
@ -14,8 +14,7 @@ deps = [
|
||||
"@npm//sass",
|
||||
"@npm//sass-loader",
|
||||
"@npm//vue",
|
||||
"//nexus/meta_api/proto:meta_api_grpc_js",
|
||||
"//nexus/meta_api/proto:meta_api_proto_js",
|
||||
"//nexus/meta_api/js/client",
|
||||
]
|
||||
|
||||
js_library(
|
||||
@ -30,9 +29,6 @@ js_library(
|
||||
"static/*",
|
||||
"store/*.js",
|
||||
]),
|
||||
data = [
|
||||
"//nexus/cognitron/web/client",
|
||||
],
|
||||
)
|
||||
|
||||
nuxt(
|
||||
@ -40,6 +36,7 @@ nuxt(
|
||||
args = [
|
||||
"-c",
|
||||
"nexus/cognitron/web/nuxt.config.js",
|
||||
"--watch-poll",
|
||||
],
|
||||
data = [":nuxt-srcs"] + deps,
|
||||
)
|
||||
|
@ -1,11 +0,0 @@
|
||||
export default class SummaApi {
|
||||
constructor (client) {
|
||||
this.client = client
|
||||
}
|
||||
|
||||
async search (schema, text, page, item_per_page = 5) {
|
||||
return await this.client.search(schema, text, page, item_per_page).then(response => {
|
||||
return response
|
||||
})
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
export default class HttpClient {
|
||||
search (schema, text, page, itemsPerPage) {
|
||||
const params = new URLSearchParams()
|
||||
params.append('query', text)
|
||||
if (page) {
|
||||
params.append('page', page)
|
||||
}
|
||||
if (itemsPerPage) {
|
||||
params.append('page_size', itemsPerPage)
|
||||
}
|
||||
const url = '/v1/' + schema + '/search/?' + params
|
||||
return this.nativeClient.request({
|
||||
method: 'get',
|
||||
url: url,
|
||||
cache: false
|
||||
})
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { aggregation } from '~/library/js/utils'
|
||||
import BaseClient from '~/library/js/base-client'
|
||||
import HttpClient from './http-client'
|
||||
|
||||
export default class Client extends aggregation(
|
||||
BaseClient, HttpClient
|
||||
) {}
|
@ -1,7 +1,6 @@
|
||||
<template lang="pug">
|
||||
div.document
|
||||
v-scimag(v-if="schema === 'scimag' && document", :document="document")
|
||||
v-scitech(v-if="schema === 'scitech' && document", :document="document")
|
||||
v-scitech(:document="document")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -11,10 +10,7 @@ export default {
|
||||
document: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
schema: {
|
||||
required: true
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -1,27 +1,26 @@
|
||||
<template lang="pug">
|
||||
div.d-flex
|
||||
div
|
||||
nuxt-link(:to="link") {{ document.title }}
|
||||
nuxt-link(:to="{ name: 'documents-schema-id', params: { schema: schema, id: document.id }}") {{ document.title }}
|
||||
.detail
|
||||
div
|
||||
i.mr-1(v-if='document.doi') DOI:
|
||||
span {{ document.doi }}
|
||||
div(v-if='authors')
|
||||
span {{ authors }} {{ issuedAt }}
|
||||
div(v-if='document.firstAuthors')
|
||||
span {{ document.firstAuthors }} {{ issuedAt }}
|
||||
.gp
|
||||
span.el.text-uppercase(v-if="document.extension") {{ document.extension }}
|
||||
span.el.text-uppercase(v-if="document.language") {{ document.language }}
|
||||
span.el.text-uppercase(v-if="filesize") {{ filesize }}
|
||||
span.el.text-uppercase(v-if="document.filesize") {{ document.filesize }}
|
||||
span.el(v-if="document.pages")
|
||||
span.mr-2 {{ document.pages }}
|
||||
span pages
|
||||
img(:src="coverUrl" alt="" onerror="this.style.display='none'")
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { getCoverUrl, getFirstAuthors, getIssuedDate, getMegabytes } from '@/plugins/helpers'
|
||||
import { getIssuedDate } from '@/plugins/helpers'
|
||||
|
||||
export default {
|
||||
name: 'SearchItem',
|
||||
@ -33,25 +32,17 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
authors: function () {
|
||||
return getFirstAuthors(this.document.authors, false, 3)
|
||||
},
|
||||
coverUrl: function () {
|
||||
return getCoverUrl(this.document.cu, this.document.fictionId, this.document.libgenId, this.document.cuSuf, this.document.md5)
|
||||
},
|
||||
document: function () {
|
||||
return this.scoredDocument.document
|
||||
return this.scoredDocument.typedDocument[this.schema]
|
||||
},
|
||||
issuedAt: function () {
|
||||
const date = getIssuedDate(this.document.issuedAt)
|
||||
if (date != null) return '(' + date + ')'
|
||||
return null
|
||||
},
|
||||
filesize: function () {
|
||||
return getMegabytes(this.document.filesize)
|
||||
},
|
||||
link: function () {
|
||||
return `/documents/id:${this.document.id}?schema=${this.scoredDocument.schema}`
|
||||
schema: function () {
|
||||
const td = this.scoredDocument.typedDocument
|
||||
return Object.keys(td).filter(k => td[k] !== undefined)[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template lang="pug">
|
||||
ul
|
||||
li(v-for='scoredDocument in scoredDocuments')
|
||||
search-item(:scored-document='scoredDocument', :key='scoredDocument.document.id')
|
||||
search-item(:scored-document='scoredDocument', :key='scoredDocument.typedDocument.scitech.id')
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -10,7 +10,7 @@ export default {
|
||||
name: 'VHeader',
|
||||
data () {
|
||||
return {
|
||||
search: ''
|
||||
query: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,22 @@
|
||||
<template lang="pug">
|
||||
div
|
||||
.top
|
||||
h6 {{document.title}}
|
||||
h6 {{ document.title }}
|
||||
h6
|
||||
i {{ document.locator }}
|
||||
table
|
||||
tbody
|
||||
v-tr(label="Author", :value="authors")
|
||||
v-tr(label="Issued At", :value="issuedAt")
|
||||
v-tr(label="Issue", :value="document.issue")
|
||||
v-tr(label="Volume", :value="document.volume")
|
||||
v-tr(label="Page", :value="page")
|
||||
v-tr(label="Pages", :value="pages")
|
||||
v-tr(label="Container Title", :value="document.containerTitle")
|
||||
v-tr(label="Language", :value="document.language", value-classes="text-uppercase")
|
||||
v-tr(label="DOI", :value="document.doi")
|
||||
v-tr(label="Description", :value="document.abstract", @max-length=300)
|
||||
v-tr(label="Tags", :value="tags")
|
||||
v-tr(label="ISSNS", :value="issns")
|
||||
v-tr(label="ISBNS", :value="isbns")
|
||||
v-tr-link(label="Download link", v-if="ipfsMultihash" :value="filename", :url="ipfsUrl")
|
||||
|
||||
v-tr(label="File", :value="document.filedata")
|
||||
v-tr-link(label="Download link", v-if="ipfsMultihash" :value="document.filename", :url="ipfsUrl")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getFirstAuthors, getIssuedDate } from '@/plugins/helpers'
|
||||
import { getFilename } from '@/plugins/scimag-helpers'
|
||||
import { getIssuedDate } from '@/plugins/helpers'
|
||||
import VTr from './v-tr'
|
||||
import VTrLink from './v-tr-link'
|
||||
export default {
|
||||
@ -36,9 +29,6 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
authors: function () {
|
||||
return getFirstAuthors(this.document.authors, false, 3)
|
||||
},
|
||||
pages: function () {
|
||||
if (this.document.firstPage && this.document.lastPage && this.document.firstPage !== this.document.lastPage) {
|
||||
return `${this.document.firstPage}-${this.document.lastPage}`
|
||||
@ -59,35 +49,27 @@ export default {
|
||||
}
|
||||
return null
|
||||
},
|
||||
filename: function () {
|
||||
try {
|
||||
return getFilename(this.document.authors, this.document.title, this.document.doi, this.document.issuedAt)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return `file_${this.document.id}.pdf`
|
||||
}
|
||||
},
|
||||
issns: function () {
|
||||
return (this.document.issns || []).join('; ')
|
||||
return (this.document.issnsList || []).join('; ')
|
||||
},
|
||||
isbns: function () {
|
||||
return (this.document.isbns || []).join('; ')
|
||||
return (this.document.isbnsList || []).join('; ')
|
||||
},
|
||||
issuedAt: function () {
|
||||
return getIssuedDate(this.document.issuedAt)
|
||||
},
|
||||
ipfsUrl: function () {
|
||||
if (!this.ipfsMultihash) return null
|
||||
return `${this.$config.ipfsGateway}/ipfs/${this.ipfsMultihash}?filename=${this.filename}&download=true`
|
||||
return `${this.$config.ipfs.gateway.url}/ipfs/${this.ipfsMultihash}?filename=${this.filename}&download=true`
|
||||
},
|
||||
ipfsMultihash: function () {
|
||||
if (this.document.ipfsMultihashes) {
|
||||
return this.document.ipfsMultihashes[0]
|
||||
if (this.document.ipfsMultihashesList) {
|
||||
return this.document.ipfsMultihashesList[0]
|
||||
}
|
||||
return null
|
||||
},
|
||||
tags: function () {
|
||||
return (this.document.tags || []).join('; ')
|
||||
return (this.document.tagsList || []).join('; ')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,23 @@
|
||||
<template lang="pug">
|
||||
div.document
|
||||
.top
|
||||
h6 {{document.title}}
|
||||
img(:src="coverUrl" alt="" onerror="this.style.display='none'")
|
||||
h6 {{ document.title }}
|
||||
.top
|
||||
i
|
||||
h6 {{ document.locator }}
|
||||
table
|
||||
tbody
|
||||
v-tr(label="Author", :value="authors")
|
||||
v-tr(label="Issued At", :value="issuedAt")
|
||||
v-tr(label="Extension", :value="document.extension", value-classes="text-uppercase")
|
||||
v-tr(label="Filesize", :value="filesize")
|
||||
v-tr(label="Pages", :value="document.pages")
|
||||
v-tr(label="Language", :value="document.language", value-classes="text-uppercase")
|
||||
v-tr(label="DOI", :value="document.doi")
|
||||
v-tr(label="Description", :value="document.description", @max-length=300)
|
||||
v-tr(label="Tags", :value="tags")
|
||||
v-tr(label="ISBNS", :value="isbns")
|
||||
v-tr(label="ISSNS", :value="issns")
|
||||
v-tr(label="MD5", :value="document.md5")
|
||||
v-tr-link(label="Download link", v-if="ipfsMultihash" :value="filename", :url="ipfsUrl")
|
||||
v-tr(label="File", :value="document.filedata")
|
||||
v-tr-link(label="Download link", v-if="ipfsMultihash" :value="document.filename", :url="ipfsUrl")
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCoverUrl, getFirstAuthors, getIssuedDate, getMegabytes } from '@/plugins/helpers'
|
||||
import { getFilename } from '@/plugins/scitech-helpers'
|
||||
import { getIssuedDate } from '@/plugins/helpers'
|
||||
export default {
|
||||
name: 'VScitech',
|
||||
props: {
|
||||
@ -32,48 +27,27 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
authors: function () {
|
||||
return getFirstAuthors(this.document.authors, false, 3)
|
||||
},
|
||||
coverUrl: function () {
|
||||
return getCoverUrl(this.document.cu, this.document.fictionId,
|
||||
this.document.libgenId,
|
||||
this.document.cuSuf,
|
||||
this.document.md5)
|
||||
},
|
||||
filesize: function () {
|
||||
return getMegabytes(this.document.filesize)
|
||||
},
|
||||
filename: function () {
|
||||
try {
|
||||
return getFilename(this.document.authors, this.document.title, this.document.doi,
|
||||
this.document.issuedAt, this.document.md5, this.document.extension)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return `file_${this.document.id}.${this.document.extension}`
|
||||
}
|
||||
},
|
||||
isbns: function () {
|
||||
return (this.document.isbns || []).join('; ')
|
||||
return (this.document.isbnsList || []).join('; ')
|
||||
},
|
||||
issns: function () {
|
||||
return (this.document.issns || []).join('; ')
|
||||
return (this.document.issnsList || []).join('; ')
|
||||
},
|
||||
issuedAt: function () {
|
||||
return getIssuedDate(this.document.issuedAt)
|
||||
},
|
||||
ipfsUrl: function () {
|
||||
if (!this.ipfsMultihash) return null
|
||||
return `${this.$config.ipfsGateway}/ipfs/${this.ipfsMultihash}?filename=${this.filename}&download=true`
|
||||
return `${this.$config.ipfs.gateway.url}/ipfs/${this.ipfsMultihash}?filename=${this.document.filename}&download=true`
|
||||
},
|
||||
ipfsMultihash: function () {
|
||||
if (this.document.ipfsMultihashes) {
|
||||
return this.document.ipfsMultihashes[0]
|
||||
if (this.document.ipfsMultihashesList) {
|
||||
return this.document.ipfsMultihashesList[0]
|
||||
}
|
||||
return null
|
||||
return ''
|
||||
},
|
||||
tags: function () {
|
||||
return (this.document.tags || []).join('; ')
|
||||
return (this.document.tagsList || []).join('; ')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +1,28 @@
|
||||
<template lang="pug">
|
||||
tr(v-if="value")
|
||||
th {{label}}
|
||||
tr(v-show="value")
|
||||
th {{ label }}
|
||||
td(:class="valueClasses")
|
||||
| {{formattedValue}}
|
||||
| {{ formattedValue }}
|
||||
cite
|
||||
a(href="javascript:void(null);" @click="showMore" v-if="collapseText") show more...
|
||||
a(href="javascript:void(null);" @click="showMore" v-if="shouldCollapseText") show more...
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'VTr',
|
||||
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
required: true
|
||||
required: true,
|
||||
default: ''
|
||||
},
|
||||
valueClasses: {
|
||||
type: String,
|
||||
required: false
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
value: {
|
||||
required: true,
|
||||
default: null
|
||||
type: [String, Number]
|
||||
},
|
||||
maxLength: {
|
||||
type: Number,
|
||||
@ -35,18 +35,15 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
collapseText () {
|
||||
return this.value.length > this.maxLength && !this.showAll
|
||||
shouldCollapseText () {
|
||||
return this.value && this.value.length > this.maxLength && !this.showAll
|
||||
},
|
||||
formattedValue () {
|
||||
if (this.value) {
|
||||
if (this.collapseText) {
|
||||
return this.value.substr(0, this.maxLength)
|
||||
} else {
|
||||
return this.value
|
||||
}
|
||||
if (this.shouldCollapseText) {
|
||||
return this.value.substr(0, this.maxLength)
|
||||
} else {
|
||||
return this.value
|
||||
}
|
||||
return null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -56,7 +53,3 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
||||
|
@ -8,7 +8,7 @@ if (buildDir) {
|
||||
export default {
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: 80
|
||||
port: 8082
|
||||
},
|
||||
buildDir: buildDir,
|
||||
srcDir: 'nexus/cognitron/web',
|
||||
@ -39,16 +39,20 @@ export default {
|
||||
],
|
||||
|
||||
publicRuntimeConfig: {
|
||||
ipfsGateway: process.env.NEXUS_COGNITRON_WEB_IPFS_GATEWAY || 'http://localhost:8080',
|
||||
searchApi: process.env.NEXUS_COGNITRON_WEB_SEARCH_API || 'http://localhost:50000'
|
||||
meta_api: {
|
||||
url: process.env.NEXUS_COGNITRON_WEB_meta_api.url || 'http://nexus-meta-api:8080'
|
||||
},
|
||||
ipfs: {
|
||||
gateway: {
|
||||
url: process.env.NEXUS_COGNITRON_WEB_ipfs.gateway.url || 'https://ipfs.io'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins)
|
||||
plugins: [
|
||||
'plugins/helpers',
|
||||
'plugins/search-api',
|
||||
'plugins/scimag-helpers',
|
||||
'plugins/scitech-helpers',
|
||||
'plugins/meta-api',
|
||||
'plugins/utils'
|
||||
],
|
||||
|
||||
@ -66,6 +70,11 @@ export default {
|
||||
],
|
||||
|
||||
loading: { color: '#1a95e0', throttle: 0 },
|
||||
watchers: {
|
||||
webpack: {
|
||||
poll: true
|
||||
}
|
||||
},
|
||||
|
||||
// Build Configuration (https://go.nuxtjs.dev/config-build)
|
||||
build: {
|
||||
|
@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<document
|
||||
v-if="document"
|
||||
:document="document"
|
||||
:schema="schema"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Key',
|
||||
data () {
|
||||
return {
|
||||
document: {},
|
||||
schema: null
|
||||
}
|
||||
},
|
||||
async fetch () {
|
||||
await this.$search_api.search(this.$route.query.schema, this.$route.params.key).then(response => {
|
||||
if (response.scoredDocuments.length === 0) {
|
||||
this.$nuxt.error(404)
|
||||
}
|
||||
if (response.scoredDocuments.length > 1) {
|
||||
this.$nuxt.error(500)
|
||||
}
|
||||
this.document = response.scoredDocuments[0].document
|
||||
this.schema = this.$route.query.schema
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
this.$nuxt.error(e.statusCode)
|
||||
})
|
||||
},
|
||||
fetchOnServer: false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
30
nexus/cognitron/web/pages/documents/_schema/_id.vue
Normal file
30
nexus/cognitron/web/pages/documents/_schema/_id.vue
Normal file
@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<div>
|
||||
<document
|
||||
v-if="document"
|
||||
:document="document"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
document: {}
|
||||
}
|
||||
},
|
||||
async fetch () {
|
||||
const response = await this.$meta_api.getView(this.$route.params.schema, this.$route.params.id)
|
||||
this.document = {
|
||||
...response.typedDocument.scitech,
|
||||
filedata: response.filedata,
|
||||
filename: response.filename,
|
||||
filesize: response.filesize,
|
||||
firstAuthors: response.firstAuthors,
|
||||
locator: response.locator
|
||||
}
|
||||
},
|
||||
fetchOnServer: false
|
||||
}
|
||||
</script>
|
@ -2,15 +2,15 @@
|
||||
div
|
||||
form
|
||||
.input-group
|
||||
b-form-input(v-model='search' placeholder='Enter book name or DOI')
|
||||
b-button(type='submit' @click.stop.prevent='submit(search, 1, schema)') Search
|
||||
b-form-input(v-model='query' placeholder='Enter book name or DOI')
|
||||
b-button(type='submit' @click.stop.prevent='submit(query, 1, schema)') Search
|
||||
b-form-radio-group(
|
||||
v-model="schema"
|
||||
:options="schemas"
|
||||
class="radio-group"
|
||||
value-field="item"
|
||||
text-field="name")
|
||||
p.mt-5(v-if="nothingFound") Nothing found
|
||||
p.mt-5(v-if="scoredDocuments.length == 0") Nothing found
|
||||
b-pagination(v-if='scoredDocuments.length > 0' v-model='page' :total-rows='totalRows' :per-page='perPage' limit="2" :disabled="isLoading")
|
||||
.search_list
|
||||
search-list(:scored-documents='scoredDocuments')
|
||||
@ -25,48 +25,40 @@ export default {
|
||||
loading: true,
|
||||
data () {
|
||||
return {
|
||||
search: '',
|
||||
query: '',
|
||||
scoredDocuments: [],
|
||||
defaultSchema: 'scitech',
|
||||
schema: 'scitech',
|
||||
schemas: [
|
||||
{ item: 'scitech', name: 'Scitech' }
|
||||
{ item: 'scitech', name: 'Scitech' },
|
||||
// { item: 'scimag', name: 'Scimag' }
|
||||
],
|
||||
page: 1,
|
||||
totalRows: 10,
|
||||
perPage: 1,
|
||||
nothingFound: false
|
||||
perPage: 1
|
||||
}
|
||||
},
|
||||
async fetch () {
|
||||
this.search = this.$route.query.search
|
||||
if (!this.search) {
|
||||
this.query = this.$route.query.query
|
||||
if (!this.query) {
|
||||
await this.$router.push({ path: '/' })
|
||||
this.scoredDocuments = []
|
||||
this.nothingFound = false
|
||||
return
|
||||
}
|
||||
this.page = this.$route.query.page
|
||||
this.schema = this.$route.query.schema || this.defaultSchema
|
||||
let scoredDocuments = []
|
||||
|
||||
if (!process.server) {
|
||||
this.$nuxt.$loading.start()
|
||||
}
|
||||
await this.$search_api.search(this.schema, this.search, this.page, 5).then(response => {
|
||||
if (!response.hasNext) {
|
||||
this.totalRows = this.page
|
||||
} else {
|
||||
this.totalRows = Number(this.page) + 1
|
||||
}
|
||||
scoredDocuments = response.scoredDocuments
|
||||
}).catch(e => {
|
||||
console.error(e)
|
||||
this.$nuxt.error(500)
|
||||
})
|
||||
this.scoredDocuments = scoredDocuments
|
||||
this.nothingFound = (!scoredDocuments.length > 0)
|
||||
const response = await this.$meta_api.search(this.schema, this.query, this.page - 1, 5)
|
||||
if (response.hasNext) {
|
||||
this.totalRows = Number(this.page) + 1
|
||||
} else {
|
||||
this.totalRows = this.page
|
||||
}
|
||||
this.scoredDocuments = response.scoredDocumentsList
|
||||
|
||||
if (!process.server) {
|
||||
this.$nuxt.$loading.finish()
|
||||
}
|
||||
@ -80,17 +72,17 @@ export default {
|
||||
watch: {
|
||||
'$route.query': '$fetch',
|
||||
schema () {
|
||||
if (this.search) {
|
||||
this.submit(this.search, this.page, this.schema)
|
||||
if (this.query) {
|
||||
this.submit(this.query, this.page, this.schema)
|
||||
}
|
||||
},
|
||||
page () {
|
||||
this.submit(this.search, this.page, this.schema)
|
||||
this.submit(this.query, this.page, this.schema)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit (search, page, schema) {
|
||||
this.$router.push({ path: '/', query: { search: search, page: page, schema: schema } })
|
||||
submit (query, page, schema) {
|
||||
this.$router.push({ path: '/', query: { query: query, page: page, schema: schema } })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,5 @@
|
||||
import dateFormat from 'dateformat'
|
||||
|
||||
export function getFirstAuthors (authors, etAl = true, firstNAuthors = 1) {
|
||||
let etAlSuffix = ''
|
||||
if (etAl) {
|
||||
etAlSuffix = ' et al'
|
||||
}
|
||||
if (authors) {
|
||||
if (authors.length > firstNAuthors) {
|
||||
return authors.slice(0, firstNAuthors).join(';') + etAlSuffix
|
||||
} else if (authors.length === 1) {
|
||||
if (authors[0].split(';').length - 1 >= 1) {
|
||||
const commaAuthors = authors[0].split(';').map(function (el) {
|
||||
return el.trim()
|
||||
})
|
||||
if (commaAuthors.length > firstNAuthors) {
|
||||
return (commaAuthors.slice(0, firstNAuthors)).join('; ') + etAlSuffix
|
||||
} else {
|
||||
return commaAuthors.join('; ')
|
||||
}
|
||||
}
|
||||
return authors[0]
|
||||
} else {
|
||||
return authors.join('; ')
|
||||
}
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export function getMegabytes (bytes) {
|
||||
try {
|
||||
if (bytes) {
|
||||
return (bytes / (1024 * 1024)).toFixed(2) + ' Mb'
|
||||
}
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function getIssuedDate (unixtime) {
|
||||
if (!unixtime) return null
|
||||
try {
|
||||
@ -47,24 +9,3 @@ export function getIssuedDate (unixtime) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function getCoverUrl (cu, fictionId, libgenId, cuSuf, md5) {
|
||||
if (cu) return cu
|
||||
let r = ''
|
||||
if (libgenId || fictionId) {
|
||||
if (libgenId) {
|
||||
const bulkId = (libgenId - (libgenId % 1000))
|
||||
r = `covers/${bulkId}/${md5}`
|
||||
} else if (fictionId) {
|
||||
const bulkId = (fictionId - (fictionId % 1000))
|
||||
r = `fictioncovers/${bulkId}/${md5}`
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
if (cuSuf) {
|
||||
r = r + `-${cuSuf}`
|
||||
return `http://gen.lib.rus.ec/${r}.jpg`
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
6
nexus/cognitron/web/plugins/meta-api.js
Executable file
6
nexus/cognitron/web/plugins/meta-api.js
Executable file
@ -0,0 +1,6 @@
|
||||
import MetaApi from '~/nexus/meta_api/js/client'
|
||||
|
||||
export default ({ $config }, inject) => {
|
||||
const metaApi = new MetaApi($config.metaApi)
|
||||
inject('meta_api', metaApi)
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
import { castStringToSingleString, quoteUrl } from './utils'
|
||||
import { getIssuedDate } from './helpers'
|
||||
|
||||
export function getFilename (authors, title, doi, issuedDate) {
|
||||
const limit = 55
|
||||
|
||||
let processedAuthor = ''
|
||||
if (authors) {
|
||||
processedAuthor = authors[0]
|
||||
}
|
||||
|
||||
processedAuthor = castStringToSingleString((processedAuthor || '').toLowerCase())
|
||||
const processedTitle = castStringToSingleString((title || '').toLowerCase())
|
||||
|
||||
const parts = []
|
||||
if (processedAuthor) {
|
||||
parts.push(processedAuthor)
|
||||
}
|
||||
if (processedTitle) {
|
||||
parts.push(processedTitle)
|
||||
}
|
||||
|
||||
let filename = parts.join('-')
|
||||
const chars = []
|
||||
let size = 0
|
||||
let hitLimit = false
|
||||
|
||||
for (const c of filename) {
|
||||
const currentSize = size + c.length
|
||||
if (currentSize > limit) {
|
||||
hitLimit = true
|
||||
break
|
||||
}
|
||||
chars.push(c)
|
||||
size = currentSize
|
||||
}
|
||||
|
||||
filename = chars.join('')
|
||||
if (hitLimit) {
|
||||
const glyph = filename.lastIndexOf('-')
|
||||
if (glyph !== -1) {
|
||||
filename = filename.substr(0, glyph)
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
filename = quoteUrl(doi, '').substr(0, limit)
|
||||
}
|
||||
|
||||
const year = getIssuedDate(issuedDate)
|
||||
|
||||
if (year) {
|
||||
filename = `${filename}-${year}`
|
||||
}
|
||||
|
||||
filename = filename.replace(/-+/g, '-')
|
||||
|
||||
return `${filename}.pdf`
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
import { castStringToSingleString, escapeFormat, quoteUrl } from './utils'
|
||||
import { getFirstAuthors, getIssuedDate } from './helpers'
|
||||
|
||||
function getRobustTitle (title, volume) {
|
||||
if (volume) {
|
||||
if (title) {
|
||||
title = `${title} ${volume}`
|
||||
} else {
|
||||
title = volume
|
||||
}
|
||||
}
|
||||
return escapeFormat(title)
|
||||
}
|
||||
|
||||
export function getFilename (authors, title, doi, issuedDate, md5, extension) {
|
||||
const limit = 55
|
||||
|
||||
const processedAuthor = castStringToSingleString((getFirstAuthors(authors, false, 1)).toLowerCase())
|
||||
const processedTitle = castStringToSingleString(getRobustTitle(title)).toLowerCase()
|
||||
|
||||
const parts = []
|
||||
if (processedAuthor) {
|
||||
parts.push(processedAuthor)
|
||||
}
|
||||
if (processedTitle) {
|
||||
parts.push(processedTitle)
|
||||
}
|
||||
|
||||
let filename = parts.join('-')
|
||||
const chars = []
|
||||
let size = 0
|
||||
let hitLimit = false
|
||||
|
||||
for (const c of filename) {
|
||||
const currentSize = size + c.length
|
||||
if (currentSize > limit) {
|
||||
hitLimit = true
|
||||
break
|
||||
}
|
||||
chars.push(c)
|
||||
size = currentSize
|
||||
}
|
||||
|
||||
filename = chars.join('')
|
||||
if (hitLimit) {
|
||||
const glyph = filename.lastIndexOf('-')
|
||||
if (glyph !== -1) {
|
||||
filename = filename.substr(0, glyph)
|
||||
}
|
||||
}
|
||||
|
||||
if (!filename) {
|
||||
if (doi) {
|
||||
filename = quoteUrl(doi, '')
|
||||
} else {
|
||||
filename = md5
|
||||
}
|
||||
}
|
||||
|
||||
const year = getIssuedDate(issuedDate)
|
||||
|
||||
if (year) {
|
||||
filename = `${filename}-${year}`
|
||||
}
|
||||
filename = filename.replace(/-+/g, '-')
|
||||
|
||||
return `${filename}.${extension}`
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
import HttpClient from '~/nexus/cognitron/web/client/index'
|
||||
import SummaApi from '~/nexus/cognitron/web/client/api'
|
||||
|
||||
export default ({ $config }, inject) => {
|
||||
const summaApi = new SummaApi(
|
||||
new HttpClient({
|
||||
baseUrl: $config.searchApi,
|
||||
headers: () => {
|
||||
return {
|
||||
Accept: 'application/json'
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
inject('search_api', summaApi)
|
||||
}
|
@ -2,9 +2,7 @@ const ALNUMWHITESPACE_REGEX = /\P{L}/gu
|
||||
const MULTIWHITESPACE_REGEX = /\s+/g
|
||||
|
||||
export function castStringToSingleString (s) {
|
||||
let processed = s.replace(ALNUMWHITESPACE_REGEX, ' ')
|
||||
processed = processed.replace(MULTIWHITESPACE_REGEX, '-')
|
||||
return processed
|
||||
return s.replace(ALNUMWHITESPACE_REGEX, ' ').replace(MULTIWHITESPACE_REGEX, '-')
|
||||
}
|
||||
|
||||
export function escapeFormat (text) {
|
||||
|
@ -7,7 +7,7 @@ def get_config():
|
||||
'nexus/hub/configs/base.yaml',
|
||||
'nexus/hub/configs/%s.yaml?' % env.type,
|
||||
'nexus/hub/configs/logging.yaml',
|
||||
])
|
||||
], env_prefix='NEXUS_HUB')
|
||||
|
||||
|
||||
config = get_config()
|
||||
|
@ -12,8 +12,8 @@ application:
|
||||
database:
|
||||
database: nexus
|
||||
host:
|
||||
password: '{{ DATABASE_PASSWORD }}'
|
||||
username: '{{ DATABASE_USERNAME }}'
|
||||
password:
|
||||
username:
|
||||
grobid:
|
||||
url:
|
||||
grpc:
|
||||
@ -24,7 +24,7 @@ grpc:
|
||||
ipfs:
|
||||
address:
|
||||
port: 4001
|
||||
log_path: '/var/log/nexus-hub/{{ ENV_TYPE }}'
|
||||
log_path: '/var/log/nexus-hub'
|
||||
meta_api:
|
||||
url:
|
||||
pylon:
|
||||
@ -34,14 +34,14 @@ pylon:
|
||||
resolve_proxy: socks5://127.0.0.1:9050
|
||||
telegram:
|
||||
# Telegram App Hash from https://my.telegram.org/
|
||||
app_hash: '{{ APP_HASH }}'
|
||||
app_hash:
|
||||
# Telegram App ID from https://my.telegram.org/
|
||||
app_id: 00000
|
||||
# External bot name shown in messages to users
|
||||
bot_external_name: libgen_scihub_bot
|
||||
# Internal bot name used in logging
|
||||
bot_name: nexus-hub
|
||||
bot_token: '{{ BOT_TOKEN }}'
|
||||
bot_token:
|
||||
# Telethon database for keeping cache
|
||||
database:
|
||||
session_id: nexus-hub
|
||||
|
@ -122,7 +122,9 @@ class SubmitterService(SubmitterServicer, BaseHubService):
|
||||
request_context.error_log(e)
|
||||
await self.telegram_client.send_message(
|
||||
request_context.chat.chat_id,
|
||||
t('UNPARSABLE_DOCUMENT_ERROR', language=request_context.chat.language),
|
||||
t('UNPARSABLE_DOCUMENT_ERROR', language=request_context.chat.language).format(
|
||||
filename=document.attributes[0].file_name,
|
||||
),
|
||||
buttons=[close_button()],
|
||||
)
|
||||
return SubmitResponsePb()
|
||||
@ -132,7 +134,9 @@ class SubmitterService(SubmitterServicer, BaseHubService):
|
||||
request_context.error_log(UnparsableDoiError())
|
||||
await self.telegram_client.send_message(
|
||||
request_context.chat.chat_id,
|
||||
t('UNPARSABLE_DOI_ERROR', language=request_context.chat.language),
|
||||
t('UNPARSABLE_DOI_ERROR', language=request_context.chat.language).format(
|
||||
filename=document.attributes[0].file_name,
|
||||
),
|
||||
buttons=[close_button()],
|
||||
)
|
||||
return SubmitResponsePb()
|
||||
@ -162,17 +166,16 @@ class SubmitterService(SubmitterServicer, BaseHubService):
|
||||
return SubmitResponsePb()
|
||||
|
||||
document_view = ScimagView(search_response_pb.scored_documents[0].typed_document.scimag)
|
||||
uploaded_message = await self.send_file(
|
||||
document_view=document_view,
|
||||
file=file,
|
||||
request_context=request_context,
|
||||
session_id=session_id,
|
||||
voting=False,
|
||||
)
|
||||
finally:
|
||||
await processing_message.delete()
|
||||
|
||||
uploaded_message = await self.send_file(
|
||||
document_view=document_view,
|
||||
file=file,
|
||||
request_context=request_context,
|
||||
session_id=session_id,
|
||||
voting=False,
|
||||
)
|
||||
|
||||
document_operation_pb = DocumentOperationPb(
|
||||
update_document=UpdateDocumentPb(
|
||||
typed_document=TypedDocumentPb(sharience=ShariencePb(
|
||||
|
94
nexus/meta_api/BUILD.bazel
Normal file
94
nexus/meta_api/BUILD.bazel
Normal file
@ -0,0 +1,94 @@
|
||||
load("@io_bazel_rules_docker//python3:image.bzl", "py3_image")
|
||||
load("@io_bazel_rules_docker//container:container.bzl", "container_push")
|
||||
load("@pip_modules//:requirements.bzl", "requirement")
|
||||
|
||||
alias(
|
||||
name = "binary",
|
||||
actual = ":image.binary",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
py3_image(
|
||||
name = "image",
|
||||
srcs = glob(
|
||||
["**/*.py"],
|
||||
exclude = ["proto/**/*.py"],
|
||||
),
|
||||
base = "//images/production:base-python-image",
|
||||
data = [
|
||||
"configs/base.yaml",
|
||||
"configs/logging.yaml",
|
||||
"models/classic.txt",
|
||||
],
|
||||
main = "main.py",
|
||||
srcs_version = "PY3ONLY",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
requirement("aiochclient"),
|
||||
requirement("aiopg"),
|
||||
requirement("cachetools"),
|
||||
requirement("grpcio"),
|
||||
requirement("lightgbm"),
|
||||
requirement("numpy"),
|
||||
requirement("protobuf"),
|
||||
requirement("recordclass"),
|
||||
requirement("uvloop"),
|
||||
"//library/aiogrpctools",
|
||||
"//library/aiopostgres",
|
||||
"//library/configurator",
|
||||
"//library/logging",
|
||||
"//nexus/meta_api/proto:meta_api_grpc_py",
|
||||
"//nexus/meta_api/query_extensionner",
|
||||
"//nexus/models/proto:models_proto_py",
|
||||
"//nexus/nlptools",
|
||||
"//nexus/views/telegram",
|
||||
requirement("aiosumma"),
|
||||
],
|
||||
)
|
||||
|
||||
py3_image(
|
||||
name = "learn",
|
||||
srcs = ["learn.py"],
|
||||
base = "//images/production:base-python-image",
|
||||
main = "learn.py",
|
||||
srcs_version = "PY3ONLY",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
requirement("fire"),
|
||||
requirement("lightgbm"),
|
||||
requirement("numpy"),
|
||||
requirement("orjson"),
|
||||
requirement("pandas"),
|
||||
"//nexus/meta_api/proto:meta_api_proto_py",
|
||||
requirement("izihawa_utils"),
|
||||
],
|
||||
)
|
||||
|
||||
py_binary(
|
||||
name = "cli",
|
||||
srcs = ["cli.py"],
|
||||
main = "cli.py",
|
||||
deps = [
|
||||
"//nexus/meta_api/aioclient",
|
||||
requirement("fire"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
container_push(
|
||||
name = "push-public-latest",
|
||||
format = "Docker",
|
||||
image = ":image",
|
||||
registry = "registry.hub.docker.com",
|
||||
repository = "thesuperpirate/meta-api",
|
||||
tag = "latest",
|
||||
)
|
||||
|
||||
container_push(
|
||||
name = "push-public-testing",
|
||||
format = "Docker",
|
||||
image = ":image",
|
||||
registry = "registry.hub.docker.com",
|
||||
repository = "thesuperpirate/meta-api",
|
||||
tag = "testing",
|
||||
)
|
1
nexus/meta_api/README.md
Normal file
1
nexus/meta_api/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Nexus Search: Meta API
|
0
nexus/meta_api/__init__.py
Normal file
0
nexus/meta_api/__init__.py
Normal file
16
nexus/meta_api/cli.py
Normal file
16
nexus/meta_api/cli.py
Normal file
@ -0,0 +1,16 @@
|
||||
import fire
|
||||
from aiokit.utils import sync_fu
|
||||
from nexus.meta_api.aioclient import MetaApiGrpcClient
|
||||
|
||||
|
||||
async def search(url, schema, query):
|
||||
client = MetaApiGrpcClient(url)
|
||||
try:
|
||||
await client.start()
|
||||
print(await client.search(schemas=(schema,), query=query, language='ru'))
|
||||
finally:
|
||||
await client.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
fire.Fire(sync_fu(search))
|
14
nexus/meta_api/configs/__init__.py
Normal file
14
nexus/meta_api/configs/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
from izihawa_utils import env
|
||||
from library.configurator import Configurator
|
||||
|
||||
|
||||
def get_config():
|
||||
return Configurator([
|
||||
'nexus/meta_api/configs/base.yaml',
|
||||
'nexus/meta_api/configs/metrics.yaml?',
|
||||
'nexus/meta_api/configs/%s.yaml?' % env.type,
|
||||
'nexus/meta_api/configs/logging.yaml',
|
||||
], env_prefix='NEXUS_META_API')
|
||||
|
||||
|
||||
config = get_config()
|
20
nexus/meta_api/configs/base.yaml
Normal file
20
nexus/meta_api/configs/base.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
|
||||
application:
|
||||
debug: true
|
||||
learn_log: true
|
||||
request_id_length: 12
|
||||
session_id_length: 8
|
||||
threads: 4
|
||||
data_provider:
|
||||
enabled: false
|
||||
grpc:
|
||||
host: 0.0.0.0
|
||||
port: 9090
|
||||
log_path: '/var/log/nexus-meta-api'
|
||||
stat_provider:
|
||||
enabled: false
|
||||
summa:
|
||||
timeout: 15
|
||||
ttl_dns_cache: 30
|
||||
url:
|
106
nexus/meta_api/configs/logging.yaml
Normal file
106
nexus/meta_api/configs/logging.yaml
Normal file
@ -0,0 +1,106 @@
|
||||
---
|
||||
|
||||
logging:
|
||||
disable_existing_loggers: false
|
||||
formatters:
|
||||
base:
|
||||
class: library.logging.formatters.BaseFormatter
|
||||
default:
|
||||
class: library.logging.formatters.DefaultFormatter
|
||||
none:
|
||||
class: logging.Formatter
|
||||
traceback:
|
||||
class: library.logging.formatters.TracebackFormatter
|
||||
handlers:
|
||||
debug:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/debug.log'
|
||||
level: DEBUG
|
||||
error:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/error.log'
|
||||
formatter: default
|
||||
level: ERROR
|
||||
learn:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/learn.log'
|
||||
formatter: base
|
||||
level: INFO
|
||||
operation:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/operation.log'
|
||||
formatter: base
|
||||
level: DEBUG
|
||||
query:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/query.log'
|
||||
formatter: default
|
||||
level: DEBUG
|
||||
statbox:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/statbox.log'
|
||||
formatter: default
|
||||
level: DEBUG
|
||||
traceback:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/traceback.log'
|
||||
formatter: traceback
|
||||
level: ERROR
|
||||
warning:
|
||||
class: library.logging.handlers.BaseFileHandler
|
||||
filename: '{{ log_path }}/warning.log'
|
||||
formatter: default
|
||||
level: WARNING
|
||||
wsgi:
|
||||
class: logging.StreamHandler
|
||||
level: WARNING
|
||||
stream: 'ext://sys.stderr'
|
||||
loggers:
|
||||
aiobaseclient:
|
||||
handlers:
|
||||
- error
|
||||
- warning
|
||||
propagate: false
|
||||
chardet:
|
||||
handlers:
|
||||
- error
|
||||
propagate: false
|
||||
debug:
|
||||
handlers:
|
||||
- debug
|
||||
propagate: false
|
||||
error:
|
||||
handlers:
|
||||
- error
|
||||
- traceback
|
||||
- warning
|
||||
propagate: false
|
||||
learn:
|
||||
handlers:
|
||||
- learn
|
||||
propagate: false
|
||||
metrics:
|
||||
handlers:
|
||||
- error
|
||||
propagate: false
|
||||
operation:
|
||||
handlers:
|
||||
- operation
|
||||
propagate: false
|
||||
query:
|
||||
handlers:
|
||||
- query
|
||||
propagate: false
|
||||
statbox:
|
||||
handlers:
|
||||
- statbox
|
||||
propagate: false
|
||||
telethon:
|
||||
handlers:
|
||||
- error
|
||||
propagate: false
|
||||
root:
|
||||
handlers:
|
||||
- debug
|
||||
level: DEBUG
|
||||
version: 1
|
@ -6,6 +6,7 @@ js_library(
|
||||
data = [
|
||||
"//library/js:base-client",
|
||||
"//library/js:utils",
|
||||
"//nexus/meta_api/proto:meta_api_grpc_web_js",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
39
nexus/meta_api/js/client/index.js
Normal file
39
nexus/meta_api/js/client/index.js
Normal file
@ -0,0 +1,39 @@
|
||||
import documentsProto from '~/nexus/meta_api/proto/documents_service_grpc_web_pb'
|
||||
import searchProto from '~/nexus/meta_api/proto/search_service_grpc_web_pb'
|
||||
|
||||
export default class MetaApi {
|
||||
constructor (config) {
|
||||
this.documentsClient = new documentsProto.DocumentsPromiseClient(config.url)
|
||||
this.searchClient = new searchProto.SearchPromiseClient(config.url)
|
||||
}
|
||||
|
||||
generateId (length) {
|
||||
const result = []
|
||||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
||||
const charactersLength = characters.length
|
||||
for (let i = 0; i < length; i++) {
|
||||
result.push(characters.charAt(Math.floor(Math.random() * charactersLength)))
|
||||
}
|
||||
return result.join('')
|
||||
}
|
||||
|
||||
async getView (schema, documentId) {
|
||||
const request = new documentsProto.TypedDocumentRequest()
|
||||
request.setSchema(schema)
|
||||
request.setDocumentId(documentId)
|
||||
request.setSessionId(this.generateId(8))
|
||||
const response = await this.documentsClient.get_view(request, { 'request-id': this.generateId(12) })
|
||||
return response.toObject()
|
||||
}
|
||||
|
||||
async search (schema, query, page, pageSize = 5) {
|
||||
const request = new searchProto.SearchRequest()
|
||||
request.setPage(page)
|
||||
request.setPageSize(pageSize)
|
||||
request.addSchemas(schema)
|
||||
request.setQuery(query)
|
||||
request.setSessionId(this.generateId(8))
|
||||
const response = await this.searchClient.search(request, { 'request-id': this.generateId(12) })
|
||||
return response.toObject()
|
||||
}
|
||||
}
|
66
nexus/meta_api/main.py
Normal file
66
nexus/meta_api/main.py
Normal file
@ -0,0 +1,66 @@
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
import uvloop
|
||||
from aiosumma import SummaHttpClient
|
||||
from library.aiogrpctools import AioGrpcServer
|
||||
from library.configurator import Configurator
|
||||
from library.logging import configure_logging
|
||||
from nexus.meta_api.configs import get_config
|
||||
from nexus.meta_api.providers.data import DataProvider
|
||||
from nexus.meta_api.providers.stat import StatProvider
|
||||
from nexus.meta_api.services.documents import DocumentsService
|
||||
from nexus.meta_api.services.search import SearchService
|
||||
|
||||
|
||||
class GrpcServer(AioGrpcServer):
|
||||
def __init__(self, config):
|
||||
super().__init__(address=config['grpc']['host'], port=config['grpc']['port'])
|
||||
self.config = config
|
||||
|
||||
self.summa_client = SummaHttpClient(
|
||||
base_url=config['summa']['url'],
|
||||
timeout=config['summa']['timeout'],
|
||||
ttl_dns_cache=config['summa']['ttl_dns_cache'],
|
||||
)
|
||||
self.data_provider = DataProvider(data_provider_config=self.config['data_provider'])
|
||||
self.stat_provider = StatProvider(stat_provider_config=self.config['stat_provider'])
|
||||
|
||||
learn_logger = logging.getLogger('learn') if self.config['application']['learn_log'] else None
|
||||
|
||||
self.search_service = SearchService(
|
||||
server=self.server,
|
||||
summa_client=self.summa_client,
|
||||
stat_provider=self.stat_provider,
|
||||
learn_logger=learn_logger,
|
||||
)
|
||||
self.documents_service = DocumentsService(
|
||||
server=self.server,
|
||||
summa_client=self.summa_client,
|
||||
data_provider=self.data_provider,
|
||||
stat_provider=self.stat_provider,
|
||||
learn_logger=learn_logger,
|
||||
)
|
||||
self.waits.extend([self.summa_client, self.data_provider, self.stat_provider,
|
||||
self.search_service, self.documents_service])
|
||||
|
||||
|
||||
async def create_app(config: Configurator):
|
||||
try:
|
||||
await GrpcServer(config).start_and_wait()
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
config = get_config()
|
||||
configure_logging(config)
|
||||
if config['metrics']['enabled']:
|
||||
from library.metrics_server import MetricsServer
|
||||
MetricsServer(config['metrics']).fork_process()
|
||||
asyncio.set_event_loop(uvloop.new_event_loop())
|
||||
asyncio.get_event_loop().run_until_complete(create_app(config))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
1760
nexus/meta_api/models/classic.txt
Normal file
1760
nexus/meta_api/models/classic.txt
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library")
|
||||
load("@rules_rust//proto:proto.bzl", "rust_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
load("@rules_proto_grpc//js:defs.bzl", "js_grpc_node_library", "js_proto_library")
|
||||
load("@rules_proto_grpc//js:defs.bzl", "js_grpc_web_library")
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
@ -34,13 +34,10 @@ rust_proto_library(
|
||||
deps = [":meta_api_proto"],
|
||||
)
|
||||
|
||||
js_proto_library(
|
||||
name = "meta_api_proto_js",
|
||||
deps = ["meta_api_proto"],
|
||||
)
|
||||
|
||||
js_grpc_node_library(
|
||||
name = "meta_api_grpc_js",
|
||||
js_grpc_web_library(
|
||||
name = "meta_api_grpc_web_js",
|
||||
prefix_path = "../../../../",
|
||||
protos = [":meta_api_proto"],
|
||||
deps = [":meta_api_proto_js"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//nexus/models/proto:models_proto_js"],
|
||||
)
|
||||
|
@ -35,8 +35,18 @@ message TypedDocumentRequest {
|
||||
|
||||
message PutTypedDocumentResponse {}
|
||||
|
||||
message GetViewResponse {
|
||||
nexus.models.proto.TypedDocument typed_document = 1;
|
||||
string filedata = 2;
|
||||
string filename = 3;
|
||||
string filesize = 4;
|
||||
string first_authors = 5;
|
||||
string locator = 6;
|
||||
}
|
||||
|
||||
service Documents {
|
||||
rpc get (TypedDocumentRequest) returns (nexus.models.proto.TypedDocument) {}
|
||||
rpc get_view (TypedDocumentRequest) returns (GetViewResponse) {}
|
||||
rpc roll (RollRequest) returns (RollResponse) {}
|
||||
rpc top_missed (TopMissedRequest) returns (TopMissedResponse) {}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
syntax='proto3',
|
||||
serialized_options=None,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
serialized_pb=b'\n,nexus/meta_api/proto/documents_service.proto\x12\x14nexus.meta_api.proto\x1a\'nexus/models/proto/typed_document.proto\"D\n\x0bRollRequest\x12\x10\n\x08language\x18\x01 \x01(\t\x12\x12\n\nsession_id\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\x03\"#\n\x0cRollResponse\x12\x13\n\x0b\x64ocument_id\x18\x01 \x01(\x04\"X\n\x10TopMissedRequest\x12\x0c\n\x04page\x18\x01 \x01(\r\x12\x11\n\tpage_size\x18\x02 \x01(\r\x12\x12\n\nsession_id\x18\x03 \x01(\t\x12\x0f\n\x07user_id\x18\x04 \x01(\x03\"a\n\x11TopMissedResponse\x12:\n\x0ftyped_documents\x18\x01 \x03(\x0b\x32!.nexus.models.proto.TypedDocument\x12\x10\n\x08has_next\x18\x02 \x01(\x08\"r\n\x14TypedDocumentRequest\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12\x13\n\x0b\x64ocument_id\x18\x02 \x01(\x04\x12\x10\n\x08position\x18\x03 \x01(\r\x12\x12\n\nsession_id\x18\x04 \x01(\t\x12\x0f\n\x07user_id\x18\x05 \x01(\x03\"\x1a\n\x18PutTypedDocumentResponse2\x95\x02\n\tDocuments\x12V\n\x03get\x12*.nexus.meta_api.proto.TypedDocumentRequest\x1a!.nexus.models.proto.TypedDocument\"\x00\x12O\n\x04roll\x12!.nexus.meta_api.proto.RollRequest\x1a\".nexus.meta_api.proto.RollResponse\"\x00\x12_\n\ntop_missed\x12&.nexus.meta_api.proto.TopMissedRequest\x1a\'.nexus.meta_api.proto.TopMissedResponse\"\x00\x62\x06proto3'
|
||||
serialized_pb=b'\n,nexus/meta_api/proto/documents_service.proto\x12\x14nexus.meta_api.proto\x1a\'nexus/models/proto/typed_document.proto\"D\n\x0bRollRequest\x12\x10\n\x08language\x18\x01 \x01(\t\x12\x12\n\nsession_id\x18\x02 \x01(\t\x12\x0f\n\x07user_id\x18\x03 \x01(\x03\"#\n\x0cRollResponse\x12\x13\n\x0b\x64ocument_id\x18\x01 \x01(\x04\"X\n\x10TopMissedRequest\x12\x0c\n\x04page\x18\x01 \x01(\r\x12\x11\n\tpage_size\x18\x02 \x01(\r\x12\x12\n\nsession_id\x18\x03 \x01(\t\x12\x0f\n\x07user_id\x18\x04 \x01(\x03\"a\n\x11TopMissedResponse\x12:\n\x0ftyped_documents\x18\x01 \x03(\x0b\x32!.nexus.models.proto.TypedDocument\x12\x10\n\x08has_next\x18\x02 \x01(\x08\"r\n\x14TypedDocumentRequest\x12\x0e\n\x06schema\x18\x01 \x01(\t\x12\x13\n\x0b\x64ocument_id\x18\x02 \x01(\x04\x12\x10\n\x08position\x18\x03 \x01(\r\x12\x12\n\nsession_id\x18\x04 \x01(\t\x12\x0f\n\x07user_id\x18\x05 \x01(\x03\"\x1a\n\x18PutTypedDocumentResponse\"u\n\x0fGetViewResponse\x12\x39\n\x0etyped_document\x18\x01 \x01(\x0b\x32!.nexus.models.proto.TypedDocument\x12\x10\n\x08\x66ilename\x18\x02 \x01(\t\x12\x15\n\rfirst_authors\x18\x03 \x01(\t2\xf6\x02\n\tDocuments\x12V\n\x03get\x12*.nexus.meta_api.proto.TypedDocumentRequest\x1a!.nexus.models.proto.TypedDocument\"\x00\x12_\n\x08get_view\x12*.nexus.meta_api.proto.TypedDocumentRequest\x1a%.nexus.meta_api.proto.GetViewResponse\"\x00\x12O\n\x04roll\x12!.nexus.meta_api.proto.RollRequest\x1a\".nexus.meta_api.proto.RollResponse\"\x00\x12_\n\ntop_missed\x12&.nexus.meta_api.proto.TopMissedRequest\x1a\'.nexus.meta_api.proto.TopMissedResponse\"\x00\x62\x06proto3'
|
||||
,
|
||||
dependencies=[nexus_dot_models_dot_proto_dot_typed__document__pb2.DESCRIPTOR,])
|
||||
|
||||
@ -282,13 +282,61 @@ _PUTTYPEDDOCUMENTRESPONSE = _descriptor.Descriptor(
|
||||
serialized_end=549,
|
||||
)
|
||||
|
||||
|
||||
_GETVIEWRESPONSE = _descriptor.Descriptor(
|
||||
name='GetViewResponse',
|
||||
full_name='nexus.meta_api.proto.GetViewResponse',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='typed_document', full_name='nexus.meta_api.proto.GetViewResponse.typed_document', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='filename', full_name='nexus.meta_api.proto.GetViewResponse.filename', index=1,
|
||||
number=2, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=b"".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='first_authors', full_name='nexus.meta_api.proto.GetViewResponse.first_authors', index=2,
|
||||
number=3, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=b"".decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=551,
|
||||
serialized_end=668,
|
||||
)
|
||||
|
||||
_TOPMISSEDRESPONSE.fields_by_name['typed_documents'].message_type = nexus_dot_models_dot_proto_dot_typed__document__pb2._TYPEDDOCUMENT
|
||||
_GETVIEWRESPONSE.fields_by_name['typed_document'].message_type = nexus_dot_models_dot_proto_dot_typed__document__pb2._TYPEDDOCUMENT
|
||||
DESCRIPTOR.message_types_by_name['RollRequest'] = _ROLLREQUEST
|
||||
DESCRIPTOR.message_types_by_name['RollResponse'] = _ROLLRESPONSE
|
||||
DESCRIPTOR.message_types_by_name['TopMissedRequest'] = _TOPMISSEDREQUEST
|
||||
DESCRIPTOR.message_types_by_name['TopMissedResponse'] = _TOPMISSEDRESPONSE
|
||||
DESCRIPTOR.message_types_by_name['TypedDocumentRequest'] = _TYPEDDOCUMENTREQUEST
|
||||
DESCRIPTOR.message_types_by_name['PutTypedDocumentResponse'] = _PUTTYPEDDOCUMENTRESPONSE
|
||||
DESCRIPTOR.message_types_by_name['GetViewResponse'] = _GETVIEWRESPONSE
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
RollRequest = _reflection.GeneratedProtocolMessageType('RollRequest', (_message.Message,), {
|
||||
@ -333,6 +381,13 @@ PutTypedDocumentResponse = _reflection.GeneratedProtocolMessageType('PutTypedDoc
|
||||
})
|
||||
_sym_db.RegisterMessage(PutTypedDocumentResponse)
|
||||
|
||||
GetViewResponse = _reflection.GeneratedProtocolMessageType('GetViewResponse', (_message.Message,), {
|
||||
'DESCRIPTOR' : _GETVIEWRESPONSE,
|
||||
'__module__' : 'nexus.meta_api.proto.documents_service_pb2'
|
||||
# @@protoc_insertion_point(class_scope:nexus.meta_api.proto.GetViewResponse)
|
||||
})
|
||||
_sym_db.RegisterMessage(GetViewResponse)
|
||||
|
||||
|
||||
|
||||
_DOCUMENTS = _descriptor.ServiceDescriptor(
|
||||
@ -342,8 +397,8 @@ _DOCUMENTS = _descriptor.ServiceDescriptor(
|
||||
index=0,
|
||||
serialized_options=None,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
serialized_start=552,
|
||||
serialized_end=829,
|
||||
serialized_start=671,
|
||||
serialized_end=1045,
|
||||
methods=[
|
||||
_descriptor.MethodDescriptor(
|
||||
name='get',
|
||||
@ -355,10 +410,20 @@ _DOCUMENTS = _descriptor.ServiceDescriptor(
|
||||
serialized_options=None,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
),
|
||||
_descriptor.MethodDescriptor(
|
||||
name='get_view',
|
||||
full_name='nexus.meta_api.proto.Documents.get_view',
|
||||
index=1,
|
||||
containing_service=None,
|
||||
input_type=_TYPEDDOCUMENTREQUEST,
|
||||
output_type=_GETVIEWRESPONSE,
|
||||
serialized_options=None,
|
||||
create_key=_descriptor._internal_create_key,
|
||||
),
|
||||
_descriptor.MethodDescriptor(
|
||||
name='roll',
|
||||
full_name='nexus.meta_api.proto.Documents.roll',
|
||||
index=1,
|
||||
index=2,
|
||||
containing_service=None,
|
||||
input_type=_ROLLREQUEST,
|
||||
output_type=_ROLLRESPONSE,
|
||||
@ -368,7 +433,7 @@ _DOCUMENTS = _descriptor.ServiceDescriptor(
|
||||
_descriptor.MethodDescriptor(
|
||||
name='top_missed',
|
||||
full_name='nexus.meta_api.proto.Documents.top_missed',
|
||||
index=2,
|
||||
index=3,
|
||||
containing_service=None,
|
||||
input_type=_TOPMISSEDREQUEST,
|
||||
output_type=_TOPMISSEDRESPONSE,
|
||||
|
@ -22,6 +22,11 @@ class DocumentsStub(object):
|
||||
request_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TypedDocumentRequest.SerializeToString,
|
||||
response_deserializer=nexus_dot_models_dot_proto_dot_typed__document__pb2.TypedDocument.FromString,
|
||||
)
|
||||
self.get_view = channel.unary_unary(
|
||||
'/nexus.meta_api.proto.Documents/get_view',
|
||||
request_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TypedDocumentRequest.SerializeToString,
|
||||
response_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.GetViewResponse.FromString,
|
||||
)
|
||||
self.roll = channel.unary_unary(
|
||||
'/nexus.meta_api.proto.Documents/roll',
|
||||
request_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollRequest.SerializeToString,
|
||||
@ -43,6 +48,12 @@ class DocumentsServicer(object):
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def get_view(self, request, context):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def roll(self, request, context):
|
||||
"""Missing associated documentation comment in .proto file."""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
@ -63,6 +74,11 @@ def add_DocumentsServicer_to_server(servicer, server):
|
||||
request_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TypedDocumentRequest.FromString,
|
||||
response_serializer=nexus_dot_models_dot_proto_dot_typed__document__pb2.TypedDocument.SerializeToString,
|
||||
),
|
||||
'get_view': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.get_view,
|
||||
request_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TypedDocumentRequest.FromString,
|
||||
response_serializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.GetViewResponse.SerializeToString,
|
||||
),
|
||||
'roll': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.roll,
|
||||
request_deserializer=nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.RollRequest.FromString,
|
||||
@ -100,6 +116,23 @@ class Documents(object):
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def get_view(request,
|
||||
target,
|
||||
options=(),
|
||||
channel_credentials=None,
|
||||
call_credentials=None,
|
||||
insecure=False,
|
||||
compression=None,
|
||||
wait_for_ready=None,
|
||||
timeout=None,
|
||||
metadata=None):
|
||||
return grpc.experimental.unary_unary(request, target, '/nexus.meta_api.proto.Documents/get_view',
|
||||
nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.TypedDocumentRequest.SerializeToString,
|
||||
nexus_dot_meta__api_dot_proto_dot_documents__service__pb2.GetViewResponse.FromString,
|
||||
options, channel_credentials,
|
||||
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
||||
|
||||
@staticmethod
|
||||
def roll(request,
|
||||
target,
|
||||
|
0
nexus/meta_api/providers/__init__.py
Normal file
0
nexus/meta_api/providers/__init__.py
Normal file
69
nexus/meta_api/providers/data.py
Normal file
69
nexus/meta_api/providers/data.py
Normal file
@ -0,0 +1,69 @@
|
||||
from typing import List
|
||||
|
||||
import aiopg
|
||||
from aiokit import AioThing
|
||||
from library.aiopostgres.pool_holder import AioPostgresPoolHolder
|
||||
from recordclass import dataobject
|
||||
|
||||
|
||||
class DocumentData(dataobject):
|
||||
ipfs_multihashes: List[str]
|
||||
telegram_file_id: int
|
||||
|
||||
|
||||
class DataProvider(AioThing):
|
||||
def __init__(self, data_provider_config: dict):
|
||||
super().__init__()
|
||||
self.pool_holder = None
|
||||
if data_provider_config['enabled']:
|
||||
self.pool_holder = AioPostgresPoolHolder(
|
||||
fn=aiopg.create_pool,
|
||||
dsn=f'dbname={data_provider_config["database"]} '
|
||||
f'user={data_provider_config["username"]} '
|
||||
f'password={data_provider_config["password"]} '
|
||||
f'host={data_provider_config["host"]}',
|
||||
timeout=30,
|
||||
pool_recycle=60,
|
||||
maxsize=4,
|
||||
)
|
||||
self.waits.append(self.pool_holder)
|
||||
|
||||
async def get(self, document_id):
|
||||
if not self.pool_holder:
|
||||
return
|
||||
pg_data = await self.pool_holder.execute('''
|
||||
select id, telegram_file_id, ipfs_multihashes
|
||||
from scimag
|
||||
where id = %s
|
||||
union all
|
||||
select id, telegram_file_id, ipfs_multihashes
|
||||
from scitech
|
||||
where id = %s
|
||||
''', (document_id, document_id), fetch=True)
|
||||
for _, telegram_file_id, ipfs_multihashes in pg_data:
|
||||
return DocumentData(
|
||||
ipfs_multihashes=ipfs_multihashes or [],
|
||||
telegram_file_id=telegram_file_id or '',
|
||||
)
|
||||
|
||||
async def random_id(self, language):
|
||||
if not self.pool_holder:
|
||||
return
|
||||
pg_data = await self.pool_holder.execute('''
|
||||
select id from scitech
|
||||
where
|
||||
(language = %s or language = 'en')
|
||||
and original_id is null
|
||||
and is_deleted = false
|
||||
offset floor(
|
||||
random() * (
|
||||
select count(*) from scitech where
|
||||
(language = %s or language = 'en')
|
||||
and original_id is null
|
||||
and is_deleted = false
|
||||
)
|
||||
)
|
||||
limit 1;
|
||||
''', (language, language), fetch=True)
|
||||
for (id_,) in pg_data:
|
||||
return id_
|
114
nexus/meta_api/providers/stat.py
Normal file
114
nexus/meta_api/providers/stat.py
Normal file
@ -0,0 +1,114 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from aiochclient import ChClient
|
||||
from aiohttp import ClientSession
|
||||
from aiokit import AioThing
|
||||
from recordclass import dataobject
|
||||
|
||||
|
||||
class DocumentStat(dataobject):
|
||||
downloads_count: int
|
||||
|
||||
|
||||
class StatProvider(AioThing):
|
||||
def __init__(self, stat_provider_config):
|
||||
super().__init__()
|
||||
self.stat_provider_config = stat_provider_config
|
||||
self.clickhouse_session = None
|
||||
self.clickhouse_client = None
|
||||
self.download_stats = {}
|
||||
self.top_missed_stats = []
|
||||
self.current_task = None
|
||||
|
||||
if stat_provider_config['enabled']:
|
||||
self.clickhouse_session = ClientSession()
|
||||
self.clickhouse_client = ChClient(
|
||||
self.clickhouse_session,
|
||||
url=stat_provider_config['clickhouse']['host'],
|
||||
user=stat_provider_config['clickhouse']['username'],
|
||||
password=stat_provider_config['clickhouse']['password'],
|
||||
)
|
||||
|
||||
@asynccontextmanager
|
||||
async def _safe_execution(self):
|
||||
try:
|
||||
yield
|
||||
except asyncio.CancelledError as e:
|
||||
logging.getLogger('error').warning(e)
|
||||
except Exception as e:
|
||||
logging.getLogger('error').error(e)
|
||||
raise
|
||||
|
||||
async def load_download_stats(self):
|
||||
async with self._safe_execution():
|
||||
download_stats = {}
|
||||
logging.getLogger('statbox').info({
|
||||
'action': 'start_loading',
|
||||
'stats': 'download_stats',
|
||||
})
|
||||
async for row in self.clickhouse_client.iterate('''
|
||||
select id, count(distinct user_id) as c
|
||||
from query_log where mode = 'get' and id != 0
|
||||
group by id
|
||||
'''):
|
||||
download_stats[row['id']] = DocumentStat(downloads_count=row['c'])
|
||||
self.download_stats = download_stats
|
||||
logging.getLogger('statbox').info({
|
||||
'action': 'loaded',
|
||||
'stats': 'download_stats',
|
||||
'items': len(download_stats),
|
||||
})
|
||||
await asyncio.sleep(self.stat_provider_config['download_stats']['refresh_time_secs'])
|
||||
|
||||
async def load_top_missed_stats(self):
|
||||
async with self._safe_execution():
|
||||
top_missed_stats = []
|
||||
logging.getLogger('statbox').info({
|
||||
'action': 'start_loading',
|
||||
'stats': 'top_missing',
|
||||
})
|
||||
async for row in self.clickhouse_client.iterate('''
|
||||
select
|
||||
document_id,
|
||||
count(distinct chat_id) as c from telegram_statbox_log
|
||||
where action = 'missed' and
|
||||
(mode = 'start_delivery' or mode = 'delivery') and
|
||||
schema = 'scimag'
|
||||
group by document_id
|
||||
order by count(distinct chat_id) desc, document_id desc limit 1000
|
||||
'''):
|
||||
top_missed_stats.append(row['document_id'])
|
||||
self.top_missed_stats = top_missed_stats
|
||||
logging.getLogger('statbox').info({
|
||||
'action': 'loaded',
|
||||
'stats': 'top_missing',
|
||||
'items': len(top_missed_stats),
|
||||
})
|
||||
await asyncio.sleep(self.stat_provider_config['top_missed_stats']['refresh_time_secs'])
|
||||
|
||||
def get_download_stats(self, document_id, default=None):
|
||||
return self.download_stats.get(document_id, default)
|
||||
|
||||
def get_top_missed_stats(self):
|
||||
return self.top_missed_stats
|
||||
|
||||
async def all_tasks(self):
|
||||
return await asyncio.gather(
|
||||
self.load_download_stats(),
|
||||
self.load_top_missed_stats(),
|
||||
)
|
||||
|
||||
async def start(self):
|
||||
if self.clickhouse_session:
|
||||
self.current_task = asyncio.create_task(self.all_tasks())
|
||||
|
||||
async def stop(self):
|
||||
await self.cancel()
|
||||
if self.clickhouse_session:
|
||||
await self.clickhouse_session.close()
|
||||
if self.current_task:
|
||||
self.current_task.cancel()
|
||||
await self.current_task
|
||||
await super().stop()
|
16
nexus/meta_api/query_extensionner/BUILD.bazel
Normal file
16
nexus/meta_api/query_extensionner/BUILD.bazel
Normal file
@ -0,0 +1,16 @@
|
||||
load("@pip_modules//:requirements.bzl", "requirement")
|
||||
load("@rules_python//python:defs.bzl", "py_library")
|
||||
|
||||
py_library(
|
||||
name = "query_extensionner",
|
||||
srcs = glob(["**/*.py"]),
|
||||
srcs_version = "PY3",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
requirement("en_core_web_sm"),
|
||||
requirement("ply"),
|
||||
requirement("izihawa_types"),
|
||||
"//nexus/nlptools",
|
||||
requirement("izihawa_utils"),
|
||||
],
|
||||
)
|
31
nexus/meta_api/query_extensionner/__init__.py
Normal file
31
nexus/meta_api/query_extensionner/__init__.py
Normal file
@ -0,0 +1,31 @@
|
||||
from nexus.meta_api.query_extensionner.grammar import (
|
||||
FieldResolver,
|
||||
MorphyResolver,
|
||||
OrOperation,
|
||||
UnknownOperationResolver,
|
||||
parser,
|
||||
)
|
||||
|
||||
from . import checks
|
||||
from .checks import QueryClass
|
||||
|
||||
|
||||
class QueryProcessor:
|
||||
checks = tuple()
|
||||
|
||||
def process(self, query, language):
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class ClassicQueryProcessor(QueryProcessor):
|
||||
checks = (checks.check_doi, checks.check_isbn, checks.check_nid, checks.check_url)
|
||||
|
||||
def process(self, query, language):
|
||||
uor = UnknownOperationResolver(OrOperation)
|
||||
fr = FieldResolver()
|
||||
morphy = MorphyResolver(language)
|
||||
for c in self.checks:
|
||||
r = c(query)
|
||||
if r:
|
||||
return r
|
||||
return {'query': str(uor.visit(fr.visit(morphy.visit(parser.parse(query))))), 'class': QueryClass.Default}
|
60
nexus/meta_api/query_extensionner/checks.py
Normal file
60
nexus/meta_api/query_extensionner/checks.py
Normal file
@ -0,0 +1,60 @@
|
||||
import re
|
||||
from enum import Enum
|
||||
|
||||
from nexus.nlptools.regex import (
|
||||
DOI_REGEX,
|
||||
ISBN_REGEX,
|
||||
NID_REGEX,
|
||||
URL_REGEX,
|
||||
)
|
||||
|
||||
# ToDo: redo all, code is logically incorrect now
|
||||
|
||||
|
||||
class QueryClass(Enum):
|
||||
Default = 'default'
|
||||
DOI = 'doi'
|
||||
ISBN = 'isbn'
|
||||
NID = 'nid'
|
||||
URL = 'url'
|
||||
|
||||
|
||||
def check_doi(query) -> (QueryClass, str):
|
||||
# ToDo: rewrite normally, just hotfixed
|
||||
if query.startswith('references:'):
|
||||
return
|
||||
if r := re.search(DOI_REGEX, query):
|
||||
doi = (r[1] + '/' + r[2]).lower()
|
||||
return {
|
||||
'doi': doi,
|
||||
'query': f'doi:"{doi}"',
|
||||
'class': QueryClass.DOI,
|
||||
}
|
||||
|
||||
|
||||
def check_isbn(query: str) -> (QueryClass, str):
|
||||
if r := re.search(ISBN_REGEX, query):
|
||||
isbn = r[1].replace('-', '')
|
||||
return {
|
||||
'isbn': isbn,
|
||||
'query': 'isbns:' + isbn,
|
||||
'class': QueryClass.ISBN
|
||||
}
|
||||
|
||||
|
||||
def check_nid(query: str) -> (QueryClass, str):
|
||||
if r := re.search(NID_REGEX, query):
|
||||
return {
|
||||
'id': r[1],
|
||||
'query': 'id:' + r[1],
|
||||
'class': QueryClass.NID,
|
||||
}
|
||||
|
||||
|
||||
def check_url(query: str) -> (QueryClass, str):
|
||||
if r := re.search(URL_REGEX, query):
|
||||
return {
|
||||
'url': r[0],
|
||||
'query': r[0],
|
||||
'class': QueryClass.URL,
|
||||
}
|
9
nexus/meta_api/query_extensionner/grammar/__init__.py
Normal file
9
nexus/meta_api/query_extensionner/grammar/__init__.py
Normal file
@ -0,0 +1,9 @@
|
||||
from .parser import parser
|
||||
from .tree import OrOperation
|
||||
from .tree_transformer import (
|
||||
FieldResolver,
|
||||
MorphyResolver,
|
||||
UnknownOperationResolver,
|
||||
)
|
||||
|
||||
__all__ = ['parser', 'FieldResolver', 'MorphyResolver', 'OrOperation', 'UnknownOperationResolver']
|
330
nexus/meta_api/query_extensionner/grammar/parser.py
Normal file
330
nexus/meta_api/query_extensionner/grammar/parser.py
Normal file
@ -0,0 +1,330 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""The Lucene Query DSL parser based on PLY
|
||||
"""
|
||||
|
||||
import logging
|
||||
# TODO : add reserved chars and escaping, regex
|
||||
# see : https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html
|
||||
# https://lucene.apache.org/core/3_6_0/queryparsersyntax.html
|
||||
import re
|
||||
|
||||
import ply.lex as lex
|
||||
import ply.yacc as yacc
|
||||
from izihawa_utils.exceptions import BaseError
|
||||
|
||||
from .tree import (
|
||||
QUOTES,
|
||||
AndOperation,
|
||||
Boost,
|
||||
Fuzzy,
|
||||
Group,
|
||||
Not,
|
||||
OrOperation,
|
||||
Phrase,
|
||||
Plus,
|
||||
Prohibit,
|
||||
Proximity,
|
||||
Range,
|
||||
Regex,
|
||||
SearchField,
|
||||
UnknownOperation,
|
||||
Word,
|
||||
create_operation,
|
||||
group_to_fieldgroup,
|
||||
)
|
||||
|
||||
|
||||
class ParseError(BaseError):
|
||||
code = 'parse_error'
|
||||
level = logging.WARNING
|
||||
|
||||
|
||||
reserved = {
|
||||
'AND': 'AND_OP',
|
||||
'OR': 'OR_OP',
|
||||
'NOT': 'NOT',
|
||||
'TO': 'TO',
|
||||
'to': 'TO',
|
||||
}
|
||||
|
||||
|
||||
# tokens of our grammar
|
||||
tokens = (
|
||||
['TERM',
|
||||
'PHRASE',
|
||||
'REGEX',
|
||||
'APPROX',
|
||||
'BOOST',
|
||||
'MINUS',
|
||||
'PLUS',
|
||||
'COLUMN',
|
||||
'LPAREN',
|
||||
'RPAREN',
|
||||
'LBRACKET',
|
||||
'RBRACKET'
|
||||
] + sorted(set(reserved.values()))
|
||||
)
|
||||
|
||||
|
||||
# text of some simple tokens
|
||||
t_PLUS = r'\+(?=\S)'
|
||||
t_MINUS = r'\-(?=\S)'
|
||||
t_NOT = 'NOT'
|
||||
t_AND_OP = r'AND'
|
||||
t_OR_OP = r'OR'
|
||||
t_COLUMN = r'(?<=\S):(?=\S)'
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_LBRACKET = r'(\[|\{)'
|
||||
t_RBRACKET = r'(\]|\})'
|
||||
|
||||
# precedence rules
|
||||
precedence = (
|
||||
('left', 'OR_OP',),
|
||||
('left', 'AND_OP'),
|
||||
('nonassoc', 'MINUS',),
|
||||
('nonassoc', 'PLUS',),
|
||||
('nonassoc', 'APPROX'),
|
||||
('nonassoc', 'BOOST'),
|
||||
('nonassoc', 'LPAREN', 'RPAREN'),
|
||||
('nonassoc', 'LBRACKET', 'TO', 'RBRACKET'),
|
||||
('nonassoc', 'REGEX'),
|
||||
('nonassoc', 'PHRASE'),
|
||||
('nonassoc', 'TERM'),
|
||||
)
|
||||
|
||||
# term
|
||||
|
||||
# the case of : which is used in date is problematic because it is also a delimiter
|
||||
# lets catch those expressions appart
|
||||
# Note : we must use positive look behind, because regexp engine is eager,
|
||||
# and it's only arrived at ':' that it will try this rule
|
||||
TIME_RE = r'''
|
||||
(?<=T\d{2}): # look behind for T and two digits: hours
|
||||
\d{2} # minutes
|
||||
(:\d{2})? # seconds
|
||||
'''
|
||||
# this is a wide catching expression, to also include date math.
|
||||
# Inspired by the original lucene parser:
|
||||
# https://github.com/apache/lucene-solr/blob/master/lucene/queryparser/src/java/org/apache/lucene/queryparser/surround/parser/QueryParser.jj#L189
|
||||
# We do allow the wildcards operators ('*' and '?') as our parser doesn't deal with them.
|
||||
|
||||
TERM_RE = fr'''
|
||||
(?P<term> # group term
|
||||
(?:
|
||||
[^\s:^~(){{}}[\]/,{QUOTES}+\-\\] # first char is not a space neither some char which have meanings
|
||||
# note: escape of "-" and "]"
|
||||
# and doubling of "{{}}" (because we use format)
|
||||
| # but
|
||||
\\. # we can start with an escaped character
|
||||
)
|
||||
([^\s:^\\~(){{}}[\]{QUOTES}] # following chars
|
||||
| # OR
|
||||
\\. # an escaped char
|
||||
| # OR
|
||||
{TIME_RE} # a time expression
|
||||
)*
|
||||
)
|
||||
'''
|
||||
# phrase
|
||||
PHRASE_RE = fr'''
|
||||
(?P<phrase> # phrase
|
||||
[{QUOTES}] # opening quote
|
||||
(?: # repeating
|
||||
[^\\{QUOTES}] # - a char which is not escape or end of phrase
|
||||
| # OR
|
||||
\\. # - an escaped char
|
||||
)*
|
||||
[{QUOTES}] # closing quote
|
||||
)'''
|
||||
# r'(?P<phrase>"(?:[^\\"]|\\"|\\[^"])*")' # this is quite complicated to handle \"
|
||||
# modifiers after term or phrase
|
||||
APPROX_RE = r'~(?P<degree>[0-9.]+)?'
|
||||
BOOST_RE = r'\^(?P<force>[0-9.]+)?'
|
||||
|
||||
# regex
|
||||
REGEX_RE = r'''
|
||||
(?P<regex> # regex
|
||||
/ # open slash
|
||||
(?: # repeating
|
||||
[^\\/] # - a char which is not escape or end of regex
|
||||
| # OR
|
||||
\\. # an escaped char
|
||||
)*
|
||||
/ # closing slash
|
||||
)'''
|
||||
|
||||
|
||||
def t_IGNORE_HANGING_SIGNS(t):
|
||||
r"""\s+[\+-]\s+"""
|
||||
pass
|
||||
|
||||
|
||||
def t_IGNORE_MAD_COLUMNS(t):
|
||||
r"""\s+:|:\s+|\s+:\s+"""
|
||||
pass
|
||||
|
||||
|
||||
def t_SEPARATOR(t):
|
||||
r'\s+'
|
||||
pass # discard separators
|
||||
|
||||
|
||||
@lex.TOKEN(TERM_RE)
|
||||
def t_TERM(t):
|
||||
# check if it is not a reserved term (an operation)
|
||||
t.type = reserved.get(t.value, 'TERM')
|
||||
# it's not, make it a Word
|
||||
if t.type == 'TERM':
|
||||
m = re.match(TERM_RE, t.value, re.VERBOSE)
|
||||
value = m.group("term")
|
||||
t.value = Word(value)
|
||||
return t
|
||||
|
||||
|
||||
@lex.TOKEN(PHRASE_RE)
|
||||
def t_PHRASE(t):
|
||||
m = re.match(PHRASE_RE, t.value, re.VERBOSE)
|
||||
value = m.group("phrase")
|
||||
t.value = Phrase(value)
|
||||
return t
|
||||
|
||||
|
||||
@lex.TOKEN(REGEX_RE)
|
||||
def t_REGEX(t):
|
||||
m = re.match(REGEX_RE, t.value, re.VERBOSE)
|
||||
value = m.group("regex")
|
||||
t.value = Regex(value)
|
||||
return t
|
||||
|
||||
|
||||
@lex.TOKEN(APPROX_RE)
|
||||
def t_APPROX(t):
|
||||
m = re.match(APPROX_RE, t.value)
|
||||
t.value = m.group("degree")
|
||||
return t
|
||||
|
||||
|
||||
@lex.TOKEN(BOOST_RE)
|
||||
def t_BOOST(t):
|
||||
m = re.match(BOOST_RE, t.value)
|
||||
t.value = m.group("force")
|
||||
return t
|
||||
|
||||
|
||||
# Error handling rule FIXME
|
||||
def t_error(t): # pragma: no cover
|
||||
t.lexer.skip(1)
|
||||
|
||||
|
||||
lexer = lex.lex()
|
||||
|
||||
|
||||
def p_expression_or(p):
|
||||
'expression : expression OR_OP expression'
|
||||
p[0] = create_operation(OrOperation, p[1], p[3])
|
||||
|
||||
|
||||
def p_expression_and(p):
|
||||
'''expression : expression AND_OP expression'''
|
||||
p[0] = create_operation(AndOperation, p[1], p[len(p) - 1])
|
||||
|
||||
|
||||
def p_expression_implicit(p):
|
||||
'''expression : expression expression'''
|
||||
p[0] = create_operation(UnknownOperation, p[1], p[2])
|
||||
|
||||
|
||||
def p_expression_plus(p):
|
||||
'''unary_expression : PLUS unary_expression'''
|
||||
p[0] = Plus(p[2])
|
||||
|
||||
|
||||
def p_expression_minus(p):
|
||||
'''unary_expression : MINUS unary_expression'''
|
||||
p[0] = Prohibit(p[2])
|
||||
|
||||
|
||||
def p_expression_not(p):
|
||||
'''unary_expression : NOT unary_expression'''
|
||||
p[0] = Not(p[2])
|
||||
|
||||
|
||||
def p_expression_unary(p):
|
||||
'''expression : unary_expression'''
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_grouping(p):
|
||||
'unary_expression : LPAREN expression RPAREN'
|
||||
p[0] = Group(p[2]) # Will p_field_search will transform as FieldGroup if necessary
|
||||
|
||||
|
||||
def p_range(p):
|
||||
'''unary_expression : LBRACKET phrase_or_term TO phrase_or_term RBRACKET'''
|
||||
include_low = p[1] == "["
|
||||
include_high = p[5] == "]"
|
||||
p[0] = Range(p[2], p[4], include_low, include_high)
|
||||
|
||||
|
||||
def p_field_search(p):
|
||||
'''unary_expression : TERM COLUMN unary_expression'''
|
||||
if isinstance(p[3], Group):
|
||||
p[3] = group_to_fieldgroup(p[3])
|
||||
# for field name we take p[1].value for it was captured as a word expression
|
||||
p[0] = SearchField(p[1].value, p[3])
|
||||
|
||||
|
||||
def p_quoting(p):
|
||||
'unary_expression : PHRASE'
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_proximity(p):
|
||||
'''unary_expression : PHRASE APPROX'''
|
||||
p[0] = Proximity(p[1], p[2])
|
||||
|
||||
|
||||
def p_boosting(p):
|
||||
'''expression : expression BOOST'''
|
||||
p[0] = Boost(p[1], p[2])
|
||||
|
||||
|
||||
def p_terms(p):
|
||||
'''unary_expression : TERM'''
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
def p_fuzzy(p):
|
||||
'''unary_expression : TERM APPROX'''
|
||||
p[0] = Fuzzy(p[1], p[2])
|
||||
|
||||
|
||||
def p_regex(p):
|
||||
'''unary_expression : REGEX'''
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
# handling a special case, TO is reserved only in range
|
||||
def p_to_as_term(p):
|
||||
'''unary_expression : TO'''
|
||||
p[0] = Word(p[1])
|
||||
|
||||
|
||||
def p_phrase_or_term(p):
|
||||
'''phrase_or_term : TERM
|
||||
| PHRASE'''
|
||||
p[0] = p[1]
|
||||
|
||||
|
||||
# Error rule for syntax errors
|
||||
# TODO : should report better
|
||||
def p_error(p):
|
||||
if p is None:
|
||||
p = "(probably at end of input, may be unmatch parenthesis or so)"
|
||||
raise ParseError(error="Syntax error in input at %r!" % p)
|
||||
|
||||
|
||||
parser = yacc.yacc()
|
||||
"""This is the parser generated by PLY
|
||||
"""
|
370
nexus/meta_api/query_extensionner/grammar/tree.py
Normal file
370
nexus/meta_api/query_extensionner/grammar/tree.py
Normal file
@ -0,0 +1,370 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Elements that will constitute the parse tree of a query.
|
||||
You may use these items to build a tree representing a query,
|
||||
or get a tree as the result of parsing a query string.
|
||||
"""
|
||||
import re
|
||||
from decimal import Decimal
|
||||
|
||||
_MARKER = object()
|
||||
NON_DEFAULT_QUOTES = r''''“”‘«»„`'''
|
||||
QUOTES = NON_DEFAULT_QUOTES + '"'
|
||||
QUOTE_RE = re.compile(f'[{QUOTES}]')
|
||||
NON_DEFAULT_QUOTE_RE = re.compile(f'[{NON_DEFAULT_QUOTES}]')
|
||||
|
||||
|
||||
class Item(object):
|
||||
"""Base class for all items that compose the parse tree.
|
||||
An item is a part of a request.
|
||||
"""
|
||||
|
||||
# /!\ Note on Item (and subclasses) __magic__ methods: /!\
|
||||
#
|
||||
# Since we're dealing with recursive structures, we must avoid using
|
||||
# the builtin helper methods when dealing with nested objects in
|
||||
# __magic__ methods.
|
||||
#
|
||||
# As the helper usually calls the relevant method, we end up with two
|
||||
# function calls instead of one, and end up hitting python's max recursion
|
||||
# limit twice as fast!
|
||||
#
|
||||
# This is why we're calling c.__repr__ instead of repr(c) in the __repr__
|
||||
# method. Same thing applies for all magic methods (__str__, __eq__, and any
|
||||
# other we might add in the future).
|
||||
|
||||
_equality_attrs = []
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
"""As base of a tree structure, an item may have children"""
|
||||
# empty by default
|
||||
return []
|
||||
|
||||
def __repr__(self):
|
||||
children = ", ".join(c.__repr__() for c in self.children)
|
||||
return "%s(%s)" % (self.__class__.__name__, children)
|
||||
|
||||
def __eq__(self, other):
|
||||
"""a basic equal operation
|
||||
"""
|
||||
return (self.__class__ == other.__class__
|
||||
and len(self.children) == len(other.children)
|
||||
and all(
|
||||
getattr(self, a, _MARKER) == getattr(other, a, _MARKER)
|
||||
for a in self._equality_attrs
|
||||
)
|
||||
and all(c.__eq__(d) for c, d in zip(self.children, other.children)))
|
||||
|
||||
|
||||
class SearchField(Item):
|
||||
"""Indicate wich field the search expression operates on
|
||||
eg: *desc* in ``desc:(this OR that)``
|
||||
:param str name: name of the field
|
||||
:param expr: the searched expression
|
||||
"""
|
||||
_equality_attrs = ['name']
|
||||
|
||||
def __init__(self, name, expr):
|
||||
self.name = name
|
||||
self.expr = expr
|
||||
|
||||
def __str__(self):
|
||||
return self.name + ":" + self.expr.__str__()
|
||||
|
||||
def __repr__(self):
|
||||
return "SearchField(%r, %s)" % (self.name, self.expr.__repr__())
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
"""the only child is the expression"""
|
||||
return [self.expr]
|
||||
|
||||
|
||||
class BaseGroup(Item):
|
||||
"""Base class for group of expressions or field values
|
||||
:param expr: the expression inside parenthesis
|
||||
"""
|
||||
def __init__(self, expr):
|
||||
self.expr = expr
|
||||
|
||||
def __str__(self):
|
||||
return "(%s)" % self.expr.__str__()
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
"""the only child is the expression"""
|
||||
return [self.expr]
|
||||
|
||||
|
||||
class Group(BaseGroup):
|
||||
"""Group sub expressions
|
||||
"""
|
||||
|
||||
|
||||
class FieldGroup(BaseGroup):
|
||||
"""Group values for a query on a field
|
||||
"""
|
||||
|
||||
|
||||
def group_to_fieldgroup(g): # FIXME: no use !
|
||||
return FieldGroup(g.expr)
|
||||
|
||||
|
||||
class Range(Item):
|
||||
"""A Range
|
||||
:param low: lower bound
|
||||
:param high: higher bound
|
||||
:param bool include_low: wether lower bound is included
|
||||
:param bool include_high: wether higher bound is included
|
||||
"""
|
||||
|
||||
LOW_CHAR = {True: '[', False: '{'}
|
||||
HIGH_CHAR = {True: ']', False: '}'}
|
||||
|
||||
def __init__(self, low, high, include_low=True, include_high=True):
|
||||
self.low = low
|
||||
self.high = high
|
||||
self.include_low = include_low
|
||||
self.include_high = include_high
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
"""children are lower and higher bound expressions"""
|
||||
return [self.low, self.high]
|
||||
|
||||
def __str__(self):
|
||||
return "%s%s TO %s%s" % (
|
||||
self.LOW_CHAR[self.include_low],
|
||||
self.low.__str__(),
|
||||
self.high.__str__(),
|
||||
self.HIGH_CHAR[self.include_high])
|
||||
|
||||
|
||||
class Term(Item):
|
||||
"""Base for terms
|
||||
:param str value: the value
|
||||
"""
|
||||
WILDCARDS_PATTERN = re.compile(r"((?<=[^\\])[?*]|^[?*])") # non escaped * and ?
|
||||
# see
|
||||
# https://lucene.apache.org/core/3_6_0/queryparsersyntax.html#Escaping%20Special%20Characters
|
||||
WORD_ESCAPED_CHARS = re.compile(r'\\([+\-&|!(){}[\]^"~*?:\\])')
|
||||
|
||||
_equality_attrs = ['value']
|
||||
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
|
||||
@property
|
||||
def unescaped_value(self):
|
||||
# remove '\' that escape characters
|
||||
return self.WORD_ESCAPED_CHARS.sub(r'\1', self.value)
|
||||
|
||||
def is_wildcard(self):
|
||||
""":return bool: True if value is the wildcard ``*``
|
||||
"""
|
||||
return self.value == "*"
|
||||
|
||||
def iter_wildcards(self):
|
||||
"""list wildcards contained in value and their positions
|
||||
"""
|
||||
for matched in self.WILDCARDS_PATTERN.finditer(self.value):
|
||||
yield matched.span(), matched.group()
|
||||
|
||||
def split_wildcards(self):
|
||||
"""split term on wildcards
|
||||
"""
|
||||
return self.WILDCARDS_PATTERN.split(self.value)
|
||||
|
||||
def has_wildcard(self):
|
||||
""":return bool: True if value contains a wildcards
|
||||
"""
|
||||
return any(self.iter_wildcards())
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r)" % (self.__class__.__name__, str(self))
|
||||
|
||||
|
||||
class Word(Term):
|
||||
"""A single word term
|
||||
:param str value: the value
|
||||
"""
|
||||
def __init__(self, value, final=False):
|
||||
super().__init__(value)
|
||||
self.final = final
|
||||
|
||||
|
||||
class Phrase(Term):
|
||||
"""A phrase term, that is a sequence of words enclose in quotes
|
||||
:param str value: the value, including the quotes. Eg. ``'"my phrase"'``
|
||||
"""
|
||||
def __init__(self, value):
|
||||
value = QUOTE_RE.sub('"', value)
|
||||
super(Phrase, self).__init__(value)
|
||||
assert self.value.endswith('"') and self.value.startswith('"'), (
|
||||
"Phrase value must contain the quotes")
|
||||
|
||||
|
||||
class Regex(Term):
|
||||
"""A regex term, that is a sequence of words enclose in slashes
|
||||
:param str value: the value, including the slashes. Eg. ``'/my regex/'``
|
||||
"""
|
||||
def __init__(self, value):
|
||||
super(Regex, self).__init__(value)
|
||||
assert value.endswith('/') and value.startswith('/'), (
|
||||
"Regex value must contain the slashes")
|
||||
|
||||
|
||||
class BaseApprox(Item):
|
||||
"""Base for approximations, that is fuzziness and proximity
|
||||
"""
|
||||
_equality_attrs = ['term', 'degree']
|
||||
|
||||
def __repr__(self): # pragma: no cover
|
||||
return "%s(%s, %s)" % (self.__class__.__name__, self.term.__repr__(), self.degree)
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
return [self.term]
|
||||
|
||||
|
||||
class Fuzzy(BaseApprox):
|
||||
"""Fuzzy search on word
|
||||
:param Word term: the approximated term
|
||||
:param degree: the degree which will be converted to :py:class:`decimal.Decimal`.
|
||||
"""
|
||||
def __init__(self, term, degree=None):
|
||||
self.term = term
|
||||
if degree is None:
|
||||
degree = 0.5
|
||||
self.degree = Decimal(degree).normalize()
|
||||
|
||||
def __str__(self):
|
||||
return "%s~%s" % (self.term, self.degree)
|
||||
|
||||
|
||||
class Proximity(BaseApprox):
|
||||
"""Proximity search on phrase
|
||||
:param Phrase term: the approximated phrase
|
||||
:param degree: the degree which will be converted to :py:func:`int`.
|
||||
"""
|
||||
def __init__(self, term, degree=None):
|
||||
self.term = term
|
||||
if degree is None:
|
||||
degree = 1
|
||||
self.degree = int(degree)
|
||||
|
||||
def __str__(self):
|
||||
return "%s~" % self.term + ("%d" % self.degree if self.degree is not None else "")
|
||||
|
||||
|
||||
class Boost(Item):
|
||||
"""A term for boosting a value or a group there of
|
||||
:param expr: the boosted expression
|
||||
:param force: boosting force, will be converted to :py:class:`decimal.Decimal`
|
||||
"""
|
||||
def __init__(self, expr, force):
|
||||
self.expr = expr
|
||||
if force is None:
|
||||
force = 1.0
|
||||
self.force = Decimal(force).normalize()
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
"""The only child is the boosted expression
|
||||
"""
|
||||
return [self.expr]
|
||||
|
||||
def __str__(self):
|
||||
return "%s^%s" % (self.expr.__str__(), self.force)
|
||||
|
||||
|
||||
class BaseOperation(Item):
|
||||
"""
|
||||
Parent class for binary operations are binary operation used to join expressions,
|
||||
like OR and AND
|
||||
:param operands: expressions to apply operation on
|
||||
"""
|
||||
def __init__(self, *operands):
|
||||
self.operands = operands
|
||||
|
||||
def __str__(self):
|
||||
return (" %s " % self.op).join(str(o) for o in self.operands)
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
"""children are left and right expressions
|
||||
"""
|
||||
return self.operands
|
||||
|
||||
|
||||
class UnknownOperation(BaseOperation):
|
||||
"""Unknown Boolean operator.
|
||||
.. warning::
|
||||
This is used to represent implicit operations (ie: term:foo term:bar),
|
||||
as we cannot know for sure which operator should be used.
|
||||
Lucene seem to use whatever operator was used before reaching that one,
|
||||
defaulting to AND, but we cannot know anything about this at parsing
|
||||
time...
|
||||
.. seealso::
|
||||
the :py:class:`.utils.UnknownOperationResolver` to resolve those nodes to OR and AND
|
||||
"""
|
||||
op = ''
|
||||
|
||||
def __str__(self):
|
||||
return " ".join(str(o) for o in self.operands)
|
||||
|
||||
|
||||
class OrOperation(BaseOperation):
|
||||
"""OR expression
|
||||
"""
|
||||
op = 'OR'
|
||||
|
||||
|
||||
class AndOperation(BaseOperation):
|
||||
"""AND expression
|
||||
"""
|
||||
op = 'AND'
|
||||
|
||||
|
||||
def create_operation(cls, a, b):
|
||||
"""Create operation between a and b, merging if a or b is already an operation of same class
|
||||
"""
|
||||
operands = []
|
||||
operands.extend(a.operands if isinstance(a, cls) else [a])
|
||||
operands.extend(b.operands if isinstance(b, cls) else [b])
|
||||
return cls(*operands)
|
||||
|
||||
|
||||
class Unary(Item):
|
||||
"""Parent class for unary operations
|
||||
:param a: the expression the operator applies on
|
||||
"""
|
||||
|
||||
def __init__(self, a):
|
||||
self.a = a
|
||||
|
||||
def __str__(self):
|
||||
return "%s%s" % (self.op, self.a.__str__())
|
||||
|
||||
@property
|
||||
def children(self):
|
||||
return [self.a]
|
||||
|
||||
|
||||
class Plus(Unary):
|
||||
"""plus, unary operation
|
||||
"""
|
||||
op = "+"
|
||||
|
||||
|
||||
class Not(Unary):
|
||||
op = 'NOT '
|
||||
|
||||
|
||||
class Prohibit(Unary):
|
||||
"""The negation
|
||||
"""
|
||||
op = "-"
|
211
nexus/meta_api/query_extensionner/grammar/tree_transformer.py
Normal file
211
nexus/meta_api/query_extensionner/grammar/tree_transformer.py
Normal file
@ -0,0 +1,211 @@
|
||||
from izihawa_utils.text import camel_to_snake
|
||||
from nexus.nlptools.morph import (
|
||||
EnglishMorphology,
|
||||
RussianMorphology,
|
||||
)
|
||||
|
||||
from .tree import (
|
||||
AndOperation,
|
||||
BaseOperation,
|
||||
Group,
|
||||
OrOperation,
|
||||
Unary,
|
||||
Word,
|
||||
)
|
||||
|
||||
|
||||
class TreeVisitor:
|
||||
visitor_method_prefix = 'visit_'
|
||||
generic_visitor_method_name = 'generic_visit'
|
||||
|
||||
_get_method_cache = None
|
||||
|
||||
def _get_method(self, node):
|
||||
if self._get_method_cache is None:
|
||||
self._get_method_cache = {}
|
||||
try:
|
||||
meth = self._get_method_cache[type(node)]
|
||||
except KeyError:
|
||||
for cls in node.__class__.mro():
|
||||
try:
|
||||
method_name = "{}{}".format(
|
||||
self.visitor_method_prefix,
|
||||
camel_to_snake(cls.__name__)
|
||||
)
|
||||
meth = getattr(self, method_name)
|
||||
break
|
||||
except AttributeError:
|
||||
continue
|
||||
else:
|
||||
meth = getattr(self, self.generic_visitor_method_name)
|
||||
self._get_method_cache[type(node)] = meth
|
||||
return meth
|
||||
|
||||
def visit(self, node, parents=None):
|
||||
""" Basic, recursive traversal of the tree. """
|
||||
parents = parents or []
|
||||
method = self._get_method(node)
|
||||
yield from method(node, parents)
|
||||
for child in node.children:
|
||||
yield from self.visit(child, parents + [node])
|
||||
|
||||
def generic_visit(self, node, parents=None):
|
||||
"""
|
||||
Default visitor function, called if nothing matches the current node.
|
||||
"""
|
||||
return iter([]) # No-op
|
||||
|
||||
|
||||
class TreeTransformer(TreeVisitor):
|
||||
def replace_node(self, old_node, new_node, parent):
|
||||
for k, v in parent.__dict__.items(): # pragma: no branch
|
||||
if v == old_node:
|
||||
parent.__dict__[k] = new_node
|
||||
break
|
||||
elif isinstance(v, list):
|
||||
try:
|
||||
i = v.index(old_node)
|
||||
if new_node is None:
|
||||
del v[i]
|
||||
else:
|
||||
v[i] = new_node
|
||||
break
|
||||
except ValueError:
|
||||
pass # this was not the attribute containing old_node
|
||||
elif isinstance(v, tuple):
|
||||
try:
|
||||
i = v.index(old_node)
|
||||
v = list(v)
|
||||
if new_node is None:
|
||||
del v[i]
|
||||
else:
|
||||
v[i] = new_node
|
||||
parent.__dict__[k] = tuple(v)
|
||||
break
|
||||
except ValueError:
|
||||
pass # this was not the attribute containing old_node
|
||||
|
||||
def generic_visit(self, node, parent=None):
|
||||
return node
|
||||
|
||||
def visit(self, node, parents=None):
|
||||
"""
|
||||
Recursively traverses the tree and replace nodes with the appropriate
|
||||
visitor method's return values.
|
||||
"""
|
||||
parents = parents or []
|
||||
method = self._get_method(node)
|
||||
new_node = method(node, parents)
|
||||
if parents:
|
||||
self.replace_node(node, new_node, parents[-1])
|
||||
node = new_node
|
||||
if node is not None:
|
||||
for child in node.children:
|
||||
self.visit(child, parents + [node])
|
||||
return node
|
||||
|
||||
|
||||
class UnknownOperationResolver(TreeTransformer):
|
||||
VALID_OPERATIONS = frozenset([None, AndOperation, OrOperation])
|
||||
DEFAULT_OPERATION = OrOperation
|
||||
|
||||
def __init__(self, resolve_to=None):
|
||||
if resolve_to not in self.VALID_OPERATIONS:
|
||||
raise ValueError("%r is not a valid value for resolve_to" % resolve_to)
|
||||
self.resolve_to = resolve_to
|
||||
self.last_operation = {}
|
||||
|
||||
def _first_nonop_parent(self, parents):
|
||||
for parent in parents:
|
||||
if not isinstance(parent, BaseOperation):
|
||||
return id(parent) # use id() because parent might not be hashable
|
||||
return None
|
||||
|
||||
def visit_or_operation(self, node, parents=None):
|
||||
if self.resolve_to is None:
|
||||
# memorize last op
|
||||
parent = self._first_nonop_parent(parents)
|
||||
self.last_operation[parent] = OrOperation
|
||||
return node
|
||||
|
||||
def visit_and_operation(self, node, parents=None):
|
||||
if self.resolve_to is None:
|
||||
# memorize last op
|
||||
parent = self._first_nonop_parent(parents)
|
||||
self.last_operation[parent] = AndOperation
|
||||
return node
|
||||
|
||||
def visit_unknown_operation(self, node, parents=None):
|
||||
# resolve
|
||||
if any(map(lambda x: isinstance(x, Unary), node.operands)):
|
||||
operation = AndOperation
|
||||
elif self.resolve_to is not None:
|
||||
operation = self.resolve_to
|
||||
else:
|
||||
parent = self._first_nonop_parent(parents)
|
||||
operation = self.last_operation.get(parent, None)
|
||||
if operation is None:
|
||||
operation = self.DEFAULT_OPERATION
|
||||
return operation(*node.operands)
|
||||
|
||||
|
||||
class FieldResolver(TreeTransformer):
|
||||
FIELD_ALIASES = {
|
||||
'author': 'authors',
|
||||
'isbn': 'isbns',
|
||||
'journal': 'container_title',
|
||||
'lang': 'language',
|
||||
}
|
||||
VALID_FIELDS = frozenset([
|
||||
'id', 'abstract', 'authors', 'container_title',
|
||||
'doi', 'description', 'isbns', 'issued_at', 'language', 'original_id',
|
||||
'references', 'tags', 'title', 'year',
|
||||
])
|
||||
|
||||
def visit_search_field(self, node, parents=None):
|
||||
if node.name in self.FIELD_ALIASES:
|
||||
node.name = self.FIELD_ALIASES[node.name]
|
||||
|
||||
if node.name not in self.VALID_FIELDS:
|
||||
return OrOperation(Word(node.name), node.expr)
|
||||
|
||||
return node
|
||||
|
||||
|
||||
class MorphyResolver(TreeTransformer):
|
||||
morphology = {
|
||||
'ru': RussianMorphology(),
|
||||
'en': EnglishMorphology('en_core_web_sm'),
|
||||
}
|
||||
|
||||
def __init__(self, language, is_morph=False, is_accent=True):
|
||||
super().__init__()
|
||||
self.language = language
|
||||
self.is_morph = is_morph
|
||||
self.is_accent = is_accent
|
||||
|
||||
def has_morphy_condition(self, node):
|
||||
return (
|
||||
(isinstance(node, BaseOperation)
|
||||
and len(node.operands) <= 2
|
||||
and all(map(lambda x: isinstance(x, Word), node.operands)))
|
||||
or isinstance(node, Word)
|
||||
)
|
||||
|
||||
def morph(self, node, parents=None):
|
||||
if self.has_morphy_condition(node):
|
||||
return self.visit(node, parents)
|
||||
return node
|
||||
|
||||
def visit_word(self, node, parents=None):
|
||||
node.value = node.value.lower()
|
||||
if node.final or self.language not in self.morphology:
|
||||
return node
|
||||
if self.is_morph:
|
||||
forms = [Word(w, final=True) for w in self.morphology[self.language].derive_forms(node.value)]
|
||||
return Group(OrOperation(*forms))
|
||||
if self.is_accent:
|
||||
if 'ё' in node.value:
|
||||
forms = [Word(node.value, final=True), Word(node.value.replace('ё', 'е'), final=True)]
|
||||
return Group(OrOperation(*forms))
|
||||
return node
|
12
nexus/meta_api/query_extensionner/tests/BUILD.bazel
Normal file
12
nexus/meta_api/query_extensionner/tests/BUILD.bazel
Normal file
@ -0,0 +1,12 @@
|
||||
load("@pip_modules//:requirements.bzl", "requirement")
|
||||
load("@rules_python//python:defs.bzl", "py_test")
|
||||
|
||||
py_test(
|
||||
name = "tests",
|
||||
srcs = glob(["**/*.py"]),
|
||||
main = "test.py",
|
||||
deps = [
|
||||
"//nexus/meta_api/query_extensionner",
|
||||
requirement("pytest"),
|
||||
],
|
||||
)
|
0
nexus/meta_api/query_extensionner/tests/__init__.py
Normal file
0
nexus/meta_api/query_extensionner/tests/__init__.py
Normal file
7
nexus/meta_api/query_extensionner/tests/test.py
Normal file
7
nexus/meta_api/query_extensionner/tests/test.py
Normal file
@ -0,0 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(pytest.main([os.path.dirname(__file__), '-vvv', '-W', 'ignore::DeprecationWarning']))
|
41
nexus/meta_api/query_extensionner/tests/test_grammar.py
Normal file
41
nexus/meta_api/query_extensionner/tests/test_grammar.py
Normal file
@ -0,0 +1,41 @@
|
||||
from nexus.meta_api.query_extensionner.grammar import (
|
||||
FieldResolver,
|
||||
UnknownOperationResolver,
|
||||
parser,
|
||||
)
|
||||
|
||||
|
||||
def test_parser():
|
||||
assert (
|
||||
str(parser.parse(
|
||||
'(hemoglobin- er OR hemoglobins-a) '
|
||||
'AND -fetal AND (human to monkey - is cool) '
|
||||
'AND year:[1992 to 1994]'
|
||||
)) == '(hemoglobin- er OR hemoglobins-a) AND -fetal AND (human to monkey is cool) AND year:[1992 TO 1994]'
|
||||
)
|
||||
assert (str(parser.parse("bek OR 'kek'")) == 'bek OR "kek"')
|
||||
assert (str(parser.parse("bek OR 'kek")) == 'bek OR kek')
|
||||
assert (str(parser.parse("bek OR a'kek")) == 'bek OR a kek')
|
||||
assert (str(parser.parse("bek' OR 'kek mek'")) == 'bek " OR " kek mek')
|
||||
|
||||
assert (str(parser.parse("field:test")) == 'field:test')
|
||||
assert (str(parser.parse("field: test")) == 'field test')
|
||||
assert (str(parser.parse("field : test")) == 'field test')
|
||||
assert (str(parser.parse("field :test")) == 'field test')
|
||||
|
||||
|
||||
def test_resolvers():
|
||||
def resolver(query):
|
||||
tree = parser.parse(query)
|
||||
return UnknownOperationResolver().visit(FieldResolver().visit(tree))
|
||||
|
||||
assert str(resolver('kek -bek')) == 'kek AND -bek'
|
||||
assert str(resolver("Glass s OR Guide OR to OR Commercial OR Vehicles OR 1989")) == \
|
||||
'Glass OR s OR Guide OR to OR Commercial OR Vehicles OR 1989'
|
||||
assert str(resolver('bek OR kek')) == 'bek OR kek'
|
||||
assert str(resolver('bek kek')) == 'bek OR kek'
|
||||
assert str(resolver('title:(hemoglobin OR -fetal) OR abstract:"alpha-hemoglobin"')) == \
|
||||
'title:(hemoglobin OR -fetal) OR abstract:"alpha-hemoglobin"'
|
||||
# assert str(resolver('lumbar spinal [with]')) == ''
|
||||
# assert str(resolver('lumbar spinal [with consumer]')) == ''
|
||||
# assert str(resolver('lumbar spinal [with consumer summary]')) == ''
|
@ -0,0 +1,70 @@
|
||||
from nexus.meta_api.query_extensionner import ClassicQueryProcessor
|
||||
from nexus.meta_api.query_extensionner.checks import QueryClass
|
||||
|
||||
|
||||
def classic_query_processor(query):
|
||||
result = ClassicQueryProcessor().process(query, 'en')
|
||||
return result['query'], result['class']
|
||||
|
||||
|
||||
def test_doi_query():
|
||||
assert classic_query_processor('10.1001/azeroth1021.azerty') == ('doi:"10.1001/azeroth1021.azerty"', QueryClass.DOI)
|
||||
assert classic_query_processor('https://doi.org/10.1001/azeroth1021.azerty') == (
|
||||
'doi:"10.1001/azeroth1021.azerty"', QueryClass.DOI
|
||||
)
|
||||
assert classic_query_processor('Gimme https://doi.org/10.1001/azeroth1021.azerty please') == (
|
||||
'doi:"10.1001/azeroth1021.azerty"', QueryClass.DOI
|
||||
)
|
||||
assert classic_query_processor('Gimme https://doi.org/10.1001/azeroth1021.azerty not 10.6666/kek please') == (
|
||||
'doi:"10.1001/azeroth1021.azerty"', QueryClass.DOI
|
||||
)
|
||||
assert classic_query_processor('10.1001 / test') == ('doi:"10.1001/test"', QueryClass.DOI)
|
||||
assert classic_query_processor('kek 10.1001 / test') == ('kek OR 10.1001 OR test', QueryClass.Default)
|
||||
|
||||
|
||||
def test_isbn_query():
|
||||
assert classic_query_processor('ISBN: 9784567890123') == ('isbns:9784567890123', QueryClass.ISBN)
|
||||
assert classic_query_processor('ISBN:9784567890123') == ('isbns:9784567890123', QueryClass.ISBN)
|
||||
assert classic_query_processor('ISBN: 978-4567890123') == ('isbns:9784567890123', QueryClass.ISBN)
|
||||
assert classic_query_processor('9784567890123') == ('isbns:9784567890123', QueryClass.ISBN)
|
||||
assert classic_query_processor('978-4567890123') == ('isbns:9784567890123', QueryClass.ISBN)
|
||||
|
||||
|
||||
def test_url():
|
||||
assert classic_query_processor('https://www.google.com/lelkek') == (
|
||||
'https://www.google.com/lelkek',
|
||||
QueryClass.URL,
|
||||
)
|
||||
|
||||
|
||||
def test_default():
|
||||
assert classic_query_processor('“Gay niggas in the space”') == (
|
||||
'"Gay niggas in the space"',
|
||||
QueryClass.Default,
|
||||
)
|
||||
assert classic_query_processor('“Gay niggas” in the space”') == (
|
||||
'"Gay niggas" OR in OR the OR space',
|
||||
QueryClass.Default,
|
||||
)
|
||||
assert classic_query_processor('Search “Gay niggas in the space”') == (
|
||||
'search OR "Gay niggas in the space"',
|
||||
QueryClass.Default,
|
||||
)
|
||||
assert classic_query_processor(
|
||||
'hemoglobin OR blood OR issued_at:978307200^0.65 OR '
|
||||
'issued_at:[1262304000 TO 1577836800]^0.65 '
|
||||
'wrong_field : 123 spaced_1: 123 spaced :2'
|
||||
) == (
|
||||
'hemoglobin OR blood OR issued_at:978307200^0.65 OR '
|
||||
'issued_at:[1262304000 TO 1577836800]^0.65 '
|
||||
'OR wrong_field OR 123 OR spaced_1 OR 123 OR spaced OR 2',
|
||||
QueryClass.Default,
|
||||
)
|
||||
assert classic_query_processor('Gay Niggas: In the Space') == (
|
||||
'gay OR niggas OR in OR the OR space',
|
||||
QueryClass.Default,
|
||||
)
|
||||
assert classic_query_processor("Glass's Guide to Commercial Vehicles 1989") == (
|
||||
'glass OR s OR guide OR to OR commercial OR vehicles OR 1989',
|
||||
QueryClass.Default,
|
||||
)
|
3
nexus/meta_api/rescorers/__init__.py
Normal file
3
nexus/meta_api/rescorers/__init__.py
Normal file
@ -0,0 +1,3 @@
|
||||
from .classic_rescorer import ClassicRescorer
|
||||
|
||||
__all__ = ['ClassicRescorer']
|
11
nexus/meta_api/rescorers/base.py
Normal file
11
nexus/meta_api/rescorers/base.py
Normal file
@ -0,0 +1,11 @@
|
||||
from aiokit import AioThing
|
||||
|
||||
|
||||
class Rescorer(AioThing):
|
||||
def __init__(self, learn_logger=None, executor=None):
|
||||
super().__init__()
|
||||
self.learn_logger = learn_logger
|
||||
self.executor = executor
|
||||
|
||||
async def rescore(self, document_pbs, query, session_id, language):
|
||||
raise NotImplementedError()
|
236
nexus/meta_api/rescorers/classic_rescorer.py
Normal file
236
nexus/meta_api/rescorers/classic_rescorer.py
Normal file
@ -0,0 +1,236 @@
|
||||
import asyncio
|
||||
import base64
|
||||
import datetime
|
||||
import io
|
||||
import time
|
||||
|
||||
import lightgbm as lgbm
|
||||
import numpy as np
|
||||
from nexus.nlptools.language_detect import detect_language
|
||||
|
||||
from .base import Rescorer
|
||||
|
||||
# ToDo: deduplicate code
|
||||
|
||||
|
||||
def convert_scoring_to_vec_current_version(
|
||||
original_score,
|
||||
schema_id,
|
||||
document_age,
|
||||
downloads_count,
|
||||
ref_by_count,
|
||||
same_language,
|
||||
same_query_language,
|
||||
query_tokens_count,
|
||||
query_documents_similarity_vector,
|
||||
):
|
||||
return np.array([
|
||||
original_score,
|
||||
schema_id,
|
||||
document_age,
|
||||
downloads_count,
|
||||
ref_by_count,
|
||||
same_language,
|
||||
same_query_language,
|
||||
query_tokens_count,
|
||||
] + query_documents_similarity_vector)
|
||||
|
||||
|
||||
def convert_scoring_to_vec_future_version(
|
||||
doc_id,
|
||||
original_score,
|
||||
schema_id,
|
||||
document_age,
|
||||
downloads_count,
|
||||
ref_by_count,
|
||||
same_language,
|
||||
same_query_language,
|
||||
query_tokens_count,
|
||||
query_documents_similarity_vector,
|
||||
):
|
||||
return np.array([
|
||||
doc_id,
|
||||
original_score,
|
||||
schema_id,
|
||||
document_age,
|
||||
downloads_count,
|
||||
ref_by_count,
|
||||
same_language,
|
||||
same_query_language,
|
||||
query_tokens_count,
|
||||
] + query_documents_similarity_vector)
|
||||
|
||||
|
||||
def schema_to_id(schema):
|
||||
return 1 if schema == 'scimag' else 2
|
||||
|
||||
|
||||
def query_document_similarity_measures(query_tokens, query_tokens_set, query_tokens_count, document_tokens):
|
||||
max_longest_sequence_not_ordered = 0
|
||||
min_sequence_not_ordered = 1024
|
||||
current_longest_sequence_not_ordered = 0
|
||||
two_grams_not_ordered = 0
|
||||
last_token = -1
|
||||
for token_ix, token in enumerate(document_tokens):
|
||||
if token in query_tokens_set:
|
||||
if last_token != -1:
|
||||
min_sequence_not_ordered = min(min_sequence_not_ordered, token_ix - last_token)
|
||||
if token_ix - last_token == 1:
|
||||
two_grams_not_ordered += 1
|
||||
last_token = token_ix
|
||||
current_longest_sequence_not_ordered += 1
|
||||
else:
|
||||
current_longest_sequence_not_ordered = 0
|
||||
max_longest_sequence_not_ordered = max(
|
||||
max_longest_sequence_not_ordered,
|
||||
current_longest_sequence_not_ordered,
|
||||
)
|
||||
return [
|
||||
max_longest_sequence_not_ordered,
|
||||
min_sequence_not_ordered,
|
||||
two_grams_not_ordered,
|
||||
float(max_longest_sequence_not_ordered) / (float(query_tokens_count) + 1.0),
|
||||
float(two_grams_not_ordered) / (float(query_tokens_count) + 1.0),
|
||||
]
|
||||
|
||||
|
||||
def cast_issued_at(document):
|
||||
if 'issued_at' in document:
|
||||
try:
|
||||
return datetime.date.fromtimestamp(document['issued_at'])
|
||||
except ValueError:
|
||||
return datetime.date(2000, 1, 1)
|
||||
else:
|
||||
return datetime.date(2000, 1, 1)
|
||||
|
||||
|
||||
def calculate_title_tokens(document):
|
||||
# ToDo: should we add tags?
|
||||
title_tokens = list(document.get('authors', []))
|
||||
if document.get('title'):
|
||||
title_tokens.append(document['title'])
|
||||
return (' '.join(title_tokens)).lower().split()
|
||||
|
||||
|
||||
class ClassicRescorer(Rescorer):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.lgbm_ranker = lgbm.Booster(model_file='nexus/meta_api/models/classic.txt')
|
||||
|
||||
def write_to_log_future_version(self, session_id, scored_documents, query, now, language):
|
||||
future_scoring_vecs = []
|
||||
|
||||
query_language = detect_language(query)
|
||||
query_tokens_count = query.count(' ')
|
||||
query_tokens = query.lower().strip('"\'”`').split()
|
||||
query_tokens_set = set(query_tokens)
|
||||
|
||||
for scored_document in scored_documents:
|
||||
document = scored_document['document']
|
||||
original_id = document.get('original_id') or document['id']
|
||||
|
||||
title_tokens = calculate_title_tokens(document)
|
||||
|
||||
query_documents_similarity_vector = query_document_similarity_measures(
|
||||
query_tokens,
|
||||
query_tokens_set,
|
||||
query_tokens_count,
|
||||
title_tokens,
|
||||
)
|
||||
future_scoring_vecs.append(convert_scoring_to_vec_future_version(
|
||||
doc_id=original_id,
|
||||
original_score=scored_document['score'],
|
||||
schema_id=schema_to_id(scored_document['schema']),
|
||||
document_age=(now - cast_issued_at(document)).total_seconds(),
|
||||
downloads_count=scored_document['document'].get('downloads_count', 0),
|
||||
ref_by_count=document.get('ref_by_count', 0),
|
||||
same_language=int(language == document.get('language')),
|
||||
same_query_language=int(query_language == document.get('language')),
|
||||
query_tokens_count=query_tokens_count,
|
||||
query_documents_similarity_vector=query_documents_similarity_vector
|
||||
))
|
||||
|
||||
data = io.BytesIO()
|
||||
np.savez_compressed(data, future_scoring_vecs, allow_pickle=True)
|
||||
data = base64.b64encode(data.getvalue()).decode()
|
||||
|
||||
log_entry = {
|
||||
'action': 'search',
|
||||
'scorings': data,
|
||||
'session_id': session_id,
|
||||
'unixtime': time.time(),
|
||||
'version': 4,
|
||||
'vertical': 'classic',
|
||||
}
|
||||
|
||||
self.learn_logger.info(log_entry)
|
||||
|
||||
def _rescore(self, session_id, scored_documents, query, now, language):
|
||||
current_scoring_vecs = []
|
||||
|
||||
query_language = detect_language(query)
|
||||
query_tokens_count = query.count(' ')
|
||||
query_tokens = query.lower().strip('"\'”`').split()
|
||||
query_tokens_set = set(query_tokens)
|
||||
|
||||
for scored_document in scored_documents:
|
||||
# ToDo: Use shared wrappers
|
||||
document = scored_document['document']
|
||||
|
||||
title_tokens = calculate_title_tokens(document)
|
||||
query_documents_similarity_vector = query_document_similarity_measures(
|
||||
query_tokens,
|
||||
query_tokens_set,
|
||||
query_tokens_count,
|
||||
title_tokens,
|
||||
)
|
||||
current_scoring_vecs.append(convert_scoring_to_vec_current_version(
|
||||
original_score=scored_document['score'],
|
||||
schema_id=schema_to_id(scored_document['schema']),
|
||||
document_age=(now - cast_issued_at(document)).total_seconds(),
|
||||
downloads_count=scored_document['document'].get('downloads_count', 0),
|
||||
ref_by_count=document.get('ref_by_count', 0),
|
||||
same_language=int(language == document.get('language')),
|
||||
same_query_language=int(query_language == document.get('language')),
|
||||
query_tokens_count=query_tokens_count,
|
||||
query_documents_similarity_vector=query_documents_similarity_vector,
|
||||
))
|
||||
|
||||
scores = self.lgbm_ranker.predict(current_scoring_vecs)
|
||||
for score, scored_document in zip(scores, scored_documents):
|
||||
scored_document['score'] = score
|
||||
|
||||
scored_documents = sorted(scored_documents, key=lambda x: x['score'], reverse=True)
|
||||
for position, scored_document in enumerate(scored_documents):
|
||||
scored_document['position'] = position
|
||||
return scored_documents
|
||||
|
||||
async def rescore(self, scored_documents, query, session_id, language):
|
||||
if not scored_documents:
|
||||
return scored_documents
|
||||
|
||||
now = datetime.date.today()
|
||||
|
||||
if self.learn_logger:
|
||||
# Needed due to bug in uvloop
|
||||
async def nested():
|
||||
await asyncio.get_running_loop().run_in_executor(
|
||||
self.executor,
|
||||
self.write_to_log_future_version,
|
||||
session_id,
|
||||
scored_documents,
|
||||
query,
|
||||
now,
|
||||
language,
|
||||
)
|
||||
asyncio.create_task(nested())
|
||||
|
||||
return await asyncio.get_running_loop().run_in_executor(
|
||||
self.executor,
|
||||
self._rescore,
|
||||
session_id,
|
||||
scored_documents,
|
||||
query,
|
||||
now,
|
||||
language,
|
||||
)
|
15
nexus/meta_api/services/base.py
Normal file
15
nexus/meta_api/services/base.py
Normal file
@ -0,0 +1,15 @@
|
||||
from aiosumma.exceptions import (
|
||||
InvalidSyntaxError,
|
||||
QueryTimeoutError,
|
||||
)
|
||||
from grpc import StatusCode
|
||||
from library.aiogrpctools.base import BaseService as LibraryBaseService
|
||||
from nexus.meta_api.query_extensionner.grammar.parser import ParseError
|
||||
|
||||
|
||||
class BaseService(LibraryBaseService):
|
||||
error_mapping = {
|
||||
InvalidSyntaxError: (StatusCode.INVALID_ARGUMENT, 'invalid_query_error'),
|
||||
ParseError: (StatusCode.INVALID_ARGUMENT, 'invalid_query_error'),
|
||||
QueryTimeoutError: (StatusCode.CANCELLED, 'cancelled_error'),
|
||||
}
|
163
nexus/meta_api/services/documents.py
Normal file
163
nexus/meta_api/services/documents.py
Normal file
@ -0,0 +1,163 @@
|
||||
import logging
|
||||
import time
|
||||
|
||||
from grpc import StatusCode
|
||||
from library.aiogrpctools.base import aiogrpc_request_wrapper
|
||||
from nexus.meta_api.proto.documents_service_pb2 import \
|
||||
GetViewResponse as GetViewResponsePb
|
||||
from nexus.meta_api.proto.documents_service_pb2 import \
|
||||
RollResponse as RollResponsePb
|
||||
from nexus.meta_api.proto.documents_service_pb2 import \
|
||||
TopMissedResponse as TopMissedResponsePb
|
||||
from nexus.meta_api.proto.documents_service_pb2_grpc import (
|
||||
DocumentsServicer,
|
||||
add_DocumentsServicer_to_server,
|
||||
)
|
||||
from nexus.models.proto.scimag_pb2 import Scimag as ScimagPb
|
||||
from nexus.models.proto.typed_document_pb2 import \
|
||||
TypedDocument as TypedDocumentPb
|
||||
from nexus.views.telegram import parse_typed_document_to_view
|
||||
from nexus.views.telegram.registry import pb_registry
|
||||
|
||||
from .base import BaseService
|
||||
|
||||
|
||||
class DocumentsService(DocumentsServicer, BaseService):
|
||||
def __init__(self, server, summa_client, data_provider, stat_provider, learn_logger=None):
|
||||
super().__init__(service_name='meta_api')
|
||||
self.server = server
|
||||
self.summa_client = summa_client
|
||||
self.stat_provider = stat_provider
|
||||
self.data_provider = data_provider
|
||||
self.learn_logger = learn_logger
|
||||
|
||||
async def get_document(self, schema, document_id, request_id, context):
|
||||
search_response = await self.summa_client.search(
|
||||
schema=schema,
|
||||
query=f'id:{document_id}',
|
||||
page=0,
|
||||
page_size=1,
|
||||
request_id=request_id,
|
||||
)
|
||||
|
||||
if len(search_response['scored_documents']) == 0:
|
||||
await context.abort(StatusCode.NOT_FOUND, 'not_found')
|
||||
|
||||
return search_response['scored_documents'][0]['document']
|
||||
|
||||
def copy_document(self, source, target):
|
||||
for key in source:
|
||||
target[key] = source[key]
|
||||
|
||||
async def start(self):
|
||||
add_DocumentsServicer_to_server(self, self.server)
|
||||
|
||||
async def _get_typed_document(self, request, context, metadata):
|
||||
document = await self.get_document(request.schema, request.document_id, metadata['request-id'], context)
|
||||
if document.get('original_id'):
|
||||
original_document = await self.get_document(
|
||||
request.schema,
|
||||
document['original_id'],
|
||||
metadata['request-id'],
|
||||
context,
|
||||
)
|
||||
for to_remove in ('doi', 'fiction_id', 'filesize', 'libgen_id', 'telegram_file_id',):
|
||||
original_document.pop(to_remove, None)
|
||||
document = {**original_document, **document}
|
||||
|
||||
document_data = await self.data_provider.get(request.document_id)
|
||||
download_stats = self.stat_provider.get_download_stats(request.document_id)
|
||||
|
||||
if self.learn_logger:
|
||||
self.learn_logger.info({
|
||||
'action': 'get',
|
||||
'session_id': request.session_id,
|
||||
'unixtime': time.time(),
|
||||
'schema': request.schema,
|
||||
'document_id': document['id'],
|
||||
})
|
||||
|
||||
logging.getLogger('query').info({
|
||||
'action': 'get',
|
||||
'cache_hit': False,
|
||||
'id': document['id'],
|
||||
'mode': 'get',
|
||||
'position': request.position,
|
||||
'request_id': metadata['request-id'],
|
||||
'schema': request.schema,
|
||||
'session_id': request.session_id,
|
||||
'user_id': request.user_id,
|
||||
})
|
||||
|
||||
document_pb = pb_registry[request.schema](**document)
|
||||
if document_data:
|
||||
document_pb.telegram_file_id = document_data.telegram_file_id
|
||||
del document_pb.ipfs_multihashes[:]
|
||||
document_pb.ipfs_multihashes.extend(document_data.ipfs_multihashes)
|
||||
if download_stats and download_stats.downloads_count:
|
||||
document_pb.downloads_count = download_stats.downloads_count
|
||||
|
||||
return TypedDocumentPb(
|
||||
**{request.schema: document_pb},
|
||||
)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def get(self, request, context, metadata) -> TypedDocumentPb:
|
||||
return await self._get_typed_document(request, context, metadata)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def get_view(self, request, context, metadata) -> GetViewResponsePb:
|
||||
typed_document = await self._get_typed_document(request, context, metadata)
|
||||
view = parse_typed_document_to_view(typed_document)
|
||||
|
||||
return GetViewResponsePb(
|
||||
typed_document=typed_document,
|
||||
filedata=view.get_formatted_filedata(show_filesize=True),
|
||||
filename=view.get_filename(),
|
||||
filesize=view.get_formatted_filesize(),
|
||||
first_authors=view.get_first_authors(),
|
||||
locator=view.get_formatted_locator(),
|
||||
)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def roll(self, request, context, metadata):
|
||||
random_id = await self.data_provider.random_id(request.language)
|
||||
|
||||
logging.getLogger('query').info({
|
||||
'action': 'roll',
|
||||
'cache_hit': False,
|
||||
'id': random_id,
|
||||
'mode': 'roll',
|
||||
'request_id': metadata['request-id'],
|
||||
'session_id': request.session_id,
|
||||
'user_id': request.user_id,
|
||||
})
|
||||
|
||||
return RollResponsePb(document_id=random_id)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def top_missed(self, request, context, metadata):
|
||||
document_ids = self.stat_provider.get_top_missed_stats()
|
||||
offset = request.page * request.page_size
|
||||
limit = request.page_size
|
||||
document_ids = document_ids[offset:offset + limit]
|
||||
document_ids = map(lambda document_id: f'id:{document_id}', document_ids)
|
||||
document_ids = ' OR '.join(document_ids)
|
||||
|
||||
search_response = await self.summa_client.search(
|
||||
schema='scimag',
|
||||
query=document_ids,
|
||||
page=0,
|
||||
page_size=limit,
|
||||
request_id=metadata['request-id'],
|
||||
)
|
||||
|
||||
if len(search_response['scored_documents']) == 0:
|
||||
await context.abort(StatusCode.NOT_FOUND, 'not_found')
|
||||
|
||||
documents = list(map(
|
||||
lambda document: TypedDocumentPb(scimag=ScimagPb(**document['document'])),
|
||||
search_response['scored_documents'],
|
||||
))
|
||||
|
||||
return TopMissedResponsePb(typed_documents=documents)
|
235
nexus/meta_api/services/search.py
Normal file
235
nexus/meta_api/services/search.py
Normal file
@ -0,0 +1,235 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from contextlib import suppress
|
||||
from timeit import default_timer
|
||||
|
||||
from aiokit import AioThing
|
||||
from cachetools import TTLCache
|
||||
from google.protobuf.json_format import MessageToDict
|
||||
from grpc import StatusCode
|
||||
from izihawa_utils.exceptions import NeedRetryError
|
||||
from izihawa_utils.text import camel_to_snake
|
||||
from library.aiogrpctools.base import aiogrpc_request_wrapper
|
||||
from nexus.meta_api.proto.search_service_pb2 import \
|
||||
ScoredDocument as ScoredDocumentPb
|
||||
from nexus.meta_api.proto.search_service_pb2 import \
|
||||
SearchResponse as SearchResponsePb
|
||||
from nexus.meta_api.proto.search_service_pb2_grpc import (
|
||||
SearchServicer,
|
||||
add_SearchServicer_to_server,
|
||||
)
|
||||
from nexus.meta_api.query_extensionner import (
|
||||
ClassicQueryProcessor,
|
||||
QueryClass,
|
||||
)
|
||||
from nexus.meta_api.rescorers import ClassicRescorer
|
||||
from nexus.models.proto.operation_pb2 import \
|
||||
DocumentOperation as DocumentOperationPb
|
||||
from nexus.models.proto.operation_pb2 import UpdateDocument as UpdateDocumentPb
|
||||
from nexus.models.proto.scimag_pb2 import Scimag as ScimagPb
|
||||
from nexus.models.proto.typed_document_pb2 import \
|
||||
TypedDocument as TypedDocumentPb
|
||||
from nexus.nlptools.utils import despace_full
|
||||
from nexus.views.telegram.registry import pb_registry
|
||||
from tenacity import (
|
||||
AsyncRetrying,
|
||||
RetryError,
|
||||
retry_if_exception_type,
|
||||
stop_after_attempt,
|
||||
wait_fixed,
|
||||
)
|
||||
|
||||
from .base import BaseService
|
||||
|
||||
|
||||
class Searcher(BaseService):
|
||||
page_sizes = {
|
||||
'scimag': 100,
|
||||
'scitech': 100,
|
||||
}
|
||||
|
||||
def __init__(self, summa_client, query_processor, rescorer, stat_provider):
|
||||
super().__init__(service_name='meta_api')
|
||||
self.summa_client = summa_client
|
||||
|
||||
self.operation_logger = logging.getLogger('operation')
|
||||
self.class_name = camel_to_snake(self.__class__.__name__)
|
||||
|
||||
self.query_cache = TTLCache(maxsize=1024 * 4, ttl=300)
|
||||
self.query_processor = query_processor
|
||||
self.rescorer = rescorer
|
||||
self.stat_provider = stat_provider
|
||||
|
||||
async def processed_response_hook(self, processor_response, context):
|
||||
return processor_response
|
||||
|
||||
async def post_search_hook(self, search_response, processor_response, request, context,
|
||||
metadata, retry_state):
|
||||
return search_response
|
||||
|
||||
def merge_search_responses(self, search_responses):
|
||||
if not search_responses:
|
||||
return
|
||||
elif len(search_responses) == 1:
|
||||
return search_responses[0]
|
||||
return dict(
|
||||
scored_documents=[
|
||||
scored_document
|
||||
for search_response in search_responses
|
||||
for scored_document in search_response['scored_documents']
|
||||
],
|
||||
has_next=any([search_response['has_next'] for search_response in search_responses]),
|
||||
)
|
||||
|
||||
def cast_search_response(self, search_response):
|
||||
scored_documents_pb = []
|
||||
for scored_document in search_response['scored_documents']:
|
||||
document_pb = pb_registry[scored_document['schema']](**scored_document['document'])
|
||||
scored_documents_pb.append(ScoredDocumentPb(
|
||||
position=scored_document['position'],
|
||||
score=scored_document['score'],
|
||||
typed_document=TypedDocumentPb(
|
||||
**{scored_document['schema']: document_pb},
|
||||
)
|
||||
))
|
||||
return SearchResponsePb(
|
||||
scored_documents=scored_documents_pb,
|
||||
has_next=search_response['has_next'],
|
||||
)
|
||||
|
||||
@aiogrpc_request_wrapper()
|
||||
async def search(self, request, context, metadata):
|
||||
start = default_timer()
|
||||
processor_response = None
|
||||
cache_hit = True
|
||||
page_size = request.page_size or 5
|
||||
|
||||
if (
|
||||
(request.user_id, request.language, request.query) not in self.query_cache
|
||||
or len(self.query_cache[(request.user_id, request.language, request.query)].scored_documents) == 0
|
||||
):
|
||||
cache_hit = False
|
||||
query = despace_full(request.query)
|
||||
processor_response = self.query_processor.process(query, request.language)
|
||||
processor_response = await self.processed_response_hook(processor_response, context)
|
||||
|
||||
with suppress(RetryError):
|
||||
async for attempt in AsyncRetrying(
|
||||
retry=retry_if_exception_type(NeedRetryError),
|
||||
wait=wait_fixed(10),
|
||||
stop=stop_after_attempt(3)
|
||||
):
|
||||
with attempt:
|
||||
requests = []
|
||||
for schema in request.schemas:
|
||||
requests.append(
|
||||
self.summa_client.search(
|
||||
schema=schema,
|
||||
query=processor_response['query'],
|
||||
page=0,
|
||||
page_size=self.page_sizes[schema],
|
||||
request_id=metadata['request-id'],
|
||||
)
|
||||
)
|
||||
search_response = self.merge_search_responses(await asyncio.gather(*requests))
|
||||
search_response = await self.post_search_hook(
|
||||
search_response,
|
||||
processor_response=processor_response,
|
||||
request=request,
|
||||
context=context,
|
||||
metadata=metadata,
|
||||
retry_state=attempt.retry_state
|
||||
)
|
||||
|
||||
rescored_documents = await self.rescorer.rescore(
|
||||
scored_documents=search_response['scored_documents'],
|
||||
query=query,
|
||||
session_id=request.session_id,
|
||||
language=request.language,
|
||||
)
|
||||
search_response['scored_documents'] = rescored_documents
|
||||
search_response_pb = self.cast_search_response(search_response)
|
||||
self.query_cache[(request.user_id, request.language, request.query)] = search_response_pb
|
||||
|
||||
logging.getLogger('query').info({
|
||||
'action': 'request',
|
||||
'cache_hit': cache_hit,
|
||||
'duration': default_timer() - start,
|
||||
'mode': 'search',
|
||||
'page': request.page,
|
||||
'page_size': page_size,
|
||||
'processed_query': processor_response['query'] if processor_response else None,
|
||||
'query': request.query,
|
||||
'query_class': processor_response['class'].value if processor_response else None,
|
||||
'request_id': metadata['request-id'],
|
||||
'schemas': [schema for schema in request.schemas],
|
||||
'session_id': request.session_id,
|
||||
'user_id': request.user_id,
|
||||
})
|
||||
|
||||
scored_documents = self.query_cache[(request.user_id, request.language, request.query)].scored_documents
|
||||
left_offset = request.page * page_size
|
||||
right_offset = left_offset + page_size
|
||||
has_next = len(scored_documents) > right_offset
|
||||
|
||||
search_response_pb = SearchResponsePb(
|
||||
scored_documents=scored_documents[left_offset:right_offset],
|
||||
has_next=has_next,
|
||||
)
|
||||
|
||||
return search_response_pb
|
||||
|
||||
|
||||
class ClassicSearcher(Searcher):
|
||||
async def processed_response_hook(self, processor_response, context):
|
||||
if processor_response['class'] == QueryClass.URL:
|
||||
await context.abort(StatusCode.INVALID_ARGUMENT, 'url_query_error')
|
||||
return processor_response
|
||||
|
||||
async def post_search_hook(self, search_response, processor_response, request, context, metadata,
|
||||
retry_state):
|
||||
if len(search_response['scored_documents']) == 0 and processor_response['class'] == QueryClass.DOI:
|
||||
if retry_state.attempt_number == 1:
|
||||
await self.request_doi_delivery(doi=processor_response['doi'])
|
||||
raise NeedRetryError()
|
||||
for scored_document in search_response['scored_documents']:
|
||||
original_id = (
|
||||
scored_document['document'].get('original_id')
|
||||
or scored_document['document']['id']
|
||||
)
|
||||
download_stats = self.stat_provider.get_download_stats(original_id)
|
||||
if download_stats and download_stats.downloads_count:
|
||||
scored_document['document']['downloads_count'] = download_stats.downloads_count
|
||||
return search_response
|
||||
|
||||
async def request_doi_delivery(self, doi):
|
||||
document_operation = DocumentOperationPb(
|
||||
update_document=UpdateDocumentPb(
|
||||
commit=True,
|
||||
reindex=True,
|
||||
should_fill_from_external_source=True,
|
||||
typed_document=TypedDocumentPb(scimag=ScimagPb(doi=doi)),
|
||||
),
|
||||
)
|
||||
self.operation_logger.info(MessageToDict(document_operation))
|
||||
|
||||
|
||||
class SearchService(SearchServicer, AioThing):
|
||||
def __init__(self, server, summa_client, stat_provider, learn_logger=None):
|
||||
super().__init__()
|
||||
self.server = server
|
||||
self.searcher = ClassicSearcher(
|
||||
summa_client=summa_client,
|
||||
query_processor=ClassicQueryProcessor(),
|
||||
rescorer=ClassicRescorer(
|
||||
learn_logger=learn_logger,
|
||||
),
|
||||
stat_provider=stat_provider,
|
||||
)
|
||||
self.starts.append(self.searcher)
|
||||
|
||||
async def start(self):
|
||||
add_SearchServicer_to_server(self, self.server)
|
||||
|
||||
async def search(self, request, context):
|
||||
return await self.searcher.search(request, context)
|
@ -1,6 +1,7 @@
|
||||
load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_proto_library")
|
||||
load("@rules_rust//proto:proto.bzl", "rust_proto_library")
|
||||
load("@rules_proto//proto:defs.bzl", "proto_library")
|
||||
load("@rules_proto_grpc//js:defs.bzl", "js_proto_library")
|
||||
|
||||
proto_library(
|
||||
name = "models_proto",
|
||||
@ -22,3 +23,10 @@ rust_proto_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [":models_proto"],
|
||||
)
|
||||
|
||||
js_proto_library(
|
||||
name = "models_proto_js",
|
||||
prefix_path = "../../../../",
|
||||
protos = [":models_proto"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
@ -158,8 +158,8 @@ en:
|
||||
TRANSMITTED_FROM: 'transmitted from {source}'
|
||||
UNAVAILABLE_METADATA_ERROR: 'Cannot acquire metadata for {doi} from CrossRef API. Ensure it is resolvable before uploading.'
|
||||
UNKNOWN_FILE_FORMAT_ERROR: Only PDF files are supported
|
||||
UNPARSABLE_DOCUMENT_ERROR: Cannot parse the document
|
||||
UNPARSABLE_DOI_ERROR: DOI cannot be found in the document
|
||||
UNPARSABLE_DOCUMENT_ERROR: Cannot parse `{filename}`
|
||||
UNPARSABLE_DOI_ERROR: DOI cannot be found in `{filename}`
|
||||
UPGRADE_MAINTENANCE: |
|
||||
```Major update is going on, come back to us tomorrow```[]({upgrade_maintenance_picture_url})
|
||||
UPLOADED_TO_TELEGRAM: uploaded to Telegram...
|
||||
|
@ -0,0 +1,5 @@
|
||||
# Welcome, stranger
|
||||
|
||||
I dedicate this work to those who are hunger to learn, help and serve to greater ideas than they are themselves.
|
||||
To those who really keeps the world from falling into the abyss of ignorance.
|
||||
Scholars, doctors, engineers, developers - every file in the repository belongs to you.
|
@ -0,0 +1,11 @@
|
||||
# Agenda
|
||||
|
||||
## Accessibility of Science
|
||||
|
||||
## Observability of Science
|
||||
|
||||
## Integrity Map of the Internet
|
||||
|
||||
## Automated Science
|
||||
|
||||
## Technology Alliance
|
26
papers-please/98-new-conditions.md
Normal file
26
papers-please/98-new-conditions.md
Normal file
@ -0,0 +1,26 @@
|
||||
# New Conditions
|
||||
|
||||
We have silently crossed Rubicon. The Internet entered in our life and now it has become an integral and essential part of our lives.
|
||||
It multiplied our powers and also it multiplied dangers we are put under.
|
||||
|
||||
## Technological Leviathan
|
||||
|
||||
Starting from 2010s there are rising tensions on the digital frontiers. The Internet that has been created to unite people across the world now is dissipating into divided islands. Rules of these dissected pieces are dictated by those who is hunger to manage and control for the sake of their own stability but oftenly not for the sake of who are hunger to learn and move humankind forward.
|
||||
|
||||
Here just a few attacks on freedom to mention:
|
||||
- Great Firewall of China that is banning the entire country out of presence in the world
|
||||
- US Corporations that taking responsibility of judging what is good and evil using full power of their technologies and de-facto applying laws of USA extraterritorially
|
||||
- Russia that is moving rapidly on the Chinese path in her attempts to border Internet traffic. The ultimate goal is spreading lies and propaganda inside and to outside to keep people ignorant.
|
||||
|
||||
Many moves that governments make means that we are considered not sane enough to live in the digital world of information.
|
||||
|
||||
Is this a fate we are destined to live with?
|
||||
|
||||
There is a plenty of projects that are in need of your time or donation support to keep fighting against digital borders:
|
||||
|
||||
- [Library Genesis](https://libgen.fun) [[1]](http://libgen.rs) [[2]](https://t.me/libgen_scihub_bot) - the biggest scientific library in the world
|
||||
- [Sci-Hub](https://sci-hub.do) [[1]](https://t.me/libgen_scihub_bot) - project aimed to make scientific knowledge accessible for everybody
|
||||
- [IPFS](https://ipfs.io) - user-friendly replacement for torrent technology allowing you to exchange files without possibility for copyretards to ban exchange
|
||||
- [TOR](https://www.torproject.org) / [I2P](https://geti2p.net) - tools for improving your anonymity in the Internet by hiding your IPs and other traits that could deanonymize you
|
||||
- [Yggdrasil](https://yggdrasil-network.github.io) / [Cjdns](https://github.com/cjdelisle/cjdns) - tools for allowing you to route your Internet packages without relying on centralized state-controlled equipment. It could be useful to encounter Internet connectivity disruptions arranged by governments. It also allowes you to create mesh networks with your neighbors for keeping high connectivity. It would be useful in densely populated areas or even during peaceful demonstrations.
|
||||
- Our own [Nexus](https://github.com/nexus-stc/hyperboria) that is aimed to store important data and make them searchable.
|
36
repository/install-packages.sh
Executable file
36
repository/install-packages.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
ROOT_DIR="$(dirname "$(dirname $SCRIPT_DIR)")"
|
||||
|
||||
if [[ "$OSTYPE" == "linux-gnu" ]]; then
|
||||
apt install curl gnupg
|
||||
curl -fsSL https://bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg
|
||||
mv bazel.gpg /etc/apt/trusted.gpg.d/
|
||||
echo "deb [arch=amd64] https://storage.googleapis.com/bazel-apt stable jdk1.8" | tee /etc/apt/sources.list.d/bazel.list
|
||||
apt-get update
|
||||
apt-get -y install bazel llvm make openjdk-8-jdk python3.9 python3.9-venv python3.9-dev python-dev \
|
||||
libsqlite3-dev nodejs libev-dev libev-perl python3-distutils yarn
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
required_packages='bazel coreutils ibazel libev libomp llvm protobuf python3.9 sqlite3'
|
||||
brew tap bazelbuild/tap
|
||||
for required_package in $required_packages; do
|
||||
if brew ls --versions $required_package > /dev/null; then
|
||||
brew upgrade $required_package
|
||||
else
|
||||
brew install $required_package
|
||||
fi
|
||||
done
|
||||
elif [[ "$OSTYPE" == "cygwin" ]]; then
|
||||
exit 1;
|
||||
elif [[ "$OSTYPE" == "msys" ]]; then
|
||||
exit 1;
|
||||
elif [[ "$OSTYPE" == "win32" ]]; then
|
||||
exit 1;
|
||||
elif [[ "$OSTYPE" == "freebsd"* ]]; then
|
||||
exit 1;
|
||||
else
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
echo "Successfully installed packages"
|
@ -33,6 +33,7 @@
|
||||
"google-protobuf": "^3.15.8",
|
||||
"grpc": "^1.24.6",
|
||||
"grpc-tools": "^1.11.1",
|
||||
"grpc-web": "^1.2.1",
|
||||
"html-entities": "^2.3.2",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"js-cookie": "^2.2.1",
|
||||
@ -46,7 +47,7 @@
|
||||
"pug-plain-loader": "^1.1.0",
|
||||
"sass": "^1.32.4",
|
||||
"sass-lint": "^1.13.1",
|
||||
"sass-loader": "^11.0.1",
|
||||
"sass-loader": "^10.1.1",
|
||||
"sockjs-client": "^1.5.0",
|
||||
"tempusdominus-bootstrap-4": "^5.39.0",
|
||||
"ts-protoc-gen": "^0.14.0",
|
||||
@ -63,7 +64,7 @@
|
||||
"vue-template-compiler": "^2.6.12",
|
||||
"vuejs-dialog": "^1.4.2",
|
||||
"vuex-persistedstate": "^4.0.0-beta.3",
|
||||
"webpack": "^5.33.2",
|
||||
"webpack": "^4.46.0",
|
||||
"webpack-cli": "^4.3.1",
|
||||
"webpack-dev-server": "^3.11.1",
|
||||
"wordwrap": "^1.0.0"
|
||||
|
@ -884,9 +884,9 @@
|
||||
integrity sha512-BTmtvJbeeEVrqRApI1gr5hvPgYcHLpdGJ5EXNXEWO692ztMPSj5fB/dH0xUlaW45jn6LimYx8ymqTMhj3538og==
|
||||
|
||||
"@bazel/ibazel@latest":
|
||||
version "0.15.9"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/ibazel/-/ibazel-0.15.9.tgz#db9dea1831a789bd87b12a2c72b1f5d8dd4853f0"
|
||||
integrity sha512-37r6bs47UNYcp3jrgXqq//GmX1GJtDPQTok4EZQq/ZMEemvh2S7m1fqe1NjNp0D6LdivUmF4z8wb3LjVaT97cg==
|
||||
version "0.15.10"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/ibazel/-/ibazel-0.15.10.tgz#cf0cff1aec6d8e7bb23e1fc618d09fbd39b7a13f"
|
||||
integrity sha512-0v+OwCQ6fsGFa50r6MXWbUkSGuWOoZ22K4pMSdtWiL5LKFIE4kfmMmtQS+M7/ICNwk2EIYob+NRreyi/DGUz5A==
|
||||
|
||||
"@csstools/convert-colors@^1.4.0":
|
||||
version "1.4.0"
|
||||
@ -1324,32 +1324,6 @@
|
||||
"@types/long" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/eslint-scope@^3.7.0":
|
||||
version "3.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86"
|
||||
integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==
|
||||
dependencies:
|
||||
"@types/eslint" "*"
|
||||
"@types/estree" "*"
|
||||
|
||||
"@types/eslint@*":
|
||||
version "7.2.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.10.tgz#4b7a9368d46c0f8cd5408c23288a59aa2394d917"
|
||||
integrity sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ==
|
||||
dependencies:
|
||||
"@types/estree" "*"
|
||||
"@types/json-schema" "*"
|
||||
|
||||
"@types/estree@*":
|
||||
version "0.0.47"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4"
|
||||
integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==
|
||||
|
||||
"@types/estree@^0.0.46":
|
||||
version "0.0.46"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe"
|
||||
integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==
|
||||
|
||||
"@types/glob@^7.1.1":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
|
||||
@ -1370,7 +1344,7 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
|
||||
"@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
|
||||
version "7.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
|
||||
integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
|
||||
@ -1391,9 +1365,9 @@
|
||||
integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==
|
||||
|
||||
"@types/node@*", "@types/node@>=12.12.47":
|
||||
version "14.14.39"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.39.tgz#9ef394d4eb52953d2890e4839393c309aa25d2d1"
|
||||
integrity sha512-Qipn7rfTxGEDqZiezH+wxqWYR8vcXq5LRpZrETD19Gs4o8LbklbmqotSUsMU+s5G3PJwMRDfNEYoxrcBwIxOuw==
|
||||
version "14.14.41"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615"
|
||||
integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g==
|
||||
|
||||
"@types/q@^1.5.1":
|
||||
version "1.5.4"
|
||||
@ -1534,14 +1508,6 @@
|
||||
optionalDependencies:
|
||||
prettier "^1.18.2"
|
||||
|
||||
"@webassemblyjs/ast@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f"
|
||||
integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==
|
||||
dependencies:
|
||||
"@webassemblyjs/helper-numbers" "1.11.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.11.0"
|
||||
|
||||
"@webassemblyjs/ast@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
||||
@ -1551,31 +1517,16 @@
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.9.0"
|
||||
"@webassemblyjs/wast-parser" "1.9.0"
|
||||
|
||||
"@webassemblyjs/floating-point-hex-parser@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c"
|
||||
integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==
|
||||
|
||||
"@webassemblyjs/floating-point-hex-parser@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4"
|
||||
integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==
|
||||
|
||||
"@webassemblyjs/helper-api-error@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4"
|
||||
integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==
|
||||
|
||||
"@webassemblyjs/helper-api-error@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2"
|
||||
integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==
|
||||
|
||||
"@webassemblyjs/helper-buffer@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642"
|
||||
integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==
|
||||
|
||||
"@webassemblyjs/helper-buffer@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00"
|
||||
@ -1600,35 +1551,11 @@
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.9.0"
|
||||
|
||||
"@webassemblyjs/helper-numbers@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9"
|
||||
integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==
|
||||
dependencies:
|
||||
"@webassemblyjs/floating-point-hex-parser" "1.11.0"
|
||||
"@webassemblyjs/helper-api-error" "1.11.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@webassemblyjs/helper-wasm-bytecode@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1"
|
||||
integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==
|
||||
|
||||
"@webassemblyjs/helper-wasm-bytecode@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790"
|
||||
integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==
|
||||
|
||||
"@webassemblyjs/helper-wasm-section@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b"
|
||||
integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/helper-buffer" "1.11.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.11.0"
|
||||
"@webassemblyjs/wasm-gen" "1.11.0"
|
||||
|
||||
"@webassemblyjs/helper-wasm-section@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346"
|
||||
@ -1639,13 +1566,6 @@
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.9.0"
|
||||
"@webassemblyjs/wasm-gen" "1.9.0"
|
||||
|
||||
"@webassemblyjs/ieee754@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf"
|
||||
integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==
|
||||
dependencies:
|
||||
"@xtuc/ieee754" "^1.2.0"
|
||||
|
||||
"@webassemblyjs/ieee754@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4"
|
||||
@ -1653,13 +1573,6 @@
|
||||
dependencies:
|
||||
"@xtuc/ieee754" "^1.2.0"
|
||||
|
||||
"@webassemblyjs/leb128@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b"
|
||||
integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==
|
||||
dependencies:
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@webassemblyjs/leb128@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95"
|
||||
@ -1667,30 +1580,11 @@
|
||||
dependencies:
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@webassemblyjs/utf8@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf"
|
||||
integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==
|
||||
|
||||
"@webassemblyjs/utf8@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab"
|
||||
integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==
|
||||
|
||||
"@webassemblyjs/wasm-edit@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78"
|
||||
integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/helper-buffer" "1.11.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.11.0"
|
||||
"@webassemblyjs/helper-wasm-section" "1.11.0"
|
||||
"@webassemblyjs/wasm-gen" "1.11.0"
|
||||
"@webassemblyjs/wasm-opt" "1.11.0"
|
||||
"@webassemblyjs/wasm-parser" "1.11.0"
|
||||
"@webassemblyjs/wast-printer" "1.11.0"
|
||||
|
||||
"@webassemblyjs/wasm-edit@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf"
|
||||
@ -1705,17 +1599,6 @@
|
||||
"@webassemblyjs/wasm-parser" "1.9.0"
|
||||
"@webassemblyjs/wast-printer" "1.9.0"
|
||||
|
||||
"@webassemblyjs/wasm-gen@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe"
|
||||
integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.11.0"
|
||||
"@webassemblyjs/ieee754" "1.11.0"
|
||||
"@webassemblyjs/leb128" "1.11.0"
|
||||
"@webassemblyjs/utf8" "1.11.0"
|
||||
|
||||
"@webassemblyjs/wasm-gen@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c"
|
||||
@ -1727,16 +1610,6 @@
|
||||
"@webassemblyjs/leb128" "1.9.0"
|
||||
"@webassemblyjs/utf8" "1.9.0"
|
||||
|
||||
"@webassemblyjs/wasm-opt@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978"
|
||||
integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/helper-buffer" "1.11.0"
|
||||
"@webassemblyjs/wasm-gen" "1.11.0"
|
||||
"@webassemblyjs/wasm-parser" "1.11.0"
|
||||
|
||||
"@webassemblyjs/wasm-opt@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61"
|
||||
@ -1747,18 +1620,6 @@
|
||||
"@webassemblyjs/wasm-gen" "1.9.0"
|
||||
"@webassemblyjs/wasm-parser" "1.9.0"
|
||||
|
||||
"@webassemblyjs/wasm-parser@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754"
|
||||
integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/helper-api-error" "1.11.0"
|
||||
"@webassemblyjs/helper-wasm-bytecode" "1.11.0"
|
||||
"@webassemblyjs/ieee754" "1.11.0"
|
||||
"@webassemblyjs/leb128" "1.11.0"
|
||||
"@webassemblyjs/utf8" "1.11.0"
|
||||
|
||||
"@webassemblyjs/wasm-parser@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e"
|
||||
@ -1783,14 +1644,6 @@
|
||||
"@webassemblyjs/helper-fsm" "1.9.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@webassemblyjs/wast-printer@1.11.0":
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e"
|
||||
integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@webassemblyjs/wast-printer@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899"
|
||||
@ -2770,9 +2623,9 @@ caniuse-api@^3.0.0:
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001205, caniuse-lite@^1.0.30001208:
|
||||
version "1.0.30001208"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001208.tgz#a999014a35cebd4f98c405930a057a0d75352eb9"
|
||||
integrity sha512-OE5UE4+nBOro8Dyvv0lfx+SRtfVIOM9uhKqFmJeUbGriqhhStgp1A0OyBpgy3OUF8AhYCT+PVwPC1gMl2ZcQMA==
|
||||
version "1.0.30001209"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001209.tgz#1bb4be0bd118e98e21cfb7ef617b1ef2164622f4"
|
||||
integrity sha512-2Ktt4OeRM7EM/JaOZjuLzPYAIqmbwQMNnYbgooT+icoRGrKOyAxA1xhlnotBD1KArRSPsuJp3TdYcZYrL7qNxA==
|
||||
|
||||
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
@ -2814,7 +2667,7 @@ chardet@^0.7.0:
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||
integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
|
||||
|
||||
"chokidar@>=2.0.0 <4.0.0", chokidar@^3.4.1, chokidar@^3.5.1:
|
||||
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.1, chokidar@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
|
||||
integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
|
||||
@ -3385,22 +3238,21 @@ css-loader@^4.3.0:
|
||||
semver "^7.3.2"
|
||||
|
||||
css-loader@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.1.tgz#15fbd5b6ac4c1b170a098f804c5abd0722f2aa73"
|
||||
integrity sha512-YCyRzlt/jgG1xanXZDG/DHqAueOtXFHeusP9TS478oP1J++JSKOyEgGW1GHVoCj/rkS+GWOlBwqQJBr9yajQ9w==
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.2.tgz#65f2c1482255f15847ecad6cbc515cae8a5b234e"
|
||||
integrity sha512-IS722y7Lh2Yq+acMR74tdf3faMOLRP2RfLwS0VzSS7T98IHtacMWJLku3A0OBTFHB07zAa4nWBhA8gfxwQVWGQ==
|
||||
dependencies:
|
||||
camelcase "^6.2.0"
|
||||
cssesc "^3.0.0"
|
||||
icss-utils "^5.1.0"
|
||||
loader-utils "^2.0.0"
|
||||
postcss "^8.2.8"
|
||||
postcss "^8.2.10"
|
||||
postcss-modules-extract-imports "^3.0.0"
|
||||
postcss-modules-local-by-default "^4.0.0"
|
||||
postcss-modules-scope "^3.0.0"
|
||||
postcss-modules-values "^4.0.0"
|
||||
postcss-value-parser "^4.1.0"
|
||||
schema-utils "^3.0.0"
|
||||
semver "^7.3.4"
|
||||
semver "^7.3.5"
|
||||
|
||||
css-prefers-color-scheme@^3.1.1:
|
||||
version "3.1.1"
|
||||
@ -3847,10 +3699,10 @@ domhandler@^2.3.0:
|
||||
dependencies:
|
||||
domelementtype "1"
|
||||
|
||||
domhandler@^4.0.0, domhandler@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.1.0.tgz#c1d8d494d5ec6db22de99e46a149c2a4d23ddd43"
|
||||
integrity sha512-/6/kmsGlMY4Tup/nGVutdrK9yQi4YjWVcVeoQmixpzjOUK1U7pQkvAPHBJeUxOgxF0J8f8lwCJSlCfD0V4CMGQ==
|
||||
domhandler@^4.0.0, domhandler@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059"
|
||||
integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==
|
||||
dependencies:
|
||||
domelementtype "^2.2.0"
|
||||
|
||||
@ -3863,13 +3715,13 @@ domutils@^1.5.1, domutils@^1.7.0:
|
||||
domelementtype "1"
|
||||
|
||||
domutils@^2.4.3:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.5.2.tgz#37ef8ba087dff1a17175e7092e8a042e4b050e6c"
|
||||
integrity sha512-MHTthCb1zj8f1GVfRpeZUbohQf/HdBos0oX5gZcQFepOZPLLRyj6Wn7XS7EMnY7CVpwv8863u2vyE83Hfu28HQ==
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7"
|
||||
integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==
|
||||
dependencies:
|
||||
dom-serializer "^1.0.1"
|
||||
domelementtype "^2.2.0"
|
||||
domhandler "^4.1.0"
|
||||
domhandler "^4.2.0"
|
||||
|
||||
dot-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
@ -3972,14 +3824,6 @@ enhanced-resolve@^4.1.1, enhanced-resolve@^4.5.0:
|
||||
memory-fs "^0.5.0"
|
||||
tapable "^1.0.0"
|
||||
|
||||
enhanced-resolve@^5.7.0:
|
||||
version "5.7.0"
|
||||
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c"
|
||||
integrity sha512-6njwt/NsZFUKhM6j9U8hzVyD4E4r0x7NQzhTCbcWOJ0IQjNSAoalWmb0AE51Wn+fwan5qVESWi7t2ToBxs9vrw==
|
||||
dependencies:
|
||||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
|
||||
enquirer@^2.3.5, enquirer@^2.3.6:
|
||||
version "2.3.6"
|
||||
resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d"
|
||||
@ -4045,11 +3889,6 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2:
|
||||
string.prototype.trimstart "^1.0.4"
|
||||
unbox-primitive "^1.0.0"
|
||||
|
||||
es-module-lexer@^0.4.0:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e"
|
||||
integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==
|
||||
|
||||
es-to-primitive@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a"
|
||||
@ -4424,7 +4263,7 @@ eventemitter3@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
events@^3.0.0, events@^3.2.0:
|
||||
events@^3.0.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
@ -5073,11 +4912,6 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0:
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob-to-regexp@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
|
||||
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
|
||||
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.1.1:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
@ -5192,6 +5026,11 @@ grpc-tools@^1.11.1:
|
||||
dependencies:
|
||||
node-pre-gyp "^0.15.0"
|
||||
|
||||
grpc-web@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/grpc-web/-/grpc-web-1.2.1.tgz#860051d705bf5baa7b81fcbd14030060bf16b7b9"
|
||||
integrity sha512-ibBaJPzfMVuLPgaST9w0kZl60s+SnkPBQp6QKdpEr85tpc1gXW2QDqSne9xiyiym0logDfdUSm4aX5h9YBA2mw==
|
||||
|
||||
grpc@^1.24.6:
|
||||
version "1.24.6"
|
||||
resolved "https://registry.yarnpkg.com/grpc/-/grpc-1.24.6.tgz#1862a9d990f79cfa20b962d77f090000d915469c"
|
||||
@ -6142,7 +5981,7 @@ isobject@^3.0.0, isobject@^3.0.1:
|
||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
||||
|
||||
jest-worker@^26.5.0, jest-worker@^26.6.2:
|
||||
jest-worker@^26.5.0:
|
||||
version "26.6.2"
|
||||
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
|
||||
integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==
|
||||
@ -6405,7 +6244,7 @@ loader-runner@^2.4.0:
|
||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
|
||||
integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
|
||||
|
||||
loader-runner@^4.1.0, loader-runner@^4.2.0:
|
||||
loader-runner@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384"
|
||||
integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==
|
||||
@ -6766,9 +6605,9 @@ mimic-fn@^3.1.0:
|
||||
integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==
|
||||
|
||||
mini-css-extract-plugin@^1.3.4:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.4.1.tgz#975e27c1d0bd8e052972415f47c79cea5ed37548"
|
||||
integrity sha512-COAGbpAsU0ioFzj+/RRfO5Qv177L1Z/XAx2EmCF33b8GDDqKygMffBTws2lit8iaPdrbKEY5P+zsseBUCREZWQ==
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.5.0.tgz#69bee3b273d2d4ee8649a2eb409514b7df744a27"
|
||||
integrity sha512-SIbuLMv6jsk1FnLIU5OUG/+VMGUprEjM1+o2trOAx8i5KOKMrhyezb1dJ4Ugsykb8Jgq8/w5NEopy6escV9G7g==
|
||||
dependencies:
|
||||
loader-utils "^2.0.0"
|
||||
schema-utils "^3.0.0"
|
||||
@ -7311,9 +7150,9 @@ object-copy@^0.1.0:
|
||||
kind-of "^3.0.3"
|
||||
|
||||
object-inspect@^1.9.0:
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a"
|
||||
integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.2.tgz#b6385a3e2b7cae0b5eafcf90cddf85d128767f30"
|
||||
integrity sha512-gz58rdPpadwztRrPjZE9DZLOABUpTGdcANUgOwBFO1C+HZZhePoP83M65WGDmbpwFYJSWqavbl4SgDn4k8RYTA==
|
||||
|
||||
object-is@^1.0.1:
|
||||
version "1.1.5"
|
||||
@ -8524,7 +8363,7 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2
|
||||
source-map "^0.6.1"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
postcss@^8.2.8:
|
||||
postcss@^8.2.10:
|
||||
version "8.2.10"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.10.tgz#ca7a042aa8aff494b334d0ff3e9e77079f6f702b"
|
||||
integrity sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw==
|
||||
@ -9319,20 +9158,23 @@ sass-lint@^1.13.1:
|
||||
path-is-absolute "^1.0.0"
|
||||
util "^0.10.3"
|
||||
|
||||
sass-loader@^11.0.1:
|
||||
version "11.0.1"
|
||||
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-11.0.1.tgz#8672f896593466573b904f47693e0695368e38c9"
|
||||
integrity sha512-Vp1LcP4slTsTNLEiDkTcm8zGN/XYYrZz2BZybQbliWA8eXveqA/AxsEjllQTpJbg2MzCsx/qNO48sHdZtOaxTw==
|
||||
sass-loader@^10.1.1:
|
||||
version "10.1.1"
|
||||
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.1.1.tgz#4ddd5a3d7638e7949065dd6e9c7c04037f7e663d"
|
||||
integrity sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw==
|
||||
dependencies:
|
||||
klona "^2.0.4"
|
||||
loader-utils "^2.0.0"
|
||||
neo-async "^2.6.2"
|
||||
schema-utils "^3.0.0"
|
||||
semver "^7.3.2"
|
||||
|
||||
sass@^1.32.4:
|
||||
version "1.32.8"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.8.tgz#f16a9abd8dc530add8834e506878a2808c037bdc"
|
||||
integrity sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==
|
||||
version "1.32.10"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.10.tgz#d40da4e20031b450359ee1c7e69bc8cc89569241"
|
||||
integrity sha512-Nx0pcWoonAkn7CRp0aE/hket1UP97GiR1IFw3kcjV3pnenhWgZEWUf0ZcfPOV2fK52fnOcK3JdC/YYZ9E47DTQ==
|
||||
dependencies:
|
||||
chokidar ">=2.0.0 <4.0.0"
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
|
||||
sax@^1.2.4, sax@~1.2.4:
|
||||
version "1.2.4"
|
||||
@ -9398,7 +9240,7 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semve
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
|
||||
semver@^7.2.1, semver@^7.3.2, semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||
@ -9678,7 +9520,7 @@ sort-keys@^2.0.0:
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
source-list-map@^2.0.0, source-list-map@^2.0.1:
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
|
||||
@ -10107,7 +9949,7 @@ tapable@^1.0.0, tapable@^1.0.0-beta.5, tapable@^1.1.3:
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
|
||||
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
|
||||
|
||||
tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0:
|
||||
tapable@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
|
||||
integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
|
||||
@ -10178,18 +10020,6 @@ terser-webpack-plugin@^4.2.3:
|
||||
terser "^5.3.4"
|
||||
webpack-sources "^1.4.3"
|
||||
|
||||
terser-webpack-plugin@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.1.tgz#7effadee06f7ecfa093dbbd3e9ab23f5f3ed8673"
|
||||
integrity sha512-5XNNXZiR8YO6X6KhSGXfY0QrGrCRlSwAEjIIrlRQR4W8nP69TaJUlh3bkuac6zzgspiGPfKEHcY295MMVExl5Q==
|
||||
dependencies:
|
||||
jest-worker "^26.6.2"
|
||||
p-limit "^3.1.0"
|
||||
schema-utils "^3.0.0"
|
||||
serialize-javascript "^5.0.1"
|
||||
source-map "^0.6.1"
|
||||
terser "^5.5.1"
|
||||
|
||||
terser@^4.1.2, terser@^4.6.3:
|
||||
version "4.8.0"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
|
||||
@ -10199,7 +10029,7 @@ terser@^4.1.2, terser@^4.6.3:
|
||||
source-map "~0.6.1"
|
||||
source-map-support "~0.5.12"
|
||||
|
||||
terser@^5.3.4, terser@^5.5.1:
|
||||
terser@^5.3.4:
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.6.1.tgz#a48eeac5300c0a09b36854bf90d9c26fb201973c"
|
||||
integrity sha512-yv9YLFQQ+3ZqgWCUk+pvNJwgUTdlIxUk1WTN+RnaFJe2L7ipG2csPT0ra2XRm7Cs8cxN7QXmK1rFzEwYEQkzXw==
|
||||
@ -10838,14 +10668,6 @@ watchpack@^1.7.4:
|
||||
chokidar "^3.4.1"
|
||||
watchpack-chokidar2 "^2.0.1"
|
||||
|
||||
watchpack@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7"
|
||||
integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw==
|
||||
dependencies:
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.1.2"
|
||||
|
||||
wbuf@^1.1.0, wbuf@^1.7.3:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"
|
||||
@ -10989,14 +10811,6 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.4.0, webpack-
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
webpack-sources@^2.1.1:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac"
|
||||
integrity sha512-bQsA24JLwcnWGArOKUxYKhX3Mz/nK1Xf6hxullKERyktjNMC4x8koOeaDNTA2fEJ09BdWLbM/iTW0ithREUP0w==
|
||||
dependencies:
|
||||
source-list-map "^2.0.1"
|
||||
source-map "^0.6.1"
|
||||
|
||||
webpack@^4.46.0:
|
||||
version "4.46.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542"
|
||||
@ -11026,35 +10840,6 @@ webpack@^4.46.0:
|
||||
watchpack "^1.7.4"
|
||||
webpack-sources "^1.4.1"
|
||||
|
||||
webpack@^5.33.2:
|
||||
version "5.33.2"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.33.2.tgz#c049717c9b038febf5a72fd2f53319ad59a8c1fc"
|
||||
integrity sha512-X4b7F1sYBmJx8mlh2B7mV5szEkE0jYNJ2y3akgAP0ERi0vLCG1VvdsIxt8lFd4st6SUy0lf7W0CCQS566MBpJg==
|
||||
dependencies:
|
||||
"@types/eslint-scope" "^3.7.0"
|
||||
"@types/estree" "^0.0.46"
|
||||
"@webassemblyjs/ast" "1.11.0"
|
||||
"@webassemblyjs/wasm-edit" "1.11.0"
|
||||
"@webassemblyjs/wasm-parser" "1.11.0"
|
||||
acorn "^8.0.4"
|
||||
browserslist "^4.14.5"
|
||||
chrome-trace-event "^1.0.2"
|
||||
enhanced-resolve "^5.7.0"
|
||||
es-module-lexer "^0.4.0"
|
||||
eslint-scope "^5.1.1"
|
||||
events "^3.2.0"
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.2.4"
|
||||
json-parse-better-errors "^1.0.2"
|
||||
loader-runner "^4.2.0"
|
||||
mime-types "^2.1.27"
|
||||
neo-async "^2.6.2"
|
||||
schema-utils "^3.0.0"
|
||||
tapable "^2.1.1"
|
||||
terser-webpack-plugin "^5.1.1"
|
||||
watchpack "^2.0.0"
|
||||
webpack-sources "^2.1.1"
|
||||
|
||||
webpackbar@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-4.0.0.tgz#ee7a87f16077505b5720551af413c8ecd5b1f780"
|
||||
@ -11240,9 +11025,9 @@ ws@^6.2.1:
|
||||
async-limiter "~1.0.0"
|
||||
|
||||
ws@^7.3.1:
|
||||
version "7.4.4"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.4.tgz#383bc9742cb202292c9077ceab6f6047b17f2d59"
|
||||
integrity sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==
|
||||
version "7.4.5"
|
||||
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.5.tgz#a484dd851e9beb6fdb420027e3885e8ce48986c1"
|
||||
integrity sha512-xzyu3hFvomRfXKH8vOFMU3OguG6oOvhXMo3xsGy3xWExqaM2dxBbVxuD99O7m3ZUFMvvscsZDqxfgMaRr/Nr1g==
|
||||
|
||||
xtend@^4.0.0, xtend@~4.0.1:
|
||||
version "4.0.2"
|
||||
|
@ -123,7 +123,7 @@ dependencies = [
|
||||
"log",
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project 1.0.6",
|
||||
"pin-project 1.0.7",
|
||||
"rand 0.7.3",
|
||||
"regex",
|
||||
"serde 1.0.125",
|
||||
@ -189,7 +189,7 @@ dependencies = [
|
||||
"mio-uds",
|
||||
"num_cpus",
|
||||
"slab",
|
||||
"socket2",
|
||||
"socket2 0.3.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -213,7 +213,7 @@ dependencies = [
|
||||
"actix-server",
|
||||
"actix-service",
|
||||
"log",
|
||||
"socket2",
|
||||
"socket2 0.3.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -309,12 +309,12 @@ dependencies = [
|
||||
"fxhash",
|
||||
"log",
|
||||
"mime",
|
||||
"pin-project 1.0.6",
|
||||
"pin-project 1.0.7",
|
||||
"regex",
|
||||
"serde 1.0.125",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"socket2",
|
||||
"socket2 0.3.19",
|
||||
"time 0.2.26",
|
||||
"tinyvec",
|
||||
"url",
|
||||
@ -422,9 +422,9 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.48"
|
||||
version = "0.1.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf"
|
||||
checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -551,11 +551,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.2"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"serde 1.0.125",
|
||||
]
|
||||
|
||||
@ -639,9 +638,9 @@ checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.4"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
@ -666,9 +665,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.3"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
|
||||
checksum = "cc38c385bfd7e444464011bb24820f40dd1c76bcdfa1b78611cb7c2e5cafab75"
|
||||
dependencies = [
|
||||
"rustc_version",
|
||||
]
|
||||
@ -760,6 +759,17 @@ name = "config"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"nom",
|
||||
"serde 1.0.125",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"nom",
|
||||
@ -773,9 +783,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.6"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "076a6803b0dacd6a88cfe64deba628b01533ff5ef265687e6938280c1afd0a28"
|
||||
checksum = "402da840495de3f976eaefc3485b7f5eb5b0bf9761f9a47be27fe975b3b8c2ec"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
@ -877,9 +887,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
|
||||
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crossbeam-utils 0.8.3",
|
||||
@ -1023,7 +1033,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4aaff9a7a1de9893f4004fa08527b31cb2ae4121c44e053cf53f29203c73bd23"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"config",
|
||||
"config 0.10.1",
|
||||
"crossbeam-queue",
|
||||
"num_cpus",
|
||||
"serde 1.0.125",
|
||||
@ -1037,7 +1047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faad41e7f93dd682108c72aec029e5bc6238e7df64c9d84832525d4033d2e726"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"config",
|
||||
"config 0.10.1",
|
||||
"deadpool",
|
||||
"futures",
|
||||
"log",
|
||||
@ -1224,7 +1234,7 @@ checksum = "1d34cfa13a63ae058bfa601fe9e313bbdb3746427c1459185464ce0fcf62e1e8"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall 0.2.6",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
@ -1305,9 +1315,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1"
|
||||
checksum = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -1320,9 +1330,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939"
|
||||
checksum = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@ -1330,15 +1340,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94"
|
||||
checksum = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1"
|
||||
checksum = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -1348,15 +1358,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59"
|
||||
checksum = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7"
|
||||
checksum = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b"
|
||||
dependencies = [
|
||||
"proc-macro-hack",
|
||||
"proc-macro2",
|
||||
@ -1366,21 +1376,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3"
|
||||
checksum = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80"
|
||||
checksum = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1"
|
||||
checksum = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -1564,9 +1574,9 @@ checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.3"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747"
|
||||
checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"fnv",
|
||||
@ -1575,9 +1585,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.3.5"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691"
|
||||
checksum = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437"
|
||||
|
||||
[[package]]
|
||||
name = "httpbis"
|
||||
@ -1642,11 +1652,11 @@ dependencies = [
|
||||
"clap",
|
||||
"colored",
|
||||
"combine",
|
||||
"config",
|
||||
"config 0.11.0",
|
||||
"crc32fast",
|
||||
"criterion",
|
||||
"crossbeam",
|
||||
"crossbeam-channel 0.5.0",
|
||||
"crossbeam-channel 0.5.1",
|
||||
"deadpool",
|
||||
"deadpool-postgres",
|
||||
"derive_more",
|
||||
@ -1705,7 +1715,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_qs",
|
||||
"serde_yaml",
|
||||
"signal-hook 0.3.7",
|
||||
"signal-hook 0.3.8",
|
||||
"slog",
|
||||
"slog-async",
|
||||
"slog-json",
|
||||
@ -1737,9 +1747,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21"
|
||||
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||
dependencies = [
|
||||
"matches",
|
||||
"unicode-bidi",
|
||||
@ -1786,7 +1796,7 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
|
||||
dependencies = [
|
||||
"socket2",
|
||||
"socket2 0.3.19",
|
||||
"widestring",
|
||||
"winapi 0.3.9",
|
||||
"winreg",
|
||||
@ -1818,9 +1828,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.49"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821"
|
||||
checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@ -1871,19 +1881,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.91"
|
||||
version = "0.2.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
|
||||
dependencies = [
|
||||
"serde 0.8.23",
|
||||
"serde_test",
|
||||
]
|
||||
checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
@ -1893,9 +1893,9 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
|
||||
checksum = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
@ -1965,7 +1965,7 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||
dependencies = [
|
||||
"linked-hash-map 0.5.4",
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2012,6 +2012,17 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"digest",
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
@ -2317,7 +2328,7 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"instant",
|
||||
"libc",
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall 0.2.6",
|
||||
"smallvec",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
@ -2357,11 +2368,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6"
|
||||
checksum = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4"
|
||||
dependencies = [
|
||||
"pin-project-internal 1.0.6",
|
||||
"pin-project-internal 1.0.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2377,9 +2388,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5"
|
||||
checksum = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -2477,16 +2488,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "postgres-protocol"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70e34ad3dc5c56d036b9418185ee97e14b6766d55c8ccf9dc18302ad4e6371d9"
|
||||
checksum = "ff3e0f70d32e20923cabf2df02913be7c1842d4c772db8065c00fcfdd1d1bff3"
|
||||
dependencies = [
|
||||
"base64 0.13.0",
|
||||
"byteorder",
|
||||
"bytes 1.0.1",
|
||||
"fallible-iterator",
|
||||
"hmac 0.10.1",
|
||||
"md5",
|
||||
"md-5",
|
||||
"memchr",
|
||||
"rand 0.8.3",
|
||||
"sha2",
|
||||
@ -2509,13 +2520,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "postgres-types"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5493d9d4613b88b12433aa12890e74e74cd93fdc1e08b7c2aed4768aaae8414c"
|
||||
checksum = "430f4131e1b7657b0cd9a2b0c3408d77c9a43a042d300b8c77f981dffcc43a2f"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"fallible-iterator",
|
||||
"postgres-protocol 0.6.0",
|
||||
"postgres-protocol 0.6.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2538,9 +2549,9 @@ checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@ -2768,7 +2779,7 @@ version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
|
||||
dependencies = [
|
||||
"crossbeam-channel 0.5.0",
|
||||
"crossbeam-channel 0.5.1",
|
||||
"crossbeam-deque 0.8.0",
|
||||
"crossbeam-utils 0.8.3",
|
||||
"lazy_static",
|
||||
@ -2792,9 +2803,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.5"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9"
|
||||
checksum = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
@ -2806,7 +2817,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64"
|
||||
dependencies = [
|
||||
"getrandom 0.2.2",
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall 0.2.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2999,7 +3010,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"linked-hash-map 0.3.0",
|
||||
"num-traits 0.1.43",
|
||||
"regex",
|
||||
"serde 0.8.23",
|
||||
@ -3058,15 +3068,6 @@ dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_test"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5"
|
||||
dependencies = [
|
||||
"serde 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_urlencoded"
|
||||
version = "0.7.0"
|
||||
@ -3086,7 +3087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23"
|
||||
dependencies = [
|
||||
"dtoa",
|
||||
"linked-hash-map 0.5.4",
|
||||
"linked-hash-map",
|
||||
"serde 1.0.125",
|
||||
"yaml-rust",
|
||||
]
|
||||
@ -3135,9 +3136,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.7"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6aa894ef3fade0ee7243422f4fbbd6c2b48e6de767e621d37ef65f2310f53cea"
|
||||
checksum = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
@ -3179,7 +3180,7 @@ version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c60813879f820c85dbc4eabf3269befe374591289019775898d56a81a804fbdc"
|
||||
dependencies = [
|
||||
"crossbeam-channel 0.5.0",
|
||||
"crossbeam-channel 0.5.1",
|
||||
"slog",
|
||||
"take_mut",
|
||||
"thread_local",
|
||||
@ -3272,6 +3273,16 @@ dependencies = [
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
@ -3384,9 +3395,9 @@ checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.67"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702"
|
||||
checksum = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -3452,7 +3463,7 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"rand 0.8.3",
|
||||
"redox_syscall 0.2.5",
|
||||
"redox_syscall 0.2.6",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
@ -3605,9 +3616,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.1.1"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023"
|
||||
checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
@ -3665,9 +3676,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.4.0"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722"
|
||||
checksum = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"bytes 1.0.1",
|
||||
@ -3694,7 +3705,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f2b78f3566383ffabc553c72bbb2f129962a54886c5c4d8e8c706f84eceab8"
|
||||
dependencies = [
|
||||
"tokio-postgres 0.7.0",
|
||||
"tokio-postgres 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3705,7 +3716,7 @@ checksum = "8548f756cd6eb4069c5af0fb0cec57001fb42bd1fb7330d8f24067ee3fa62608"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"tokio-postgres 0.7.0",
|
||||
"tokio-postgres 0.7.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3732,9 +3743,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-postgres"
|
||||
version = "0.7.0"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cc9f82c2bfb06a33dd0dfb44b07ca98fe72df19e681d80c78d05a1bac2138e2"
|
||||
checksum = "98779a950cb6ef76f8ad71c411176115c5c1200a83eeeca4dd9f61e3fc4836c8"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"byteorder",
|
||||
@ -3746,11 +3757,11 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"phf",
|
||||
"pin-project-lite 0.2.6",
|
||||
"postgres-protocol 0.6.0",
|
||||
"postgres-types 0.2.0",
|
||||
"socket2",
|
||||
"tokio 1.4.0",
|
||||
"tokio-util 0.6.5",
|
||||
"postgres-protocol 0.6.1",
|
||||
"postgres-types 0.2.1",
|
||||
"socket2 0.4.0",
|
||||
"tokio 1.5.0",
|
||||
"tokio-util 0.6.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3784,16 +3795,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.6.5"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5143d049e85af7fbc36f5454d990e62c2df705b3589f123b71f441b6b59f443f"
|
||||
checksum = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e"
|
||||
dependencies = [
|
||||
"bytes 1.0.1",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"log",
|
||||
"pin-project-lite 0.2.6",
|
||||
"tokio 1.4.0",
|
||||
"tokio 1.5.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3832,7 +3843,7 @@ version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2"
|
||||
dependencies = [
|
||||
"pin-project 1.0.6",
|
||||
"pin-project 1.0.7",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
@ -3898,9 +3909,9 @@ checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.4"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
|
||||
checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0"
|
||||
dependencies = [
|
||||
"matches",
|
||||
]
|
||||
@ -4037,9 +4048,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe"
|
||||
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
@ -4047,9 +4058,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3"
|
||||
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@ -4062,9 +4073,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b"
|
||||
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@ -4072,9 +4083,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d"
|
||||
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -4085,15 +4096,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.72"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa"
|
||||
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.49"
|
||||
version = "0.3.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310"
|
||||
checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@ -4182,5 +4193,5 @@ version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map 0.5.4",
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
@ -33,7 +33,7 @@ chrono = { version = "0.4.13", features = ["serde"] }
|
||||
clap = "2.33.3"
|
||||
colored = "2"
|
||||
combine = { version = "4", default-features = false, features = [] }
|
||||
config = "0.10.1"
|
||||
config = "0.11.0"
|
||||
crc32fast = "1.2.0"
|
||||
criterion = "0.3.3"
|
||||
crossbeam = "0.7.3"
|
||||
@ -60,7 +60,7 @@ integer-encoding = "2.0.0"
|
||||
itertools = "0.9.0"
|
||||
lazy_static = "1.4.0"
|
||||
levenshtein_automata = { version="0.1", features = ["fst_automaton"] }
|
||||
lexical-core = "0.7.4"
|
||||
lexical-core = "0.7.5"
|
||||
libc = "0.2.74"
|
||||
log = { version = "0.4.11", features = ["std"] }
|
||||
log4rs = { version = "0.10.0", features = ["file", "json_encoder"] }
|
||||
@ -162,12 +162,6 @@ additional_flags = [
|
||||
"--cfg=libc_packedN",
|
||||
]
|
||||
|
||||
[package.metadata.raze.crates.lexical-core.'*']
|
||||
additional_flags = [
|
||||
"--cfg=limb_width_32",
|
||||
"--cfg=has_i128",
|
||||
]
|
||||
|
||||
[package.metadata.raze.crates.log.'*']
|
||||
additional_flags = [
|
||||
"--cfg=atomic_cas"
|
||||
|
@ -86,7 +86,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "async_trait",
|
||||
actual = "@raze__async_trait__0_1_48//:async_trait",
|
||||
actual = "@raze__async_trait__0_1_50//:async_trait",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -149,7 +149,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "bincode",
|
||||
actual = "@raze__bincode__1_3_2//:bincode",
|
||||
actual = "@raze__bincode__1_3_3//:bincode",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -176,7 +176,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "byteorder",
|
||||
actual = "@raze__byteorder__1_3_4//:byteorder",
|
||||
actual = "@raze__byteorder__1_4_3//:byteorder",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -239,7 +239,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "config",
|
||||
actual = "@raze__config__0_10_1//:config",
|
||||
actual = "@raze__config__0_11_0//:config",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -275,7 +275,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "crossbeam_channel",
|
||||
actual = "@raze__crossbeam_channel__0_5_0//:crossbeam_channel",
|
||||
actual = "@raze__crossbeam_channel__0_5_1//:crossbeam_channel",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -410,7 +410,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "futures",
|
||||
actual = "@raze__futures__0_3_13//:futures",
|
||||
actual = "@raze__futures__0_3_14//:futures",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -502,7 +502,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "libc",
|
||||
actual = "@raze__libc__0_2_91//:libc",
|
||||
actual = "@raze__libc__0_2_93//:libc",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
@ -828,7 +828,7 @@ alias(
|
||||
|
||||
alias(
|
||||
name = "signal_hook",
|
||||
actual = "@raze__signal_hook__0_3_7//:signal_hook",
|
||||
actual = "@raze__signal_hook__0_3_8//:signal_hook",
|
||||
tags = [
|
||||
"cargo-raze",
|
||||
"manual",
|
||||
|
@ -313,12 +313,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__async_trait__0_1_48",
|
||||
url = "https://crates.io/api/v1/crates/async-trait/0.1.48/download",
|
||||
name = "raze__async_trait__0_1_50",
|
||||
url = "https://crates.io/api/v1/crates/async-trait/0.1.50/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf",
|
||||
strip_prefix = "async-trait-0.1.48",
|
||||
build_file = Label("//rules/rust/remote:BUILD.async-trait-0.1.48.bazel"),
|
||||
sha256 = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722",
|
||||
strip_prefix = "async-trait-0.1.50",
|
||||
build_file = Label("//rules/rust/remote:BUILD.async-trait-0.1.50.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -433,12 +433,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__bincode__1_3_2",
|
||||
url = "https://crates.io/api/v1/crates/bincode/1.3.2/download",
|
||||
name = "raze__bincode__1_3_3",
|
||||
url = "https://crates.io/api/v1/crates/bincode/1.3.3/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "d175dfa69e619905c4c3cdb7c3c203fa3bdd5d51184e3afdb2742c0280493772",
|
||||
strip_prefix = "bincode-1.3.2",
|
||||
build_file = Label("//rules/rust/remote:BUILD.bincode-1.3.2.bazel"),
|
||||
sha256 = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad",
|
||||
strip_prefix = "bincode-1.3.3",
|
||||
build_file = Label("//rules/rust/remote:BUILD.bincode-1.3.3.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -533,12 +533,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__byteorder__1_3_4",
|
||||
url = "https://crates.io/api/v1/crates/byteorder/1.3.4/download",
|
||||
name = "raze__byteorder__1_4_3",
|
||||
url = "https://crates.io/api/v1/crates/byteorder/1.4.3/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de",
|
||||
strip_prefix = "byteorder-1.3.4",
|
||||
build_file = Label("//rules/rust/remote:BUILD.byteorder-1.3.4.bazel"),
|
||||
sha256 = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610",
|
||||
strip_prefix = "byteorder-1.4.3",
|
||||
build_file = Label("//rules/rust/remote:BUILD.byteorder-1.4.3.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -573,12 +573,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__cast__0_2_3",
|
||||
url = "https://crates.io/api/v1/crates/cast/0.2.3/download",
|
||||
name = "raze__cast__0_2_5",
|
||||
url = "https://crates.io/api/v1/crates/cast/0.2.5/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0",
|
||||
strip_prefix = "cast-0.2.3",
|
||||
build_file = Label("//rules/rust/remote:BUILD.cast-0.2.3.bazel"),
|
||||
sha256 = "cc38c385bfd7e444464011bb24820f40dd1c76bcdfa1b78611cb7c2e5cafab75",
|
||||
strip_prefix = "cast-0.2.5",
|
||||
build_file = Label("//rules/rust/remote:BUILD.cast-0.2.5.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -683,12 +683,22 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__const_fn__0_4_6",
|
||||
url = "https://crates.io/api/v1/crates/const_fn/0.4.6/download",
|
||||
name = "raze__config__0_11_0",
|
||||
url = "https://crates.io/api/v1/crates/config/0.11.0/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "076a6803b0dacd6a88cfe64deba628b01533ff5ef265687e6938280c1afd0a28",
|
||||
strip_prefix = "const_fn-0.4.6",
|
||||
build_file = Label("//rules/rust/remote:BUILD.const_fn-0.4.6.bazel"),
|
||||
sha256 = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369",
|
||||
strip_prefix = "config-0.11.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.config-0.11.0.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__const_fn__0_4_7",
|
||||
url = "https://crates.io/api/v1/crates/const_fn/0.4.7/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "402da840495de3f976eaefc3485b7f5eb5b0bf9761f9a47be27fe975b3b8c2ec",
|
||||
strip_prefix = "const_fn-0.4.7",
|
||||
build_file = Label("//rules/rust/remote:BUILD.const_fn-0.4.7.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -783,12 +793,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__crossbeam_channel__0_5_0",
|
||||
url = "https://crates.io/api/v1/crates/crossbeam-channel/0.5.0/download",
|
||||
name = "raze__crossbeam_channel__0_5_1",
|
||||
url = "https://crates.io/api/v1/crates/crossbeam-channel/0.5.1/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775",
|
||||
strip_prefix = "crossbeam-channel-0.5.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.crossbeam-channel-0.5.0.bazel"),
|
||||
sha256 = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4",
|
||||
strip_prefix = "crossbeam-channel-0.5.1",
|
||||
build_file = Label("//rules/rust/remote:BUILD.crossbeam-channel-0.5.1.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1223,92 +1233,92 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures/0.3.13/download",
|
||||
name = "raze__futures__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1",
|
||||
strip_prefix = "futures-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-0.3.13.bazel"),
|
||||
sha256 = "a9d5813545e459ad3ca1bff9915e9ad7f1a47dc6a91b627ce321d5863b7dd253",
|
||||
strip_prefix = "futures-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_channel__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-channel/0.3.13/download",
|
||||
name = "raze__futures_channel__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-channel/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939",
|
||||
strip_prefix = "futures-channel-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-channel-0.3.13.bazel"),
|
||||
sha256 = "ce79c6a52a299137a6013061e0cf0e688fce5d7f1bc60125f520912fdb29ec25",
|
||||
strip_prefix = "futures-channel-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-channel-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_core__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-core/0.3.13/download",
|
||||
name = "raze__futures_core__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-core/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94",
|
||||
strip_prefix = "futures-core-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-core-0.3.13.bazel"),
|
||||
sha256 = "098cd1c6dda6ca01650f1a37a794245eb73181d0d4d4e955e2f3c37db7af1815",
|
||||
strip_prefix = "futures-core-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-core-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_executor__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-executor/0.3.13/download",
|
||||
name = "raze__futures_executor__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-executor/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1",
|
||||
strip_prefix = "futures-executor-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-executor-0.3.13.bazel"),
|
||||
sha256 = "10f6cb7042eda00f0049b1d2080aa4b93442997ee507eb3828e8bd7577f94c9d",
|
||||
strip_prefix = "futures-executor-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-executor-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_io__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-io/0.3.13/download",
|
||||
name = "raze__futures_io__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-io/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59",
|
||||
strip_prefix = "futures-io-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-io-0.3.13.bazel"),
|
||||
sha256 = "365a1a1fb30ea1c03a830fdb2158f5236833ac81fa0ad12fe35b29cddc35cb04",
|
||||
strip_prefix = "futures-io-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-io-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_macro__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-macro/0.3.13/download",
|
||||
name = "raze__futures_macro__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-macro/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7",
|
||||
strip_prefix = "futures-macro-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-macro-0.3.13.bazel"),
|
||||
sha256 = "668c6733a182cd7deb4f1de7ba3bf2120823835b3bcfbeacf7d2c4a773c1bb8b",
|
||||
strip_prefix = "futures-macro-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-macro-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_sink__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-sink/0.3.13/download",
|
||||
name = "raze__futures_sink__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-sink/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3",
|
||||
strip_prefix = "futures-sink-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-sink-0.3.13.bazel"),
|
||||
sha256 = "5c5629433c555de3d82861a7a4e3794a4c40040390907cfbfd7143a92a426c23",
|
||||
strip_prefix = "futures-sink-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-sink-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_task__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-task/0.3.13/download",
|
||||
name = "raze__futures_task__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-task/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80",
|
||||
strip_prefix = "futures-task-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-task-0.3.13.bazel"),
|
||||
sha256 = "ba7aa51095076f3ba6d9a1f702f74bd05ec65f555d70d2033d55ba8d69f581bc",
|
||||
strip_prefix = "futures-task-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-task-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__futures_util__0_3_13",
|
||||
url = "https://crates.io/api/v1/crates/futures-util/0.3.13/download",
|
||||
name = "raze__futures_util__0_3_14",
|
||||
url = "https://crates.io/api/v1/crates/futures-util/0.3.14/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1",
|
||||
strip_prefix = "futures-util-0.3.13",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-util-0.3.13.bazel"),
|
||||
sha256 = "3c144ad54d60f23927f0a6b6d816e4271278b64f005ad65e4e35291d2de9c025",
|
||||
strip_prefix = "futures-util-0.3.14",
|
||||
build_file = Label("//rules/rust/remote:BUILD.futures-util-0.3.14.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1473,22 +1483,22 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__http__0_2_3",
|
||||
url = "https://crates.io/api/v1/crates/http/0.2.3/download",
|
||||
name = "raze__http__0_2_4",
|
||||
url = "https://crates.io/api/v1/crates/http/0.2.4/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747",
|
||||
strip_prefix = "http-0.2.3",
|
||||
build_file = Label("//rules/rust/remote:BUILD.http-0.2.3.bazel"),
|
||||
sha256 = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11",
|
||||
strip_prefix = "http-0.2.4",
|
||||
build_file = Label("//rules/rust/remote:BUILD.http-0.2.4.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__httparse__1_3_5",
|
||||
url = "https://crates.io/api/v1/crates/httparse/1.3.5/download",
|
||||
name = "raze__httparse__1_4_0",
|
||||
url = "https://crates.io/api/v1/crates/httparse/1.4.0/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691",
|
||||
strip_prefix = "httparse-1.3.5",
|
||||
build_file = Label("//rules/rust/remote:BUILD.httparse-1.3.5.bazel"),
|
||||
sha256 = "4a1ce40d6fc9764887c2fdc7305c3dcc429ba11ff981c1509416afd5697e4437",
|
||||
strip_prefix = "httparse-1.4.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.httparse-1.4.0.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1523,12 +1533,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__idna__0_2_2",
|
||||
url = "https://crates.io/api/v1/crates/idna/0.2.2/download",
|
||||
name = "raze__idna__0_2_3",
|
||||
url = "https://crates.io/api/v1/crates/idna/0.2.3/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21",
|
||||
strip_prefix = "idna-0.2.2",
|
||||
build_file = Label("//rules/rust/remote:BUILD.idna-0.2.2.bazel"),
|
||||
sha256 = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8",
|
||||
strip_prefix = "idna-0.2.3",
|
||||
build_file = Label("//rules/rust/remote:BUILD.idna-0.2.3.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1613,12 +1623,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__js_sys__0_3_49",
|
||||
url = "https://crates.io/api/v1/crates/js-sys/0.3.49/download",
|
||||
name = "raze__js_sys__0_3_50",
|
||||
url = "https://crates.io/api/v1/crates/js-sys/0.3.50/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "dc15e39392125075f60c95ba416f5381ff6c3a948ff02ab12464715adf56c821",
|
||||
strip_prefix = "js-sys-0.3.49",
|
||||
build_file = Label("//rules/rust/remote:BUILD.js-sys-0.3.49.bazel"),
|
||||
sha256 = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c",
|
||||
strip_prefix = "js-sys-0.3.50",
|
||||
build_file = Label("//rules/rust/remote:BUILD.js-sys-0.3.50.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1673,22 +1683,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__libc__0_2_91",
|
||||
url = "https://crates.io/api/v1/crates/libc/0.2.91/download",
|
||||
name = "raze__libc__0_2_93",
|
||||
url = "https://crates.io/api/v1/crates/libc/0.2.93/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7",
|
||||
strip_prefix = "libc-0.2.91",
|
||||
build_file = Label("//rules/rust/remote:BUILD.libc-0.2.91.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__linked_hash_map__0_3_0",
|
||||
url = "https://crates.io/api/v1/crates/linked-hash-map/0.3.0/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd",
|
||||
strip_prefix = "linked-hash-map-0.3.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.linked-hash-map-0.3.0.bazel"),
|
||||
sha256 = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41",
|
||||
strip_prefix = "libc-0.2.93",
|
||||
build_file = Label("//rules/rust/remote:BUILD.libc-0.2.93.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1703,12 +1703,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__lock_api__0_4_2",
|
||||
url = "https://crates.io/api/v1/crates/lock_api/0.4.2/download",
|
||||
name = "raze__lock_api__0_4_3",
|
||||
url = "https://crates.io/api/v1/crates/lock_api/0.4.3/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312",
|
||||
strip_prefix = "lock_api-0.4.2",
|
||||
build_file = Label("//rules/rust/remote:BUILD.lock_api-0.4.2.bazel"),
|
||||
sha256 = "5a3c91c24eae6777794bb1997ad98bbb87daf92890acab859f7eaa4320333176",
|
||||
strip_prefix = "lock_api-0.4.3",
|
||||
build_file = Label("//rules/rust/remote:BUILD.lock_api-0.4.3.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -1831,6 +1831,16 @@ def raze_fetch_remote_crates():
|
||||
build_file = Label("//rules/rust/remote:BUILD.maybe-uninit-2.0.0.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__md_5__0_9_1",
|
||||
url = "https://crates.io/api/v1/crates/md-5/0.9.1/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15",
|
||||
strip_prefix = "md-5-0.9.1",
|
||||
build_file = Label("//rules/rust/remote:BUILD.md-5-0.9.1.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__md5__0_7_0",
|
||||
@ -2193,12 +2203,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__pin_project__1_0_6",
|
||||
url = "https://crates.io/api/v1/crates/pin-project/1.0.6/download",
|
||||
name = "raze__pin_project__1_0_7",
|
||||
url = "https://crates.io/api/v1/crates/pin-project/1.0.7/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "bc174859768806e91ae575187ada95c91a29e96a98dc5d2cd9a1fed039501ba6",
|
||||
strip_prefix = "pin-project-1.0.6",
|
||||
build_file = Label("//rules/rust/remote:BUILD.pin-project-1.0.6.bazel"),
|
||||
sha256 = "c7509cc106041c40a4518d2af7a61530e1eed0e6285296a3d8c5472806ccc4a4",
|
||||
strip_prefix = "pin-project-1.0.7",
|
||||
build_file = Label("//rules/rust/remote:BUILD.pin-project-1.0.7.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -2213,12 +2223,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__pin_project_internal__1_0_6",
|
||||
url = "https://crates.io/api/v1/crates/pin-project-internal/1.0.6/download",
|
||||
name = "raze__pin_project_internal__1_0_7",
|
||||
url = "https://crates.io/api/v1/crates/pin-project-internal/1.0.7/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "a490329918e856ed1b083f244e3bfe2d8c4f336407e4ea9e1a9f479ff09049e5",
|
||||
strip_prefix = "pin-project-internal-1.0.6",
|
||||
build_file = Label("//rules/rust/remote:BUILD.pin-project-internal-1.0.6.bazel"),
|
||||
sha256 = "48c950132583b500556b1efd71d45b319029f2b71518d979fcc208e16b42426f",
|
||||
strip_prefix = "pin-project-internal-1.0.7",
|
||||
build_file = Label("//rules/rust/remote:BUILD.pin-project-internal-1.0.7.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -2313,12 +2323,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__postgres_protocol__0_6_0",
|
||||
url = "https://crates.io/api/v1/crates/postgres-protocol/0.6.0/download",
|
||||
name = "raze__postgres_protocol__0_6_1",
|
||||
url = "https://crates.io/api/v1/crates/postgres-protocol/0.6.1/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "70e34ad3dc5c56d036b9418185ee97e14b6766d55c8ccf9dc18302ad4e6371d9",
|
||||
strip_prefix = "postgres-protocol-0.6.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.postgres-protocol-0.6.0.bazel"),
|
||||
sha256 = "ff3e0f70d32e20923cabf2df02913be7c1842d4c772db8065c00fcfdd1d1bff3",
|
||||
strip_prefix = "postgres-protocol-0.6.1",
|
||||
build_file = Label("//rules/rust/remote:BUILD.postgres-protocol-0.6.1.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -2333,12 +2343,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__postgres_types__0_2_0",
|
||||
url = "https://crates.io/api/v1/crates/postgres-types/0.2.0/download",
|
||||
name = "raze__postgres_types__0_2_1",
|
||||
url = "https://crates.io/api/v1/crates/postgres-types/0.2.1/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "5493d9d4613b88b12433aa12890e74e74cd93fdc1e08b7c2aed4768aaae8414c",
|
||||
strip_prefix = "postgres-types-0.2.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.postgres-types-0.2.0.bazel"),
|
||||
sha256 = "430f4131e1b7657b0cd9a2b0c3408d77c9a43a042d300b8c77f981dffcc43a2f",
|
||||
strip_prefix = "postgres-types-0.2.1",
|
||||
build_file = Label("//rules/rust/remote:BUILD.postgres-types-0.2.1.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -2373,12 +2383,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__proc_macro2__1_0_24",
|
||||
url = "https://crates.io/api/v1/crates/proc-macro2/1.0.24/download",
|
||||
name = "raze__proc_macro2__1_0_26",
|
||||
url = "https://crates.io/api/v1/crates/proc-macro2/1.0.26/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71",
|
||||
strip_prefix = "proc-macro2-1.0.24",
|
||||
build_file = Label("//rules/rust/remote:BUILD.proc-macro2-1.0.24.bazel"),
|
||||
sha256 = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec",
|
||||
strip_prefix = "proc-macro2-1.0.26",
|
||||
build_file = Label("//rules/rust/remote:BUILD.proc-macro2-1.0.26.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -2623,12 +2633,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__redox_syscall__0_2_5",
|
||||
url = "https://crates.io/api/v1/crates/redox_syscall/0.2.5/download",
|
||||
name = "raze__redox_syscall__0_2_6",
|
||||
url = "https://crates.io/api/v1/crates/redox_syscall/0.2.6/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9",
|
||||
strip_prefix = "redox_syscall-0.2.5",
|
||||
build_file = Label("//rules/rust/remote:BUILD.redox_syscall-0.2.5.bazel"),
|
||||
sha256 = "8270314b5ccceb518e7e578952f0b72b88222d02e8f77f5ecf7abbb673539041",
|
||||
strip_prefix = "redox_syscall-0.2.6",
|
||||
build_file = Label("//rules/rust/remote:BUILD.redox_syscall-0.2.6.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -2931,16 +2941,6 @@ def raze_fetch_remote_crates():
|
||||
build_file = Label("//rules/rust/remote:BUILD.serde_qs-0.8.3.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__serde_test__0_8_23",
|
||||
url = "https://crates.io/api/v1/crates/serde_test/0.8.23/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5",
|
||||
strip_prefix = "serde_test-0.8.23",
|
||||
build_file = Label("//rules/rust/remote:BUILD.serde_test-0.8.23.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__serde_urlencoded__0_7_0",
|
||||
@ -3003,12 +3003,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__signal_hook__0_3_7",
|
||||
url = "https://crates.io/api/v1/crates/signal-hook/0.3.7/download",
|
||||
name = "raze__signal_hook__0_3_8",
|
||||
url = "https://crates.io/api/v1/crates/signal-hook/0.3.8/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "6aa894ef3fade0ee7243422f4fbbd6c2b48e6de767e621d37ef65f2310f53cea",
|
||||
strip_prefix = "signal-hook-0.3.7",
|
||||
build_file = Label("//rules/rust/remote:BUILD.signal-hook-0.3.7.bazel"),
|
||||
sha256 = "ef33d6d0cd06e0840fba9985aab098c147e67e05cee14d412d3345ed14ff30ac",
|
||||
strip_prefix = "signal-hook-0.3.8",
|
||||
build_file = Label("//rules/rust/remote:BUILD.signal-hook-0.3.8.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3151,6 +3151,16 @@ def raze_fetch_remote_crates():
|
||||
build_file = Label("//rules/rust/remote:BUILD.socket2-0.3.19.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__socket2__0_4_0",
|
||||
url = "https://crates.io/api/v1/crates/socket2/0.4.0/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2",
|
||||
strip_prefix = "socket2-0.4.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.socket2-0.4.0.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__stable_deref_trait__1_2_0",
|
||||
@ -3273,12 +3283,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__syn__1_0_67",
|
||||
url = "https://crates.io/api/v1/crates/syn/1.0.67/download",
|
||||
name = "raze__syn__1_0_69",
|
||||
url = "https://crates.io/api/v1/crates/syn/1.0.69/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702",
|
||||
strip_prefix = "syn-1.0.67",
|
||||
build_file = Label("//rules/rust/remote:BUILD.syn-1.0.67.bazel"),
|
||||
sha256 = "48fe99c6bd8b1cc636890bcc071842de909d902c81ac7dab53ba33c421ab8ffb",
|
||||
strip_prefix = "syn-1.0.69",
|
||||
build_file = Label("//rules/rust/remote:BUILD.syn-1.0.69.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3483,12 +3493,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__tinyvec__1_1_1",
|
||||
url = "https://crates.io/api/v1/crates/tinyvec/1.1.1/download",
|
||||
name = "raze__tinyvec__1_2_0",
|
||||
url = "https://crates.io/api/v1/crates/tinyvec/1.2.0/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023",
|
||||
strip_prefix = "tinyvec-1.1.1",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tinyvec-1.1.1.bazel"),
|
||||
sha256 = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342",
|
||||
strip_prefix = "tinyvec-1.2.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tinyvec-1.2.0.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3533,12 +3543,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__tokio__1_4_0",
|
||||
url = "https://crates.io/api/v1/crates/tokio/1.4.0/download",
|
||||
name = "raze__tokio__1_5_0",
|
||||
url = "https://crates.io/api/v1/crates/tokio/1.5.0/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "134af885d758d645f0f0505c9a8b3f9bf8a348fd822e112ab5248138348f1722",
|
||||
strip_prefix = "tokio-1.4.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tokio-1.4.0.bazel"),
|
||||
sha256 = "83f0c8e7c0addab50b663055baf787d0af7f413a46e6e7fb9559a4e4db7137a5",
|
||||
strip_prefix = "tokio-1.5.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tokio-1.5.0.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3583,12 +3593,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__tokio_postgres__0_7_0",
|
||||
url = "https://crates.io/api/v1/crates/tokio-postgres/0.7.0/download",
|
||||
name = "raze__tokio_postgres__0_7_1",
|
||||
url = "https://crates.io/api/v1/crates/tokio-postgres/0.7.1/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "1cc9f82c2bfb06a33dd0dfb44b07ca98fe72df19e681d80c78d05a1bac2138e2",
|
||||
strip_prefix = "tokio-postgres-0.7.0",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tokio-postgres-0.7.0.bazel"),
|
||||
sha256 = "98779a950cb6ef76f8ad71c411176115c5c1200a83eeeca4dd9f61e3fc4836c8",
|
||||
strip_prefix = "tokio-postgres-0.7.1",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tokio-postgres-0.7.1.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3613,12 +3623,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__tokio_util__0_6_5",
|
||||
url = "https://crates.io/api/v1/crates/tokio-util/0.6.5/download",
|
||||
name = "raze__tokio_util__0_6_6",
|
||||
url = "https://crates.io/api/v1/crates/tokio-util/0.6.6/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "5143d049e85af7fbc36f5454d990e62c2df705b3589f123b71f441b6b59f443f",
|
||||
strip_prefix = "tokio-util-0.6.5",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tokio-util-0.6.5.bazel"),
|
||||
sha256 = "940a12c99365c31ea8dd9ba04ec1be183ffe4920102bb7122c2f515437601e8e",
|
||||
strip_prefix = "tokio-util-0.6.6",
|
||||
build_file = Label("//rules/rust/remote:BUILD.tokio-util-0.6.6.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3713,12 +3723,12 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__unicode_bidi__0_3_4",
|
||||
url = "https://crates.io/api/v1/crates/unicode-bidi/0.3.4/download",
|
||||
name = "raze__unicode_bidi__0_3_5",
|
||||
url = "https://crates.io/api/v1/crates/unicode-bidi/0.3.5/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5",
|
||||
strip_prefix = "unicode-bidi-0.3.4",
|
||||
build_file = Label("//rules/rust/remote:BUILD.unicode-bidi-0.3.4.bazel"),
|
||||
sha256 = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0",
|
||||
strip_prefix = "unicode-bidi-0.3.5",
|
||||
build_file = Label("//rules/rust/remote:BUILD.unicode-bidi-0.3.5.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
@ -3893,62 +3903,62 @@ def raze_fetch_remote_crates():
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__wasm_bindgen__0_2_72",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen/0.2.72/download",
|
||||
name = "raze__wasm_bindgen__0_2_73",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen/0.2.73/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "8fe8f61dba8e5d645a4d8132dc7a0a66861ed5e1045d2c0ed940fab33bac0fbe",
|
||||
strip_prefix = "wasm-bindgen-0.2.72",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-0.2.72.bazel"),
|
||||
sha256 = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9",
|
||||
strip_prefix = "wasm-bindgen-0.2.73",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-0.2.73.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__wasm_bindgen_backend__0_2_72",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-backend/0.2.72/download",
|
||||
name = "raze__wasm_bindgen_backend__0_2_73",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-backend/0.2.73/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "046ceba58ff062da072c7cb4ba5b22a37f00a302483f7e2a6cdc18fedbdc1fd3",
|
||||
strip_prefix = "wasm-bindgen-backend-0.2.72",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-backend-0.2.72.bazel"),
|
||||
sha256 = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae",
|
||||
strip_prefix = "wasm-bindgen-backend-0.2.73",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-backend-0.2.73.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__wasm_bindgen_macro__0_2_72",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-macro/0.2.72/download",
|
||||
name = "raze__wasm_bindgen_macro__0_2_73",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-macro/0.2.73/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "0ef9aa01d36cda046f797c57959ff5f3c615c9cc63997a8d545831ec7976819b",
|
||||
strip_prefix = "wasm-bindgen-macro-0.2.72",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-macro-0.2.72.bazel"),
|
||||
sha256 = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f",
|
||||
strip_prefix = "wasm-bindgen-macro-0.2.73",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-macro-0.2.73.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__wasm_bindgen_macro_support__0_2_72",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-macro-support/0.2.72/download",
|
||||
name = "raze__wasm_bindgen_macro_support__0_2_73",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-macro-support/0.2.73/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "96eb45c1b2ee33545a813a92dbb53856418bf7eb54ab34f7f7ff1448a5b3735d",
|
||||
strip_prefix = "wasm-bindgen-macro-support-0.2.72",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-macro-support-0.2.72.bazel"),
|
||||
sha256 = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c",
|
||||
strip_prefix = "wasm-bindgen-macro-support-0.2.73",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-macro-support-0.2.73.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__wasm_bindgen_shared__0_2_72",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-shared/0.2.72/download",
|
||||
name = "raze__wasm_bindgen_shared__0_2_73",
|
||||
url = "https://crates.io/api/v1/crates/wasm-bindgen-shared/0.2.73/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "b7148f4696fb4960a346eaa60bbfb42a1ac4ebba21f750f75fc1375b098d5ffa",
|
||||
strip_prefix = "wasm-bindgen-shared-0.2.72",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-shared-0.2.72.bazel"),
|
||||
sha256 = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489",
|
||||
strip_prefix = "wasm-bindgen-shared-0.2.73",
|
||||
build_file = Label("//rules/rust/remote:BUILD.wasm-bindgen-shared-0.2.73.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
http_archive,
|
||||
name = "raze__web_sys__0_3_49",
|
||||
url = "https://crates.io/api/v1/crates/web-sys/0.3.49/download",
|
||||
name = "raze__web_sys__0_3_50",
|
||||
url = "https://crates.io/api/v1/crates/web-sys/0.3.50/download",
|
||||
type = "tar.gz",
|
||||
sha256 = "59fe19d70f5dacc03f6e46777213facae5ac3801575d56ca6cbd4c93dcd12310",
|
||||
strip_prefix = "web-sys-0.3.49",
|
||||
build_file = Label("//rules/rust/remote:BUILD.web-sys-0.3.49.bazel"),
|
||||
sha256 = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be",
|
||||
strip_prefix = "web-sys-0.3.50",
|
||||
build_file = Label("//rules/rust/remote:BUILD.web-sys-0.3.50.bazel"),
|
||||
)
|
||||
|
||||
maybe(
|
||||
|
@ -67,8 +67,8 @@ rust_library(
|
||||
"@raze__bitflags__1_2_1//:bitflags",
|
||||
"@raze__bytes__0_5_6//:bytes",
|
||||
"@raze__crossbeam_channel__0_4_4//:crossbeam_channel",
|
||||
"@raze__futures_channel__0_3_13//:futures_channel",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_channel__0_3_14//:futures_channel",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__once_cell__1_7_2//:once_cell",
|
||||
"@raze__parking_lot__0_11_1//:parking_lot",
|
||||
|
@ -51,8 +51,8 @@ rust_library(
|
||||
deps = [
|
||||
"@raze__bitflags__1_2_1//:bitflags",
|
||||
"@raze__bytes__0_5_6//:bytes",
|
||||
"@raze__futures_core__0_3_13//:futures_core",
|
||||
"@raze__futures_sink__0_3_13//:futures_sink",
|
||||
"@raze__futures_core__0_3_14//:futures_core",
|
||||
"@raze__futures_sink__0_3_14//:futures_sink",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__tokio__0_2_25//:tokio",
|
||||
"@raze__tokio_util__0_2_0//:tokio_util",
|
||||
|
@ -51,8 +51,8 @@ rust_library(
|
||||
deps = [
|
||||
"@raze__bitflags__1_2_1//:bitflags",
|
||||
"@raze__bytes__0_5_6//:bytes",
|
||||
"@raze__futures_core__0_3_13//:futures_core",
|
||||
"@raze__futures_sink__0_3_13//:futures_sink",
|
||||
"@raze__futures_core__0_3_14//:futures_core",
|
||||
"@raze__futures_sink__0_3_14//:futures_sink",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__pin_project__0_4_28//:pin_project",
|
||||
"@raze__tokio__0_2_25//:tokio",
|
||||
|
@ -60,8 +60,8 @@ rust_library(
|
||||
"@raze__actix_service__1_0_6//:actix_service",
|
||||
"@raze__actix_utils__2_0_0//:actix_utils",
|
||||
"@raze__either__1_6_1//:either",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__http__0_2_3//:http",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__http__0_2_4//:http",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__trust_dns_proto__0_19_7//:trust_dns_proto",
|
||||
"@raze__trust_dns_resolver__0_19_7//:trust_dns_resolver",
|
||||
|
@ -55,10 +55,10 @@ rust_library(
|
||||
# buildifier: leave-alone
|
||||
deps = [
|
||||
"@raze__actix_web__3_3_2//:actix_web",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__once_cell__1_7_2//:once_cell",
|
||||
"@raze__tinyvec__1_1_1//:tinyvec",
|
||||
"@raze__tinyvec__1_2_0//:tinyvec",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -78,13 +78,13 @@ rust_library(
|
||||
"@raze__copyless__0_1_5//:copyless",
|
||||
"@raze__either__1_6_1//:either",
|
||||
"@raze__encoding_rs__0_8_28//:encoding_rs",
|
||||
"@raze__futures_channel__0_3_13//:futures_channel",
|
||||
"@raze__futures_core__0_3_13//:futures_core",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_channel__0_3_14//:futures_channel",
|
||||
"@raze__futures_core__0_3_14//:futures_core",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__fxhash__0_2_1//:fxhash",
|
||||
"@raze__h2__0_2_7//:h2",
|
||||
"@raze__http__0_2_3//:http",
|
||||
"@raze__httparse__1_3_5//:httparse",
|
||||
"@raze__http__0_2_4//:http",
|
||||
"@raze__httparse__1_4_0//:httparse",
|
||||
"@raze__indexmap__1_6_2//:indexmap",
|
||||
"@raze__itoa__0_4_7//:itoa",
|
||||
"@raze__language_tags__0_2_2//:language_tags",
|
||||
@ -92,7 +92,7 @@ rust_library(
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__mime__0_3_16//:mime",
|
||||
"@raze__percent_encoding__2_1_0//:percent_encoding",
|
||||
"@raze__pin_project__1_0_6//:pin_project",
|
||||
"@raze__pin_project__1_0_7//:pin_project",
|
||||
"@raze__rand__0_7_3//:rand",
|
||||
"@raze__regex__1_4_5//:regex",
|
||||
"@raze__serde__1_0_125//:serde",
|
||||
|
@ -50,7 +50,7 @@ rust_library(
|
||||
# buildifier: leave-alone
|
||||
deps = [
|
||||
"@raze__quote__1_0_9//:quote",
|
||||
"@raze__syn__1_0_67//:syn",
|
||||
"@raze__syn__1_0_69//:syn",
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -52,7 +52,7 @@ rust_library(
|
||||
# buildifier: leave-alone
|
||||
deps = [
|
||||
"@raze__bytestring__1_0_0//:bytestring",
|
||||
"@raze__http__0_2_3//:http",
|
||||
"@raze__http__0_2_4//:http",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__regex__1_4_5//:regex",
|
||||
"@raze__serde__1_0_125//:serde",
|
||||
|
@ -54,8 +54,8 @@ rust_library(
|
||||
deps = [
|
||||
"@raze__actix_threadpool__0_3_3//:actix_threadpool",
|
||||
"@raze__copyless__0_1_5//:copyless",
|
||||
"@raze__futures_channel__0_3_13//:futures_channel",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_channel__0_3_14//:futures_channel",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__smallvec__1_6_1//:smallvec",
|
||||
"@raze__tokio__0_2_25//:tokio",
|
||||
],
|
||||
|
@ -54,8 +54,8 @@ rust_library(
|
||||
"@raze__actix_rt__1_1_1//:actix_rt",
|
||||
"@raze__actix_service__1_0_6//:actix_service",
|
||||
"@raze__actix_utils__2_0_0//:actix_utils",
|
||||
"@raze__futures_channel__0_3_13//:futures_channel",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_channel__0_3_14//:futures_channel",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__mio__0_6_23//:mio",
|
||||
"@raze__mio_uds__0_6_8//:mio_uds",
|
||||
|
@ -53,7 +53,7 @@ rust_library(
|
||||
version = "1.0.6",
|
||||
# buildifier: leave-alone
|
||||
deps = [
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__pin_project__0_4_28//:pin_project",
|
||||
],
|
||||
)
|
||||
|
@ -52,7 +52,7 @@ rust_library(
|
||||
version = "0.3.3",
|
||||
# buildifier: leave-alone
|
||||
deps = [
|
||||
"@raze__futures_channel__0_3_13//:futures_channel",
|
||||
"@raze__futures_channel__0_3_14//:futures_channel",
|
||||
"@raze__lazy_static__1_4_0//:lazy_static",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__num_cpus__1_13_0//:num_cpus",
|
||||
|
@ -53,6 +53,6 @@ rust_library(
|
||||
"@raze__actix_codec__0_3_0//:actix_codec",
|
||||
"@raze__actix_service__1_0_6//:actix_service",
|
||||
"@raze__actix_utils__2_0_0//:actix_utils",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
],
|
||||
)
|
||||
|
@ -55,7 +55,7 @@ rust_library(
|
||||
"@raze__bitflags__1_2_1//:bitflags",
|
||||
"@raze__bytes__0_5_6//:bytes",
|
||||
"@raze__either__1_6_1//:either",
|
||||
"@raze__futures__0_3_13//:futures",
|
||||
"@raze__futures__0_3_14//:futures",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__pin_project__0_4_28//:pin_project",
|
||||
"@raze__slab__0_4_2//:slab",
|
||||
|
@ -55,9 +55,9 @@ rust_library(
|
||||
"@raze__bitflags__1_2_1//:bitflags",
|
||||
"@raze__bytes__0_5_6//:bytes",
|
||||
"@raze__either__1_6_1//:either",
|
||||
"@raze__futures_channel__0_3_13//:futures_channel",
|
||||
"@raze__futures_sink__0_3_13//:futures_sink",
|
||||
"@raze__futures_util__0_3_13//:futures_util",
|
||||
"@raze__futures_channel__0_3_14//:futures_channel",
|
||||
"@raze__futures_sink__0_3_14//:futures_sink",
|
||||
"@raze__futures_util__0_3_14//:futures_util",
|
||||
"@raze__log__0_4_14//:log",
|
||||
"@raze__pin_project__0_4_28//:pin_project",
|
||||
"@raze__slab__0_4_2//:slab",
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user