forked from potsda.mn/mobilizon
Compare commits
210 commits
Author | SHA1 | Date | |
---|---|---|---|
778a69cd | 473881136a | ||
778a69cd | 317d628792 | ||
778a69cd | 6df05308f6 | ||
b48ab8201f | |||
18c78b81cb | |||
778a69cd | 7a67cd5301 | ||
815bd8e2f9 | |||
563e7be0ed | |||
f789fcd2ee | |||
778a69cd | d1a2b4acb3 | ||
778a69cd | 435cbd0d6b | ||
778a69cd | 656bbd46c0 | ||
778a69cd | 375ff82076 | ||
778a69cd | 191d17b42e | ||
778a69cd | da8c7b281e | ||
df6ffee7cf | |||
778a69cd | 3c3206fd8a | ||
2078dbcf55 | |||
79bd6a5d21 | |||
0218dbe06e | |||
93562c6be9 | |||
4821bfc984 | |||
8f2a8b4349 | |||
9ff494f1b5 | |||
593f636933 | |||
380031d77a | |||
a91307116f | |||
aedc7a40c4 | |||
04f889be4d | |||
a3fa87a3ea | |||
545cb81797 | |||
320c40e511 | |||
46bfe5ff54 | |||
778a69cd | 8d6ee125ef | ||
be14c18d2e | |||
462ed5b3c7 | |||
e51dfd392c | |||
91f329f00a | |||
7050f11ed1 | |||
77a6773247 | |||
87dd2c09cd | |||
023f15938b | |||
778a69cd | 2f3ea848c4 | ||
6d7688e4f7 | |||
c6683595ff | |||
c36bd4c048 | |||
30d9778070 | |||
20f62729ee | |||
7a7edb1b6b | |||
e41ecd377f | |||
cde54249a9 | |||
3657636e3a | |||
d88bae8536 | |||
005ef28f8c | |||
778a69cd | 7c5e8cf31f | ||
b8b2e895b0 | |||
745b4a82d1 | |||
c237b276ca | |||
c0680f4bd6 | |||
66280a07e6 | |||
778a69cd | 1852d07ecf | ||
778a69cd | 3aaed0b2d7 | ||
1217f8a777 | |||
a70bad568b | |||
6bc2d7c970 | |||
74d56aa522 | |||
778a69cd | ac52522992 | ||
ed5fc7add6 | |||
7210869d36 | |||
5003822b09 | |||
15c0f93e37 | |||
28c045a77b | |||
442e5ae39d | |||
732f4db3b9 | |||
965f72a179 | |||
9977f3c555 | |||
5c202e31c1 | |||
ad9bb27343 | |||
ba5ac5cc94 | |||
dde1db73c3 | |||
b74358140c | |||
49e6d8afc7 | |||
d3fe6dece2 | |||
3b0d6b90ad | |||
0cbe7d3d17 | |||
29fb9f6934 | |||
dcd15f46fc | |||
7ee3c21352 | |||
703256809f | |||
7491b08df2 | |||
70036fefaa | |||
014dd0d62c | |||
d651acce1f | |||
f5ad8207c6 | |||
ca95a8cab3 | |||
54eafe2698 | |||
778a69cd | 9cf861850c | ||
04ee634594 | |||
0a2cc39c3c | |||
a0fc154268 | |||
ec616ec517 | |||
d5adda00a9 | |||
5998b49fae | |||
778a69cd | 83dce0c8ee | ||
778a69cd | e9d17efa37 | ||
778a69cd | ad05c9ea93 | ||
778a69cd | 579397a9b5 | ||
778a69cd | ca76b7bcf1 | ||
162d4f5fb1 | |||
7030d56864 | |||
778a69cd | 5f92e4bbb9 | ||
778a69cd | 18f791368b | ||
778a69cd | 6f373f5ea8 | ||
778a69cd | ec4b6abc4d | ||
778a69cd | fa813f6216 | ||
778a69cd | 989158ef4d | ||
778a69cd | 561677ce3a | ||
778a69cd | 0cec96ee41 | ||
778a69cd | 9894330bff | ||
778a69cd | a49ba0fdbd | ||
778a69cd | 941d3cc3e2 | ||
778a69cd | 864e2fa660 | ||
778a69cd | cb64baa0a4 | ||
778a69cd | 24f534fc57 | ||
778a69cd | 9672131ad0 | ||
a78dc261e5 | |||
778a69cd | de47f3da2e | ||
summersamara | f320e72991 | ||
778a69cd | 7f5b792a3e | ||
summersamara | 11fbe35725 | ||
778a69cd | a0a873d234 | ||
778a69cd | e31286040a | ||
ddbf5a258b | |||
6e23f7c55a | |||
ab0643ba3d | |||
778a69cd | 1fafd34fea | ||
5cc4e6d0b6 | |||
831a2deb87 | |||
077929318a | |||
f00d2babc0 | |||
f90865ffb4 | |||
3f73b2f856 | |||
98230a56bb | |||
baa11c18b0 | |||
9d99684402 | |||
778a69cd | b31491582f | ||
d1b1979ee5 | |||
06cdb1cb43 | |||
57b6bc604c | |||
c919b992e5 | |||
445ee92f28 | |||
f6435e621a | |||
778a69cd | 80e3095b4c | ||
778a69cd | eb40d76311 | ||
778a69cd | 7044f63788 | ||
778a69cd | 10d3d03da1 | ||
e3b36434cb | |||
5429afba21 | |||
4dc2f489e7 | |||
67314928e0 | |||
28430d6d57 | |||
ab3f5dfd27 | |||
1f4a7c253b | |||
cba2075431 | |||
6a482b0d97 | |||
34c0dd6498 | |||
f6bcb02b98 | |||
b1ecf4b36f | |||
1acf931ac5 | |||
04edc4fef0 | |||
8e9f7a81b4 | |||
8a2e262474 | |||
77308a9477 | |||
a6a1ab71c2 | |||
3b7124a57b | |||
ba66874cc3 | |||
ef20585f8c | |||
9207d76712 | |||
0bd00de501 | |||
aa388a7a47 | |||
43c6143ddf | |||
95379885c8 | |||
681f8dcd04 | |||
5bc0593ed6 | |||
10c4038b85 | |||
c9a1c35aa7 | |||
dcbb8eae01 | |||
6a4123f385 | |||
01eecbf1d4 | |||
387d3b1c30 | |||
456dc36f64 | |||
c12df03b5d | |||
5de22f91e2 | |||
1441d35e0b | |||
594ad440da | |||
790db906a6 | |||
48f57ec1cf | |||
2b5439b1d0 | |||
5cb4fc11c4 | |||
410446c843 | |||
0d7462de06 | |||
fae480c24e | |||
50b1ee11a0 | |||
778a69cd | ebe3e62a1e | ||
778a69cd | a12de7a0c1 | ||
54aa628403 | |||
d25577ea5d | |||
e854500693 | |||
137a8ed69c | |||
9670b77bc3 |
10
.credo.exs
10
.credo.exs
|
@ -108,9 +108,10 @@
|
|||
{Credo.Check.Refactor.MatchInCondition, []},
|
||||
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
|
||||
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
|
||||
{Credo.Check.Refactor.Nesting, [
|
||||
max_nesting: 3
|
||||
]},
|
||||
{Credo.Check.Refactor.Nesting,
|
||||
[
|
||||
max_nesting: 3
|
||||
]},
|
||||
{Credo.Check.Refactor.PipeChainStart,
|
||||
[
|
||||
excluded_argument_types: [:atom, :binary, :fn, :keyword, :number],
|
||||
|
@ -159,8 +160,7 @@
|
|||
# Removed checks
|
||||
#
|
||||
{Credo.Check.Warning.LazyLogging, false},
|
||||
{Credo.Check.Refactor.MapInto, false},
|
||||
{Credo.Check.Warning.MissedMetadataKeyInLoggerConfig, false}
|
||||
{Credo.Check.Refactor.MapInto, false}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -306,7 +306,7 @@ docker-latest:
|
|||
|
||||
# Packaging app for amd64
|
||||
package-app:
|
||||
image: mobilizon/buildpack:1.15.7-erlang-26.1.2-${SYSTEM}
|
||||
image: mobilizon/buildpack:1.16.1-erlang-26.2.2-${SYSTEM}
|
||||
stage: build
|
||||
variables: &release-variables
|
||||
MIX_ENV: "prod"
|
||||
|
@ -340,7 +340,6 @@ package-app:
|
|||
"debian-buster",
|
||||
"ubuntu-jammy",
|
||||
"ubuntu-focal",
|
||||
"ubuntu-bionic",
|
||||
"fedora-38",
|
||||
"fedora-39",
|
||||
]
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
npm run pre-commit
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
|
||||
155A1FB53DE39EC8EFCFD7FB94EA823D
|
||||
1C29EE70E90ECED01AF28EC58D2575B5
|
||||
26ED12A8E03D044BEDC08749BAA5E357
|
||||
2BB1D36656B423758A470021718FCB09
|
||||
31CE26BC979C57B9E3CC97B40C290CE5
|
||||
3529E7A4CECC24D02678820E6F521162
|
||||
3644C4E850300482AA409471EFE1EFB3
|
||||
4E7C044C59E0BCB76AA826789998F624
|
||||
53CBBEB6243FAF5C37249CBA17DE6F4C
|
||||
5BCE3651A03711295046DE48BDFE007E
|
||||
5C4CED447689F00D9D1ACEB9B895ED29
|
||||
5D8350E7A2DE5BB1CBCC983AF121F0DA
|
||||
94ACF7B17C3FF42F64E57DD1DA936BD8
|
||||
A32E125003F1EDFAD95C487C6A969725
|
||||
ACF6272A1DBB3A2ABD96C0C120B5CA69
|
||||
C46C4893B2F702ACADC4CAA5683FE370
|
||||
CDF2CCE0CF10F49CDFAE22FE26208155
|
||||
CD4CD6571816FCAF1E305066CDA0CD2F
|
||||
E720CB13C50FF3ADEE7C522531E11217
|
||||
F3D5851D3FB050939841ED2F14307A27
|
||||
FD1C9756370A195B74E95CE504C45E9E
|
|
@ -1,2 +1,3 @@
|
|||
elixir 1.15.5-otp-26
|
||||
erlang 26.0.2
|
||||
erlang 26.2.2
|
||||
elixir 1.16.1-otp-26
|
||||
nodejs 18.19.1
|
||||
|
|
178
CHANGELOG.md
178
CHANGELOG.md
|
@ -5,6 +5,184 @@ 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).
|
||||
|
||||
## 4.1.0 (2024-02-29)
|
||||
|
||||
This release is the last provided by Framasoft. [The project is now supported by the Kaihuri association](https://framacolibri.org/t/mobilizon-nous/19752).
|
||||
|
||||
The highlights for this release are the following:
|
||||
- improved event federation with https://event-federation.eu and https://gancio.org, as well as adding event metadata in summary for micro-blogging platforms that make use of it like Mastodon
|
||||
- allowing to filter events by local-only, so that you can find only the events created on this instance
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **activitpub:** add summary of metadata to events ([1441d35](https://framagit.org/framasoft/mobilizon/commits/1441d35e0b0c3a151b8626711b3acaf30d3dcf58))
|
||||
* **activitypub:** allow simple text for address field ([64237cf](https://framagit.org/framasoft/mobilizon/commits/64237cfc2633794a48022a059c79155b1ece14d1)), closes [#1387](https://framagit.org/framasoft/mobilizon/issues/1387)
|
||||
* **activitypub:** implement FEP-2677 to identify the application actor used for federation ([f10977a](https://framagit.org/framasoft/mobilizon/commits/f10977a99ac73ce5a702a12ed31e773a4b0f6961)), closes [#1367](https://framagit.org/framasoft/mobilizon/issues/1367)
|
||||
* allow to filter events by local-only ([9d99684](https://framagit.org/framasoft/mobilizon/commits/9d996844025f9d128305a54f8f169fb4b1ffac44)), closes [#1322](https://framagit.org/framasoft/mobilizon/issues/1322)
|
||||
* **config:** enable instance feeds by default ([ab3f5df](https://framagit.org/framasoft/mobilizon/commits/ab3f5dfd278dc55dd0f28bb11cf4a976d212e9fc))
|
||||
* **docker:** add new environment variables for Docker config ([28430d6](https://framagit.org/framasoft/mobilizon/commits/28430d6d57a85b568c839e75ba1bcbff90e4149e))
|
||||
* **front:** upgrade to Oruga 0.8.x ([a9676d6](https://framagit.org/framasoft/mobilizon/commits/a9676d6481e6966d939ea4e44ad610eb9231c370))
|
||||
* **graphql:** increase max_complexity to 300 ([dcbb8ea](https://framagit.org/framasoft/mobilizon/commits/dcbb8eae01012e6e3aa2c83e06cc50f61176b8ef))
|
||||
* **http:** allow to provide self-signed certificates ([baa11c1](https://framagit.org/framasoft/mobilizon/commits/baa11c18b03684e508e56793a800878e95644962)), closes [#1355](https://framagit.org/framasoft/mobilizon/issues/1355)
|
||||
* **nodeinfo:** extract and save NodeInfo information from instances to display it on instances list ([99b2339](https://framagit.org/framasoft/mobilizon/commits/99b2339424edb5b0c514581fbd6a42e4f0fcc5e1)), closes [#1392](https://framagit.org/framasoft/mobilizon/issues/1392)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **activitypub:** also handle as:Public and Public values for public addressing ([4dc2f48](https://framagit.org/framasoft/mobilizon/commits/4dc2f489e79d4f7d64ba3d5c2588d5d6ec0bc99c)), closes [#1413](https://framagit.org/framasoft/mobilizon/issues/1413)
|
||||
* **activitypub:** consider PM as private conversations even if attributed_to_id is defined ([387d3b1](https://framagit.org/framasoft/mobilizon/commits/387d3b1c30ec719a992c565fd495ef2b6642641e))
|
||||
* **activitypub:** do not try to calculate timezone from missing geo-coordinates ([001a0ed](https://framagit.org/framasoft/mobilizon/commits/001a0ed1a50894ad1abe0f7fc9dc5b9666de5dae))
|
||||
* **activitypub:** handle actors following with manually_approves_followers not set ([7351468](https://framagit.org/framasoft/mobilizon/commits/73514688423b92b9f62b52fd54f2e523abeb3e34))
|
||||
* **activitypub:** handle any type of error when fetching Application actor from NodeInfo ([9308c53](https://framagit.org/framasoft/mobilizon/commits/9308c5399dc2e7afd8844d083de2ea291a3c5a66))
|
||||
* **activitypub:** handle issue with AP Fetcher not catching some changeset errors ([e3b3643](https://framagit.org/framasoft/mobilizon/commits/e3b36434cb05feb2e6add2b6b229e83b9dccf825)), closes [#1409](https://framagit.org/framasoft/mobilizon/issues/1409)
|
||||
* **activitypub:** make relay outbox events ordered by desc publication date ([e73fd9b](https://framagit.org/framasoft/mobilizon/commits/e73fd9b370b9679a0ab424a0bd44f262a21a4697))
|
||||
* **activitypub:** refresh NodeInfo metadata straight away when adding a new instance to follow ([2f4b8fe](https://framagit.org/framasoft/mobilizon/commits/2f4b8feeba9e7e1c4d1fc967505b3ed80e314b3c))
|
||||
* allow html_to_text to receive nil, e.g. for empty event descriptions ([5030b75](https://framagit.org/framasoft/mobilizon/commits/5030b755a0880a022d0656598b591cb47ebd7dc5))
|
||||
* **announcements:** error message not showing when an event announcement is created with empty text ([ef20585](https://framagit.org/framasoft/mobilizon/commits/ef20585f8cc1e4ac2f2f3359a70b7f456d2adeeb))
|
||||
* **announcements:** make sure only valid announcements are shown to the user ([c9a1c35](https://framagit.org/framasoft/mobilizon/commits/c9a1c35aa7a1d399b524dc5cc1fbebb38681ee24))
|
||||
* **backend:** avoid duplicating locality and region if they are the same ([5de22f9](https://framagit.org/framasoft/mobilizon/commits/5de22f91e22109da9e2169928dc744acd94b7299))
|
||||
* **backend:** fix sending N notifications to a single conversation participant ([9537988](https://framagit.org/framasoft/mobilizon/commits/95379885c8fb3decd19fa434774023a7b05ef0b5)), closes [#1384](https://framagit.org/framasoft/mobilizon/issues/1384)
|
||||
* **backend:** hide non-public replies to comments in event comment threads ([10c4038](https://framagit.org/framasoft/mobilizon/commits/10c4038b856b7e5c4981dcdce0bb9a885afb3cea))
|
||||
* **backend:** only send announcement event emails when the comment author has the right to do so ([0bd00de](https://framagit.org/framasoft/mobilizon/commits/0bd00de501b36c5f2320c2530019f302bf084517))
|
||||
* **backend:** validate length of instance actor details and set description column to text ([f7585cf](https://framagit.org/framasoft/mobilizon/commits/f7585cfc759576475133bcc86d2e816b2553626d)), closes [#1393](https://framagit.org/framasoft/mobilizon/issues/1393)
|
||||
* **back:** fix instances filtering ([b3ba45e](https://framagit.org/framasoft/mobilizon/commits/b3ba45e8a73038dc70286afbb479c1db51b6fbcd))
|
||||
* **back:** sitemapper fix after upgrade ([1acf931](https://framagit.org/framasoft/mobilizon/commits/1acf931ac558ac0818213264a6177a1f647393f1))
|
||||
* **docker:** add --break-system-packages to pip install to add weasyprint and pyexcel-ods3 ([889cb91](https://framagit.org/framasoft/mobilizon/commits/889cb91f2649861a87eb7e959065cfb49b30f366))
|
||||
* **docker:** remove openssl1.1-compat ([75d7816](https://framagit.org/framasoft/mobilizon/commits/75d7816a6cd1fe6754a66c1bb81153068b9c13e3)), closes [#1390](https://framagit.org/framasoft/mobilizon/issues/1390)
|
||||
* **event announcements:** only show comments from event organizers in event announcement list ([01eecbf](https://framagit.org/framasoft/mobilizon/commits/01eecbf1d46614241c92e1a38e30057a84c55744))
|
||||
* **feeds:** increase feed item limit from 500 to 5000 ([ff0440c](https://framagit.org/framasoft/mobilizon/commits/ff0440c634ac17813607f5929cd4024d87601c3b))
|
||||
* **feeds:** make sure posts for feeds are ordered by publication date desc ([3c75856](https://framagit.org/framasoft/mobilizon/commits/3c7585614971849035011ede6c0d5d2d5621df81))
|
||||
* **front-end:** fix current actor not being set on first access when relogging ([ae466b8](https://framagit.org/framasoft/mobilizon/commits/ae466b879cd09a9d04ffab0469ee991c7d90ce8e))
|
||||
* **front-end:** fix issues with expired accessToken refreshment queue ([d4489f6](https://framagit.org/framasoft/mobilizon/commits/d4489f691b312891013767f7e39d92a9b0863387))
|
||||
* **front:** add a required attribute to the text editor and show error message if text empty on blur ([ba66874](https://framagit.org/framasoft/mobilizon/commits/ba66874cc3e5979c2a9a6f86ea55463eca911472))
|
||||
* **front:** add announcements link on EventParticipationCard as well as EventView ([83eb5c6](https://framagit.org/framasoft/mobilizon/commits/83eb5c6a69ac312c19dc3cef10f26ab686cb4be7))
|
||||
* **front:** add condition on DraggableList in ResourceFolder.vue ([a408b47](https://framagit.org/framasoft/mobilizon/commits/a408b476cf2151298c7cf4eb6b3268334be13599))
|
||||
* **front:** correctly show error message when a tag is too short ([cba2075](https://framagit.org/framasoft/mobilizon/commits/cba2075431d1de4bf621e1d2b2a2e5f0641997c6)), closes [#1382](https://framagit.org/framasoft/mobilizon/issues/1382)
|
||||
* **front:** create head without old options ([45f8757](https://framagit.org/framasoft/mobilizon/commits/45f8757d72d1a2c72d069ced6fcbe21571d334c5))
|
||||
* **frontend:** various fixes ([456dc36](https://framagit.org/framasoft/mobilizon/commits/456dc36f64b3eb7c43d8ff69aa458b89b5a5b4ab))
|
||||
* **front:** escape event.title when it's passed to dialog component HTML message ([f4ee116](https://framagit.org/framasoft/mobilizon/commits/f4ee11611294c2cc957453768f768de0a51b05a7))
|
||||
* **front:** fix debouncing instances filtering ([fe0cf93](https://framagit.org/framasoft/mobilizon/commits/fe0cf9360428185d261dad4065a7bea1dd8d8d59))
|
||||
* **front:** fix dialog from EventParticipationCard.vue without input ([89641c5](https://framagit.org/framasoft/mobilizon/commits/89641c502ef5771f93cfa55caea6b52c63e73b4b))
|
||||
* **front:** fix ErrorComponent.vue sentry integration ([00d8bc7](https://framagit.org/framasoft/mobilizon/commits/00d8bc733d52a810c438e1081496e3b0ac58958f))
|
||||
* **front:** fix focus when creating a new resource ([76668e0](https://framagit.org/framasoft/mobilizon/commits/76668e0bebd2bd235925494f90fac6400e74d179))
|
||||
* **front:** fix focusing text editor ([3b7124a](https://framagit.org/framasoft/mobilizon/commits/3b7124a57b2dedf5583fdebced6b9a4e502e8731))
|
||||
* **front:** fix reporting group ([57d0372](https://framagit.org/framasoft/mobilizon/commits/57d0372ce8b29952caff8bbf7c902c7862a77b49))
|
||||
* **front:** fix TagInput display ([790db90](https://framagit.org/framasoft/mobilizon/commits/790db906a6e814352aa694c26febb9d6a43fa321))
|
||||
* **front:** fix TagInput width properly ([6a4123f](https://framagit.org/framasoft/mobilizon/commits/6a4123f385fb2e20aab1c1cbc666c5d1a3f93589))
|
||||
* **front:** husky fixes after upgrade ([04edc4f](https://framagit.org/framasoft/mobilizon/commits/04edc4fef08306c55067abd0e22443c4cb43d7c8))
|
||||
* **front:** improve display of SendPasswordReset view ([1d39eb5](https://framagit.org/framasoft/mobilizon/commits/1d39eb548898b3c4840b4a36950a62b4ce46ba90))
|
||||
* **front:** only update identity username from name if it's a new identity ([34c0dd6](https://framagit.org/framasoft/mobilizon/commits/34c0dd6498247cf6a90576a602c4e305c80c9692))
|
||||
* **front:** patch vue-i18n-extract because of mjs incompatibility ([1f4a7c2](https://framagit.org/framasoft/mobilizon/commits/1f4a7c253bfe40809b432f3a36faa6b5fb340ae9))
|
||||
* **front:** remove broken identity check in EventMinimalistCard ([ee63814](https://framagit.org/framasoft/mobilizon/commits/ee6381463d9f8e6d130e29b410cf5e2700f3c10b))
|
||||
* **front:** reset instances list to page 1 if filter or follow status changes ([2b5439b](https://framagit.org/framasoft/mobilizon/commits/2b5439b1d0ef1f60c19019540a01eb6d437eee23))
|
||||
* **front:** reset page to lower or page 1 if we didn't found results in instances view ([48f57ec](https://framagit.org/framasoft/mobilizon/commits/48f57ec1cf3ce81c3c83333bea59c2a7d8c70e99))
|
||||
* **front:** rollback to vue 3.3 for now ([5cb4fc1](https://framagit.org/framasoft/mobilizon/commits/5cb4fc11c4ccc381a041cb2615913a8fb77e1b85))
|
||||
* **front:** show correct label when adding a new calc or videoconference resource in resources ([cecbea6](https://framagit.org/framasoft/mobilizon/commits/cecbea6db52d360e046d69cf0762eb1208c45f19))
|
||||
* **front:** tagInput fixes ([f6bcb02](https://framagit.org/framasoft/mobilizon/commits/f6bcb02b9802e04bd8e9c80092a0680b64482688))
|
||||
* **front:** uI fixes ([0948cce](https://framagit.org/framasoft/mobilizon/commits/0948cce83e5af128f78b67891ed24c323b159f0f))
|
||||
* **front:** use functions to generate classnames dynamically ([98230a5](https://framagit.org/framasoft/mobilizon/commits/98230a56bb5e1c75f070e4d4c352028741869066))
|
||||
* **front:** various cleanups ([6a482b0](https://framagit.org/framasoft/mobilizon/commits/6a482b0d9754fc85f1f61922e92852fbca52beb9))
|
||||
* **front:** various little CSS fixes ([51d43aa](https://framagit.org/framasoft/mobilizon/commits/51d43aa2d1d1f099078895d67a45fc27b74d4604))
|
||||
* **front:** various UI improvements ([a6a1ab7](https://framagit.org/framasoft/mobilizon/commits/a6a1ab71c23264805d61b5312982e6d345454027))
|
||||
* **front:** vite fixes after upgrade (everything is esm) ([b1ecf4b](https://framagit.org/framasoft/mobilizon/commits/b1ecf4b36f5855c895f72c4d9dc0f7e1beb449e1))
|
||||
* **graphql:** add missing operation name for RegisterPerson ([a47f4f6](https://framagit.org/framasoft/mobilizon/commits/a47f4f6444d12a13a6f7e79ed6746e74088ca294))
|
||||
* **graphql:** fix checking actor identity when publishing event announcements ([5bc0593](https://framagit.org/framasoft/mobilizon/commits/5bc0593ed6e772d48722c308ccb444dc49f3c079))
|
||||
* **nodeinfo:** fix getting application actor information from NodeInfo response ([dd775b6](https://framagit.org/framasoft/mobilizon/commits/dd775b6ae25f381cf76e00999fd7d37764870122))
|
||||
* **nodeinfo:** make sure we only process JSON content ([da3b074](https://framagit.org/framasoft/mobilizon/commits/da3b0746198544d7977d9c0b32d8a26e1da64d40))
|
||||
* **front:** fix adding tags to an event ([d75d464](https://framagit.org/framasoft/mobilizon/commits/d75d464135332f639bd275684109a89980718b75)), closes [#1419](https://framagit.org/framasoft/mobilizon/issues/1419)
|
||||
* **front:** fix space around input icons ([ba9299c](https://framagit.org/framasoft/mobilizon/commits/ba9299c6321cd62bb84efb6db5b6e122e4b1b264))
|
||||
* **backend:** set Gettext default locale to "en" ([d390a91](https://framagit.org/framasoft/mobilizon/commits/d390a915d80ce5d2447f5323b78c71e9e1aa58dc))
|
||||
* **front:** fix discussion comment changed subscription done before having slug value ([0670297](https://framagit.org/framasoft/mobilizon/commits/067029705dd3c78b54ea4765357ba58930144aab))
|
||||
* **front:** fix typing for canReport prop on DiscussionComment ([c2055d9](https://framagit.org/framasoft/mobilizon/commits/c2055d92ae7707b5aab3fd14ea827df0696cca61))
|
||||
* **front:** remove extra classes on comment that are not needed ([a9b9775](https://framagit.org/framasoft/mobilizon/commits/a9b977540b900416cfe0d5739cba13e506f83120))
|
||||
|
||||
## 4.1.0-beta.1 (2024-02-27)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **front:** fix adding tags to an event ([d75d464](https://framagit.org/framasoft/mobilizon/commits/d75d464135332f639bd275684109a89980718b75)), closes [#1419](https://framagit.org/framasoft/mobilizon/issues/1419)
|
||||
* **front:** fix space around input icons ([ba9299c](https://framagit.org/framasoft/mobilizon/commits/ba9299c6321cd62bb84efb6db5b6e122e4b1b264))
|
||||
|
||||
|
||||
## 4.1.0-alpha.1 (2024-02-09)
|
||||
|
||||
### Features
|
||||
|
||||
* **activitpub:** add summary of metadata to events ([1441d35](https://framagit.org/framasoft/mobilizon/commits/1441d35e0b0c3a151b8626711b3acaf30d3dcf58))
|
||||
* **activitypub:** allow simple text for address field ([64237cf](https://framagit.org/framasoft/mobilizon/commits/64237cfc2633794a48022a059c79155b1ece14d1)), closes [#1387](https://framagit.org/framasoft/mobilizon/issues/1387)
|
||||
* **activitypub:** implement FEP-2677 to identify the application actor used for federation ([f10977a](https://framagit.org/framasoft/mobilizon/commits/f10977a99ac73ce5a702a12ed31e773a4b0f6961)), closes [#1367](https://framagit.org/framasoft/mobilizon/issues/1367)
|
||||
* allow to filter events by local-only ([9d99684](https://framagit.org/framasoft/mobilizon/commits/9d996844025f9d128305a54f8f169fb4b1ffac44)), closes [#1322](https://framagit.org/framasoft/mobilizon/issues/1322)
|
||||
* **config:** enable instance feeds by default ([ab3f5df](https://framagit.org/framasoft/mobilizon/commits/ab3f5dfd278dc55dd0f28bb11cf4a976d212e9fc))
|
||||
* **docker:** add new environment variables for Docker config ([28430d6](https://framagit.org/framasoft/mobilizon/commits/28430d6d57a85b568c839e75ba1bcbff90e4149e))
|
||||
* **front:** upgrade to Oruga 0.8.x ([a9676d6](https://framagit.org/framasoft/mobilizon/commits/a9676d6481e6966d939ea4e44ad610eb9231c370))
|
||||
* **graphql:** increase max_complexity to 300 ([dcbb8ea](https://framagit.org/framasoft/mobilizon/commits/dcbb8eae01012e6e3aa2c83e06cc50f61176b8ef))
|
||||
* **http:** allow to provide self-signed certificates ([baa11c1](https://framagit.org/framasoft/mobilizon/commits/baa11c18b03684e508e56793a800878e95644962)), closes [#1355](https://framagit.org/framasoft/mobilizon/issues/1355)
|
||||
* **nodeinfo:** extract and save NodeInfo information from instances to display it on instances list ([99b2339](https://framagit.org/framasoft/mobilizon/commits/99b2339424edb5b0c514581fbd6a42e4f0fcc5e1)), closes [#1392](https://framagit.org/framasoft/mobilizon/issues/1392)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **activitypub:** also handle as:Public and Public values for public addressing ([4dc2f48](https://framagit.org/framasoft/mobilizon/commits/4dc2f489e79d4f7d64ba3d5c2588d5d6ec0bc99c)), closes [#1413](https://framagit.org/framasoft/mobilizon/issues/1413)
|
||||
* **activitypub:** consider PM as private conversations even if attributed_to_id is defined ([387d3b1](https://framagit.org/framasoft/mobilizon/commits/387d3b1c30ec719a992c565fd495ef2b6642641e))
|
||||
* **activitypub:** do not try to calculate timezone from missing geo-coordinates ([001a0ed](https://framagit.org/framasoft/mobilizon/commits/001a0ed1a50894ad1abe0f7fc9dc5b9666de5dae))
|
||||
* **activitypub:** handle actors following with manually_approves_followers not set ([7351468](https://framagit.org/framasoft/mobilizon/commits/73514688423b92b9f62b52fd54f2e523abeb3e34))
|
||||
* **activitypub:** handle any type of error when fetching Application actor from NodeInfo ([9308c53](https://framagit.org/framasoft/mobilizon/commits/9308c5399dc2e7afd8844d083de2ea291a3c5a66))
|
||||
* **activitypub:** handle issue with AP Fetcher not catching some changeset errors ([e3b3643](https://framagit.org/framasoft/mobilizon/commits/e3b36434cb05feb2e6add2b6b229e83b9dccf825)), closes [#1409](https://framagit.org/framasoft/mobilizon/issues/1409)
|
||||
* **activitypub:** make relay outbox events ordered by desc publication date ([e73fd9b](https://framagit.org/framasoft/mobilizon/commits/e73fd9b370b9679a0ab424a0bd44f262a21a4697))
|
||||
* **activitypub:** refresh NodeInfo metadata straight away when adding a new instance to follow ([2f4b8fe](https://framagit.org/framasoft/mobilizon/commits/2f4b8feeba9e7e1c4d1fc967505b3ed80e314b3c))
|
||||
* allow html_to_text to receive nil, e.g. for empty event descriptions ([5030b75](https://framagit.org/framasoft/mobilizon/commits/5030b755a0880a022d0656598b591cb47ebd7dc5))
|
||||
* **announcements:** error message not showing when an event announcement is created with empty text ([ef20585](https://framagit.org/framasoft/mobilizon/commits/ef20585f8cc1e4ac2f2f3359a70b7f456d2adeeb))
|
||||
* **announcements:** make sure only valid announcements are shown to the user ([c9a1c35](https://framagit.org/framasoft/mobilizon/commits/c9a1c35aa7a1d399b524dc5cc1fbebb38681ee24))
|
||||
* **backend:** avoid duplicating locality and region if they are the same ([5de22f9](https://framagit.org/framasoft/mobilizon/commits/5de22f91e22109da9e2169928dc744acd94b7299))
|
||||
* **backend:** fix sending N notifications to a single conversation participant ([9537988](https://framagit.org/framasoft/mobilizon/commits/95379885c8fb3decd19fa434774023a7b05ef0b5)), closes [#1384](https://framagit.org/framasoft/mobilizon/issues/1384)
|
||||
* **backend:** hide non-public replies to comments in event comment threads ([10c4038](https://framagit.org/framasoft/mobilizon/commits/10c4038b856b7e5c4981dcdce0bb9a885afb3cea))
|
||||
* **backend:** only send announcement event emails when the comment author has the right to do so ([0bd00de](https://framagit.org/framasoft/mobilizon/commits/0bd00de501b36c5f2320c2530019f302bf084517))
|
||||
* **backend:** validate length of instance actor details and set description column to text ([f7585cf](https://framagit.org/framasoft/mobilizon/commits/f7585cfc759576475133bcc86d2e816b2553626d)), closes [#1393](https://framagit.org/framasoft/mobilizon/issues/1393)
|
||||
* **back:** fix instances filtering ([b3ba45e](https://framagit.org/framasoft/mobilizon/commits/b3ba45e8a73038dc70286afbb479c1db51b6fbcd))
|
||||
* **back:** sitemapper fix after upgrade ([1acf931](https://framagit.org/framasoft/mobilizon/commits/1acf931ac558ac0818213264a6177a1f647393f1))
|
||||
* **docker:** add --break-system-packages to pip install to add weasyprint and pyexcel-ods3 ([889cb91](https://framagit.org/framasoft/mobilizon/commits/889cb91f2649861a87eb7e959065cfb49b30f366))
|
||||
* **docker:** remove openssl1.1-compat ([75d7816](https://framagit.org/framasoft/mobilizon/commits/75d7816a6cd1fe6754a66c1bb81153068b9c13e3)), closes [#1390](https://framagit.org/framasoft/mobilizon/issues/1390)
|
||||
* **event announcements:** only show comments from event organizers in event announcement list ([01eecbf](https://framagit.org/framasoft/mobilizon/commits/01eecbf1d46614241c92e1a38e30057a84c55744))
|
||||
* **feeds:** increase feed item limit from 500 to 5000 ([ff0440c](https://framagit.org/framasoft/mobilizon/commits/ff0440c634ac17813607f5929cd4024d87601c3b))
|
||||
* **feeds:** make sure posts for feeds are ordered by publication date desc ([3c75856](https://framagit.org/framasoft/mobilizon/commits/3c7585614971849035011ede6c0d5d2d5621df81))
|
||||
* **front-end:** fix current actor not being set on first access when relogging ([ae466b8](https://framagit.org/framasoft/mobilizon/commits/ae466b879cd09a9d04ffab0469ee991c7d90ce8e))
|
||||
* **front-end:** fix issues with expired accessToken refreshment queue ([d4489f6](https://framagit.org/framasoft/mobilizon/commits/d4489f691b312891013767f7e39d92a9b0863387))
|
||||
* **front:** add a required attribute to the text editor and show error message if text empty on blur ([ba66874](https://framagit.org/framasoft/mobilizon/commits/ba66874cc3e5979c2a9a6f86ea55463eca911472))
|
||||
* **front:** add announcements link on EventParticipationCard as well as EventView ([83eb5c6](https://framagit.org/framasoft/mobilizon/commits/83eb5c6a69ac312c19dc3cef10f26ab686cb4be7))
|
||||
* **front:** add condition on DraggableList in ResourceFolder.vue ([a408b47](https://framagit.org/framasoft/mobilizon/commits/a408b476cf2151298c7cf4eb6b3268334be13599))
|
||||
* **front:** correctly show error message when a tag is too short ([cba2075](https://framagit.org/framasoft/mobilizon/commits/cba2075431d1de4bf621e1d2b2a2e5f0641997c6)), closes [#1382](https://framagit.org/framasoft/mobilizon/issues/1382)
|
||||
* **front:** create head without old options ([45f8757](https://framagit.org/framasoft/mobilizon/commits/45f8757d72d1a2c72d069ced6fcbe21571d334c5))
|
||||
* **frontend:** various fixes ([456dc36](https://framagit.org/framasoft/mobilizon/commits/456dc36f64b3eb7c43d8ff69aa458b89b5a5b4ab))
|
||||
* **front:** escape event.title when it's passed to dialog component HTML message ([f4ee116](https://framagit.org/framasoft/mobilizon/commits/f4ee11611294c2cc957453768f768de0a51b05a7))
|
||||
* **front:** fix debouncing instances filtering ([fe0cf93](https://framagit.org/framasoft/mobilizon/commits/fe0cf9360428185d261dad4065a7bea1dd8d8d59))
|
||||
* **front:** fix dialog from EventParticipationCard.vue without input ([89641c5](https://framagit.org/framasoft/mobilizon/commits/89641c502ef5771f93cfa55caea6b52c63e73b4b))
|
||||
* **front:** fix ErrorComponent.vue sentry integration ([00d8bc7](https://framagit.org/framasoft/mobilizon/commits/00d8bc733d52a810c438e1081496e3b0ac58958f))
|
||||
* **front:** fix focus when creating a new resource ([76668e0](https://framagit.org/framasoft/mobilizon/commits/76668e0bebd2bd235925494f90fac6400e74d179))
|
||||
* **front:** fix focusing text editor ([3b7124a](https://framagit.org/framasoft/mobilizon/commits/3b7124a57b2dedf5583fdebced6b9a4e502e8731))
|
||||
* **front:** fix reporting group ([57d0372](https://framagit.org/framasoft/mobilizon/commits/57d0372ce8b29952caff8bbf7c902c7862a77b49))
|
||||
* **front:** fix TagInput display ([790db90](https://framagit.org/framasoft/mobilizon/commits/790db906a6e814352aa694c26febb9d6a43fa321))
|
||||
* **front:** fix TagInput width properly ([6a4123f](https://framagit.org/framasoft/mobilizon/commits/6a4123f385fb2e20aab1c1cbc666c5d1a3f93589))
|
||||
* **front:** husky fixes after upgrade ([04edc4f](https://framagit.org/framasoft/mobilizon/commits/04edc4fef08306c55067abd0e22443c4cb43d7c8))
|
||||
* **front:** improve display of SendPasswordReset view ([1d39eb5](https://framagit.org/framasoft/mobilizon/commits/1d39eb548898b3c4840b4a36950a62b4ce46ba90))
|
||||
* **front:** only update identity username from name if it's a new identity ([34c0dd6](https://framagit.org/framasoft/mobilizon/commits/34c0dd6498247cf6a90576a602c4e305c80c9692))
|
||||
* **front:** patch vue-i18n-extract because of mjs incompatibility ([1f4a7c2](https://framagit.org/framasoft/mobilizon/commits/1f4a7c253bfe40809b432f3a36faa6b5fb340ae9))
|
||||
* **front:** remove broken identity check in EventMinimalistCard ([ee63814](https://framagit.org/framasoft/mobilizon/commits/ee6381463d9f8e6d130e29b410cf5e2700f3c10b))
|
||||
* **front:** reset instances list to page 1 if filter or follow status changes ([2b5439b](https://framagit.org/framasoft/mobilizon/commits/2b5439b1d0ef1f60c19019540a01eb6d437eee23))
|
||||
* **front:** reset page to lower or page 1 if we didn't found results in instances view ([48f57ec](https://framagit.org/framasoft/mobilizon/commits/48f57ec1cf3ce81c3c83333bea59c2a7d8c70e99))
|
||||
* **front:** rollback to vue 3.3 for now ([5cb4fc1](https://framagit.org/framasoft/mobilizon/commits/5cb4fc11c4ccc381a041cb2615913a8fb77e1b85))
|
||||
* **front:** show correct label when adding a new calc or videoconference resource in resources ([cecbea6](https://framagit.org/framasoft/mobilizon/commits/cecbea6db52d360e046d69cf0762eb1208c45f19))
|
||||
* **front:** tagInput fixes ([f6bcb02](https://framagit.org/framasoft/mobilizon/commits/f6bcb02b9802e04bd8e9c80092a0680b64482688))
|
||||
* **front:** uI fixes ([0948cce](https://framagit.org/framasoft/mobilizon/commits/0948cce83e5af128f78b67891ed24c323b159f0f))
|
||||
* **front:** use functions to generate classnames dynamically ([98230a5](https://framagit.org/framasoft/mobilizon/commits/98230a56bb5e1c75f070e4d4c352028741869066))
|
||||
* **front:** various cleanups ([6a482b0](https://framagit.org/framasoft/mobilizon/commits/6a482b0d9754fc85f1f61922e92852fbca52beb9))
|
||||
* **front:** various little CSS fixes ([51d43aa](https://framagit.org/framasoft/mobilizon/commits/51d43aa2d1d1f099078895d67a45fc27b74d4604))
|
||||
* **front:** various UI improvements ([a6a1ab7](https://framagit.org/framasoft/mobilizon/commits/a6a1ab71c23264805d61b5312982e6d345454027))
|
||||
* **front:** vite fixes after upgrade (everything is esm) ([b1ecf4b](https://framagit.org/framasoft/mobilizon/commits/b1ecf4b36f5855c895f72c4d9dc0f7e1beb449e1))
|
||||
* **graphql:** add missing operation name for RegisterPerson ([a47f4f6](https://framagit.org/framasoft/mobilizon/commits/a47f4f6444d12a13a6f7e79ed6746e74088ca294))
|
||||
* **graphql:** fix checking actor identity when publishing event announcements ([5bc0593](https://framagit.org/framasoft/mobilizon/commits/5bc0593ed6e772d48722c308ccb444dc49f3c079))
|
||||
* **nodeinfo:** fix getting application actor information from NodeInfo response ([dd775b6](https://framagit.org/framasoft/mobilizon/commits/dd775b6ae25f381cf76e00999fd7d37764870122))
|
||||
* **nodeinfo:** make sure we only process JSON content ([da3b074](https://framagit.org/framasoft/mobilizon/commits/da3b0746198544d7977d9c0b32d8a26e1da64d40))
|
||||
|
||||
|
||||
## 4.0.2 (2023-12-07)
|
||||
|
||||
### Security issues
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -630,7 +630,7 @@ state the exclusion of warranty; and each file should have at least
|
|||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
Mobilizon
|
||||
Copyright (C) 2018 Thomas Citharel
|
||||
Copyright (C) 2018 - 2024 Framasoft
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
|
|
4
Makefile
4
Makefile
|
@ -19,8 +19,8 @@ stop:
|
|||
@bash docker/message.sh "Mobilizon is stopped"
|
||||
test: stop
|
||||
@bash docker/message.sh "Running tests"
|
||||
docker compose -f docker compose.yml -f docker compose.test.yml run api mix prepare_test
|
||||
docker compose -f docker compose.yml -f docker compose.test.yml run api mix test $(only)
|
||||
docker compose -f docker-compose.yml -f docker-compose.test.yml run api mix prepare_test
|
||||
docker compose -f docker-compose.yml -f docker-compose.test.yml run api mix test $(only)
|
||||
@bash docker/message.sh "Done running tests"
|
||||
format:
|
||||
docker compose run --rm api bash -c "mix format && mix credo --strict"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
Mobilizon is your federated organization and mobilization platform. Gather people with a convivial, ethical, and emancipating tool.
|
||||
|
||||
<p align="center">
|
||||
<strong>Developed with ♥ by <a href="https://framasoft.org">Framasoft</a></strong>
|
||||
<strong>2017 - 2024 Developed with ♥ by <a href="https://framasoft.org">Framasoft</a></strong>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
@ -20,7 +20,7 @@ Mobilizon is your federated organization and mobilization platform. Gather peopl
|
|||
|
||||
## Notes about this fork
|
||||
|
||||
The currently deployed `main` branch can be tested at [https://rotes.potsda.mn/](https://rotes.potsda.mn/).
|
||||
The currently deployed `v4.x` branch can be tested at [https://rotes.potsda.mn/](https://rotes.potsda.mn/).
|
||||
|
||||
### Building with Nix
|
||||
|
||||
|
|
10
SECURITY.md
10
SECURITY.md
|
@ -1,7 +1,7 @@
|
|||
[Mobilizon](https://joinmobilizon.org) takes security, privacy and user control seriously, and we want to put them front and centre of our project.
|
||||
|
||||
This document outlines security procedures and general policies for the Mobilizon project.
|
||||
Framasoft, the Mobilizon maintainer team and community take all security bugs in Mobilizon seriously. Thank you for improving the security of Mobilizon. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.
|
||||
The Mobilizon maintainer team and community take all security bugs in Mobilizon seriously. Thank you for improving the security of Mobilizon. We appreciate your efforts and responsible disclosure and will make every effort to acknowledge your contributions.
|
||||
|
||||
### Goals
|
||||
|
||||
|
@ -15,8 +15,6 @@ Framasoft, the Mobilizon maintainer team and community take all security bugs in
|
|||
|
||||
* GDPR compliance.
|
||||
|
||||
Framasoft is both a developer of open-source/free/libre self-hosted software, and a service provider with users in the European Union. As a result, we are putting user privacy, data sovereignty, and GDPR compliance into our security plans, including asking both the Framasoft community and outside hackers to review our approaches and implementations.
|
||||
|
||||
### Challenges
|
||||
|
||||
[Mobilizon](https://joinmobilizon.org) will be challenging to keep secure, as it is:
|
||||
|
@ -33,14 +31,14 @@ This means there are more attack surfaces compared to typical proprietary, centr
|
|||
|
||||
We are committed to working with security researchers to verify, reproduce, and respond to legitimate reported vulnerabilities. You can help us by following these simple guidelines:
|
||||
|
||||
* Alert us about the vulnerability as soon as you become aware of it by emailing the lead maintainer at tcit+mobilizon@framasoft.org.
|
||||
* Alert us about the vulnerability as soon as you become aware of it by emailing the lead maintainer.
|
||||
* Provide details needed to reproduce and validate the vulnerability and a Proof of Concept (PoC) as soon as possible
|
||||
* Act in good faith to avoid privacy violations, destruction of data, and interruption or degradation of services
|
||||
* Do not access or modify users’ private data, without explicit permission of the owner. Only interact with your own accounts or test accounts for security research purposes;
|
||||
* Contact Framasoft or a maintainer of the Mobilizon project (or the instance admin) immediately if you do inadvertently encounter user data. Do not view, alter, save, store, transfer, or otherwise access the data, and immediately purge any local information upon reporting the vulnerability;
|
||||
* Contact a maintainer of the Mobilizon project (or the instance admin) immediately if you do inadvertently encounter user data. Do not view, alter, save, store, transfer, or otherwise access the data, and immediately purge any local information upon reporting the vulnerability;
|
||||
* The lead maintainer will acknowledge your email within 48 hours, and will send a more detailed response within 48 hours indicating the next steps in handling your report. After the initial reply to your report, the security team will endeavor to keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
|
||||
* Give us time to confirm, determine the affected versions and prepare fixes to correct the issue before disclosing it to other parties (if after waiting a reasonable amount of time, we are clearly unable or unwilling to do anything about it, please do hold us accountable!)
|
||||
* Please test against a local instance of the software, and refrain from running any Denial of Service or automated testing tools against Framasoft's (and our partners') infrastructure
|
||||
* Please test against a local instance of the software, and refrain from running any Denial of Service or automated testing tools against the project managers (and their partners') infrastructure
|
||||
|
||||
Note : Please report security bugs in third-party modules to the person or team maintaining the module.
|
||||
|
||||
|
|
|
@ -36,7 +36,8 @@ config :mobilizon, :instance,
|
|||
unconfirmed_user_grace_period_hours: 48,
|
||||
activity_expire_days: 365,
|
||||
activity_keep_number: 100,
|
||||
enable_instance_feeds: false,
|
||||
duration_of_long_event: 30,
|
||||
enable_instance_feeds: true,
|
||||
email_from: "noreply@localhost",
|
||||
email_reply_to: "noreply@localhost"
|
||||
|
||||
|
@ -51,6 +52,7 @@ config :mobilizon, :restrictions, only_groups_can_create_events: false
|
|||
|
||||
# Configures the endpoint
|
||||
config :mobilizon, Mobilizon.Web.Endpoint,
|
||||
adapter: Bandit.PhoenixAdapter,
|
||||
url: [
|
||||
host: "mobilizon.local",
|
||||
scheme: "https"
|
||||
|
@ -134,7 +136,7 @@ config :vite_phx,
|
|||
environment: config_env(),
|
||||
# this manifest is different from the Phoenix "cache_manifest.json"!
|
||||
# optional
|
||||
vite_manifest: "priv/static/manifest.json",
|
||||
vite_manifest: "priv/static/.vite/manifest.json",
|
||||
# optional
|
||||
dev_server_address: "http://localhost:5173"
|
||||
|
||||
|
@ -204,6 +206,8 @@ config :codepagex, :encodings, [
|
|||
:"VENDORS/MICSFT/WINDOWS/CP1252"
|
||||
]
|
||||
|
||||
config :gettext, :default_locale, "en"
|
||||
|
||||
config :mobilizon, Mobilizon.Web.Gettext, split_module_by: [:locale, :domain]
|
||||
|
||||
config :ex_cldr,
|
||||
|
|
|
@ -5,9 +5,9 @@ config :mobilizon, Mobilizon.Web.Endpoint,
|
|||
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "4000"))
|
||||
],
|
||||
url: [
|
||||
host: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.local"),
|
||||
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "80")),
|
||||
scheme: "http"
|
||||
host: System.get_env("MOBILIZON_INSTANCE_HOST", "localhost"),
|
||||
port: String.to_integer(System.get_env("MOBILIZON_INSTANCE_HOST_PORT", "4000")),
|
||||
scheme: System.get_env("MOBILIZON_INSTANCE_SCHEME", "http")
|
||||
],
|
||||
secret_key_base: System.get_env("MOBILIZON_INSTANCE_SECRET_KEY_BASE", "changethis"),
|
||||
debug_errors: true,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Mobilizon instance configuration
|
||||
|
||||
import Config
|
||||
import Mobilizon.Service.Config.Helpers
|
||||
|
||||
{:ok, _} = Application.ensure_all_started(:tls_certificate_check)
|
||||
|
||||
|
@ -49,9 +50,20 @@ config :mobilizon, :instance,
|
|||
description: "Change this to a proper description of your instance",
|
||||
hostname: System.get_env("MOBILIZON_INSTANCE_HOST", "mobilizon.lan"),
|
||||
registrations_open: System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_OPEN", "false") == "true",
|
||||
demo: false,
|
||||
allow_relay: true,
|
||||
federating: true,
|
||||
registration_email_allowlist:
|
||||
System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_EMAIL_ALLOWLIST", "")
|
||||
|> String.split(",", trim: true),
|
||||
registration_email_denylist:
|
||||
System.get_env("MOBILIZON_INSTANCE_REGISTRATIONS_EMAIL_DENYLIST", "")
|
||||
|> String.split(",", trim: true),
|
||||
disable_database_login:
|
||||
System.get_env("MOBILIZON_INSTANCE_DISABLE_DATABASE_LOGIN", "false") == "true",
|
||||
default_language: System.get_env("MOBILIZON_INSTANCE_DEFAULT_LANGUAGE", "en"),
|
||||
demo: System.get_env("MOBILIZON_INSTANCE_DEMO", "false") == "true",
|
||||
allow_relay: System.get_env("MOBILIZON_INSTANCE_ALLOW_RELAY", "true") == "true",
|
||||
federating: System.get_env("MOBILIZON_INSTANCE_FEDERATING", "true") == "true",
|
||||
enable_instance_feeds:
|
||||
System.get_env("MOBILIZON_INSTANCE_ENABLE_INSTANCE_FEEDS", "true") == "true",
|
||||
email_from: System.get_env("MOBILIZON_INSTANCE_EMAIL", "noreply@mobilizon.lan"),
|
||||
email_reply_to: System.get_env("MOBILIZON_REPLY_EMAIL", "noreply@mobilizon.lan")
|
||||
|
||||
|
@ -79,7 +91,7 @@ config :mobilizon, Mobilizon.Web.Email.Mailer,
|
|||
ssl: System.get_env("MOBILIZON_SMTP_SSL", "false"),
|
||||
retries: 1,
|
||||
no_mx_lookups: false,
|
||||
auth: :if_available
|
||||
auth: System.get_env("MOBILIZON_SMTP_AUTH", "if_available")
|
||||
|
||||
config :geolix,
|
||||
databases: [
|
||||
|
@ -93,13 +105,30 @@ config :geolix,
|
|||
config :mobilizon, Mobilizon.Web.Upload.Uploader.Local,
|
||||
uploads: System.get_env("MOBILIZON_UPLOADS", "/var/lib/mobilizon/uploads")
|
||||
|
||||
formats =
|
||||
if System.get_env("MOBILIZON_EXPORTS_FORMAT_CSV_ENABLED", "true") == "true" do
|
||||
[Mobilizon.Service.Export.Participants.CSV]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
formats =
|
||||
if System.get_env("MOBILIZON_EXPORTS_FORMAT_PDF_ENABLED", "true") == "true" do
|
||||
formats ++ [Mobilizon.Service.Export.Participants.PDF]
|
||||
else
|
||||
formats
|
||||
end
|
||||
|
||||
formats =
|
||||
if System.get_env("MOBILIZON_EXPORTS_FORMAT_ODS_ENABLED", "true") == "true" do
|
||||
formats ++ [Mobilizon.Service.Export.Participants.ODS]
|
||||
else
|
||||
formats
|
||||
end
|
||||
|
||||
config :mobilizon, :exports,
|
||||
path: System.get_env("MOBILIZON_UPLOADS_EXPORTS", "/var/lib/mobilizon/uploads/exports"),
|
||||
formats: [
|
||||
Mobilizon.Service.Export.Participants.CSV,
|
||||
Mobilizon.Service.Export.Participants.PDF,
|
||||
Mobilizon.Service.Export.Participants.ODS
|
||||
]
|
||||
formats: formats
|
||||
|
||||
config :tz_world,
|
||||
data_dir: System.get_env("MOBILIZON_TIMEZONES_DIR", "/var/lib/mobilizon/timezones")
|
||||
|
@ -110,3 +139,118 @@ config :web_push_encryption, :vapid_details,
|
|||
subject: System.get_env("MOBILIZON_WEB_PUSH_ENCRYPTION_SUBJECT", nil),
|
||||
public_key: System.get_env("MOBILIZON_WEB_PUSH_ENCRYPTION_PUBLIC_KEY", nil),
|
||||
private_key: System.get_env("MOBILIZON_WEB_PUSH_ENCRYPTION_PRIVATE_KEY", nil)
|
||||
|
||||
geospatial_service =
|
||||
case System.get_env("MOBILIZON_GEOSPATIAL_SERVICE", "Nominatim") do
|
||||
"Nominatim" -> Mobilizon.Service.Geospatial.Nominatim
|
||||
"Addok" -> Mobilizon.Service.Geospatial.Addok
|
||||
"Photon" -> Mobilizon.Service.Geospatial.Photon
|
||||
"GoogleMaps" -> Mobilizon.Service.Geospatial.GoogleMaps
|
||||
"MapQuest" -> Mobilizon.Service.Geospatial.MapQuest
|
||||
"Mimirsbrunn" -> Mobilizon.Service.Geospatial.Mimirsbrunn
|
||||
"Pelias" -> Mobilizon.Service.Geospatial.Pelias
|
||||
"Hat" -> Mobilizon.Service.Geospatial.Hat
|
||||
end
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial, service: geospatial_service
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.Nominatim,
|
||||
endpoint:
|
||||
System.get_env(
|
||||
"MOBILIZON_GEOSPATIAL_NOMINATIM_ENDPOINT",
|
||||
"https://nominatim.openstreetmap.org"
|
||||
),
|
||||
api_key: System.get_env("MOBILIZON_GEOSPATIAL_NOMINATIM_API_KEY", nil)
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.Addok,
|
||||
endpoint:
|
||||
System.get_env("MOBILIZON_GEOSPATIAL_ADDOK_ENDPOINT", "https://api-adresse.data.gouv.fr")
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.Photon,
|
||||
endpoint: System.get_env("MOBILIZON_GEOSPATIAL_PHOTON_ENDPOINT", "https://photon.komoot.de")
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.GoogleMaps,
|
||||
api_key: System.get_env("MOBILIZON_GEOSPATIAL_GOOGLE_MAPS_API_KEY", nil),
|
||||
fetch_place_details: true
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.MapQuest,
|
||||
api_key: System.get_env("MOBILIZON_GEOSPATIAL_MAP_QUEST_API_KEY", nil)
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.Mimirsbrunn,
|
||||
endpoint: System.get_env("MOBILIZON_GEOSPATIAL_MIMIRSBRUNN_ENDPOINT", nil)
|
||||
|
||||
config :mobilizon, Mobilizon.Service.Geospatial.Pelias,
|
||||
endpoint: System.get_env("MOBILIZON_GEOSPATIAL_PELIAS_ENDPOINT", nil)
|
||||
|
||||
sentry_dsn = System.get_env("MOBILIZON_ERROR_REPORTING_SENTRY_DSN", nil)
|
||||
|
||||
included_environments = if sentry_dsn, do: ["prod"], else: []
|
||||
|
||||
config :sentry,
|
||||
dsn: sentry_dsn,
|
||||
included_environments: included_environments,
|
||||
release: to_string(Application.spec(:mobilizon, :vsn))
|
||||
|
||||
config :logger, Sentry.LoggerBackend,
|
||||
capture_log_messages: true,
|
||||
level: :error
|
||||
|
||||
if sentry_dsn != nil do
|
||||
config :mobilizon, Mobilizon.Service.ErrorReporting,
|
||||
adapter: Mobilizon.Service.ErrorReporting.Sentry
|
||||
end
|
||||
|
||||
matomo_enabled = System.get_env("MOBILIZON_FRONT_END_ANALYTICS_MATOMO_ENABLED", "false") == "true"
|
||||
matomo_endpoint = System.get_env("MOBILIZON_FRONT_END_ANALYTICS_MATOMO_ENDPOINT", nil)
|
||||
matomo_site_id = System.get_env("MOBILIZON_FRONT_END_ANALYTICS_MATOMO_SITE_ID", nil)
|
||||
|
||||
matomo_tracker_file_name =
|
||||
System.get_env("MOBILIZON_FRONT_END_ANALYTICS_MATOMO_TRACKER_FILE_NAME", "matomo")
|
||||
|
||||
matomo_host = host_from_uri(matomo_endpoint)
|
||||
|
||||
analytics_providers =
|
||||
if matomo_enabled do
|
||||
[Mobilizon.Service.FrontEndAnalytics.Matomo]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
analytics_providers =
|
||||
if sentry_dsn != nil do
|
||||
analytics_providers ++ [Mobilizon.Service.FrontEndAnalytics.Sentry]
|
||||
else
|
||||
analytics_providers
|
||||
end
|
||||
|
||||
config :mobilizon, :analytics, providers: analytics_providers
|
||||
|
||||
matomo_csp =
|
||||
if matomo_enabled and matomo_host do
|
||||
[
|
||||
connect_src: [matomo_host],
|
||||
script_src: [matomo_host],
|
||||
img_src: [matomo_host]
|
||||
]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
||||
config :mobilizon, Mobilizon.Service.FrontEndAnalytics.Matomo,
|
||||
enabled: matomo_enabled,
|
||||
host: matomo_endpoint,
|
||||
siteId: matomo_site_id,
|
||||
trackerFileName: matomo_tracker_file_name,
|
||||
csp: matomo_csp
|
||||
|
||||
config :mobilizon, Mobilizon.Service.FrontEndAnalytics.Sentry,
|
||||
enabled: sentry_dsn != nil,
|
||||
dsn: sentry_dsn,
|
||||
tracesSampleRate: 1.0,
|
||||
organization: System.get_env("MOBILIZON_ERROR_REPORTING_SENTRY_ORGANISATION", nil),
|
||||
project: System.get_env("MOBILIZON_ERROR_REPORTING_SENTRY_PROJECT", nil),
|
||||
host: System.get_env("MOBILIZON_ERROR_REPORTING_SENTRY_HOST", nil),
|
||||
csp: [
|
||||
connect_src:
|
||||
System.get_env("MOBILIZON_ERROR_REPORTING_SENTRY_HOST", "") |> String.split(" ", trim: true)
|
||||
]
|
||||
|
|
|
@ -25,7 +25,7 @@ config :vite_phx,
|
|||
release_app: :mobilizon,
|
||||
# Hard code :prod as an environment as :e2e will not be recongnized
|
||||
environment: :prod,
|
||||
vite_manifest: "priv/static/manifest.json",
|
||||
vite_manifest: "priv/static/.vite/manifest.json",
|
||||
phx_manifest: "priv/static/cache_manifest.json",
|
||||
dev_server_address: "http://localhost:5173"
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ import Config
|
|||
|
||||
config :mobilizon, :instance,
|
||||
name: "Test instance",
|
||||
registrations_open: true
|
||||
registrations_open: true,
|
||||
duration_of_long_event: 0
|
||||
|
||||
# We don't run a server during test. If one is required,
|
||||
# you can enable the server option below.
|
||||
|
|
128
default.nix
128
default.nix
|
@ -1,40 +1,35 @@
|
|||
{ lib
|
||||
, beamPackages
|
||||
, fetchFromGitHub
|
||||
, git
|
||||
, cmake
|
||||
, nixosTests
|
||||
, src
|
||||
, src-config
|
||||
, mobilizon-js
|
||||
{
|
||||
lib,
|
||||
beam_nox,
|
||||
fetchFromGitHub,
|
||||
cmake,
|
||||
nixosTests,
|
||||
src,
|
||||
src-config,
|
||||
mobilizon-js,
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (beamPackages) mixRelease buildMix;
|
||||
inherit (beam_nox.packages.erlang) mixRelease buildMix elixir;
|
||||
in
|
||||
mixRelease rec {
|
||||
pname = "mobilizon";
|
||||
version = "4.0.2";
|
||||
|
||||
# This has to be kept in sync with the version in mix.exs and package.json!
|
||||
# Otherwise the nginx routing isn't going to work properly.
|
||||
version = "5.0.0-beta.1";
|
||||
|
||||
inherit src;
|
||||
|
||||
# See https://github.com/whitfin/cachex/issues/205
|
||||
# This circumvents a startup error for now
|
||||
stripDebug = false;
|
||||
|
||||
nativeBuildInputs = [ git cmake ];
|
||||
|
||||
mixNixDeps = import ./mix.nix {
|
||||
inherit beamPackages lib;
|
||||
overrides = (final: prev:
|
||||
(lib.mapAttrs
|
||||
(_: value: value.override {
|
||||
appConfigPath = src-config;
|
||||
})
|
||||
prev) // {
|
||||
fast_html = prev.fast_html.override {
|
||||
nativeBuildInputs = [ cmake ];
|
||||
};
|
||||
# Update deps.nix by running `mix deps.nix`
|
||||
mixNixDeps = import ./deps.nix {
|
||||
inherit lib;
|
||||
beamPackages = beam_nox.packages.erlang;
|
||||
overrides = (
|
||||
final: prev:
|
||||
(lib.mapAttrs (_: value: value.override { appConfigPath = src-config; }) prev)
|
||||
// {
|
||||
fast_html = prev.fast_html.override { nativeBuildInputs = [ cmake ]; };
|
||||
ex_cldr = prev.ex_cldr.overrideAttrs (old: {
|
||||
# We have to use the GitHub sources, as it otherwise tries to download
|
||||
# the locales at build time.
|
||||
|
@ -42,77 +37,27 @@ mixRelease rec {
|
|||
owner = "elixir-cldr";
|
||||
repo = "cldr";
|
||||
rev = "v${old.version}";
|
||||
sha256 = assert old.version == "2.37.5";
|
||||
sha256 =
|
||||
assert old.version == "2.37.5";
|
||||
"sha256-T5Qvuo+xPwpgBsqHNZYnTCA4loToeBn1LKTMsDcCdYs=";
|
||||
};
|
||||
postInstall = ''
|
||||
cp $src/priv/cldr/locales/* $out/lib/erlang/lib/ex_cldr-${old.version}/priv/cldr/locales/
|
||||
'';
|
||||
});
|
||||
# Upstream issue: https://github.com/bryanjos/geo_postgis/pull/87
|
||||
geo_postgis = prev.geo_postgis.overrideAttrs (old: {
|
||||
propagatedBuildInputs = old.propagatedBuildInputs ++ [ final.ecto ];
|
||||
});
|
||||
|
||||
# The remainder are Git dependencies (and their deps) that are not supported by mix2nix currently.
|
||||
web_push_encryption = buildMix rec {
|
||||
name = "web_push_encryption";
|
||||
version = "0.3.1";
|
||||
src = fetchFromGitHub {
|
||||
owner = "danhper";
|
||||
repo = "elixir-web-push-encryption";
|
||||
rev = "70f00d06cbd88c9ac382e0ad2539e54448e9d8da";
|
||||
sha256 = "sha256-b4ZMrt/8n2sPUFtCDRTwXS1qWm5VlYdbx8qC0R0boOA=";
|
||||
};
|
||||
beamDeps = with final; [ httpoison jose ];
|
||||
};
|
||||
icalendar = buildMix rec {
|
||||
name = "icalendar";
|
||||
version = "unstable-2022-04-10";
|
||||
src = fetchFromGitHub {
|
||||
owner = "tcitworld";
|
||||
repo = name;
|
||||
rev = "1033d922c82a7223db0ec138e2316557b70ff49f";
|
||||
sha256 = "sha256-N3bJZznNazLewHS4c2B7LP1lgxd1wev+EWVlQ7rOwfU=";
|
||||
};
|
||||
beamDeps = with final; [ mix_test_watch ex_doc timex ];
|
||||
};
|
||||
rajska = buildMix rec {
|
||||
name = "rajska";
|
||||
version = "1.3.3";
|
||||
src = fetchFromGitHub {
|
||||
owner = "tcitworld";
|
||||
repo = name;
|
||||
rev = "0c036448e261e8be6a512581c592fadf48982d84";
|
||||
sha256 = "sha256-4pfply1vTAIT2Xvm3kONmrCK05xKfXFvcb8EKoSCXBE=";
|
||||
};
|
||||
beamDeps = with final; [ ex_doc credo absinthe excoveralls hammer mock ];
|
||||
};
|
||||
exkismet = buildMix rec {
|
||||
name = "exkismet";
|
||||
version = "0.0.3";
|
||||
src = fetchFromGitHub {
|
||||
owner = "tcitworld";
|
||||
repo = name;
|
||||
rev = "8b5485fde00fafbde20f315bec387a77f7358334";
|
||||
sha256 = "sha256-ttgCWoBKU7VTjZJBhZNtqVF4kN7psBr/qOeR65MbTqw=";
|
||||
};
|
||||
beamDeps = with final; [ httpoison ex_doc credo doctor dialyxir ];
|
||||
};
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
preConfigure = ''
|
||||
export LANG=C.UTF-8 # fix elixir locale warning
|
||||
'';
|
||||
# fix elixir locale warning
|
||||
env.LANG = "C.UTF-8";
|
||||
|
||||
# Install the compiled js part
|
||||
preBuild =
|
||||
''
|
||||
cp -a "${mobilizon-js}/_napalm-install/priv/static" ./priv
|
||||
chmod 770 -R ./priv
|
||||
'';
|
||||
preBuild = ''
|
||||
cp -a "${mobilizon-js}/_napalm-install/priv/static" ./priv
|
||||
chmod 770 -R ./priv
|
||||
'';
|
||||
|
||||
postBuild = ''
|
||||
mix phx.digest --no-deps-check
|
||||
|
@ -128,12 +73,15 @@ mixRelease rec {
|
|||
ln -s ${ex_cldr.src}/priv/cldr/locales $out/lib/ex_cldr-${ex_cldr.version}/priv/cldr/locales
|
||||
'';
|
||||
|
||||
passthru.elixirPackage = beamPackages.elixir;
|
||||
passthru.elixirPackage = elixir;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Mobilizon is an online tool to help manage your events, your profiles and your groups";
|
||||
homepage = "https://joinmobilizon.org/";
|
||||
license = licenses.agpl3Plus;
|
||||
maintainers = with maintainers; [ minijackson erictapen ];
|
||||
maintainers = with maintainers; [
|
||||
minijackson
|
||||
erictapen
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE="elixir:1.15"
|
||||
ARG IMAGE="elixir:1.16"
|
||||
|
||||
FROM ${IMAGE} as build
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
|
|
@ -9,7 +9,7 @@ COPY . .
|
|||
RUN npm install && npm run build
|
||||
|
||||
# Then, build the application binary
|
||||
FROM elixir:1.15-alpine AS builder
|
||||
FROM elixir:1.16-alpine AS builder
|
||||
|
||||
# Fix qemu segfault on arm64
|
||||
# See https://github.com/plausible/analytics/pull/2879 and https://github.com/erlang/otp/pull/6340
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
FROM elixir:latest
|
||||
LABEL maintainer="Thomas Citharel <thomas.citharel@framasoft.org>"
|
||||
|
||||
ENV REFRESHED_AT=2023-11-20
|
||||
ENV REFRESHED_AT=2024-02-29
|
||||
RUN apt-get update -yq && apt-get install -yq ca-certificates build-essential inotify-tools postgresql-client git curl gnupg xvfb libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 cmake exiftool python3-pip python3-setuptools
|
||||
RUN mkdir -p /etc/apt/keyrings && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && apt-get update && apt-get install nodejs -yq
|
||||
RUN npm install -g wait-on
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
RUN mix local.hex --force && mix local.rebar --force
|
||||
RUN pip3 --no-cache-dir install -Iv weasyprint pyexcel_ods3
|
||||
RUN pip --no-cache-dir install --break-system-packages weasyprint pyexcel-ods3
|
||||
RUN curl https://dbip.mirror.framasoft.org/files/dbip-city-lite-latest.mmdb --output GeoLite2-City.mmdb -s && mkdir -p /usr/share/GeoIP && mv GeoLite2-City.mmdb /usr/share/GeoIP/
|
||||
|
|
18
flake.lock
18
flake.lock
|
@ -26,11 +26,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1703102458,
|
||||
"narHash": "sha256-3pOV731qi34Q2G8e2SqjUXqnftuFrbcq+NdagEZXISo=",
|
||||
"lastModified": 1717929455,
|
||||
"narHash": "sha256-BiI5xWygriOJuNISnGAeL0KYxrEMnjgpg+7wDskVBhI=",
|
||||
"owner": "nix-community",
|
||||
"repo": "napalm",
|
||||
"rev": "edcb26c266ca37c9521f6a97f33234633cbec186",
|
||||
"rev": "e1babff744cd278b56abe8478008b4a9e23036cf",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -41,11 +41,11 @@
|
|||
},
|
||||
"nix-filter": {
|
||||
"locked": {
|
||||
"lastModified": 1705332318,
|
||||
"narHash": "sha256-kcw1yFeJe9N4PjQji9ZeX47jg0p9A0DuU4djKvg1a7I=",
|
||||
"lastModified": 1710156097,
|
||||
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=",
|
||||
"owner": "numtide",
|
||||
"repo": "nix-filter",
|
||||
"rev": "3449dc925982ad46246cfc36469baf66e1b64f17",
|
||||
"rev": "3342559a24e85fc164b295c3444e8a139924675b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
@ -56,11 +56,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1706550542,
|
||||
"narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=",
|
||||
"lastModified": 1726463316,
|
||||
"narHash": "sha256-gI9kkaH0ZjakJOKrdjaI/VbaMEo9qBbSUl93DnU7f4c=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "97b17f32362e475016f942bbdfda4a4a72a8a652",
|
||||
"rev": "99dc8785f6a0adac95f5e2ab05cc2e1bf666d172",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
507
flake.nix
507
flake.nix
|
@ -8,20 +8,27 @@
|
|||
napalm.inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, nix-filter, napalm }:
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
nix-filter,
|
||||
napalm,
|
||||
}:
|
||||
let
|
||||
forAllSystems = f: nixpkgs.lib.genAttrs
|
||||
[ "x86_64-linux" "aarch64-linux" ]
|
||||
(system: f system);
|
||||
nixpkgsFor = forAllSystems (
|
||||
system:
|
||||
import nixpkgs { inherit system; }
|
||||
);
|
||||
forAllSystems =
|
||||
f:
|
||||
nixpkgs.lib.genAttrs [
|
||||
"x86_64-linux"
|
||||
"aarch64-linux"
|
||||
] (system: f system);
|
||||
nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; });
|
||||
filter = nix-filter.lib;
|
||||
in
|
||||
{
|
||||
|
||||
packages = forAllSystems (system:
|
||||
packages = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgsFor.${system};
|
||||
# Directories that are neither needed for building the frontend nor the backend.
|
||||
|
@ -55,9 +62,6 @@
|
|||
};
|
||||
|
||||
mobilizon-frontend =
|
||||
let
|
||||
nodejs = pkgs.nodejs-18_x;
|
||||
in
|
||||
napalm.legacyPackages."${system}".buildPackage
|
||||
(filter {
|
||||
root = ./.;
|
||||
|
@ -70,43 +74,183 @@
|
|||
] ++ unrelatedDirs;
|
||||
})
|
||||
{
|
||||
inherit nodejs;
|
||||
inherit (pkgs) nodejs;
|
||||
nativeBuildInputs = [ pkgs.imagemagick ];
|
||||
npmCommands = [ "npm install" "npm run build" ];
|
||||
npmCommands = [
|
||||
"npm install"
|
||||
"npm run build"
|
||||
];
|
||||
# Keep this in sync with the content of ./patches/
|
||||
customPatchPackages = {
|
||||
vue-i18n-extract."2.0.7" = pkgs: prev: {
|
||||
preConfigure = ''
|
||||
${pkgs.git}/bin/git apply -p3 ${./patches/vue-i18n-extract+2.0.7.patch}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
default = self.packages."${system}".mobilizon;
|
||||
}
|
||||
);
|
||||
|
||||
# Update local Mobilizon definition
|
||||
update =
|
||||
pkgs.writeShellScriptBin "update" ''
|
||||
set -eou pipefail
|
||||
|
||||
${pkgs.mix2nix}/bin/mix2nix ./mix.lock > mix.nix
|
||||
'';
|
||||
});
|
||||
|
||||
devShells = forAllSystems (system:
|
||||
let pkgs = nixpkgsFor.${system};
|
||||
in {
|
||||
default =
|
||||
pkgs.mkShell {
|
||||
buildInputs = with pkgs; [
|
||||
elixir
|
||||
mix2nix
|
||||
cmake
|
||||
imagemagick
|
||||
nodejs-18_x
|
||||
];
|
||||
devShells = forAllSystems (
|
||||
system:
|
||||
let
|
||||
pkgs = nixpkgsFor.${system};
|
||||
settingsFormat = pkgs.formats.elixirConf { };
|
||||
mobilizonConfig = settingsFormat.generate "runtime.exs" {
|
||||
":mobilizon" = {
|
||||
"Mobilizon.Web.Endpoint" = {
|
||||
server = true;
|
||||
url.host = "mobilizon.dev";
|
||||
http = {
|
||||
ip = settingsFormat.lib.mkTuple [
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
0
|
||||
1
|
||||
];
|
||||
port = 4000;
|
||||
};
|
||||
secret_key_base = "2q/l1WDx3RQQy7gZ1k001//6nc66moWUEJQyGuMK/z3zPLYW6FYtIgCkUzGP0+X/";
|
||||
};
|
||||
"Mobilizon.Web.Auth.Guardian" = {
|
||||
secret_key = "N8x7/tf0kInLFS2poO22g6OGPiMjSrDEhmk29nFqV35q7hQ0DtBt/cRYCsqBNp2L";
|
||||
};
|
||||
":instance" = {
|
||||
name = "Mobilizon";
|
||||
description = "Change this to a proper description of your instance";
|
||||
hostname = "mobilizon.dev";
|
||||
registrations_open = true;
|
||||
email_from = "noreply@mobilizon.dev";
|
||||
email_reply_to = "noreply@mobilizon.dev";
|
||||
};
|
||||
"Mobilizon.Storage.Repo" = {
|
||||
adapter = settingsFormat.lib.mkAtom "Ecto.Adapters.Postgres";
|
||||
pool_size = 10;
|
||||
username = "mobilizon";
|
||||
database = "mobilizon";
|
||||
socket_dir = "/var/run/postgresql";
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
in
|
||||
{
|
||||
default = pkgs.mkShell {
|
||||
MIX_ENV = "dev";
|
||||
PGUSER = "mobilizon";
|
||||
PGDATABASE = "mobilizon";
|
||||
buildInputs = with pkgs; [
|
||||
elixir
|
||||
cmake
|
||||
imagemagick
|
||||
nodejs
|
||||
inotify-tools
|
||||
(pkgs.writeShellApplication {
|
||||
name = "build";
|
||||
runtimeInputs = [
|
||||
elixir
|
||||
nodejs
|
||||
];
|
||||
text = ''
|
||||
mix deps.get
|
||||
mix deps.nix
|
||||
mix deps.compile
|
||||
mix phx.digest
|
||||
npm install
|
||||
npm run build
|
||||
'';
|
||||
})
|
||||
(pkgs.writeShellApplication {
|
||||
name = "setup";
|
||||
runtimeInputs = [
|
||||
elixir
|
||||
postgresql
|
||||
];
|
||||
text = ''
|
||||
cat ${mobilizonConfig} > config/runtime.exs
|
||||
# We assume the database already exists
|
||||
sudo -u postgres psql -d mobilizon << SQL
|
||||
create extension if not exists postgis;
|
||||
create extension if not exists unaccent;
|
||||
create extension if not exists pg_trgm;
|
||||
SQL
|
||||
mix ecto.migrate
|
||||
'';
|
||||
})
|
||||
(pkgs.writeShellApplication {
|
||||
name = "start";
|
||||
runtimeInputs = [ elixir ];
|
||||
text = ''
|
||||
mix phx.server
|
||||
'';
|
||||
})
|
||||
(pkgs.writeShellApplication {
|
||||
name = "clean";
|
||||
runtimeInputs = [ postgresql ];
|
||||
text = ''
|
||||
rm -rf deps/ _build/ node_modules/
|
||||
sudo -u postgres psql -c "DROP DATABASE mobilizon;"
|
||||
sudo systemctl restart postgresql.service
|
||||
'';
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
overlays.default = final: prev: {
|
||||
inherit (self.packages."${prev.system}") mobilizon;
|
||||
};
|
||||
nixosModules.devSetup =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.mobilizonDevEnvironment;
|
||||
in
|
||||
{
|
||||
|
||||
options.mobilizonDevEnvironment = {
|
||||
enable = lib.mkEnableOption (lib.mdDoc "development environment for Mobilizon");
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "Unix user that runs the backend application to connect to the database";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "mobilizon" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "mobilizon";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
extraPlugins = with config.services.postgresql.package.pkgs; [ postgis ];
|
||||
identMap = ''
|
||||
map-mobilizon ${cfg.user} mobilizon
|
||||
'';
|
||||
authentication = ''
|
||||
local all mobilizon ident map=map-mobilizon
|
||||
'';
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
overlays.default = final: prev: { inherit (self.packages."${prev.system}") mobilizon; };
|
||||
|
||||
checks = forAllSystems (system: {
|
||||
inherit (self.packages.${system}) mobilizon update;
|
||||
inherit (self.packages.${system}) mobilizon;
|
||||
nixosTest =
|
||||
let
|
||||
pkgsMobilizon = import nixpkgs {
|
||||
|
@ -114,7 +258,7 @@
|
|||
overlays = [ self.overlays.default ];
|
||||
};
|
||||
certs = import "${nixpkgs}/nixos/tests/common/acme/server/snakeoil-certs.nix";
|
||||
test = import ./nixos-test.nix { inherit certs; };
|
||||
test = import ./integration-test.nix { inherit certs; };
|
||||
in
|
||||
pkgsMobilizon.nixosTest test;
|
||||
});
|
||||
|
@ -122,120 +266,197 @@
|
|||
lib = {
|
||||
# Patch the logos in the source tree of a mobilizon-frontend package before building.
|
||||
# Can be used to construct the argument for .overrideAttrs on mobilizon-frontend.
|
||||
mobilizonLogosOverride = icons:
|
||||
mobilizonLogosOverride =
|
||||
icons:
|
||||
let
|
||||
inherit (icons) logo favicon;
|
||||
in
|
||||
old: {
|
||||
postPatch = ''
|
||||
cp '${logo}' src/assets/logo.svg
|
||||
postPatch =
|
||||
''
|
||||
cp '${logo}' src/assets/logo.svg
|
||||
|
||||
magick convert \
|
||||
-resize x16 \
|
||||
-gravity center \
|
||||
-crop 16x16+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
public/img/icons/favicon-16x16.png
|
||||
|
||||
magick convert \
|
||||
-resize x32 \
|
||||
-gravity center \
|
||||
-crop 32x32+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
public/img/icons/favicon-32x32.png
|
||||
|
||||
|
||||
magick convert \
|
||||
-resize x16 \
|
||||
-gravity center \
|
||||
-crop 16x16+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
favicon-16x16.ico
|
||||
|
||||
magick convert \
|
||||
-resize x32 \
|
||||
-gravity center \
|
||||
-crop 32x32+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
favicon-32x32.ico
|
||||
|
||||
magick convert \
|
||||
-resize x48 \
|
||||
-gravity center \
|
||||
-crop 48x48+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
favicon-48x48.ico
|
||||
|
||||
magick convert \
|
||||
favicon-16x16.ico \
|
||||
favicon-32x32.ico \
|
||||
favicon-48x48.ico \
|
||||
public/favicon.ico
|
||||
|
||||
rm favicon-16x16.ico favicon-32x32.ico favicon-48x48.ico
|
||||
|
||||
cp '${favicon}' public/img/icons/favicon.svg
|
||||
cp '${favicon}' public/img/icons/safari-pinned-tab.svg
|
||||
|
||||
magick convert \
|
||||
'${favicon}' \
|
||||
-gravity center \
|
||||
-extent 630x350 \
|
||||
public/img/mobilizon_default_card.png
|
||||
|
||||
magick convert \
|
||||
-background '#e08c96' \
|
||||
'${logo}' \
|
||||
-resize 366x108 \
|
||||
public/img/mobilizon_logo.png
|
||||
|
||||
'' + nixpkgs.lib.concatMapStrings
|
||||
({ resize, filename }: ''
|
||||
magick convert \
|
||||
-resize x${resize} \
|
||||
-resize x16 \
|
||||
-gravity center \
|
||||
-crop 16x16+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
public/img/icons/${filename}
|
||||
public/img/icons/favicon-16x16.png
|
||||
|
||||
'')
|
||||
[
|
||||
{ resize = "180"; filename = "apple-touch-icon.png"; }
|
||||
{ resize = "180"; filename = "apple-touch-icon-180x180.png"; }
|
||||
{ resize = "152"; filename = "apple-touch-icon-152x152.png"; }
|
||||
{ resize = "120"; filename = "apple-touch-icon-120x120.png"; }
|
||||
{ resize = "76"; filename = "apple-touch-icon-76x76.png"; }
|
||||
{ resize = "60"; filename = "apple-touch-icon-60x60.png"; }
|
||||
{ resize = "192"; filename = "android-chrome-192x192.png"; }
|
||||
{ resize = "512"; filename = "android-chrome-512x512.png"; }
|
||||
{ resize = "192"; filename = "android-chrome-maskable-192x192.png"; }
|
||||
{ resize = "512"; filename = "android-chrome-maskable-512x512.png"; }
|
||||
{ resize = "128"; filename = "badge-128x128.png"; }
|
||||
{ resize = "144"; filename = "icon-144x144.png"; }
|
||||
{ resize = "168"; filename = "icon-168x168.png"; }
|
||||
{ resize = "256"; filename = "icon-256x256.png"; }
|
||||
{ resize = "48"; filename = "icon-48x48.png"; }
|
||||
{ resize = "72"; filename = "icon-72x72.png"; }
|
||||
{ resize = "96"; filename = "icon-96x96.png"; }
|
||||
{ resize = "144"; filename = "msapplication-icon-144x144.png"; }
|
||||
{ resize = "150"; filename = "mstile-150x150.png"; }
|
||||
{ resize = "192"; filename = "android-chrome-192x192.png"; }
|
||||
{ resize = "512"; filename = "android-chrome-512x512.png"; }
|
||||
{ resize = "192"; filename = "android-chrome-maskable-192x192.png"; }
|
||||
{ resize = "512"; filename = "android-chrome-maskable-512x512.png"; }
|
||||
];
|
||||
magick convert \
|
||||
-resize x32 \
|
||||
-gravity center \
|
||||
-crop 32x32+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
public/img/icons/favicon-32x32.png
|
||||
|
||||
|
||||
magick convert \
|
||||
-resize x16 \
|
||||
-gravity center \
|
||||
-crop 16x16+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
favicon-16x16.ico
|
||||
|
||||
magick convert \
|
||||
-resize x32 \
|
||||
-gravity center \
|
||||
-crop 32x32+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
favicon-32x32.ico
|
||||
|
||||
magick convert \
|
||||
-resize x48 \
|
||||
-gravity center \
|
||||
-crop 48x48+0+0 \
|
||||
-flatten \
|
||||
-colors 256 \
|
||||
'${favicon}' \
|
||||
favicon-48x48.ico
|
||||
|
||||
magick convert \
|
||||
favicon-16x16.ico \
|
||||
favicon-32x32.ico \
|
||||
favicon-48x48.ico \
|
||||
public/favicon.ico
|
||||
|
||||
rm favicon-16x16.ico favicon-32x32.ico favicon-48x48.ico
|
||||
|
||||
cp '${favicon}' public/img/icons/favicon.svg
|
||||
cp '${favicon}' public/img/icons/safari-pinned-tab.svg
|
||||
|
||||
magick convert \
|
||||
'${favicon}' \
|
||||
-gravity center \
|
||||
-extent 630x350 \
|
||||
public/img/mobilizon_default_card.png
|
||||
|
||||
magick convert \
|
||||
-background '#e08c96' \
|
||||
'${logo}' \
|
||||
-resize 366x108 \
|
||||
public/img/mobilizon_logo.png
|
||||
|
||||
''
|
||||
+
|
||||
nixpkgs.lib.concatMapStrings
|
||||
(
|
||||
{ resize, filename }:
|
||||
''
|
||||
magick convert \
|
||||
-resize x${resize} \
|
||||
'${favicon}' \
|
||||
public/img/icons/${filename}
|
||||
|
||||
''
|
||||
)
|
||||
[
|
||||
{
|
||||
resize = "180";
|
||||
filename = "apple-touch-icon.png";
|
||||
}
|
||||
{
|
||||
resize = "180";
|
||||
filename = "apple-touch-icon-180x180.png";
|
||||
}
|
||||
{
|
||||
resize = "152";
|
||||
filename = "apple-touch-icon-152x152.png";
|
||||
}
|
||||
{
|
||||
resize = "120";
|
||||
filename = "apple-touch-icon-120x120.png";
|
||||
}
|
||||
{
|
||||
resize = "76";
|
||||
filename = "apple-touch-icon-76x76.png";
|
||||
}
|
||||
{
|
||||
resize = "60";
|
||||
filename = "apple-touch-icon-60x60.png";
|
||||
}
|
||||
{
|
||||
resize = "192";
|
||||
filename = "android-chrome-192x192.png";
|
||||
}
|
||||
{
|
||||
resize = "512";
|
||||
filename = "android-chrome-512x512.png";
|
||||
}
|
||||
{
|
||||
resize = "192";
|
||||
filename = "android-chrome-maskable-192x192.png";
|
||||
}
|
||||
{
|
||||
resize = "512";
|
||||
filename = "android-chrome-maskable-512x512.png";
|
||||
}
|
||||
{
|
||||
resize = "128";
|
||||
filename = "badge-128x128.png";
|
||||
}
|
||||
{
|
||||
resize = "144";
|
||||
filename = "icon-144x144.png";
|
||||
}
|
||||
{
|
||||
resize = "168";
|
||||
filename = "icon-168x168.png";
|
||||
}
|
||||
{
|
||||
resize = "256";
|
||||
filename = "icon-256x256.png";
|
||||
}
|
||||
{
|
||||
resize = "48";
|
||||
filename = "icon-48x48.png";
|
||||
}
|
||||
{
|
||||
resize = "72";
|
||||
filename = "icon-72x72.png";
|
||||
}
|
||||
{
|
||||
resize = "96";
|
||||
filename = "icon-96x96.png";
|
||||
}
|
||||
{
|
||||
resize = "144";
|
||||
filename = "msapplication-icon-144x144.png";
|
||||
}
|
||||
{
|
||||
resize = "150";
|
||||
filename = "mstile-150x150.png";
|
||||
}
|
||||
{
|
||||
resize = "192";
|
||||
filename = "android-chrome-192x192.png";
|
||||
}
|
||||
{
|
||||
resize = "512";
|
||||
filename = "android-chrome-512x512.png";
|
||||
}
|
||||
{
|
||||
resize = "192";
|
||||
filename = "android-chrome-maskable-192x192.png";
|
||||
}
|
||||
{
|
||||
resize = "512";
|
||||
filename = "android-chrome-maskable-512x512.png";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
formatter = forAllSystems (system: nixpkgsFor.${system}.nixfmt-rfc-style);
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,7 +7,10 @@ in
|
|||
|
||||
{
|
||||
name = "mobilizon";
|
||||
meta.maintainers = with lib.maintainers; [ minijackson erictapen ];
|
||||
meta.maintainers = with lib.maintainers; [
|
||||
minijackson
|
||||
erictapen
|
||||
];
|
||||
|
||||
nodes.server =
|
||||
{ pkgs, ... }:
|
|
@ -105,6 +105,9 @@ defmodule Mobilizon.Federation.ActivityPub.Fetcher do
|
|||
{:error, %Ecto.Changeset{} = err} ->
|
||||
{:error, err}
|
||||
|
||||
{:error, {:error, %Ecto.Changeset{} = err}} ->
|
||||
{:error, err}
|
||||
|
||||
:error ->
|
||||
{:error, :transmogrifier_error}
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule Mobilizon.Federation.ActivityPub.Publisher do
|
|||
alias Mobilizon.Config
|
||||
alias Mobilizon.Federation.ActivityPub.{Activity, Federator, Relay, Transmogrifier, Visibility}
|
||||
alias Mobilizon.Federation.HTTPSignatures.Signature
|
||||
alias Mobilizon.Service.HTTP.ActivityPub, as: ActivityPubClient
|
||||
require Logger
|
||||
|
||||
import Mobilizon.Federation.ActivityPub.Utils,
|
||||
|
@ -95,16 +96,16 @@ defmodule Mobilizon.Federation.ActivityPub.Publisher do
|
|||
date: date
|
||||
})
|
||||
|
||||
Tesla.post(
|
||||
inbox,
|
||||
json,
|
||||
headers: [
|
||||
{"Content-Type", "application/activity+json"},
|
||||
{"signature", signature},
|
||||
{"digest", digest},
|
||||
{"date", date}
|
||||
]
|
||||
)
|
||||
headers = [
|
||||
{"Content-Type", "application/activity+json"},
|
||||
{"signature", signature},
|
||||
{"digest", digest},
|
||||
{"date", date}
|
||||
]
|
||||
|
||||
client = ActivityPubClient.client(headers: headers)
|
||||
|
||||
ActivityPubClient.post(client, inbox, json)
|
||||
end
|
||||
|
||||
@spec convert_followers_in_recipients(list(String.t())) :: {list(String.t()), list(String.t())}
|
||||
|
|
|
@ -71,8 +71,10 @@ defmodule Mobilizon.Federation.ActivityPub.Transmogrifier do
|
|||
case Discussions.get_comment_from_url_with_preload(object["id"]) do
|
||||
{:error, :comment_not_found} ->
|
||||
case Converter.Comment.as_to_model_data(object) do
|
||||
%{visibility: visibility, attributed_to_id: attributed_to_id} = object_data
|
||||
when visibility === :private and is_nil(attributed_to_id) ->
|
||||
%{visibility: visibility, attributed_to_id: attributed_to_id, actor_id: actor_id} =
|
||||
object_data
|
||||
when visibility === :private and
|
||||
(is_nil(attributed_to_id) or actor_id == attributed_to_id) ->
|
||||
Actions.Create.create(:conversation, object_data, false)
|
||||
|
||||
object_data when is_map(object_data) ->
|
||||
|
|
|
@ -6,10 +6,13 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
internal one, and back.
|
||||
"""
|
||||
|
||||
alias Cldr.DateTime.Formatter
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Addresses.Address
|
||||
alias Mobilizon.Events.Categories
|
||||
alias Mobilizon.Events.Event, as: EventModel
|
||||
alias Mobilizon.Events.EventOptions
|
||||
alias Mobilizon.Medias.Media
|
||||
|
||||
alias Mobilizon.Federation.ActivityStream.{Converter, Convertible}
|
||||
|
@ -29,7 +32,14 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
maybe_fetch_actor_and_attributed_to_id: 1,
|
||||
process_pictures: 2,
|
||||
get_address: 1,
|
||||
fetch_actor: 1
|
||||
fetch_actor: 1,
|
||||
visibility_public?: 1
|
||||
]
|
||||
|
||||
import Mobilizon.Service.Metadata.Utils,
|
||||
only: [
|
||||
datetime_to_string: 3,
|
||||
render_address!: 1
|
||||
]
|
||||
|
||||
require Logger
|
||||
|
@ -146,7 +156,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
"anonymousParticipationEnabled" => event.options.anonymous_participation,
|
||||
"attachment" => Enum.map(event.metadata, &EventMetadataConverter.metadata_to_as/1),
|
||||
"draft" => event.draft,
|
||||
# Remove me in MBZ 5.x
|
||||
# TODO: Remove me in MBZ 5.x
|
||||
"ical:status" => event.status |> to_string |> String.upcase(),
|
||||
"status" => event.status |> to_string |> String.upcase(),
|
||||
"id" => event.url,
|
||||
|
@ -154,7 +164,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
"inLanguage" => event.language,
|
||||
"timezone" => event.options.timezone,
|
||||
"contacts" => Enum.map(event.contacts, & &1.url),
|
||||
"isOnline" => event.options.is_online
|
||||
"isOnline" => event.options.is_online,
|
||||
"summary" => event_summary(event)
|
||||
}
|
||||
|> maybe_add_physical_address(event)
|
||||
|> maybe_add_event_picture(event)
|
||||
|
@ -216,7 +227,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
|
||||
defp get_metdata(_), do: []
|
||||
|
||||
defp get_visibility(object), do: if(@ap_public in object["to"], do: :public, else: :unlisted)
|
||||
defp get_visibility(object),
|
||||
do: if(visibility_public?(object["to"]), do: :public, else: :unlisted)
|
||||
|
||||
@spec date_to_string(DateTime.t() | nil) :: String.t()
|
||||
defp date_to_string(nil), do: nil
|
||||
|
@ -341,4 +353,47 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Event do
|
|||
_participant_count
|
||||
),
|
||||
do: nil
|
||||
|
||||
def event_summary(%EventModel{
|
||||
begins_on: begins_on,
|
||||
physical_address: address,
|
||||
options: %EventOptions{timezone: timezone},
|
||||
language: language
|
||||
}) do
|
||||
begins_on = build_begins_on(begins_on, timezone)
|
||||
|
||||
begins_on
|
||||
|> datetime_to_string(language || "en", :long)
|
||||
|> (&[&1]).()
|
||||
|> add_timezone(begins_on)
|
||||
|> maybe_build_address(address)
|
||||
|> Enum.join(" - ")
|
||||
end
|
||||
|
||||
@spec build_begins_on(DateTime.t(), String.t() | nil) :: DateTime.t()
|
||||
defp build_begins_on(begins_on, nil), do: begins_on
|
||||
|
||||
defp build_begins_on(begins_on, timezone) do
|
||||
case DateTime.shift_zone(begins_on, timezone) do
|
||||
{:ok, begins_on} -> begins_on
|
||||
{:error, _err} -> begins_on
|
||||
end
|
||||
end
|
||||
|
||||
defp add_timezone(elements, %DateTime{} = begins_on) do
|
||||
elements ++ [Formatter.zone_gmt(begins_on)]
|
||||
end
|
||||
|
||||
@spec maybe_build_address(list(String.t()), Address.t() | nil) :: list(String.t())
|
||||
defp maybe_build_address(elements, %Address{} = address) do
|
||||
elements ++ [render_address!(address)]
|
||||
rescue
|
||||
# If the address is not renderable
|
||||
e in ArgumentError ->
|
||||
require Logger
|
||||
Logger.error(Exception.format(:error, e, __STACKTRACE__))
|
||||
elements
|
||||
end
|
||||
|
||||
defp maybe_build_address(elements, _address), do: elements
|
||||
end
|
||||
|
|
|
@ -9,13 +9,9 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Media do
|
|||
alias Mobilizon.Federation.ActivityStream
|
||||
alias Mobilizon.Medias
|
||||
alias Mobilizon.Medias.Media, as: MediaModel
|
||||
|
||||
alias Mobilizon.Service.HTTP.RemoteMediaDownloaderClient
|
||||
alias Mobilizon.Web.Upload
|
||||
|
||||
@http_options [
|
||||
ssl: [{:versions, [:"tlsv1.2"]}]
|
||||
]
|
||||
|
||||
@doc """
|
||||
Convert a media struct to an ActivityStream representation.
|
||||
"""
|
||||
|
@ -65,7 +61,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Media do
|
|||
defp upload_media(media_url, ""), do: upload_media(media_url, "unknown")
|
||||
|
||||
defp upload_media(media_url, name) do
|
||||
case Tesla.get(media_url, opts: @http_options) do
|
||||
case RemoteMediaDownloaderClient.get(media_url) do
|
||||
{:ok, %{body: body}} ->
|
||||
case Upload.store(%{body: body, name: name}) do
|
||||
{:ok, %{url: _url} = uploaded} ->
|
||||
|
|
|
@ -15,7 +15,8 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Post do
|
|||
|
||||
import Mobilizon.Federation.ActivityStream.Converter.Utils,
|
||||
only: [
|
||||
process_pictures: 2
|
||||
process_pictures: 2,
|
||||
visibility_public?: 1
|
||||
]
|
||||
|
||||
import Mobilizon.Service.Guards, only: [is_valid_string: 1]
|
||||
|
@ -134,14 +135,12 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Post do
|
|||
)
|
||||
end
|
||||
|
||||
@ap_public "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
defp get_visibility(%{"to" => to}, %Actor{
|
||||
followers_url: followers_url,
|
||||
members_url: members_url
|
||||
}) do
|
||||
cond do
|
||||
@ap_public in to -> :public
|
||||
visibility_public?(to) -> :public
|
||||
followers_url in to -> :unlisted
|
||||
members_url in to -> :private
|
||||
end
|
||||
|
|
|
@ -205,9 +205,7 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
|
|||
|
||||
@spec process_pictures(map(), integer()) :: Keyword.t()
|
||||
def process_pictures(object, actor_id) do
|
||||
attachements = Map.get(object, "attachment", [])
|
||||
|
||||
{banner, media_attachements} = get_medias(attachements)
|
||||
{banner, media_attachements} = get_medias(object)
|
||||
|
||||
media_attachements_map =
|
||||
media_attachements
|
||||
|
@ -259,24 +257,46 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
|
|||
do: String.replace(body, old_url, new_url)
|
||||
|
||||
@spec get_medias(list(map())) :: {map(), list(map())}
|
||||
defp get_medias(attachments) do
|
||||
banner = get_banner_picture(attachments)
|
||||
{banner, Enum.filter(attachments, &(&1["type"] == "Document" && &1["url"] != banner["url"]))}
|
||||
def get_medias(object) do
|
||||
banner = get_banner_picture(object)
|
||||
attachments = Map.get(object, "attachment", [])
|
||||
{banner, Enum.filter(attachments, &(valid_banner_media?(&1) && &1["url"] != banner["url"]))}
|
||||
end
|
||||
|
||||
@spec get_banner_picture(list(map())) :: map()
|
||||
defp get_banner_picture(attachments) do
|
||||
# Prefer media with
|
||||
media_with_picture_name =
|
||||
Enum.find(attachments, &(&1["type"] == "Document" && &1["name"] == @banner_picture_name))
|
||||
@spec get_banner_picture(map()) :: map()
|
||||
defp get_banner_picture(object) do
|
||||
attachments = Map.get(object, "attachment", [])
|
||||
image = Map.get(object, "image", %{})
|
||||
|
||||
case media_with_picture_name do
|
||||
# If no banner found, use the first media
|
||||
nil -> Enum.find(attachments, &(&1["type"] == "Document"))
|
||||
media_with_picture_name -> media_with_picture_name
|
||||
media_with_picture_name =
|
||||
Enum.find(attachments, &(valid_banner_media?(&1) && &1["name"] == @banner_picture_name))
|
||||
|
||||
cond do
|
||||
# Check if the "image" key is set and of type "Document" or "Image"
|
||||
is_nil(media_with_picture_name) and valid_banner_media?(image) ->
|
||||
image
|
||||
|
||||
is_nil(media_with_picture_name) and Enum.find(attachments, &valid_banner_media?/1) ->
|
||||
Enum.find(attachments, &valid_banner_media?/1)
|
||||
|
||||
!is_nil(media_with_picture_name) ->
|
||||
media_with_picture_name
|
||||
|
||||
true ->
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@spec valid_banner_media?(map()) :: boolean()
|
||||
defp valid_banner_media?(media) do
|
||||
media |> Map.get("type") |> valid_attachment_type?()
|
||||
end
|
||||
|
||||
@spec valid_attachment_type?(any()) :: boolean()
|
||||
defp valid_attachment_type?(type) do
|
||||
type in ["Document", "Image"]
|
||||
end
|
||||
|
||||
@spec get_address(map | binary | nil) :: Address.t() | nil
|
||||
def get_address(text_address) when is_binary(text_address) do
|
||||
get_address(%{"type" => "Place", "name" => text_address})
|
||||
|
@ -315,4 +335,13 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do
|
|||
nil
|
||||
end
|
||||
end
|
||||
|
||||
@ap_public "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
@spec visibility_public?(String.t() | list(String.t())) :: boolean()
|
||||
def visibility_public?(to) when is_binary(to), do: visibility_public?([to])
|
||||
|
||||
def visibility_public?(to) when is_list(to) do
|
||||
!MapSet.disjoint?(MapSet.new(to), MapSet.new([@ap_public, "as:Public", "Public"]))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,15 +57,25 @@ defmodule Mobilizon.GraphQL.API.Events do
|
|||
defp process_picture(%{media_id: _picture_id} = args, _), do: args
|
||||
|
||||
defp process_picture(%{media: media}, %Actor{id: actor_id}) do
|
||||
with uploaded when is_map(uploaded) <-
|
||||
media
|
||||
|> Map.get(:file)
|
||||
|> Utils.make_media_data(description: Map.get(media, :name)) do
|
||||
# case url
|
||||
if Map.has_key?(media, :url) do
|
||||
%{
|
||||
file: Map.take(uploaded, [:url, :name, :content_type, :size]),
|
||||
metadata: Map.take(uploaded, [:width, :height, :blurhash]),
|
||||
file: %{"url" => media.url, "name" => media.name},
|
||||
actor_id: actor_id
|
||||
}
|
||||
|
||||
# case upload
|
||||
else
|
||||
with uploaded when is_map(uploaded) <-
|
||||
media
|
||||
|> Map.get(:file)
|
||||
|> Utils.make_media_data(description: Map.get(media, :name)) do
|
||||
%{
|
||||
file: Map.take(uploaded, [:url, :name, :content_type, :size]),
|
||||
metadata: Map.take(uploaded, [:width, :height, :blurhash]),
|
||||
actor_id: actor_id
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -56,7 +56,8 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
minimum_visibility: Map.get(args, :minimum_visibility, :public),
|
||||
current_actor_id: Map.get(args, :current_actor_id),
|
||||
exclude_my_groups: Map.get(args, :exclude_my_groups, false),
|
||||
exclude_stale_actors: true
|
||||
exclude_stale_actors: true,
|
||||
local_only: Map.get(args, :search_target, :internal) == :self
|
||||
],
|
||||
page,
|
||||
limit
|
||||
|
@ -94,7 +95,13 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||
|
||||
{:ok, service.search_events(Keyword.new(args, fn {k, v} -> {k, v} end))}
|
||||
else
|
||||
{:ok, Events.build_events_for_search(Map.put(args, :term, term), page, limit)}
|
||||
results =
|
||||
args
|
||||
|> Map.put(:term, term)
|
||||
|> Map.put(:local_only, Map.get(args, :search_target, :internal) == :self)
|
||||
|> Events.build_events_for_search(page, limit)
|
||||
|
||||
{:ok, results}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,11 +5,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||
|
||||
import Mobilizon.Users.Guards
|
||||
|
||||
alias Mobilizon.{Actors, Admin, Config, Events, Instances, Users}
|
||||
alias Mobilizon.{Actors, Admin, Config, Events, Instances, Media, Users}
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mobilizon.Admin.{ActionLog, Setting}
|
||||
alias Mobilizon.Admin.{ActionLog, Setting, SettingMedia}
|
||||
alias Mobilizon.Cldr.Language
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Federation.ActivityPub.{Actions, Relay}
|
||||
|
@ -20,6 +19,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||
alias Mobilizon.Storage.Page
|
||||
alias Mobilizon.Users.User
|
||||
alias Mobilizon.Web.Email
|
||||
|
||||
alias Mobilizon.GraphQL.Resolvers.Media, as: MediaResolver
|
||||
|
||||
import Mobilizon.Web.Gettext
|
||||
require Logger
|
||||
|
||||
|
@ -268,8 +270,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||
with {:ok, res} <- Admin.save_settings("instance", args),
|
||||
res <-
|
||||
res
|
||||
|> Enum.map(fn {key, %Setting{value: value}} ->
|
||||
{key, Admin.get_setting_value(value)}
|
||||
|> Enum.map(fn {key, val} ->
|
||||
case val do
|
||||
%Setting{value: value} -> {key, Admin.get_setting_value(value)}
|
||||
%SettingMedia{media: media} -> {key, media}
|
||||
end
|
||||
end)
|
||||
|> Enum.into(%{}),
|
||||
:ok <- eventually_update_instance_actor(res) do
|
||||
|
@ -284,6 +289,38 @@ defmodule Mobilizon.GraphQL.Resolvers.Admin do
|
|||
dgettext("errors", "You need to be logged-in and an administrator to save admin settings")}
|
||||
end
|
||||
|
||||
@spec get_media_setting(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Media.t()} | {:error, String.t()}
|
||||
def get_media_setting(_parent, %{group: group, name: name}, %{
|
||||
context: %{current_user: %User{role: role}}
|
||||
})
|
||||
when is_admin(role) do
|
||||
{:ok, MediaResolver.transform_media(Admin.get_admin_setting_media(group, name, nil))}
|
||||
end
|
||||
|
||||
def get_media_setting(_parent, _args, _resolution) do
|
||||
{:error,
|
||||
dgettext("errors", "You need to be logged-in and an administrator to access admin settings")}
|
||||
end
|
||||
|
||||
@spec get_instance_logo(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Media.t() | nil} | {:error, String.t()}
|
||||
def get_instance_logo(parent, _args, resolution) do
|
||||
get_media_setting(parent, %{group: "instance", name: "instance_logo"}, resolution)
|
||||
end
|
||||
|
||||
@spec get_instance_favicon(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Media.t() | nil} | {:error, String.t()}
|
||||
def get_instance_favicon(parent, _args, resolution) do
|
||||
get_media_setting(parent, %{group: "instance", name: "instance_favicon"}, resolution)
|
||||
end
|
||||
|
||||
@spec get_default_picture(any(), any(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Media.t() | nil} | {:error, String.t()}
|
||||
def get_default_picture(parent, _args, resolution) do
|
||||
get_media_setting(parent, %{group: "instance", name: "default_picture"}, resolution)
|
||||
end
|
||||
|
||||
@spec update_user(any, map(), Absinthe.Resolution.t()) ::
|
||||
{:error, :invalid_argument | :user_not_found | binary | Ecto.Changeset.t()}
|
||||
| {:ok, Mobilizon.Users.User.t()}
|
||||
|
|
|
@ -5,8 +5,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
|||
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Events.Categories
|
||||
alias Mobilizon.Medias.Media
|
||||
alias Mobilizon.Service.{AntiSpam, FrontEndAnalytics}
|
||||
|
||||
alias Mobilizon.GraphQL.Resolvers.Media, as: MediaResolver
|
||||
|
||||
@doc """
|
||||
Gets config.
|
||||
"""
|
||||
|
@ -31,6 +34,16 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
|||
{:ok, data}
|
||||
end
|
||||
|
||||
@spec instance_logo(any(), map(), Absinthe.Resolution.t()) :: {:ok, Media.t()}
|
||||
def instance_logo(_parent, _params, _resolution) do
|
||||
{:ok, MediaResolver.transform_media(Config.instance_logo())}
|
||||
end
|
||||
|
||||
@spec default_picture(any(), map(), Absinthe.Resolution.t()) :: {:ok, Media.t()}
|
||||
def default_picture(_parent, _params, _resolution) do
|
||||
{:ok, MediaResolver.transform_media(Config.default_picture())}
|
||||
end
|
||||
|
||||
@spec terms(any(), map(), Absinthe.Resolution.t()) :: {:ok, map()}
|
||||
def terms(_parent, %{locale: locale}, _resolution) do
|
||||
type = Config.instance_terms_type()
|
||||
|
@ -94,10 +107,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Config do
|
|||
registrations_allowlist: Config.instance_registrations_allowlist?(),
|
||||
contact: Config.contact(),
|
||||
demo_mode: Config.instance_demo_mode?(),
|
||||
long_events: Config.instance_long_events?(),
|
||||
description: Config.instance_description(),
|
||||
long_description: Config.instance_long_description(),
|
||||
slogan: Config.instance_slogan(),
|
||||
languages: Config.instance_languages(),
|
||||
instance_logo: Config.instance_logo(),
|
||||
primary_color: Config.primary_color(),
|
||||
secondary_color: Config.secondary_color(),
|
||||
default_picture: Config.default_picture(),
|
||||
anonymous: %{
|
||||
participation: %{
|
||||
allowed: Config.anonymous_participation?(),
|
||||
|
|
|
@ -156,6 +156,9 @@ defmodule Mobilizon.GraphQL.Resolvers.Conversation do
|
|||
|
||||
{:ok, conversation_to_view(conversation, conversation_participant_actor)}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:error, changeset}
|
||||
|
||||
{:error, :empty_participants} ->
|
||||
{:error,
|
||||
dgettext(
|
||||
|
|
|
@ -69,13 +69,31 @@ defmodule Mobilizon.GraphQL.Resolvers.Event do
|
|||
|
||||
@spec list_events(any(), map(), Absinthe.Resolution.t()) ::
|
||||
{:ok, Page.t(Event.t())} | {:error, :events_max_limit_reached}
|
||||
def list_events(
|
||||
_parent,
|
||||
%{
|
||||
page: page,
|
||||
limit: limit,
|
||||
order_by: order_by,
|
||||
direction: direction,
|
||||
longevents: longevents,
|
||||
location: location,
|
||||
radius: radius
|
||||
},
|
||||
_resolution
|
||||
)
|
||||
when limit < @event_max_limit do
|
||||
{:ok,
|
||||
Events.list_events(page, limit, order_by, direction, true, longevents, location, radius)}
|
||||
end
|
||||
|
||||
def list_events(
|
||||
_parent,
|
||||
%{page: page, limit: limit, order_by: order_by, direction: direction},
|
||||
_resolution
|
||||
)
|
||||
when limit < @event_max_limit do
|
||||
{:ok, Events.list_events(page, limit, order_by, direction)}
|
||||
{:ok, Events.list_events(page, limit, order_by, direction, true)}
|
||||
end
|
||||
|
||||
def list_events(_parent, %{page: _page, limit: _limit}, _resolution) do
|
||||
|
|
|
@ -18,6 +18,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Media do
|
|||
do_fetch_media(media_id)
|
||||
end
|
||||
|
||||
def media(%{media_id: media_id} = _parent, _args, _resolution) do
|
||||
do_fetch_media(media_id)
|
||||
end
|
||||
|
||||
def media(%{picture: media} = _parent, _args, _resolution), do: {:ok, media}
|
||||
def media(_parent, %{id: media_id}, _resolution), do: do_fetch_media(media_id)
|
||||
def media(_parent, _args, _resolution), do: {:ok, nil}
|
||||
|
@ -133,8 +137,10 @@ defmodule Mobilizon.GraphQL.Resolvers.Media do
|
|||
|
||||
def user_size(_parent, _args, _resolution), do: {:error, :unauthenticated}
|
||||
|
||||
@spec transform_media(Media.t()) :: map()
|
||||
defp transform_media(%Media{id: id, file: file, metadata: metadata}) do
|
||||
@spec transform_media(Media.t() | nil) :: map() | nil
|
||||
def transform_media(nil), do: nil
|
||||
|
||||
def transform_media(%Media{id: id, file: file, metadata: metadata}) do
|
||||
%{
|
||||
name: file.name,
|
||||
url: file.url,
|
||||
|
|
|
@ -381,10 +381,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Participant do
|
|||
visibility: :private
|
||||
})
|
||||
|
||||
with {:member, true} <-
|
||||
with {:ok,
|
||||
%Event{organizer_actor_id: organizer_actor_id, attributed_to_id: attributed_to_id} =
|
||||
_event} <- Mobilizon.Events.get_event(event_id),
|
||||
{:member, true} <-
|
||||
{:member,
|
||||
to_string(current_actor_id) == to_string(actor_id) or
|
||||
Actors.member?(current_actor_id, actor_id)},
|
||||
(to_string(current_actor_id) == to_string(organizer_actor_id) and
|
||||
to_string(current_actor_id) == to_string(actor_id)) or
|
||||
(!is_nil(attributed_to_id) and Actors.member?(current_actor_id, attributed_to_id) and
|
||||
to_string(attributed_to_id) == to_string(actor_id))},
|
||||
{:ok, _activity, %Conversation{} = conversation} <- Comments.create_conversation(args) do
|
||||
{:ok, conversation_to_view(conversation, Actors.get_actor(actor_id))}
|
||||
else
|
||||
|
|
|
@ -124,6 +124,24 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||
field(:instance_terms_type, :instance_terms_type, description: "The instance's terms type")
|
||||
field(:instance_terms_url, :string, description: "The instance's terms URL")
|
||||
|
||||
field(:instance_logo, :media,
|
||||
description: "The instance's logo",
|
||||
resolve: &Admin.get_instance_logo/3
|
||||
)
|
||||
|
||||
field(:instance_favicon, :media,
|
||||
description: "The instance's favicon",
|
||||
resolve: &Admin.get_instance_favicon/3
|
||||
)
|
||||
|
||||
field(:default_picture, :media,
|
||||
description: "The default picture",
|
||||
resolve: &Admin.get_default_picture/3
|
||||
)
|
||||
|
||||
field(:primary_color, :string, description: "The instance's primary color")
|
||||
field(:secondary_color, :string, description: "The instance's secondary color")
|
||||
|
||||
field(:instance_privacy_policy, :string,
|
||||
description: "The instance's privacy policy body text"
|
||||
)
|
||||
|
@ -412,6 +430,25 @@ defmodule Mobilizon.GraphQL.Schema.AdminType do
|
|||
arg(:instance_long_description, :string, description: "The instance's long description")
|
||||
arg(:instance_slogan, :string, description: "The instance's slogan")
|
||||
arg(:contact, :string, description: "The instance's contact details")
|
||||
|
||||
arg(:instance_logo, :media_input,
|
||||
description:
|
||||
"The instance's logo, either as an object or directly the ID of an existing media"
|
||||
)
|
||||
|
||||
arg(:instance_favicon, :media_input,
|
||||
description:
|
||||
"The instance's favicon, either as an object or directly the ID of an existing media"
|
||||
)
|
||||
|
||||
arg(:default_picture, :media_input,
|
||||
description:
|
||||
"The default picture, either as an object or directly the ID of an existing media"
|
||||
)
|
||||
|
||||
arg(:primary_color, :string, description: "The instance's primary color")
|
||||
arg(:secondary_color, :string, description: "The instance's secondary color")
|
||||
|
||||
arg(:instance_terms, :string, description: "The instance's terms body text")
|
||||
arg(:instance_terms_type, :instance_terms_type, description: "The instance's terms type")
|
||||
arg(:instance_terms_url, :string, description: "The instance's terms URL")
|
||||
|
|
|
@ -31,6 +31,7 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
|
|||
)
|
||||
|
||||
field(:demo_mode, :boolean, description: "Whether the demo mode is enabled")
|
||||
field(:long_events, :boolean, description: "Whether the long events mode is enabled")
|
||||
field(:country_code, :string, description: "The country code from the IP")
|
||||
field(:location, :lonlat, description: "The IP's location")
|
||||
field(:geocoding, :geocoding, description: "The instance's geocoding settings")
|
||||
|
@ -59,6 +60,17 @@ defmodule Mobilizon.GraphQL.Schema.ConfigType do
|
|||
resolve(&Config.terms/3)
|
||||
end
|
||||
|
||||
field(:instance_logo, :media, description: "The instance's logo") do
|
||||
resolve(&Config.instance_logo/3)
|
||||
end
|
||||
|
||||
field(:default_picture, :media, description: "The default picture") do
|
||||
resolve(&Config.default_picture/3)
|
||||
end
|
||||
|
||||
field(:primary_color, :string, description: "The instance's primary color")
|
||||
field(:secondary_color, :string, description: "The instance's secondary color")
|
||||
|
||||
field(:privacy, :privacy, description: "The instance's privacy policy") do
|
||||
arg(:locale, :string,
|
||||
default_value: "en",
|
||||
|
|
|
@ -20,6 +20,7 @@ defmodule Mobilizon.GraphQL.Schema.ConversationType do
|
|||
)
|
||||
|
||||
field(:last_comment, :comment, description: "The last comment of the conversation")
|
||||
field(:origin_comment, :comment, description: "The first comment of the conversation")
|
||||
|
||||
field :comments, :paginated_comment_list do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
|
|||
"""
|
||||
use Absinthe.Schema.Notation
|
||||
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1, dataloader: 2]
|
||||
|
||||
alias Mobilizon.{Actors, Discussions, Events}
|
||||
alias Mobilizon.GraphQL.Resolvers.Comment
|
||||
|
@ -23,7 +23,7 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
|
|||
|
||||
field(:replies, list_of(:comment)) do
|
||||
description("A list of replies to the comment")
|
||||
resolve(dataloader(Discussions))
|
||||
resolve(dataloader(Discussions, args: %{replies: true}))
|
||||
end
|
||||
|
||||
field(:total_replies, :integer,
|
||||
|
@ -47,6 +47,12 @@ defmodule Mobilizon.GraphQL.Schema.Discussions.CommentType do
|
|||
|
||||
field(:threadLanguages, non_null(list_of(:string)), description: "The thread languages")
|
||||
field(:actor, :person, resolve: dataloader(Actors), description: "The comment's author")
|
||||
|
||||
field(:attributed_to, :actor,
|
||||
resolve: dataloader(Actors),
|
||||
description: "The comment's attributed to actor"
|
||||
)
|
||||
|
||||
field(:inserted_at, :datetime, description: "When was the comment inserted in database")
|
||||
field(:updated_at, :datetime, description: "When was the comment updated")
|
||||
field(:deleted_at, :datetime, description: "When was the comment deleted")
|
||||
|
|
|
@ -263,6 +263,10 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
|||
description: "Whether or not to show the participation price"
|
||||
)
|
||||
|
||||
field(:hide_number_of_participants, :boolean,
|
||||
description: "Whether or not the number of participants is hidden"
|
||||
)
|
||||
|
||||
field(:show_start_time, :boolean, description: "Show event start time")
|
||||
field(:show_end_time, :boolean, description: "Show event end time")
|
||||
|
||||
|
@ -316,6 +320,10 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
|||
description: "Whether or not to show the participation price"
|
||||
)
|
||||
|
||||
field(:hide_number_of_participants, :boolean,
|
||||
description: "Whether or not the number of participants is hidden"
|
||||
)
|
||||
|
||||
field(:show_start_time, :boolean, description: "Show event start time")
|
||||
field(:show_end_time, :boolean, description: "Show event end time")
|
||||
|
||||
|
@ -367,6 +375,13 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
|||
object :event_queries do
|
||||
@desc "Get all events"
|
||||
field :events, :paginated_event_list do
|
||||
arg(:location, :string, default_value: nil, description: "A geohash for coordinates")
|
||||
|
||||
arg(:radius, :float,
|
||||
default_value: nil,
|
||||
description: "Radius around the location to search in"
|
||||
)
|
||||
|
||||
arg(:page, :integer, default_value: 1, description: "The page in the paginated event list")
|
||||
arg(:limit, :integer, default_value: 10, description: "The limit of events per page")
|
||||
|
||||
|
@ -380,6 +395,11 @@ defmodule Mobilizon.GraphQL.Schema.EventType do
|
|||
description: "Direction for the sort"
|
||||
)
|
||||
|
||||
arg(:longevents, :boolean,
|
||||
default_value: nil,
|
||||
description: "if mention filter in or out long events"
|
||||
)
|
||||
|
||||
middleware(Rajska.QueryAuthorization, permit: :all)
|
||||
|
||||
resolve(&Event.list_events/3)
|
||||
|
|
|
@ -52,8 +52,9 @@ defmodule Mobilizon.GraphQL.Schema.MediaType do
|
|||
input_object :media_input_object do
|
||||
field(:name, non_null(:string), description: "The media's name")
|
||||
field(:alt, :string, description: "The media's alternative text")
|
||||
field(:file, non_null(:upload), description: "The media file")
|
||||
field(:file, :upload, description: "The media file")
|
||||
field(:actor_id, :id, description: "The media owner")
|
||||
field(:url, :string, description: "The media URL")
|
||||
end
|
||||
|
||||
object :media_queries do
|
||||
|
|
|
@ -160,6 +160,8 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
|
|||
end
|
||||
|
||||
enum :search_target do
|
||||
value(:self, description: "Search only on content from this instance")
|
||||
|
||||
value(:internal,
|
||||
description: "Search on content from this instance and from the followed instances"
|
||||
)
|
||||
|
@ -271,6 +273,8 @@ defmodule Mobilizon.GraphQL.Schema.SearchType do
|
|||
description: "Radius around the location to search in"
|
||||
)
|
||||
|
||||
arg(:longevents, :boolean, description: "if mention filter in or out long events")
|
||||
|
||||
arg(:bbox, :string, description: "The bbox to search events into")
|
||||
arg(:zoom, :integer, description: "The zoom level for searching events")
|
||||
|
||||
|
|
|
@ -85,7 +85,9 @@ defmodule Mobilizon do
|
|||
ErrorReporting.attach()
|
||||
end
|
||||
|
||||
Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor)
|
||||
with :ok <- load_certificates() do
|
||||
Supervisor.start_link(children, strategy: :one_for_one, name: Mobilizon.Supervisor)
|
||||
end
|
||||
end
|
||||
|
||||
@spec config_change(keyword, keyword, [atom]) :: :ok
|
||||
|
@ -160,4 +162,16 @@ defmodule Mobilizon do
|
|||
end
|
||||
|
||||
defp setup_ecto_dev_logger(_), do: nil
|
||||
|
||||
defp load_certificates do
|
||||
custom_cert_path = System.get_env("MOBILIZON_CA_CERT_PATH")
|
||||
|
||||
if is_binary(custom_cert_path) do
|
||||
with :ok <- :tls_certificate_check.override_trusted_authorities({:file, custom_cert_path}) do
|
||||
:public_key.cacerts_load(custom_cert_path)
|
||||
end
|
||||
else
|
||||
:ok
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -525,6 +525,7 @@ defmodule Mobilizon.Actors do
|
|||
Keyword.get(options, :radius),
|
||||
Keyword.get(options, :bbox)
|
||||
)
|
||||
|> filter_by_local_only(Keyword.get(options, :local_only, false))
|
||||
|> actors_for_location(Keyword.get(options, :location), Keyword.get(options, :radius))
|
||||
|> events_for_bounding_box(Keyword.get(options, :bbox))
|
||||
|> filter_by_type(Keyword.get(options, :actor_type, :Group))
|
||||
|
@ -1418,6 +1419,13 @@ defmodule Mobilizon.Actors do
|
|||
|
||||
defp maybe_join_address(query, _location, _radius, _bbox), do: query
|
||||
|
||||
@spec filter_by_local_only(Ecto.Queryable.t(), boolean()) :: Ecto.Query.t()
|
||||
defp filter_by_local_only(query, true) do
|
||||
where(query, [q], is_nil(q.domain))
|
||||
end
|
||||
|
||||
defp filter_by_local_only(query, false), do: query
|
||||
|
||||
@spec actors_for_location(Ecto.Queryable.t(), String.t(), integer()) :: Ecto.Query.t()
|
||||
defp actors_for_location(query, location, radius)
|
||||
when is_valid_string(location) and not is_nil(radius) do
|
||||
|
|
|
@ -9,7 +9,8 @@ defmodule Mobilizon.Admin do
|
|||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.{Admin, Users}
|
||||
alias Mobilizon.Admin.ActionLog
|
||||
alias Mobilizon.Admin.Setting
|
||||
alias Mobilizon.Admin.{Setting, SettingMedia}
|
||||
alias Mobilizon.Medias.Media
|
||||
alias Mobilizon.Storage.{Page, Repo}
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
|
@ -78,9 +79,47 @@ defmodule Mobilizon.Admin do
|
|||
|
||||
defp stringify_struct(struct), do: struct
|
||||
|
||||
@spec get_all_admin_settings :: list(Setting.t())
|
||||
@spec get_all_admin_settings :: map()
|
||||
def get_all_admin_settings do
|
||||
Repo.all(Setting)
|
||||
medias =
|
||||
SettingMedia
|
||||
|> Repo.all()
|
||||
|> Repo.preload(:media)
|
||||
|> Enum.map(fn %SettingMedia{group: group, name: name, media: media} ->
|
||||
{group, name, media}
|
||||
end)
|
||||
|
||||
values =
|
||||
Setting
|
||||
|> Repo.all()
|
||||
|> Enum.map(fn %Setting{group: group, name: name, value: value} ->
|
||||
{group, name, get_setting_value(value)}
|
||||
end)
|
||||
|
||||
all_settings = Enum.concat(values, medias)
|
||||
|
||||
Enum.reduce(
|
||||
all_settings,
|
||||
%{},
|
||||
# For each {group,name,value}
|
||||
fn {group, name, value}, acc ->
|
||||
# We update the %{group: map} in the accumulator
|
||||
{_, new_acc} =
|
||||
Map.get_and_update(
|
||||
acc,
|
||||
group,
|
||||
# We put the %{name: value} into the %{group: map}
|
||||
fn group_map ->
|
||||
{
|
||||
group_map,
|
||||
Map.put(group_map || %{}, name, value)
|
||||
}
|
||||
end
|
||||
)
|
||||
|
||||
new_acc
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
@spec get_admin_setting_value(String.t(), String.t(), String.t() | nil) ::
|
||||
|
@ -119,21 +158,40 @@ defmodule Mobilizon.Admin do
|
|||
end
|
||||
end
|
||||
|
||||
@spec get_admin_setting_media(String.t(), String.t(), String.t() | nil) ::
|
||||
{:ok, Media.t()} | {:error, :not_found} | nil
|
||||
def get_admin_setting_media(group, name, fallback \\ nil)
|
||||
when is_binary(group) and is_binary(name) do
|
||||
case SettingMedia
|
||||
|> where(group: ^group)
|
||||
|> where(name: ^name)
|
||||
|> preload(:media)
|
||||
|> Repo.one() do
|
||||
nil ->
|
||||
fallback
|
||||
|
||||
%SettingMedia{media: media} ->
|
||||
media
|
||||
|
||||
%SettingMedia{} ->
|
||||
fallback
|
||||
end
|
||||
end
|
||||
|
||||
@spec save_settings(String.t(), map()) :: {:ok, any} | {:error, any}
|
||||
def save_settings(group, args) do
|
||||
{medias, values} = Map.split(args, [:instance_logo, :instance_favicon, :default_picture])
|
||||
|
||||
Multi.new()
|
||||
|> do_save_setting(group, args)
|
||||
|> do_save_media_setting(group, medias)
|
||||
|> do_save_value_setting(group, values)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
def clear_settings(group) do
|
||||
Setting |> where([s], s.group == ^group) |> Repo.delete_all()
|
||||
end
|
||||
@spec do_save_value_setting(Ecto.Multi.t(), String.t(), map()) :: Ecto.Multi.t()
|
||||
defp do_save_value_setting(transaction, _group, args) when args == %{}, do: transaction
|
||||
|
||||
@spec do_save_setting(Ecto.Multi.t(), String.t(), map()) :: Ecto.Multi.t()
|
||||
defp do_save_setting(transaction, _group, args) when args == %{}, do: transaction
|
||||
|
||||
defp do_save_setting(transaction, group, args) do
|
||||
defp do_save_value_setting(transaction, group, args) do
|
||||
key = hd(Map.keys(args))
|
||||
{val, rest} = Map.pop(args, key)
|
||||
|
||||
|
@ -150,7 +208,40 @@ defmodule Mobilizon.Admin do
|
|||
conflict_target: [:group, :name]
|
||||
)
|
||||
|
||||
do_save_setting(transaction, group, rest)
|
||||
do_save_value_setting(transaction, group, rest)
|
||||
end
|
||||
|
||||
@spec do_save_media_setting(Ecto.Multi.t(), String.t(), map()) :: Ecto.Multi.t()
|
||||
defp do_save_media_setting(transaction, _group, args) when args == %{}, do: transaction
|
||||
|
||||
defp do_save_media_setting(transaction, group, args) do
|
||||
key = hd(Map.keys(args))
|
||||
{val, rest} = Map.pop(args, key)
|
||||
|
||||
transaction =
|
||||
case val do
|
||||
val ->
|
||||
Multi.insert(
|
||||
transaction,
|
||||
key,
|
||||
SettingMedia.changeset(%SettingMedia{}, %{
|
||||
group: group,
|
||||
name: Atom.to_string(key),
|
||||
media: val
|
||||
}),
|
||||
on_conflict: :replace_all,
|
||||
conflict_target: [:group, :name]
|
||||
)
|
||||
end
|
||||
|
||||
do_save_media_setting(transaction, group, rest)
|
||||
end
|
||||
|
||||
def clear_settings(group) do
|
||||
Multi.new()
|
||||
|> Multi.delete_all(:settings, Setting |> where([s], s.group == ^group))
|
||||
|> Multi.delete_all(:settings_medias, SettingMedia |> where([s], s.group == ^group))
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
@spec convert_to_string(any()) :: String.t()
|
||||
|
|
|
@ -4,6 +4,7 @@ defmodule Mobilizon.Admin.Setting do
|
|||
"""
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Ecto.Changeset
|
||||
|
||||
@required_attrs [:group, :name]
|
||||
@optional_attrs [:value]
|
||||
|
@ -32,3 +33,93 @@ defmodule Mobilizon.Admin.Setting do
|
|||
|> unique_constraint(:group, name: :admin_settings_group_name_index)
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Mobilizon.Admin.SettingMedia do
|
||||
@moduledoc """
|
||||
A Key-Value settings table for media settings
|
||||
"""
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Ecto.Changeset
|
||||
alias Mobilizon.Federation.ActivityPub.Relay
|
||||
alias Mobilizon.Medias
|
||||
alias Mobilizon.Medias.Media
|
||||
alias Mobilizon.Storage.Repo
|
||||
|
||||
@required_attrs [:group, :name]
|
||||
|
||||
@type t :: %{
|
||||
group: String.t(),
|
||||
name: String.t(),
|
||||
media: Media.t()
|
||||
}
|
||||
|
||||
schema "admin_settings_medias" do
|
||||
field(:group, :string)
|
||||
field(:name, :string)
|
||||
belongs_to(:media, Media, on_replace: :delete)
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(setting_media, attrs) do
|
||||
setting_media
|
||||
|> Repo.preload(:media)
|
||||
|> cast(attrs, @required_attrs)
|
||||
|> put_media(attrs)
|
||||
|> validate_required(@required_attrs)
|
||||
|> unique_constraint(:group, name: :admin_settings_medias_group_name_index)
|
||||
end
|
||||
|
||||
# # In case the provided media is an existing one
|
||||
@spec put_media(Changeset.t(), map) :: Changeset.t()
|
||||
defp put_media(%Changeset{} = changeset, %{media: %{media_id: id}}) do
|
||||
%Media{} = media = Medias.get_media!(id)
|
||||
put_assoc(changeset, :media, media)
|
||||
end
|
||||
|
||||
# In case it's a new media
|
||||
defp put_media(%Changeset{} = changeset, %{media: %{media: media}}) do
|
||||
{:ok, media} = upload_media(media)
|
||||
put_assoc(changeset, :media, media)
|
||||
end
|
||||
|
||||
# In case there is no media
|
||||
defp put_media(%Changeset{} = changeset, _media) do
|
||||
put_assoc(changeset, :media, nil)
|
||||
end
|
||||
|
||||
import Mobilizon.Web.Gettext
|
||||
@spec upload_media(map) :: {:ok, Media.t()} | {:error, any}
|
||||
defp upload_media(%{file: %Plug.Upload{} = file} = args) do
|
||||
with {:ok,
|
||||
%{
|
||||
name: _name,
|
||||
url: url,
|
||||
content_type: content_type,
|
||||
size: size
|
||||
} = uploaded} <-
|
||||
Mobilizon.Web.Upload.store(file),
|
||||
args <-
|
||||
args
|
||||
|> Map.put(:url, url)
|
||||
|> Map.put(:size, size)
|
||||
|> Map.put(:content_type, content_type),
|
||||
{:ok, media = %Media{}} <-
|
||||
Medias.create_media(%{
|
||||
file: args,
|
||||
actor_id: Map.get(args, :actor_id, Relay.get_actor().id),
|
||||
metadata: Map.take(uploaded, [:width, :height, :blurhash])
|
||||
}) do
|
||||
{:ok, media}
|
||||
else
|
||||
{:error, :mime_type_not_allowed} ->
|
||||
{:error, dgettext("errors", "File doesn't have an allowed MIME type.")}
|
||||
|
||||
error ->
|
||||
{:error, error}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,8 @@ defmodule Mobilizon.Config do
|
|||
"""
|
||||
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Admin.Setting
|
||||
alias Mobilizon.Admin
|
||||
alias Mobilizon.Medias.Media
|
||||
alias Mobilizon.Service.GitStatus
|
||||
require Logger
|
||||
import Mobilizon.Service.Export.Participants.Common, only: [enabled_formats: 0]
|
||||
|
@ -30,56 +31,18 @@ defmodule Mobilizon.Config do
|
|||
@spec instance_config :: mobilizon_config
|
||||
def instance_config, do: Application.get_env(:mobilizon, :instance)
|
||||
|
||||
@spec db_instance_config :: list(Setting.t())
|
||||
def db_instance_config, do: Mobilizon.Admin.get_all_admin_settings()
|
||||
|
||||
@spec config_cache :: map()
|
||||
def config_cache do
|
||||
case Cachex.fetch(:config, :all_db_config, fn _key ->
|
||||
value =
|
||||
Enum.reduce(
|
||||
Mobilizon.Admin.get_all_admin_settings(),
|
||||
%{},
|
||||
&arrange_values/2
|
||||
)
|
||||
|
||||
{:commit, value}
|
||||
end) do
|
||||
case Cachex.fetch(
|
||||
:config,
|
||||
:all_db_config,
|
||||
fn _key -> {:commit, Admin.get_all_admin_settings()} end
|
||||
) do
|
||||
{status, value} when status in [:ok, :commit] -> value
|
||||
_err -> %{}
|
||||
end
|
||||
end
|
||||
|
||||
@spec arrange_values(Setting.t(), map()) :: map()
|
||||
defp arrange_values(setting, acc) do
|
||||
{_, new_data} =
|
||||
Map.get_and_update(acc, setting.group, fn current_value ->
|
||||
new_value = current_value || %{}
|
||||
|
||||
{current_value, Map.put(new_value, setting.name, process_value(setting.value))}
|
||||
end)
|
||||
|
||||
new_data
|
||||
end
|
||||
|
||||
@spec process_value(String.t() | nil) :: any()
|
||||
defp process_value(nil), do: nil
|
||||
defp process_value(""), do: nil
|
||||
|
||||
defp process_value(value) do
|
||||
case Jason.decode(value) do
|
||||
{:ok, val} ->
|
||||
val
|
||||
|
||||
{:error, _} ->
|
||||
case value do
|
||||
"true" -> true
|
||||
"false" -> false
|
||||
value -> value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@spec config_cached_value(String.t(), String.t(), String.t()) :: any()
|
||||
def config_cached_value(group, name, fallback \\ nil) do
|
||||
config_cache()
|
||||
|
@ -116,10 +79,23 @@ defmodule Mobilizon.Config do
|
|||
@spec instance_slogan :: String.t() | nil
|
||||
def instance_slogan, do: config_cached_value("instance", "instance_slogan")
|
||||
|
||||
@spec instance_logo :: Media.t() | nil
|
||||
def instance_logo, do: config_cached_value("instance", "instance_logo")
|
||||
|
||||
@spec instance_favicon :: Media.t() | nil
|
||||
def instance_favicon, do: config_cached_value("instance", "instance_favicon")
|
||||
|
||||
@spec default_picture :: Media.t() | nil
|
||||
def default_picture, do: config_cached_value("instance", "default_picture")
|
||||
|
||||
@spec primary_color :: Media.t() | nil
|
||||
def primary_color, do: config_cached_value("instance", "primary_color")
|
||||
|
||||
@spec secondary_color :: Media.t() | nil
|
||||
def secondary_color, do: config_cached_value("instance", "secondary_color")
|
||||
|
||||
@spec contact :: String.t() | nil
|
||||
def contact do
|
||||
config_cached_value("instance", "contact")
|
||||
end
|
||||
def contact, do: config_cached_value("instance", "contact")
|
||||
|
||||
@spec instance_terms(String.t()) :: String.t()
|
||||
def instance_terms(locale \\ "en") do
|
||||
|
@ -201,6 +177,9 @@ defmodule Mobilizon.Config do
|
|||
@spec instance_demo_mode? :: boolean
|
||||
def instance_demo_mode?, do: to_boolean(instance_config()[:demo])
|
||||
|
||||
@spec instance_long_events? :: boolean
|
||||
def instance_long_events?, do: instance_config()[:duration_of_long_event] > 0
|
||||
|
||||
@spec instance_repository :: String.t()
|
||||
def instance_repository, do: instance_config()[:repository]
|
||||
|
||||
|
@ -469,6 +448,9 @@ defmodule Mobilizon.Config do
|
|||
instance_slogan: instance_slogan(),
|
||||
registrations_open: instance_registrations_open?(),
|
||||
contact: contact(),
|
||||
primary_color: primary_color(),
|
||||
secondary_color: secondary_color(),
|
||||
instance_logo: instance_logo(),
|
||||
instance_terms: instance_terms(),
|
||||
instance_terms_type: instance_terms_type(),
|
||||
instance_terms_url: instance_terms_url(),
|
||||
|
|
|
@ -104,6 +104,10 @@ defmodule Mobilizon.Conversations do
|
|||
|> join(:inner, [_cp, _c, _e, _a, _lc, _oc, p], ap in Actor, on: p.actor_id == ap.id)
|
||||
|> where([_cp, c], c.event_id == ^event_id)
|
||||
|> where([cp], cp.actor_id == ^actor_id)
|
||||
|> where(
|
||||
[_cp, _c, _e, _a, _lc, oc],
|
||||
oc.actor_id == ^actor_id or oc.attributed_to_id == ^actor_id
|
||||
)
|
||||
|> order_by([cp], desc: cp.unread, desc: cp.updated_at)
|
||||
|> preload([_cp, c, e, a, lc, oc, p, ap],
|
||||
actor: a,
|
||||
|
@ -113,6 +117,14 @@ defmodule Mobilizon.Conversations do
|
|||
|> Page.build_page(page, limit)
|
||||
end
|
||||
|
||||
def find_all_conversations_for_event(event_id) do
|
||||
ConversationParticipant
|
||||
|> join(:inner, [cp], c in Conversation, on: cp.conversation_id == c.id)
|
||||
|> join(:left, [_cp, c], e in Event, on: c.event_id == e.id)
|
||||
|> where([_cp, c], c.event_id == ^event_id)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@spec list_conversation_participants_for_actor(
|
||||
integer | String.t(),
|
||||
integer | nil,
|
||||
|
@ -133,7 +145,7 @@ defmodule Mobilizon.Conversations do
|
|||
subquery
|
||||
|> subquery()
|
||||
|> order_by([cp], desc: cp.unread, desc: cp.updated_at)
|
||||
|> preload([:actor, conversation: [:last_comment, :participants]])
|
||||
|> preload([:actor, conversation: [:last_comment, :origin_comment, :participants, :event]])
|
||||
|> Page.build_page(page, limit)
|
||||
end
|
||||
|
||||
|
@ -147,7 +159,7 @@ defmodule Mobilizon.Conversations do
|
|||
ConversationParticipant
|
||||
|> join(:inner, [cp], a in Actor, on: cp.actor_id == a.id)
|
||||
|> where([_cp, a], a.user_id == ^user_id)
|
||||
|> preload([:actor, conversation: [:last_comment, :participants]])
|
||||
|> preload([:actor, conversation: [:last_comment, :origin_comment, :participants, :event]])
|
||||
|> Page.build_page(page, limit)
|
||||
end
|
||||
|
||||
|
|
|
@ -85,6 +85,13 @@ defmodule Mobilizon.Discussions do
|
|||
|> select([c, r], %{c | total_replies: count(r.id)})
|
||||
end
|
||||
|
||||
# Replies are only used on event comments, so we always use public visibily here
|
||||
def query(Comment, %{replies: true}) do
|
||||
Comment
|
||||
|> where([c], c.visibility in ^@public_visibility)
|
||||
|> order_by([c], asc: :is_announcement, asc: :published_at)
|
||||
end
|
||||
|
||||
def query(Comment, _) do
|
||||
order_by(Comment, [c], asc: :is_announcement, asc: :published_at)
|
||||
end
|
||||
|
|
|
@ -25,6 +25,7 @@ defmodule Mobilizon.Events.EventOptions do
|
|||
show_participation_price: boolean,
|
||||
offers: [EventOffer.t()],
|
||||
participation_condition: [EventParticipationCondition.t()],
|
||||
hide_number_of_participants: boolean,
|
||||
show_start_time: boolean,
|
||||
show_end_time: boolean,
|
||||
timezone: String.t() | nil,
|
||||
|
@ -41,6 +42,7 @@ defmodule Mobilizon.Events.EventOptions do
|
|||
:program,
|
||||
:comment_moderation,
|
||||
:show_participation_price,
|
||||
:hide_number_of_participants,
|
||||
:show_start_time,
|
||||
:show_end_time,
|
||||
:timezone,
|
||||
|
@ -59,6 +61,7 @@ defmodule Mobilizon.Events.EventOptions do
|
|||
field(:program, :string)
|
||||
field(:comment_moderation, CommentModeration)
|
||||
field(:show_participation_price, :boolean)
|
||||
field(:hide_number_of_participants, :boolean, default: false)
|
||||
field(:show_start_time, :boolean, default: true)
|
||||
field(:show_end_time, :boolean, default: true)
|
||||
field(:timezone, :string)
|
||||
|
|
|
@ -16,6 +16,7 @@ defmodule Mobilizon.Events do
|
|||
|
||||
alias Mobilizon.Actors.{Actor, Follower}
|
||||
alias Mobilizon.Addresses.Address
|
||||
alias Mobilizon.Config
|
||||
|
||||
alias Mobilizon.Events.{
|
||||
Event,
|
||||
|
@ -358,19 +359,34 @@ defmodule Mobilizon.Events do
|
|||
@doc """
|
||||
Returns the list of events.
|
||||
"""
|
||||
@spec list_events(integer | nil, integer | nil, atom, atom, boolean) :: Page.t(Event.t())
|
||||
@spec list_events(
|
||||
integer | nil,
|
||||
integer | nil,
|
||||
atom,
|
||||
atom,
|
||||
boolean,
|
||||
boolean | nil,
|
||||
string | nil,
|
||||
float | nil
|
||||
) :: Page.t(Event.t())
|
||||
def list_events(
|
||||
page \\ nil,
|
||||
limit \\ nil,
|
||||
sort \\ :begins_on,
|
||||
direction \\ :asc,
|
||||
is_future \\ true
|
||||
is_future \\ true,
|
||||
longevents \\ nil,
|
||||
location \\ nil,
|
||||
radius \\ nil
|
||||
) do
|
||||
Event
|
||||
|> distinct([e], [{^direction, ^sort}, asc: e.id])
|
||||
|> preload([:organizer_actor, :participants])
|
||||
|> sort(sort, direction)
|
||||
|> maybe_join_address(%{location: location, radius: radius})
|
||||
|> events_for_location(%{location: location, radius: radius})
|
||||
|> filter_future_events(is_future)
|
||||
|> events_for_longevents(longevents)
|
||||
|> filter_public_visibility()
|
||||
|> filter_draft()
|
||||
|> filter_cancelled_events()
|
||||
|
@ -571,6 +587,7 @@ defmodule Mobilizon.Events do
|
|||
|> events_for_search_query()
|
||||
|> events_for_begins_on(Map.get(args, :begins_on, DateTime.utc_now()))
|
||||
|> events_for_ends_on(Map.get(args, :ends_on))
|
||||
|> events_for_longevents(Map.get(args, :longevents))
|
||||
|> events_for_category(args)
|
||||
|> events_for_categories(args)
|
||||
|> events_for_languages(args)
|
||||
|
@ -581,6 +598,7 @@ defmodule Mobilizon.Events do
|
|||
|> events_for_bounding_box(args)
|
||||
|> filter_online(args)
|
||||
|> filter_draft()
|
||||
|> filter_local(if Map.get(args, :local_only, nil) == true, do: true, else: nil)
|
||||
|> filter_local_or_from_followed_instances_events()
|
||||
|> filter_public_visibility()
|
||||
|> event_order(Map.get(args, :sort_by, :match_desc), search_string)
|
||||
|
@ -792,7 +810,7 @@ defmodule Mobilizon.Events do
|
|||
end
|
||||
end
|
||||
|
||||
def get_participant(event_id, actor_id, %{}) do
|
||||
def get_participant(event_id, actor_id, _params) do
|
||||
case Participant
|
||||
|> Repo.get_by(event_id: event_id, actor_id: actor_id)
|
||||
|> Repo.preload(@participant_preloads) do
|
||||
|
@ -1376,6 +1394,36 @@ defmodule Mobilizon.Events do
|
|||
end
|
||||
end
|
||||
|
||||
@spec events_for_longevents(Ecto.Queryable.t(), Boolean.t() | nil) :: Ecto.Query.t()
|
||||
defp events_for_longevents(query, longevents) do
|
||||
duration = Config.get([:instance, :duration_of_long_event], 0)
|
||||
|
||||
if duration <= 0 do
|
||||
query
|
||||
else
|
||||
case longevents do
|
||||
nil ->
|
||||
query
|
||||
|
||||
true ->
|
||||
where(
|
||||
query,
|
||||
[q],
|
||||
not is_nil(q.ends_on) and
|
||||
q.ends_on > fragment("? + '1 days'::interval * ?", q.begins_on, ^duration)
|
||||
)
|
||||
|
||||
false ->
|
||||
where(
|
||||
query,
|
||||
[q],
|
||||
is_nil(q.ends_on) or
|
||||
q.ends_on <= fragment("? + '1 days'::interval * ?", q.begins_on, ^duration)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@spec events_for_category(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
|
||||
defp events_for_category(query, %{category: category}) when is_valid_string(category) do
|
||||
where(query, [q], q.category == ^category)
|
||||
|
@ -1774,6 +1822,7 @@ defmodule Mobilizon.Events do
|
|||
|> distinct([e], e.id)
|
||||
|> join(:left, [e], et in "events_tags", on: e.id == et.event_id)
|
||||
|> join(:left, [e], a in Address, on: e.physical_address_id == a.id)
|
||||
|> filter_future_events(true)
|
||||
|> filter_draft()
|
||||
|> filter_local_or_from_followed_instances_events()
|
||||
|> filter_public_visibility()
|
||||
|
|
|
@ -185,7 +185,8 @@ defmodule Mobilizon.Medias do
|
|||
[from: "events_medias", param: "media_id"],
|
||||
[from: "posts", param: "picture_id"],
|
||||
[from: "posts_medias", param: "media_id"],
|
||||
[from: "comments_medias", param: "media_id"]
|
||||
[from: "comments_medias", param: "media_id"],
|
||||
[from: "admin_settings_medias", param: "media_id"]
|
||||
]
|
||||
|> Enum.map_join(" UNION ", fn [from: from, param: param] ->
|
||||
"SELECT 1 FROM #{from} WHERE #{from}.#{param} = m0.id"
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule Mobilizon.Service.Activity.Conversation do
|
|||
@moduledoc """
|
||||
Insert a conversation activity
|
||||
"""
|
||||
alias Mobilizon.Conversations
|
||||
alias Mobilizon.{Actors, Conversations}
|
||||
alias Mobilizon.Conversations.{Conversation, ConversationParticipant}
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.Event
|
||||
|
@ -38,7 +38,7 @@ defmodule Mobilizon.Service.Activity.Conversation do
|
|||
%Conversation{
|
||||
id: conversation_id
|
||||
} = conversation,
|
||||
%Comment{actor_id: actor_id, text: last_comment_text},
|
||||
%Comment{actor_id: actor_id, text: last_comment_text} = comment,
|
||||
_options
|
||||
)
|
||||
when subject in [
|
||||
|
@ -55,7 +55,8 @@ defmodule Mobilizon.Service.Activity.Conversation do
|
|||
actor_id: conversation_participant_actor_id
|
||||
} =
|
||||
conversation_participant ->
|
||||
if actor_id != conversation_participant_actor_id do
|
||||
if actor_id != conversation_participant_actor_id and
|
||||
can_send_event_announcement?(conversation, comment) do
|
||||
LegacyNotifierBuilder.enqueue(
|
||||
:legacy_notify,
|
||||
%{
|
||||
|
@ -98,4 +99,31 @@ defmodule Mobilizon.Service.Activity.Conversation do
|
|||
}
|
||||
|
||||
defp event_subject_params(_), do: %{}
|
||||
|
||||
@spec can_send_event_announcement?(Conversation.t(), Comment.t()) :: boolean()
|
||||
defp can_send_event_announcement?(
|
||||
%Conversation{
|
||||
event: %Event{
|
||||
attributed_to_id: attributed_to_id
|
||||
}
|
||||
},
|
||||
%Comment{actor_id: actor_id}
|
||||
)
|
||||
when not is_nil(attributed_to_id) do
|
||||
attributed_to_id == actor_id or Actors.member?(actor_id, attributed_to_id)
|
||||
end
|
||||
|
||||
defp can_send_event_announcement?(
|
||||
%Conversation{
|
||||
event: %Event{
|
||||
organizer_actor_id: organizer_actor_id
|
||||
}
|
||||
},
|
||||
%Comment{actor_id: actor_id}
|
||||
)
|
||||
when not is_nil(organizer_actor_id) do
|
||||
organizer_actor_id == actor_id
|
||||
end
|
||||
|
||||
defp can_send_event_announcement?(_, _), do: false
|
||||
end
|
||||
|
|
|
@ -85,7 +85,7 @@ defmodule Mobilizon.Service.Address do
|
|||
defined?(street) ->
|
||||
if defined?(locality), do: "#{street} (#{locality})", else: street
|
||||
|
||||
defined?(locality) ->
|
||||
defined?(locality) and locality != region ->
|
||||
"#{locality}, #{region}, #{country}"
|
||||
|
||||
defined?(region) ->
|
||||
|
|
12
lib/service/config/helpers.ex
Normal file
12
lib/service/config/helpers.ex
Normal file
|
@ -0,0 +1,12 @@
|
|||
defmodule Mobilizon.Service.Config.Helpers do
|
||||
@moduledoc """
|
||||
Provide some helpers to configuration files
|
||||
"""
|
||||
|
||||
@spec host_from_uri(String.t() | nil) :: String.t() | nil
|
||||
def host_from_uri(nil), do: nil
|
||||
|
||||
def host_from_uri(uri) when is_binary(uri) do
|
||||
URI.parse(uri).host
|
||||
end
|
||||
end
|
43
lib/service/geospatial/hat.ex
Normal file
43
lib/service/geospatial/hat.ex
Normal file
|
@ -0,0 +1,43 @@
|
|||
defmodule Mobilizon.Service.Geospatial.Hat do
|
||||
@moduledoc """
|
||||
Hat backend.
|
||||
"""
|
||||
|
||||
alias Mobilizon.Addresses.Address
|
||||
alias Mobilizon.Service.Geospatial.Addok
|
||||
alias Mobilizon.Service.Geospatial.Nominatim
|
||||
alias Mobilizon.Service.Geospatial.Provider
|
||||
require Logger
|
||||
|
||||
@behaviour Provider
|
||||
|
||||
@impl Provider
|
||||
@doc """
|
||||
Hat implementation for `c:Mobilizon.Service.Geospatial.Provider.geocode/3`.
|
||||
"""
|
||||
@spec geocode(String.t(), keyword()) :: list(Address.t())
|
||||
def geocode(lon, lat, options \\ []) do
|
||||
tasks = [
|
||||
Task.async(fn -> Addok.geocode(lon, lat, options) end),
|
||||
Task.async(fn -> Nominatim.geocode(lon, lat, options) end)
|
||||
]
|
||||
|
||||
[addrlist1, addrlist2] = Task.await_many(tasks, 12_000)
|
||||
addrlist2 ++ addrlist1
|
||||
end
|
||||
|
||||
@impl Provider
|
||||
@doc """
|
||||
Hat implementation for `c:Mobilizon.Service.Geospatial.Provider.search/2`.
|
||||
"""
|
||||
@spec search(String.t(), keyword()) :: list(Address.t())
|
||||
def search(q, options \\ []) do
|
||||
tasks = [
|
||||
Task.async(fn -> Addok.search(q, options) end),
|
||||
Task.async(fn -> Nominatim.search(q, options) end)
|
||||
]
|
||||
|
||||
[addrlist1, addrlist2] = Task.await_many(tasks, 12_000)
|
||||
addrlist2 ++ addrlist1
|
||||
end
|
||||
end
|
|
@ -3,7 +3,9 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
|
|||
Tesla HTTP Client that is preconfigured to get and post ActivityPub content
|
||||
"""
|
||||
|
||||
require Logger
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
|
@ -13,7 +15,11 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do
|
|||
def client(options \\ []) do
|
||||
headers = Keyword.get(options, :headers, [])
|
||||
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
|
||||
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
|
||||
|
||||
opts =
|
||||
@default_opts
|
||||
|> Keyword.merge(ssl_options: get_tls_config())
|
||||
|> Keyword.merge(Keyword.get(options, :opts, []))
|
||||
|
||||
middleware = [
|
||||
{Tesla.Middleware.Headers,
|
||||
|
|
|
@ -4,6 +4,7 @@ defmodule Mobilizon.Service.HTTP.GenericJSONClient do
|
|||
"""
|
||||
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
|
@ -13,7 +14,11 @@ defmodule Mobilizon.Service.HTTP.GenericJSONClient do
|
|||
def client(options \\ []) do
|
||||
headers = Keyword.get(options, :headers, [])
|
||||
adapter = Application.get_env(:tesla, __MODULE__, [])[:adapter] || Tesla.Adapter.Hackney
|
||||
opts = Keyword.merge(@default_opts, Keyword.get(options, :opts, []))
|
||||
|
||||
opts =
|
||||
@default_opts
|
||||
|> Keyword.merge(ssl_options: get_tls_config())
|
||||
|> Keyword.merge(Keyword.get(options, :opts, []))
|
||||
|
||||
middleware = [
|
||||
{Tesla.Middleware.Headers,
|
||||
|
|
|
@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.GeospatialClient do
|
|||
|
||||
use Tesla
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
]
|
||||
|
||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
|
||||
|
||||
plug(Tesla.Middleware.FollowRedirects)
|
||||
|
||||
|
|
|
@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.HostMetaClient do
|
|||
|
||||
use Tesla
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
]
|
||||
|
||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
|
||||
|
||||
plug(Tesla.Middleware.FollowRedirects)
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@ defmodule Mobilizon.Service.HTTP.RemoteMediaDownloaderClient do
|
|||
|
||||
use Tesla
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
]
|
||||
|
||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
|
||||
|
||||
plug(Tesla.Middleware.FollowRedirects)
|
||||
|
||||
|
|
|
@ -5,12 +5,13 @@ defmodule Mobilizon.Service.HTTP.RichMediaPreviewClient do
|
|||
|
||||
use Tesla
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
]
|
||||
|
||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
|
||||
|
||||
plug(Tesla.Middleware.FollowRedirects)
|
||||
|
||||
|
|
|
@ -3,6 +3,17 @@ defmodule Mobilizon.Service.HTTP.Utils do
|
|||
Utils for HTTP operations
|
||||
"""
|
||||
|
||||
def get_tls_config do
|
||||
cacertfile =
|
||||
if is_nil(System.get_env("MOBILIZON_CA_CERT_PATH")) do
|
||||
CAStore.file_path()
|
||||
else
|
||||
System.get_env("MOBILIZON_CA_CERT_PATH")
|
||||
end
|
||||
|
||||
[cacertfile: cacertfile]
|
||||
end
|
||||
|
||||
@spec get_header(Enum.t(), String.t()) :: String.t() | nil
|
||||
def get_header(headers, key) do
|
||||
key = String.downcase(key)
|
||||
|
|
|
@ -6,12 +6,13 @@ defmodule Mobilizon.Service.HTTP.WebfingerClient do
|
|||
|
||||
use Tesla
|
||||
alias Mobilizon.Config
|
||||
import Mobilizon.Service.HTTP.Utils, only: [get_tls_config: 0]
|
||||
|
||||
@default_opts [
|
||||
recv_timeout: 20_000
|
||||
]
|
||||
|
||||
adapter(Tesla.Adapter.Hackney, @default_opts)
|
||||
adapter(Tesla.Adapter.Hackney, Keyword.merge([ssl_options: get_tls_config()], @default_opts))
|
||||
|
||||
plug(Tesla.Middleware.FollowRedirects)
|
||||
|
||||
|
|
|
@ -136,14 +136,12 @@ defimpl Mobilizon.Service.Metadata, for: Mobilizon.Events.Event do
|
|||
defp build_language(language, locale), do: language || locale
|
||||
|
||||
@spec build_begins_on(DateTime.t(), String.t() | nil) :: DateTime.t()
|
||||
defp build_begins_on(begins_on, nil), do: begins_on
|
||||
|
||||
defp build_begins_on(begins_on, timezone) do
|
||||
if timezone do
|
||||
case DateTime.shift_zone(begins_on, timezone) do
|
||||
{:ok, begins_on} -> begins_on
|
||||
{:error, _err} -> begins_on
|
||||
end
|
||||
else
|
||||
begins_on
|
||||
case DateTime.shift_zone(begins_on, timezone) do
|
||||
{:ok, begins_on} -> begins_on
|
||||
{:error, _err} -> begins_on
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -56,7 +56,6 @@ defmodule Mobilizon.Service.SiteMap do
|
|||
end)
|
||||
|> Sitemapper.generate(config)
|
||||
|> Sitemapper.persist(config)
|
||||
|> Sitemapper.ping(config)
|
||||
|> Stream.run()
|
||||
end,
|
||||
timeout: :infinity
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
|
|||
"""
|
||||
|
||||
alias Mobilizon.Activities.Activity
|
||||
alias Mobilizon.{Actors, Events, Users}
|
||||
alias Mobilizon.{Actors, Config, Events, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.Service.Notifier
|
||||
|
@ -37,9 +37,10 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
|
|||
end
|
||||
|
||||
defp special_handling("conversation_created", args, activity) do
|
||||
notify_participants(
|
||||
notify_participant(
|
||||
get_in(args, ["subject_params", "conversation_event_id"]),
|
||||
activity,
|
||||
get_in(args, ["participant", "actor_id"]),
|
||||
args["author_id"]
|
||||
)
|
||||
end
|
||||
|
@ -143,6 +144,24 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
|
|||
notify_anonymous_participants(event_id, activity)
|
||||
end
|
||||
|
||||
defp notify_participant(nil, _activity, _conversation_participant_actor_id, _author_id),
|
||||
do: :ok
|
||||
|
||||
defp notify_participant(event_id, activity, conversation_participant_actor_id, author_id) do
|
||||
# Anonymous participation
|
||||
if conversation_participant_actor_id == Config.anonymous_actor_id() do
|
||||
notify_anonymous_participants(event_id, activity)
|
||||
else
|
||||
[conversation_participant_actor_id]
|
||||
|> users_from_actor_ids(author_id)
|
||||
|> Enum.each(fn user ->
|
||||
Notifier.Email.send_anonymous_activity(user.email, activity,
|
||||
locale: Map.get(user, :locale, "en")
|
||||
)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
defp notify_anonymous_participants(nil, _activity), do: :ok
|
||||
|
||||
defp notify_anonymous_participants(event_id, activity) do
|
||||
|
@ -154,7 +173,7 @@ defmodule Mobilizon.Service.Workers.LegacyNotifierBuilder do
|
|||
|> Enum.map(fn %Participant{metadata: metadata} -> metadata end)
|
||||
|> Enum.map(fn %{email: email} = metadata ->
|
||||
Notifier.Email.send_anonymous_activity(email, activity,
|
||||
locale: Map.get(metadata, :locale, "en")
|
||||
locale: Map.get(metadata, :locale, "en") || "en"
|
||||
)
|
||||
end)
|
||||
end
|
||||
|
|
58
lib/web/controllers/manifest_controller.ex
Normal file
58
lib/web/controllers/manifest_controller.ex
Normal file
|
@ -0,0 +1,58 @@
|
|||
defmodule Mobilizon.Web.ManifestController do
|
||||
use Mobilizon.Web, :controller
|
||||
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Medias.Media
|
||||
|
||||
@spec manifest(Plug.Conn.t(), any) :: Plug.Conn.t()
|
||||
def manifest(conn, _params) do
|
||||
favicons =
|
||||
case Config.instance_favicon() do
|
||||
%Media{file: %{url: url}, metadata: metadata} ->
|
||||
[
|
||||
Map.merge(
|
||||
%{
|
||||
src: url
|
||||
},
|
||||
case metadata do
|
||||
%{width: width} -> %{sizes: "#{width}x#{width}"}
|
||||
_ -> %{}
|
||||
end
|
||||
)
|
||||
]
|
||||
|
||||
_ ->
|
||||
[
|
||||
%{
|
||||
src: "./img/icons/android-chrome-512x512.png",
|
||||
sizes: "512x512",
|
||||
type: "image/png"
|
||||
},
|
||||
%{
|
||||
src: "./img/icons/android-chrome-192x192.png",
|
||||
sizes: "192x192",
|
||||
type: "image/png"
|
||||
}
|
||||
]
|
||||
end
|
||||
|
||||
json(conn, %{
|
||||
name: Config.instance_name(),
|
||||
start_url: "/",
|
||||
scope: "/",
|
||||
display: "standalone",
|
||||
background_color: "#ffffff",
|
||||
theme_color: "#ffd599",
|
||||
orientation: "portrait-primary",
|
||||
icons: favicons
|
||||
})
|
||||
end
|
||||
|
||||
@spec favicon(Plug.Conn.t(), any) :: Plug.Conn.t()
|
||||
def favicon(conn, _params) do
|
||||
case Config.instance_favicon() do
|
||||
%Media{file: %{url: url}} -> redirect(conn, external: url)
|
||||
_ -> redirect(conn, to: "/img/icons/favicon.ico")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -18,8 +18,7 @@ defmodule Mobilizon.Web do
|
|||
"""
|
||||
|
||||
def static_paths,
|
||||
do:
|
||||
~w(index.html manifest.json manifest.webmanifest service-worker.js css fonts img js favicon.ico robots.txt assets)
|
||||
do: ~w(index.html service-worker.js css fonts img js robots.txt assets)
|
||||
|
||||
def controller do
|
||||
quote do
|
||||
|
|
|
@ -95,7 +95,7 @@ defmodule Mobilizon.Web.Router do
|
|||
forward("/", Absinthe.Plug,
|
||||
schema: Mobilizon.GraphQL.Schema,
|
||||
analyze_complexity: true,
|
||||
max_complexity: 250
|
||||
max_complexity: 300
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -113,6 +113,12 @@ defmodule Mobilizon.Web.Router do
|
|||
get("/nodeinfo/:version", NodeInfoController, :nodeinfo)
|
||||
end
|
||||
|
||||
scope "/", Mobilizon.Web do
|
||||
get("/manifest.webmanifest", ManifestController, :manifest)
|
||||
get("/manifest.json", ManifestController, :manifest)
|
||||
get("/favicon.ico", ManifestController, :favicon)
|
||||
end
|
||||
|
||||
scope "/", Mobilizon.Web do
|
||||
pipe_through(:activity_pub_and_html)
|
||||
pipe_through(:activity_pub_signature)
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<p>
|
||||
<%= pgettext(
|
||||
"terms",
|
||||
"When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a French not-for-profit organization advocating for Free/Libre Software. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
"When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
)
|
||||
|> raw %>
|
||||
</p>
|
||||
|
|
|
@ -7,4 +7,4 @@
|
|||
<%= if @follower.type == :Application do %><%= gettext "Note: %{name} following you doesn't necessarily imply that you follow this instance, but you can ask to follow them too.", name: Mobilizon.Actors.Actor.display_name_and_username(@follower) %><% end %>
|
||||
|
||||
<%= if @follower.type == :Application do %><%= gettext "To accept this invitation, head over to the instance's admin settings." %><% else %><%= gettext "To accept this invitation, head over to the profile's admin page." %><% end %>
|
||||
<%= if @follower.type == :Application do %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/instances/%{name}" %><% else %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/profiles/#{@follower.id}" %><% end %>
|
||||
<%= if @follower.type == :Application do %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/instances/#{@follower.domain}" %><% else %><%= "#{Mobilizon.Web.Endpoint.url()}/settings/admin/profiles/#{@follower.id}" %><% end %>
|
||||
|
|
|
@ -4,26 +4,23 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png" sizes="152x152" />
|
||||
<link rel="apple-touch-icon" href={favicon_url()} sizes={favicon_sizes()} />
|
||||
<link rel="icon" href={favicon_url()} sizes={favicon_sizes()} />
|
||||
<link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color={theme_color()} />
|
||||
<link rel="manifest" href="/manifest.webmanifest" />
|
||||
<meta name="theme-color" content={theme_color()} />
|
||||
<script>
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
document.documentElement.classList.add('dark')
|
||||
document.documentElement.classList.add('dark')
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark')
|
||||
document.documentElement.classList.remove('dark')
|
||||
}
|
||||
</script>
|
||||
<%= if root?(assigns) do %>
|
||||
<link rel="preload" href="/img/shape-1.svg" as="image" />
|
||||
<link rel="preload" href="/img/shape-2.svg" as="image" />
|
||||
<link rel="preload" href="/img/shape-3.svg" as="image" />
|
||||
<% end %>
|
||||
<%= tags(assigns) || assigns.tags %>
|
||||
<%= Vite.vite_client() %>
|
||||
<%= Vite.vite_snippet("src/main.ts") %>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule Mobilizon.Web.PageView do
|
|||
use Mobilizon.Web, :view
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Discussions.{Comment, Discussion}
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Posts.Post
|
||||
|
@ -91,4 +92,27 @@ defmodule Mobilizon.Web.PageView do
|
|||
def root?(assigns) do
|
||||
assigns |> Map.get(:conn, %{request_path: "/"}) |> Map.get(:request_path, "/") == "/"
|
||||
end
|
||||
|
||||
defp favicon do
|
||||
case Config.instance_favicon() do
|
||||
%{file: %{url: url}, metadata: metadata} ->
|
||||
%{
|
||||
src: url,
|
||||
sizes:
|
||||
case metadata do
|
||||
%{width: width} -> "#{width}x#{width}"
|
||||
_ -> "any"
|
||||
end
|
||||
}
|
||||
|
||||
_ ->
|
||||
%{
|
||||
src: "/img/icons/apple-touch-icon-152x152.png",
|
||||
sizes: "152x152"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def favicon_url, do: Map.get(favicon(), :src)
|
||||
def favicon_sizes, do: Map.get(favicon(), :sizes)
|
||||
end
|
||||
|
|
25
mix.exs
25
mix.exs
|
@ -1,7 +1,7 @@
|
|||
defmodule Mobilizon.Mixfile do
|
||||
use Mix.Project
|
||||
|
||||
@version "4.0.2"
|
||||
@version "5.0.0-beta.1"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
@ -121,10 +121,12 @@ defmodule Mobilizon.Mixfile do
|
|||
|> to_string()
|
||||
|> String.split()
|
||||
|> Enum.map(fn strategy_entry ->
|
||||
with [_strategy, dependency] <- String.split(strategy_entry, ":") do
|
||||
dependency
|
||||
else
|
||||
[strategy] -> "ueberauth_#{strategy}"
|
||||
case String.split(strategy_entry, ":") do
|
||||
[_strategy, dependency] ->
|
||||
dependency
|
||||
|
||||
[strategy] ->
|
||||
"ueberauth_#{strategy}"
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -144,7 +146,6 @@ defmodule Mobilizon.Mixfile do
|
|||
{:phoenix_live_view, "~> 0.20.0"},
|
||||
{:phoenix_view, "~> 2.0"},
|
||||
{:gettext, "~> 0.24"},
|
||||
{:cowboy, "~> 2.6"},
|
||||
{:guardian, "~> 2.0"},
|
||||
{:guardian_db, "~> 3.0.0"},
|
||||
{:guardian_phoenix, "~> 2.0"},
|
||||
|
@ -169,7 +170,6 @@ defmodule Mobilizon.Mixfile do
|
|||
{:absinthe_phoenix, "~> 2.0.1"},
|
||||
{:absinthe_plug, "~> 1.5.0"},
|
||||
{:dataloader, "~> 2.0"},
|
||||
{:plug_cowboy, "~> 2.0"},
|
||||
{:atomex, "~> 0.4"},
|
||||
{:cachex, "~> 3.1"},
|
||||
{:geohax, "~> 1.0.0"},
|
||||
|
@ -185,7 +185,7 @@ defmodule Mobilizon.Mixfile do
|
|||
{:floki, "~> 0.31"},
|
||||
{:ip_reserved, "~> 0.1.0"},
|
||||
{:fast_sanitize, "~> 0.1"},
|
||||
{:ueberauth, "0.10.5", override: true},
|
||||
{:ueberauth, "0.10.8", override: true},
|
||||
{:ueberauth_twitter, "~> 0.4"},
|
||||
{:ueberauth_discord, "~> 0.7"},
|
||||
{:ueberauth_github, "~> 0.8.1"},
|
||||
|
@ -221,6 +221,7 @@ defmodule Mobilizon.Mixfile do
|
|||
{:rajska, github: "tcitworld/rajska", branch: "mobilizon"},
|
||||
{:hammer, "~> 6.1"},
|
||||
{:tls_certificate_check, "~> 1.20"},
|
||||
{:bandit, "~> 1.0"},
|
||||
# Dev and test dependencies
|
||||
{:phoenix_live_reload, "~> 1.2", only: [:dev, :e2e]},
|
||||
{:ex_machina, "~> 2.3", only: [:dev, :test]},
|
||||
|
@ -238,7 +239,9 @@ defmodule Mobilizon.Mixfile do
|
|||
{:doctor, "~> 0.21", only: :dev},
|
||||
{:haversine, "~> 0.1.0"},
|
||||
{:ecto_dev_logger, "~> 0.7"},
|
||||
{:credo_code_climate, "~> 0.1.0", only: [:dev, :test]}
|
||||
{:credo_code_climate, "~> 0.1.0", only: [:dev, :test]},
|
||||
# Generate nix dependencies
|
||||
{:deps_nix, "~> 0.0", only: :dev}
|
||||
] ++ oauth_deps()
|
||||
end
|
||||
|
||||
|
@ -283,7 +286,7 @@ defmodule Mobilizon.Mixfile do
|
|||
File.rm_rf!("test/uploads")
|
||||
end
|
||||
|
||||
defp docs() do
|
||||
defp docs do
|
||||
[
|
||||
source_ref: "v#{@version}",
|
||||
groups_for_modules: groups_for_modules(),
|
||||
|
@ -323,7 +326,7 @@ defmodule Mobilizon.Mixfile do
|
|||
]
|
||||
end
|
||||
|
||||
defp groups_for_modules() do
|
||||
defp groups_for_modules do
|
||||
[
|
||||
Models: [
|
||||
~r/Mobilizon.Actors~r/,
|
||||
|
|
57
mix.lock
57
mix.lock
|
@ -4,6 +4,7 @@
|
|||
"absinthe_plug": {:hex, :absinthe_plug, "1.5.8", "38d230641ba9dca8f72f1fed2dfc8abd53b3907d1996363da32434ab6ee5d6ab", [:mix], [{:absinthe, "~> 1.5", [hex: :absinthe, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bbb04176647b735828861e7b2705465e53e2cf54ccf5a73ddd1ebd855f996e5a"},
|
||||
"argon2_elixir": {:hex, :argon2_elixir, "4.0.0", "7f6cd2e4a93a37f61d58a367d82f830ad9527082ff3c820b8197a8a736648941", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f9da27cf060c9ea61b1bd47837a28d7e48a8f6fa13a745e252556c14f9132c7f"},
|
||||
"atomex": {:hex, :atomex, "0.5.1", "706a8241fd6d1719b27a77b6d1192d2f85e6ecc78e6eadab29207d8cb9bb7ae5", [:mix], [{:xml_builder, "~> 2.1", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "6248891b5fcab8503982e090eedeeadb757a6311c2ef2e2998b874f7d319ab3f"},
|
||||
"bandit": {:hex, :bandit, "1.2.3", "a98d664a96fec23b68e776062296d76a94b4459795b38209f4ae89cb4225709c", [:mix], [{:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:thousand_island, "~> 1.0", [hex: :thousand_island, repo: "hexpm", optional: false]}, {:websock, "~> 0.5", [hex: :websock, repo: "hexpm", optional: false]}], "hexpm", "3e29150245a9b5f56944434e5240966e75c917dad248f689ab589b32187a81af"},
|
||||
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
|
||||
"cachex": {:hex, :cachex, "3.6.0", "14a1bfbeee060dd9bec25a5b6f4e4691e3670ebda28c8ba2884b12fe30b36bf8", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "ebf24e373883bc8e0c8d894a63bbe102ae13d918f790121f5cfe6e485cc8e2e2"},
|
||||
"castore": {:hex, :castore, "1.0.5", "9eeebb394cc9a0f3ae56b813459f990abb0a3dedee1be6b27fdb50301930502f", [:mix], [], "hexpm", "8d7c597c3e4a64c395980882d4bca3cebb8d74197c590dc272cfd3b6a6310578"},
|
||||
|
@ -12,29 +13,26 @@
|
|||
"codepagex": {:hex, :codepagex, "0.1.6", "49110d09a25ee336a983281a48ef883da4c6190481e0b063afe2db481af6117e", [:mix], [], "hexpm", "1521461097dde281edf084062f525a4edc6a5e49f4fd1f5ec41c9c4955d5bd59"},
|
||||
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
|
||||
"comeonin": {:hex, :comeonin, "5.4.0", "246a56ca3f41d404380fc6465650ddaa532c7f98be4bda1b4656b3a37cc13abe", [:mix], [], "hexpm", "796393a9e50d01999d56b7b8420ab0481a7538d0caf80919da493b4a6e51faf1"},
|
||||
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
|
||||
"cors_plug": {:hex, :cors_plug, "3.0.3", "7c3ac52b39624bc616db2e937c282f3f623f25f8d550068b6710e58d04a0e330", [:mix], [{:plug, "~> 1.13", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3f2d759e8c272ed3835fab2ef11b46bddab8c1ab9528167bd463b6452edf830d"},
|
||||
"cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
||||
"cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"},
|
||||
"credo": {:hex, :credo, "1.7.2", "fdee3a7cb553d8f2e773569181f0a4a2bb7d192e27e325404cc31b354f59d68c", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "dd15d6fbc280f6cf9b269f41df4e4992dee6615939653b164ef951f60afcb68e"},
|
||||
"credo": {:hex, :credo, "1.7.5", "643213503b1c766ec0496d828c90c424471ea54da77c8a168c725686377b9545", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f799e9b5cd1891577d8c773d245668aa74a2fcd15eb277f51a0131690ebfb3fd"},
|
||||
"credo_code_climate": {:hex, :credo_code_climate, "0.1.0", "1c4efbd11cb0244622ed5f09246b9afbbf796316ce03e78f67db6d81271d2978", [:mix], [{:credo, "~> 1.5", [hex: :credo, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "75529fe38056f4e229821d604758282838b8397c82e2c12e409fda16b16821ca"},
|
||||
"dataloader": {:hex, :dataloader, "2.0.0", "49b42d60b9bb06d761a71d7b034c4b34787957e713d4fae15387a25fcd639112", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:opentelemetry_process_propagator, "~> 0.2.1", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "09d61781b76ce216e395cdbc883ff00d00f46a503e215c22722dba82507dfef0"},
|
||||
"dataloader": {:hex, :dataloader, "2.0.1", "fa06b057b432b993203003fbff5ff040b7f6483a77e732b7dfc18f34ded2634f", [:mix], [{:ecto, ">= 3.4.3 and < 4.0.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:opentelemetry_process_propagator, "~> 0.3 or ~> 0.2.1", [hex: :opentelemetry_process_propagator, repo: "hexpm", optional: true]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "da7ff00890e1b14f7457419b9508605a8e66ae2cc2d08c5db6a9f344550efa11"},
|
||||
"db_connection": {:hex, :db_connection, "2.6.0", "77d835c472b5b67fc4f29556dee74bf511bbafecdcaf98c27d27fa5918152086", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c2f992d15725e721ec7fbc1189d4ecdb8afef76648c746a8e1cad35e3b8a35f3"},
|
||||
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
|
||||
"deps_nix": {:hex, :deps_nix, "0.5.2", "81af6ec4614de6b1012bf335338ededb61b4153b4b0eae62bc12886fc84b6578", [:mix], [], "hexpm", "8b6bbd21dfefa6e2b432d9f3228d66c88189b1b382eb2c0cdb8f14567118b104"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"},
|
||||
"digital_token": {:hex, :digital_token, "0.6.0", "13e6de581f0b1f6c686f7c7d12ab11a84a7b22fa79adeb4b50eec1a2d278d258", [:mix], [{:cldr_utils, "~> 2.17", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "2455d626e7c61a128b02a4a8caddb092548c3eb613ac6f6a85e4cbb6caddc4d1"},
|
||||
"doctor": {:hex, :doctor, "0.21.0", "20ef89355c67778e206225fe74913e96141c4d001cb04efdeba1a2a9704f1ab5", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "a227831daa79784eb24cdeedfa403c46a4cb7d0eab0e31232ec654314447e4e0"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
|
||||
"eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"},
|
||||
"ecto": {:hex, :ecto, "3.11.1", "4b4972b717e7ca83d30121b12998f5fcdc62ba0ed4f20fd390f16f3270d85c3e", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ebd3d3772cd0dfcd8d772659e41ed527c28b2a8bde4b00fe03e0463da0f1983b"},
|
||||
"ecto": {:hex, :ecto, "3.11.2", "e1d26be989db350a633667c5cda9c3d115ae779b66da567c68c80cfb26a8c9ee", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3c38bca2c6f8d8023f2145326cc8a80100c3ffe4dcbd9842ff867f7fc6156c65"},
|
||||
"ecto_autoslug_field": {:hex, :ecto_autoslug_field, "3.1.0", "ddf26e814baf3c32c6aebfed56a637f10a097db83f65d71e6f2d1e7faf2e9e51", [:mix], [{:ecto, ">= 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:slugify, "~> 1.3", [hex: :slugify, repo: "hexpm", optional: false]}], "hexpm", "b6ddd614805263e24b5c169532c934440d0289181cce873061fca3a8e92fd9ff"},
|
||||
"ecto_dev_logger": {:hex, :ecto_dev_logger, "0.10.0", "5b3a3900b845e0d40127bed9bdf9d02bf20aa38198a60fe108cddff63ed0048f", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "a55e58bad5d5c9b8ef2a3c3347dbdf7efa880a5371cf1457e44b41f489a43927"},
|
||||
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
|
||||
"ecto_shortuuid": {:hex, :ecto_shortuuid, "0.2.0", "57cae7b6016cc56a04457b4fc8f63957398dfd9023ff3e900eaf6805a40f8043", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:shortuuid, "~> 2.1 or ~> 3.0", [hex: :shortuuid, repo: "hexpm", optional: false]}], "hexpm", "b92e3b71e86be92f5a7ef6f3de170e7864454e630f7b01dd930414baf38efb65"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.11.1", "e9abf28ae27ef3916b43545f9578b4750956ccea444853606472089e7d169470", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.11.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ce14063ab3514424276e7e360108ad6c2308f6d88164a076aac8a387e1fea634"},
|
||||
"elixir_feed_parser": {:hex, :elixir_feed_parser, "2.1.0", "bb96fb6422158dc7ad59de62ef211cc69d264acbbe63941a64a5dce97bbbc2e6", [:mix], [{:timex, "~> 3.4", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "2d3c62fe7b396ee3b73d7160bc8fadbd78bfe9597c98c7d79b3f1038d9cba28f"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.7.7", "7128c60c2476019ed978210c245badf08b03dbec4f24d05790ef791da11aa17c", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bc19fff950fad52bbe5f211b12db9ec82c6b34a9647da0c2224b8b8464c7e6c"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.7.8", "505026f266552ee5aabca0b9f9c229cbb496c689537c9f922f3eb5431157efc7", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "7a71945b913d37ea89b06966e1342c85cfe549b15e6d6d081e8081c493062c07"},
|
||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||
"erlport": {:hex, :erlport, "0.11.0", "8bb46a520e6eb9146e655fbf9b824433d9d532194667069d9aa45696aae9684b", [:rebar3], [], "hexpm", "8eb136ccaf3948d329b8d1c3278ad2e17e2a7319801bc4cc2da6db278204eee4"},
|
||||
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
|
||||
|
@ -43,9 +41,9 @@
|
|||
"ex_cldr_currencies": {:hex, :ex_cldr_currencies, "2.15.1", "e92ba17c41e7405b7784e0e65f406b5f17cfe313e0e70de9befd653e12854822", [:mix], [{:ex_cldr, "~> 2.34", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "31df8bd37688340f8819bdd770eb17d659652078d34db632b85d4a32864d6a25"},
|
||||
"ex_cldr_dates_times": {:hex, :ex_cldr_dates_times, "2.16.0", "d9848a5de83b6f1bcba151cc43d63b5c6311813cd605b1df1afd896dfdd21001", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:ex_cldr_calendars, "~> 1.22", [hex: :ex_cldr_calendars, repo: "hexpm", optional: false]}, {:ex_cldr_numbers, "~> 2.31", [hex: :ex_cldr_numbers, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:tz, "~> 0.26", [hex: :tz, repo: "hexpm", optional: true]}], "hexpm", "0f2f250d479cadda4e0ef3a5e3d936ae7ba1a3f1199db6791e284e86203495b1"},
|
||||
"ex_cldr_languages": {:hex, :ex_cldr_languages, "0.3.3", "9787002803552b15a7ade19496c9e46fc921baca992ea80d0394e11fe3acea45", [:mix], [{:ex_cldr, "~> 2.25", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "22fb1fef72b7b4b4872d243b34e7b83734247a78ad87377986bf719089cc447a"},
|
||||
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.32.3", "b631ff94c982ec518e46bf4736000a30a33d6b58facc085d5f240305f512ad4a", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:digital_token, "~> 0.3 or ~> 1.0", [hex: :digital_token, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.37", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, ">= 2.14.2", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "7b626ff1e59a0ec9c3c5db5ce9ca91a6995e2ab56426b71f3cbf67181ea225f5"},
|
||||
"ex_cldr_numbers": {:hex, :ex_cldr_numbers, "2.32.4", "5562148dfc631b04712983975093d2aac29df30b3bf2f7257e0c94b85b72e91b", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:digital_token, "~> 0.3 or ~> 1.0", [hex: :digital_token, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.37", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_currencies, ">= 2.14.2", [hex: :ex_cldr_currencies, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "6fd5a82f0785418fa8b698c0be2b1845dff92b77f1b3172c763d37868fb503d2"},
|
||||
"ex_cldr_plugs": {:hex, :ex_cldr_plugs, "1.3.1", "ae58748df815ad21b8618830374a28b2ab593230e5df70ed9f647e953a884bec", [:mix], [{:ex_cldr, "~> 2.37", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:gettext, "~> 0.19", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "4f7b4a5fe061734cef7b62ff29118ed6ac72698cdd7bcfc97495db73611fe0fe"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.31.0", "06eb1dfd787445d9cab9a45088405593dd3bb7fe99e097eaa71f37ba80c7a676", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5350cafa6b7f77bdd107aa2199fe277acf29d739aba5aee7e865fc680c62a110"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.31.1", "8a2355ac42b1cc7b2379da9e40243f2670143721dd50748bf6c3b1184dae2089", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3178c3a407c557d8343479e1ff117a96fd31bafe52a039079593fb0524ef61b0"},
|
||||
"ex_ical": {:hex, :ex_ical, "0.2.0", "4b928b554614704016cc0c9ee226eb854da9327a1cc460457621ceacb1ac29a6", [:mix], [{:timex, "~> 3.1", [hex: :timex, repo: "hexpm", optional: false]}], "hexpm", "db76473b2ae0259e6633c6c479a5a4d8603f09497f55c88f9ef4d53d2b75befb"},
|
||||
"ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"},
|
||||
"ex_optimizer": {:hex, :ex_optimizer, "0.1.1", "62da37e206fc2233ff7a4e54e40eae365c40f96c81992fcd15b782eb25169b80", [:mix], [{:file_info, "~> 0.0.4", [hex: :file_info, repo: "hexpm", optional: false]}], "hexpm", "e6f5c059bcd58b66be2f6f257fdc4f69b74b0fa5c9ddd669486af012e4b52286"},
|
||||
|
@ -53,13 +51,13 @@
|
|||
"excoveralls": {:hex, :excoveralls, "0.18.0", "b92497e69465dc51bc37a6422226ee690ab437e4c06877e836f1c18daeb35da9", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1109bb911f3cb583401760be49c02cbbd16aed66ea9509fc5479335d284da60b"},
|
||||
"exgravatar": {:hex, :exgravatar, "2.0.3", "2349709832ee535f826f48db98cddd294ae62b01acb44d539a16419bd8ebc3e5", [:mix], [], "hexpm", "aca18ff9bd8991d3be3e5446d3bdefc051be084c1ffc9ab2d43b3e65339300e1"},
|
||||
"exkismet": {:git, "https://github.com/tcitworld/exkismet.git", "8b5485fde00fafbde20f315bec387a77f7358334", []},
|
||||
"expo": {:hex, :expo, "0.5.1", "249e826a897cac48f591deba863b26c16682b43711dd15ee86b92f25eafd96d9", [:mix], [], "hexpm", "68a4233b0658a3d12ee00d27d37d856b1ba48607e7ce20fd376958d0ba6ce92b"},
|
||||
"expo": {:hex, :expo, "0.5.2", "beba786aab8e3c5431813d7a44b828e7b922bfa431d6bfbada0904535342efe2", [:mix], [], "hexpm", "8c9bfa06ca017c9cb4020fabe980bc7fdb1aaec059fd004c2ab3bff03b1c599c"},
|
||||
"export": {:hex, :export, "0.1.1", "6dfd268b0692428f89b9285859a2dc02b6dcd2e8fdfbca34ac6e6a331351df91", [:mix], [{:erlport, "~> 0.9", [hex: :erlport, repo: "hexpm", optional: false]}], "hexpm", "3da7444ff4053f1824352f4bdb13fbd2c28c93c2011786fb686b649fdca1021f"},
|
||||
"fast_html": {:hex, :fast_html, "2.2.0", "6c5ef1be087a4ed613b0379c13f815c4d11742b36b67bb52cee7859847c84520", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "064c4f23b4a6168f9187dac8984b056f2c531bb0787f559fd6a8b34b38aefbae"},
|
||||
"fast_html": {:hex, :fast_html, "2.3.0", "08c1d8ead840dd3060ba02c761bed9f37f456a1ddfe30bcdcfee8f651cec06a6", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "f18e3c7668f82d3ae0b15f48d48feeb257e28aa5ab1b0dbf781c7312e5da029d"},
|
||||
"fast_sanitize": {:hex, :fast_sanitize, "0.2.3", "67b93dfb34e302bef49fec3aaab74951e0f0602fd9fa99085987af05bd91c7a5", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "e8ad286d10d0386e15d67d0ee125245ebcfbc7d7290b08712ba9013c8c5e56e2"},
|
||||
"file_info": {:hex, :file_info, "0.0.4", "2e0e77f211e833f38ead22cb29ce53761d457d80b3ffe0ffe0eb93880b0963b2", [:mix], [{:mimetype_parser, "~> 0.1.2", [hex: :mimetype_parser, repo: "hexpm", optional: false]}], "hexpm", "50e7ad01c2c8b9339010675fe4dc4a113b8d6ca7eddce24d1d74fd0e762781a5"},
|
||||
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||
"floki": {:hex, :floki, "0.35.2", "87f8c75ed8654b9635b311774308b2760b47e9a579dabf2e4d5f1e1d42c39e0b", [:mix], [], "hexpm", "6b05289a8e9eac475f644f09c2e4ba7e19201fd002b89c28c1293e7bd16773d9"},
|
||||
"floki": {:hex, :floki, "0.35.4", "cc947b446024732c07274ac656600c5c4dc014caa1f8fb2dfff93d275b83890d", [:mix], [], "hexpm", "27fa185d3469bd8fc5947ef0f8d5c4e47f0af02eb6b070b63c868f69e3af0204"},
|
||||
"gen_smtp": {:hex, :gen_smtp, "1.2.0", "9cfc75c72a8821588b9b9fe947ae5ab2aed95a052b81237e0928633a13276fd3", [:rebar3], [{:ranch, ">= 1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "5ee0375680bca8f20c4d85f58c2894441443a743355430ff33a783fe03296779"},
|
||||
"geo": {:hex, :geo, "3.6.0", "00c9c6338579f67e91cd5950af4ae2eb25cdce0c3398718c232539f61625d0bd", [:mix], [{:jason, "~> 1.4", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "1dbdebf617183b54bc3c8ad7a36531a9a76ada8ca93f75f573b0ae94006168da"},
|
||||
"geo_postgis": {:hex, :geo_postgis, "3.5.0", "e3675b6276b8c2166dc20a6fa9d992eb73c665de2b09b666d09c7824dc8a8300", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:geo, "~> 3.5", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: false]}], "hexpm", "0bebc5b00f8b11835066bd6213fbeeec03704b4a1c206920b81c1ec2201d185f"},
|
||||
|
@ -71,29 +69,30 @@
|
|||
"guardian_db": {:hex, :guardian_db, "3.0.0", "c42902e3f1af1ba1e2d0c10913b926a1421f3a7e38eb4fc382b715c17489abdb", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.1", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:guardian, "~> 1.0 or ~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "9c2ec4278efa34f9f1cc6ba795e552d41fdc7ffba5319d67eeb533b89392d183"},
|
||||
"guardian_phoenix": {:hex, :guardian_phoenix, "2.0.1", "89a817265af09a6ddf7cb1e77f17ffca90cea2db10ff888375ef34502b2731b1", [:mix], [{:guardian, "~> 2.0", [hex: :guardian, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "21f439246715192b231f228680465d1ed5fbdf01555a4a3b17165532f5f9a08c"},
|
||||
"hackney": {:hex, :hackney, "1.20.1", "8d97aec62ddddd757d128bfd1df6c5861093419f8f7a4223823537bad5d064e2", [:rebar3], [{:certifi, "~> 2.12.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "fe9094e5f1a2a2c0a7d10918fee36bfec0ec2a979994cff8cfe8058cd9af38e3"},
|
||||
"hammer": {:hex, :hammer, "6.1.0", "f263e3c3e9946bd410ea0336b2abe0cb6260af4afb3a221e1027540706e76c55", [:make, :mix], [{:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b47e415a562a6d072392deabcd58090d8a41182cf9044cdd6b0d0faaaf68ba57"},
|
||||
"hammer": {:hex, :hammer, "6.2.1", "5ae9c33e3dceaeb42de0db46bf505bd9c35f259c8defb03390cd7556fea67ee2", [:mix], [{:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}], "hexpm", "b9476d0c13883d2dc0cc72e786bac6ac28911fba7cc2e04b70ce6a6d9c4b2bdc"},
|
||||
"haversine": {:hex, :haversine, "0.1.0", "14240e90dae07c9459f538d12a811492f655d95fc68f999403503b4f6c4ec522", [:mix], [], "hexpm", "54dc48e895bc18a59437a37026c873634e17b648a64cb87bfafb96f64d607060"},
|
||||
"hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"},
|
||||
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
||||
"http_signatures": {:hex, :http_signatures, "0.1.2", "ed1cc7043abcf5bb4f30d68fb7bad9d618ec1a45c4ff6c023664e78b67d9c406", [:mix], [], "hexpm", "f08aa9ac121829dae109d608d83c84b940ef2f183ae50f2dd1e9a8bc619d8be7"},
|
||||
"httpoison": {:hex, :httpoison, "1.8.2", "9eb9c63ae289296a544842ef816a85d881d4a31f518a0fec089aaa744beae290", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "2bb350d26972e30c96e2ca74a1aaf8293d61d0742ff17f01e0279fef11599921"},
|
||||
"icalendar": {:git, "https://github.com/tcitworld/icalendar.git", "1033d922c82a7223db0ec138e2316557b70ff49f", []},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"},
|
||||
"inet_cidr": {:hex, :inet_cidr, "1.0.8", "d26bb7bdbdf21ae401ead2092bf2bb4bf57fe44a62f5eaa5025280720ace8a40", [:mix], [], "hexpm", "d5b26da66603bb56c933c65214c72152f0de9a6ea53618b56d63302a68f6a90e"},
|
||||
"ip_reserved": {:hex, :ip_reserved, "0.1.1", "e5112d71f1abf05207f82fd9597d369a5fde1e0b6d1bbe77c02a99bb26ecdc33", [:mix], [{:inet_cidr, "~> 1.0.0", [hex: :inet_cidr, repo: "hexpm", optional: false]}], "hexpm", "55fcd2b6e211caef09ea3f54ef37d43030bec486325d12fe865ab5ed8140a4fe"},
|
||||
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
|
||||
"jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"},
|
||||
"jose": {:hex, :jose, "1.11.6", "613fda82552128aa6fb804682e3a616f4bc15565a048dabd05b1ebd5827ed965", [:mix, :rebar3], [], "hexpm", "6275cb75504f9c1e60eeacb771adfeee4905a9e182103aa59b53fed651ff9738"},
|
||||
"jumper": {:hex, :jumper, "1.0.2", "68cdcd84472a00ac596b4e6459a41b3062d4427cbd4f1e8c8793c5b54f1406a7", [:mix], [], "hexpm", "9b7782409021e01ab3c08270e26f36eb62976a38c1aa64b2eaf6348422f165e1"},
|
||||
"junit_formatter": {:hex, :junit_formatter, "3.3.1", "c729befb848f1b9571f317d2fefa648e9d4869befc4b2980daca7c1edc468e40", [:mix], [], "hexpm", "761fc5be4b4c15d8ba91a6dafde0b2c2ae6db9da7b8832a55b5a1deb524da72b"},
|
||||
"linkify": {:hex, :linkify, "0.5.3", "5f8143d8f61f5ff08d3aeeff47ef6509492b4948d8f08007fbf66e4d2246a7f2", [:mix], [], "hexpm", "3ef35a1377d47c25506e07c1c005ea9d38d700699d92ee92825f024434258177"},
|
||||
"makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"},
|
||||
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"},
|
||||
"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.1.1", "eee6fc570d77ad6851c7bc08de420a47fd1e449ef5ccfa6a77ef68b72e7e51ad", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "f82262b54dee533467021723892e15c3267349849f1f737526523ecba4e6baae"},
|
||||
"mix_test_watch": {:hex, :mix_test_watch, "1.1.2", "431bdccf20b110f1595fe2a0e3c6cffd96d8f706721def5d04d557bc0898c476", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "8ce79fc69a304eec81ab6c1a05de2eb026a8959f65fb47f933ce8eb56018ba35"},
|
||||
"mmdb2_decoder": {:hex, :mmdb2_decoder, "3.0.1", "78e3aedde88035c6873ada5ceaf41b7f15a6259ed034e0eaca72ccfa937798f0", [:mix], [], "hexpm", "316af0f388fac824782d944f54efe78e7c9691bbbdb0afd5cccdd0510adf559d"},
|
||||
"mock": {:hex, :mock, "0.3.8", "7046a306b71db2488ef54395eeb74df0a7f335a7caca4a3d3875d1fc81c884dd", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "7fa82364c97617d79bb7d15571193fc0c4fe5afd0c932cef09426b3ee6fe2022"},
|
||||
"mogrify": {:hex, :mogrify, "0.9.3", "238c782f00271dace01369ad35ae2e9dd020feee3443b9299ea5ea6bed559841", [:mix], [], "hexpm", "0189b1e1de27455f2b9ae8cf88239cefd23d38de9276eb5add7159aea51731e6"},
|
||||
|
@ -103,31 +102,30 @@
|
|||
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
|
||||
"oauth2": {:hex, :oauth2, "2.1.0", "beb657f393814a3a7a8a15bd5e5776ecae341fd344df425342a3b6f1904c2989", [:mix], [{:tesla, "~> 1.5", [hex: :tesla, repo: "hexpm", optional: false]}], "hexpm", "8ac07f85b3307dd1acfeb0ec852f64161b22f57d0ce0c15e616a1dfc8ebe2b41"},
|
||||
"oauther": {:hex, :oauther, "1.3.0", "82b399607f0ca9d01c640438b34d74ebd9e4acd716508f868e864537ecdb1f76", [:mix], [], "hexpm", "78eb888ea875c72ca27b0864a6f550bc6ee84f2eeca37b093d3d833fbcaec04e"},
|
||||
"oban": {:hex, :oban, "2.17.1", "42d6221a1c17b63d81c19e3bad9ea82b59e39c47c1f9b7670ee33628569a449b", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c02686ada7979b00e259c0efbafeae2749f8209747b3460001fe695c5bdbeee6"},
|
||||
"oban": {:hex, :oban, "2.17.5", "3d1bf04ac701ad3c0241eb1f2eb94ea6b8f2f2a3f99ea828847377d2dd256cfe", [:mix], [{:ecto_sql, "~> 3.10", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:ecto_sqlite3, "~> 0.9", [hex: :ecto_sqlite3, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fd3ccbbfdbb2bc77107c8790946f9821a831ed0720688485ee6adcd7863886cf"},
|
||||
"paasaa": {:hex, :paasaa, "0.6.0", "07c8ed81010caa25db351d474f0c053072c809821c60f9646f7b1547bec52f6d", [:mix], [], "hexpm", "732ddfc21bac0831edb26aec468af3ec2b8997d74f6209810b1cc53199c29f2e"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
|
||||
"phoenix": {:hex, :phoenix, "1.7.10", "02189140a61b2ce85bb633a9b6fd02dff705a5f1596869547aeb2b2b95edd729", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.6", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "cf784932e010fd736d656d7fead6a584a4498efefe5b8227e9f383bf15bb79d0"},
|
||||
"phoenix": {:hex, :phoenix, "1.7.11", "1d88fc6b05ab0c735b250932c4e6e33bfa1c186f76dcf623d8dd52f07d6379c7", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.7", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:websock_adapter, "~> 0.5.3", [hex: :websock_adapter, repo: "hexpm", optional: false]}], "hexpm", "b1ec57f2e40316b306708fe59b92a16b9f6f4bf50ccfa41aa8c7feb79e0ec02a"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.3", "86e9878f833829c3f66da03d75254c155d91d72a201eb56ae83482328dc7ca93", [:mix], [{:ecto, "~> 3.5", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d36c401206f3011fefd63d04e8ef626ec8791975d9d107f9a0817d426f61ac07"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "3.3.3", "380b8fb45912b5638d2f1d925a3771b4516b9a78587249cabe394e0a5d579dc9", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "923ebe6fec6e2e3b3e569dfbdc6560de932cd54b000ada0208b5f45024bdd76c"},
|
||||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [: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", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "0.20.3", "8b6406bc0a451f295407d7acff7f234a6314be5bbe0b3f90ed82b07f50049878", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a8e4385e05618b424779f894ed2df97d3c7518b7285fcd11979077ae6226466b"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "0.20.10", "a790858cf9b63815bb93d1748e26c73f0c7f09f20873562f4f307dd52b0ca32f", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:plug, "~> 1.15", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "daa17b3fbdfd6347aaade4db01a5dd24d23af0f4344e2e24934e8adfb4a11607"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.3", "3168d78ba41835aecad272d5e8cd51aa87a7ac9eb836eabc42f6e57538e3731d", [:mix], [], "hexpm", "bba06bc1dcfd8cb086759f0edc94a8ba2bc8896d5331a1e2c2902bf8e36ee502"},
|
||||
"phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.0", "a544d83fde4a767efb78f45404a74c9e37b2a9c5ea3339692e65a6966731f935", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "e88d117251e89a16b92222415a6d87b99a96747ddf674fc5c7631de734811dba"},
|
||||
"phoenix_swoosh": {:hex, :phoenix_swoosh, "1.2.1", "b74ccaa8046fbc388a62134360ee7d9742d5a8ae74063f34eb050279de7a99e1", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4000eeba3f9d7d1a6bf56d2bd56733d5cadf41a7f0d8ffe5bb67e7d667e204a2"},
|
||||
"phoenix_template": {:hex, :phoenix_template, "1.0.4", "e2092c132f3b5e5b2d49c96695342eb36d0ed514c5b252a77048d5969330d639", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "2c0c81f0e5c6753faf5cca2f229c9709919aba34fab866d3bc05060c9c444206"},
|
||||
"phoenix_view": {:hex, :phoenix_view, "2.0.3", "4d32c4817fce933693741deeb99ef1392619f942633dde834a5163124813aad3", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "cd34049af41be2c627df99cd4eaa71fc52a328c0c3d8e7d4aa28f880c30e7f64"},
|
||||
"plug": {:hex, :plug, "1.15.2", "94cf1fa375526f30ff8770837cb804798e0045fd97185f0bb9e5fcd858c792a3", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "02731fa0c2dcb03d8d21a1d941bdbbe99c2946c0db098eee31008e04c6283615"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"},
|
||||
"plug": {:hex, :plug, "1.15.3", "712976f504418f6dff0a3e554c40d705a9bcf89a7ccef92fc6a5ef8f16a30a97", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cc4365a3c010a56af402e0809208873d113e9c38c401cabd88027ef4f5c01fd2"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"},
|
||||
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
|
||||
"postgrex": {:hex, :postgrex, "0.17.4", "5777781f80f53b7c431a001c8dad83ee167bcebcf3a793e3906efff680ab62b3", [:mix], [{: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]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "6458f7d5b70652bc81c3ea759f91736c16a31be000f306d3c64bcdfe9a18b3cc"},
|
||||
"progress_bar": {:hex, :progress_bar, "3.0.0", "f54ff038c2ac540cfbb4c2bfe97c75e7116ead044f3c2b10c9f212452194b5cd", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "6981c2b25ab24aecc91a2dc46623658e1399c21a2ae24db986b90d678530f2b7"},
|
||||
"rajska": {:git, "https://github.com/tcitworld/rajska.git", "0c036448e261e8be6a512581c592fadf48982d84", [branch: "mobilizon"]},
|
||||
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
|
||||
"ranch": {:hex, :ranch, "2.1.0", "2261f9ed9574dcfcc444106b9f6da155e6e540b2f82ba3d42b339b93673b72a3", [:make, :rebar3], [], "hexpm", "244ee3fa2a6175270d8e1fc59024fd9dbc76294a321057de8f803b1479e76916"},
|
||||
"remote_ip": {:hex, :remote_ip, "1.1.0", "cb308841595d15df3f9073b7c39243a1dd6ca56e5020295cb012c76fbec50f2d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "616ffdf66aaad6a72fc546dabf42eed87e2a99e97b09cbd92b10cc180d02ed74"},
|
||||
"replug": {:hex, :replug, "0.1.0", "61d35f8c873c0078a23c49579a48f36e45789414b1ec0daee3fd5f4e34221f23", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f71f7a57e944e854fe4946060c6964098e53958074c69fb844b96e0bd58cfa60"},
|
||||
"sentry": {:hex, :sentry, "8.1.0", "8d235b62fce5f8e067ea1644e30939405b71a5e1599d9529ff82899d11d03f2b", [: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", "f9fc7641ef61e885510f5e5963c2948b9de1de597c63f781e9d3d6c9c8681ab4"},
|
||||
"shortuuid": {:hex, :shortuuid, "3.0.0", "028684d9eeed0ad4b800e8481afd854e1a61c526f35952455b2ee4248601e7b8", [:mix], [], "hexpm", "dfd8f80f514cbb91622cb83f4ac0d6e2f06d98cc6d4aeba94444a212289d0d39"},
|
||||
"sitemapper": {:hex, :sitemapper, "0.7.0", "4aee7930327a9a01b1c9b81d1d42f60c1a295e9f420108eb2d130c317415abd7", [:mix], [{:ex_aws_s3, "~> 2.0", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:xml_builder, "~> 2.1", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "60f7a684e5e9fe7f10ac5b69f48b0be2bcbba995afafcb3c143fc0c8ef1f223f"},
|
||||
"sitemapper": {:hex, :sitemapper, "0.8.0", "50c8c85ed38c013829ce700e8a8d195a2faf4aed8685659b14529dcb6f91fee0", [:mix], [{:ex_aws_s3, "~> 2.0", [hex: :ex_aws_s3, repo: "hexpm", optional: true]}, {:xml_builder, "~> 2.1", [hex: :xml_builder, repo: "hexpm", optional: false]}], "hexpm", "7cd42b454035da457151c9b6a314b688b5bbe5383add95badc65d013c25989c5"},
|
||||
"sleeplocks": {:hex, :sleeplocks, "1.1.2", "d45aa1c5513da48c888715e3381211c859af34bee9b8290490e10c90bb6ff0ca", [:rebar3], [], "hexpm", "9fe5d048c5b781d6305c1a3a0f40bb3dfc06f49bf40571f3d2d0c57eaa7f59a5"},
|
||||
"slugger": {:hex, :slugger, "0.3.0", "efc667ab99eee19a48913ccf3d038b1fb9f165fa4fbf093be898b8099e61b6ed", [:mix], [], "hexpm", "20d0ded0e712605d1eae6c5b4889581c3460d92623a930ddda91e0e609b5afba"},
|
||||
"slugify": {:hex, :slugify, "1.3.1", "0d3b8b7e5c1eeaa960e44dce94382bee34a39b3ea239293e457a9c5b47cc6fd3", [:mix], [], "hexpm", "cb090bbeb056b312da3125e681d98933a360a70d327820e4b7f91645c4d8be76"},
|
||||
|
@ -135,14 +133,15 @@
|
|||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"},
|
||||
"struct_access": {:hex, :struct_access, "1.1.2", "a42e6ceedd9b9ea090ee94a6da089d56e16f374dbbc010c3eebdf8be17df286f", [:mix], [], "hexpm", "e4c411dcc0226081b95709909551fc92b8feb1a3476108348ea7e3f6c12e586a"},
|
||||
"sweet_xml": {:hex, :sweet_xml, "0.7.4", "a8b7e1ce7ecd775c7e8a65d501bc2cd933bff3a9c41ab763f5105688ef485d08", [:mix], [], "hexpm", "e7c4b0bdbf460c928234951def54fe87edf1a170f6896675443279e2dbeba167"},
|
||||
"swoosh": {:hex, :swoosh, "1.14.3", "949e6bf6dd469449238a94ec6f19ec10b63fc8753de7f3ebe3d3aeaf772f4c6b", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6c565103fc8f086bdd96e5c948660af8e20922b7a90a75db261f06a34f805c8b"},
|
||||
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
|
||||
"swoosh": {:hex, :swoosh, "1.15.3", "5c3f05b6e4e08cd4f75ad7e90db3c2b73c9d9de00503cce36a694951c2d69185", [:mix], [{:bandit, ">= 1.0.0", [hex: :bandit, repo: "hexpm", optional: true]}, {:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:req, "~> 0.4 or ~> 1.0", [hex: :req, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "97a667b96ca8cc48a4679f6cd1f40a36d8701cf052587298473614caa70f164a"},
|
||||
"telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"},
|
||||
"tesla": {:hex, :tesla, "1.8.0", "d511a4f5c5e42538d97eef7c40ec4f3e44effdc5068206f42ed859e09e51d1fd", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, ">= 1.0.0", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.2", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "10501f360cd926a309501287470372af1a6e1cbed0f43949203a4c13300bc79f"},
|
||||
"thousand_island": {:hex, :thousand_island, "1.3.5", "6022b6338f1635b3d32406ff98d68b843ba73b3aa95cfc27154223244f3a6ca5", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2be6954916fdfe4756af3239fb6b6d75d0b8063b5df03ba76fd8a4c87849e180"},
|
||||
"timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"},
|
||||
"tls_certificate_check": {:hex, :tls_certificate_check, "1.21.0", "042ab2c0c860652bc5cf69c94e3a31f96676d14682e22ec7813bd173ceff1788", [:rebar3], [{:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "6cee6cffc35a390840d48d463541d50746a7b0e421acaadb833cfc7961e490e7"},
|
||||
"tz_world": {:hex, :tz_world, "1.3.2", "15d331ad1ff22735dfcc8c98bfc7b2a9fdc17f1f071e31e21cdafe2d9318a300", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:geo, "~> 1.0 or ~> 2.0 or ~> 3.3", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d1a345e07b3378c4c902ad54fbd5d54c8c3dd55dba883b7407fe57bcec45ff2a"},
|
||||
"tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"},
|
||||
"ueberauth": {:hex, :ueberauth, "0.10.8", "ba78fbcbb27d811a6cd06ad851793aaf7d27c3b30c9e95349c2c362b344cd8f0", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f2d3172e52821375bccb8460e5fa5cb91cfd60b19b636b6e57e9759b6f8c10c1"},
|
||||
"ueberauth_cas": {:hex, :ueberauth_cas, "2.3.1", "df45a1f2c5df8bc80191cbca4baeeed808d697702ec5ebe5bd5d5a264481752f", [:mix], [{:httpoison, "~> 1.8", [hex: :httpoison, repo: "hexpm", optional: false]}, {:sweet_xml, "~> 0.7", [hex: :sweet_xml, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.6", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "5068ae2b9e217c2f05aa9a67483a6531e21ba0be9a6f6c8749bb7fd1599be321"},
|
||||
"ueberauth_discord": {:hex, :ueberauth_discord, "0.7.0", "463f6dfe1ed10a76739331ce8e1dd3600ab611f10524dd828eb3aa50e76e9d43", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "d6f98ef91abb4ddceada4b7acba470e0e68c4d2de9735ff2f24172a8e19896b4"},
|
||||
"ueberauth_facebook": {:hex, :ueberauth_facebook, "0.10.0", "0d607fbd1b7c6e0449981571027d869c2d156b8ad20c42e3672346678c05ccf1", [:mix], [{:oauth2, "~> 1.0 or ~> 2.0", [hex: :oauth2, repo: "hexpm", optional: false]}, {:ueberauth, "~> 0.7", [hex: :ueberauth, repo: "hexpm", optional: false]}], "hexpm", "bf8ce5d66b1c50da8abff77e8086c1b710bdde63f4acaef19a651ba43a9537a8"},
|
||||
|
|
3253
package-lock.json
generated
3253
package-lock.json
generated
File diff suppressed because it is too large
Load diff
31
package.json
31
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mobilizon",
|
||||
"version": "4.0.2",
|
||||
"version": "5.0.0-beta.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
@ -27,17 +27,17 @@
|
|||
"mix credo"
|
||||
]
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.3.16",
|
||||
"@apollo/client": "^3.9.5",
|
||||
"@framasoft/socket": "^1.0.0",
|
||||
"@framasoft/socket-apollo-link": "^1.0.0",
|
||||
"@oruga-ui/oruga-next": "0.8.12",
|
||||
"@oruga-ui/theme-oruga": "^0.2.0",
|
||||
"@fullcalendar/core": "^6.1.10",
|
||||
"@fullcalendar/daygrid": "^6.1.10",
|
||||
"@fullcalendar/icalendar": "^6.1.10",
|
||||
"@fullcalendar/interaction": "^6.1.10",
|
||||
"@fullcalendar/vue3": "^6.1.10",
|
||||
"@oruga-ui/oruga-next": "^0.8.2",
|
||||
"@oruga-ui/theme-oruga": "^0.2.0",
|
||||
"@sentry/tracing": "^7.1",
|
||||
"@sentry/vue": "^7.1",
|
||||
"@tiptap/core": "^2.0.0-beta.41",
|
||||
|
@ -77,7 +77,7 @@
|
|||
"blurhash": "^2.0.0",
|
||||
"date-fns": "^2.16.0",
|
||||
"date-fns-tz": "^2.0.0",
|
||||
"floating-vue": "^2.0.0-beta.24",
|
||||
"floating-vue": "^5.0.0",
|
||||
"graphql": "^16.8.1",
|
||||
"graphql-tag": "^2.10.3",
|
||||
"hammerjs": "^2.0.8",
|
||||
|
@ -90,6 +90,7 @@
|
|||
"lodash": "^4.17.11",
|
||||
"ngeohash": "^0.6.3",
|
||||
"p-debounce": "^4.0.0",
|
||||
"patch-package": "^8.0.0",
|
||||
"phoenix": "^1.6",
|
||||
"postcss": "^8",
|
||||
"register-service-worker": "^1.7.2",
|
||||
|
@ -97,7 +98,7 @@
|
|||
"tailwindcss": "^3",
|
||||
"tippy.js": "^6.2.3",
|
||||
"unfetch": "^5.0.0",
|
||||
"vue": "^3.2.37",
|
||||
"vue": "^3.4.20",
|
||||
"vue-i18n": "9",
|
||||
"vue-material-design-icons": "^5.1.2",
|
||||
"vue-matomo": "^4.1.0",
|
||||
|
@ -121,9 +122,9 @@
|
|||
"@types/ngeohash": "^0.6.2",
|
||||
"@types/phoenix": "^1.5.2",
|
||||
"@types/sanitize-html": "^2.5.0",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vitest/coverage-v8": "^0.34.1",
|
||||
"@vitest/ui": "^0.34.1",
|
||||
"@vitejs/plugin-vue": "^5.0.0",
|
||||
"@vitest/coverage-v8": "^1.2.2",
|
||||
"@vitest/ui": "^1.2.2",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
"@vue/test-utils": "^2.0.2",
|
||||
|
@ -134,8 +135,8 @@
|
|||
"eslint-plugin-vue": "^9.3.0",
|
||||
"flush-promises": "^1.0.2",
|
||||
"histoire": "^0.17.0",
|
||||
"husky": "^8.0.3",
|
||||
"jsdom": "^22.0.0",
|
||||
"husky": "^9.0.10",
|
||||
"jsdom": "^24.0.0",
|
||||
"lint-staged": "^15.1.0",
|
||||
"mock-apollo-client": "^1.1.0",
|
||||
"prettier": "^3.0.0",
|
||||
|
@ -143,10 +144,10 @@
|
|||
"rollup-plugin-visualizer": "^5.7.1",
|
||||
"sass": "^1.34.1",
|
||||
"typescript": "~5.3.2",
|
||||
"vite": "^4.5.0",
|
||||
"vite-plugin-pwa": "^0.17.0",
|
||||
"vite": "^5.0.12",
|
||||
"vite-svg-loader": "^4.0.0",
|
||||
"vitest": "^0.34.1",
|
||||
"vite-plugin-pwa": "^0.19.0",
|
||||
"vitest": "^1.2.2",
|
||||
"vue-i18n-extract": "^2.0.4",
|
||||
"vue-router-mock": "^1.0.0"
|
||||
}
|
||||
|
|
66
patches/vue-i18n-extract+2.0.7.patch
Normal file
66
patches/vue-i18n-extract+2.0.7.patch
Normal file
|
@ -0,0 +1,66 @@
|
|||
diff --git a/node_modules/vue-i18n-extract/dist/vue-i18n-extract.modern.mjs b/node_modules/vue-i18n-extract/dist/vue-i18n-extract.modern.mjs
|
||||
index 670733e..872d1af 100644
|
||||
--- a/node_modules/vue-i18n-extract/dist/vue-i18n-extract.modern.mjs
|
||||
+++ b/node_modules/vue-i18n-extract/dist/vue-i18n-extract.modern.mjs
|
||||
@@ -38,7 +38,7 @@ var defaultConfig = {
|
||||
};
|
||||
|
||||
function initCommand() {
|
||||
- fs.writeFileSync(path.resolve(process.cwd(), './vue-i18n-extract.config.js'), `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`);
|
||||
+ fs.writeFileSync(path.resolve(process.cwd(), './vue-i18n-extract.config.cjs'), `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`);
|
||||
}
|
||||
function resolveConfig() {
|
||||
const argvOptions = cac().parse(process.argv, {
|
||||
@@ -47,7 +47,7 @@ function resolveConfig() {
|
||||
let options;
|
||||
|
||||
try {
|
||||
- const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js'); // eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
+ const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.cjs'); // eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
|
||||
const configOptions = require(pathToConfigFile);
|
||||
|
||||
diff --git a/node_modules/vue-i18n-extract/dist/vue-i18n-extract.umd.js b/node_modules/vue-i18n-extract/dist/vue-i18n-extract.umd.js
|
||||
index ca19c7a..11cb846 100644
|
||||
--- a/node_modules/vue-i18n-extract/dist/vue-i18n-extract.umd.js
|
||||
+++ b/node_modules/vue-i18n-extract/dist/vue-i18n-extract.umd.js
|
||||
@@ -45,7 +45,7 @@
|
||||
};
|
||||
|
||||
function initCommand() {
|
||||
- fs__default["default"].writeFileSync(path__default["default"].resolve(process.cwd(), './vue-i18n-extract.config.js'), `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`);
|
||||
+ fs__default["default"].writeFileSync(path__default["default"].resolve(process.cwd(), './vue-i18n-extract.config.cjs'), `module.exports = ${JSON.stringify(defaultConfig, null, 2)}`);
|
||||
}
|
||||
function resolveConfig() {
|
||||
const argvOptions = cac__default["default"]().parse(process.argv, {
|
||||
@@ -54,7 +54,7 @@
|
||||
let options;
|
||||
|
||||
try {
|
||||
- const pathToConfigFile = path__default["default"].resolve(process.cwd(), './vue-i18n-extract.config.js'); // eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
+ const pathToConfigFile = path__default["default"].resolve(process.cwd(), './vue-i18n-extract.config.cjs'); // eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
|
||||
const configOptions = require(pathToConfigFile);
|
||||
|
||||
diff --git a/node_modules/vue-i18n-extract/src/config-file/index.ts b/node_modules/vue-i18n-extract/src/config-file/index.ts
|
||||
index 3db836f..744bd74 100644
|
||||
--- a/node_modules/vue-i18n-extract/src/config-file/index.ts
|
||||
+++ b/node_modules/vue-i18n-extract/src/config-file/index.ts
|
||||
@@ -5,7 +5,7 @@ import defaultConfig from './vue-i18n-extract.config';
|
||||
|
||||
export function initCommand(): void {
|
||||
fs.writeFileSync(
|
||||
- path.resolve(process.cwd(), './vue-i18n-extract.config.js'),
|
||||
+ path.resolve(process.cwd(), './vue-i18n-extract.config.cjs'),
|
||||
`module.exports = ${JSON.stringify(defaultConfig, null, 2)}`,
|
||||
);
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export function resolveConfig (): Record<string, string> {
|
||||
let options;
|
||||
|
||||
try {
|
||||
- const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.js');
|
||||
+ const pathToConfigFile = path.resolve(process.cwd(), './vue-i18n-extract.config.cjs');
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const configOptions = require(pathToConfigFile);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = {
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
|
|
|
@ -214,7 +214,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/email_direct_activity.html.heex:230
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:23
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "View one more activity"
|
||||
msgid_plural "View %{count} more activities"
|
||||
msgstr[0] ""
|
||||
|
@ -224,7 +224,7 @@ msgstr[1] ""
|
|||
#: lib/web/templates/email/email_direct_activity.html.heex:60
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:6
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:7
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "There has been an activity!"
|
||||
msgid_plural "There has been some activity!"
|
||||
msgstr[0] ""
|
||||
|
|
|
@ -216,7 +216,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/email_direct_activity.html.heex:230
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:23
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "View one more activity"
|
||||
msgid_plural "View %{count} more activities"
|
||||
msgstr[0] ""
|
||||
|
@ -230,7 +230,7 @@ msgstr[5] ""
|
|||
#: lib/web/templates/email/email_direct_activity.html.heex:60
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:6
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:7
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "There has been an activity!"
|
||||
msgid_plural "There has been some activity!"
|
||||
msgstr[0] ""
|
||||
|
|
|
@ -317,7 +317,7 @@ msgid "Mobilizon on %{instance}: email changed"
|
|||
msgstr ""
|
||||
|
||||
#: lib/web/email/notification.ex:52
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned today"
|
||||
msgid_plural "%{nb_events} events planned today"
|
||||
msgstr[0] ""
|
||||
|
@ -329,7 +329,7 @@ msgstr[5] ""
|
|||
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:47
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event today:"
|
||||
msgid_plural "You have %{total} events today:"
|
||||
msgstr[0] ""
|
||||
|
@ -383,7 +383,7 @@ msgid "You have been invited by %{inviter} to join group %{group}"
|
|||
msgstr ""
|
||||
|
||||
#: lib/web/email/notification.ex:81
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned this week"
|
||||
msgid_plural "%{nb_events} events planned this week"
|
||||
msgstr[0] ""
|
||||
|
@ -394,7 +394,7 @@ msgstr[4] ""
|
|||
msgstr[5] ""
|
||||
|
||||
#: lib/web/email/notification.ex:107
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One participation request for event %{title} to process"
|
||||
msgid_plural "%{number_participation_requests} participation requests for event %{title} to process"
|
||||
msgstr[0] ""
|
||||
|
@ -406,7 +406,7 @@ msgstr[5] ""
|
|||
|
||||
#: lib/web/templates/email/notification_each_week.html.heex:47
|
||||
#: lib/web/templates/email/notification_each_week.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event this week:"
|
||||
msgid_plural "You have %{total} events this week:"
|
||||
msgstr[0] ""
|
||||
|
@ -776,7 +776,7 @@ msgstr ""
|
|||
#: lib/web/templates/email/notification_each_week.text.eex:11
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:89
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:11
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "Would you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
|
||||
msgid_plural "Would you wish to cancel your attendance to one or several events, visit the event pages through the links above and click the « Attending » button."
|
||||
msgstr[0] ""
|
||||
|
@ -1076,7 +1076,7 @@ msgstr ""
|
|||
msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/email/group.ex:108
|
||||
#: lib/web/email/group.ex:106
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The group %{group} has been suspended on %{instance}"
|
||||
msgstr ""
|
||||
|
@ -1160,12 +1160,6 @@ msgctxt "terms"
|
|||
msgid "We reserve the right to modify these Terms at any time. For instance, we may need to change these Terms if we come out with a new feature."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a French not-for-profit organization advocating for Free/Libre Software. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:105
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
|
@ -1650,7 +1644,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/pending_participation_notification.html.heex:47
|
||||
#: lib/web/templates/email/pending_participation_notification.text.eex:4
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one pending attendance request to process for the following event:"
|
||||
msgid_plural "You have %{number_participation_requests} attendance requests to process for the following event:"
|
||||
msgstr[0] ""
|
||||
|
@ -2048,3 +2042,9 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Well done!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
|
|
|
@ -207,13 +207,13 @@ msgstr ""
|
|||
msgid "The current password is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:334
|
||||
#: lib/graphql/resolvers/admin.ex:335
|
||||
#: lib/graphql/resolvers/user.ex:527
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email doesn't seem to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:323
|
||||
#: lib/graphql/resolvers/admin.ex:324
|
||||
#: lib/graphql/resolvers/user.ex:514
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email must be different"
|
||||
|
@ -647,7 +647,7 @@ msgstr ""
|
|||
msgid "You don't have permission to delete this token"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:56
|
||||
#: lib/graphql/resolvers/admin.ex:57
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and a moderator to list action logs"
|
||||
msgstr ""
|
||||
|
@ -667,17 +667,17 @@ msgstr ""
|
|||
msgid "You need to be logged-in and a moderator to view a report"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:258
|
||||
#: lib/graphql/resolvers/admin.ex:259
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access admin settings"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:242
|
||||
#: lib/graphql/resolvers/admin.ex:243
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access dashboard statistics"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:283
|
||||
#: lib/graphql/resolvers/admin.ex:284
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to save admin settings"
|
||||
msgstr ""
|
||||
|
@ -964,7 +964,7 @@ msgstr ""
|
|||
msgid "Failed to update the group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:357
|
||||
#: lib/graphql/resolvers/admin.ex:358
|
||||
#: lib/graphql/resolvers/user.ex:547
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Failed to update user email"
|
||||
|
@ -1095,22 +1095,22 @@ msgstr ""
|
|||
msgid "Your email seems to be using an invalid format"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:399
|
||||
#: lib/graphql/resolvers/admin.ex:400
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Can't confirm an already confirmed user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:403
|
||||
#: lib/graphql/resolvers/admin.ex:404
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deconfirming users is not supported"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:375
|
||||
#: lib/graphql/resolvers/admin.ex:376
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "The new role must be different"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:314
|
||||
#: lib/graphql/resolvers/admin.ex:315
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You need to be logged-in and an administrator to edit an user's details"
|
||||
msgstr ""
|
||||
|
@ -1120,7 +1120,7 @@ msgstr ""
|
|||
msgid "A profile or group with that name already exists"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:542
|
||||
#: lib/graphql/resolvers/admin.ex:560
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Unable to find an instance to follow at this address"
|
||||
msgstr ""
|
||||
|
@ -1382,7 +1382,7 @@ msgstr ""
|
|||
msgid "The same push subscription has already been registered"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:536
|
||||
#: lib/graphql/resolvers/admin.ex:554
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "This instance is pending follow approval"
|
||||
msgstr ""
|
||||
|
@ -1392,7 +1392,7 @@ msgstr ""
|
|||
msgid "Timezone ID %{timezone} is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:539
|
||||
#: lib/graphql/resolvers/admin.ex:557
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You are already following this instance"
|
||||
msgstr ""
|
||||
|
@ -1412,12 +1412,12 @@ msgstr ""
|
|||
msgid "The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/conversation.ex:161
|
||||
#: lib/graphql/resolvers/conversation.ex:164
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Conversation needs to mention at least one participant that's not yourself"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/participant.ex:396
|
||||
#: lib/graphql/resolvers/participant.ex:401
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "There are no participants matching the audience you've selected."
|
||||
msgstr ""
|
||||
|
|
|
@ -215,7 +215,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/email_direct_activity.html.heex:230
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:23
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "View one more activity"
|
||||
msgid_plural "View %{count} more activities"
|
||||
msgstr[0] ""
|
||||
|
@ -226,7 +226,7 @@ msgstr[2] ""
|
|||
#: lib/web/templates/email/email_direct_activity.html.heex:60
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:6
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:7
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "There has been an activity!"
|
||||
msgid_plural "There has been some activity!"
|
||||
msgstr[0] ""
|
||||
|
|
|
@ -315,7 +315,7 @@ msgid "Mobilizon on %{instance}: email changed"
|
|||
msgstr ""
|
||||
|
||||
#: lib/web/email/notification.ex:52
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned today"
|
||||
msgid_plural "%{nb_events} events planned today"
|
||||
msgstr[0] ""
|
||||
|
@ -324,7 +324,7 @@ msgstr[2] ""
|
|||
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:47
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event today:"
|
||||
msgid_plural "You have %{total} events today:"
|
||||
msgstr[0] ""
|
||||
|
@ -375,7 +375,7 @@ msgid "You have been invited by %{inviter} to join group %{group}"
|
|||
msgstr ""
|
||||
|
||||
#: lib/web/email/notification.ex:81
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned this week"
|
||||
msgid_plural "%{nb_events} events planned this week"
|
||||
msgstr[0] ""
|
||||
|
@ -383,7 +383,7 @@ msgstr[1] ""
|
|||
msgstr[2] ""
|
||||
|
||||
#: lib/web/email/notification.ex:107
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One participation request for event %{title} to process"
|
||||
msgid_plural "%{number_participation_requests} participation requests for event %{title} to process"
|
||||
msgstr[0] ""
|
||||
|
@ -392,7 +392,7 @@ msgstr[2] ""
|
|||
|
||||
#: lib/web/templates/email/notification_each_week.html.heex:47
|
||||
#: lib/web/templates/email/notification_each_week.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event this week:"
|
||||
msgid_plural "You have %{total} events this week:"
|
||||
msgstr[0] ""
|
||||
|
@ -759,7 +759,7 @@ msgstr ""
|
|||
#: lib/web/templates/email/notification_each_week.text.eex:11
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:89
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:11
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "Would you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
|
||||
msgid_plural "Would you wish to cancel your attendance to one or several events, visit the event pages through the links above and click the « Attending » button."
|
||||
msgstr[0] ""
|
||||
|
@ -1056,7 +1056,7 @@ msgstr ""
|
|||
msgid "Your instance's moderation team has decided to suspend %{group_name} (%{group_address}). You are no longer a member of this group."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/email/group.ex:108
|
||||
#: lib/web/email/group.ex:106
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The group %{group} has been suspended on %{instance}"
|
||||
msgstr ""
|
||||
|
@ -1140,12 +1140,6 @@ msgctxt "terms"
|
|||
msgid "We reserve the right to modify these Terms at any time. For instance, we may need to change these Terms if we come out with a new feature."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a French not-for-profit organization advocating for Free/Libre Software. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:105
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
|
@ -1630,7 +1624,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/pending_participation_notification.html.heex:47
|
||||
#: lib/web/templates/email/pending_participation_notification.text.eex:4
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one pending attendance request to process for the following event:"
|
||||
msgid_plural "You have %{number_participation_requests} attendance requests to process for the following event:"
|
||||
msgstr[0] ""
|
||||
|
@ -2025,3 +2019,9 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Well done!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
|
|
|
@ -181,13 +181,13 @@ msgstr ""
|
|||
msgid "The current password is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:334
|
||||
#: lib/graphql/resolvers/admin.ex:335
|
||||
#: lib/graphql/resolvers/user.ex:527
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email doesn't seem to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:323
|
||||
#: lib/graphql/resolvers/admin.ex:324
|
||||
#: lib/graphql/resolvers/user.ex:514
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email must be different"
|
||||
|
@ -621,7 +621,7 @@ msgstr ""
|
|||
msgid "You don't have permission to delete this token"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:56
|
||||
#: lib/graphql/resolvers/admin.ex:57
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and a moderator to list action logs"
|
||||
msgstr ""
|
||||
|
@ -641,17 +641,17 @@ msgstr ""
|
|||
msgid "You need to be logged-in and a moderator to view a report"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:258
|
||||
#: lib/graphql/resolvers/admin.ex:259
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access admin settings"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:242
|
||||
#: lib/graphql/resolvers/admin.ex:243
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access dashboard statistics"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:283
|
||||
#: lib/graphql/resolvers/admin.ex:284
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to save admin settings"
|
||||
msgstr ""
|
||||
|
@ -938,7 +938,7 @@ msgstr ""
|
|||
msgid "Failed to update the group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:357
|
||||
#: lib/graphql/resolvers/admin.ex:358
|
||||
#: lib/graphql/resolvers/user.ex:547
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Failed to update user email"
|
||||
|
@ -1069,22 +1069,22 @@ msgstr ""
|
|||
msgid "Your email seems to be using an invalid format"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:399
|
||||
#: lib/graphql/resolvers/admin.ex:400
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Can't confirm an already confirmed user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:403
|
||||
#: lib/graphql/resolvers/admin.ex:404
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deconfirming users is not supported"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:375
|
||||
#: lib/graphql/resolvers/admin.ex:376
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "The new role must be different"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:314
|
||||
#: lib/graphql/resolvers/admin.ex:315
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You need to be logged-in and an administrator to edit an user's details"
|
||||
msgstr ""
|
||||
|
@ -1094,7 +1094,7 @@ msgstr ""
|
|||
msgid "A profile or group with that name already exists"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:542
|
||||
#: lib/graphql/resolvers/admin.ex:560
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Unable to find an instance to follow at this address"
|
||||
msgstr ""
|
||||
|
@ -1356,7 +1356,7 @@ msgstr ""
|
|||
msgid "The same push subscription has already been registered"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:536
|
||||
#: lib/graphql/resolvers/admin.ex:554
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "This instance is pending follow approval"
|
||||
msgstr ""
|
||||
|
@ -1366,7 +1366,7 @@ msgstr ""
|
|||
msgid "Timezone ID %{timezone} is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:539
|
||||
#: lib/graphql/resolvers/admin.ex:557
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You are already following this instance"
|
||||
msgstr ""
|
||||
|
@ -1386,12 +1386,12 @@ msgstr ""
|
|||
msgid "The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/conversation.ex:161
|
||||
#: lib/graphql/resolvers/conversation.ex:164
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Conversation needs to mention at least one participant that's not yourself"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/participant.ex:396
|
||||
#: lib/graphql/resolvers/participant.ex:401
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "There are no participants matching the audience you've selected."
|
||||
msgstr ""
|
||||
|
|
|
@ -222,7 +222,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/email_direct_activity.html.heex:230
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:23
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "View one more activity"
|
||||
msgid_plural "View %{count} more activities"
|
||||
msgstr[0] ""
|
||||
|
@ -232,7 +232,7 @@ msgstr[1] ""
|
|||
#: lib/web/templates/email/email_direct_activity.html.heex:60
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:6
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:7
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "There has been an activity!"
|
||||
msgid_plural "There has been some activity!"
|
||||
msgstr[0] ""
|
||||
|
|
|
@ -358,7 +358,7 @@ msgid "Mobilizon on %{instance}: email changed"
|
|||
msgstr "Mobilizon a %{instance}: s'ha canviat l'adreça de correu"
|
||||
|
||||
#: lib/web/email/notification.ex:52
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned today"
|
||||
msgid_plural "%{nb_events} events planned today"
|
||||
msgstr[0] "Una activitat planificada per avui"
|
||||
|
@ -366,7 +366,7 @@ msgstr[1] "%{nb_events} activitats planificades avui"
|
|||
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:47
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event today:"
|
||||
msgid_plural "You have %{total} events today:"
|
||||
msgstr[0] "Tens una activitat avui:"
|
||||
|
@ -416,14 +416,14 @@ msgid "You have been invited by %{inviter} to join group %{group}"
|
|||
msgstr "%{inviter} t'ha convidat al grup %{group}"
|
||||
|
||||
#: lib/web/email/notification.ex:81
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned this week"
|
||||
msgid_plural "%{nb_events} events planned this week"
|
||||
msgstr[0] "Una activitat planificada per aquesta setmana"
|
||||
msgstr[1] "%{nb_events} planificades per aquesta setmana"
|
||||
|
||||
#: lib/web/email/notification.ex:107
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One participation request for event %{title} to process"
|
||||
msgid_plural "%{number_participation_requests} participation requests for event %{title} to process"
|
||||
msgstr[0] "Hi ha una soŀlicitud de participar a %{title} pendent de resoldre"
|
||||
|
@ -433,7 +433,7 @@ msgstr[1] ""
|
|||
|
||||
#: lib/web/templates/email/notification_each_week.html.heex:47
|
||||
#: lib/web/templates/email/notification_each_week.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event this week:"
|
||||
msgid_plural "You have %{total} events this week:"
|
||||
msgstr[0] "Tens una activitat aquesta setmana:"
|
||||
|
@ -925,7 +925,7 @@ msgstr "No ho facis servir més que proves, sisplau"
|
|||
#: lib/web/templates/email/notification_each_week.text.eex:11
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:89
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:11
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "Would you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
|
||||
msgid_plural "Would you wish to cancel your attendance to one or several events, visit the event pages through the links above and click the « Attending » button."
|
||||
msgstr[0] ""
|
||||
|
@ -1261,7 +1261,7 @@ msgstr ""
|
|||
"L'equip de moderació de la teva instància ha decidit suspendre el grup "
|
||||
"%{group_name} (%{group_address}). Ja no formes part del grup."
|
||||
|
||||
#: lib/web/email/group.ex:108
|
||||
#: lib/web/email/group.ex:106
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The group %{group} has been suspended on %{instance}"
|
||||
msgstr "El grup %{group} ha estat suspès a %{instance}"
|
||||
|
@ -1375,12 +1375,6 @@ msgctxt "terms"
|
|||
msgid "We reserve the right to modify these Terms at any time. For instance, we may need to change these Terms if we come out with a new feature."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a French not-for-profit organization advocating for Free/Libre Software. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:105
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
|
@ -1876,7 +1870,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/pending_participation_notification.html.heex:47
|
||||
#: lib/web/templates/email/pending_participation_notification.text.eex:4
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one pending attendance request to process for the following event:"
|
||||
msgid_plural "You have %{number_participation_requests} attendance requests to process for the following event:"
|
||||
msgstr[0] "Tens una soŀlicitud de participació pendent de resoldre:"
|
||||
|
@ -2283,3 +2277,9 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Well done!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
|
|
|
@ -182,13 +182,13 @@ msgstr ""
|
|||
msgid "The current password is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:334
|
||||
#: lib/graphql/resolvers/admin.ex:335
|
||||
#: lib/graphql/resolvers/user.ex:527
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email doesn't seem to be valid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:323
|
||||
#: lib/graphql/resolvers/admin.ex:324
|
||||
#: lib/graphql/resolvers/user.ex:514
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email must be different"
|
||||
|
@ -622,7 +622,7 @@ msgstr ""
|
|||
msgid "You don't have permission to delete this token"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:56
|
||||
#: lib/graphql/resolvers/admin.ex:57
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and a moderator to list action logs"
|
||||
msgstr ""
|
||||
|
@ -642,17 +642,17 @@ msgstr ""
|
|||
msgid "You need to be logged-in and a moderator to view a report"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:258
|
||||
#: lib/graphql/resolvers/admin.ex:259
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access admin settings"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:242
|
||||
#: lib/graphql/resolvers/admin.ex:243
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access dashboard statistics"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:283
|
||||
#: lib/graphql/resolvers/admin.ex:284
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to save admin settings"
|
||||
msgstr ""
|
||||
|
@ -939,7 +939,7 @@ msgstr ""
|
|||
msgid "Failed to update the group"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:357
|
||||
#: lib/graphql/resolvers/admin.ex:358
|
||||
#: lib/graphql/resolvers/user.ex:547
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Failed to update user email"
|
||||
|
@ -1070,22 +1070,22 @@ msgstr ""
|
|||
msgid "Your email seems to be using an invalid format"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:399
|
||||
#: lib/graphql/resolvers/admin.ex:400
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Can't confirm an already confirmed user"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:403
|
||||
#: lib/graphql/resolvers/admin.ex:404
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deconfirming users is not supported"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:375
|
||||
#: lib/graphql/resolvers/admin.ex:376
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "The new role must be different"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:314
|
||||
#: lib/graphql/resolvers/admin.ex:315
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You need to be logged-in and an administrator to edit an user's details"
|
||||
msgstr ""
|
||||
|
@ -1095,7 +1095,7 @@ msgstr ""
|
|||
msgid "A profile or group with that name already exists"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:542
|
||||
#: lib/graphql/resolvers/admin.ex:560
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Unable to find an instance to follow at this address"
|
||||
msgstr ""
|
||||
|
@ -1357,7 +1357,7 @@ msgstr ""
|
|||
msgid "The same push subscription has already been registered"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:536
|
||||
#: lib/graphql/resolvers/admin.ex:554
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "This instance is pending follow approval"
|
||||
msgstr ""
|
||||
|
@ -1367,7 +1367,7 @@ msgstr ""
|
|||
msgid "Timezone ID %{timezone} is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:539
|
||||
#: lib/graphql/resolvers/admin.ex:557
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You are already following this instance"
|
||||
msgstr ""
|
||||
|
@ -1387,12 +1387,12 @@ msgstr ""
|
|||
msgid "The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/conversation.ex:161
|
||||
#: lib/graphql/resolvers/conversation.ex:164
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Conversation needs to mention at least one participant that's not yourself"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/participant.ex:396
|
||||
#: lib/graphql/resolvers/participant.ex:401
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "There are no participants matching the audience you've selected."
|
||||
msgstr ""
|
||||
|
|
|
@ -224,7 +224,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/email_direct_activity.html.heex:230
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:23
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "View one more activity"
|
||||
msgid_plural "View %{count} more activities"
|
||||
msgstr[0] "Zobrazit jednu další aktivitu"
|
||||
|
@ -235,7 +235,7 @@ msgstr[2] "Zobrazit %{count} dalších aktivit"
|
|||
#: lib/web/templates/email/email_direct_activity.html.heex:60
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:6
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:7
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "There has been an activity!"
|
||||
msgid_plural "There has been some activity!"
|
||||
msgstr[0] "Došlo k aktivitě!"
|
||||
|
|
|
@ -355,7 +355,7 @@ msgid "Mobilizon on %{instance}: email changed"
|
|||
msgstr "Mobilizon na %{instance}: e-mail změněn"
|
||||
|
||||
#: lib/web/email/notification.ex:52
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned today"
|
||||
msgid_plural "%{nb_events} events planned today"
|
||||
msgstr[0] "Na dnešek je naplánována jedna událost"
|
||||
|
@ -364,7 +364,7 @@ msgstr[2] "%{nb_events} událostí plánovaných na dnešek"
|
|||
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:47
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event today:"
|
||||
msgid_plural "You have %{total} events today:"
|
||||
msgstr[0] "Dnes máte jednu událost:"
|
||||
|
@ -415,7 +415,7 @@ msgid "You have been invited by %{inviter} to join group %{group}"
|
|||
msgstr "Byl/a jste pozván/a %{inviter} do skupiny %{group}"
|
||||
|
||||
#: lib/web/email/notification.ex:81
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One event planned this week"
|
||||
msgid_plural "%{nb_events} events planned this week"
|
||||
msgstr[0] "Tento týden je naplánována jedna akce"
|
||||
|
@ -423,7 +423,7 @@ msgstr[1] "%{nb_events} události plánované na tento týden"
|
|||
msgstr[2] "%{nb_events} událostí plánovaných na tento týden"
|
||||
|
||||
#: lib/web/email/notification.ex:107
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "One participation request for event %{title} to process"
|
||||
msgid_plural "%{number_participation_requests} participation requests for event %{title} to process"
|
||||
msgstr[0] "Jeden požadavek na účast pro událost %{title} ke zpracování"
|
||||
|
@ -436,7 +436,7 @@ msgstr[2] ""
|
|||
|
||||
#: lib/web/templates/email/notification_each_week.html.heex:47
|
||||
#: lib/web/templates/email/notification_each_week.text.eex:3
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one event this week:"
|
||||
msgid_plural "You have %{total} events this week:"
|
||||
msgstr[0] "Tento týden máte jednu událost:"
|
||||
|
@ -932,7 +932,7 @@ msgstr "Nepoužívejte ji pro skutečné účely."
|
|||
#: lib/web/templates/email/notification_each_week.text.eex:11
|
||||
#: lib/web/templates/email/on_day_notification.html.heex:89
|
||||
#: lib/web/templates/email/on_day_notification.text.eex:11
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "Would you wish to cancel your attendance, visit the event page through the link above and click the « Attending » button."
|
||||
msgid_plural "Would you wish to cancel your attendance to one or several events, visit the event pages through the links above and click the « Attending » button."
|
||||
msgstr[0] ""
|
||||
|
@ -1278,7 +1278,7 @@ msgstr ""
|
|||
"Moderátorský tým vaší instance se rozhodl pozastavit %{group_name} "
|
||||
"(%{group_address}). Již nejste členem této skupiny."
|
||||
|
||||
#: lib/web/email/group.ex:108
|
||||
#: lib/web/email/group.ex:106
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The group %{group} has been suspended on %{instance}"
|
||||
msgstr "Skupina %{group} byla pozastavena na %{instance}"
|
||||
|
@ -1403,20 +1403,6 @@ msgstr ""
|
|||
"Vyhrazujeme si právo tyto podmínky kdykoli změnit. Tyto podmínky můžeme "
|
||||
"například změnit, pokud přijdeme s novou funkcí."
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors, supported by <a href=\"https://framasoft.org\">Framasoft</a>, a French not-for-profit organization advocating for Free/Libre Software. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
"Když v tomto dokumentu říkáme \"my\", \"naše\" nebo \"nás\", máme na mysli "
|
||||
"vlastníky, provozovatele a správce této instance Mobilizon. Software "
|
||||
"Mobilizon je poskytován týmem přispěvatelů Mobilizonu, který je podporován "
|
||||
"<a href=\"https://framasoft.org\">Framasoft</a>, francouzskou neziskovou "
|
||||
"organizací prosazující svobodný software. Pokud to není výslovně uvedeno, je "
|
||||
"tato instance Mobilizonu nezávislou službou využívající zdrojový kód "
|
||||
"Mobilizonu. Více informací o této instanci najdete na stránce <a href=\"/"
|
||||
"about/instance\">\"O této instanci\"</a>."
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:105
|
||||
#, elixir-autogen, elixir-format
|
||||
msgctxt "terms"
|
||||
|
@ -1945,7 +1931,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/pending_participation_notification.html.heex:47
|
||||
#: lib/web/templates/email/pending_participation_notification.text.eex:4
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "You have one pending attendance request to process for the following event:"
|
||||
msgid_plural "You have %{number_participation_requests} attendance requests to process for the following event:"
|
||||
msgstr[0] ""
|
||||
|
@ -2376,3 +2362,17 @@ msgstr ""
|
|||
#, elixir-autogen, elixir-format
|
||||
msgid "Well done!"
|
||||
msgstr ""
|
||||
|
||||
#: lib/web/templates/api/terms.html.heex:55
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgctxt "terms"
|
||||
msgid "When we say “we”, “our”, or “us” in this document, we are referring to the owners, operators and administrators of this Mobilizon instance. The Mobilizon software is provided by the team of Mobilizon contributors. Unless explicitly stated, this Mobilizon instance is an independent service using Mobilizon's source code. You may find more information about this instance on the <a href=\"/about/instance\">\"About this instance\"</a> page."
|
||||
msgstr ""
|
||||
"Když v tomto dokumentu říkáme \"my\", \"naše\" nebo \"nás\", máme na mysli "
|
||||
"vlastníky, provozovatele a správce této instance Mobilizon. Software "
|
||||
"Mobilizon je poskytován týmem přispěvatelů Mobilizonu, který je podporován "
|
||||
"<a href=\"https://framasoft.org\">Framasoft</a>, francouzskou neziskovou "
|
||||
"organizací prosazující svobodný software. Pokud to není výslovně uvedeno, je "
|
||||
"tato instance Mobilizonu nezávislou službou využívající zdrojový kód "
|
||||
"Mobilizonu. Více informací o této instanci najdete na stránce <a href=\"/"
|
||||
"about/instance\">\"O této instanci\"</a>."
|
||||
|
|
|
@ -190,13 +190,13 @@ msgstr "Registrace nejsou otevřeny"
|
|||
msgid "The current password is invalid"
|
||||
msgstr "Aktuální heslo je neplatné"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:334
|
||||
#: lib/graphql/resolvers/admin.ex:335
|
||||
#: lib/graphql/resolvers/user.ex:527
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email doesn't seem to be valid"
|
||||
msgstr "Nový e-mail se nezdá být platný"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:323
|
||||
#: lib/graphql/resolvers/admin.ex:324
|
||||
#: lib/graphql/resolvers/user.ex:514
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new email must be different"
|
||||
|
@ -635,7 +635,7 @@ msgstr "Do této skupiny nelze zvát"
|
|||
msgid "You don't have permission to delete this token"
|
||||
msgstr "Nemáte oprávnění tento token odstranit"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:56
|
||||
#: lib/graphql/resolvers/admin.ex:57
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and a moderator to list action logs"
|
||||
msgstr ""
|
||||
|
@ -656,19 +656,19 @@ msgstr "Chcete-li aktualizovat zprávu, musíte být přihlášeni a být moder
|
|||
msgid "You need to be logged-in and a moderator to view a report"
|
||||
msgstr "Pro zobrazení zprávy musíte být přihlášeni a být moderátorem"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:258
|
||||
#: lib/graphql/resolvers/admin.ex:259
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access admin settings"
|
||||
msgstr "Pro přístup k nastavení správce musíte být přihlášeni jako správce"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:242
|
||||
#: lib/graphql/resolvers/admin.ex:243
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to access dashboard statistics"
|
||||
msgstr ""
|
||||
"Pro přístup ke statistikám ovládacího panelu musíte být přihlášeni jako "
|
||||
"správce"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:283
|
||||
#: lib/graphql/resolvers/admin.ex:284
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to save admin settings"
|
||||
msgstr ""
|
||||
|
@ -959,7 +959,7 @@ msgstr "Nepodařilo se opustit událost"
|
|||
msgid "Failed to update the group"
|
||||
msgstr "Nepodařilo se aktualizovat skupinu"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:357
|
||||
#: lib/graphql/resolvers/admin.ex:358
|
||||
#: lib/graphql/resolvers/user.ex:547
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Failed to update user email"
|
||||
|
@ -1090,22 +1090,22 @@ msgstr "Chcete-li odebrat člena, musíte být přihlášeni"
|
|||
msgid "Your email seems to be using an invalid format"
|
||||
msgstr "Váš e-mail zřejmě používá nesprávný formát"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:399
|
||||
#: lib/graphql/resolvers/admin.ex:400
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Can't confirm an already confirmed user"
|
||||
msgstr "Nelze potvrdit již potvrzeného uživatele"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:403
|
||||
#: lib/graphql/resolvers/admin.ex:404
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Deconfirming users is not supported"
|
||||
msgstr "Zrušení potvrzení uživatelů není podporováno"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:375
|
||||
#: lib/graphql/resolvers/admin.ex:376
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "The new role must be different"
|
||||
msgstr "Nová role musí být jiná"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:314
|
||||
#: lib/graphql/resolvers/admin.ex:315
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "You need to be logged-in and an administrator to edit an user's details"
|
||||
msgstr ""
|
||||
|
@ -1116,7 +1116,7 @@ msgstr ""
|
|||
msgid "A profile or group with that name already exists"
|
||||
msgstr "Profil nebo skupina s tímto názvem již existuje"
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:542
|
||||
#: lib/graphql/resolvers/admin.ex:560
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Unable to find an instance to follow at this address"
|
||||
msgstr ""
|
||||
|
@ -1389,7 +1389,7 @@ msgstr ""
|
|||
msgid "The same push subscription has already been registered"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:536
|
||||
#: lib/graphql/resolvers/admin.ex:554
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "This instance is pending follow approval"
|
||||
msgstr ""
|
||||
|
@ -1399,7 +1399,7 @@ msgstr ""
|
|||
msgid "Timezone ID %{timezone} is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/admin.ex:539
|
||||
#: lib/graphql/resolvers/admin.ex:557
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
msgid "You are already following this instance"
|
||||
msgstr "Tuto skupinu již sledujete"
|
||||
|
@ -1419,12 +1419,12 @@ msgstr ""
|
|||
msgid "The token you provided is invalid. Make sure that the URL is exactly the one provided inside the email you got."
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/conversation.ex:161
|
||||
#: lib/graphql/resolvers/conversation.ex:164
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "Conversation needs to mention at least one participant that's not yourself"
|
||||
msgstr ""
|
||||
|
||||
#: lib/graphql/resolvers/participant.ex:396
|
||||
#: lib/graphql/resolvers/participant.ex:401
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "There are no participants matching the audience you've selected."
|
||||
msgstr ""
|
||||
|
|
|
@ -8,15 +8,15 @@
|
|||
## to merge POT files into PO files.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2023-10-14 00:00+0000\n"
|
||||
"Last-Translator: Vri <vrifox@vrifox.cc>\n"
|
||||
"PO-Revision-Date: 2024-04-12 14:40+0000\n"
|
||||
"Last-Translator: Samuel Brinkmann <sbrinkmann@54gradsoftware.de>\n"
|
||||
"Language-Team: German <https://weblate.framasoft.org/projects/mobilizon/"
|
||||
"activity/de/>\n"
|
||||
"Language: de\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 5.0.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Weblate 5.4.3\n"
|
||||
|
||||
#: lib/web/templates/email/activity/_member_activity_item.html.heex:14
|
||||
#: lib/web/templates/email/activity/_member_activity_item.text.eex:12
|
||||
|
@ -228,7 +228,7 @@ msgstr ""
|
|||
|
||||
#: lib/web/templates/email/email_direct_activity.html.heex:230
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:23
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "View one more activity"
|
||||
msgid_plural "View %{count} more activities"
|
||||
msgstr[0] "%{count} weitere Aktivität anzeigen"
|
||||
|
@ -238,7 +238,7 @@ msgstr[1] "Eine weitere Aktivität anzeigen"
|
|||
#: lib/web/templates/email/email_direct_activity.html.heex:60
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:6
|
||||
#: lib/web/templates/email/email_direct_activity.text.eex:7
|
||||
#, elixir-format
|
||||
#, elixir-format, elixir-autogen
|
||||
msgid "There has been an activity!"
|
||||
msgid_plural "There has been some activity!"
|
||||
msgstr[0] "Es hat sich etwas getan!"
|
||||
|
@ -502,10 +502,10 @@ msgstr "Ein anonymes Profil"
|
|||
|
||||
#: lib/web/templates/email/email_anonymous_activity.html.heex:107
|
||||
#: lib/web/templates/email/email_anonymous_activity.text.eex:14
|
||||
#, elixir-autogen, elixir-format, fuzzy
|
||||
#, elixir-autogen, elixir-format
|
||||
msgid "%{profile} has posted a private announcement about event %{event}."
|
||||
msgstr ""
|
||||
"%{profile} hat eine Ankündigung unter der Veranstaltung %{event} "
|
||||
"%{profile} hat eine private Ankündigung zur Veranstaltung %{event} "
|
||||
"veröffentlicht."
|
||||
|
||||
#: lib/web/templates/email/email_anonymous_activity.html.heex:50
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue