Merge pull request #28 from the-superpirate/master

- feat(nexus): Bump versions
This commit is contained in:
the-superpirate 2021-04-23 18:34:30 +03:00 committed by GitHub
commit 7daa6184d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
241 changed files with 5648 additions and 1746 deletions

3
.gitignore vendored
View File

@ -21,6 +21,3 @@ node_modules/
# Telethon session files
*.session
# IPFS collection for Cognitron
bafykbzacebzohi352bddfunaub5rgqv5b324nejk5v6fltjh45be5ykw5jsjg/

View File

@ -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/)

View File

@ -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()

View File

@ -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):

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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
View File

@ -0,0 +1 @@
data

View File

@ -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
```

View File

@ -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

View File

@ -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"

View File

@ -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,
)

View File

@ -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
})
}
}

View File

@ -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
})
}
}

View File

@ -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
) {}

View File

@ -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>

View File

@ -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]
}
}
}

View File

@ -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>

View File

@ -10,7 +10,7 @@ export default {
name: 'VHeader',
data () {
return {
search: ''
query: ''
}
}
}

View File

@ -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('; ')
}
}
}

View File

@ -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('; ')
}
}
}

View File

@ -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>

View File

@ -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: {

View File

@ -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>

View 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>

View File

@ -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 } })
}
}
}

View File

@ -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
}

View 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)
}

View File

@ -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`
}

View File

@ -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}`
}

View File

@ -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)
}

View File

@ -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) {

View File

@ -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()

View File

@ -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

View File

@ -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(

View 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
View File

@ -0,0 +1 @@
# Nexus Search: Meta API

View File

16
nexus/meta_api/cli.py Normal file
View 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))

View 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()

View 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:

View 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

View File

@ -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"],
)

View 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
View 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()

File diff suppressed because it is too large Load Diff

View File

@ -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"],
)

View File

@ -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) {}
}

View File

@ -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,

View File

@ -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,

View File

View 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_

View 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()

View 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"),
],
)

View 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}

View 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,
}

View 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']

View 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
"""

View 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 = "-"

View 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

View 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"),
],
)

View 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']))

View 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]')) == ''

View File

@ -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,
)

View File

@ -0,0 +1,3 @@
from .classic_rescorer import ClassicRescorer
__all__ = ['ClassicRescorer']

View 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()

View 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,
)

View 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'),
}

View 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)

View 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)

View File

@ -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"],
)

View File

@ -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...

View File

@ -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.

View File

@ -0,0 +1,11 @@
# Agenda
## Accessibility of Science
## Observability of Science
## Integrity Map of the Internet
## Automated Science
## Technology Alliance

View 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
View 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"

View File

@ -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"

View File

@ -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"

View File

@ -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",
]

View File

@ -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"

View File

@ -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",

View File

@ -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(

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",

View File

@ -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",
],
)

View File

@ -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",

View File

@ -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",
],
)

View File

@ -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",

View File

@ -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",
],

View File

@ -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",

View File

@ -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",
],
)

View File

@ -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",

View File

@ -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",
],
)

View File

@ -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",

View File

@ -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