From: Dessalines Date: Thu, 29 Aug 2019 23:14:28 +0000 (-0700) Subject: Adding emoji support. X-Git-Url: http://these/git/?a=commitdiff_plain;h=988eef2e6575f5e47b71489791ae0cb1b16730d8;hp=9cb10f7258ece889262f30ff4f3d6642acbb6882;p=lemmy.git Adding emoji support. --- diff --git a/.dockerignore b/.dockerignore index 73c47554..03466f0a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ ui/node_modules ui/dist server/target +docs .git diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..fa728e48 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +* linguist-vendored +*.rs linguist-vendored=false diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..e2aa0547 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +patreon: dessalines diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2feec03c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +ansible/inventory +ansible/passwords/ diff --git a/README.md b/README.md index 836a003b..4d2d9c90 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ -

Lemmy

+

Lemmy

+[![Github](https://img.shields.io/badge/-Github-blue)](https://github.com/dessalines/lemmy) +[![Gitlab](https://img.shields.io/badge/-Gitlab-yellowgreen)](https://gitlab.com/dessalines/lemmy) ![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/dessalines/lemmy.svg) [![Build Status](https://travis-ci.org/dessalines/lemmy.svg?branch=master)](https://travis-ci.org/dessalines/lemmy) -![Docker Cloud Build Status](https://img.shields.io/docker/cloud/build/dessalines/lemmy.svg) [![star this repo](http://githubbadges.com/star.svg?user=dessalines&repo=lemmy&style=flat)](https://github.com/dessalines/lemmy) [![fork this repo](http://githubbadges.com/fork.svg?user=dessalines&repo=lemmy&style=flat)](https://github.com/dessalines/lemmy/fork) -![Docker Pulls](https://img.shields.io/docker/pulls/dessalines/lemmy.svg) +[![Docker Pulls](https://img.shields.io/docker/pulls/dessalines/lemmy.svg)](https://cloud.docker.com/repository/docker/dessalines/lemmy/) [![GitHub issues](https://img.shields.io/github/issues-raw/dessalines/lemmy.svg)](https://github.com/dessalines/lemmy/issues) ![GitHub repo size](https://img.shields.io/github/repo-size/dessalines/lemmy.svg) ![GitHub commit activity](https://img.shields.io/github/commit-activity/m/dessalines/lemmy.svg) [![License](https://img.shields.io/github/license/dessalines/lemmy.svg)](LICENSE) -[![Mastodon](https://img.shields.io/badge/Mastodon-follow-lightgrey.svg)](https://mastodon.social/@LemmyDev) +[![Mastodon](https://img.shields.io/badge/Mastodon-@LemmyDev-lightgrey.svg)](https://mastodon.social/@LemmyDev) [![Matrix](https://img.shields.io/matrix/rust-reddit-fediverse:matrix.org.svg?label=matrix-chat)](https://riot.im/app/#/room/#rust-reddit-fediverse:matrix.org) [![Patreon](https://img.shields.io/badge/-Support%20on%20Patreon-blueviolet.svg)](https://www.patreon.com/dessalines) @@ -24,9 +25,10 @@ Front Page|Post ---|--- ![main screen](https://i.imgur.com/y64BtXC.png)|![chat screen](https://i.imgur.com/vsOr87q.png) ## Features + - Open source, [AGPL License](/LICENSE). - Self hostable, easy to deploy. - - Comes with [Docker](#docker), [Kubernetes](#kubernetes). + - Comes with [Docker](#docker), [Ansible](#ansible). - Live-updating Comment threads. - Full vote scores `(+/-)` like old reddit. - Moderation abilities. @@ -35,10 +37,16 @@ Front Page|Post - Can lock, remove, and restore posts and comments. - Can ban and unban users from communities and the site. - Clean, mobile-friendly interface. +- i18n / internationalization support. +- NSFW post / community support. +- Cross-posting support. +- Can transfer site and communities to others. - High performance. - Server is written in rust. - Front end is `~80kB` gzipped. + ## About + [Lemmy](https://github.com/dessalines/lemmy) is similar to sites like [Reddit](https://reddit.com), [Lobste.rs](https://lobste.rs), [Raddle](https://raddle.me), or [Hacker News](https://news.ycombinator.com/): you subscribe to forums you're interested in, post links and discussions, then vote, and comment on them. Behind the scenes, it is very different; anyone can easily run a server, and all these servers are federated (think email), and connected to the same universe, called the [Fediverse](https://en.wikipedia.org/wiki/Fediverse). For a link aggregator, this means a user registered on one server can subscribe to forums on any other server, and can have discussions with users registered elsewhere. @@ -48,70 +56,85 @@ The overall goal is to create an easily self-hostable, decentralized alternative Each lemmy server can set its own moderation policy; appointing site-wide admins, and community moderators to keep out the trolls, and foster a healthy, non-toxic environment where all can feel comfortable contributing. ## Why's it called Lemmy? + - Lead singer from [motorhead](https://invidio.us/watch?v=pWB5JZRGl0U). - The old school [video game](). - The [Koopa from Super Mario](https://www.mariowiki.com/Lemmy_Koopa). - The [furry rodents](http://sunchild.fpwc.org/lemming-the-little-giant-of-the-north/). Made with [Rust](https://www.rust-lang.org), [Actix](https://actix.rs/), [Inferno](https://www.infernojs.org), [Typescript](https://www.typescriptlang.org/) and [Diesel](http://diesel.rs/). + ## Install + ### Docker -Make sure you have both docker and docker-compose installed. -``` -git clone https://github.com/dessalines/lemmy -cd lemmy/docker +Make sure you have both docker and docker-compose(>=`1.24.0`) installed. + +```bash +mkdir lemmy/ +cd lemmy/ +wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/prod/docker-compose.yml +wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/prod/.env +# Edit the .env if you want custom passwords docker-compose up -d ``` and goto http://localhost:8536 -## Develop -### Docker Development -``` -git clone https://github.com/dessalines/lemmy -cd lemmy -./docker_update.sh # This pulls the newest version, builds and runs it -``` +[A sample nginx config](/docker/prod/nginx.conf), could be setup with: -and goto http://localhost:8536 -### Kubernetes -#### Requirements -- Local or remote Kubernetes cluster, i.e. [`minikube`](https://kubernetes.io/docs/tasks/tools/install-minikube/) -- [`kubectl`](https://kubernetes.io/docs/tasks/tools/install-kubectl/) -- [`skaffold`](https://skaffold.dev/) -#### Production ```bash -# Deploy the Traefik Ingress -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-rbac.yaml -kubectl apply -f https://raw.githubusercontent.com/containous/traefik/v1.7/examples/k8s/traefik-ds.yaml -# Replace ${IP} with your Ingress' IP -echo "${IP} dev.lemmy.local" >> /etc/hosts +wget https://raw.githubusercontent.com/dessalines/lemmy/master/docker/prod/nginx.conf +# Replace the {{ vars }} +sudo mv nginx.conf /etc/nginx/sites-enabled/lemmy.conf ``` +### Ansible + +First, you need to [install Ansible on your local computer](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html), +eg using `sudo apt install ansible`, or the equivalent for you platform. + +Then run the following commands on your local computer: + ```bash -skaffold run -p lemmy--prod +git clone https://github.com/dessalines/lemmy.git +cd lemmy/ansible/ +cp inventory.example inventory +nano inventory # enter your server, domain, contact email +ansible-playbook lemmy.yml ``` -Now go to http://dev.lemmy.local. -#### Development +## Develop + +### Docker Development + ```bash -skaffold dev -p lemmy--dev +git clone https://github.com/dessalines/lemmy +cd lemmy/docker/dev +./docker_update.sh # This builds and runs it, updating for your changes ``` -Now go to http://localhost:4444. It automatically proxies to localhost, both if the cluster is local or remote; it also hot-reloads the UI and automatically recompiles and restarts the server. +and goto http://localhost:8536 + ### Local Development + #### Requirements + - [Rust](https://www.rust-lang.org/) - [Yarn](https://yarnpkg.com/en/) -- [Postgres](https://www.sqlite.org/index.html) +- [Postgres](https://www.postgresql.org/) + #### Set up Postgres DB + +```bash + psql -c "create user lemmy with password 'password' superuser;" -U postgres + psql -c 'create database lemmy with owner lemmy;' -U postgres + export DATABASE_URL=postgres://lemmy:password@localhost:5432/lemmy ``` - psql -c "create user rrr with password 'rrr' superuser;" -U postgres - psql -c 'create database rrr with owner rrr;' -U postgres -``` + #### Running -``` + +```bash git clone https://github.com/dessalines/lemmy cd lemmy ./install.sh @@ -120,17 +143,41 @@ cd lemmy # cd server && cargo watch -x run ``` -and goto http://localhost:8536 ## Documentation + - [Websocket API for App developers](docs/api.md) - [ActivityPub API.md](docs/apub_api_outline.md) - [Goals](docs/goals.md) - [Ranking Algorithm](docs/ranking.md) + ## Support + Lemmy is free, open-source software, meaning no advertising, monetizing, or venture capital, ever. Your donations directly support full-time development of the project. - [Support on Patreon](https://www.patreon.com/dessalines). -- [Sponsor List](https://dev.lemmy.ml/#/sponsors). +- [Sponsor List](https://dev.lemmy.ml/sponsors). - bitcoin: `1Hefs7miXS5ff5Ck5xvmjKjXf5242KzRtK` - ethereum: `0x400c96c96acbC6E7B3B43B1dc1BB446540a88A01` +- monero: `41taVyY6e1xApqKyMVDRVxJ76sPkfZhALLTjRvVKpaAh2pBd4wv9RgYj1tSPrx8wc6iE1uWUfjtQdTmTy2FGMeChGVKPQuV` + +## Translations + +If you'd like to add translations, take a look a look at the [english translation file](ui/src/translations/en.ts). + +- Languages supported: English (`en`), Chinese (`zh`), Dutch (`nl`), Esperanto (`eo`), French (`fr`), Spanish (`es`), Swedish (`sv`), German (`de`), Russian (`ru`). + +### Report + +lang | done | missing +--- | --- | --- +de | 88% | cross_posts,cross_post,users,number_of_communities,settings,subscribed,expires,recent_comments,nsfw,show_nsfw,crypto,monero,joined,by,to,transfer_community,transfer_site,are_you_sure,yes,no +eo | 98% | number_of_communities,are_you_sure,yes,no +es | 98% | number_of_communities,are_you_sure,yes,no +fr | 91% | cross_posts,cross_post,users,number_of_communities,settings,recent_comments,nsfw,show_nsfw,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +nl | 100% | +ru | 93% | cross_posts,cross_post,number_of_communities,recent_comments,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +sv | 91% | cross_posts,cross_post,number_of_communities,settings,recent_comments,nsfw,show_nsfw,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no +zh | 91% | cross_posts,cross_post,users,number_of_communities,settings,recent_comments,nsfw,show_nsfw,monero,by,to,transfer_community,transfer_site,are_you_sure,yes,no + ## Credits -Icons made by [Freepik](https://www.freepik.com/) licensed by [CC 3.0](http://creativecommons.org/licenses/by/3.0/) + +Logo made by Andy Cuccaro (@andycuccaro) under the CC-BY-SA 4.0 license diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 00000000..960a7c40 --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,5 @@ +[defaults] +inventory=inventory + +[ssh_connection] +pipelining = True diff --git a/ansible/inventory.example b/ansible/inventory.example new file mode 100644 index 00000000..52b45d3c --- /dev/null +++ b/ansible/inventory.example @@ -0,0 +1,6 @@ +[lemmy] +# define the username and hostname that you use for ssh connection, and specify the domain +myuser@example.com domain=example.com letsencrypt_contact_email=your@email.com + +[all:vars] +ansible_connection=ssh diff --git a/ansible/lemmy.yml b/ansible/lemmy.yml new file mode 100644 index 00000000..4ba80e90 --- /dev/null +++ b/ansible/lemmy.yml @@ -0,0 +1,70 @@ +--- +- hosts: all + + # Install python if required + # https://www.josharcher.uk/code/ansible-python-connection-failure-ubuntu-server-1604/ + gather_facts: False + pre_tasks: + - name: install python for Ansible + raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal python-setuptools) + args: + executable: /bin/bash + register: output + changed_when: output.stdout != "" + - setup: # gather facts + + tasks: + - name: install dependencies + apt: + pkg: ['nginx', 'docker-compose', 'docker.io', 'certbot', 'python-certbot-nginx'] + + - name: request initial letsencrypt certificate + command: certbot certonly --nginx --agree-tos -d '{{ domain }}' -m '{{ letsencrypt_contact_email }}' + args: + creates: '/etc/letsencrypt/live/{{domain}}/privkey.pem' + + - name: create lemmy folder + file: path={{item.path}} state=directory + with_items: + - { path: '/lemmy/' } + - { path: '/lemmy/volumes/' } + + - name: add all template files + template: src={{item.src}} dest={{item.dest}} + with_items: + - { src: 'templates/env', dest: '/lemmy/.env' } + - { src: '../docker/prod/docker-compose.yml', dest: '/lemmy/docker-compose.yml' } + - { src: 'templates/nginx.conf', dest: '/etc/nginx/sites-enabled/lemmy.conf' } + vars: + postgres_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/postgres chars=ascii_letters,digits') }}" + jwt_password: "{{ lookup('password', 'passwords/{{ inventory_hostname }}/jwt chars=ascii_letters,digits') }}" + + - name: set env file permissions + file: + path: "/lemmy/.env" + state: touch + mode: 0600 + access_time: preserve + modification_time: preserve + + - name: enable and start docker service + systemd: + name: docker + enabled: yes + state: started + + - name: start docker-compose + docker_compose: + project_src: /lemmy/ + state: present + pull: yes + + - name: reload nginx with new config + shell: nginx -s reload + + - name: certbot renewal cronjob + cron: + special_time=daily + name=certbot-renew-lemmy + user=root + job="certbot certonly --nginx -d '{{ domain }}' --deploy-hook 'docker-compose -f /peertube/docker-compose.yml exec nginx nginx -s reload'" diff --git a/ansible/templates/env b/ansible/templates/env new file mode 100644 index 00000000..12ff8506 --- /dev/null +++ b/ansible/templates/env @@ -0,0 +1,4 @@ +DOMAIN={{ domain }} +DATABASE_PASSWORD={{ postgres_password }} +DATABASE_URL=postgres://lemmy:{{ postgres_password }}@db:5432/lemmy +JWT_SECRET={{ jwt_password }} diff --git a/ansible/templates/nginx.conf b/ansible/templates/nginx.conf new file mode 100644 index 00000000..74fbcda9 --- /dev/null +++ b/ansible/templates/nginx.conf @@ -0,0 +1,61 @@ +server { + listen 80; + server_name {{ domain }}; + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + server_name {{ domain }}; + + ssl_certificate /etc/letsencrypt/live/{{domain}}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{domain}}/privkey.pem; + + # Various TLS hardening settings + # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; + ssl_session_timeout 10m; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + + # Hide nginx version + server_tokens off; + + # Enable compression for JS/CSS/HTML bundle, for improved client load times. + # It might be nice to compress JSON, but leaving that out to protect against potential + # compression+encryption information leak attacks like BREACH. + gzip on; + gzip_types text/css application/javascript; + gzip_vary on; + + # Only connect to this site via HTTPS for the two years + add_header Strict-Transport-Security "max-age=63072000"; + + # Various content security headers + add_header Referrer-Policy "same-origin"; + add_header X-Content-Type-Options "nosniff"; + add_header X-Frame-Options "DENY"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + rewrite (\/(user|u\/|inbox|post|community|c\/|login|search|sponsors|communities|modlog|home)+) /static/index.html break; + proxy_pass http://0.0.0.0:8536; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 2b9f3171..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: '2.4' - -services: - db: - image: postgres - restart: always - environment: - POSTGRES_USER: rrr - POSTGRES_PASSWORD: rrr - POSTGRES_DB: rrr - healthcheck: - test: ["CMD-SHELL", "pg_isready -U rrr"] - interval: 5s - timeout: 5s - retries: 20 - lemmy: - build: - context: . - ports: - - "8536:8536" - environment: - LEMMY_FRONT_END_DIR: /app/dist - DATABASE_URL: postgres://rrr:rrr@db:5432/rrr - JWT_SECRET: changeme - HOSTNAME: rrr - restart: always - depends_on: - db: - condition: service_healthy diff --git a/docker/dev/.env b/docker/dev/.env new file mode 100644 index 00000000..f82502d7 --- /dev/null +++ b/docker/dev/.env @@ -0,0 +1,4 @@ +DOMAIN=my_domain +DATABASE_PASSWORD=password +DATABASE_URL=postgres://lemmy:password@lemmy_db:5432/lemmy +JWT_SECRET=changeme diff --git a/Dockerfile b/docker/dev/Dockerfile similarity index 96% rename from Dockerfile rename to docker/dev/Dockerfile index 0eb5f60d..69ef3aae 100644 --- a/Dockerfile +++ b/docker/dev/Dockerfile @@ -1,4 +1,5 @@ FROM node:10-jessie as node + WORKDIR /app/ui # Cache deps @@ -9,7 +10,7 @@ RUN yarn install --pure-lockfile COPY ui /app/ui RUN yarn build -FROM rust:latest as rust +FROM rust:1.37 as rust # Install musl RUN apt-get update @@ -34,7 +35,7 @@ RUN RUSTFLAGS=-Clinker=musl-gcc cargo build --frozen --release --target=x86_64-u # Get diesel-cli on there just in case # RUN cargo install diesel_cli --no-default-features --features postgres -FROM alpine:latest +FROM alpine:3.10 # Install libpq for postgres RUN apk add libpq diff --git a/docker/dev/deploy.sh b/docker/dev/deploy.sh new file mode 100755 index 00000000..5982318a --- /dev/null +++ b/docker/dev/deploy.sh @@ -0,0 +1,27 @@ +#!/bin/sh +git checkout master + +# Creating the new tag +new_tag="$1" +git tag $new_tag + +# Setting the version on the front end +pushd ../../ui/ +node set_version.js +git add src/version.ts +popd + +# Changing the docker-compose prod +sed -i "s/dessalines\/lemmy:.*/dessalines\/lemmy:$new_tag/" ../prod/docker-compose.yml +git add ../prod/docker-compose.yml + +# The commit +git commit -m"Upping version." + +git push origin $new_tag +git push + +# Rebuilding docker +./docker_update.sh +docker tag dev_lemmy:latest dessalines/lemmy:$new_tag +docker push dessalines/lemmy:$new_tag diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml new file mode 100644 index 00000000..b7ab8c2b --- /dev/null +++ b/docker/dev/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3.3' + +services: + lemmy_db: + image: postgres:12-alpine + environment: + - POSTGRES_USER=lemmy + - POSTGRES_PASSWORD=${DATABASE_PASSWORD} + - POSTGRES_DB=lemmy + volumes: + - lemmy_db:/var/lib/postgresql/data + lemmy: + build: + context: ../../ + dockerfile: docker/dev/Dockerfile + ports: + - "8536:8536" + environment: + - LEMMY_FRONT_END_DIR=/app/dist + - DATABASE_URL=${DATABASE_URL} + - JWT_SECRET=${JWT_SECRET} + - HOSTNAME=${DOMAIN} + depends_on: + - lemmy_db +volumes: + lemmy_db: diff --git a/docker_update.sh b/docker/dev/docker_update.sh similarity index 74% rename from docker_update.sh rename to docker/dev/docker_update.sh index 4a52b522..9d0f4542 100755 --- a/docker_update.sh +++ b/docker/dev/docker_update.sh @@ -1,5 +1,2 @@ #!/bin/sh -set -e - -git pull docker-compose up -d --no-deps --build diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index 4f5d51a9..00000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,28 +0,0 @@ -version: '2.4' - -services: - db: - image: postgres - restart: always - environment: - POSTGRES_USER: rrr - POSTGRES_PASSWORD: rrr - POSTGRES_DB: rrr - healthcheck: - test: ["CMD-SHELL", "pg_isready -U rrr"] - interval: 5s - timeout: 5s - retries: 20 - lemmy: - image: dessalines/lemmy:latest - ports: - - "8536:8536" - environment: - LEMMY_FRONT_END_DIR: /app/dist - DATABASE_URL: postgres://rrr:rrr@db:5432/rrr - JWT_SECRET: changeme - HOSTNAME: rrr - restart: always - depends_on: - db: - condition: service_healthy diff --git a/docker/docker_db_backup.sh b/docker/docker_db_backup.sh new file mode 100755 index 00000000..d42826e0 --- /dev/null +++ b/docker/docker_db_backup.sh @@ -0,0 +1 @@ +docker exec -it dev_lemmy_db_1 pg_dumpall -c -U rrr > dump_`date +%Y-%m-%d"_"%H_%M_%S`.sql diff --git a/docker/prod/.env b/docker/prod/.env new file mode 100644 index 00000000..f82502d7 --- /dev/null +++ b/docker/prod/.env @@ -0,0 +1,4 @@ +DOMAIN=my_domain +DATABASE_PASSWORD=password +DATABASE_URL=postgres://lemmy:password@lemmy_db:5432/lemmy +JWT_SECRET=changeme diff --git a/docker/prod/docker-compose.yml b/docker/prod/docker-compose.yml new file mode 100644 index 00000000..9e438cc9 --- /dev/null +++ b/docker/prod/docker-compose.yml @@ -0,0 +1,24 @@ +version: '3.3' + +services: + lemmy_db: + image: postgres:12-alpine + environment: + - POSTGRES_USER=lemmy + - POSTGRES_PASSWORD=${DATABASE_PASSWORD} + - POSTGRES_DB=lemmy + volumes: + - lemmy_db:/var/lib/postgresql/data + lemmy: + image: dessalines/lemmy:v0.0.8.7 + ports: + - "8536:8536" + environment: + - LEMMY_FRONT_END_DIR=/app/dist + - DATABASE_URL=${DATABASE_URL} + - JWT_SECRET=${JWT_SECRET} + - HOSTNAME=${DOMAIN} + depends_on: + - lemmy_db +volumes: + lemmy_db: diff --git a/docker/prod/nginx.conf b/docker/prod/nginx.conf new file mode 100644 index 00000000..918851a0 --- /dev/null +++ b/docker/prod/nginx.conf @@ -0,0 +1,61 @@ +server { + listen 80; + server_name {{ your domain }}; + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl http2; + server_name {{ your domain }}; + + ssl_certificate /etc/letsencrypt/live/{{ your domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ your domain }}/privkey.pem; + + # Various TLS hardening settings + # https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html + ssl_protocols TLSv1.2 TLSv1.3; + ssl_prefer_server_ciphers on; + ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; + ssl_session_timeout 10m; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + + # Hide nginx version + server_tokens off; + + # Enable compression for JS/CSS/HTML bundle, for improved client load times. + # It might be nice to compress JSON, but leaving that out to protect against potential + # compression+encryption information leak attacks like BREACH. + gzip on; + gzip_types text/css application/javascript; + gzip_vary on; + + # Only connect to this site via HTTPS for the two years + add_header Strict-Transport-Security "max-age=63072000"; + + # Various content security headers + add_header Referrer-Policy "same-origin"; + add_header X-Content-Type-Options "nosniff"; + add_header X-Frame-Options "DENY"; + add_header X-XSS-Protection "1; mode=block"; + + location / { + rewrite (\/(user|u|inbox|post|community|c|login|search|sponsors|communities|modlog|home)+) /static/index.html break; + proxy_pass http://0.0.0.0:8536; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # WebSocket support + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } +} diff --git a/docker_db_backup.sh b/docker_db_backup.sh deleted file mode 100755 index 5b87b818..00000000 --- a/docker_db_backup.sh +++ /dev/null @@ -1 +0,0 @@ -docker exec -it lemmy_db_1 pg_dumpall -c -U rrr > dump_`date +%d-%m-%Y"_"%H_%M_%S`.sql diff --git a/docs/api.md b/docs/api.md index 744de5f3..dd5f6d60 100644 --- a/docs/api.md +++ b/docs/api.md @@ -28,7 +28,8 @@ A simple test command: ## API ### List -`Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead` +`Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead, SaveUserSettings, TransferCommunity, +TransferSite` ### Sort Types These go wherever there is a `sort` field. @@ -109,7 +110,21 @@ Only the first user will be able to be the admin. posts: Vec, } ``` - +#### Save User Settings +##### Request +```rust +{ + show_nsfw: bool, + auth: String, +} +``` +##### Response +```rust +{ + op: String, + jwt: String +} +``` #### Get Replies / Inbox ##### Request ```rust @@ -320,6 +335,27 @@ Search types are `Both, Comments, Posts`. } ``` +#### Transfer Site +##### Request +```rust +{ + op: "TransferSite", + data: { + user_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + site: Option, + admins: Vec, + banned: Vec, +} +``` + ### Community #### Get Community ##### Request @@ -498,6 +534,28 @@ Mods and admins can remove and lock a community, creators can delete it. } ``` +#### Transfer Community +##### Request +```rust +{ + op: "TransferCommunity", + data: { + community_id: i32, + user_id: i32, + auth: String + } +} +``` +##### Response +```rust +{ + op: String, + community: CommunityView, + moderators: Vec, + admins: Vec, +} +``` + ### Post #### Create Post ##### Request diff --git a/docs/goals.md b/docs/goals.md index 0d92ab65..7ec3c490 100644 --- a/docs/goals.md +++ b/docs/goals.md @@ -23,7 +23,7 @@ - [Activitypub main](https://www.w3.org/TR/activitypub/) - [Diesel to Postgres data types](https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html) - [helpful diesel examples](http://siciarz.net/24-days-rust-diesel/) -- [Mastodan public key server example](https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/) +- [Mastodon public key server example](https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/) - [Recursive query for adjacency list for nested comments](https://stackoverflow.com/questions/192220/what-is-the-most-efficient-elegant-way-to-parse-a-flat-table-into-a-tree/192462#192462) - https://github.com/sparksuite/simplemde-markdown-editor - [Markdown-it](https://github.com/markdown-it/markdown-it) @@ -36,8 +36,10 @@ - [RES expando - Possibly make this into a switching react component.](https://github.com/honestbleeps/Reddit-Enhancement-Suite/tree/d21f55c21e734f47d8ed03fe0ebce5b16653b0bd/lib/modules/hosts) - [Temp Icon](https://www.flaticon.com/free-icon/mouse_194242) - [Rust docker build](https://shaneutt.com/blog/rust-fast-small-docker-image-builds/) +- [Zurb mentions](https://github.com/zurb/tribute) - Activitypub guides - https://blog.joinmastodon.org/2018/06/how-to-implement-a-basic-activitypub-server/ - https://raw.githubusercontent.com/w3c/activitypub/gh-pages/activitypub-tutorial.txt - https://github.com/tOkeshu/activitypub-example + - https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/ diff --git a/docs/ranking.md b/docs/ranking.md index 608b5484..361dc24d 100644 --- a/docs/ranking.md +++ b/docs/ranking.md @@ -5,7 +5,7 @@ - Use a log scale, since votes tend to snowball, and so the first 10 votes are just as important as the next hundred. ## Reddit Sorting -[Reddit's comment sorting algorithm](https://medium.com/hacking-and-gonzo/how-reddit-ranking-algorithms-work-ef111e33d0d9), the wilson confidence sort, is inadequate, because it completely ignores time. What ends up happening, especially in smaller subreddits, is that the early comments end up getting upvoted, and newer comments stay at the bottom, never to be seen. +[Reddit's comment sorting algorithm](https://medium.com/hacking-and-gonzo/how-reddit-ranking-algorithms-work-ef111e33d0d9), the wilson confidence sort, is inadequate, because it completely ignores time. What ends up happening, especially in smaller subreddits, is that the early comments end up getting upvoted, and newer comments stay at the bottom, never to be seen. Research showed that nearly all top comments are just the [first ones posted.](https://minimaxir.com/2016/11/first-comment/) ## Hacker News Sorting The [Hacker New's ranking algorithm](https://medium.com/hacking-and-gonzo/how-hacker-news-ranking-algorithm-works-1d9b0cf2c08d) is great, but it doesn't use a log scale for the scores. diff --git a/server/Cargo.lock b/server/Cargo.lock index 659bd235..72398c2a 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -2,20 +2,20 @@ # It is not intended for manual editing. [[package]] name = "activitypub" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "activitystreams-types 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "activitystreams-derive" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -29,209 +29,379 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "activitystreams-types" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "activitystreams-derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "actix" -version = "0.7.9" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "actix_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "actix_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "actix-net" -version = "0.2.6" +name = "actix-codec" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-connect" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "actix-web" -version = "0.7.18" +name = "actix-files" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-net 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "v_htmlescape 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-http" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-connect 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-threadpool 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-router" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-rt" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-threadpool 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-server" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-rt 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-server-config" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-service" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-threadpool" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-utils" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "actix-web" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-router 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-rt 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-server 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-threadpool 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-utils 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web-codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "awc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "v_htmlescape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "actix_derive" -version = "0.3.2" +name = "actix-web-actors" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "actix 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "adler32" -version = "1.0.3" +name = "actix-web-codegen" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] -name = "aho-corasick" -version = "0.6.10" +name = "actix_derive" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "arc-swap" -version = "0.3.7" +name = "adler32" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "arrayvec" -version = "0.4.10" +name = "aho-corasick" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "arc-swap" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "atty" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "autocfg" -version = "0.1.2" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "backtrace" -version = "0.3.14" +name = "awc" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-http 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "backtrace-sys" -version = "0.1.28" +name = "backtrace" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "base64" -version = "0.9.3" +name = "backtrace-sys" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -239,24 +409,24 @@ name = "base64" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bcrypt" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "blowfish 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "bitflags" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -264,7 +434,7 @@ name = "block-cipher-trait" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -273,7 +443,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -282,8 +452,8 @@ name = "brotli-sys" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -292,17 +462,12 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "build_const" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "byteorder" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -310,28 +475,38 @@ name = "bytes" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "c2-chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "cc" -version = "1.0.29" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "cfg-if" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chrono" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -340,34 +515,20 @@ name = "cloudabi" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "cookie" -version = "0.11.0" +name = "copyless" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crc" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "crc32fast" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -376,46 +537,40 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "crossbeam-epoch" -version = "0.7.1" +name = "crossbeam-utils" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "crossbeam-queue" -version = "0.1.2" +name = "derive_more" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "crossbeam-utils" -version = "0.6.5" +name = "derive_more" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -423,9 +578,9 @@ name = "diesel" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -435,9 +590,9 @@ name = "diesel_derives" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -451,15 +606,22 @@ dependencies = [ [[package]] name = "dotenv" -version = "0.9.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "dtoa" -version = "0.4.3" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "either" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -520,23 +682,33 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "env_logger" -version = "0.6.0" +name = "encoding_rs" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "error-chain" -version = "0.8.1" +name = "enum-as-inner" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "env_logger" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", + "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -544,7 +716,7 @@ name = "failure" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -553,21 +725,21 @@ name = "failure_derive" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "flate2" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -585,7 +757,7 @@ name = "fuchsia-zircon" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -596,49 +768,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "futures" -version = "0.1.25" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "futures-cpupool" -version = "0.1.8" +name = "generic-array" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "generic-array" -version = "0.12.0" +name = "getrandom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "h2" -version = "0.1.16" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "hashbrown" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "hashbrown" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "heck" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -646,23 +828,23 @@ name = "hostname" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "http" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "httparse" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -693,38 +875,37 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ipconfig" -version = "0.1.9" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "itoa" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "jsonwebtoken" -version = "5.0.1" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -746,44 +927,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "lazy_static" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazycell" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "lemmy_server" version = "0.0.1" dependencies = [ - "activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)", - "bcrypt 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "activitypub 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "actix 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-files 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "actix-web-actors 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "bcrypt 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dotenv 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonwebtoken 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonwebtoken 6.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", + "strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", + "strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "libc" -version = "0.2.49" +version = "0.2.60" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "linked-hash-map" -version = "0.4.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -795,20 +976,36 @@ dependencies = [ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "lock_api" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lock_api" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "log" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lru-cache" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -818,12 +1015,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "memchr" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "memoffset" -version = "0.2.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -849,7 +1041,7 @@ name = "mime" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -865,16 +1057,16 @@ dependencies = [ [[package]] name = "miniz-sys" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "miniz_oxide" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -882,27 +1074,26 @@ dependencies = [ [[package]] name = "miniz_oxide_c_api" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", + "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "mio" -version = "0.6.16" +version = "0.6.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -915,8 +1106,8 @@ version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -935,44 +1126,43 @@ name = "net2" version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nodrop" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "nom" -version = "4.2.2" +version = "4.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-integer" -version = "0.1.39" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "num-traits" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "num_cpus" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -997,16 +1187,65 @@ dependencies = [ "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "parking_lot" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1049,12 +1288,17 @@ dependencies = [ "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ppv-lite86" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "pq-sys" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1067,7 +1311,7 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "0.4.27" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1093,22 +1337,10 @@ dependencies = [ [[package]] name = "quote" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.5.6" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1116,17 +1348,29 @@ name = "rand" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1134,10 +1378,20 @@ name = "rand_chacha" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_chacha" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -1151,6 +1405,14 @@ name = "rand_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "rand_core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_hc" version = "0.1.0" @@ -1159,6 +1421,14 @@ dependencies = [ "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rand_isaac" version = "0.1.1" @@ -1169,25 +1439,25 @@ dependencies = [ [[package]] name = "rand_jitter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand_os" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1195,7 +1465,7 @@ name = "rand_pcg" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1217,55 +1487,27 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.1.51" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "0.2.11" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "regex" -version = "1.1.2" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.5" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1279,18 +1521,20 @@ dependencies = [ [[package]] name = "ring" -version = "0.13.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rustc-demangle" -version = "0.1.13" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1303,17 +1547,17 @@ dependencies = [ [[package]] name = "ryu" -version = "0.2.7" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] -name = "safemem" -version = "0.3.0" +name = "scopeguard" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "scopeguard" -version = "0.3.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1331,40 +1575,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.88" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive" -version = "1.0.88" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_json" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_urlencoded" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", + "dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1375,11 +1619,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "signal-hook" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook-registry 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "signal-hook-registry" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1394,20 +1647,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "smallvec" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "socket2" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "spin" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "stable_deref_trait" version = "1.1.1" @@ -1415,23 +1673,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "string" -version = "0.1.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "strum" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "strum_macros" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1456,11 +1717,11 @@ dependencies = [ [[package]] name = "syn" -version = "0.15.26" +version = "0.15.40" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1474,33 +1735,23 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "termcolor" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "termion" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "thread_local" version = "0.3.6" @@ -1510,36 +1761,21 @@ dependencies = [ ] [[package]] -name = "time" -version = "0.1.42" +name = "threadpool" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "tokio" -version = "0.1.16" +name = "time" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1548,36 +1784,26 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-current-thread" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-executor" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-fs" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1586,8 +1812,8 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1596,16 +1822,16 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1613,24 +1839,24 @@ name = "tokio-signal" version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-sync" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1639,38 +1865,22 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tokio-threadpool" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "tokio-timer" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1679,101 +1889,54 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "tokio-uds" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "tower-service" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "trust-dns-proto" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "trust-dns-proto" -version = "0.6.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "enum-as-inner 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "trust-dns-resolver" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "ipconfig 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", + "ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "trust-dns-proto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1783,7 +1946,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ucd-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1796,7 +1959,7 @@ dependencies = [ [[package]] name = "unicase" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1815,12 +1978,12 @@ name = "unicode-normalization" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "unicode-segmentation" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1851,50 +2014,41 @@ dependencies = [ [[package]] name = "utf8-ranges" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "uuid" -version = "0.7.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] [[package]] name = "v_escape" -version = "0.3.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "v_escape_derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "v_escape_derive 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "v_escape_derive" -version = "0.2.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "nom 4.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "v_htmlescape" -version = "0.3.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "v_escape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "v_escape 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "vcpkg" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1904,7 +2058,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "widestring" -version = "0.2.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1914,7 +2068,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "winapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1936,7 +2090,7 @@ name = "winapi-util" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1949,16 +2103,16 @@ name = "wincolor" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "winreg" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1966,7 +2120,7 @@ name = "winutil" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1979,50 +2133,60 @@ dependencies = [ ] [metadata] -"checksum activitypub 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08018b04725f5107d4a64e850f8a44a1f8a7e72abf0ca09125e3054921d26fd9" -"checksum activitystreams-derive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "48db826c588a009960d74530e7c215e21fae130f585362504dc6b6357e5ce86b" +"checksum activitypub 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dbb11d9099278667d3723c6491f25ea34dcae3eb54d73070e665d312c4455b25" +"checksum activitystreams-derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "176bdecfca82b1980e4769e3d54b6a392284b724083e0bff68272e290f17458f" "checksum activitystreams-traits 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "670ef03168e704b0cae242e7a5d8b40506772b339687e01a3496fc4afe2e8542" -"checksum activitystreams-types 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "224d1e28d043f4275139445475da8866f0a430ecfc9047c9a15fbe3c70c22b04" -"checksum actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c616db5fa4b0c40702fb75201c2af7f8aa8f3a2e2c1dda3b0655772aa949666" -"checksum actix-net 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8bebfbe6629e0131730746718c9e032b58f02c6ce06ed7c982b9fef6c8545acd" -"checksum actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e9f33c941e5e69a58a6bfef33853228042ed3799fc4b5a4923a36a85776fb690" -"checksum actix_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4300e9431455322ae393d43a2ba1ef96b8080573c0fc23b196219efedfb6ba69" +"checksum activitystreams-types 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ff74c5765278614a009f97b9ec12f9a7c732bbcc5e0337fcfcab619b784860ec" +"checksum actix 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "671ce3d27313f236827a5dd153a1073ad03ef31fc77f562020263e7830cf1ef7" +"checksum actix-codec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2c11af4b06dc935d8e1b1491dad56bfb32febc49096a91e773f8535c176453" +"checksum actix-connect 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d161322a26e6b76d6598f48654afbdcfee644c900d4368e9962ec68abd0713b" +"checksum actix-files 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f1e4640b28cd96059541c932f6f350c63c76688e43d68305cdb88e0004da12b5" +"checksum actix-http 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "59698e11ceb42ea16a2e491bd5a9b48adc7268323a5b600522d408d09783828c" +"checksum actix-router 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "23224bb527e204261d0291102cb9b52713084def67d94f7874923baefe04ccf7" +"checksum actix-rt 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "18d9054b1cfacfa441846b9b99001010cb8fbb02130e6cfdb25cea36d3e98e87" +"checksum actix-server 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb3038e9e457e0a498ea682723e0f4e6cc2c4f362a1868d749808355275ad959" +"checksum actix-server-config 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "483a34989c682d93142bacad6300375bb6ad8002d2e0bb249dbad86128b9ff30" +"checksum actix-service 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aaecc01bbc595ebd7a563a7d4f8a607d0b964bb55273c6f362b0b02c26508cf2" +"checksum actix-threadpool 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1c29f7c554d56b3841f4bb85d5b3dee01ba536e1307679f56eb54de28aaec3fb" +"checksum actix-utils 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6ea501068a0173533704be321f149853f702d9e3c3ce9d57e7a96d94b1ab5aca" +"checksum actix-web 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0147b2fd52ced64145c8370af627f12f098222a1c6ba67d021e21cd0d806f574" +"checksum actix-web-actors 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "008c1b686048a16fef4ef2fc6b6e5fcf5f29829891ad87fc0848ade26b285627" +"checksum actix-web-codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe9e3cdec1e645b675f354766e0688c5705021c85ab3cf739be1c8999b91c76" +"checksum actix_derive 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0bf5f6d7bf2d220ae8b4a7ae02a572bb35b7c4806b24049af905ab8110de156c" "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" -"checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" -"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" -"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" +"checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282" +"checksum arc-swap 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "bc4662175ead9cd84451d5c35070517777949a2ed84551764129cedb88384841" +"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" +"checksum autocfg 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "22130e92352b948e7e82a49cdb0aa94f2211761117f29e052dd397c1ac33542b" +"checksum awc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4c4763e6aa29a801d761dc3464f081d439ea5249ba90c3c3bdfc8dd3f739d233" +"checksum backtrace 0.3.33 (registry+https://github.com/rust-lang/crates.io-index)" = "88fb679bc9af8fa639198790a77f52d345fe13656c08b43afa9424c206b731c6" +"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bcrypt 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2a426ab63025c1d21e4e12a218c915fa22097b89ab7ed5765fa803101e004b27" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" +"checksum bcrypt 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4fd6a91ff640809cfab4ea74312a892238a7bbae53adbf717b71122deb0c85" +"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774" "checksum blowfish 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6aeb80d00f2688459b8542068abd974cfb101e7a82182414a99b5026c0d85cc3" "checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" "checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" +"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" -"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" -"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" +"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" +"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d" +"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" +"checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf" -"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" +"checksum copyless 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6ff9c56c9fb2a49c05ef0e431485a22400af20d33226dc0764d891d09e724127" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" "checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" -"checksum crossbeam-deque 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b18cd2e169ad86297e6bc0ad9aa679aee9daa4f19e8163860faf7c164e4f5a71" -"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" +"checksum derive_more 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6d944ac6003ed268757ef1ee686753b57efc5fcf0ebe7b64c9fc81e7e32ff839" +"checksum derive_more 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a141330240c921ec6d074a3e188a7c7ef95668bb95e7d44fa0e5778ec2a7afe" "checksum diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d24935ba50c4a8dc375a0fd1f8a2ba6bdbdc4125713126a74b965d6a01a06d7" "checksum diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "62a27666098617d52c487a41f70de23d44a1dc1f3aa5877ceba2790fb1f1cab4" "checksum diesel_migrations 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3cde8413353dc7f5d72fa8ce0b99a560a359d2c5ef1e5817ca731cd9008f4c" -"checksum dotenv 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "400b347fe65ccfbd8f545c9d9a75d04b0caf23fec49aaa838a9a05398f94c019" -"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" +"checksum dotenv 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4424bad868b0ffe6ae351ee463526ba625bbca817978293bbe6bb7dc1804a175" +"checksum dtoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ea57b42383d091c85abcc2706240b94ab2a8fa1fc81c10ff23c4de06e2a90b5e" +"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" "checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" "checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" "checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" @@ -2030,168 +2194,170 @@ dependencies = [ "checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -"checksum env_logger 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afb070faf94c85d17d50ca44f6ad076bce18ae92f0037d350947240a36e9d42e" -"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" +"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed" +"checksum enum-as-inner 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d58266c97445680766be408285e798d3401c6d4c378ec5552e78737e681e37d" +"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" -"checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4" +"checksum flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "550934ad4808d5d39365e5d61727309bf18b3b02c6c56b729cb92e7dd84bc3d8" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum generic-array 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c0f28c2f5bfb5960175af447a2da7c18900693738343dc896ffbcabd9839592" -"checksum h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb2b25a33e231484694267af28fec74ac63b5ccf51ee2065a5e313b834d836e" +"checksum futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "45dc39533a6cae6da2b56da48edae506bb767ec07370f86f70fc062e9d435869" +"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" +"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" +"checksum h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "a539b63339fbbb00e081e84b6e11bd1d9634a82d91da2984a18ac74a8823f392" +"checksum hashbrown 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "29fba9abe4742d586dfd0c06ae4f7e73a1c2d86b856933509b269d82cdf06e18" +"checksum hashbrown 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e1de41fb8dba9714efd92241565cdff73f78508c95697dd56787d3cba27e2353" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" -"checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" -"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" +"checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a" +"checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" "checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum ipconfig 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "08f7eadeaf4b52700de180d147c4805f199854600b36faa963d91114827b2ffc" -"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum jsonwebtoken 5.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8d438ea707d465c230305963b67f8357a1d56fcfad9434797d7cb1c46c2e41df" +"checksum ipconfig 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" +"checksum jsonwebtoken 6.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a81d1812d731546d2614737bee92aa071d37e9afa1409bc374da9e5e70e70b22" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e" -"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" +"checksum libc 0.2.60 (registry+https://github.com/rust-lang/crates.io-index)" = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" +"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" +"checksum lock_api 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8912e782533a93a167888781b836336a6ca5da6175c05944c86cf28c31104dc" +"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3" +"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" +"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" "checksum migrations_internals 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8089920229070f914b9ce9b07ef60e175b2b9bc2d35c3edd8bf4433604e863b9" "checksum migrations_macros 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1664412abf7db2b8a6d58be42a38b099780cc542b5b350383b805d88932833fe" "checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425" "checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" -"checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649" -"checksum miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c468f2369f07d651a5d0bb2c9079f8488a66d5466efe42d0c5c6466edcb7f71e" -"checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab" -"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" +"checksum miniz-sys 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9e3ae51cea1576ceba0dde3d484d30e6e5b86dee0b2d412fe3a16a15c98202" +"checksum miniz_oxide 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c061edee74a88eb35d876ce88b94d77a0448a201de111c244b70d047f5820516" +"checksum miniz_oxide_c_api 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6c675792957b0d19933816c4e1d56663c341dd9bfa31cb2140ff2267c1d8ecf4" +"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23" "checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nom 4.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22293d25d3f33a8567cc8a1dc20f40c7eeb761ce83d0fcca059858580790cac3" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" +"checksum nom 4.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6" +"checksum num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09" +"checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" +"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" +"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" +"checksum parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" +"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" +"checksum parking_lot_core 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" "checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" "checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" "checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" "checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" +"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b" "checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda" "checksum proc-macro2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1b06e2f335f48d24442b35a19df506a835fb3547bc3c06ef27340da9acf5cae7" -"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" +"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" +"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +"checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c" "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +"checksum rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e193067942ef6f485a349a113329140d0ab9e2168ce92274499bb0e9a4190d9d" "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" +"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" -"checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d" +"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "53ee8cfdddb2e0291adfb9f13d31d3bbe0a03c9a402c01b1e24188d86c35b24f" -"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" +"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" +"checksum regex 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b23da8dfd98a84bd7e08700190a5d9f7d2d38abd4369dd1dae651bc40bfd2cc" +"checksum regex-syntax 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5485bf1523a9ed51c4964273f22f63f24e31632adb5dad134f488f86a3875c" "checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" -"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" -"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" +"checksum ring 0.14.6 (registry+https://github.com/rust-lang/crates.io-index)" = "426bc186e3e95cac1e4a4be125a4aca7e84c2d616ffc02244eef36e2a60a093c" +"checksum rustc-demangle 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "a7f4dccf6f4891ebcc0c39f9b6eb1a83b9bf5d747cb439ec6fba4f3b977038af" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" +"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850" -"checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4" -"checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" -"checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" +"checksum serde 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "d46b3dfedb19360a74316866cef04687cd4d6a70df8e6a506c63512790769b72" +"checksum serde_derive 1.0.97 (registry+https://github.com/rust-lang/crates.io-index)" = "c22a0820adfe2f257b098714323563dd06426502abbbce4f51b72ef544c5027f" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" +"checksum serde_urlencoded 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" "checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum signal-hook 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "97a47ae722318beceb0294e6f3d601205a1e6abaa4437d9d33e3a212233e3021" +"checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68" +"checksum signal-hook-registry 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cded4ffa32146722ec54ab1f16320568465aa922aa9ab4708129599740da85d7" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" -"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" +"checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" +"checksum socket2 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4e626972d3593207547f14bf5fc9efa4d0e7283deb73fef1dff313dae9ab8878" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" "checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" -"checksum strum 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1810e25f576e7ffce1ff5243b37066da5ded0310b3274c20baaeccb1145b2806" -"checksum strum_macros 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "572a2f4e53dd4c3483fd79e5cc10ddd773a3acb1169bbfe8762365e107110579" +"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" +"checksum strum 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d1c33039533f051704951680f1adfd468fd37ac46816ded0d9ee068e60f05f" +"checksum strum_macros 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "47cd23f5c7dee395a00fa20135e2ec0fffcdfa151c56182966d7a3261343432e" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.13.11 (registry+https://github.com/rust-lang/crates.io-index)" = "14f9bf6292f3a61d2c716723fdb789a41bbe104168e6f496dc6497e531ea1b9b" -"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" +"checksum syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)" = "bc945221ccf4a7e8c31222b9d1fc77aefdd6638eb901a6ce457a3dc29d4c31e8" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" -"checksum termcolor 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4096add70612622289f2fdcdbd5086dc81c1e2675e6ae58d6c4f62a16c6d7f2f" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" +"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f" +"checksum termcolor 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "96d6098003bde162e4277c70665bd87c326f5a0c3f3fbfb285787fa482d54e6e" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" +"checksum threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e2f0c90a5f3459330ac8bc0d2f879c693bb7a2f59689c1083fc4ef83834da865" "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tokio 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fcaabb3cec70485d0df6e9454fe514393ad1c4070dee8915f11041e95630b230" "checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-current-thread 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c756b04680eea21902a46fca4e9f410a2332c04995af590e07ff262e2193a9a3" -"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" -"checksum tokio-fs 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "3fe6dc22b08d6993916647d108a1a7d15b9cd29c4f4496c62b92c45b5041b7af" +"checksum tokio-current-thread 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "d16217cad7f1b840c5a97dfb3c43b0c871fef423a6e8d2118c604e843662a443" +"checksum tokio-executor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f27ee0e6db01c5f0b2973824547ce7e637b2ed79b891a9677b0de9bd532b6ac" "checksum tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" "checksum tokio-reactor 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6af16bfac7e112bea8b0442542161bfc41cbfa4466b580bdda7d18cb88b911ce" "checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" -"checksum tokio-sync 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1bf2b9dac2a0509b5cfd1df5aa25eafacb616a42a491a13604d6bbeab4486363" +"checksum tokio-sync 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2162248ff317e2bc713b261f242b69dbb838b85248ed20bb21df56d60ea4cae7" "checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "742e511f6ce2298aeb86fc9ea0d8df81c2388c6ebae3dc8a7316e8c9df0df801" -"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" +"checksum tokio-timer 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f2106812d500ed25a4f38235b9cae8f78a09edf43203e16e59c3b769a342a60e" "checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" -"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum tower-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b32f72af77f1bfe3d3d4da8516a238ebe7039b51dd8637a09841ac7f16d2c987" -"checksum trust-dns-proto 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0838272e89f1c693b4df38dc353412e389cf548ceed6f9fd1af5a8d6e0e7cf74" -"checksum trust-dns-proto 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09144f0992b0870fa8d2972cc069cbf1e3c0fda64d1f3d45c4d68d0e0b52ad4e" -"checksum trust-dns-resolver 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a9f877f7a1ad821ab350505e1f1b146a4960402991787191d6d8cab2ce2de2c" +"checksum trust-dns-proto 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5559ebdf6c2368ddd11e20b11d6bbaf9e46deb803acd7815e93f5a7b4a6d2901" +"checksum trust-dns-resolver 0.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c9992e58dba365798803c0b91018ff6c8d3fc77e06977c4539af2a6bfe0a039" "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" +"checksum ucd-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fa9b3b49edd3468c0e6565d85783f51af95212b6fa3986a5500954f00b460874" "checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90" +"checksum unicase 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a84e5511b2a947f3ae965dcb29b13b7b1691b6e7332cf5dbc1744138d5acb7f6" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" "checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" +"checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" "checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" "checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" "checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" -"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" -"checksum v_escape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b50688edb86f4c092a1a9fe8bda004b0faa3197100897653809e97e09a2814" -"checksum v_escape_derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7cd994c63b487fef7aad31e5394ec04b9e24de7b32ea5251c9fb499cd2cbf44c" -"checksum v_htmlescape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "020cae817dc82693aa523f01087b291b1c7a9ac8cea5c12297963f21769fb27f" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" +"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" +"checksum v_escape 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8865501b78eef9193c1b45486acf18ba889e5662eba98854d6fc59d8ecf3542d" +"checksum v_escape_derive 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "306896ff4b75998501263a1dc000456de442e21d68fe8c8bdf75c66a33a58e23" +"checksum v_htmlescape 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7fbbe0fa88dd36f9c8cf61a218d4b953ba669de4d0785832f33cc72bd081e1be" +"checksum vcpkg 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "33dd455d0f96e90a75803cfeb7f948768c08d70a6de9a8d2362461935698bf95" "checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7157704c2e12e3d2189c507b7482c52820a16dfa4465ba91add92f266667cadb" +"checksum widestring 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "effc0e4ff8085673ea7b9b2e3c73f6bd4d118810c9009ed8f1e16bd96c331db6" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" +"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" "checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "561ed901ae465d6185fa7864d63fbd5720d0ef718366c9a4dc83cf6170d7e9ba" -"checksum winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a27a759395c1195c4cc5cda607ef6f8f6498f64e78f7900f5de0a127a424704a" +"checksum winreg 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73f1f3c6c4d3cab118551b96c476a2caab920701e28875b64a458f2ecb96ec9d" "checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" diff --git a/server/Cargo.toml b/server/Cargo.toml index 5ee8b8a6..6c50c695 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -2,23 +2,27 @@ name = "lemmy_server" version = "0.0.1" authors = ["Dessalines "] +edition = "2018" [dependencies] diesel = { version = "1.4.2", features = ["postgres","chrono"] } -diesel_migrations = "*" -dotenv = "0.9.0" -bcrypt = "0.3" -activitypub = "0.1.4" -chrono = { version = "0.4", features = ["serde"] } +diesel_migrations = "1.4.0" +dotenv = "0.14.1" +bcrypt = "0.5.0" +activitypub = "0.1.5" +chrono = { version = "0.4.7", features = ["serde"] } failure = "0.1.5" -serde_json = "*" -serde = { version = "1.0", features = ["derive"] } -actix = "*" -actix-web = "*" -env_logger = "*" -rand = "0.6.5" -strum = "0.14.0" -strum_macros = "0.14.0" -jsonwebtoken = "*" -regex = "*" -lazy_static = "*" +serde_json = "1.0.40" +serde = { version = "1.0.94", features = ["derive"] } +actix = "0.8.3" +actix-web = "1.0" +actix-files = "0.1.3" +actix-web-actors = "1.0" +env_logger = "0.6.2" +rand = "0.7.0" +strum = "0.15.0" +strum_macros = "0.15.0" +jsonwebtoken = "6.0.1" +regex = "1.1.9" +lazy_static = "1.3.0" + diff --git a/server/Dockerfile.dev b/server/Dockerfile.dev deleted file mode 100644 index 203dd742..00000000 --- a/server/Dockerfile.dev +++ /dev/null @@ -1,28 +0,0 @@ -# Setup env -FROM rust:1.33 AS build -RUN USER=root cargo new --bin /opt/lemmy/server--dev -WORKDIR /opt/lemmy/server--dev -# Enable deps caching -RUN mkdir -p src/bin -RUN echo 'fn main() { println!("Dummy") }' >src/bin/main.rs -# Install deps -COPY Cargo.toml . -COPY Cargo.lock . -RUN cargo build --release -RUN rm src/bin/main.rs -# Add app -COPY src/ src/ -COPY migrations/ migrations/ -RUN rm target/release/deps/lemmy* -RUN cargo build --release - -# Setup env (no Alpine because Rust requires glibc) -FROM ubuntu:18.04 -RUN apt update -RUN apt install postgresql-client -y -# Create empty directory where the frontend would normally be -RUN mkdir -p /opt/lemmy/ui--dev/dist -# Add app -COPY --from=build /opt/lemmy/server--dev/target/release/lemmy . -# Run app -CMD ["./lemmy"] diff --git a/server/Dockerfile.prod b/server/Dockerfile.prod deleted file mode 100644 index b375e478..00000000 --- a/server/Dockerfile.prod +++ /dev/null @@ -1,28 +0,0 @@ -# Setup env -FROM rust:1.33 AS build -RUN USER=root cargo new --bin /opt/lemmy/server--prod -WORKDIR /opt/lemmy/server--prod -# Enable deps caching -RUN mkdir -p src/bin -RUN echo 'fn main() { println!("Dummy") }' >src/bin/main.rs -# Install deps -COPY Cargo.toml . -COPY Cargo.lock . -RUN cargo build --release -RUN rm src/bin/main.rs -# Add app -COPY src/ src/ -COPY migrations/ migrations/ -RUN rm target/release/deps/lemmy* -RUN cargo build --release - -# Setup env (no Alpine because Rust requires glibc) -FROM ubuntu:18.04 -RUN apt update -RUN apt install postgresql-client -y -# Create empty directory where the frontend would normally be -RUN mkdir -p /opt/lemmy/ui--prod/dist -# Add app -COPY --from=build /opt/lemmy/server--prod/target/release/lemmy . -# Run app -CMD ["./lemmy"] diff --git a/server/migrations/2019-06-01-222649_remove_admin/down.sql b/server/migrations/2019-06-01-222649_remove_admin/down.sql new file mode 100644 index 00000000..6178857f --- /dev/null +++ b/server/migrations/2019-06-01-222649_remove_admin/down.sql @@ -0,0 +1 @@ +insert into user_ (name, fedi_name, password_encrypted) values ('admin', 'TBD', 'TBD'); diff --git a/server/migrations/2019-06-01-222649_remove_admin/up.sql b/server/migrations/2019-06-01-222649_remove_admin/up.sql new file mode 100644 index 00000000..7cec8870 --- /dev/null +++ b/server/migrations/2019-06-01-222649_remove_admin/up.sql @@ -0,0 +1 @@ +delete from user_ where name like 'admin'; diff --git a/server/migrations/2019-08-11-000918_add_nsfw_columns/down.sql b/server/migrations/2019-08-11-000918_add_nsfw_columns/down.sql new file mode 100644 index 00000000..2eefece4 --- /dev/null +++ b/server/migrations/2019-08-11-000918_add_nsfw_columns/down.sql @@ -0,0 +1,80 @@ +drop view community_view; +drop view post_view; +alter table community drop column nsfw; +alter table post drop column nsfw; +alter table user_ drop column show_nsfw; + +-- the views +create view community_view as +with all_community as +( + select *, + (select name from user_ u where c.creator_id = u.id) as creator_name, + (select name from category ct where c.category_id = ct.id) as category_name, + (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, + (select count(*) from post p where p.community_id = c.id) as number_of_posts, + (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, + hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank + from community c +) + +select +ac.*, +u.id as user_id, +(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed +from user_ u +cross join all_community ac + +union all + +select +ac.*, +null as user_id, +null as subscribed +from all_community ac +; + + +-- Post view +create view post_view as +with all_post as +( + select + p.*, + (select name from user_ where p.creator_id = user_.id) as creator_name, + (select name from community where p.community_id = community.id) as community_name, + (select removed from community c where p.community_id = c.id) as community_removed, + (select deleted from community c where p.community_id = c.id) as community_deleted, + (select count(*) from comment where comment.post_id = p.id) as number_of_comments, + coalesce(sum(pl.score), 0) as score, + count (case when pl.score = 1 then 1 else null end) as upvotes, + count (case when pl.score = -1 then 1 else null end) as downvotes, + hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank + from post p + left join post_like pl on p.id = pl.post_id + group by p.id +) + +select +ap.*, +u.id as user_id, +coalesce(pl.score, 0) as my_vote, +(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, +(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, +(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved +from user_ u +cross join all_post ap +left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id + +union all + +select +ap.*, +null as user_id, +null as my_vote, +null as subscribed, +null as read, +null as saved +from all_post ap +; + diff --git a/server/migrations/2019-08-11-000918_add_nsfw_columns/up.sql b/server/migrations/2019-08-11-000918_add_nsfw_columns/up.sql new file mode 100644 index 00000000..cc1e0074 --- /dev/null +++ b/server/migrations/2019-08-11-000918_add_nsfw_columns/up.sql @@ -0,0 +1,79 @@ +alter table community add column nsfw boolean default false not null; +alter table post add column nsfw boolean default false not null; +alter table user_ add column show_nsfw boolean default false not null; + +-- The views +drop view community_view; +create view community_view as +with all_community as +( + select *, + (select name from user_ u where c.creator_id = u.id) as creator_name, + (select name from category ct where c.category_id = ct.id) as category_name, + (select count(*) from community_follower cf where cf.community_id = c.id) as number_of_subscribers, + (select count(*) from post p where p.community_id = c.id) as number_of_posts, + (select count(*) from comment co, post p where c.id = p.community_id and p.id = co.post_id) as number_of_comments, + hot_rank((select count(*) from community_follower cf where cf.community_id = c.id), c.published) as hot_rank + from community c +) + +select +ac.*, +u.id as user_id, +(select cf.id::boolean from community_follower cf where u.id = cf.user_id and ac.id = cf.community_id) as subscribed +from user_ u +cross join all_community ac + +union all + +select +ac.*, +null as user_id, +null as subscribed +from all_community ac +; + +-- Post view +drop view post_view; +create view post_view as +with all_post as +( + select + p.*, + (select name from user_ where p.creator_id = user_.id) as creator_name, + (select name from community where p.community_id = community.id) as community_name, + (select removed from community c where p.community_id = c.id) as community_removed, + (select deleted from community c where p.community_id = c.id) as community_deleted, + (select nsfw from community c where p.community_id = c.id) as community_nsfw, + (select count(*) from comment where comment.post_id = p.id) as number_of_comments, + coalesce(sum(pl.score), 0) as score, + count (case when pl.score = 1 then 1 else null end) as upvotes, + count (case when pl.score = -1 then 1 else null end) as downvotes, + hot_rank(coalesce(sum(pl.score) , 0), p.published) as hot_rank + from post p + left join post_like pl on p.id = pl.post_id + group by p.id +) + +select +ap.*, +u.id as user_id, +coalesce(pl.score, 0) as my_vote, +(select cf.id::bool from community_follower cf where u.id = cf.user_id and cf.community_id = ap.community_id) as subscribed, +(select pr.id::bool from post_read pr where u.id = pr.user_id and pr.post_id = ap.id) as read, +(select ps.id::bool from post_saved ps where u.id = ps.user_id and ps.post_id = ap.id) as saved +from user_ u +cross join all_post ap +left join post_like pl on u.id = pl.user_id and ap.id = pl.post_id + +union all + +select +ap.*, +null as user_id, +null as my_vote, +null as subscribed, +null as read, +null as saved +from all_post ap +; diff --git a/server/migrations/2019-08-29-040006_add_community_count/down.sql b/server/migrations/2019-08-29-040006_add_community_count/down.sql new file mode 100644 index 00000000..6302f267 --- /dev/null +++ b/server/migrations/2019-08-29-040006_add_community_count/down.sql @@ -0,0 +1,9 @@ +drop view site_view; + +create view site_view as +select *, +(select name from user_ u where s.creator_id = u.id) as creator_name, +(select count(*) from user_) as number_of_users, +(select count(*) from post) as number_of_posts, +(select count(*) from comment) as number_of_comments +from site s; diff --git a/server/migrations/2019-08-29-040006_add_community_count/up.sql b/server/migrations/2019-08-29-040006_add_community_count/up.sql new file mode 100644 index 00000000..0ec1c9c3 --- /dev/null +++ b/server/migrations/2019-08-29-040006_add_community_count/up.sql @@ -0,0 +1,10 @@ +drop view site_view; + +create view site_view as +select *, +(select name from user_ u where s.creator_id = u.id) as creator_name, +(select count(*) from user_) as number_of_users, +(select count(*) from post) as number_of_posts, +(select count(*) from comment) as number_of_comments, +(select count(*) from community) as number_of_communities +from site s; diff --git a/server/src/api/comment.rs b/server/src/api/comment.rs index ffd7da2e..3d18c72a 100644 --- a/server/src/api/comment.rs +++ b/server/src/api/comment.rs @@ -53,7 +53,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -62,12 +62,12 @@ impl Perform for Oper { // Check for a community ban let post = Post::read(&conn, data.post_id)?; if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() { - return Err(APIError::err(&self.op, "You have been banned from this community"))? + return Err(APIError::err(&self.op, "community_ban"))? } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } let content_slurs_removed = remove_slurs(&data.content.to_owned()); @@ -86,7 +86,7 @@ impl Perform for Oper { let inserted_comment = match Comment::create(&conn, &comment_form) { Ok(comment) => comment, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't create Comment"))? + return Err(APIError::err(&self.op, "couldnt_create_comment"))? } }; @@ -101,7 +101,7 @@ impl Perform for Oper { let _inserted_like = match CommentLike::like(&conn, &like_form) { Ok(like) => like, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't like comment."))? + return Err(APIError::err(&self.op, "couldnt_like_comment"))? } }; @@ -124,7 +124,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -153,17 +153,17 @@ impl Perform for Oper { ); if !editors.contains(&user_id) { - return Err(APIError::err(&self.op, "Not allowed to edit comment."))? + return Err(APIError::err(&self.op, "no_comment_edit_allowed"))? } // Check for a community ban if CommunityUserBanView::get(&conn, user_id, orig_comment.community_id).is_ok() { - return Err(APIError::err(&self.op, "You have been banned from this community"))? + return Err(APIError::err(&self.op, "community_ban"))? } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } } @@ -184,7 +184,7 @@ impl Perform for Oper { let _updated_comment = match Comment::update(&conn, data.edit_id, &comment_form) { Ok(comment) => comment, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update Comment"))? + return Err(APIError::err(&self.op, "couldnt_update_comment"))? } }; @@ -220,7 +220,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -235,14 +235,14 @@ impl Perform for Oper { match CommentSaved::save(&conn, &comment_saved_form) { Ok(comment) => comment, Err(_e) => { - return Err(APIError::err(&self.op, "Couldnt do comment save"))? + return Err(APIError::err(&self.op, "couldnt_save_comment"))? } }; } else { match CommentSaved::unsave(&conn, &comment_saved_form) { Ok(comment) => comment, Err(_e) => { - return Err(APIError::err(&self.op, "Couldnt do comment save"))? + return Err(APIError::err(&self.op, "couldnt_save_comment"))? } }; } @@ -266,7 +266,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -275,12 +275,12 @@ impl Perform for Oper { // Check for a community ban let post = Post::read(&conn, data.post_id)?; if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() { - return Err(APIError::err(&self.op, "You have been banned from this community"))? + return Err(APIError::err(&self.op, "community_ban"))? } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } let like_form = CommentLikeForm { @@ -299,7 +299,7 @@ impl Perform for Oper { let _inserted_like = match CommentLike::like(&conn, &like_form) { Ok(like) => like, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't like comment."))? + return Err(APIError::err(&self.op, "couldnt_like_comment"))? } }; } diff --git a/server/src/api/community.rs b/server/src/api/community.rs index be4bb41a..a278aa14 100644 --- a/server/src/api/community.rs +++ b/server/src/api/community.rs @@ -22,7 +22,8 @@ pub struct CreateCommunity { name: String, title: String, description: Option, - category_id: i32 , + category_id: i32, + nsfw: bool, auth: String } @@ -86,6 +87,7 @@ pub struct EditCommunity { category_id: i32, removed: Option, deleted: Option, + nsfw: bool, reason: Option, expires: Option, auth: String @@ -109,6 +111,13 @@ pub struct GetFollowedCommunitiesResponse { communities: Vec } +#[derive(Serialize, Deserialize)] +pub struct TransferCommunity { + community_id: i32, + user_id: i32, + auth: String +} + impl Perform for Oper { fn perform(&self) -> Result { let data: &GetCommunity = &self.data; @@ -135,18 +144,22 @@ impl Perform for Oper { let community_view = match CommunityView::read(&conn, community_id, user_id) { Ok(community) => community, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't find Community"))? + return Err(APIError::err(&self.op, "couldnt_find_community"))? } }; let moderators = match CommunityModeratorView::for_community(&conn, community_id) { Ok(moderators) => moderators, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't find Community"))? + return Err(APIError::err(&self.op, "couldnt_find_community"))? } }; - let admins = UserView::admins(&conn)?; + let site_creator_id = Site::read(&conn, 1)?.creator_id; + let mut admins = UserView::admins(&conn)?; + let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); + let creator_user = admins.remove(creator_index); + admins.insert(0, creator_user); // Return the jwt Ok( @@ -168,21 +181,21 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; if has_slurs(&data.name) || has_slurs(&data.title) || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } let user_id = claims.id; // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } // When you create a community, make sure the user becomes a moderator and a follower @@ -194,13 +207,14 @@ impl Perform for Oper { creator_id: user_id, removed: None, deleted: None, + nsfw: data.nsfw, updated: None, }; let inserted_community = match Community::create(&conn, &community_form) { Ok(community) => community, Err(_e) => { - return Err(APIError::err(&self.op, "Community already exists."))? + return Err(APIError::err(&self.op, "community_already_exists"))? } }; @@ -212,7 +226,7 @@ impl Perform for Oper { let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community moderator already exists."))? + return Err(APIError::err(&self.op, "community_moderator_already_exists"))? } }; @@ -224,7 +238,7 @@ impl Perform for Oper { let _inserted_community_follower = match CommunityFollower::follow(&conn, &community_follower_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community follower already exists."))? + return Err(APIError::err(&self.op, "community_follower_already_exists"))? } }; @@ -244,7 +258,7 @@ impl Perform for Oper { let data: &EditCommunity = &self.data; if has_slurs(&data.name) || has_slurs(&data.title) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } let conn = establish_connection(); @@ -252,7 +266,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -260,7 +274,7 @@ impl Perform for Oper { // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } // Verify its a mod @@ -280,7 +294,7 @@ impl Perform for Oper { .collect() ); if !editors.contains(&user_id) { - return Err(APIError::err(&self.op, "Not allowed to edit community"))? + return Err(APIError::err(&self.op, "no_community_edit_allowed"))? } let community_form = CommunityForm { @@ -291,13 +305,14 @@ impl Perform for Oper { creator_id: user_id, removed: data.removed.to_owned(), deleted: data.deleted.to_owned(), + nsfw: data.nsfw, updated: Some(naive_now()) }; let _updated_community = match Community::update(&conn, data.edit_id, &community_form) { Ok(community) => community, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update Community"))? + return Err(APIError::err(&self.op, "couldnt_update_community"))? } }; @@ -333,22 +348,38 @@ impl Perform for Oper { let data: &ListCommunities = &self.data; let conn = establish_connection(); - let user_id: Option = match &data.auth { + let user_claims: Option = match &data.auth { Some(auth) => { match Claims::decode(&auth) { Ok(claims) => { - let user_id = claims.claims.id; - Some(user_id) + Some(claims.claims) } Err(_e) => None } } None => None }; + + let user_id = match &user_claims { + Some(claims) => Some(claims.id), + None => None + }; + + let show_nsfw = match &user_claims { + Some(claims) => claims.show_nsfw, + None => false + }; let sort = SortType::from_str(&data.sort)?; - let communities: Vec = CommunityView::list(&conn, user_id, sort, data.page, data.limit)?; + let communities: Vec = CommunityView::list( + &conn, + &sort, + user_id, + show_nsfw, + None, + data.page, + data.limit)?; // Return the jwt Ok( @@ -369,7 +400,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -384,14 +415,14 @@ impl Perform for Oper { match CommunityFollower::follow(&conn, &community_follower_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community follower already exists."))? + return Err(APIError::err(&self.op, "community_follower_already_exists"))? } }; } else { match CommunityFollower::ignore(&conn, &community_follower_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community follower already exists."))? + return Err(APIError::err(&self.op, "community_follower_already_exists"))? } }; } @@ -416,7 +447,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -425,7 +456,7 @@ impl Perform for Oper { let communities: Vec = match CommunityFollowerView::for_user(&conn, user_id) { Ok(communities) => communities, Err(_e) => { - return Err(APIError::err(&self.op, "System error, try logging out and back in."))? + return Err(APIError::err(&self.op, "system_err_login"))? } }; @@ -448,7 +479,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -463,14 +494,14 @@ impl Perform for Oper { match CommunityUserBan::ban(&conn, &community_user_ban_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community user ban already exists"))? + return Err(APIError::err(&self.op, "community_user_already_banned"))? } }; } else { match CommunityUserBan::unban(&conn, &community_user_ban_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community user ban already exists"))? + return Err(APIError::err(&self.op, "community_user_already_banned"))? } }; } @@ -511,7 +542,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -526,14 +557,14 @@ impl Perform for Oper { match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community moderator already exists."))? + return Err(APIError::err(&self.op, "community_moderator_already_exists"))? } }; } else { match CommunityModerator::leave(&conn, &community_moderator_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community moderator already exists."))? + return Err(APIError::err(&self.op, "community_moderator_already_exists"))? } }; } @@ -557,3 +588,109 @@ impl Perform for Oper { ) } } + +impl Perform for Oper { + fn perform(&self) -> Result { + let data: &TransferCommunity = &self.data; + let conn = establish_connection(); + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return Err(APIError::err(&self.op, "not_logged_in"))? + } + }; + + let user_id = claims.id; + + let read_community = Community::read(&conn, data.community_id)?; + + let site_creator_id = Site::read(&conn, 1)?.creator_id; + let mut admins = UserView::admins(&conn)?; + let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); + let creator_user = admins.remove(creator_index); + admins.insert(0, creator_user); + + + // Make sure user is the creator, or an admin + if user_id != read_community.creator_id && !admins.iter().map(|a| a.id).collect::>().contains(&user_id) { + return Err(APIError::err(&self.op, "not_an_admin"))? + } + + let community_form = CommunityForm { + name: read_community.name, + title: read_community.title, + description: read_community.description, + category_id: read_community.category_id, + creator_id: data.user_id, + removed: None, + deleted: None, + nsfw: read_community.nsfw, + updated: Some(naive_now()) + }; + + let _updated_community = match Community::update(&conn, data.community_id, &community_form) { + Ok(community) => community, + Err(_e) => { + return Err(APIError::err(&self.op, "couldnt_update_community"))? + } + }; + + // You also have to re-do the community_moderator table, reordering it. + let mut community_mods = CommunityModeratorView::for_community(&conn, data.community_id)?; + let creator_index = community_mods.iter().position(|r| r.user_id == data.user_id).unwrap(); + let creator_user = community_mods.remove(creator_index); + community_mods.insert(0, creator_user); + + CommunityModerator::delete_for_community(&conn, data.community_id)?; + + for cmod in &community_mods { + + let community_moderator_form = CommunityModeratorForm { + community_id: cmod.community_id, + user_id: cmod.user_id + }; + + let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) { + Ok(user) => user, + Err(_e) => { + return Err(APIError::err(&self.op, "community_moderator_already_exists"))? + } + }; + } + + // Mod tables + let form = ModAddCommunityForm { + mod_user_id: user_id, + other_user_id: data.user_id, + community_id: data.community_id, + removed: Some(false), + }; + ModAddCommunity::create(&conn, &form)?; + + let community_view = match CommunityView::read(&conn, data.community_id, Some(user_id)) { + Ok(community) => community, + Err(_e) => { + return Err(APIError::err(&self.op, "couldnt_find_community"))? + } + }; + + let moderators = match CommunityModeratorView::for_community(&conn, data.community_id) { + Ok(moderators) => moderators, + Err(_e) => { + return Err(APIError::err(&self.op, "couldnt_find_community"))? + } + }; + + + // Return the jwt + Ok( + GetCommunityResponse { + op: self.op.to_string(), + community: community_view, + moderators: moderators, + admins: admins, + } + ) + } +} diff --git a/server/src/api/mod.rs b/server/src/api/mod.rs index 6e3e8269..ac11d30c 100644 --- a/server/src/api/mod.rs +++ b/server/src/api/mod.rs @@ -1,18 +1,18 @@ use serde::{Deserialize, Serialize}; use failure::Error; -use db::*; -use db::community::*; -use db::user::*; -use db::post::*; -use db::comment::*; -use db::post_view::*; -use db::comment_view::*; -use db::category::*; -use db::community_view::*; -use db::user_view::*; -use db::moderator_views::*; -use db::moderator::*; -use {has_slurs, remove_slurs, Settings, naive_now, naive_from_unix}; +use crate::db::*; +use crate::db::community::*; +use crate::db::user::*; +use crate::db::post::*; +use crate::db::comment::*; +use crate::db::post_view::*; +use crate::db::comment_view::*; +use crate::db::category::*; +use crate::db::community_view::*; +use crate::db::user_view::*; +use crate::db::moderator_views::*; +use crate::db::moderator::*; +use crate::{has_slurs, remove_slurs, Settings, naive_now, naive_from_unix}; pub mod user; pub mod community; @@ -22,7 +22,7 @@ pub mod site; #[derive(EnumString,ToString,Debug)] pub enum UserOperation { - Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead + Login, Register, CreateCommunity, CreatePost, ListCommunities, ListCategories, GetPost, GetCommunity, CreateComment, EditComment, SaveComment, CreateCommentLike, GetPosts, CreatePostLike, EditPost, SavePost, EditCommunity, FollowCommunity, GetFollowedCommunities, GetUserDetails, GetReplies, GetModlog, BanFromCommunity, AddModToCommunity, CreateSite, EditSite, GetSite, AddAdmin, BanUser, Search, MarkAllAsRead, SaveUserSettings, TransferCommunity, TransferSite } #[derive(Fail, Debug)] diff --git a/server/src/api/post.rs b/server/src/api/post.rs index a6010781..8fc24ac1 100644 --- a/server/src/api/post.rs +++ b/server/src/api/post.rs @@ -6,6 +6,7 @@ pub struct CreatePost { name: String, url: Option, body: Option, + nsfw: bool, community_id: i32, auth: String } @@ -73,6 +74,7 @@ pub struct EditPost { body: Option, removed: Option, deleted: Option, + nsfw: bool, locked: Option, reason: Option, auth: String @@ -94,25 +96,25 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } let user_id = claims.id; // Check for a community ban if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() { - return Err(APIError::err(&self.op, "You have been banned from this community"))? + return Err(APIError::err(&self.op, "community_ban"))? } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } let post_form = PostForm { @@ -123,6 +125,7 @@ impl Perform for Oper { creator_id: user_id, removed: None, deleted: None, + nsfw: data.nsfw, locked: None, updated: None }; @@ -130,7 +133,7 @@ impl Perform for Oper { let inserted_post = match Post::create(&conn, &post_form) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't create Post"))? + return Err(APIError::err(&self.op, "couldnt_create_post"))? } }; @@ -145,7 +148,7 @@ impl Perform for Oper { let _inserted_like = match PostLike::like(&conn, &like_form) { Ok(like) => like, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't like post."))? + return Err(APIError::err(&self.op, "couldnt_like_post"))? } }; @@ -153,7 +156,7 @@ impl Perform for Oper { let post_view = match PostView::read(&conn, inserted_post.id, Some(user_id)) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't find Post"))? + return Err(APIError::err(&self.op, "couldnt_find_post"))? } }; @@ -187,7 +190,7 @@ impl Perform for Oper { let post_view = match PostView::read(&conn, data.id, user_id) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't find Post"))? + return Err(APIError::err(&self.op, "couldnt_find_post"))? } }; @@ -197,7 +200,11 @@ impl Perform for Oper { let moderators = CommunityModeratorView::for_community(&conn, post_view.community_id)?; - let admins = UserView::admins(&conn)?; + let site_creator_id = Site::read(&conn, 1)?.creator_id; + let mut admins = UserView::admins(&conn)?; + let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); + let creator_user = admins.remove(creator_index); + admins.insert(0, creator_user); // Return the jwt Ok( @@ -219,40 +226,51 @@ impl Perform for Oper { let data: &GetPosts = &self.data; let conn = establish_connection(); - let user_id: Option = match &data.auth { + let user_claims: Option = match &data.auth { Some(auth) => { match Claims::decode(&auth) { Ok(claims) => { - let user_id = claims.claims.id; - Some(user_id) + Some(claims.claims) } Err(_e) => None } } None => None }; + + let user_id = match &user_claims { + Some(claims) => Some(claims.id), + None => None + }; + + let show_nsfw = match &user_claims { + Some(claims) => claims.show_nsfw, + None => false + }; let type_ = PostListingType::from_str(&data.type_)?; let sort = SortType::from_str(&data.sort)?; - let posts = match PostView::list(&conn, - type_, - &sort, - data.community_id, - None, - None, - user_id, - false, - false, - data.page, - data.limit) { + let posts = match PostView::list( + &conn, + type_, + &sort, + data.community_id, + None, + None, + None, + user_id, + show_nsfw, + false, + false, + data.page, + data.limit) { Ok(posts) => posts, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't get posts"))? + return Err(APIError::err(&self.op, "couldnt_get_posts"))? } }; - // Return the jwt Ok( GetPostsResponse { op: self.op.to_string(), @@ -270,7 +288,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -279,12 +297,12 @@ impl Perform for Oper { // Check for a community ban let post = Post::read(&conn, data.post_id)?; if CommunityUserBanView::get(&conn, user_id, post.community_id).is_ok() { - return Err(APIError::err(&self.op, "You have been banned from this community"))? + return Err(APIError::err(&self.op, "community_ban"))? } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } let like_form = PostLikeForm { @@ -302,7 +320,7 @@ impl Perform for Oper { let _inserted_like = match PostLike::like(&conn, &like_form) { Ok(like) => like, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't like post."))? + return Err(APIError::err(&self.op, "couldnt_like_post"))? } }; } @@ -310,7 +328,7 @@ impl Perform for Oper { let post_view = match PostView::read(&conn, data.post_id, Some(user_id)) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't find Post"))? + return Err(APIError::err(&self.op, "couldnt_find_post"))? } }; @@ -329,7 +347,7 @@ impl Perform for Oper { let data: &EditPost = &self.data; if has_slurs(&data.name) || (data.body.is_some() && has_slurs(&data.body.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } let conn = establish_connection(); @@ -337,7 +355,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -360,17 +378,17 @@ impl Perform for Oper { .collect() ); if !editors.contains(&user_id) { - return Err(APIError::err(&self.op, "Not allowed to edit post."))? + return Err(APIError::err(&self.op, "no_post_edit_allowed"))? } // Check for a community ban if CommunityUserBanView::get(&conn, user_id, data.community_id).is_ok() { - return Err(APIError::err(&self.op, "You have been banned from this community"))? + return Err(APIError::err(&self.op, "community_ban"))? } // Check for a site ban if UserView::read(&conn, user_id)?.banned { - return Err(APIError::err(&self.op, "You have been banned from the site"))? + return Err(APIError::err(&self.op, "site_ban"))? } let post_form = PostForm { @@ -381,6 +399,7 @@ impl Perform for Oper { community_id: data.community_id, removed: data.removed.to_owned(), deleted: data.deleted.to_owned(), + nsfw: data.nsfw, locked: data.locked.to_owned(), updated: Some(naive_now()) }; @@ -388,7 +407,7 @@ impl Perform for Oper { let _updated_post = match Post::update(&conn, data.edit_id, &post_form) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update Post"))? + return Err(APIError::err(&self.op, "couldnt_update_post"))? } }; @@ -431,7 +450,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -446,14 +465,14 @@ impl Perform for Oper { match PostSaved::save(&conn, &post_saved_form) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldnt do post save"))? + return Err(APIError::err(&self.op, "couldnt_save_post"))? } }; } else { match PostSaved::unsave(&conn, &post_saved_form) { Ok(post) => post, Err(_e) => { - return Err(APIError::err(&self.op, "Couldnt do post save"))? + return Err(APIError::err(&self.op, "couldnt_save_post"))? } }; } diff --git a/server/src/api/site.rs b/server/src/api/site.rs index 03ee90ff..7827913b 100644 --- a/server/src/api/site.rs +++ b/server/src/api/site.rs @@ -23,8 +23,11 @@ pub struct Search { #[derive(Serialize, Deserialize)] pub struct SearchResponse { op: String, + type_: String, comments: Vec, posts: Vec, + communities: Vec, + users: Vec, } #[derive(Serialize, Deserialize)] @@ -64,8 +67,7 @@ pub struct EditSite { } #[derive(Serialize, Deserialize)] -pub struct GetSite { -} +pub struct GetSite; #[derive(Serialize, Deserialize)] pub struct SiteResponse { @@ -81,6 +83,12 @@ pub struct GetSiteResponse { banned: Vec, } +#[derive(Serialize, Deserialize)] +pub struct TransferSite { + user_id: i32, + auth: String +} + impl Perform for Oper { fn perform(&self) -> Result { let _data: &ListCategories = &self.data; @@ -145,20 +153,20 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; if has_slurs(&data.name) || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } let user_id = claims.id; // Make sure user is an admin if !UserView::read(&conn, user_id)?.admin { - return Err(APIError::err(&self.op, "Not an admin."))? + return Err(APIError::err(&self.op, "not_an_admin"))? } let site_form = SiteForm { @@ -171,7 +179,7 @@ impl Perform for Oper { match Site::create(&conn, &site_form) { Ok(site) => site, Err(_e) => { - return Err(APIError::err(&self.op, "Site exists already"))? + return Err(APIError::err(&self.op, "site_already_exists"))? } }; @@ -195,20 +203,20 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; if has_slurs(&data.name) || (data.description.is_some() && has_slurs(&data.description.to_owned().unwrap())) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } let user_id = claims.id; // Make sure user is an admin if UserView::read(&conn, user_id)?.admin == false { - return Err(APIError::err(&self.op, "Not an admin."))? + return Err(APIError::err(&self.op, "not_an_admin"))? } let found_site = Site::read(&conn, 1)?; @@ -223,7 +231,7 @@ impl Perform for Oper { match Site::update(&conn, 1, &site_form) { Ok(site) => site, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update site."))? + return Err(APIError::err(&self.op, "couldnt_update_site"))? } }; @@ -249,7 +257,14 @@ impl Perform for Oper { Err(_e) => None }; - let admins = UserView::admins(&conn)?; + let mut admins = UserView::admins(&conn)?; + if site_view.is_some() { + let site_creator_id = site_view.to_owned().unwrap().creator_id; + let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); + let creator_user = admins.remove(creator_index); + admins.insert(0, creator_user); + } + let banned = UserView::banned(&conn)?; Ok( @@ -273,53 +288,113 @@ impl Perform for Oper { let mut posts = Vec::new(); let mut comments = Vec::new(); + let mut communities = Vec::new(); + let mut users = Vec::new(); + + // TODO no clean / non-nsfw searching rn match type_ { SearchType::Posts => { - posts = PostView::list(&conn, - PostListingType::All, - &sort, - data.community_id, - None, - Some(data.q.to_owned()), - None, - false, - false, - data.page, - data.limit)?; + posts = PostView::list( + &conn, + PostListingType::All, + &sort, + data.community_id, + None, + Some(data.q.to_owned()), + None, + None, + true, + false, + false, + data.page, + data.limit)?; }, SearchType::Comments => { - comments = CommentView::list(&conn, - &sort, - None, - None, - Some(data.q.to_owned()), - None, - false, - data.page, - data.limit)?; + comments = CommentView::list( + &conn, + &sort, + None, + None, + Some(data.q.to_owned()), + None, + false, + data.page, + data.limit)?; + }, + SearchType::Communities => { + communities = CommunityView::list( + &conn, + &sort, + None, + true, + Some(data.q.to_owned()), + data.page, + data.limit)?; + }, + SearchType::Users => { + users = UserView::list( + &conn, + &sort, + Some(data.q.to_owned()), + data.page, + data.limit)?; }, - SearchType::Both => { - posts = PostView::list(&conn, - PostListingType::All, - &sort, - data.community_id, - None, - Some(data.q.to_owned()), - None, - false, - false, - data.page, - data.limit)?; - comments = CommentView::list(&conn, - &sort, - None, - None, - Some(data.q.to_owned()), - None, - false, - data.page, - data.limit)?; + SearchType::All => { + posts = PostView::list( + &conn, + PostListingType::All, + &sort, + data.community_id, + None, + Some(data.q.to_owned()), + None, + None, + true, + false, + false, + data.page, + data.limit)?; + comments = CommentView::list( + &conn, + &sort, + None, + None, + Some(data.q.to_owned()), + None, + false, + data.page, + data.limit)?; + communities = CommunityView::list( + &conn, + &sort, + None, + true, + Some(data.q.to_owned()), + data.page, + data.limit)?; + users = UserView::list( + &conn, + &sort, + Some(data.q.to_owned()), + data.page, + data.limit)?; + }, + SearchType::Url => { + posts = PostView::list( + &conn, + PostListingType::All, + &sort, + data.community_id, + None, + None, + Some(data.q.to_owned()), + None, + true, + false, + false, + data.page, + data.limit)?; } }; @@ -328,9 +403,77 @@ impl Perform for Oper { Ok( SearchResponse { op: self.op.to_string(), + type_: data.type_.to_owned(), comments: comments, posts: posts, + communities: communities, + users: users, } ) } } + +impl Perform for Oper { + fn perform(&self) -> Result { + let data: &TransferSite = &self.data; + let conn = establish_connection(); + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return Err(APIError::err(&self.op, "not_logged_in"))? + } + }; + + let user_id = claims.id; + + let read_site = Site::read(&conn, 1)?; + + // Make sure user is the creator + if read_site.creator_id != user_id { + return Err(APIError::err(&self.op, "not_an_admin"))? + } + + let site_form = SiteForm { + name: read_site.name, + description: read_site.description, + creator_id: data.user_id, + updated: Some(naive_now()), + }; + + match Site::update(&conn, 1, &site_form) { + Ok(site) => site, + Err(_e) => { + return Err(APIError::err(&self.op, "couldnt_update_site"))? + } + }; + + // Mod tables + let form = ModAddForm { + mod_user_id: user_id, + other_user_id: data.user_id, + removed: Some(false), + }; + + ModAdd::create(&conn, &form)?; + + let site_view = SiteView::read(&conn)?; + + let mut admins = UserView::admins(&conn)?; + let creator_index = admins.iter().position(|r| r.id == site_view.creator_id).unwrap(); + let creator_user = admins.remove(creator_index); + admins.insert(0, creator_user); + + let banned = UserView::banned(&conn)?; + + Ok( + GetSiteResponse { + op: self.op.to_string(), + site: Some(site_view), + admins: admins, + banned: banned, + } + ) + } +} + diff --git a/server/src/api/user.rs b/server/src/api/user.rs index 9361ca4d..d8610fa9 100644 --- a/server/src/api/user.rs +++ b/server/src/api/user.rs @@ -15,6 +15,13 @@ pub struct Register { password: String, password_verify: String, admin: bool, + show_nsfw: bool, +} + +#[derive(Serialize, Deserialize)] +pub struct SaveUserSettings { + show_nsfw: bool, + auth: String, } #[derive(Serialize, Deserialize)] @@ -102,13 +109,13 @@ impl Perform for Oper { // Fetch that username / email let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) { Ok(user) => user, - Err(_e) => return Err(APIError::err(&self.op, "Couldn't find that username or email"))? + Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_that_username_or_email"))? }; // Verify the password let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false); if !valid { - return Err(APIError::err(&self.op, "Password incorrect"))? + return Err(APIError::err(&self.op, "password_incorrect"))? } // Return the jwt @@ -129,16 +136,16 @@ impl Perform for Oper { // Make sure passwords match if &data.password != &data.password_verify { - return Err(APIError::err(&self.op, "Passwords do not match."))? + return Err(APIError::err(&self.op, "passwords_dont_match"))? } if has_slurs(&data.username) { - return Err(APIError::err(&self.op, "No slurs"))? + return Err(APIError::err(&self.op, "no_slurs"))? } // Make sure there are no admins if data.admin && UserView::admins(&conn)?.len() > 0 { - return Err(APIError::err(&self.op, "Sorry, there's already an admin."))? + return Err(APIError::err(&self.op, "admin_already_created"))? } // Register the new user @@ -151,40 +158,60 @@ impl Perform for Oper { updated: None, admin: data.admin, banned: false, + show_nsfw: data.show_nsfw, }; // Create the user let inserted_user = match User_::register(&conn, &user_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "User already exists."))? + return Err(APIError::err(&self.op, "user_already_exists"))? + } + }; + + // Create the main community if it doesn't exist + let main_community: Community = match Community::read(&conn, 2) { + Ok(c) => c, + Err(_e) => { + let community_form = CommunityForm { + name: "main".to_string(), + title: "The Default Community".to_string(), + description: Some("The Default Community".to_string()), + category_id: 1, + nsfw: false, + creator_id: inserted_user.id, + removed: None, + deleted: None, + updated: None, + }; + Community::create(&conn, &community_form).unwrap() } }; // Sign them up for main community no matter what let community_follower_form = CommunityFollowerForm { - community_id: 1, + community_id: main_community.id, user_id: inserted_user.id, }; let _inserted_community_follower = match CommunityFollower::follow(&conn, &community_follower_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community follower already exists."))? + return Err(APIError::err(&self.op, "community_follower_already_exists"))? } }; // If its an admin, add them as a mod and follower to main if data.admin { let community_moderator_form = CommunityModeratorForm { - community_id: 1, + community_id: main_community.id, user_id: inserted_user.id, }; let _inserted_community_moderator = match CommunityModerator::join(&conn, &community_moderator_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Community moderator already exists."))? + return Err(APIError::err(&self.op, "community_moderator_already_exists"))? } }; @@ -200,24 +227,77 @@ impl Perform for Oper { } } +impl Perform for Oper { + fn perform(&self) -> Result { + let data: &SaveUserSettings = &self.data; + let conn = establish_connection(); + + let claims = match Claims::decode(&data.auth) { + Ok(claims) => claims.claims, + Err(_e) => { + return Err(APIError::err(&self.op, "not_logged_in"))? + } + }; + + let user_id = claims.id; + + let read_user = User_::read(&conn, user_id)?; + + let user_form = UserForm { + name: read_user.name, + fedi_name: read_user.fedi_name, + email: read_user.email, + password_encrypted: read_user.password_encrypted, + preferred_username: read_user.preferred_username, + updated: Some(naive_now()), + admin: read_user.admin, + banned: read_user.banned, + show_nsfw: data.show_nsfw, + }; + + let updated_user = match User_::update(&conn, user_id, &user_form) { + Ok(user) => user, + Err(_e) => { + return Err(APIError::err(&self.op, "couldnt_update_user"))? + } + }; + + // Return the jwt + Ok( + LoginResponse { + op: self.op.to_string(), + jwt: updated_user.jwt() + } + ) + } +} impl Perform for Oper { fn perform(&self) -> Result { let data: &GetUserDetails = &self.data; let conn = establish_connection(); - let user_id: Option = match &data.auth { + let user_claims: Option = match &data.auth { Some(auth) => { match Claims::decode(&auth) { Ok(claims) => { - let user_id = claims.claims.id; - Some(user_id) + Some(claims.claims) } Err(_e) => None } } None => None }; + + let user_id = match &user_claims { + Some(claims) => Some(claims.id), + None => None + }; + + let show_nsfw = match &user_claims { + Some(claims) => claims.show_nsfw, + None => false + }; //TODO add save let sort = SortType::from_str(&data.sort)?; @@ -231,50 +311,58 @@ impl Perform for Oper { // If its saved only, you don't care what creator it was let posts = if data.saved_only { - PostView::list(&conn, - PostListingType::All, - &sort, - data.community_id, - None, - None, - Some(user_details_id), - data.saved_only, - false, - data.page, - data.limit)? + PostView::list( + &conn, + PostListingType::All, + &sort, + data.community_id, + None, + None, + None, + Some(user_details_id), + show_nsfw, + data.saved_only, + false, + data.page, + data.limit)? } else { - PostView::list(&conn, - PostListingType::All, - &sort, - data.community_id, - Some(user_details_id), - None, - user_id, - data.saved_only, - false, - data.page, - data.limit)? + PostView::list( + &conn, + PostListingType::All, + &sort, + data.community_id, + Some(user_details_id), + None, + None, + user_id, + show_nsfw, + data.saved_only, + false, + data.page, + data.limit)? }; let comments = if data.saved_only { - CommentView::list(&conn, - &sort, - None, - None, - None, - Some(user_details_id), - data.saved_only, - data.page, - data.limit)? + CommentView::list( + &conn, + &sort, + None, + None, + None, + Some(user_details_id), + data.saved_only, + data.page, + data.limit)? } else { - CommentView::list(&conn, - &sort, - None, - Some(user_details_id), - None, - user_id, - data.saved_only, - data.page, - data.limit)? + CommentView::list( + &conn, + &sort, + None, + Some(user_details_id), + None, + user_id, + data.saved_only, + data.page, + data.limit)? }; let follows = CommunityFollowerView::for_user(&conn, user_details_id)?; @@ -303,7 +391,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -311,7 +399,7 @@ impl Perform for Oper { // Make sure user is an admin if UserView::read(&conn, user_id)?.admin == false { - return Err(APIError::err(&self.op, "Not an admin."))? + return Err(APIError::err(&self.op, "not_an_admin"))? } let read_user = User_::read(&conn, data.user_id)?; @@ -325,12 +413,13 @@ impl Perform for Oper { updated: Some(naive_now()), admin: data.added, banned: read_user.banned, + show_nsfw: read_user.show_nsfw, }; match User_::update(&conn, data.user_id, &user_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update user"))? + return Err(APIError::err(&self.op, "couldnt_update_user"))? } }; @@ -343,7 +432,11 @@ impl Perform for Oper { ModAdd::create(&conn, &form)?; - let admins = UserView::admins(&conn)?; + let site_creator_id = Site::read(&conn, 1)?.creator_id; + let mut admins = UserView::admins(&conn)?; + let creator_index = admins.iter().position(|r| r.id == site_creator_id).unwrap(); + let creator_user = admins.remove(creator_index); + admins.insert(0, creator_user); Ok( AddAdminResponse { @@ -362,7 +455,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -370,7 +463,7 @@ impl Perform for Oper { // Make sure user is an admin if UserView::read(&conn, user_id)?.admin == false { - return Err(APIError::err(&self.op, "Not an admin."))? + return Err(APIError::err(&self.op, "not_an_admin"))? } let read_user = User_::read(&conn, data.user_id)?; @@ -384,12 +477,13 @@ impl Perform for Oper { updated: Some(naive_now()), admin: read_user.admin, banned: data.ban, + show_nsfw: read_user.show_nsfw, }; match User_::update(&conn, data.user_id, &user_form) { Ok(user) => user, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update user"))? + return Err(APIError::err(&self.op, "couldnt_update_user"))? } }; @@ -430,7 +524,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -458,7 +552,7 @@ impl Perform for Oper { let claims = match Claims::decode(&data.auth) { Ok(claims) => claims.claims, Err(_e) => { - return Err(APIError::err(&self.op, "Not logged in."))? + return Err(APIError::err(&self.op, "not_logged_in"))? } }; @@ -481,7 +575,7 @@ impl Perform for Oper { let _updated_comment = match Comment::update(&conn, reply.id, &comment_form) { Ok(comment) => comment, Err(_e) => { - return Err(APIError::err(&self.op, "Couldn't update Comment"))? + return Err(APIError::err(&self.op, "couldnt_update_comment"))? } }; } diff --git a/server/src/apub.rs b/server/src/apub.rs index 3d9595c8..9de32401 100644 --- a/server/src/apub.rs +++ b/server/src/apub.rs @@ -1,10 +1,10 @@ extern crate activitypub; use self::activitypub::{context, actor::Person}; -use db::user::User_; +use crate::db::user::User_; impl User_ { pub fn person(&self) -> Person { - use {Settings, to_datetime_utc}; + use crate::{Settings, to_datetime_utc}; let base_url = &format!("{}/user/{}", Settings::get().api_endpoint(), self.name); let mut person = Person::default(); person.object_props.set_context_object(context()).ok(); @@ -31,7 +31,7 @@ impl User_ { #[cfg(test)] mod tests { use super::User_; - use naive_now; + use crate::naive_now; #[test] fn test_person() { @@ -46,7 +46,8 @@ mod tests { published: naive_now(), admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let person = expected_user.person(); diff --git a/server/src/db/category.rs b/server/src/db/category.rs index 99f906d4..eb822580 100644 --- a/server/src/db/category.rs +++ b/server/src/db/category.rs @@ -1,5 +1,5 @@ -use schema::{category}; -use schema::category::dsl::*; +use crate::schema::{category}; +use crate::schema::category::dsl::*; use super::*; #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] diff --git a/server/src/db/comment.rs b/server/src/db/comment.rs index a924bd4c..7901357f 100644 --- a/server/src/db/comment.rs +++ b/server/src/db/comment.rs @@ -1,4 +1,4 @@ -use schema::{comment, comment_like, comment_saved}; +use crate::schema::{comment, comment_like, comment_saved}; use super::*; use super::post::Post; @@ -40,26 +40,26 @@ pub struct CommentForm { impl Crud for Comment { fn read(conn: &PgConnection, comment_id: i32) -> Result { - use schema::comment::dsl::*; + use crate::schema::comment::dsl::*; comment.find(comment_id) .first::(conn) } fn delete(conn: &PgConnection, comment_id: i32) -> Result { - use schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::delete(comment.find(comment_id)) .execute(conn) } fn create(conn: &PgConnection, comment_form: &CommentForm) -> Result { - use schema::comment::dsl::*; + use crate::schema::comment::dsl::*; insert_into(comment) .values(comment_form) .get_result::(conn) } fn update(conn: &PgConnection, comment_id: i32, comment_form: &CommentForm) -> Result { - use schema::comment::dsl::*; + use crate::schema::comment::dsl::*; diesel::update(comment.find(comment_id)) .set(comment_form) .get_result::(conn) @@ -89,30 +89,31 @@ pub struct CommentLikeForm { impl Likeable for CommentLike { fn read(conn: &PgConnection, comment_id_from: i32) -> Result, Error> { - use schema::comment_like::dsl::*; + use crate::schema::comment_like::dsl::*; comment_like .filter(comment_id.eq(comment_id_from)) .load::(conn) } fn like(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result { - use schema::comment_like::dsl::*; + use crate::schema::comment_like::dsl::*; insert_into(comment_like) .values(comment_like_form) .get_result::(conn) } fn remove(conn: &PgConnection, comment_like_form: &CommentLikeForm) -> Result { - use schema::comment_like::dsl::*; - diesel::delete(comment_like - .filter(comment_id.eq(comment_like_form.comment_id)) - .filter(user_id.eq(comment_like_form.user_id))) + use crate::schema::comment_like::dsl::*; + diesel::delete( + comment_like + .filter(comment_id.eq(comment_like_form.comment_id)) + .filter(user_id.eq(comment_like_form.user_id))) .execute(conn) } } impl CommentLike { pub fn from_post(conn: &PgConnection, post_id_from: i32) -> Result, Error> { - use schema::comment_like::dsl::*; + use crate::schema::comment_like::dsl::*; comment_like .filter(post_id.eq(post_id_from)) .load::(conn) @@ -138,13 +139,13 @@ pub struct CommentSavedForm { impl Saveable for CommentSaved { fn save(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result { - use schema::comment_saved::dsl::*; + use crate::schema::comment_saved::dsl::*; insert_into(comment_saved) .values(comment_saved_form) .get_result::(conn) } fn unsave(conn: &PgConnection, comment_saved_form: &CommentSavedForm) -> Result { - use schema::comment_saved::dsl::*; + use crate::schema::comment_saved::dsl::*; diesel::delete(comment_saved .filter(comment_id.eq(comment_saved_form.comment_id)) .filter(user_id.eq(comment_saved_form.user_id))) @@ -170,7 +171,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -183,7 +185,8 @@ mod tests { creator_id: inserted_user.id, removed: None, deleted: None, - updated: None + updated: None, + nsfw: false, }; let inserted_community = Community::create(&conn, &new_community).unwrap(); @@ -197,7 +200,8 @@ mod tests { removed: None, deleted: None, locked: None, - updated: None + updated: None, + nsfw: false, }; let inserted_post = Post::create(&conn, &new_post).unwrap(); diff --git a/server/src/db/comment_view.rs b/server/src/db/comment_view.rs index 9cd61e33..8a6545ba 100644 --- a/server/src/db/comment_view.rs +++ b/server/src/db/comment_view.rs @@ -94,7 +94,7 @@ impl CommentView { } query = match sort { - // SortType::Hot => query.order_by(hot_rank.desc()), + // SortType::Hot => query.order(hot_rank.desc(), published.desc()), SortType::New => query.order_by(published.desc()), SortType::TopAll => query.order_by(score.desc()), SortType::TopYear => query @@ -261,7 +261,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -274,7 +275,8 @@ mod tests { creator_id: inserted_user.id, removed: None, deleted: None, - updated: None + updated: None, + nsfw: false, }; let inserted_community = Community::create(&conn, &new_community).unwrap(); @@ -288,7 +290,8 @@ mod tests { removed: None, deleted: None, locked: None, - updated: None + updated: None, + nsfw: false, }; let inserted_post = Post::create(&conn, &new_post).unwrap(); diff --git a/server/src/db/community.rs b/server/src/db/community.rs index 4540f731..e07b5c00 100644 --- a/server/src/db/community.rs +++ b/server/src/db/community.rs @@ -1,4 +1,4 @@ -use schema::{community, community_moderator, community_follower, community_user_ban, site}; +use crate::schema::{community, community_moderator, community_follower, community_user_ban, site}; use super::*; #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -14,6 +14,7 @@ pub struct Community { pub published: chrono::NaiveDateTime, pub updated: Option, pub deleted: bool, + pub nsfw: bool, } #[derive(Insertable, AsChangeset, Clone, Serialize, Deserialize)] @@ -27,30 +28,31 @@ pub struct CommunityForm { pub removed: Option, pub updated: Option, pub deleted: Option, + pub nsfw: bool, } impl Crud for Community { fn read(conn: &PgConnection, community_id: i32) -> Result { - use schema::community::dsl::*; + use crate::schema::community::dsl::*; community.find(community_id) .first::(conn) } fn delete(conn: &PgConnection, community_id: i32) -> Result { - use schema::community::dsl::*; + use crate::schema::community::dsl::*; diesel::delete(community.find(community_id)) .execute(conn) } fn create(conn: &PgConnection, new_community: &CommunityForm) -> Result { - use schema::community::dsl::*; + use crate::schema::community::dsl::*; insert_into(community) .values(new_community) .get_result::(conn) } fn update(conn: &PgConnection, community_id: i32, new_community: &CommunityForm) -> Result { - use schema::community::dsl::*; + use crate::schema::community::dsl::*; diesel::update(community.find(community_id)) .set(new_community) .get_result::(conn) @@ -59,7 +61,7 @@ impl Crud for Community { impl Community { pub fn read_from_name(conn: &PgConnection, community_name: String) -> Result { - use schema::community::dsl::*; + use crate::schema::community::dsl::*; community.filter(name.eq(community_name)) .first::(conn) } @@ -84,14 +86,14 @@ pub struct CommunityModeratorForm { impl Joinable for CommunityModerator { fn join(conn: &PgConnection, community_user_form: &CommunityModeratorForm) -> Result { - use schema::community_moderator::dsl::*; + use crate::schema::community_moderator::dsl::*; insert_into(community_moderator) .values(community_user_form) .get_result::(conn) } fn leave(conn: &PgConnection, community_user_form: &CommunityModeratorForm) -> Result { - use schema::community_moderator::dsl::*; + use crate::schema::community_moderator::dsl::*; diesel::delete(community_moderator .filter(community_id.eq(community_user_form.community_id)) .filter(user_id.eq(community_user_form.user_id))) @@ -99,6 +101,16 @@ impl Joinable for CommunityModerator { } } +impl CommunityModerator { + pub fn delete_for_community(conn: &PgConnection, for_community_id: i32) -> Result { + use crate::schema::community_moderator::dsl::*; + diesel::delete( + community_moderator + .filter(community_id.eq(for_community_id))) + .execute(conn) + } +} + #[derive(Identifiable, Queryable, Associations, PartialEq, Debug)] #[belongs_to(Community)] #[table_name = "community_user_ban"] @@ -118,14 +130,14 @@ pub struct CommunityUserBanForm { impl Bannable for CommunityUserBan { fn ban(conn: &PgConnection, community_user_ban_form: &CommunityUserBanForm) -> Result { - use schema::community_user_ban::dsl::*; + use crate::schema::community_user_ban::dsl::*; insert_into(community_user_ban) .values(community_user_ban_form) .get_result::(conn) } fn unban(conn: &PgConnection, community_user_ban_form: &CommunityUserBanForm) -> Result { - use schema::community_user_ban::dsl::*; + use crate::schema::community_user_ban::dsl::*; diesel::delete(community_user_ban .filter(community_id.eq(community_user_ban_form.community_id)) .filter(user_id.eq(community_user_ban_form.user_id))) @@ -152,13 +164,13 @@ pub struct CommunityFollowerForm { impl Followable for CommunityFollower { fn follow(conn: &PgConnection, community_follower_form: &CommunityFollowerForm) -> Result { - use schema::community_follower::dsl::*; + use crate::schema::community_follower::dsl::*; insert_into(community_follower) .values(community_follower_form) .get_result::(conn) } fn ignore(conn: &PgConnection, community_follower_form: &CommunityFollowerForm) -> Result { - use schema::community_follower::dsl::*; + use crate::schema::community_follower::dsl::*; diesel::delete(community_follower .filter(community_id.eq(&community_follower_form.community_id)) .filter(user_id.eq(&community_follower_form.user_id))) @@ -188,25 +200,25 @@ pub struct SiteForm { impl Crud for Site { fn read(conn: &PgConnection, _site_id: i32) -> Result { - use schema::site::dsl::*; + use crate::schema::site::dsl::*; site.first::(conn) } fn delete(conn: &PgConnection, site_id: i32) -> Result { - use schema::site::dsl::*; + use crate::schema::site::dsl::*; diesel::delete(site.find(site_id)) .execute(conn) } fn create(conn: &PgConnection, new_site: &SiteForm) -> Result { - use schema::site::dsl::*; + use crate::schema::site::dsl::*; insert_into(site) .values(new_site) .get_result::(conn) } fn update(conn: &PgConnection, site_id: i32, new_site: &SiteForm) -> Result { - use schema::site::dsl::*; + use crate::schema::site::dsl::*; diesel::update(site.find(site_id)) .set(new_site) .get_result::(conn) @@ -229,7 +241,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -240,6 +253,7 @@ mod tests { title: "nada".to_owned(), description: None, category_id: 1, + nsfw: false, removed: None, deleted: None, updated: None, @@ -254,6 +268,7 @@ mod tests { title: "nada".to_owned(), description: None, category_id: 1, + nsfw: false, removed: false, deleted: false, published: inserted_community.published, diff --git a/server/src/db/community_view.rs b/server/src/db/community_view.rs index ec77cc8f..a12d6bf9 100644 --- a/server/src/db/community_view.rs +++ b/server/src/db/community_view.rs @@ -12,6 +12,7 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + nsfw -> Bool, creator_name -> Varchar, category_name -> Varchar, number_of_subscribers -> BigInt, @@ -57,18 +58,19 @@ table! { } table! { - site_view (id) { - id -> Int4, - name -> Varchar, - description -> Nullable, - creator_id -> Int4, - published -> Timestamp, - updated -> Nullable, - creator_name -> Varchar, - number_of_users -> BigInt, - number_of_posts -> BigInt, - number_of_comments -> BigInt, - } + site_view (id) { + id -> Int4, + name -> Varchar, + description -> Nullable, + creator_id -> Int4, + published -> Timestamp, + updated -> Nullable, + creator_name -> Varchar, + number_of_users -> BigInt, + number_of_posts -> BigInt, + number_of_comments -> BigInt, + number_of_communities -> BigInt, + } } #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize,QueryableByName,Clone)] @@ -84,6 +86,7 @@ pub struct CommunityView { pub published: chrono::NaiveDateTime, pub updated: Option, pub deleted: bool, + pub nsfw: bool, pub creator_name: String, pub category_name: String, pub number_of_subscribers: i64, @@ -112,30 +115,43 @@ impl CommunityView { query.first::(conn) } - pub fn list(conn: &PgConnection, - from_user_id: Option, - sort: SortType, - page: Option, - limit: Option, - ) -> Result, Error> { + pub fn list( + conn: &PgConnection, + sort: &SortType, + from_user_id: Option, + show_nsfw: bool, + search_term: Option, + page: Option, + limit: Option, + ) -> Result, Error> { use super::community_view::community_view::dsl::*; let mut query = community_view.into_boxed(); let (limit, offset) = limit_and_offset(page, limit); + if let Some(search_term) = search_term { + query = query.filter(name.ilike(fuzzy_search(&search_term))); + }; + // The view lets you pass a null user_id, if you're not logged in match sort { - SortType::Hot => query = query.order_by(hot_rank.desc()).filter(user_id.is_null()), - SortType::New => query = query.order_by(published.desc()).filter(user_id.is_null()), - SortType::TopAll => { - match from_user_id { - Some(from_user_id) => query = query.filter(user_id.eq(from_user_id)).order_by((subscribed.asc(), number_of_subscribers.desc())), - None => query = query.order_by(number_of_subscribers.desc()).filter(user_id.is_null()) + SortType::Hot => query = query.order_by(hot_rank.desc()) + .then_order_by(number_of_subscribers.desc()) + .filter(user_id.is_null()), + SortType::New => query = query.order_by(published.desc()).filter(user_id.is_null()), + SortType::TopAll => { + match from_user_id { + Some(from_user_id) => query = query.filter(user_id.eq(from_user_id)).order_by((subscribed.asc(), number_of_subscribers.desc())), + None => query = query.order_by(number_of_subscribers.desc()).filter(user_id.is_null()) + } } - } _ => () }; + if !show_nsfw { + query = query.filter(nsfw.eq(false)); + }; + query .limit(limit) .offset(offset) @@ -238,6 +254,7 @@ pub struct SiteView { pub number_of_users: i64, pub number_of_posts: i64, pub number_of_comments: i64, + pub number_of_communities: i64, } impl SiteView { diff --git a/server/src/db/mod.rs b/server/src/db/mod.rs index c3587c47..3de0abb4 100644 --- a/server/src/db/mod.rs +++ b/server/src/db/mod.rs @@ -1,7 +1,7 @@ use diesel::*; use diesel::dsl::*; use diesel::result::Error; -use {Settings}; +use crate::{Settings}; use serde::{Deserialize, Serialize}; pub mod user; @@ -67,7 +67,7 @@ pub enum SortType { #[derive(EnumString,ToString,Debug, Serialize, Deserialize)] pub enum SearchType { - Both, Comments, Posts + All, Comments, Posts, Communities, Users, Url } pub fn fuzzy_search(q: &str) -> String { diff --git a/server/src/db/moderator.rs b/server/src/db/moderator.rs index 8b85e663..fec46aa1 100644 --- a/server/src/db/moderator.rs +++ b/server/src/db/moderator.rs @@ -1,4 +1,4 @@ -use schema::{mod_remove_post, mod_lock_post, mod_remove_comment, mod_remove_community, mod_ban_from_community, mod_ban, mod_add_community, mod_add}; +use crate::schema::{mod_remove_post, mod_lock_post, mod_remove_comment, mod_remove_community, mod_ban_from_community, mod_ban, mod_add_community, mod_add}; use super::*; #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -23,26 +23,26 @@ pub struct ModRemovePostForm { impl Crud for ModRemovePost { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; mod_remove_post.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; diesel::delete(mod_remove_post.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModRemovePostForm) -> Result { - use schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; insert_into(mod_remove_post) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModRemovePostForm) -> Result { - use schema::mod_remove_post::dsl::*; + use crate::schema::mod_remove_post::dsl::*; diesel::update(mod_remove_post.find(from_id)) .set(form) .get_result::(conn) @@ -71,26 +71,26 @@ pub struct ModLockPostForm { impl Crud for ModLockPost { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; mod_lock_post.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; diesel::delete(mod_lock_post.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModLockPostForm) -> Result { - use schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; insert_into(mod_lock_post) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModLockPostForm) -> Result { - use schema::mod_lock_post::dsl::*; + use crate::schema::mod_lock_post::dsl::*; diesel::update(mod_lock_post.find(from_id)) .set(form) .get_result::(conn) @@ -119,26 +119,26 @@ pub struct ModRemoveCommentForm { impl Crud for ModRemoveComment { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; mod_remove_comment.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; diesel::delete(mod_remove_comment.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModRemoveCommentForm) -> Result { - use schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; insert_into(mod_remove_comment) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModRemoveCommentForm) -> Result { - use schema::mod_remove_comment::dsl::*; + use crate::schema::mod_remove_comment::dsl::*; diesel::update(mod_remove_comment.find(from_id)) .set(form) .get_result::(conn) @@ -169,26 +169,26 @@ pub struct ModRemoveCommunityForm { impl Crud for ModRemoveCommunity { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; mod_remove_community.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; diesel::delete(mod_remove_community.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModRemoveCommunityForm) -> Result { - use schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; insert_into(mod_remove_community) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModRemoveCommunityForm) -> Result { - use schema::mod_remove_community::dsl::*; + use crate::schema::mod_remove_community::dsl::*; diesel::update(mod_remove_community.find(from_id)) .set(form) .get_result::(conn) @@ -221,26 +221,26 @@ pub struct ModBanFromCommunityForm { impl Crud for ModBanFromCommunity { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; mod_ban_from_community.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; diesel::delete(mod_ban_from_community.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModBanFromCommunityForm) -> Result { - use schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; insert_into(mod_ban_from_community) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModBanFromCommunityForm) -> Result { - use schema::mod_ban_from_community::dsl::*; + use crate::schema::mod_ban_from_community::dsl::*; diesel::update(mod_ban_from_community.find(from_id)) .set(form) .get_result::(conn) @@ -272,26 +272,26 @@ pub struct ModBanForm { impl Crud for ModBan { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; mod_ban.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; diesel::delete(mod_ban.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModBanForm) -> Result { - use schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; insert_into(mod_ban) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModBanForm) -> Result { - use schema::mod_ban::dsl::*; + use crate::schema::mod_ban::dsl::*; diesel::update(mod_ban.find(from_id)) .set(form) .get_result::(conn) @@ -320,26 +320,26 @@ pub struct ModAddCommunityForm { impl Crud for ModAddCommunity { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; mod_add_community.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; diesel::delete(mod_add_community.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModAddCommunityForm) -> Result { - use schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; insert_into(mod_add_community) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModAddCommunityForm) -> Result { - use schema::mod_add_community::dsl::*; + use crate::schema::mod_add_community::dsl::*; diesel::update(mod_add_community.find(from_id)) .set(form) .get_result::(conn) @@ -366,26 +366,26 @@ pub struct ModAddForm { impl Crud for ModAdd { fn read(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; mod_add.find(from_id) .first::(conn) } fn delete(conn: &PgConnection, from_id: i32) -> Result { - use schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; diesel::delete(mod_add.find(from_id)) .execute(conn) } fn create(conn: &PgConnection, form: &ModAddForm) -> Result { - use schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; insert_into(mod_add) .values(form) .get_result::(conn) } fn update(conn: &PgConnection, from_id: i32, form: &ModAddForm) -> Result { - use schema::mod_add::dsl::*; + use crate::schema::mod_add::dsl::*; diesel::update(mod_add.find(from_id)) .set(form) .get_result::(conn) @@ -412,7 +412,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_mod = User_::create(&conn, &new_mod).unwrap(); @@ -425,7 +426,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -438,7 +440,8 @@ mod tests { creator_id: inserted_user.id, removed: None, deleted: None, - updated: None + updated: None, + nsfw: false, }; let inserted_community = Community::create(&conn, &new_community).unwrap(); @@ -452,7 +455,8 @@ mod tests { removed: None, deleted: None, locked: None, - updated: None + updated: None, + nsfw: false, }; let inserted_post = Post::create(&conn, &new_post).unwrap(); diff --git a/server/src/db/post.rs b/server/src/db/post.rs index f0302271..12ea1081 100644 --- a/server/src/db/post.rs +++ b/server/src/db/post.rs @@ -1,4 +1,4 @@ -use schema::{post, post_like, post_saved, post_read}; +use crate::schema::{post, post_like, post_saved, post_read}; use super::*; #[derive(Queryable, Identifiable, PartialEq, Debug, Serialize, Deserialize)] @@ -15,6 +15,7 @@ pub struct Post { pub published: chrono::NaiveDateTime, pub updated: Option, pub deleted: bool, + pub nsfw: bool, } #[derive(Insertable, AsChangeset, Clone)] @@ -29,30 +30,31 @@ pub struct PostForm { pub locked: Option, pub updated: Option, pub deleted: Option, + pub nsfw: bool, } impl Crud for Post { fn read(conn: &PgConnection, post_id: i32) -> Result { - use schema::post::dsl::*; + use crate::schema::post::dsl::*; post.find(post_id) .first::(conn) } fn delete(conn: &PgConnection, post_id: i32) -> Result { - use schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::delete(post.find(post_id)) .execute(conn) } fn create(conn: &PgConnection, new_post: &PostForm) -> Result { - use schema::post::dsl::*; + use crate::schema::post::dsl::*; insert_into(post) .values(new_post) .get_result::(conn) } fn update(conn: &PgConnection, post_id: i32, new_post: &PostForm) -> Result { - use schema::post::dsl::*; + use crate::schema::post::dsl::*; diesel::update(post.find(post_id)) .set(new_post) .get_result::(conn) @@ -80,19 +82,19 @@ pub struct PostLikeForm { impl Likeable for PostLike { fn read(conn: &PgConnection, post_id_from: i32) -> Result, Error> { - use schema::post_like::dsl::*; + use crate::schema::post_like::dsl::*; post_like .filter(post_id.eq(post_id_from)) .load::(conn) } fn like(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result { - use schema::post_like::dsl::*; + use crate::schema::post_like::dsl::*; insert_into(post_like) .values(post_like_form) .get_result::(conn) } fn remove(conn: &PgConnection, post_like_form: &PostLikeForm) -> Result { - use schema::post_like::dsl::*; + use crate::schema::post_like::dsl::*; diesel::delete(post_like .filter(post_id.eq(post_like_form.post_id)) .filter(user_id.eq(post_like_form.user_id))) @@ -119,13 +121,13 @@ pub struct PostSavedForm { impl Saveable for PostSaved { fn save(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result { - use schema::post_saved::dsl::*; + use crate::schema::post_saved::dsl::*; insert_into(post_saved) .values(post_saved_form) .get_result::(conn) } fn unsave(conn: &PgConnection, post_saved_form: &PostSavedForm) -> Result { - use schema::post_saved::dsl::*; + use crate::schema::post_saved::dsl::*; diesel::delete(post_saved .filter(post_id.eq(post_saved_form.post_id)) .filter(user_id.eq(post_saved_form.user_id))) @@ -152,13 +154,13 @@ pub struct PostReadForm { impl Readable for PostRead { fn mark_as_read(conn: &PgConnection, post_read_form: &PostReadForm) -> Result { - use schema::post_read::dsl::*; + use crate::schema::post_read::dsl::*; insert_into(post_read) .values(post_read_form) .get_result::(conn) } fn mark_as_unread(conn: &PgConnection, post_read_form: &PostReadForm) -> Result { - use schema::post_read::dsl::*; + use crate::schema::post_read::dsl::*; diesel::delete(post_read .filter(post_id.eq(post_read_form.post_id)) .filter(user_id.eq(post_read_form.user_id))) @@ -183,7 +185,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -196,7 +199,8 @@ mod tests { creator_id: inserted_user.id, removed: None, deleted: None, - updated: None + updated: None, + nsfw: false, }; let inserted_community = Community::create(&conn, &new_community).unwrap(); @@ -210,6 +214,7 @@ mod tests { removed: None, deleted: None, locked: None, + nsfw: false, updated: None }; @@ -225,6 +230,7 @@ mod tests { published: inserted_post.published, removed: false, locked: false, + nsfw: false, deleted: false, updated: None }; diff --git a/server/src/db/post_view.rs b/server/src/db/post_view.rs index bfe730a2..c9d8cff7 100644 --- a/server/src/db/post_view.rs +++ b/server/src/db/post_view.rs @@ -19,10 +19,12 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + nsfw -> Bool, creator_name -> Varchar, community_name -> Varchar, community_removed -> Bool, community_deleted -> Bool, + community_nsfw -> Bool, number_of_comments -> BigInt, score -> BigInt, upvotes -> BigInt, @@ -51,10 +53,12 @@ pub struct PostView { pub published: chrono::NaiveDateTime, pub updated: Option, pub deleted: bool, + pub nsfw: bool, pub creator_name: String, pub community_name: String, pub community_removed: bool, pub community_deleted: bool, + pub community_nsfw: bool, pub number_of_comments: i64, pub score: i64, pub upvotes: i64, @@ -68,18 +72,21 @@ pub struct PostView { } impl PostView { - pub fn list(conn: &PgConnection, - type_: PostListingType, - sort: &SortType, - for_community_id: Option, - for_creator_id: Option, - search_term: Option, - my_user_id: Option, - saved_only: bool, - unread_only: bool, - page: Option, - limit: Option, - ) -> Result, Error> { + pub fn list( + conn: &PgConnection, + type_: PostListingType, + sort: &SortType, + for_community_id: Option, + for_creator_id: Option, + search_term: Option, + url_search: Option, + my_user_id: Option, + show_nsfw: bool, + saved_only: bool, + unread_only: bool, + page: Option, + limit: Option, + ) -> Result, Error> { use super::post_view::post_view::dsl::*; let (limit, offset) = limit_and_offset(page, limit); @@ -98,6 +105,10 @@ impl PostView { query = query.filter(name.ilike(fuzzy_search(&search_term))); }; + if let Some(url_search) = url_search { + query = query.filter(url.eq(url_search)); + }; + // TODO these are wrong, bc they'll only show saved for your logged in user, not theirs if saved_only { query = query.filter(saved.eq(true)); @@ -121,8 +132,15 @@ impl PostView { query = query.filter(user_id.is_null()); } + if !show_nsfw { + query = query + .filter(nsfw.eq(false)) + .filter(community_nsfw.eq(false)); + }; + query = match sort { - SortType::Hot => query.order_by(hot_rank.desc()), + SortType::Hot => query.order_by(hot_rank.desc()) + .then_order_by(published.desc()), SortType::New => query.order_by(published.desc()), SortType::TopAll => query.order_by(score.desc()), SortType::TopYear => query @@ -195,6 +213,7 @@ mod tests { updated: None, admin: false, banned: false, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -207,7 +226,8 @@ mod tests { category_id: 1, removed: None, deleted: None, - updated: None + updated: None, + nsfw: false, }; let inserted_community = Community::create(&conn, &new_community).unwrap(); @@ -221,7 +241,8 @@ mod tests { removed: None, deleted: None, locked: None, - updated: None + updated: None, + nsfw: false, }; let inserted_post = Post::create(&conn, &new_post).unwrap(); @@ -265,6 +286,7 @@ mod tests { community_name: community_name.to_owned(), community_removed: false, community_deleted: false, + community_nsfw: false, number_of_comments: 0, score: 1, upvotes: 1, @@ -275,6 +297,7 @@ mod tests { subscribed: None, read: None, saved: None, + nsfw: false, }; let expected_post_listing_with_user = PostView { @@ -293,6 +316,7 @@ mod tests { community_name: community_name.to_owned(), community_removed: false, community_deleted: false, + community_nsfw: false, number_of_comments: 0, score: 1, upvotes: 1, @@ -303,30 +327,38 @@ mod tests { subscribed: None, read: None, saved: None, + nsfw: false, }; - let read_post_listings_with_user = PostView::list(&conn, - PostListingType::Community, - &SortType::New, Some(inserted_community.id), - None, - None, - Some(inserted_user.id), - false, - false, - None, - None).unwrap(); - let read_post_listings_no_user = PostView::list(&conn, - PostListingType::Community, - &SortType::New, - Some(inserted_community.id), - None, - None, - None, - false, - false, - None, - None).unwrap(); + let read_post_listings_with_user = PostView::list( + &conn, + PostListingType::Community, + &SortType::New, + Some(inserted_community.id), + None, + None, + None, + Some(inserted_user.id), + false, + false, + false, + None, + None).unwrap(); + let read_post_listings_no_user = PostView::list( + &conn, + PostListingType::Community, + &SortType::New, + Some(inserted_community.id), + None, + None, + None, + None, + false, + false, + false, + None, + None).unwrap(); let read_post_listing_no_user = PostView::read(&conn, inserted_post.id, None).unwrap(); let read_post_listing_with_user = PostView::read(&conn, inserted_post.id, Some(inserted_user.id)).unwrap(); diff --git a/server/src/db/user.rs b/server/src/db/user.rs index a4a7be43..b794524c 100644 --- a/server/src/db/user.rs +++ b/server/src/db/user.rs @@ -1,7 +1,7 @@ -use schema::user_; -use schema::user_::dsl::*; +use crate::schema::user_; +use crate::schema::user_::dsl::*; use super::*; -use {Settings, is_email_regex}; +use crate::{Settings, is_email_regex}; use jsonwebtoken::{encode, decode, Header, Validation, TokenData}; use bcrypt::{DEFAULT_COST, hash}; @@ -18,7 +18,8 @@ pub struct User_ { pub admin: bool, pub banned: bool, pub published: chrono::NaiveDateTime, - pub updated: Option + pub updated: Option, + pub show_nsfw: bool, } #[derive(Insertable, AsChangeset, Clone)] @@ -31,12 +32,13 @@ pub struct UserForm { pub admin: bool, pub banned: bool, pub email: Option, - pub updated: Option + pub updated: Option, + pub show_nsfw: bool, } impl Crud for User_ { fn read(conn: &PgConnection, user_id: i32) -> Result { - use schema::user_::dsl::*; + use crate::schema::user_::dsl::*; user_.find(user_id) .first::(conn) } @@ -77,6 +79,7 @@ pub struct Claims { pub id: i32, pub username: String, pub iss: String, + pub show_nsfw: bool, } impl Claims { @@ -96,6 +99,7 @@ impl User_ { id: self.id, username: self.name.to_owned(), iss: self.fedi_name.to_owned(), + show_nsfw: self.show_nsfw, }; encode(&Header::default(), &my_claims, Settings::get().jwt_secret.as_ref()).unwrap() } @@ -133,7 +137,8 @@ mod tests { email: None, admin: false, banned: false, - updated: None + updated: None, + show_nsfw: false, }; let inserted_user = User_::create(&conn, &new_user).unwrap(); @@ -149,7 +154,8 @@ mod tests { admin: false, banned: false, published: inserted_user.published, - updated: None + updated: None, + show_nsfw: false, }; let read_user = User_::read(&conn, inserted_user.id).unwrap(); diff --git a/server/src/db/user_view.rs b/server/src/db/user_view.rs index 3d78ae1a..897ee23a 100644 --- a/server/src/db/user_view.rs +++ b/server/src/db/user_view.rs @@ -31,6 +31,49 @@ pub struct UserView { } impl UserView { + + pub fn list(conn: &PgConnection, + sort: &SortType, + search_term: Option, + page: Option, + limit: Option, + ) -> Result, Error> { + use super::user_view::user_view::dsl::*; + + let (limit, offset) = limit_and_offset(page, limit); + + let mut query = user_view.into_boxed(); + + if let Some(search_term) = search_term { + query = query.filter(name.ilike(fuzzy_search(&search_term))); + }; + + query = match sort { + SortType::Hot => query.order_by(comment_score.desc()) + .then_order_by(published.desc()), + SortType::New => query.order_by(published.desc()), + SortType::TopAll => query.order_by(comment_score.desc()), + SortType::TopYear => query + .filter(published.gt(now - 1.years())) + .order_by(comment_score.desc()), + SortType::TopMonth => query + .filter(published.gt(now - 1.months())) + .order_by(comment_score.desc()), + SortType::TopWeek => query + .filter(published.gt(now - 1.weeks())) + .order_by(comment_score.desc()), + SortType::TopDay => query + .filter(published.gt(now - 1.days())) + .order_by(comment_score.desc()) + }; + + query = query + .limit(limit) + .offset(offset); + + query.load::(conn) + } + pub fn read(conn: &PgConnection, from_user_id: i32) -> Result { use super::user_view::user_view::dsl::*; diff --git a/server/src/lib.rs b/server/src/lib.rs index 7dd090d6..04076771 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,3 +1,4 @@ +#![recursion_limit = "512"] #[macro_use] pub extern crate strum_macros; #[macro_use] pub extern crate lazy_static; #[macro_use] pub extern crate failure; @@ -72,7 +73,7 @@ pub fn has_slurs(test: &str) -> bool { #[cfg(test)] mod tests { - use {Settings, is_email_regex, remove_slurs, has_slurs}; + use crate::{Settings, is_email_regex, remove_slurs, has_slurs}; #[test] fn test_api() { assert_eq!(Settings::get().api_endpoint(), "rrr/api/v1"); diff --git a/server/src/main.rs b/server/src/main.rs index 48074316..5e9a1dae 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,13 +1,15 @@ extern crate lemmy_server; -#[macro_use] extern crate diesel_migrations; +#[macro_use] +extern crate diesel_migrations; -use std::time::{Instant, Duration}; -use std::env; -use lemmy_server::actix::*; -use lemmy_server::actix_web::server::HttpServer; -use lemmy_server::actix_web::{ws, App, Error, HttpRequest, HttpResponse, fs::NamedFile, fs}; -use lemmy_server::websocket::server::*; +use actix::prelude::*; +use actix_files::NamedFile; +use actix_web::*; +use actix_web_actors::ws; use lemmy_server::db::establish_connection; +use lemmy_server::websocket::server::*; +use std::env; +use std::time::{Duration, Instant}; embed_migrations!(); @@ -16,41 +18,43 @@ const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5); /// How long before lack of client response causes a timeout const CLIENT_TIMEOUT: Duration = Duration::from_secs(10); -/// This is our websocket route state, this state is shared with all route -/// instances via `HttpContext::state()` -struct WsChatSessionState { - addr: Addr, -} - /// Entry point for our route -fn chat_route(req: &HttpRequest) -> Result { +fn chat_route( + req: HttpRequest, + stream: web::Payload, + chat_server: web::Data>, + ) -> Result { ws::start( - req, WSSession { + cs_addr: chat_server.get_ref().to_owned(), id: 0, hb: Instant::now(), - ip: req.connection_info() + ip: req + .connection_info() .remote() .unwrap_or("127.0.0.1:12345") .split(":") .next() .unwrap_or("127.0.0.1") - .to_string() + .to_string(), }, + &req, + stream, ) } struct WSSession { + cs_addr: Addr, /// unique session id id: usize, ip: String, /// Client must send ping at least once per 10 seconds (CLIENT_TIMEOUT), /// otherwise we drop connection. - hb: Instant + hb: Instant, } impl Actor for WSSession { - type Context = ws::WebsocketContext; + type Context = ws::WebsocketContext; /// Method is called on actor start. /// We register ws session with ChatServer @@ -61,11 +65,9 @@ impl Actor for WSSession { // register self in chat server. `AsyncContext::wait` register // future within context, but context waits until this future resolves // before processing any other events. - // HttpContext::state() is instance of WsChatSessionState, state is shared // across all routes within application let addr = ctx.address(); - ctx.state() - .addr + self.cs_addr .send(Connect { addr: addr.recipient(), ip: self.ip.to_owned(), @@ -82,9 +84,9 @@ impl Actor for WSSession { .wait(ctx); } - fn stopping(&mut self, ctx: &mut Self::Context) -> Running { + fn stopping(&mut self, _ctx: &mut Self::Context) -> Running { // notify chat server - ctx.state().addr.do_send(Disconnect { + self.cs_addr.do_send(Disconnect { id: self.id, ip: self.ip.to_owned(), }); @@ -118,9 +120,8 @@ impl StreamHandler for WSSession { ws::Message::Text(text) => { let m = text.trim().to_owned(); println!("WEBSOCKET MESSAGE: {:?} from id: {}", &m, self.id); - - ctx.state() - .addr + + self.cs_addr .send(StandardMessage { id: self.id, msg: m, @@ -140,7 +141,8 @@ impl StreamHandler for WSSession { ws::Message::Binary(_bin) => println!("Unexpected binary"), ws::Message::Close(_) => { ctx.stop(); - }, + } + _ => {} } } } @@ -149,7 +151,7 @@ impl WSSession { /// helper method that sends ping to client every second. /// /// also this method checks heartbeats from client - fn hb(&self, ctx: &mut ws::WebsocketContext) { + fn hb(&self, ctx: &mut ws::WebsocketContext) { ctx.run_interval(HEARTBEAT_INTERVAL, |act, ctx| { // check client heartbeats if Instant::now().duration_since(act.hb) > CLIENT_TIMEOUT { @@ -157,9 +159,10 @@ impl WSSession { println!("Websocket Client heartbeat failed, disconnecting!"); // notify chat server - ctx.state() - .addr - .do_send(Disconnect { id: act.id, ip: act.ip.to_owned() }); + act.cs_addr.do_send(Disconnect { + id: act.id, + ip: act.ip.to_owned(), + }); // stop actor ctx.stop(); @@ -182,34 +185,26 @@ fn main() { embedded_migrations::run(&conn).unwrap(); // Start chat server actor in separate thread - let server = Arbiter::start(|_| ChatServer::default()); - + let server = ChatServer::default().start(); // Create Http server with websocket support HttpServer::new(move || { - // Websocket sessions state - let state = WsChatSessionState { - addr: server.clone(), - }; - - App::with_state(state) - // .resource("/api/v1/rest", |r| r.method(http::Method::POST).f(|_| {}) - .resource("/api/v1/ws", |r| r.route().f(chat_route)) + App::new() + .data(server.clone()) + .service(web::resource("/api/v1/ws").to(chat_route)) + // .service(web::resource("/api/v1/rest").route(web::post().to(||{}))) + .service(web::resource("/").to(index)) // static resources - .resource("/", |r| r.route().f(index)) - .handler( - "/static", - fs::StaticFiles::new(front_end_dir()).unwrap() - ) - .finish() - }).bind("0.0.0.0:8536") - .unwrap() + .service(actix_files::Files::new("/static", front_end_dir())) + }) + .bind("0.0.0.0:8536") + .unwrap() .start(); println!("Started http server: 0.0.0.0:8536"); let _ = sys.run(); } -fn index(_req: &HttpRequest) -> Result { +fn index() -> Result { Ok(NamedFile::open(front_end_dir() + "/index.html")?) } diff --git a/server/src/schema.rs b/server/src/schema.rs index 27bc3f94..635c8c46 100644 --- a/server/src/schema.rs +++ b/server/src/schema.rs @@ -52,6 +52,7 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + nsfw -> Bool, } } @@ -185,6 +186,7 @@ table! { published -> Timestamp, updated -> Nullable, deleted -> Bool, + nsfw -> Bool, } } @@ -240,6 +242,7 @@ table! { banned -> Bool, published -> Timestamp, updated -> Nullable, + show_nsfw -> Bool, } } diff --git a/server/src/websocket/server.rs b/server/src/websocket/server.rs index abdf9ea9..b4cbce3a 100644 --- a/server/src/websocket/server.rs +++ b/server/src/websocket/server.rs @@ -11,12 +11,12 @@ use std::str::FromStr; use failure::Error; use std::time::{SystemTime}; -use api::*; -use api::user::*; -use api::community::*; -use api::post::*; -use api::comment::*; -use api::site::*; +use crate::api::*; +use crate::api::user::*; +use crate::api::community::*; +use crate::api::post::*; +use crate::api::comment::*; +use crate::api::site::*; const RATE_LIMIT_MESSAGES: i32 = 30; const RATE_LIMIT_PER_SECOND: i32 = 60; @@ -118,7 +118,7 @@ impl ChatServer { fn join_room(&mut self, room_id: i32, id: usize) { // remove session from all rooms - for (_n, mut sessions) in &mut self.rooms { + for (_n, sessions) in &mut self.rooms { sessions.remove(&id); } @@ -131,20 +131,23 @@ impl ChatServer { } fn send_community_message(&self, community_id: &i32, message: &str, skip_id: usize) -> Result<(), Error> { - use db::*; - use db::post_view::*; + use crate::db::*; + use crate::db::post_view::*; let conn = establish_connection(); - let posts = PostView::list(&conn, - PostListingType::Community, - &SortType::New, - Some(*community_id), - None, - None, - None, - false, - false, - None, - Some(9999))?; + let posts = PostView::list( + &conn, + PostListingType::Community, + &SortType::New, + Some(*community_id), + None, + None, + None, + None, + false, + false, + false, + None, + Some(9999))?; for post in posts { self.send_room_message(&post.id, message, skip_id); } @@ -303,6 +306,11 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { + let save_user_settings: SaveUserSettings = serde_json::from_str(data)?; + let res = Oper::new(user_operation, save_user_settings).perform()?; + Ok(serde_json::to_string(&res)?) + }, UserOperation::AddAdmin => { let add_admin: AddAdmin = serde_json::from_str(data)?; let res = Oper::new(user_operation, add_admin).perform()?; @@ -482,5 +490,15 @@ fn parse_json_message(chat: &mut ChatServer, msg: StandardMessage) -> Result { + let transfer_community: TransferCommunity = serde_json::from_str(data)?; + let res = Oper::new(user_operation, transfer_community).perform()?; + Ok(serde_json::to_string(&res)?) + }, + UserOperation::TransferSite => { + let transfer_site: TransferSite = serde_json::from_str(data)?; + let res = Oper::new(user_operation, transfer_site).perform()?; + Ok(serde_json::to_string(&res)?) + }, } } diff --git a/server/stack.dev.yaml b/server/stack.dev.yaml deleted file mode 100644 index 7c6905b3..00000000 --- a/server/stack.dev.yaml +++ /dev/null @@ -1,111 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: postgres -data: - POSTGRES_PASSWORD: rrr - POSTGRES_USER: rrr - POSTGRES_DB: rrr - PGDATA: /var/lib/postgresql/data/pgdata - DATABASE_URL: postgres://rrr:rrr@postgres:5432/rrr ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: postgres -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: postgres -spec: - selector: - matchLabels: - app: postgres - template: - metadata: - labels: - app: postgres - spec: - containers: - - name: postgres - image: postgres:11.2-alpine - resources: - limits: - memory: 256Mi - cpu: 512m - ports: - - containerPort: 5432 - envFrom: - - configMapRef: - name: postgres - volumeMounts: - - name: postgres - mountPath: /var/lib/postgresql/data - volumes: - - name: postgres - persistentVolumeClaim: - claimName: postgres ---- -apiVersion: v1 -kind: Service -metadata: - name: postgres -spec: - selector: - app: postgres - ports: - - port: 5432 ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: lemmy-server--dev -data: - LEMMY_FRONT_END_DIR: /opt/lemmy/ui--dev/dist # not actually used here, polyfill for monolith ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: lemmy-server--dev -spec: - selector: - matchLabels: - app: lemmy-server--dev - template: - metadata: - labels: - app: lemmy-server--dev - spec: - containers: - - name: lemmy-server--dev - image: registry.gitlab.com/pojntfx/lemmy/server.dev - envFrom: - - configMapRef: - name: postgres - - configMapRef: - name: lemmy-server--dev - resources: - limits: - memory: 512Mi - cpu: 512m - ports: - - containerPort: 8536 ---- -apiVersion: v1 -kind: Service -metadata: - name: lemmy-server--dev -spec: - type: NodePort - selector: - app: lemmy-server--dev - ports: - - port: 8536 - nodePort: 30001 diff --git a/server/stack.prod.yaml b/server/stack.prod.yaml deleted file mode 100644 index d221de16..00000000 --- a/server/stack.prod.yaml +++ /dev/null @@ -1,110 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: postgres -data: - POSTGRES_PASSWORD: rrr - POSTGRES_USER: rrr - POSTGRES_DB: rrr - PGDATA: /var/lib/postgresql/data/pgdata - DATABASE_URL: postgres://rrr:rrr@postgres:5432/rrr ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: postgres -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: postgres -spec: - selector: - matchLabels: - app: postgres - template: - metadata: - labels: - app: postgres - spec: - containers: - - name: postgres - image: postgres:11.2-alpine - resources: - limits: - memory: 256Mi - cpu: 512m - ports: - - containerPort: 5432 - envFrom: - - configMapRef: - name: postgres - volumeMounts: - - name: postgres - mountPath: /var/lib/postgresql/data - volumes: - - name: postgres - persistentVolumeClaim: - claimName: postgres ---- -apiVersion: v1 -kind: Service -metadata: - name: postgres -spec: - selector: - app: postgres - ports: - - port: 5432 ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: lemmy-server--prod -data: - LEMMY_FRONT_END_DIR: /opt/lemmy/ui--prod/dist # not actually used here, polyfill for monolith ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: lemmy-server--prod -spec: - selector: - matchLabels: - app: lemmy-server--prod - template: - metadata: - labels: - app: lemmy-server--prod - spec: - containers: - - name: lemmy-server--prod - image: registry.gitlab.com/pojntfx/lemmy/server.prod - envFrom: - - configMapRef: - name: postgres - - configMapRef: - name: lemmy-server--prod - resources: - limits: - memory: 512Mi - cpu: 512m - ports: - - containerPort: 8536 ---- -apiVersion: v1 -kind: Service -metadata: - name: lemmy-server--prod -spec: - selector: - app: lemmy-server--prod - ports: - - port: 8536 - targetPort: 8536 diff --git a/skaffold.yaml b/skaffold.yaml deleted file mode 100644 index 9aeaa585..00000000 --- a/skaffold.yaml +++ /dev/null @@ -1,37 +0,0 @@ -apiVersion: skaffold/v1beta9 -kind: Config -profiles: - - name: lemmy--dev - build: - artifacts: - - image: registry.gitlab.com/pojntfx/lemmy/server.dev - context: server - docker: - dockerfile: Dockerfile.dev - - image: registry.gitlab.com/pojntfx/lemmy/ui.dev - context: ui - docker: - dockerfile: Dockerfile.dev - sync: - "***/*.ts": . - "***/*.tsx": . - "***/*.css": . - deploy: - kubectl: - manifests: - - "**/*.dev.yaml" - - name: lemmy--prod - build: - artifacts: - - image: registry.gitlab.com/pojntfx/lemmy/server.prod - context: server - docker: - dockerfile: Dockerfile.prod - - image: registry.gitlab.com/pojntfx/lemmy/ui.prod - context: ui - docker: - dockerfile: Dockerfile.prod - deploy: - kubectl: - manifests: - - "**/*.prod.yaml" diff --git a/ui/Dockerfile.dev b/ui/Dockerfile.dev deleted file mode 100644 index 37f9e34c..00000000 --- a/ui/Dockerfile.dev +++ /dev/null @@ -1,12 +0,0 @@ -# Setup env -FROM node:10-alpine -RUN mkdir -p /opt/lemmy/ui--dev -WORKDIR /opt/lemmy/ui--dev -# Install deps -COPY package.json . -COPY yarn.lock . -RUN npm install -# Add app -COPY . . -# Run app -CMD ["npm", "start"] diff --git a/ui/Dockerfile.prod b/ui/Dockerfile.prod deleted file mode 100644 index 9c478e67..00000000 --- a/ui/Dockerfile.prod +++ /dev/null @@ -1,22 +0,0 @@ -# Setup env -FROM node:10-alpine AS build -RUN mkdir -p /opt/lemmy/ui--prod -WORKDIR /opt/lemmy/ui--prod -# Install deps -COPY package.json . -COPY yarn.lock . -RUN npm install -# Add app -COPY . . -# Build app -RUN npm run build - -# Setup env -FROM node:10-alpine -RUN mkdir -p /opt/lemmy/ui--prod -WORKDIR /opt/lemmy/ui--prod -RUN npm install serve -# Add app -COPY --from=build /opt/lemmy/ui--prod/dist . -# Run app -CMD ["/opt/lemmy/ui--prod/node_modules/.bin/serve", "."] diff --git a/ui/assets/favicon.svg b/ui/assets/favicon.svg index 7a1b2c2a..82545965 100644 --- a/ui/assets/favicon.svg +++ b/ui/assets/favicon.svg @@ -1,53 +1,118 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/ui/fuse.js b/ui/fuse.js index 4755d9f5..85eb75e2 100644 --- a/ui/fuse.js +++ b/ui/fuse.js @@ -24,6 +24,9 @@ Sparky.task('config', _ => { transformers: { before: [transformClasscat(), transformInferno()], }, + alias: { + 'locale': 'moment/locale' + }, plugins: [ EnvPlugin({ NODE_ENV: isProduction ? 'production' : 'development' }), CSSPlugin(), @@ -45,7 +48,7 @@ Sparky.task('config', _ => { // Sparky.task('version', _ => setVersion()); Sparky.task('clean', _ => Sparky.src('dist/').clean('dist/')); Sparky.task('env', _ => (isProduction = true)); -Sparky.task('copy-assets', () => Sparky.src('assets/**/**.*').dest('dist/')); +Sparky.task('copy-assets', () => Sparky.src('assets/**/**.*').dest(isProduction ? 'dist/' : 'dist/static')); Sparky.task('dev', ['clean', 'config', 'copy-assets'], _ => { fuse.dev(); app.hmr().watch(); diff --git a/ui/package.json b/ui/package.json index 7f99e62f..797e45bc 100644 --- a/ui/package.json +++ b/ui/package.json @@ -23,7 +23,9 @@ "autosize": "^4.0.2", "classcat": "^1.1.3", "dotenv": "^6.1.0", + "i18next": "^17.0.9", "inferno": "^7.0.1", + "inferno-i18next": "nimbusec-oss/inferno-i18next", "inferno-router": "^7.0.1", "js-cookie": "^2.2.0", "jwt-decode": "^2.2.0", @@ -32,12 +34,14 @@ "markdown-it-emoji": "^1.4.0", "moment": "^2.24.0", "rxjs": "^6.4.0", - "terser": "^3.17.0" + "terser": "^3.17.0", + "ws": "^7.0.0" }, "devDependencies": { + "@types/i18next": "^12.1.0", "fuse-box": "^3.1.3", "ts-transform-classcat": "^0.0.2", "ts-transform-inferno": "^4.0.2", - "typescript": "^3.3.3333" + "typescript": "^3.5.3" } } diff --git a/ui/src/components/comment-form.tsx b/ui/src/components/comment-form.tsx index a69ae06f..7a75d9e4 100644 --- a/ui/src/components/comment-form.tsx +++ b/ui/src/components/comment-form.tsx @@ -1,7 +1,10 @@ import { Component, linkEvent } from 'inferno'; import { CommentNode as CommentNodeI, CommentForm as CommentFormI } from '../interfaces'; +import { capitalizeFirstLetter } from '../utils'; import { WebSocketService, UserService } from '../services'; import * as autosize from 'autosize'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; interface CommentFormProps { postId?: number; @@ -25,12 +28,13 @@ export class CommentForm extends Component { post_id: this.props.node ? this.props.node.comment.post_id : this.props.postId, creator_id: UserService.Instance.user ? UserService.Instance.user.id : null, }, - buttonTitle: !this.props.node ? "Post" : this.props.edit ? "Edit" : "Reply", + buttonTitle: !this.props.node ? capitalizeFirstLetter(i18n.t('post')) : this.props.edit ? capitalizeFirstLetter(i18n.t('edit')) : capitalizeFirstLetter(i18n.t('reply')), } constructor(props: any, context: any) { super(props, context); + this.state = this.emptyState; if (this.props.node) { @@ -52,7 +56,7 @@ export class CommentForm extends Component { render() { return ( -
+
@@ -62,7 +66,7 @@ export class CommentForm extends Component {
- {this.props.node && } + {this.props.node && }
@@ -84,6 +88,8 @@ export class CommentForm extends Component { if (i.props.node) { i.props.onReplyCancel(); } + + autosize.update(document.querySelector('textarea')); } handleCommentContentChange(i: CommentForm, event: any) { diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx index 126966a7..8779f1f9 100644 --- a/ui/src/components/comment-node.tsx +++ b/ui/src/components/comment-node.tsx @@ -1,12 +1,14 @@ import { Component, linkEvent } from 'inferno'; import { Link } from 'inferno-router'; -import { CommentNode as CommentNodeI, CommentLikeForm, CommentForm as CommentFormI, SaveCommentForm, BanFromCommunityForm, BanUserForm, CommunityUser, UserView, AddModToCommunityForm, AddAdminForm } from '../interfaces'; +import { CommentNode as CommentNodeI, CommentLikeForm, CommentForm as CommentFormI, SaveCommentForm, BanFromCommunityForm, BanUserForm, CommunityUser, UserView, AddModToCommunityForm, AddAdminForm, TransferCommunityForm, TransferSiteForm } from '../interfaces'; import { WebSocketService, UserService } from '../services'; import { mdToHtml, getUnixTime, canMod, isMod } from '../utils'; import * as moment from 'moment'; import { MomentTime } from './moment-time'; import { CommentForm } from './comment-form'; import { CommentNodes } from './comment-nodes'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; enum BanType {Community, Site}; @@ -19,6 +21,9 @@ interface CommentNodeState { banReason: string; banExpires: string; banType: BanType; + collapsed: boolean; + showConfirmTransferSite: boolean; + showConfirmTransferCommunity: boolean; } interface CommentNodeProps { @@ -41,7 +46,10 @@ export class CommentNode extends Component { showBanDialog: false, banReason: null, banExpires: null, - banType: BanType.Community + banType: BanType.Community, + collapsed: false, + showConfirmTransferSite: false, + showConfirmTransferCommunity: false, } constructor(props: any, context: any) { @@ -57,25 +65,25 @@ export class CommentNode extends Component { let node = this.props.node; return (
-
-
+
+
+
{node.comment.score}
-
+
+
-
+
  • {node.comment.creator_name}
  • {this.isMod && -
  • mod
  • +
  • #
  • } {this.isAdmin && -
  • admin
  • +
  • #
  • }
  • ( @@ -88,28 +96,31 @@ export class CommentNode extends Component {
  • +
  • +
    {this.state.collapsed ? '[+]' : '[-]'}
    +
{this.state.showEdit && } - {!this.state.showEdit && + {!this.state.showEdit && !this.state.collapsed &&
-
+
    {UserService.Instance.user && !this.props.viewOnly && <>
  • - reply + #
  • - {node.comment.saved ? 'unsave' : 'save'} + {node.comment.saved ? i18n.t('unsave') : i18n.t('save')}
  • {this.myComment && <>
  • - edit + #
  • - {!this.props.node.comment.deleted ? 'delete' : 'restore'} + {!this.props.node.comment.deleted ? i18n.t('delete') : i18n.t('restore')}
  • @@ -118,8 +129,8 @@ export class CommentNode extends Component { {this.canMod &&
  • {!this.props.node.comment.removed ? - remove : - restore + # : + # }
  • } @@ -129,44 +140,70 @@ export class CommentNode extends Component { {!this.isMod &&
  • {!this.props.node.comment.banned_from_community ? - ban : - unban + # : + # }
  • } {!this.props.node.comment.banned_from_community &&
  • - {`${this.isMod ? 'remove' : 'appoint'} as mod`} + {this.isMod ? i18n.t('remove_as_mod') : i18n.t('appoint_as_mod')}
  • } } + {/* Community creators and admins can transfer community to another mod */} + {(this.amCommunityCreator || this.canAdmin) && this.isMod && +
  • + {!this.state.showConfirmTransferCommunity ? + # + : <> + # + # + # + + } +
  • + } {/* Admins can ban from all, and appoint other admins */} {this.canAdmin && <> {!this.isAdmin &&
  • {!this.props.node.comment.banned ? - ban from site : - unban from site + # : + # }
  • } {!this.props.node.comment.banned &&
  • - {`${this.isAdmin ? 'remove' : 'appoint'} as admin`} + {this.isAdmin ? i18n.t('remove_as_admin') : i18n.t('appoint_as_admin')}
  • } } + {/* Site Creator can transfer to another admin */} + {this.amSiteCreator && this.isAdmin && +
  • + {!this.state.showConfirmTransferSite ? + # + : <> + # + # + # + + } +
  • + } }
  • - link + #
  • {this.props.markable &&
  • - {`mark as ${node.comment.read ? 'unread' : 'read'}`} + {node.comment.read ? i18n.t('mark_as_unread') : i18n.t('mark_as_read')}
  • }
@@ -175,23 +212,23 @@ export class CommentNode extends Component {
{this.state.showRemoveDialog &&
- - + +
} {this.state.showBanDialog &&
- - + +
{/* TODO hold off on expires until later */} {/*
*/} {/* */} - {/* */} + {/* */} {/*
*/}
- +
} @@ -202,7 +239,7 @@ export class CommentNode extends Component { disabled={this.props.locked} /> } - {this.props.node.children && + {this.props.node.children && !this.state.collapsed && { admins={this.props.admins} /> } + {/* A collapsed clearfix */} + {this.state.collapsed &&
}
) } @@ -242,6 +281,20 @@ export class CommentNode extends Component { return this.props.admins && canMod(UserService.Instance.user, this.props.admins.map(a => a.id), this.props.node.comment.creator_id); } + get amCommunityCreator(): boolean { + return this.props.moderators && + UserService.Instance.user && + (this.props.node.comment.creator_id != UserService.Instance.user.id) && + (UserService.Instance.user.id == this.props.moderators[0].user_id); + } + + get amSiteCreator(): boolean { + return this.props.admins && + UserService.Instance.user && + (this.props.node.comment.creator_id != UserService.Instance.user.id) && + (UserService.Instance.user.id == this.props.admins[0].id); + } + handleReplyClick(i: CommentNode) { i.state.showReply = true; i.setState(i.state); @@ -380,9 +433,6 @@ export class CommentNode extends Component { handleModBanBothSubmit(i: CommentNode) { event.preventDefault(); - console.log(BanType[i.state.banType]); - console.log(i.props.node.comment.banned); - if (i.state.banType == BanType.Community) { let form: BanFromCommunityForm = { user_id: i.props.node.comment.creator_id, @@ -425,9 +475,53 @@ export class CommentNode extends Component { i.setState(i.state); } + handleShowConfirmTransferCommunity(i: CommentNode) { + i.state.showConfirmTransferCommunity = true; + i.setState(i.state); + } + + handleCancelShowConfirmTransferCommunity(i: CommentNode) { + i.state.showConfirmTransferCommunity = false; + i.setState(i.state); + } + + handleTransferCommunity(i: CommentNode) { + let form: TransferCommunityForm = { + community_id: i.props.node.comment.community_id, + user_id: i.props.node.comment.creator_id, + }; + WebSocketService.Instance.transferCommunity(form); + i.state.showConfirmTransferCommunity = false; + i.setState(i.state); + } + + handleShowConfirmTransferSite(i: CommentNode) { + i.state.showConfirmTransferSite = true; + i.setState(i.state); + } + + handleCancelShowConfirmTransferSite(i: CommentNode) { + i.state.showConfirmTransferSite = false; + i.setState(i.state); + } + + handleTransferSite(i: CommentNode) { + let form: TransferSiteForm = { + user_id: i.props.node.comment.creator_id, + }; + WebSocketService.Instance.transferSite(form); + i.state.showConfirmTransferSite = false; + i.setState(i.state); + } + get isCommentNew(): boolean { let now = moment.utc().subtract(10, 'minutes'); let then = moment.utc(this.props.node.comment.published); return now.isBefore(then); } + + handleCommentCollapse(i: CommentNode) { + i.state.collapsed = !i.state.collapsed; + i.setState(i.state); + } } diff --git a/ui/src/components/comment-nodes.tsx b/ui/src/components/comment-nodes.tsx index da67bbc7..fca323e3 100644 --- a/ui/src/components/comment-nodes.tsx +++ b/ui/src/components/comment-nodes.tsx @@ -32,7 +32,7 @@ export class CommentNodes extends Component + /> )}
) diff --git a/ui/src/components/communities.tsx b/ui/src/components/communities.tsx index 96864e9a..49b982dc 100644 --- a/ui/src/components/communities.tsx +++ b/ui/src/components/communities.tsx @@ -5,6 +5,8 @@ import { retryWhen, delay, take } from 'rxjs/operators'; import { UserOperation, Community, ListCommunitiesResponse, CommunityResponse, FollowCommunityForm, ListCommunitiesForm, SortType } from '../interfaces'; import { WebSocketService } from '../services'; import { msgOp } from '../utils'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; declare const Sortable: any; @@ -26,12 +28,12 @@ export class Communities extends Component { super(props, context); this.state = this.emptyState; this.subscription = WebSocketService.Instance.subject - .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) - .subscribe( - (msg) => this.parseMessage(msg), + .pipe(retryWhen(errors => errors.pipe(delay(3000), take(10)))) + .subscribe( + (msg) => this.parseMessage(msg), (err) => console.error(err), () => console.log('complete') - ); + ); this.refetch(); @@ -46,9 +48,7 @@ export class Communities extends Component { } componentDidMount() { - document.title = "Communities - Lemmy"; - let table = document.querySelector('#community_table'); - Sortable.initTable(table); + document.title = `${i18n.t('communities')} - ${WebSocketService.Instance.site.name}`; } // Necessary for back button for some reason @@ -66,17 +66,17 @@ export class Communities extends Component { {this.state.loading ?
:
-
List of communities
+
#
- - - - - - + + + + + + @@ -91,8 +91,8 @@ export class Communities extends Component { @@ -111,9 +111,9 @@ export class Communities extends Component { return (
{this.state.page > 1 && - + } - +
); } @@ -167,7 +167,7 @@ export class Communities extends Component { console.log(msg); let op: UserOperation = msgOp(msg); if (msg.error) { - alert(msg.error); + alert(i18n.t(msg.error)); return; } else if (op == UserOperation.ListCommunities) { let res: ListCommunitiesResponse = msg; @@ -176,6 +176,8 @@ export class Communities extends Component { this.state.loading = false; window.scrollTo(0,0); this.setState(this.state); + let table = document.querySelector('#community_table'); + Sortable.initTable(table); } else if (op == UserOperation.FollowCommunity) { let res: CommunityResponse = msg; let found = this.state.communities.find(c => c.id == res.community.id); diff --git a/ui/src/components/community-form.tsx b/ui/src/components/community-form.tsx index e295dcbe..833d8a3f 100644 --- a/ui/src/components/community-form.tsx +++ b/ui/src/components/community-form.tsx @@ -3,8 +3,10 @@ import { Subscription } from "rxjs"; import { retryWhen, delay, take } from 'rxjs/operators'; import { CommunityForm as CommunityFormI, UserOperation, Category, ListCategoriesResponse, CommunityResponse } from '../interfaces'; import { WebSocketService } from '../services'; -import { msgOp } from '../utils'; +import { msgOp, capitalizeFirstLetter } from '../utils'; import * as autosize from 'autosize'; +import { i18n } from '../i18next'; +import { T } from 'inferno-i18next'; import { Community } from '../interfaces'; @@ -28,7 +30,8 @@ export class CommunityForm extends Component
- +
- +
- +
- +
NameTitleCategorySubscribersPostsComments######
{community.number_of_comments} {community.subscribed ? - Unsubscribe : - Subscribe + # : + # }