Commit 4b067c3f authored by Alex Castaño's avatar Alex Castaño

Merge branch 'release/0.0.12'

parents dc6de5da 478a10b2
......@@ -24,7 +24,7 @@ build: ## Build the Docker image
-t moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) .
@echo moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD)
build_with_cache: ## Build the Docker image
build_with_cache: ## Build the Docker image using previous cache
@echo APP_NAME=$(APP_NAME)
@echo APP_VSN=$(APP_VSN)
@echo APP_BUILD=$(APP_BUILD)
......@@ -38,13 +38,13 @@ build_with_cache: ## Build the Docker image
-t moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) .
@echo moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD)
push:
push: ## Add latest tag to last build and push
@echo docker tag moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) moodlenet/moodlenet:latest
@docker tag moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) moodlenet/moodlenet:latest
@echo docker push moodlenet/moodlenet:latest
@docker push moodlenet/moodlenet:latest
push_stable:
push_stable: ## Tag stable, latest and version tags to the last build and push
@echo docker tag moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) moodlenet/moodlenet:latest
@docker tag moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) moodlenet/moodlenet:latest
@echo docker tag moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) moodlenet/moodlenet:$(APP_VSN)
......@@ -53,6 +53,8 @@ push_stable:
@docker tag moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD) moodlenet/moodlenet:stable
@echo docker push moodlenet/moodlenet:latest
@docker push moodlenet/moodlenet:latest
@echo docker push moodlenet/moodlenet:stable
@docker push moodlenet/moodlenet:stable
@echo docker push moodlenet/moodlenet:$(APP_VSN)
@docker push moodlenet/moodlenet:$(APP_VSN)
@echo docker push moodlenet/moodlenet:$(APP_VSN)-$(APP_BUILD)
......
......@@ -18,6 +18,35 @@ The first projects using it are:
## Installation
### With Docker (recommended)
Make sure you have [docker](https://www.docker.com/), a recent [docker-compose](https://docs.docker.com/compose/install/#install-compose) (which supports v3 configs, and [make](https://www.gnu.org/software/make/) installed:
```sh
$ docker version
Docker version 18.09.1-ce
$ docker-compose -v ±[●][develop]
docker-compose version 1.23.2
$ make --version
GNU Make 4.2.1
...
```
Clone this repo and change into the directory:
```sh
$ git clone https://gitlab.com/CommonsPub/Server.git
$ cd Server
```
Build the docker image:
```
$ make build
```
Start the docker containers with docker-compose:
```sh
$ docker-compose up
```
App should be running at [http://localhost:4000/](http://localhost:4000/).
#### Configuration
The docker image can be found in: https://hub.docker.com/r/moodlenet/moodlenet/
......
......@@ -38,6 +38,7 @@ defmodule MoodleNet.Accounts do
|> Map.put("type", "Person")
|> Map.delete(:password)
|> Map.delete("password")
|> set_default_icon()
password = attrs[:password] || attrs["password"]
......@@ -221,4 +222,13 @@ defmodule MoodleNet.Accounts do
String.ends_with?(email, "@moodle.com") ||
Repo.get(WhitelistEmail, email) != nil
end
defp set_default_icon(%{icon: _} = attrs), do: attrs
defp set_default_icon(attrs) do
if email = attrs["email"] || attrs[:email] do
Map.put(attrs, :icon, %{type: "Image", url: MoodleNet.Gravatar.url(email)})
else
attrs
end
end
end
defmodule MoodleNet.DataMigration.CreateGravatarIcon do
alias ActivityPub.SQL.{Query, Alter}
alias MoodleNet.Repo
def call() do
actors =
Query.new()
|> Query.with_type("Person")
|> Query.all()
|> Query.preload_assoc(:icon)
|> Enum.filter(&(&1.icon == []))
Repo.transaction(fn ->
for actor <- actors do
gravatar = MoodleNet.Gravatar.url(actor["email"])
{:ok, icon} = ActivityPub.new(type: "Image", url: gravatar)
{:ok, icon} = ActivityPub.insert(icon)
Alter.add(actor, :icon, icon)
end
end)
end
end
defmodule MoodleNet.Gravatar do
@uri %URI{
scheme: "https",
host: "s.gravatar.com",
query: "d=identicon&r=g&s=80"
}
def url(email) when is_binary(email) do
%{@uri | path: path(email)} |> URI.to_string()
end
defp path(email), do: "/avatar/#{hash(email)}"
defp hash(email),
do: :crypto.hash(:md5, String.downcase(email)) |> Base.encode16(case: :lower)
end
defmodule MoodleNet.MetadataScraper do
def fetch(url) when is_binary(url) do
with {:ok, data} <- Furlex.unfurl(url, follow_redirect: true) do
{:ok, format_data(data)}
{:ok, format_data(data, url)}
end
end
defp format_data(data) do
defp format_data(data, url) do
%{
title: title(data),
summary: summary(data),
image: image(data),
image: image(data, url),
embed_code: embed_code(data),
language: language(data),
author: author(data),
......@@ -20,20 +20,21 @@ defmodule MoodleNet.MetadataScraper do
defp title(data) do
(get(data, :facebook, "title") || get(data, :twitter, "title") || get(data, :oembed, "title") ||
get(data, :other, "title"))
get(data, :html, "title"))
|> only_first()
end
defp summary(data) do
(get(data, :facebook, "description") || get(data, :twitter, "description") ||
get(data, :other, "description"))
get(data, :html, "description"))
|> only_first()
end
defp image(data) do
defp image(data, original_url) do
(get(data, :facebook, "image") || get(data, :twitter, "image") ||
get(data, :other, "thumbnail_url"))
|> only_first()
|> fix_relative_url(original_url)
end
defp embed_code(data) do
......@@ -74,9 +75,21 @@ defmodule MoodleNet.MetadataScraper do
defp get(%{oembed: oembed}, :oembed, label),
do: Map.get(oembed, label)
defp get(data, :html, label),
do: Map.get(data.html, label)
defp get(data, :other, label),
do: Map.get(data.other, label)
defp only_first([head | _]), do: head
defp only_first(arg), do: arg
defp fix_relative_url("", _), do: nil
defp fix_relative_url(url, original_url) when is_binary(url) do
case URI.parse(url) do
%URI{host: nil} -> URI.merge(original_url, url) |> to_string()
_ -> url
end
end
defp fix_relative_url(nil, _), do: nil
end
......@@ -4,7 +4,7 @@ defmodule MoodleNet.Mixfile do
def project do
[
app: :moodle_net,
version: "0.0.11",
version: "0.0.12",
elixir: "~> 1.7.4",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
......
......@@ -29,7 +29,7 @@
"faker": {:hex, :faker, "0.11.1", "0dcf151bef21cb27e289ae7418fd15c6a278dad676d5996b75d1d309b155c205", [:mix], [], "hexpm"},
"file_system": {:hex, :file_system, "0.2.6", "fd4dc3af89b9ab1dc8ccbcc214a0e60c41f34be251d9307920748a14bf41f1d3", [:mix], [], "hexpm"},
"floki": {:hex, :floki, "0.20.4", "be42ac911fece24b4c72f3b5846774b6e61b83fe685c2fc9d62093277fb3bc86", [:mix], [{:html_entities, "~> 0.4.0", [hex: :html_entities, repo: "hexpm", optional: false]}, {:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"},
"furlex": {:git, "https://github.com/alexcastano/furlex", "3b77bb7b19f3cee5b2e03d37a997dcec1225d47a", []},
"furlex": {:git, "https://github.com/alexcastano/furlex", "30ddad592f0284ad99ba3ed294c08c15b488f923", []},
"gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"},
"hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
"html_entities": {:hex, :html_entities, "0.4.0", "f2fee876858cf6aaa9db608820a3209e45a087c5177332799592142b50e89a6b", [:mix], [], "hexpm"},
......
......@@ -31,6 +31,15 @@ defmodule MoodleNet.AccountsTest do
assert {:ok, _} = Accounts.register_user(attrs)
end
test "set gravatar icon by default" do
attrs = Factory.attributes(:user, email: "alex@moodle.com")
|> Map.delete("icon")
assert {:ok, %{actor: actor}} = Accounts.register_user(attrs)
assert ["https://s.gravatar.com/avatar/7779b850ea05dbeca7fc39a910a77f21?d=identicon&r=g&s=80"] == get_in(actor, [:icon, Access.at(0), :url])
end
test "fails with invalid password values" do
attrs = Factory.attributes(:user) |> Map.delete("password")
Accounts.add_email_to_whitelist(attrs["email"])
......
defmodule MoodleNet.DataMigration.CreateGravatarIconTest do
use MoodleNet.DataCase, async: true
alias ActivityPub.SQL.{Query}
test "works" do
actor = Factory.actor(email: "alex@moodle.com")
for _ <- 1..100, do: Factory.actor()
Query.new()
|> Query.with_type("Image")
|> Query.delete_all()
actor = Query.reload(actor) |> Query.preload_assoc(:icon)
assert actor.icon == []
MoodleNet.DataMigration.CreateGravatarIcon.call()
actor = Query.reload(actor) |> Query.preload_assoc(:icon)
assert [icon] = actor.icon
assert ["https://s.gravatar.com/avatar/7779b850ea05dbeca7fc39a910a77f21?d=identicon&r=g&s=80"] == icon.url
end
end
defmodule MoodleNet.GravatarTest do
use MoodleNet.DataCase, async: true
test "works" do
assert "https://s.gravatar.com/avatar/7779b850ea05dbeca7fc39a910a77f21?d=identicon&r=g&s=80" == MoodleNet.Gravatar.url("alex@moodle.com")
end
end
......@@ -17,4 +17,18 @@ defmodule MoodleNet.MetadataScraperTest do
assert data.summary
assert data.title == "¿Por qué la música de Harry Potter suena tan MÁGICA?"
end
@tag :external
test "get title" do
url = "https://en.wikibooks.org/wiki/Spanish"
assert {:ok, data} = Subject.fetch(url)
assert data.title == "Spanish - Wikibooks, open books for an open world"
end
@tag :external
test "fix relative image urls" do
url = "https://graphql.org/learn/schema/#interfaces"
assert {:ok, data} = Subject.fetch(url)
assert data.image == "https://graphql.org/img/og_image.png"
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment