Compare commits

...

30 Commits

Author SHA1 Message Date
55adf7b5a0 hop 2021-05-24 11:23:05 +02:00
8e06e853b8 Merge branch 'chapril' of ssh://forge.april.org:222/Chapril/mobilizon.chapril.org-mobilizon into chapril 2021-05-24 10:36:17 +02:00
Thomas Citharel
9b9b274079
Rename python to python3 in alpine Docker build dependency
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-19 14:39:19 +02:00
Thomas Citharel
bd176a20f5 Merge branch '1.1.4' into 'master'
Release 1.1.4

See merge request framasoft/mobilizon!928
2021-05-19 10:07:07 +00:00
Thomas Citharel
96c81050bc
Release 1.1.4
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-19 11:35:20 +02:00
Thomas Citharel
18d6d0f8a6
Upgrade deps
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-19 11:35:20 +02:00
Thomas Citharel
e1cbfa98af
Upgrade dockerfiles to use node 16 and refresh CI image
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-19 11:35:19 +02:00
Thomas Citharel
b0394fdb02
Use post picture as OGP picture if existing
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-19 11:35:19 +02:00
Thomas Citharel
5d1f64ce9b Merge branch 'koena-connect' into 'master'
Add Koena Connect button

See merge request framasoft/mobilizon!926
2021-05-19 08:09:13 +00:00
Thomas Citharel
df4b947c25
Fix removed call to :crypto.hmac/3
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:56:50 +02:00
Thomas Citharel
c1fd7d558d
Make sure query is reloded after asking to join a group
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:56:50 +02:00
Thomas Citharel
a56f28f98e
Make koena connect picture configurable
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:56:49 +02:00
Thomas Citharel
9f4cc5d981
Fix ActivityPub test contacting dead server
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:56:49 +02:00
Thomas Citharel
159346d5b5
Hide other menu items when not logged in
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:17:38 +02:00
Thomas Citharel
c6e0a198bb
Add Koena Connect button
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:17:38 +02:00
Thomas Citharel
0e15abfc26
Lint files with prettier
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:17:37 +02:00
Thomas Citharel
68e223e480
Upgrade deps
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-18 17:17:37 +02:00
Thomas Citharel
ff298d4262 Merge branch 'weblate-mobilizon-frontend' into 'master'
Translations update from Weblate

See merge request framasoft/mobilizon!925
2021-05-17 16:23:29 +00:00
josé m
8fb41a7af1 Translated using Weblate (Galician)
Currently translated at 99.8% (991 of 992 strings)

Translation: Mobilizon/Frontend
Translate-URL: https://weblate.framasoft.org/projects/mobilizon/frontend/gl/
2021-05-17 18:22:17 +02:00
Leo Durruti
6f32e29f1f Translated using Weblate (Italian)
Currently translated at 100.0% (169 of 169 strings)

Translation: Mobilizon/Backend errors
Translate-URL: https://weblate.framasoft.org/projects/mobilizon/backend-errors/it/
2021-05-17 18:22:17 +02:00
Leo Durruti
d7c0eef657 Translated using Weblate (Italian)
Currently translated at 100.0% (245 of 245 strings)

Translation: Mobilizon/Backend
Translate-URL: https://weblate.framasoft.org/projects/mobilizon/backend/it/
2021-05-17 18:22:17 +02:00
Leo Durruti
2637d66195 Translated using Weblate (Italian)
Currently translated at 94.5% (938 of 992 strings)

Translation: Mobilizon/Frontend
Translate-URL: https://weblate.framasoft.org/projects/mobilizon/frontend/it/
2021-05-17 18:22:17 +02:00
Alexandra
bc2c03eec5 Translated using Weblate (French (France) (fr_FR))
Currently translated at 100.0% (992 of 992 strings)

Translation: Mobilizon/Frontend
Translate-URL: https://weblate.framasoft.org/projects/mobilizon/frontend/fr_FR/
2021-05-17 18:22:17 +02:00
Thomas Citharel
59385aa23a Merge branch 'rich-media-fixes' into 'master'
Rich media parsing fixes

See merge request framasoft/mobilizon!924
2021-05-03 14:11:37 +00:00
Thomas Citharel
5b36e71581
Fix rich media parsers
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-03 15:34:25 +02:00
Thomas Citharel
46120b16b6
Fix merging URIs for media from url when doing a rich media preview
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-03 14:57:30 +02:00
Thomas Citharel
741a084f4a
Fix favicon alignment on resource item
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-03 14:56:50 +02:00
Thomas Citharel
e25f13582e
fix vue warnings
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2021-05-03 14:56:50 +02:00
5bb6f21060 Merge tag '1.0.6' into chapril 2021-02-08 16:00:32 +01:00
27331eb7db Merge tag '1.0.5' into chapril 2021-02-01 10:39:22 +01:00
54 changed files with 1201 additions and 1135 deletions

View File

@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 1.1.4 - 19-05-2021
### Fixes
- Fixes rich media parsers, so that some resource links work again
- Fixes some depreciated calls that were removed in OTP24
- Fixes groups not being refreshed after joining a group
- Fixes the notice that is shown when joining a group that the content may not be available right away - because the group is remote - being shown everytime, even when the group is local
- Fixes OGP image not being defined for posts
### Translations
- French
- Galician
- Italian
## 1.1.3 - 03-05-2021
### Changed

View File

@ -1,7 +1,7 @@
# First build the application assets
FROM node:14-alpine as assets
FROM node:16-alpine as assets
RUN apk add --no-cache python build-base libwebp-tools bash imagemagick ncurses
RUN apk add --no-cache python3 build-base libwebp-tools bash imagemagick ncurses
COPY js .
RUN yarn install \

View File

@ -1,9 +1,9 @@
FROM elixir:latest
LABEL maintainer="Thomas Citharel <tcit@tcit.fr>"
ENV REFRESHED_AT=2021-04-30
ENV REFRESHED_AT=2021-05-19
RUN apt-get update -yq && apt-get install -yq build-essential inotify-tools postgresql-client git curl gnupg xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 cmake exiftool
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash && apt-get install nodejs -yq
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash && apt-get install nodejs -yq
RUN npm install -g yarn wait-on
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN mix local.hex --force && mix local.rebar --force

View File

@ -1,6 +1,6 @@
{
"name": "mobilizon",
"version": "1.1.3",
"version": "1.1.4",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
@ -78,14 +78,14 @@
"@types/vuedraggable": "^2.23.0",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~4.5.12",
"@vue/cli-plugin-e2e-cypress": "~4.5.12",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-pwa": "~4.5.12",
"@vue/cli-plugin-router": "~4.5.12",
"@vue/cli-plugin-typescript": "~4.5.12",
"@vue/cli-plugin-unit-jest": "~4.5.12",
"@vue/cli-service": "~4.5.12",
"@vue/cli-plugin-babel": "~4.5.13",
"@vue/cli-plugin-e2e-cypress": "~4.5.13",
"@vue/cli-plugin-eslint": "~4.5.13",
"@vue/cli-plugin-pwa": "~4.5.13",
"@vue/cli-plugin-router": "~4.5.13",
"@vue/cli-plugin-typescript": "~4.5.13",
"@vue/cli-plugin-unit-jest": "~4.5.13",
"@vue/cli-service": "~4.5.13",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^1.1.0",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -48,8 +48,9 @@
>
{{ $t("Loading comments…") }}
</p>
<transition name="comment-empty-list" mode="out-in" v-else>
<transition-group name="comment-empty-list" mode="out-in" v-else>
<transition-group
key="list"
name="comment-list"
v-if="comments.length"
class="comment-list"
@ -65,10 +66,10 @@
@delete-comment="deleteComment"
/>
</transition-group>
<div class="no-comments">
<div class="no-comments" key="no-comments">
<span>{{ $t("No comments yet") }}</span>
</div>
</transition>
</transition-group>
</div>
</template>

View File

@ -60,7 +60,8 @@ const CustomImage = Image.extend({
top: realEvent.clientY,
});
if (!coordinates) return false;
const client = apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
const client =
apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
try {
images.forEach(async (image) => {

View File

@ -8,7 +8,8 @@ import apolloProvider from "@/vue-apollo";
import { IPerson } from "@/types/actor";
import pDebounce from "p-debounce";
const client = apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
const client =
apolloProvider.defaultClient as ApolloClient<NormalizedCacheObject>;
const fetchItems = async (query: string): Promise<IPerson[]> => {
const result = await client.query({

View File

@ -18,6 +18,7 @@
</b-navbar-item>
</template>
<template slot="start">
<<<<<<< HEAD
<b-navbar-item tag="router-link" :to="{ name: RouteName.SEARCH }"
>{{ $t("Explore") }}
</b-navbar-item>
@ -32,6 +33,37 @@
</b-navbar-item>
<b-navbar-item tag="span" v-if="config && config.features.eventCreation">
=======
<b-navbar-item tag="router-link" :to="{ name: RouteName.SEARCH }">{{
$t("Explore")
}}</b-navbar-item>
<b-navbar-item
v-if="currentActor.id && currentUser.isLoggedIn"
tag="router-link"
:to="{ name: RouteName.MY_EVENTS }"
>{{ $t("My events") }}</b-navbar-item
>
<b-navbar-item
tag="router-link"
:to="{ name: RouteName.MY_GROUPS }"
v-if="
config &&
config.features.groups &&
currentActor.id &&
currentUser.isLoggedIn
"
>{{ $t("My groups") }}</b-navbar-item
>
<b-navbar-item
tag="span"
v-if="
config &&
config.features.eventCreation &&
currentActor.id &&
currentUser.isLoggedIn
"
>
>>>>>>> 1.1.4
<b-button
tag="router-link"
:to="{ name: RouteName.CREATE_EVENT }"
@ -39,6 +71,19 @@
>{{ $t("Create") }}</b-button
>
</b-navbar-item>
<b-navbar-item
v-if="config && config.features.koenaConnect"
class="koena"
tag="a"
href="https://mediation.koena.net/framasoft/mobilizon/"
target="_blank"
>
<img
src="/img/koena-a11y.svg"
width="150"
alt="Contact accessibilité"
/>
</b-navbar-item>
</template>
<template slot="end">
<b-navbar-item
@ -317,5 +362,14 @@ nav {
a.navbar-item:focus-within {
background-color: inherit;
}
.koena {
padding-top: 0;
padding-bottom: 0;
& > img {
max-height: 4rem;
padding-top: 0.2rem;
}
}
}
</style>

View File

@ -127,7 +127,6 @@ a {
white-space: nowrap;
display: inline-block;
font-weight: 500;
margin-bottom: 5px;
color: $primary;
overflow: hidden;
text-overflow: ellipsis;

View File

@ -1,7 +1,7 @@
import gql from "graphql-tag";
export const FETCH_PERSON = gql`
query($username: String!) {
query ($username: String!) {
fetchPerson(preferredUsername: $username) {
id
url
@ -37,7 +37,7 @@ export const FETCH_PERSON = gql`
`;
export const GET_PERSON = gql`
query(
query (
$actorId: ID!
$organizedEventsPage: Int
$organizedEventsLimit: Int
@ -433,7 +433,7 @@ export const PERSON_MEMBERSHIP_GROUP = gql`
`;
export const GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED = gql`
subscription($actorId: ID!, $group: String!) {
subscription ($actorId: ID!, $group: String!) {
groupMembershipChanged(personId: $actorId, group: $group) {
id
memberships {
@ -522,7 +522,7 @@ export const DELETE_PERSON = gql`
* Prefer CREATE_PERSON when creating another identity
*/
export const REGISTER_PERSON = gql`
mutation(
mutation (
$preferredUsername: String!
$name: String!
$summary: String!

View File

@ -46,7 +46,7 @@ export const COMMENT_RECURSIVE_FRAGMENT = gql`
`;
export const FETCH_THREAD_REPLIES = gql`
query($threadId: ID!) {
query ($threadId: ID!) {
thread(id: $threadId) {
...CommentRecursive
}
@ -55,7 +55,7 @@ export const FETCH_THREAD_REPLIES = gql`
`;
export const COMMENTS_THREADS = gql`
query($eventUUID: UUID!) {
query ($eventUUID: UUID!) {
event(uuid: $eventUUID) {
id
uuid

View File

@ -67,6 +67,7 @@ export const CONFIG = gql`
features {
groups
eventCreation
koenaConnect
}
auth {
ldap

View File

@ -150,7 +150,7 @@ export const DELETE_DISCUSSION = gql`
`;
export const DISCUSSION_COMMENT_CHANGED = gql`
subscription($slug: String!) {
subscription ($slug: String!) {
discussionCommentChanged(slug: $slug) {
id
lastComment {

View File

@ -177,7 +177,7 @@ export const FETCH_EVENT = gql`
`;
export const FETCH_EVENT_BASIC = gql`
query($uuid: UUID!) {
query ($uuid: UUID!) {
event(uuid: $uuid) {
id
uuid
@ -551,7 +551,7 @@ export const PARTICIPANTS = gql`
`;
export const EVENT_PERSON_PARTICIPATION = gql`
query($actorId: ID!, $eventId: ID!) {
query ($actorId: ID!, $eventId: ID!) {
person(id: $actorId) {
id
participations(eventId: $eventId) {
@ -572,7 +572,7 @@ export const EVENT_PERSON_PARTICIPATION = gql`
`;
export const EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED = gql`
subscription($actorId: ID!, $eventId: ID!) {
subscription ($actorId: ID!, $eventId: ID!) {
eventPersonParticipationChanged(personId: $actorId) {
id
participations(eventId: $eventId) {
@ -593,7 +593,7 @@ export const EVENT_PERSON_PARTICIPATION_SUBSCRIPTION_CHANGED = gql`
`;
export const FETCH_GROUP_EVENTS = gql`
query(
query (
$name: String!
$afterDateTime: DateTime
$beforeDateTime: DateTime

View File

@ -1,7 +1,7 @@
import gql from "graphql-tag";
export const GROUP_FOLLOWERS = gql`
query(
query (
$name: String!
$followersPage: Int
$followersLimit: Int

View File

@ -188,7 +188,7 @@ export const GROUP_FIELDS_FRAGMENTS = gql`
`;
export const FETCH_GROUP = gql`
query(
query (
$name: String!
$afterDateTime: DateTime
$beforeDateTime: DateTime
@ -206,7 +206,7 @@ export const FETCH_GROUP = gql`
`;
export const GET_GROUP = gql`
query(
query (
$id: ID!
$afterDateTime: DateTime
$beforeDateTime: DateTime

View File

@ -55,7 +55,7 @@ export const REJECT_INVITATION = gql`
`;
export const GROUP_MEMBERS = gql`
query($name: String!, $roles: String, $page: Int, $limit: Int) {
query ($name: String!, $roles: String, $page: Int, $limit: Int) {
group(preferredUsername: $name) {
id
url

View File

@ -12,6 +12,7 @@
"@{group}": "@{group}",
"@{username}": "@{username}",
"@{username} ({role})": "@{username} ({role})",
"@{username}'s follow request was accepted": "@{username}'s follow request was accepted",
"@{username}'s follow request was rejected": "La demande de suivi de @{username} a été rejettée",
"A cookie is a small file containing information that is sent to your computer when you visit a website. When you visit the site again, the cookie allows that site to recognize your browser. Cookies may store user preferences and other information. You can configure your browser to refuse all cookies. However, this may result in some website features or services partially working. Local storage works the same way but allows you to store more data.": "Un cookie est un petit fichier contenant des informations qui est envoyé à votre ordinateur lorsque vous visitez un site web. Lorsque vous visitez le site à nouveau, le cookie permet à ce site de reconnaître votre navigateur. Les cookies peuvent stocker les préférences des utilisateur·rice·s et d'autres informations. Vous pouvez configurer votre navigateur pour qu'il refuse tous les cookies. Toutefois, cela peut entraîner le non-fonctionnement de certaines fonctions ou de certains services du site web. Le stockage local fonctionne de la même manière mais permet de stocker davantage de données.",
"A federated software": "Un logiciel fédéré",
@ -58,6 +59,7 @@
"Admin settings successfully saved.": "Les paramètres administrateur ont bien été sauvegardés.",
"Administration": "Administration",
"Administrator": "Administrateur·rice",
"All activities": "Toutes les activités",
"All good, let's continue!": "C'est tout bon, continuons !",
"All group members and other eventual server admins will still be able to view this information.": "Tous les membres du groupes et les administrateur·rice·s d'éventuels autres serveurs seront toujours en capacité de voir cette information.",
"All the places have already been taken": "Toutes les places ont déjà été prises",
@ -87,6 +89,7 @@
"Are you sure you want to cancel the event creation? You'll lose all modifications.": "Étes-vous certain⋅e de vouloir annuler la création de l'événement ? Vous allez perdre toutes vos modifications.",
"Are you sure you want to cancel the event edition? You'll lose all modifications.": "Êtes-vous certain⋅e de vouloir annuler la modification de l'événement ? Vous allez perdre toutes vos modifications.",
"Are you sure you want to cancel your participation at event \"{title}\"?": "Êtes-vous certain⋅e de vouloir annuler votre participation à l'événement « {title} » ?",
"Are you sure you want to delete this entire discussion?": "Êtes-vous certain⋅e de vouloir supprimer l'entièreté de cette discussion ?",
"Are you sure you want to delete this event? This action cannot be reverted.": "Êtes-vous certain⋅e de vouloir supprimer cet événement ? Cette action ne peut être annulée.",
"As the event organizer has chosen to manually validate participation requests, your participation will be really confirmed only once you receive an email stating it's being accepted.": "L'organisateur de l'événement ayant choisi de valider manuellement les demandes de participation, votre participation ne sera réellement confirmée que lorsque vous recevrez un courriel indiquant qu'elle est acceptée.",
"Assigned to": "Assigné à",
@ -100,6 +103,7 @@
"Bold": "Gras",
"By @{group}": "Par @{group}",
"By @{username}": "Par @{username}",
"By others": "Des autres",
"By {author}": "Par {author}",
"By {group}": "Par {group}",
"By {username} and {group}": "Par {username} et {group}",
@ -128,10 +132,10 @@
"Click to upload": "Cliquez pour téléverser",
"Close": "Fermé",
"Close comments for all (except for admins)": "Fermer les commentaires à tout le monde (excepté les administrateur⋅rice·s)",
"Events nearby": "Événements proches",
"Closed": "Fermé",
"Comment deleted": "Commentaire supprimé",
"Comment from @{username} reported": "Commentaire de @{username} signalé",
"Comment text can't be empty": "Le texte du commentaire ne peut être vide",
"Comments": "Commentaires",
"Comments are closed for everybody else.": "Les commentaires sont fermés pour tou·te·s les autres.",
"Comments have been closed.": "Les commentaires sont fermés.",
@ -165,6 +169,7 @@
"Create my event": "Créer mon événement",
"Create my group": "Créer mon groupe",
"Create my profile": "Créer mon profil",
"Create new links": "Créer de nouveaux liens",
"Create or join an group and start organizing with other people": "Créez ou rejoignez un groupe et commencez à vous organiser avec d'autres personnes",
"Create resource": "Créer une ressource",
"Create the discussion": "Créer la discussion",
@ -194,11 +199,13 @@
"Delete Event": "Supprimer l'événement",
"Delete account": "Suppression du compte",
"Delete conversation": "Supprimer la conversation",
"Delete discussion": "Supprimer la discussion",
"Delete event": "Supprimer un événement",
"Delete everything": "Tout supprimer",
"Delete group": "Supprimer le groupe",
"Delete my account": "Supprimer mon compte",
"Delete post": "Supprimer le billet",
"Delete this discussion": "Supprimer cette discussion",
"Delete this identity": "Supprimer cette identité",
"Delete your identity": "Supprimer votre identité",
"Delete {eventTitle}": "Supprimer {eventTitle}",
@ -249,6 +256,7 @@
"Error stacktrace": "Trace d'appels de l'erreur",
"Error while changing email": "Erreur lors de la modification de l'adresse email",
"Error while communicating with the server.": "Erreur de communication avec le serveur.",
"Error while loading the preview": "Erreur lors du chargement de l'aperçu",
"Error while login with {provider}. Retry or login another way.": "Erreur lors de la connexion avec {provider}. Réessayez ou bien connectez vous autrement.",
"Error while login with {provider}. This login provider doesn't exist.": "Erreur lors de la connexion avec {provider}. Cette méthode de connexion n'existe pas.",
"Error while reporting group {groupTitle}": "Erreur lors du signalement du groupe {groupTitle}",
@ -268,6 +276,7 @@
"Event {eventTitle} deleted": "Événement {eventTitle} supprimé",
"Event {eventTitle} reported": "Événement {eventTitle} signalé",
"Events": "Événements",
"Events nearby": "Événements proches",
"Events tagged with {tag}": "Événements taggés avec {tag}",
"Everything": "Tous",
"Ex: mobilizon.fr": "Ex : mobilizon.fr",
@ -296,6 +305,7 @@
"From the {startDate} at {startTime} to the {endDate}": "Du {startDate} à {startTime} jusqu'au {endDate}",
"From the {startDate} at {startTime} to the {endDate} at {endTime}": "Du {startDate} à {startTime} au {endDate} à {endTime}",
"From the {startDate} to the {endDate}": "Du {startDate} au {endDate}",
"From yourself": "De vous",
"Gather ⋅ Organize ⋅ Mobilize": "Rassembler ⋅ Organiser ⋅ Mobiliser",
"General": "Général",
"General information": "Informations générales",
@ -364,6 +374,7 @@
"Instance Terms URL": "URL des conditions générales de l'instance",
"Instance administrator": "Administrateur·rice de l'instance",
"Instance configuration": "Configuration de l'instance",
"Instance feeds": "Flux de l'instance",
"Instance languages": "Langues de l'instance",
"Instance rules": "Règles de l'instance",
"Instance settings": "Paramètres de l'instance",
@ -380,7 +391,7 @@
"Keep the entire conversation about a specific topic together on a single page.": "Rassemblez sur une seule page toute la conversation à propos d'un sujet spécifique.",
"Key words": "Mots clés",
"Language": "Langue",
"Last IP adress": "Dernière addresse IP",
"Last IP adress": "Dernière adresse IP",
"Last group created": "Dernier groupe créé",
"Last published event": "Dernier événement publié",
"Last published events": "Derniers événements publiés",
@ -455,6 +466,7 @@
"New members": "Nouveaux·elles membres",
"New note": "Nouvelle note",
"New password": "Nouveau mot de passe",
"New post": "Nouveau billet",
"New profile": "Nouveau profil",
"Next": "Suivant",
"Next month": "Le mois-prochain",
@ -470,6 +482,7 @@
"No follower matches the filters": "Aucun⋅e abonné⋅e ne correspond aux filtres",
"No group found": "Aucun groupe trouvé",
"No groups found": "Aucun groupe trouvé",
"No information": "Non renseigné",
"No instance follows your instance yet.": "Aucune instance ne suit votre instance pour le moment.",
"No instance to approve|Approve instance|Approve {number} instances": "Aucune instance à approuver|Approuver une instance|Approuver {number} instances",
"No instance to reject|Reject instance|Reject {number} instances": "Aucune instance à rejeter|Rejeter une instance|Rejeter {number} instances",
@ -505,6 +518,7 @@
"Nothing to see here": "Il n'y a rien à voir ici",
"Notification before the event": "Notification avant l'événement",
"Notification on the day of the event": "Notification le jour de l'événement",
"Notifications": "Notifications",
"Notifications for manually approved participations to an event": "Notifications pour l'approbation manuelle des participations à un événement",
"Now, create your first profile:": "Maintenant, créez votre premier profil :",
"Number of places": "Nombre de places",
@ -558,6 +572,7 @@
"Password reset": "Réinitialisation du mot de passe",
"Past events": "Événements passés",
"Pending": "En attente",
"Personal feeds": "Flux personnels",
"Pick": "Choisir",
"Pick a group": "Choisissez un groupe",
"Pick a profile or a group": "Choisir un profil ou groupe",
@ -585,6 +600,7 @@
"Privacy policy": "Politique de confidentialité",
"Private event": "Événement privé",
"Private feeds": "Flux privés",
"Profile feeds": "Flux du profil",
"Profiles": "Profils",
"Profiles and federation": "Profils et fédération",
"Promote": "Promouvoir",
@ -606,6 +622,7 @@
"Redirecting to content…": "Redirection vers le contenu…",
"Redirecting to event…": "Redirection vers l'événement…",
"Refresh profile": "Rafraîchir le profil",
"Regenerate new links": "Regénérer de nouveaux liens",
"Region": "Région",
"Register": "S'inscrire",
"Register an account on {instanceName}!": "S'inscrire sur {instanceName} !",
@ -707,6 +724,7 @@
"The event organizer manually approves participations. Since you've chosen to participate without an account, please explain why you want to participate to this event.": "L'organisateur⋅ice de l'événement valide les participations manuellement. Comme vous avez choisi de participer sans compte, merci d'expliquer pourquoi vous voulez participer à cet événement.",
"The event title will be ellipsed.": "Le titre de l'événement sera ellipsé.",
"The event will show as attributed to this group.": "L'événement sera affiché comme étant attribué à ce groupe.",
"The event will show as attributed to this profile.": "L'événement sera affiché comme attribué à ce profil.",
"The event will show as attributed to your personal profile.": "L'événement sera affiché comme étant attribué à votre profil.",
"The event will show the group as organizer.": "L'événement affichera le groupe en tant qu'organisateur⋅ice.",
"The event {event} was created by {profile}.": "L'événement {event} a été créé par {profile}.",
@ -734,6 +752,7 @@
"The post {post} was deleted by {profile}.": "Le billet {post} a été supprimé par {profile}.",
"The post {post} was updated by {profile}.": "Le billet {post} a été mis à jour par {profile}.",
"The report will be sent to the moderators of your instance. You can explain why you report this content below.": "Le signalement sera envoyé aux modérateur⋅ices de votre instance. Vous pouvez expliquer pourquoi vous signalez ce contenu ci-dessous.",
"The selected picture is too heavy. You need to select a file smaller than {size}.": "L'image sélectionnée est trop lourde. Vous devez sélectionner un fichier de moins de {size}.",
"The technical details of the error can help developers solve the problem more easily. Please add them to your feedback.": "Les détails techniques de l'erreur peuvent aider les développeur⋅ices à résoudre le problème plus facilement. Merci de les inclure dans vos retours.",
"The user account you're trying to login as has not been confirmed yet. Check your email inbox and eventually your spam folder.": "Le compte utilisateur avec lequel vous essayez de vous connectez n'a pas été confirmé. Vérifiez la boite de réception de votre adresse email et éventuellement le dossier des messages indésirables.",
"The username is a unique identifier of your account on this and all the other instances. It's as unique as an email address, which makes it easy for other people to interact with it.": "Le nom d'utilisateur·rice est un identifiant unique pour votre compte. Il est similaire à une adresse e-mail mais permettant à d'autres personnes de vous trouver.",
@ -744,6 +763,8 @@
"There will be no way to recover your data.": "Il n'y aura aucun moyen de récupérer vos données.",
"There's no discussions yet": "Il n'y a pas encore de discussions",
"These events may interest you": "Ces événements peuvent vous intéresser",
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "Ces flux contiennent des informations sur les événements pour lesquels n'importe lequel de vos profils est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux spécifiques à chaque profil sur la page d'édition des profils.",
"These feeds contain event data for the events for which this specific profile is a participant or creator. You should keep these private. You can find feeds for all of your profiles into your notification settings.": "Ces flux contiennent des informations sur les événements pour lesquels ce profil spécifique est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux pour l'ensemble de vos profils dans vos paramètres de notification.",
"This Mobilizon instance and this event organizer allows anonymous participations, but requires validation through email confirmation.": "Cette instance Mobilizon et l'organisateur⋅ice de l'événement autorise les participations anonymes, mais requiert une validation à travers une confirmation par email.",
"This URL is not supported": "Cette URL n'est pas supportée",
"This email is already registered as participant for this event": "Cet email est déjà enregistré comme participant⋅e pour cet événement",
@ -759,7 +780,7 @@
"This instance isn't opened to registrations, but you can register on other instances.": "Cette instance n'autorise pas les inscriptions, mais vous pouvez vous enregistrer sur d'autres instances.",
"This instance, <b>{instanceName} ({domain})</b>, hosts your profile, so remember its name.": "Cette instance, <b>{instanceName} ({domain})</b>, héberge votre profil, donc notez bien son nom.",
"This is a demonstration site to test Mobilizon.": "Ceci est un site de démonstration permettant de tester Mobilizon.",
"This is like your federated username (<code>{username}</code>) for groups. It will allow the group to be found on the federation, and is guaranteed to be unique.": "C'est comme votre addresse fédérée (<code>{username}</code>) pour les groupes. Cela permettra au groupe d'être trouvable sur la fédération, et est garanti d'être unique.",
"This is like your federated username (<code>{username}</code>) for groups. It will allow the group to be found on the federation, and is guaranteed to be unique.": "C'est comme votre adresse fédérée (<code>{username}</code>) pour les groupes. Cela permettra au groupe d'être trouvable sur la fédération, et est garanti d'être unique.",
"This month": "Ce mois-ci",
"This setting will be used to display the website and send you emails in the correct language.": "Ce paramètre sera utilisé pour l'affichage du site et pour vous envoyer des courriels dans la bonne langue.",
"This user has been disabled": "Cet utilisateur·ice a été désactivé·e",
@ -787,9 +808,12 @@
"URL": "URL",
"URL copied to clipboard": "URL copiée dans le presse-papiers",
"Unable to copy to clipboard": "Impossible de copier dans le presse-papiers",
"Unable to create the group. One of the pictures may be too heavy.": "Impossible de créer le groupe. Une des images est trop lourde.",
"Unable to create the profile. The avatar picture may be too heavy.": "Impossible de créer le profil. L'image d'avatar est probablement trop lourde.",
"Unable to detect timezone.": "Impossible de détecter le fuseau horaire.",
"Unable to load event for participation. The error details are provided below:": "Impossible de charger l'événement pour la participation. Les détails de l'erreur sont disponibles ci-dessous :",
"Unable to save your participation in this browser.": "Échec de la sauvegarde de votre participation dans ce navigateur.",
"Unable to update the profile. The avatar picture may be too heavy.": "Impossible de mettre à jour le profil. L'image d'avatar est probablement trop lourde.",
"Unfortunately, this instance isn't opened to registrations": "Malheureusement, cette instance n'est pas ouverte aux inscriptions",
"Unfortunately, your participation request was rejected by the organizers.": "Malheureusement, votre demande de participation a été refusée par les organisateur⋅ices.",
"Unknown": "Inconnu",
@ -898,18 +922,21 @@
"You may also ask to {resend_confirmation_email}.": "Vous pouvez aussi demander à {resend_confirmation_email}.",
"You may clear all participation information for this device with the buttons below.": "Vous pouvez effacer toutes les informations de participation pour cet appareil avec les boutons ci-dessous.",
"You may now close this window, or {return_to_event}.": "Vous pouvez maintenant fermer cette fenêtre, ou bien {return_to_event}.",
"You may show some members as contacts.": "Vous pouvez afficher certain⋅es membres en tant que contacts.",
"You moved the folder {resource} into {new_path}.": "Vous avez déplacé le dossier {resource} dans {new_path}.",
"You moved the folder {resource} to the root folder.": "Vous avez déplacé le dossier {resource} dans le dossier racine.",
"You moved the resource {resource} into {new_path}.": "Vous avez déplacé la ressource {resource} dans {new_path}.",
"You moved the resource {resource} to the root folder.": "Vous avez déplacé la ressource {resource} dans le dossier racine.",
"You need to create the group before you create an event.": "Vous devez créer le groupe avant de créer l'événement.",
"You need to login.": "Vous devez vous connecter.",
"You posted a comment on the event {event}.": "Vous avez posté un commentaire sur l'événement {event}.",
"You promoted the member {member} to an unknown role.": "Vous avez promu le ou la membre {member} à un role inconnu.",
"You promoted {member} to administrator.": "Vous avez promu {member} en tant qu'adminstrateur⋅ice.",
"You promoted {member} to moderator.": "Vous avez promu {member} en tant que modérateur⋅ice.",
"You renamed the discussion from {old_discussion} to {discussion}.": "Vous avez renommé la discussion {old_discussion} en {discussion}.",
"You renamed the folder from {old_resource_title} to {resource}.": "Vous avez renommé le dossier {old_resource_title} en {resource}.",
"You renamed the resource from {old_resource_title} to {resource}.": "Vous avez renommé la ressource {old_resource_title} en {resource}.",
"You replied to a comment on the event {event}.": "Vous avez répondu à un commentaire sur l'événement {event}.",
"You replied to the discussion {discussion}.": "Vous avez répondu à la discussion {discussion}.",
"You requested to join the group.": "Vous avez demandé à rejoindre le groupe.",
"You updated the event {event}.": "Vous avez mis à jour l'événement {event}.",
@ -927,6 +954,7 @@
"You will find here all the events you have created or of which you are a participant.": "Vous trouverez ici tous les événements que vous avez créé ou dont vous êtes un·e participant·e.",
"You wish to participate to the following event": "Vous souhaitez participer à l'événement suivant",
"You'll get a weekly recap every Monday for upcoming events, if you have any.": "Vous recevrez un récapitulatif hebdomadaire chaque lundi pour les événements de la semaine, si vous en avez.",
"You'll need to change the URLs where there were previously entered.": "Vous devrez changer les URLs là où vous les avez entrées précédemment.",
"You'll need to transmit the group URL so people may access the group's profile. The group won't be findable in Mobilizon's search or regular search engines.": "Vous aurez besoin de transmettre l'URL du groupe pour que d'autres personnes accèdent au profil du groupe. Le groupe ne sera pas trouvable dans la recherche de Mobilizon ni dans les moteurs de recherche habituels.",
"You'll receive a confirmation email.": "Vous recevrez un email de confirmation.",
"Your account has been successfully deleted": "Votre compte a été supprimé avec succès",
@ -1008,10 +1036,15 @@
"{moderator} added a note on {report}": "{moderator} a ajouté une note sur {report}",
"{moderator} closed {report}": "{moderator} a fermé {report}",
"{moderator} deleted an event named \"{title}\"": "{moderator} a supprimé un événement nommé \"{title}\"",
"{moderator} has deleted a comment from {author}": "{moderator} a supprimé un commentaire de {author}",
"{moderator} has deleted a comment from {author} under the event {event}": "{moderator} a supprimé un commentaire de {author} sous l'événement {event}",
"{moderator} has deleted user {user}": "{moderator} a supprimé l'utilisateur·rice {user}",
"{moderator} has done an unknown action": "{moderator} a effectué une action inconnue",
"{moderator} has unsuspended group {profile}": "{moderator} a annulé la suspension du groupe {profile}",
"{moderator} has unsuspended profile {profile}": "{moderator} a annulé la suspension de {profile}",
"{moderator} marked {report} as resolved": "{moderator} a marqué {report} comme résolu",
"{moderator} reopened {report}": "{moderator} a réouvert {report}",
"{moderator} suspended group {profile}": "{moderator} a suspendu le groupe {profile}",
"{moderator} suspended profile {profile}": "{moderator} a suspendu le profil {profile}",
"{nb} km": "{nb} km",
"{number} members": "{number} membres",
@ -1037,6 +1070,7 @@
"{profile} moved the folder {resource} to the root folder.": "{profile} a déplacé le dossier {resource} dans le dossier racine.",
"{profile} moved the resource {resource} into {new_path}.": "{profile} a déplacé la ressource {resource} dans {new_path}.",
"{profile} moved the resource {resource} to the root folder.": "{profile} a déplacé la ressource {resource} dans le dossier racine.",
"{profile} posted a comment on the event {event}.": "{profile} a posté un commentaire sur l'événement {event}.",
"{profile} promoted {member} to administrator.": "{profile} a promu {member} en tant qu'administrateur⋅ice.",
"{profile} promoted {member} to an unknown role.": "{profile} a promu {member} à un role inconnu.",
"{profile} promoted {member} to moderator.": "{profile} a promu {member} en tant que modérateur⋅ice.",
@ -1044,45 +1078,11 @@
"{profile} renamed the discussion from {old_discussion} to {discussion}.": "{profile} a renommé la discussion {old_discussion} en {discussion}.",
"{profile} renamed the folder from {old_resource_title} to {resource}.": "{profile} a renommé le dossier {old_resource_title} en {resource}.",
"{profile} renamed the resource from {old_resource_title} to {resource}.": "{profile} a renommé la ressource {old_resource_title} en {resource}.",
"{profile} replied to a comment on the event {event}.": "{profile} a répondu à un commentaire sur l'événement {event}.",
"{profile} replied to the discussion {discussion}.": "{profile} a répondu à la discussion {discussion}.",
"{profile} updated the group {group}.": "{profile} a mis à jour le groupe {group}.",
"{profile} updated the member {member}.": "{profile} a mis à jour le ou la membre {member}.",
"{title} ({count} todos)": "{title} ({count} todos)",
"{username} was invited to {group}": "{username} a été invité à {group}",
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap",
"No information": "Non renseigné",
"@{username}'s follow request was accepted": "@{username}'s follow request was accepted",
"Delete this discussion": "Supprimer cette discussion",
"Are you sure you want to delete this entire discussion?": "Êtes-vous certain⋅e de vouloir supprimer l'entièreté de cette discussion ?",
"Delete discussion": "Supprimer la discussion",
"All activities": "Toutes les activités",
"From yourself": "De vous",
"By others": "Des autres",
"You posted a comment on the event {event}.": "Vous avez posté un commentaire sur l'événement {event}.",
"{profile} posted a comment on the event {event}.": "{profile} a posté un commentaire sur l'événement {event}.",
"You replied to a comment on the event {event}.": "Vous avez répondu à un commentaire sur l'événement {event}.",
"{profile} replied to a comment on the event {event}.": "{profile} a répondu à un commentaire sur l'événement {event}.",
"New post": "Nouveau billet",
"Comment text can't be empty": "Le texte du commentaire ne peut être vide",
"Notifications": "Notifications",
"Profile feeds": "Flux du profil",
"These feeds contain event data for the events for which this specific profile is a participant or creator. You should keep these private. You can find feeds for all of your profiles into your notification settings.": "Ces flux contiennent des informations sur les événements pour lesquels ce profil spécifique est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux pour l'ensemble de vos profils dans vos paramètres de notification.",
"Regenerate new links": "Regénérer de nouveaux liens",
"Create new links": "Créer de nouveaux liens",
"You'll need to change the URLs where there were previously entered.": "Vous devrez changer les URLs là où vous les avez entrées précédemment.",
"Personal feeds": "Flux personnels",
"These feeds contain event data for the events for which any of your profiles is a participant or creator. You should keep these private. You can find feeds for specific profiles on each profile edition page.": "Ces flux contiennent des informations sur les événements pour lesquels n'importe lequel de vos profils est un⋅e participant⋅e ou un⋅e créateur⋅ice. Vous devriez les garder privés. Vous pouvez trouver des flux spécifiques à chaque profil sur la page d'édition des profils.",
"The event will show as attributed to this profile.": "L'événement sera affiché comme attribué à ce profil.",
"You may show some members as contacts.": "Vous pouvez afficher certain⋅es membres en tant que contacts.",
"The selected picture is too heavy. You need to select a file smaller than {size}.": "L'image sélectionnée est trop lourde. Vous devez sélectionner un fichier de moins de {size}.",
"Unable to create the group. One of the pictures may be too heavy.": "Impossible de créer le groupe. Une des images est trop lourde.",
"Unable to update the profile. The avatar picture may be too heavy.": "Impossible de mettre à jour le profil. L'image d'avatar est probablement trop lourde.",
"Unable to create the profile. The avatar picture may be too heavy.": "Impossible de créer le profil. L'image d'avatar est probablement trop lourde.",
"Error while loading the preview": "Erreur lors du chargement de l'aperçu",
"Instance feeds": "Flux de l'instance",
"{moderator} suspended group {profile}": "{moderator} a suspendu le groupe {profile}",
"{moderator} has unsuspended group {profile}": "{moderator} a annulé la suspension du groupe {profile}",
"{moderator} has done an unknown action": "{moderator} a effectué une action inconnue",
"{moderator} has deleted a comment from {author} under the event {event}": "{moderator} a supprimé un commentaire de {author} sous l'événement {event}",
"{moderator} has deleted a comment from {author}": "{moderator} a supprimé un commentaire de {author}"
"© The OpenStreetMap Contributors": "© Les Contributeur⋅ices OpenStreetMap"
}

View File

@ -417,7 +417,7 @@
"Loading comments…": "Cargando comentarios…",
"Local": "Local",
"Locality": "Localidade",
"Location": "Lugar",
"Location": "Localización",
"Log in": "Conectar",
"Log out": "Saír",
"Login": "Conectar",

View File

@ -40,6 +40,7 @@
"Actions": "Azioni",
"Activated": "Attivato",
"Active": "Attivo",
"Activity": "Attività",
"Actor": "Partecipante",
"Add": "Aggiungi",
"Add / Remove…": "Aggiunti / Rimuovi…",
@ -384,6 +385,7 @@
"Limited number of places": "Posti a numero chiuso",
"List title": "Titolo elenco",
"Load more": "Carica di più",
"Load more activities": "Caricare più attività",
"Loading comments…": "Caricando i commenti…",
"Local": "Locale",
"Locality": "Località",
@ -788,6 +790,9 @@
"Within {number} kilometers of {place}": "|Entro un chilometro da {place}|Entro {number} chilometri da {place}",
"Write something…": "Scrivi qualcosa…",
"Yesterday": "Ieri",
"You accepted the invitation to join the group.": "Hai accettato l'invito a iscriverti al gruppo.",
"You added the member {member}.": "Hai aggiunto il membro {member}.",
"You archived the discussion {discussion}.": "Hai archiviato la discussione {discussion}.",
"You are not an administrator for this group.": "Non sei un amministratore di questo gruppo.",
"You are not part of any group.": "Non fai parte di nessun gruppo.",
"You are participating in this event anonymously": "Stai partecipando a questo evento in forma anonima",
@ -797,15 +802,23 @@
"You can pick your timezone into your preferences.": "Puoi scegliere il tuo fuso orario nelle preferenze.",
"You can try another search term or drag and drop the marker on the map": "Puoi provare un altro termine di ricerca o trascinare il marcatore sulla mappa",
"You can't change your password because you are registered through {provider}.": "Non puoi cambiare la tua password perché sei registrato con {provider}.",
"You created the discussion {discussion}.": "Hai creato la discussione {discussion}.",
"You created the event {event}.": "Hai creato l'evento {event}.",
"You created the folder {resource}.": "Hai creato la cartella {resource}.",
"You created the group {group}.": "Hai creato il gruppo {group}.",
"You created the post {post}.": "Hai creato il post {post}.",
"You created the resource {resource}.": "Hai creato la risorsa {resource}.",
"You deleted the discussion {discussion}.": "Hai eliminato la discussione {discussion}.",
"You deleted the event {event}.": "Hai cancellato l'evento {event}.",
"You deleted the folder {resource}.": "Hai eliminato la cartella {resource}.",
"You deleted the post {post}.": "Hai cancellato il post {post}.",
"You deleted the resource {resource}.": "Hai eliminato la risorsa {resource}.",
"You demoted the member {member} to an unknown role.": "Hai degradato {member} a un ruolo sconosciuto.",
"You demoted {member} to moderator.": "Hai degradato {member} a moderatore.",
"You demoted {member} to simple member.": "Hai degradato {member} a membro semplice.",
"You didn't create or join any event yet.": "Non hai ancora creato o partecipato a nessun evento.",
"You don't follow any instances yet.": "Non segui ancora nessuna istanza.",
"You excluded member {member}.": "Hai escluso il membro {member}.",
"You have been disconnected": "Sei stato disconnesso",
"You have been invited by {invitedBy} to the following group:": "Sei stato invitato da {invitedBy} al seguente gruppo:",
"You have been removed from this group's members.": "Sei stato rimosso dai membri di questo gruppo.",
@ -817,15 +830,28 @@
"You may clear all participation information for this device with the buttons below.": "Puoi rimuovere tutte le informazioni di partecipazione da questo dispositivo col bottone qui sotto.",
"You may now close this window, or {return_to_event}.": "Ora puoi chiudere questa finestra, o {return_to_event}.",
"You may now close this window.": "Ora puoi chiudere questa finestra.",
"You moved the folder {resource} into {new_path}.": "Hai spostato la cartella {resource} in {new_path}.",
"You moved the folder {resource} to the root folder.": "Hai spostato la cartella {resource} nella cartella principale.",
"You moved the resource {resource} into {new_path}.": "Hai spostato la risorsa {resource} in {new_path}.",
"You moved the resource {resource} to the root folder.": "Hai spostato la risorsa {resource} nella cartella principale.",
"You need to create the group before you create an event.": "Devi creare un gruppo prima di creare un evento.",
"You need to login.": "Devi accedere.",
"You promoted the member {member} to an unknown role.": "Hai promosso l'utente {member} a un ruolo sconosciuto.",
"You promoted {member} to administrator.": "Hai promosso {member} ad amministratore.",
"You promoted {member} to moderator.": "Hai promosso {member} a moderatore.",
"You renamed the discussion from {old_discussion} to {discussion}.": "Hai rinominato la discussione da {old_discussion} a {discussion}.",
"You renamed the folder from {old_resource_title} to {resource}.": "Hai rinominato la cartella da {old_resource_title} a {resource}.",
"You renamed the resource from {old_resource_title} to {resource}.": "Hai rinominato la risorsa da {old_resource_title} a {resource}.",
"You replied to the discussion {discussion}.": "Hai risposto alla discussione {discussion}.",
"You requested to join the group.": "Hai richiesto di unirti al gruppo.",
"You updated the event {event}.": "Hai aggiornato l'evento {event}.",
"You updated the group {group}.": "Hai aggiornato il gruppo {group}.",
"You updated the member {member}.": "Hai aggiornato il membro {member}.",
"You updated the post {post}.": "Hai aggiornato il post {post}.",
"You were demoted to moderator by {profile}.": "Sei stato declassato a moderatore da {profile}.",
"You were demoted to simple member by {profile}.": "Sei stato declassato a semplice membro da {profile}.",
"You were promoted to administrator by {profile}.": "Sei stato promosso ad amministratore da {profile}.",
"You were promoted to moderator by {profile}.": "Sei stato promosso a moderatore da {profile}.",
"You will be able to add an avatar and set other options in your account settings.": "Potrai aggiungere un avatar e impostare altre opzioni nelle impostazioni del tuo account.",
"You will be redirected to the original instance": "Sarai reindirizzato verso l'istanza originale",
"You will find here all the events you have created or of which you are a participant.": "Qui troverai tutti gli eventi che hai creato o di cui sei partecipante.",
@ -897,6 +923,8 @@
"{group}'s events": "{group} eventi",
"{instanceName} is an instance of the {mobilizon} software.": "{instanceName} è un'istanza del software {mobilizon}.",
"{instanceName} is an instance of {mobilizon_link}, a free software built with the community.": "{instanceName} è un'istanza di {mobilizon_link}, un software libero costruito con la comunità.",
"{member} accepted the invitation to join the group.": "{member} ha accettato l'invito a iscriversi al gruppo.",
"{member} rejected the invitation to join the group.": "{member} ha rifiutato l'invito a iscriversi al gruppo.",
"{member} requested to join the group.": "{member} ha richiesto di unirsi al gruppo.",
"{member} was invited by {profile}.": "{member} è stato invitato da {profile}.",
"{moderator} added a note on {report}": "ha aggiunto una nota su",
@ -913,12 +941,32 @@
"{number} participations": "Nessuna partecipazione|Una partecipazione|{number} partecipazioni",
"{number} posts": "Nessun post|Un post|{number} di post",
"{profile} (by default)": "{profile} (per impostazione predefinita)",
"{profile} added the member {member}.": "{profile} ha aggiunto il membro {member}.",
"{profile} archived the discussion {discussion}.": "{profile} ha archiviato la discussione {discussion}.",
"{profile} created the discussion {discussion}.": "{profile} ha creato la discussione {discussion}.",
"{profile} created the folder {resource}.": "{profile} ha creato la cartella {resource}.",
"{profile} created the group {group}.": "{profile} ha creato il gruppo {group}.",
"{profile} created the resource {resource}.": "{profile} ha creato la risorsa {resource}.",
"{profile} deleted the discussion {discussion}.": "{profile} ha eliminato la discussione {discussion}.",
"{profile} deleted the folder {resource}.": "{profile} ha eliminato la cartella {resource}.",
"{profile} deleted the resource {resource}.": "{profile} ha eliminato la risorsa {resource}.",
"{profile} demoted {member} to an unknown role.": "{profile} ha degradato {member} a un ruolo sconosciuto.",
"{profile} demoted {member} to moderator.": "{profile} ha degradato {member} a moderatore.",
"{profile} demoted {member} to simple member.": "{profile} ha degradato {member} a membro semplice.",
"{profile} excluded member {member}.": "{profile} ha escluso il membro {member}.",
"{profile} moved the folder {resource} into {new_path}.": "{profile} ha spostato la cartella {resource} in {new_path}.",
"{profile} moved the folder {resource} to the root folder.": "{profile} ha spostato la cartella {resource} nella cartella principale.",
"{profile} moved the resource {resource} into {new_path}.": "{profile} ha spostato la risorsa {resource} in {new_path}.",
"{profile} moved the resource {resource} to the root folder.": "{profile} ha spostato la risorsa {resource} nella cartella principale.",
"{profile} promoted {member} to administrator.": "{profile} ha promosso {member} ad amministratore.",
"{profile} promoted {member} to an unknown role.": "{profile} ha promosso {member} a un ruolo sconosciuto.",
"{profile} promoted {member} to moderator.": "{profile} ha promosso {member} a moderatore.",
"{profile} quit the group.": "{profile} ha abbandonato il gruppo.",
"{profile} renamed the discussion from {old_discussion} to {discussion}.": "{profile} ha rinominato la discussione da {old_discussion} a {discussion}.",
"{profile} renamed the folder from {old_resource_title} to {resource}.": "{profile} ha rinominato la cartella da {old_resource_title} a {resource}.",
"{profile} renamed the resource from {old_resource_title} to {resource}.": "{profile} ha rinominato la risorsa da {old_resource_title} a {resource}.",
"{profile} replied to the discussion {discussion}.": "{profile} ha risposto alla discussione {discussion}.",
"{profile} updated the group {group}.": "{profile} ha aggiornato il gruppo {group}.",
"{profile} updated the member {member}.": "{profile} ha aggiornato il membro {member}.",
"{title} ({count} todos)": "{title} ({count} tutti)",
"{username} was invited to {group}": "{username} è stato invitato a {group}",

View File

@ -14,9 +14,8 @@ export default class IdentityEditionMixin extends Mixins(Vue) {
);
if (this.identity.preferredUsername === oldUsername) {
this.identity.preferredUsername = IdentityEditionMixin.convertToUsername(
newDisplayName
);
this.identity.preferredUsername =
IdentityEditionMixin.convertToUsername(newDisplayName);
}
this.oldDisplayName = newDisplayName;

View File

@ -82,6 +82,7 @@ export interface IConfig {
features: {
eventCreation: boolean;
groups: boolean;
koenaConnect: boolean;
};
federating: boolean;
version: string;

View File

@ -344,14 +344,16 @@ export default class AdminGroupProfile extends Vue {
}
confirmSuspendProfile(): void {
const message = (this.group.domain
? this.$t(
"Are you sure you want to <b>suspend</b> this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.",
{ instance: this.group.domain }
)
: this.$t(
"Are you sure you want to <b>suspend</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>."
)) as string;
const message = (
this.group.domain
? this.$t(
"Are you sure you want to <b>suspend</b> this group? As this group originates from instance {instance}, this will only remove local members and delete the local data, as well as rejecting all the future data.",
{ instance: this.group.domain }
)
: this.$t(
"Are you sure you want to <b>suspend</b> this group? All members - including remote ones - will be notified and removed from the group, and <b>all of the group data (events, posts, discussions, todos…) will be irretrievably destroyed</b>."
)
) as string;
this.$buefy.dialog.confirm({
title: this.$t("Suspend group") as string,

View File

@ -773,9 +773,11 @@ export default class EditEvent extends Vue {
get updateEventMessage(): string {
if (this.unmodifiedEvent.draft && !this.event.draft)
return this.$i18n.t("The event has been updated and published") as string;
return (this.event.draft
? this.$i18n.t("The draft event has been updated")
: this.$i18n.t("The event has been updated")) as string;
return (
this.event.draft
? this.$i18n.t("The draft event has been updated")
: this.$i18n.t("The event has been updated")
) as string;
}
private handleError(err: any) {

View File

@ -874,7 +874,8 @@ export default class Event extends EventMixin {
try {
if (window.isSecureContext) {
this.anonymousParticipation = await this.anonymousParticipationConfirmed();
this.anonymousParticipation =
await this.anonymousParticipationConfirmed();
}
} catch (e) {
if (e instanceof AnonymousParticipationNotFoundError) {

View File

@ -31,7 +31,11 @@
{{ $t("You have been removed from this group's members.") }}
</b-message>
<b-message
v-if="isCurrentActorAGroupMember && isCurrentActorARecentMember"
v-if="
isCurrentActorAGroupMember &&
isCurrentActorARecentMember &&
isCurrentActorOnADifferentDomainThanGroup
"
type="is-info"
>
{{
@ -541,6 +545,7 @@ import { IMember } from "@/types/actor/member.model";
import RouteName from "../../router/name";
import GroupSection from "../../components/Group/GroupSection.vue";
import ReportModal from "../../components/Report/ReportModal.vue";
import { PERSON_MEMBERSHIP_GROUP } from "@/graphql/actor";
@Component({
apollo: {
@ -600,11 +605,24 @@ export default class Group extends mixins(GroupMixin) {
}
async joinGroup(): Promise<void> {
const [group, currentActorId] = [
usernameWithDomain(this.group),
this.currentActor.id,
];
this.$apollo.mutate({
mutation: JOIN_GROUP,
variables: {
groupId: this.group.id,
},
refetchQueries: [
{
query: PERSON_MEMBERSHIP_GROUP,
variables: {
id: currentActorId,
group,
},
},
],
});
}
@ -735,6 +753,10 @@ export default class Group extends mixins(GroupMixin) {
);
}
get isCurrentActorOnADifferentDomainThanGroup(): boolean {
return this.group.domain !== null;
}
get members(): IMember[] {
return this.group.members.elements.filter(
(member) =>

View File

@ -562,9 +562,10 @@ export default class Resources extends Mixins(ResourceMixin) {
const updatedResource: IResource = data.updateResource;
// eslint-disable-next-line vue/max-len
oldParentCachedResource.children.elements = oldParentCachedResource.children.elements.filter(
(cachedResource) => cachedResource.id !== updatedResource.id
);
oldParentCachedResource.children.elements =
oldParentCachedResource.children.elements.filter(
(cachedResource) => cachedResource.id !== updatedResource.id
);
store.writeQuery({
query: GET_RESOURCE,

View File

@ -155,7 +155,10 @@
<div class="container">
<div class="columns">
<div
class="column is-one-third-desktop is-offset-one-third-desktop"
class="
column
is-one-third-desktop is-offset-one-third-desktop
"
>
<h1 class="title">
{{ $t("Deleting your Mobilizon account") }}

View File

@ -251,8 +251,10 @@ export default class Notifications extends Vue {
if (this.loggedUser && this.loggedUser.settings) {
this.notificationOnDay = this.loggedUser.settings.notificationOnDay;
this.notificationEachWeek = this.loggedUser.settings.notificationEachWeek;
this.notificationBeforeEvent = this.loggedUser.settings.notificationBeforeEvent;
this.notificationPendingParticipation = this.loggedUser.settings.notificationPendingParticipation;
this.notificationBeforeEvent =
this.loggedUser.settings.notificationBeforeEvent;
this.notificationPendingParticipation =
this.loggedUser.settings.notificationPendingParticipation;
}
}

View File

@ -106,29 +106,27 @@ const decreaseFetches = () => {
Cypress.env("fetchCount", count - 1);
};
const buildTrackableFetchWithSessionId = (fetch) => (
fetchUrl,
fetchOptions
) => {
const { headers } = fetchOptions;
const modifiedHeaders = {
"x-session-id": Cypress.env("sessionId"),
...headers,
const buildTrackableFetchWithSessionId =
(fetch) => (fetchUrl, fetchOptions) => {
const { headers } = fetchOptions;
const modifiedHeaders = {
"x-session-id": Cypress.env("sessionId"),
...headers,
};
const modifiedOptions = { ...fetchOptions, headers: modifiedHeaders };
return fetch(fetchUrl, modifiedOptions)
.then((result) => {
decreaseFetches();
return Promise.resolve(result);
})
.catch((result) => {
decreaseFetches();
return Promise.reject(result);
});
};
const modifiedOptions = { ...fetchOptions, headers: modifiedHeaders };
return fetch(fetchUrl, modifiedOptions)
.then((result) => {
decreaseFetches();
return Promise.resolve(result);
})
.catch((result) => {
decreaseFetches();
return Promise.reject(result);
});
};
Cypress.on("window:before:load", (win) => {
cy.stub(win, "fetch", buildTrackableFetchWithSessionId(fetch));
});

View File

@ -3,25 +3,25 @@
exports[`CommentTree renders a comment tree 1`] = `
<div>
<!---->
<transition-stub name="comment-empty-list" mode="out-in">
<transition-group-stub name="comment-empty-list" mode="out-in">
<transition-group-stub tag="ul" name="comment-list" class="comment-list">
<comment-stub comment="[object Object]" event="[object Object]" class="root-comment"></comment-stub>
<comment-stub comment="[object Object]" event="[object Object]" class="root-comment"></comment-stub>
</transition-group-stub>
<div class="no-comments"><span>No comments yet</span></div>
</transition-stub>
</transition-group-stub>
</div>
`;
exports[`CommentTree renders a comment tree 2`] = `
<div>
<!---->
<transition-stub name="comment-empty-list" mode="out-in">
<transition-group-stub name="comment-empty-list" mode="out-in">
<transition-group-stub tag="ul" name="comment-list" class="comment-list">
<comment-stub comment="[object Object]" event="[object Object]" class="root-comment"></comment-stub>
<comment-stub comment="[object Object]" event="[object Object]" class="root-comment"></comment-stub>
</transition-group-stub>
<div class="no-comments"><span>No comments yet</span></div>
</transition-stub>
</transition-group-stub>
</div>
`;

View File

@ -54,6 +54,7 @@ export const configMock = {
__typename: "Features",
eventCreation: true,
groups: true,
koenaConnect: false,
},
geocoding: {
__typename: "Geocoding",

View File

@ -74,8 +74,7 @@ export const eventCommentThreadsMock = {
__typename: "Comment",
id: "2",
uuid: "e37910ea-fd5a-4756-9679-00971f3f4107",
url:
"https://some-instance.tld/comments/e37910ea-fd5a-4756-9679-00971f3f4107",
url: "https://some-instance.tld/comments/e37910ea-fd5a-4756-9679-00971f3f4107",
text: "my comment text",
local: true,
visibility: "PUBLIC",
@ -100,8 +99,7 @@ export const eventCommentThreadsMock = {
__typename: "Comment",
id: "29",
uuid: "e37910ea-fd5a-4756-9679-01171f3f4107",
url:
"https://some-instance.tld/comments/e37910ea-fd5a-4756-9679-01171f3f4107",
url: "https://some-instance.tld/comments/e37910ea-fd5a-4756-9679-01171f3f4107",
text: "a second comment",
local: true,
visibility: "PUBLIC",
@ -139,8 +137,7 @@ export const newCommentForEventResponse: DataMock = {
__typename: "Comment",
id: "79",
uuid: "e37910ea-fd5a-4756-9679-01171f3f4444",
url:
"https://some-instance.tld/comments/e37910ea-fd5a-4756-9679-01171f3f4444",
url: "https://some-instance.tld/comments/e37910ea-fd5a-4756-9679-01171f3f4444",
text: newCommentForEventMock.text,
local: true,
visibility: "PUBLIC",

File diff suppressed because it is too large Load Diff

View File

@ -126,7 +126,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
timezones: Tzdata.zone_list(),
features: %{
groups: Config.instance_group_feature_enabled?(),
event_creation: Config.instance_event_creation_enabled?()
event_creation: Config.instance_event_creation_enabled?(),
koena_connect: Config.get([:instance, :koena_connect_link], false)
},
rules: Config.instance_rules(),
version: Config.instance_version(),

View File

@ -268,6 +268,8 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
field(:event_creation, :boolean,
description: "Whether event creation is allowed on this instance"
)
field(:koena_connect, :boolean, description: "Activate link to Koena Connect")
end
@desc """

View File

@ -1,6 +1,7 @@
defimpl Mobilizon.Service.Metadata, for: Mobilizon.Posts.Post do
alias Phoenix.HTML
alias Phoenix.HTML.Tag
alias Mobilizon.Medias.{File, Media}
alias Mobilizon.Posts.Post
alias Mobilizon.Web.JsonLD.ObjectView
import Mobilizon.Service.Metadata.Utils, only: [process_description: 2, strip_tags: 1]
@ -8,15 +9,17 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Posts.Post do
def build_tags(%Post{} = post, locale \\ "en") do
post = Map.put(post, :body, process_description(post.body, locale))
tags = [
Tag.tag(:meta, property: "og:title", content: post.title),
Tag.tag(:meta, property: "og:url", content: post.url),
Tag.tag(:meta, property: "og:description", content: post.body),
Tag.tag(:meta, property: "og:type", content: "article"),
Tag.tag(:meta, property: "twitter:card", content: "summary"),
# Tell Search Engines what's the origin
Tag.tag(:link, rel: "canonical", href: post.url)
]
tags =
[
Tag.tag(:meta, property: "og:title", content: post.title),
Tag.tag(:meta, property: "og:url", content: post.url),
Tag.tag(:meta, property: "og:description", content: post.body),
Tag.tag(:meta, property: "og:type", content: "article"),
Tag.tag(:meta, property: "twitter:card", content: "summary"),
# Tell Search Engines what's the origin
Tag.tag(:link, rel: "canonical", href: post.url)
]
|> maybe_add_post_picture(post)
tags ++
[
@ -31,4 +34,17 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Posts.Post do
|> ObjectView.render(%{post: %{post | title: strip_tags(title)}})
|> Jason.encode!()
end
@spec maybe_add_post_picture(list(), Post.t()) :: list()
defp maybe_add_post_picture(tags, %Post{picture: %Media{file: %File{url: url}}}),
do:
tags ++
[
Tag.tag(:meta,
property: "og:image",
content: url
)
]
defp maybe_add_post_picture(tags, _), do: tags
end

View File

@ -56,20 +56,12 @@ defmodule Mobilizon.Service.RichMedia.Favicon do
@spec format_url(String.t(), String.t()) :: String.t()
defp format_url(url, path) do
image_uri = URI.parse(path)
uri = URI.parse(url)
cond do
is_nil(image_uri.host) -> "#{uri.scheme}://#{uri.host}#{correct_path(path)}"
is_nil(image_uri.scheme) -> "#{uri.scheme}:#{path}"
true -> path
end
url
|> URI.parse()
|> URI.merge(path)
|> to_string()
end
# Sometimes paths have "/" in front, sometimes not
defp correct_path("/" <> _ = path), do: path
defp correct_path(path), do: "/#{path}"
@spec find_favicon_link_tag(String.t()) :: {:ok, tuple()} | {:error, any()}
defp find_favicon_link_tag(html) do
with {:ok, html} <- Floki.parse_document(html),

View File

@ -19,6 +19,7 @@ defmodule Mobilizon.Service.RichMedia.Parser do
alias Mobilizon.Config
alias Mobilizon.Service.HTTP.RichMediaPreviewClient
alias Mobilizon.Service.RichMedia.Favicon
alias Mobilizon.Service.RichMedia.Parsers.Fallback
alias Plug.Conn.Utils
require Logger
@ -73,12 +74,11 @@ defmodule Mobilizon.Service.RichMedia.Parser do
{:is_html, _response_headers, true} <-
{:is_html, response_headers, is_html(response_headers)} do
body
|> parse_html()
|> maybe_parse()
|> Map.put(:url, url)
|> maybe_add_favicon()
|> clean_parsed_data()
|> check_parsed_data()
|> check_parsed_data(body)
|> check_remote_picture_path()
else
{:is_html, response_headers, false} ->
@ -192,8 +192,7 @@ defmodule Mobilizon.Service.RichMedia.Parser do
end
end
defp parse_html(html), do: Floki.parse_document!(html)
@spec maybe_parse(String.t()) :: {:halt, map()} | {:cont, map()}
defp maybe_parse(html) do
Enum.reduce_while(parsers(), %{}, fn parser, acc ->
case parser.parse(html, acc) do
@ -206,14 +205,24 @@ defmodule Mobilizon.Service.RichMedia.Parser do
end)
end
defp check_parsed_data(%{title: title} = data)
defp check_parsed_data(data, html, first_run \\ true)
defp check_parsed_data(%{title: title} = data, _html, _first_run)
when is_binary(title) and byte_size(title) > 0 do
data
end
defp check_parsed_data(data) do
Logger.debug("Found metadata was invalid or incomplete: #{inspect(data)}")
{:error, :invalid_parsed_data}
defp check_parsed_data(data, html, first_run) do
# Maybe the first data found is incomplete, pass it through the Fallback parser once again
if first_run do
{:ok, data} = Fallback.parse(html, data)
Logger.debug("check parsed data")
Logger.debug(inspect(data))
check_parsed_data(data, html, false)
else
Logger.debug("Found metadata was invalid or incomplete: #{inspect(data)}")
{:error, :invalid_parsed_data}
end
end
defp clean_parsed_data(data) do
@ -280,25 +289,20 @@ defmodule Mobilizon.Service.RichMedia.Parser do
@spec check_remote_picture_path(map()) :: map()
defp check_remote_picture_path(%{image_remote_url: image_remote_url, url: url} = data) do
Logger.debug("Checking image_remote_url #{image_remote_url}")
image_uri = URI.parse(image_remote_url)
uri = URI.parse(url)
image_remote_url =
cond do
is_nil(image_uri.host) -> "#{uri.scheme}://#{uri.host}#{correct_path(image_remote_url)}"
is_nil(image_uri.scheme) -> "#{uri.scheme}:#{image_remote_url}"
true -> image_remote_url
end
data = Map.put(data, :image_remote_url, image_remote_url)
data = Map.put(data, :image_remote_url, format_url(url, image_remote_url))
{:ok, data}
end
defp check_remote_picture_path(data), do: {:ok, data}
# Sometimes paths have "/" in front, sometimes not
defp correct_path("/" <> _ = path), do: path
defp correct_path(path), do: "/#{path}"
@spec format_url(String.t(), String.t()) :: String.t()
defp format_url(url, path) do
url
|> URI.parse()
|> URI.merge(path)
|> to_string()
end
# Twitter requires a well-know crawler user-agent to show server-rendered data
defp default_user_agent("https://twitter.com/" <> _) do

View File

@ -29,11 +29,19 @@ defmodule Mobilizon.Service.RichMedia.Parsers.Fallback do
end
defp get_page(html, :title) do
html |> Floki.find("html head title") |> List.first() |> Floki.text() |> String.trim()
html
|> Floki.parse_document!()
|> Floki.find("html title")
|> List.first()
|> Floki.text()
|> String.trim()
end
defp get_page(html, :description) do
case html |> Floki.find("html head meta[name='description']") |> List.first() do
case html
|> Floki.parse_document!()
|> Floki.find("html meta[name='description']")
|> List.first() do
nil -> ""
elem -> elem |> Floki.attribute("content") |> List.first() |> String.trim()
end

View File

@ -36,7 +36,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.MetaTagsParser do
end
defp get_elements(html, key_name, prefix) do
html |> Floki.find("meta[#{to_string(key_name)}^='#{prefix}:']")
html |> Floki.parse_document!() |> Floki.find("meta[#{to_string(key_name)}^='#{prefix}:']")
end
defp normalize_attributes(html_node, prefix, key_name, value_name, allowed_attributes) do
@ -83,14 +83,26 @@ defmodule Mobilizon.Service.RichMedia.Parsers.MetaTagsParser do
defp maybe_put_description(meta, _), do: meta
@spec get_page_title(String.t()) :: String.t()
defp get_page_title(html) do
html |> Floki.find("html head title") |> List.first() |> Floki.text()
with {:ok, document} <- Floki.parse_document(html),
elem when not is_nil(elem) <- document |> Floki.find("html head title") |> List.first(),
title when is_binary(title) <- Floki.text(elem) do
title
else
_ -> ""
end
end
@spec get_page_description(String.t()) :: String.t()
defp get_page_description(html) do
case html |> Floki.find("html head meta[name='description']") |> List.first() do
nil -> ""
elem -> Floki.attribute(elem, "content")
with {:ok, document} <- Floki.parse_document(html),
elem when not is_nil(elem) <-
document |> Floki.find("html head meta[name='description']") |> List.first(),
description when is_binary(description) <- Floki.attribute(elem, "content") do
description
else
_ -> ""
end
end
end

View File

@ -32,7 +32,9 @@ defmodule Mobilizon.Service.RichMedia.Parsers.OEmbed do
end
defp get_discovery_data(html) do
html |> Floki.find("link[type='application/json+oembed']")
with {:ok, document} <- Floki.parse_document(html) do
Floki.find(document, "link[type='application/json+oembed']")
end
end
defp get_oembed_url(nodes) do

View File

@ -58,7 +58,7 @@ defmodule Mobilizon.Web.MediaProxy do
end
defp signed_url(url) do
:crypto.hmac(:sha, Config.get([Web.Endpoint, :secret_key_base]), url)
:crypto.mac(:hmac, :sha, Config.get([Web.Endpoint, :secret_key_base]), url)
end
def filename(url_or_path) do

View File

@ -1,7 +1,7 @@
defmodule Mobilizon.Mixfile do
use Mix.Project
@version "1.1.3"
@version "1.1.4"
def project do
[

View File

@ -15,9 +15,9 @@
"comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"},
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"},
"cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
"cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"},
"dataloader": {:hex, :dataloader, "1.0.8", "114294362db98a613f231589246aa5b0ce847412e8e75c4c94f31f204d272cbf", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "eaf3c2aa2bc9dbd2f1e960561d616b7f593396c4754185b75904f6d66c82a667"},
"db_connection": {:hex, :db_connection, "2.4.0", "d04b1b73795dae60cead94189f1b8a51cc9e1f911c234cc23074017c43c031e5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad416c21ad9f61b3103d254a71b63696ecadb6a917b36f563921e0de00d7d7c8"},
@ -35,12 +35,12 @@
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"erlsom": {:hex, :erlsom, "1.5.0", "c5a5cdd0ee0e8dca62bcc4b13ff08da24fdefc16ccd8b25282a2fda2ba1be24a", [:rebar3], [], "hexpm", "55a9dbf9cfa77fcfc108bd8e2c4f9f784dea228a8f4b06ea10b684944946955a"},
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
"ex_cldr": {:hex, :ex_cldr, "2.20.0", "571a4b490c333809be59cc984a21be2deaab1db9e2418e323d5935aec8b1394a", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.15", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "06147e4a27be62e6fe92db14cf5048c645927bfc530aa1cc6af8c92d65e32427"},
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.14.0", "e1d1a6a0e9d594bc0da4f2881c9b0fac822075f5e2bfdba3ef5edf1a0a66abac", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.17", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.5", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "6f95e8350b00aedb26610fd461803993efe737bc535bfbf8cce4c7f66944648c"},
"ex_cldr": {:hex, :ex_cldr, "2.21.0", "27144a6649df3a315de85da5b9ad2db1b9e2a754d0c6ea498653b859b6340e04", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.15", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "4b3d8df8ada72f0d82e867fea7c88de9904c19dc69e5797684757ad64e907df7"},
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.14.1", "50b4d2b1105780743647bbcede5109c9efcf57c525cb773ba9467bea817df379", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.17", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.5", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "ffd960e96a1d67d565a59c5d02c16506c4a3df6c70673d8d48087d6b11bca0a3"},
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.9.1", "692d9d8262bd9c423d601d5ce6ae294df85f8652664e723e2cfd68d97bd72a10", [:mix], [{:ex_cldr, "~> 2.20", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1bc6f9eabef1e79e98cb9f8b14dc5657c17ddcbea31e800440fd52a6e45e20ac"},
"ex_cldr_dates_times": {:hex, :ex_cldr_dates_times, "2.7.0", "c8fc77e075e7408fd414b2a4396e2023901032a3c20d94035b8cee54a10f28c9", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_calendars, "~> 1.13", [hex: :ex_cldr_calendars, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.17", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "e21e8c6f9440c91d6111cb39ac96a423d833206ce8d1b24bbdeddd12b2b9427d"},
"ex_cldr_dates_times": {:hex, :ex_cldr_dates_times, "2.7.2", "04aea75ccc017e006961f9c6413aa203630ec2a3bb03091b5943d0013ff21b61", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_calendars, "~> 1.13", [hex: :ex_cldr_calendars, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.17", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "ae6bcb69d5e6585b10265eb984d60894e82ff5b91c0ac61ea7d35278a11e9aa0"},
"ex_cldr_languages": {:hex, :ex_cldr_languages, "0.2.2", "d7dab93272443b70e18e6aef0f62974418baaca3a3b31a66d51921ec1547113c", [:mix], [{:ex_cldr, "~> 2.2 and >= 2.2.1", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "d9cbf4bf643365b0042e774520ddfcbc31618efd5a5383fac98f75149961622c"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.17.0", "e79d4161ca82ce8d40bec5bb7dc83d457e81d03e39042e5b62ff48b2cc3c35f3", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.20", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.9", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "c6b7ee62e97cefc6d3c47896608f8152cc65ea40238ea99cd92c6f04acdd1627"},
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.18.0", "58ff26aa7420e6bc3d0e0902c031b409b30cbc924e31efa1df0988f865c7756c", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.21", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, "~> 2.9", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:ex_doc, "~> 0.18", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "9663db9c6a3d2bae4d6cf9847aad7f00c48c87a3336629b34d72f70ad753f7cb"},
"ex_crypto": {:hex, :ex_crypto, "0.10.0", "af600a89b784b36613a989da6e998c1b200ff1214c3cfbaf8deca4aa2f0a1739", [:mix], [{:poison, ">= 2.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "ccc7472cfe8a0f4565f97dce7e9280119bf15a5ea51c6535e5b65f00660cde1c"},
"ex_doc": {:hex, :ex_doc, "0.24.2", "e4c26603830c1a2286dae45f4412a4d1980e1e89dc779fcd0181ed1d5a05c8d9", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e134e1d9e821b8d9e4244687fb2ace58d479b67b282de5158333b0d57c6fb7da"},
"ex_ical": {:hex, :ex_ical, "0.2.0", "4b928b554614704016cc0c9ee226eb854da9327a1cc460457621ceacb1ac29a6", [:mix], [{:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "db76473b2ae0259e6633c6c479a5a4d8603f09497f55c88f9ef4d53d2b75befb"},
@ -86,14 +86,14 @@
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"meck": {:hex, :meck, "0.8.13", "ffedb39f99b0b99703b8601c6f17c7f76313ee12de6b646e671e3188401f7866", [:rebar3], [], "hexpm", "d34f013c156db51ad57cc556891b9720e6a1c1df5fe2e15af999c84d6cebeb1a"},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"mimetype_parser": {:hex, :mimetype_parser, "0.1.3", "628ac9fe56aa7edcedb534d68397dd66674ab82493c8ebe39acb9a19b666099d", [:mix], [], "hexpm", "7d8f80c567807ce78cd93c938e7f4b0a20b1aaaaab914bf286f68457d9f7a852"},
"mix_test_watch": {:hex, :mix_test_watch, "1.0.2", "34900184cbbbc6b6ed616ed3a8ea9b791f9fd2088419352a6d3200525637f785", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "47ac558d8b06f684773972c6d04fcc15590abdb97aeb7666da19fcbfdc441a07"},
"mmdb2_decoder": {:hex, :mmdb2_decoder, "3.0.0", "54828676a36e75e9a25bc9a0bb0598d4c7fcc767bf0b40674850b22e05b7b6cc", [:mix], [], "hexpm", "359dc9242915538d1dceb9f6d96c72201dca76ce62e49d22e2ed1e86f20bea8e"},
"mock": {:hex, :mock, "0.3.6", "e810a91fabc7adf63ab5fdbec5d9d3b492413b8cda5131a2a8aa34b4185eb9b4", [:mix], [{:meck, "~> 0.8.13", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "bcf1d0a6826fb5aee01bae3d74474669a3fa8b2df274d094af54a25266a1ebd2"},
"mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"},
"mogrify": {:hex, :mogrify, "0.8.0", "3506f3ca3f7b95a155f3b4ef803b5db176f5a0633723e3fe85e0d6399e3b11c8", [:mix], [], "hexpm", "2278d245f07056ea3b586e98801e933695147066fa4cf563f552c1b4f0ff8ad9"},
"mox": {:hex, :mox, "1.0.0", "4b3c7005173f47ff30641ba044eb0fe67287743eec9bd9545e37f3002b0a9f8b", [:mix], [], "hexpm", "201b0a20b7abdaaab083e9cf97884950f8a30a1350a1da403b3145e213c6f4df"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
@ -102,7 +102,7 @@
"oauther": {:hex, :oauther, "1.1.1", "7d8b16167bb587ecbcddd3f8792beb9ec3e7b65c1f8ebd86b8dd25318d535752", [:mix], [], "hexpm", "9374f4302045321874cccdc57eb975893643bd69c3b22bf1312dab5f06e5788e"},
"oban": {:hex, :oban, "2.6.1", "7466e25934be6c3f696c624ed0779459dd2add03d19f9865a478d3b47b77e814", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3e86eaab8fdd1c1af64f7cfd46ad4352d19696709eb2068de239e40894a254ea"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"phoenix": {:hex, :phoenix, "1.5.8", "71cfa7a9bb9a37af4df98939790642f210e35f696b935ca6d9d9c55a884621a4", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "35ded0a32f4836168c7ab6c33b88822eccd201bcd9492125a9bea4c54332d955"},
"phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.2.1", "13f124cf0a3ce0f1948cf24654c7b9f2347169ff75c1123f44674afee6af3b03", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "478a1bae899cac0a6e02be1deec7e2944b7754c04e7d4107fc5a517f877743c0"},
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.1", "9eba6ad16bd80c45f338b2059c7b255ce30784d76f4181304e7b78640e5a7513", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "f3ae26b5abb85a1cb2bc8bb199e29fbcefb34259e469b31fe0c6323f2175a5ef"},
@ -113,7 +113,7 @@
"poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm", "ba8836feea4b394bb718a161fc59a288fe0109b5006d6bdf97b6badfcf6f0f25"},
"postgrex": {:hex, :postgrex, "0.15.9", "46f8fe6f25711aeb861c4d0ae09780facfdf3adbd2fb5594ead61504dd489bda", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "610719103e4cb2223d4ab78f9f0f3e720320eeca6011415ab4137ddef730adee"},
"progress_bar": {:hex, :progress_bar, "2.0.1", "7b40200112ae533d5adceb80ff75fbe66dc753bca5f6c55c073bfc122d71896d", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "2519eb58a2f149a3a094e729378256d8cb6d96a259ec94841bd69fdc71f18f87"},
"ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
"remote_ip": {:hex, :remote_ip, "1.0.0", "3d7fb45204a5704443f480cee9515e464997f52c35e0a60b6ece1f81484067ae", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "9e9fcad4e50c43b5234bb6a9629ed6ab223f3ed07147bd35470e4ee5c8caf907"},
"rsa_ex": {:hex, :rsa_ex, "0.4.0", "e28dd7dc5236e156df434af0e4aa822384c8866c928e17b785d4edb7c253b558", [:mix], [], "hexpm", "40e1f08e8401da4be59a6dd0f4da30c42d5bb01703161f0208d839d97db27f4e"},
"sentry": {:hex, :sentry, "8.0.5", "5ca922b9238a50c7258b52f47364b2d545beda5e436c7a43965b34577f1ef61f", [:mix], [{:hackney, "~> 1.8", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, "~> 2.3", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "4972839fdbf52e886d7b3e694c8adf421f764f2fa79036b88fb4742049bd4b7c"},

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-09-24 14:40+0000\n"
"PO-Revision-Date: 2021-04-28 14:49+0000\n"
"PO-Revision-Date: 2021-05-17 16:22+0000\n"
"Last-Translator: Leo Durruti <leodurruti@disroot.org>\n"
"Language-Team: Italian <https://weblate.framasoft.org/projects/mobilizon/"
"backend/it/>\n"
@ -100,7 +100,7 @@ msgstr "Partecipazione approvata"
#: lib/web/templates/email/password_reset.text.eex:1
#, elixir-format
msgid "Password reset"
msgstr "Reset della password"
msgstr "Resettare la password"
#: lib/web/templates/email/password_reset.text.eex:7
#, elixir-format
@ -144,7 +144,7 @@ msgstr "Hai richiesto una nuova password per il tuo account su %{instance}."
#: lib/web/templates/email/email.html.eex:85
#, elixir-format
msgid "Warning"
msgstr "Attenzione"
msgstr "Avviso"
#: lib/web/email/participation.ex:135
#, elixir-format
@ -1039,9 +1039,9 @@ msgstr ""
"Ciao! Solo una breve nota per confermare che l'indirizzo email collegato al "
"tuo account su% {host} è stato cambiato da questo a:"
#, elixir-format
#: lib/web/templates/email/email_changed_old.html.eex:62
#: lib/web/templates/email/email_changed_old.text.eex:5
#, elixir-format
msgid "If you did not trigger this change yourself, it is likely that someone has gained access to your %{host} account. Please log in and change your password immediately. If you cannot login, contact the admin on %{host}."
msgstr ""
"Se non hai attivato tu stesso questa modifica, è probabile che qualcuno "
@ -1079,7 +1079,7 @@ msgstr "Scopri di più su Mobilizon qui!"
#: lib/web/templates/email/event_updated.html.eex:94
#, elixir-format
msgid "Location"
msgstr "Luogo"
msgstr "Posizione"
#: lib/web/templates/email/event_updated.html.eex:104
#, elixir-format
@ -1694,25 +1694,25 @@ msgstr "Siamo spiacenti, ma qualcosa è andato storto da parte nostra."
#: lib/web/templates/email/email.text.eex:4
#, elixir-format
msgid "This is a demonstration site to test Mobilizon."
msgstr "Questo è un sito dimostrativo per testare Mobilizon."
msgstr "Questo è un sito di prova per testare Mobilizon."
#: lib/service/metadata/actor.ex:53 lib/service/metadata/actor.ex:60
#: lib/service/metadata/instance.ex:54 lib/service/metadata/instance.ex:60
msgid "%{name}'s feed"
msgstr "Flusso di %{name}"
#, elixir-format
#: lib/service/export/feed.ex:120
#, elixir-format
msgid "%{actor}'s private events feed on %{instance}"
msgstr "Flusso privato degli eventi di %{actor} su %{instance}"
#, elixir-format
#: lib/service/export/feed.ex:115
#, elixir-format
msgid "%{actor}'s public events feed on %{instance}"
msgstr "Flusso pubblico degli eventi di %{actor} su %{instance}"
#, elixir-format
#: lib/service/export/feed.ex:220
#, elixir-format
msgid "Feed for %{email} on %{instance}"
msgstr "Flusso per %{email} su %{instance}"
@ -1739,7 +1739,7 @@ msgstr "Dettagli tecnici"
msgid "The Mobilizon server %{instance} seems to be temporarily down."
msgstr "Il server Mobilizon sembra essere temporaneamente inattivo."
#, elixir-format
#: lib/service/export/feed.ex:73
#, elixir-format
msgid "Public feed for %{instance}"
msgstr ""
msgstr "Feed pubblico per %{instance}"

View File

@ -8,7 +8,7 @@
## to merge POT files into PO files.
msgid ""
msgstr ""
"PO-Revision-Date: 2021-04-28 14:49+0000\n"
"PO-Revision-Date: 2021-05-17 16:22+0000\n"
"Last-Translator: Leo Durruti <leodurruti@disroot.org>\n"
"Language-Team: Italian <https://weblate.framasoft.org/projects/mobilizon/"
"backend-errors/it/>\n"
@ -99,13 +99,13 @@ msgstr "dev'essere uguale a %{number}"
msgid "Cannot refresh the token"
msgstr "Il token non può essere aggiornato"
#, elixir-format
#: lib/graphql/resolvers/group.ex:206
#, elixir-format
msgid "Current profile is not a member of this group"
msgstr "Il profilo corrente non è membro di questo gruppo"
#, elixir-format
#: lib/graphql/resolvers/group.ex:210
#, elixir-format
msgid "Current profile is not an administrator of the selected group"
msgstr "Il profilo corrente non è amministratore del gruppo selezionato"
@ -114,14 +114,14 @@ msgstr "Il profilo corrente non è amministratore del gruppo selezionato"
msgid "Error while saving user settings"
msgstr "Errore nel salvare le preferenze utente"
#, elixir-format
#: lib/graphql/error.ex:90 lib/graphql/resolvers/group.ex:203
#: lib/graphql/resolvers/group.ex:234 lib/graphql/resolvers/group.ex:269 lib/graphql/resolvers/member.ex:80
#, elixir-format
msgid "Group not found"
msgstr "Gruppo non trovato"
#, elixir-format
#: lib/graphql/resolvers/group.ex:68
#, elixir-format
msgid "Group with ID %{id} not found"
msgstr "Gruppo con ID %{id} non trovato"
@ -130,8 +130,8 @@ msgstr "Gruppo con ID %{id} non trovato"
msgid "Impossible to authenticate, either your email or password are invalid."
msgstr "Impossibile autenticarsi: email e/o password non validi."
#, elixir-format
#: lib/graphql/resolvers/group.ex:266
#, elixir-format
msgid "Member not found"
msgstr "Membro non trovato"
@ -146,8 +146,8 @@ msgstr "Nessun profilo trovato per l'utente moderatore"
msgid "No user to validate with this email was found"
msgstr "Nessun utente da convalidare trovato con questa email"
#, elixir-format
#: lib/graphql/resolvers/person.ex:254 lib/graphql/resolvers/user.ex:218
#, elixir-format
msgid "No user with this email was found"
msgstr "Nessun utente con questa email"
@ -220,23 +220,23 @@ msgstr "Utente già disabilitato"
msgid "User requested is not logged-in"
msgstr "L'utente richiesto non è loggato"
#, elixir-format
#: lib/graphql/resolvers/group.ex:240
#, elixir-format
msgid "You are already a member of this group"
msgstr "Sei già un membro di questo gruppo"
#, elixir-format
#: lib/graphql/resolvers/group.ex:273
#, elixir-format
msgid "You can't leave this group because you are the only administrator"
msgstr "Non puoi lasciare questo gruppo perchè sei l'unico amministratore"
#, elixir-format
#: lib/graphql/resolvers/group.ex:237
#, elixir-format
msgid "You cannot join this group"
msgstr "Non puoi unirti a questo gruppo"
#, elixir-format
#: lib/graphql/resolvers/group.ex:96
#, elixir-format
msgid "You may not list groups unless moderator."
msgstr "Non è possibile elencare i gruppi a meno che non sia un moderatore."
@ -250,8 +250,8 @@ msgstr "È necessario effettuare il login per modificare la tua email"
msgid "You need to be logged-in to change your password"
msgstr "È necessario effettuare il login per modificare la tua password"
#, elixir-format
#: lib/graphql/resolvers/group.ex:215
#, elixir-format
msgid "You need to be logged-in to delete a group"
msgstr "È necessario effettuare il login per eliminare un gruppo"
@ -260,18 +260,18 @@ msgstr "È necessario effettuare il login per eliminare un gruppo"
msgid "You need to be logged-in to delete your account"
msgstr "È necessario effettuare il login per eliminare il tuo account"
#, elixir-format
#: lib/graphql/resolvers/group.ex:245
#, elixir-format
msgid "You need to be logged-in to join a group"
msgstr "È necessario effettuare il login per entrare a far parte di un gruppo"
#, elixir-format
#: lib/graphql/resolvers/group.ex:278
#, elixir-format
msgid "You need to be logged-in to leave a group"
msgstr "È necessario effettuare il login per lasciare un gruppo"
#, elixir-format
#: lib/graphql/resolvers/group.ex:180
#, elixir-format
msgid "You need to be logged-in to update a group"
msgstr "È necessario effettuare il login per aggiornare un gruppo"
@ -337,13 +337,13 @@ msgstr "Un'email valida è richiesta dalla vostra istanza"
msgid "Anonymous participation is not enabled"
msgstr "La partecipazione anonima non è abilitata"
#, elixir-format
#: lib/graphql/resolvers/person.ex:196
#, elixir-format
msgid "Cannot remove the last administrator of a group"
msgstr "Impossibile rimuovere l'ultimo amministratore di un gruppo"
#, elixir-format
#: lib/graphql/resolvers/person.ex:193
#, elixir-format
msgid "Cannot remove the last identity of a user"
msgstr "Impossibile rimuovere l'ultima identità di un utente"
@ -389,8 +389,8 @@ msgstr "L'evento con questo ID %{id} non esiste"
msgid "Internal Error"
msgstr "Errore Interno"
#, elixir-format
#: lib/graphql/resolvers/discussion.ex:202
#, elixir-format
msgid "No discussion with ID %{id}"
msgstr "Nessuna discussione con l'ID %{id}"
@ -399,8 +399,8 @@ msgstr "Nessuna discussione con l'ID %{id}"
msgid "No profile found for user"
msgstr "Nessuno profilo trovato per l'utente"
#, elixir-format
#: lib/graphql/resolvers/feed_token.ex:64
#, elixir-format
msgid "No such feed token"
msgstr "Nessun token di rifornimento corrispondente"
@ -416,13 +416,13 @@ msgstr "Il partecipante ha già il ruolo %{role}"
msgid "Participant not found"
msgstr "Partecipante non trovato"
#, elixir-format
#: lib/graphql/resolvers/person.ex:30
#, elixir-format
msgid "Person with ID %{id} not found"
msgstr "La persona con l'ID %{id} non è stata trovata"
#, elixir-format
#: lib/graphql/resolvers/person.ex:52
#, elixir-format
msgid "Person with username %{username} not found"
msgstr "La persona con il nome utente %{username} non è stata trovata"
@ -455,14 +455,14 @@ msgstr "Il profilo è già un membro diquesto gruppo"
msgid "Profile is not member of group"
msgstr "Il profilo non è membro del gruppo"
#, elixir-format
#: lib/graphql/resolvers/person.ex:162 lib/graphql/resolvers/person.ex:190
#, elixir-format
msgid "Profile not found"
msgstr "Profilo non trovato"
#, elixir-format
#: lib/graphql/resolvers/report.ex:36
#, elixir-format
#, elixir-format
msgid "Report not found"
msgstr "Segnalazione non trovata"
@ -492,23 +492,23 @@ msgstr "L'elemento to-do non esiste"
msgid "Todo list doesn't exist"
msgstr "la lista non esiste"
#, elixir-format
#: lib/graphql/resolvers/feed_token.ex:73
#, elixir-format
msgid "Token does not exist"
msgstr "Il token non esiste"
#, elixir-format
#: lib/graphql/resolvers/feed_token.ex:67 lib/graphql/resolvers/feed_token.ex:70
#, elixir-format
msgid "Token is not a valid UUID"
msgstr "Il token non è un UUID valido"
#, elixir-format
#: lib/graphql/error.ex:87 lib/graphql/resolvers/person.ex:362
#, elixir-format
msgid "User not found"
msgstr "Utente non trovato"
#, elixir-format
#: lib/graphql/resolvers/person.ex:257
#, elixir-format
msgid "You already have a profile for this user"
msgstr "Hai già un profilo per questo utente"
@ -522,8 +522,8 @@ msgstr "Se già un partecipante di questo evento"
msgid "You are not a member of this group"
msgstr "Non sei un membro di questo gruppo"
#, elixir-format
#: lib/graphql/resolvers/member.ex:149
#, elixir-format
msgid "You are not a moderator or admin for this group"
msgstr "Non sei un moderatore o amministratore di questo gruppo"
@ -542,8 +542,8 @@ msgstr "Non puoi creare un token di rifornimento senza connessione"
msgid "You are not allowed to delete a comment if not connected"
msgstr "Non è consentito eliminare un commento se non si è collegati"
#, elixir-format
#: lib/graphql/resolvers/feed_token.ex:82
#, elixir-format
msgid "You are not allowed to delete a feed token if not connected"
msgstr "Non puoi eliminare un token di rifornimento senza connettersi"
@ -559,8 +559,8 @@ msgid "You can't leave event because you're the only event creator participant"
msgstr ""
"Non puoi lasciare l'evento perchè sei l'unico partecipante creatore di eventi"
#, elixir-format
#: lib/graphql/resolvers/member.ex:153
#, elixir-format
msgid "You can't set yourself to a lower member role for this group because you are the only administrator"
msgstr ""
"Non puoi impostare te stesso per un ruolo di membro inferiore per questo "
@ -581,13 +581,13 @@ msgstr "Non puoi eliminare questo evento"
msgid "You cannot invite to this group"
msgstr "Non puoi invitare in questo gruppo"
#, elixir-format
#: lib/graphql/resolvers/feed_token.ex:76
#, elixir-format
msgid "You don't have permission to delete this token"
msgstr "Non hai il permesso di cancellare questo token"
#, elixir-format
#: lib/graphql/resolvers/admin.ex:53
#, elixir-format
msgid "You need to be logged-in and a moderator to list action logs"
msgstr "Devi essere connesso e un moderatore per elencare i log delle azioni"
@ -606,29 +606,29 @@ msgstr "Devi essere connesso e un moderatore per aggiornare un rapporto"
msgid "You need to be logged-in and a moderator to view a report"
msgstr "Devi essere connesso e un moderatore per visualizzare un rapporto"
#, elixir-format
#: lib/graphql/resolvers/admin.ex:237
#, elixir-format
msgid "You need to be logged-in and an administrator to access admin settings"
msgstr ""
"Devi essere connesso e un moderatore per accedere alle opzioni "
"dell'amministratore"
#, elixir-format
#: lib/graphql/resolvers/admin.ex:222
#, elixir-format
msgid "You need to be logged-in and an administrator to access dashboard statistics"
msgstr ""
"Devi essere connesso e un moderatore per accedere alle statistiche del "
"dashboard"
#, elixir-format
#: lib/graphql/resolvers/admin.ex:261
#, elixir-format
msgid "You need to be logged-in and an administrator to save admin settings"
msgstr ""
"Devi essere connesso e un moderatore per salvare le impostazioni "
"dell'amministratore"
#, elixir-format
#: lib/graphql/resolvers/discussion.ex:77
#, elixir-format
msgid "You need to be logged-in to access discussions"
msgstr "Devi essere connesso per accedere alle discussioni"
@ -769,13 +769,13 @@ msgstr "Non hai il permesso di farlo"
msgid "You need to be logged in"
msgstr "Devi essere connesso"
#, elixir-format
#: lib/graphql/resolvers/member.ex:114
#, elixir-format
msgid "You can't accept this invitation with this profile."
msgstr "Non puoi accettare l'invito con questo profilo."
#, elixir-format
#: lib/graphql/resolvers/member.ex:132
#, elixir-format
msgid "You can't reject this invitation with this profile."
msgstr "Non puoi rifiutare l'invito con questo profilo."
@ -784,8 +784,8 @@ msgstr "Non puoi rifiutare l'invito con questo profilo."
msgid "File doesn't have an allowed MIME type."
msgstr "Il file non ha un tipo MIME consentito."
#, elixir-format
#: lib/graphql/resolvers/group.ex:175
#, elixir-format
msgid "Profile is not administrator for the group"
msgstr "Il profilo non è amministratore del gruppo"
@ -799,18 +799,18 @@ msgstr "Non puoi modificare questo evento."
msgid "You can't attribute this event to this profile."
msgstr "Non puo iattribuire questo evento a questo profilo."
#, elixir-format
#: lib/graphql/resolvers/member.ex:135
#, elixir-format
msgid "This invitation doesn't exist."
msgstr "Questo invito non esiste."
#, elixir-format
#: lib/graphql/resolvers/member.ex:177
#, elixir-format
msgid "This member already has been rejected."
msgstr "Questo memebro è già stato rifiutato."
#, elixir-format
#: lib/graphql/resolvers/member.ex:184
#, elixir-format
msgid "You don't have the right to remove this member."
msgstr "Non hai il diritto di rimuovere questo membro."
@ -819,8 +819,8 @@ msgstr "Non hai il diritto di rimuovere questo membro."
msgid "This username is already taken."
msgstr "Questo nome utente è già in uso."
#, elixir-format
#: lib/graphql/resolvers/discussion.ex:74
#, elixir-format
msgid "You must provide either an ID or a slug to access a discussion"
msgstr ""
"Devi fornire un ID o la stringa utente (ad es. <em>utente@mobilizon.sm</em>) "
@ -836,9 +836,9 @@ msgstr "Il profilo dell'organizzatore non è di proprietà dell'utente"
msgid "Profile ID provided is not the anonymous profile one"
msgstr "L'ID profilo fornito non è quello del profilo anonimo"
#, elixir-format
#: lib/graphql/resolvers/group.ex:136 lib/graphql/resolvers/group.ex:169
#: lib/graphql/resolvers/person.ex:132 lib/graphql/resolvers/person.ex:159 lib/graphql/resolvers/person.ex:251
#, elixir-format
msgid "The provided picture is too heavy"
msgstr "L'immagine inserita è troppo pesante"
@ -847,9 +847,9 @@ msgstr "L'immagine inserita è troppo pesante"
msgid "Index file not found. You need to recompile the front-end."
msgstr "Il file di indice non è stato trovato. Devi ricompilare il front-end."
#, elixir-format
#: lib/graphql/resolvers/resource.ex:122
#, elixir-format
#, elixir-format
msgid "Error while creating resource"
msgstr "Errore durante la creazione della risorsa"
@ -861,10 +861,10 @@ msgstr "Token di attivazione non valido"
#: lib/graphql/resolvers/resource.ex:208
#, elixir-format
msgid "Unable to fetch resource details from this URL."
msgstr ""
msgstr "Impossibile recuperare i dettagli della risorsa da questa URL."
#, elixir-format
#: lib/graphql/resolvers/event.ex:145 lib/graphql/resolvers/participant.ex:234
#, elixir-format
msgid "Provided profile doesn't have moderator permissions on this event"
msgstr ""
"Il profilo del moderatore fornito non dispone dell'autorizzazione per questo "

View File

@ -61,8 +61,8 @@ defmodule Mobilizon.Federation.ActivityPubTest do
end
test "object reply by url" do
url = "https://zoltasila.pl/objects/1c295713-8e3c-411e-9e62-57a7b9c9e514"
reply_to_url = "https://framapiaf.org/users/peertube/statuses/104584600044284729"
url = "https://pirateradio.social/notice/A5XnLBsFNQDKtthzM0"
reply_to_url = "https://framapiaf.org/users/peertube/statuses/105945857653893100"
data =
File.read!("test/fixtures/mastodon-status-3.json")

View File

@ -40,7 +40,7 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
File.read!("test/fixtures/mastodon-post-activity.json")
|> Jason.decode!()
reply_to_url = "https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94"
reply_to_url = "https://soc.punktrash.club/objects/d811df79-6e54-4f51-841e-0c38bc356467"
object =
data["object"]
@ -65,11 +65,11 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier.CommentsTest do
%Comment{} =
origin_comment =
Discussions.get_comment_from_url(
"https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94"
"https://soc.punktrash.club/objects/d811df79-6e54-4f51-841e-0c38bc356467"
)
assert returned_activity.data["object"]["inReplyTo"] ==
"https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94"
"https://soc.punktrash.club/objects/d811df79-6e54-4f51-841e-0c38bc356467"
assert returned_activity.data["object"]["inReplyTo"] == origin_comment.url
end

View File

@ -1,23 +1,24 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://zoltasila.pl/schemas/litepub-0.1.jsonld",
"https://pirateradio.social/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://zoltasila.pl/users/mkljczk",
"actor": "https://pirateradio.social/users/captain",
"attachment": [],
"attributedTo": "https://zoltasila.pl/users/mkljczk",
"cc": ["https://zoltasila.pl/users/mkljczk/followers"],
"content": "<p><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"9xUDK5nC4I2pNtyIsq\" href=\"https://framapiaf.org/@peertube\" rel=\"ugc\">@<span>peertube</span></a></span> guess you wanted to put the <a href=\"https://joinpeertube.org/en_US/news#release-2-3-0\">en_US lang link</a></p>",
"context": "tag:framapiaf.org,2020-07-27:objectId=39135637:objectType=Conversation",
"conversation": "tag:framapiaf.org,2020-07-27:objectId=39135637:objectType=Conversation",
"id": "https://zoltasila.pl/objects/1c295713-8e3c-411e-9e62-57a7b9c9e514",
"inReplyTo": "https://framapiaf.org/users/peertube/statuses/104584600044284729",
"published": "2020-07-27T09:37:57.202806Z",
"attributedTo": "https://pirateradio.social/users/captain",
"cc": ["https://pirateradio.social/users/captain/followers"],
"content": "<p><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"A56TgeKXmVurb7Znoe\" href=\"https://framapiaf.org/@peertube\" rel=\"ugc\">@<span>peertube</span></a></span> <a href=\"https://tv.pirateradio.social/about/instance\">Pirate Radio TV</a> is updated. You can now remote follow channels on PeerTube, awesome!</p>",
"context": "tag:framapiaf.org,2021-03-24:objectId=47491096:objectType=Conversation",
"conversation": "tag:framapiaf.org,2021-03-24:objectId=47491096:objectType=Conversation",
"id": "https://pirateradio.social/objects/eeaa8ced-27d6-49bb-a53b-fd2646b63f99",
"inReplyTo": "https://framapiaf.org/users/peertube/statuses/105945857653893100",
"published": "2021-03-24T19:01:37.759478Z",
"repliesCount": 1,
"sensitive": false,
"source": "@peertube@framapiaf.org guess you wanted to put the [en_US lang link](https://joinpeertube.org/en_US/news#release-2-3-0)",
"source": "@peertube@framapiaf.org [Pirate Radio TV](https://tv.pirateradio.social/about/instance) is updated. You can now remote follow channels on PeerTube, awesome!",
"summary": "",
"tag": [
{

View File

@ -16,40 +16,40 @@
}
}
],
"id": "https://framapiaf.org/users/peertube/statuses/104584600044284729",
"id": "https://framapiaf.org/users/peertube/statuses/105945857653893100",
"type": "Note",
"summary": null,
"inReplyTo": null,
"published": "2020-07-27T07:19:11Z",
"url": "https://framapiaf.org/@peertube/104584600044284729",
"published": "2021-03-24T17:04:54Z",
"url": "https://framapiaf.org/@peertube/105945857653893100",
"attributedTo": "https://framapiaf.org/users/peertube",
"to": ["https://www.w3.org/ns/activitystreams#Public"],
"cc": ["https://framapiaf.org/users/peertube/followers"],
"sensitive": false,
"atomUri": "https://framapiaf.org/users/peertube/statuses/104584600044284729",
"atomUri": "https://framapiaf.org/users/peertube/statuses/105945857653893100",
"inReplyToAtomUri": null,
"conversation": "tag:framapiaf.org,2020-07-27:objectId=39135637:objectType=Conversation",
"content": "<p>PeerTube 2.3 is out! Discover on <a href=\"https://joinpeertube.org/fr_FR/news#release-2-3-0\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">joinpeertube.org/fr_FR/news#re</span><span class=\"invisible\">lease-2-3-0</span></a> the list of new features! </p><p>Have you seen the broadcast message system ? 🤩</p>",
"conversation": "tag:framapiaf.org,2021-03-24:objectId=47491096:objectType=Conversation",
"content": "<p>PeerTube v3.1 is out! <br />Better transcoding features, more pleasant interfaces, possibility to easily subscribe to a remote account and... so many great features!</p><p>➡️ <a href=\"https://joinpeertube.org/en_US/news#release-3.1\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">joinpeertube.org/en_US/news#re</span><span class=\"invisible\">lease-3.1</span></a></p>",
"contentMap": {
"en": "<p>PeerTube 2.3 is out! Discover on <a href=\"https://joinpeertube.org/fr_FR/news#release-2-3-0\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">joinpeertube.org/fr_FR/news#re</span><span class=\"invisible\">lease-2-3-0</span></a> the list of new features! </p><p>Have you seen the broadcast message system ? 🤩</p>"
"en": "<p>PeerTube v3.1 is out! <br />Better transcoding features, more pleasant interfaces, possibility to easily subscribe to a remote account and... so many great features!</p><p>➡️ <a href=\"https://joinpeertube.org/en_US/news#release-3.1\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">joinpeertube.org/en_US/news#re</span><span class=\"invisible\">lease-3.1</span></a></p>"
},
"attachment": [
{
"type": "Document",
"mediaType": "image/png",
"url": "https://framapiaf.s3.framasoft.org/framapiaf/media_attachments/files/104/584/599/807/860/387/original/88c94143f78fdfa3.png",
"url": "https://framapiaf.s3.framasoft.org/framapiaf/media_attachments/files/105/945/857/331/391/923/original/7932c6912fe1e5ac.png",
"name": null,
"blurhash": "U5SY?Z00nOxu7ORP.8-pU^kVS#NGXyxbMxM{"
"blurhash": "UdMHJg00D%9F-pozjFoL?aWBe.of%Mofaeof"
}
],
"tag": [],
"replies": {
"id": "https://framapiaf.org/users/peertube/statuses/104584600044284729/replies",
"id": "https://framapiaf.org/users/peertube/statuses/105945857653893100/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://framapiaf.org/users/peertube/statuses/104584600044284729/replies?only_other_accounts=true&page=true",
"partOf": "https://framapiaf.org/users/peertube/statuses/104584600044284729/replies",
"next": "https://framapiaf.org/users/peertube/statuses/105945857653893100/replies?only_other_accounts=true&page=true",
"partOf": "https://framapiaf.org/users/peertube/statuses/105945857653893100/replies",
"items": []
}
}

View File

@ -1,28 +1,23 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://blob.cat/schemas/litepub-0.1.jsonld",
"https://soc.punktrash.club/schemas/litepub-0.1.jsonld",
{
"@language": "und"
}
],
"actor": "https://blob.cat/users/comicbot",
"attachment": [
{
"mediaType": "image/gif",
"name": "1574936800141.gif",
"type": "Document",
"url": "https://blob.cat/media/143ba9b1ed15e67d7401906f7b71a459b90680af7075af5b8ac9cb8e3b86868a.gif"
}
],
"attributedTo": "https://blob.cat/users/comicbot",
"cc": ["https://blob.cat/users/comicbot/followers"],
"content": "Super Mega Comics <br> <a href=\"http://supermegacomics.com/\" rel=\"ugc\">http://supermegacomics.com/</a>",
"context": "https://blob.cat/contexts/26f3271a-3eb8-4f3f-8fb1-8ff96e2c4a47",
"conversation": "https://blob.cat/contexts/26f3271a-3eb8-4f3f-8fb1-8ff96e2c4a47",
"id": "https://blob.cat/objects/02fdea3d-932c-4348-9ecb-3f9eb3fbdd94",
"published": "2019-11-28T10:26:42.503473Z",
"actor": "https://soc.punktrash.club/users/jorin",
"attachment": [],
"attributedTo": "https://soc.punktrash.club/users/jorin",
"cc": ["https://soc.punktrash.club/users/jorin/followers"],
"content": "I live in Spain<br><br>The S is silent<br><br>And it&#39;s French<br><br>🥖😎",
"context": "https://soc.punktrash.club/contexts/62eb8f27-c8ea-4cc3-818d-385ff96e4397",
"conversation": "https://soc.punktrash.club/contexts/62eb8f27-c8ea-4cc3-818d-385ff96e4397",
"id": "https://soc.punktrash.club/objects/d811df79-6e54-4f51-841e-0c38bc356467",
"published": "2021-05-06T03:52:10.195835Z",
"repliesCount": 1,
"sensitive": false,
"source": "I live in Spain\n\nThe S is silent\n\nAnd it's French\n\n🥖😎",
"summary": "",
"tag": [],
"to": ["https://www.w3.org/ns/activitystreams#Public"],

View File

@ -120,7 +120,7 @@ defmodule Mobilizon.Service.MetadataTest do
Metadata.Utils.process_description(post.body)
}\" property=\"og:description\"><meta content=\"article\" property=\"og:type\"><meta content=\"summary\" property=\"twitter:card\"><link href=\"#{
post.url
}\" rel=\"canonical\"><meta content=\"summary_large_image\" property=\"twitter:card\"><script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"Article\",\"author\":{\"@type\":\"Organization\",\"name\":\"#{
}\" rel=\"canonical\"><meta content=\"#{post.picture.file.url}\" property=\"og:image\"><meta content=\"summary_large_image\" property=\"twitter:card\"><script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"Article\",\"author\":{\"@type\":\"Organization\",\"name\":\"#{
post.attributed_to.preferred_username
}\"},\"dateModified\":\"#{DateTime.to_iso8601(post.updated_at)}\",\"datePublished\":\"#{
DateTime.to_iso8601(post.publish_at)