Current section

37 Versions

Jump to

Compare versions

28 files changed
+617 additions
-170 deletions
  @@ -5,7 +5,7 @@
5 5 <br/>
6 6
7 7 <a href="https://gitter.im/infinitered/thesis-phoenix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/infinitered/thesis-phoenix.svg" alt="Join the chat at https://gitter.im/infinitered/thesis-phoenix"></a>
8 - <img src=https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat alt='js-standard-style'/>
8 + <img src="https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat" alt="js-standard-style"/>
9 9 <a href="https://semaphoreci.com/ir/thesis-phoenix"><img alt="Build Status" src="https://semaphoreci.com/api/v1/projects/0540dbb0-887a-45dd-9190-baa19b2ca9fb/816876/badge.svg"></a>
10 10 </p>
11 11
  @@ -42,7 +42,7 @@ _If you are having problems, view `README_INSTALL.md` for manual instructions._
42 42
43 43 ```elixir
44 44 def deps do
45 - [{:thesis, "~> 0.0.28"}]
45 + [{:thesis, "~> 0.0.29"}]
46 46 end
47 47
48 48 def application do
  @@ -416,15 +416,18 @@ websites. Please help us improve!
416 416 4. Run `brunch watch -p` during development
417 417 5. Use the `apps/example` Phoenix app to manually test your feature
418 418 6. Write tests for your new feature
419 - 7. Run `mix test && npm test` in the root directory to ensure that Thesis tests pass.
420 - 8. Run `mix test` in the `apps/example` directory to ensure the example app passes
421 - 9. Push to the branch (`git push origin my-new-feature`)
422 - 10. Create new Pull Request
419 + 7. Run `./bin/ci` in the root directory to ensure that Thesis tests pass.
420 + 8. Push to the branch (`git push origin my-new-feature`)
421 + 9. Create new Pull Request
422 +
423 + ## Premium Support
424 +
425 + [Thesis Phoenix](https://github.com/infinitered/thesis-phoenix), as an open source project, is free to use and always will be. [Infinite Red](https://infinite.red/) offers premium Thesis Phoenix support and general web app design/development services. Email us at [hello@infinite.red](mailto:hello@infinite.red) to get in touch with us for more details.
423 426
424 427 ### Key Contributors
425 428
426 429 * Jamon Holmgren [@jamonholmgren](https://twitter.com/jamonholmgren)
427 - * Yulian Glukhenko [@yulianglukhenko](https://github.com/yulianglukhenko)
430 + * Yulian Glukhenko [@yulolimum](https://github.com/yulolimum)
428 431 * Ken Miller [@seriousken](https://github.com/kemiller)
429 432 * Daniel Berkompas [@dberkom](https://twitter.com/dberkom)
  @@ -6,7 +6,7 @@ For automatic setup, see `README.md`.
6 6
7 7 ```elixir
8 8 def deps do
9 - [{:thesis, "~> 0.0.28"}]
9 + [{:thesis, "~> 0.0.29"}]
10 10 end
11 11
12 12 def application do
  @@ -23,10 +23,12 @@
23 23 <<"priv/templates/thesis.install/create_thesis_files_table.exs">>,
24 24 <<"priv/templates/thesis.install/create_thesis_tables.exs">>,
25 25 <<"priv/templates/thesis.install/thesis_auth.exs">>,
26 + <<"priv/tmp/open-source-info-image-2">>,
26 27 <<"web/static/css/_extends/_extends.sass">>,
27 28 <<"web/static/css/_extends/_forms.sass">>,
28 29 <<"web/static/css/_mixins/_barber-pole.sass">>,
29 - <<"web/static/css/_mixins/_editor.sass">>,
30 + <<"web/static/css/_mixins/_editor-icons.sass">>,
31 + <<"web/static/css/_mixins/_loader-balls.sass">>,
30 32 <<"web/static/css/_mixins/_mixins.sass">>,
31 33 <<"web/static/css/_mixins/_normalize.scss">>,
32 34 <<"web/static/css/_vendor/_medium-editor.scss">>,
  @@ -122,6 +124,8 @@
122 124 <<"web/static/js/components/cancel_button.js">>,
123 125 <<"web/static/js/components/delete_button.js">>,
124 126 <<"web/static/js/components/edit_button.js">>,
127 + <<"web/static/js/components/import_export_button.js">>,
128 + <<"web/static/js/components/import_export_tray.js">>,
125 129 <<"web/static/js/components/save_button.js">>,
126 130 <<"web/static/js/components/settings_button.js">>,
127 131 <<"web/static/js/components/settings_tray.js">>,
  @@ -138,7 +142,7 @@
138 142 <<"README_INSTALL.md">>,<<"LICENSE.md">>,<<"package.json">>]}.
139 143 {<<"licenses">>,[<<"MIT">>]}.
140 144 {<<"links">>,
141 - [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.28/api-reference.html">>},
145 + [{<<"Docs">>,<<"https://hexdocs.pm/thesis/0.0.29/api-reference.html">>},
142 146 {<<"GitHub">>,<<"https://github.com/infinitered/thesis-phoenix">>}]}.
143 147 {<<"maintainers">>,
144 148 [<<"Jamon Holmgren">>,<<"Yulian Glukhenko">>,<<"Ken Miller">>,
  @@ -165,8 +169,12 @@
165 169 {<<"name">>,<<"poison">>},
166 170 {<<"optional">>,false},
167 171 {<<"requirement">>,<<">= 1.0.0">>}],
172 + [{<<"app">>,<<"httpoison">>},
173 + {<<"name">>,<<"httpoison">>},
174 + {<<"optional">>,false},
175 + {<<"requirement">>,<<"~> 0.11.0">>}],
168 176 [{<<"app">>,<<"html_sanitize_ex">>},
169 177 {<<"name">>,<<"html_sanitize_ex">>},
170 178 {<<"optional">>,false},
171 179 {<<"requirement">>,<<">= 1.0.1">>}]]}.
172 - {<<"version">>,<<"0.0.28">>}.
180 + {<<"version">>,<<"0.0.29">>}.
  @@ -3,6 +3,7 @@ defmodule Thesis.ApiController do
3 3
4 4 use Phoenix.Controller
5 5 import Thesis.Config
6 + alias Thesis.Utilities
6 7
7 8 plug :ensure_authorized! when not action in [:show_file]
8 9
  @@ -18,13 +19,21 @@ defmodule Thesis.ApiController do
18 19 json conn, %{}
19 20 end
20 21
21 - def upload_file(conn, %{"file" => ""}), do: json conn, %{path: ""}
22 - def upload_file(conn, %{"file" => file}) do
23 - case uploader.upload(file) do
24 - {:ok, path} -> json conn, %{path: path}
25 - {:error, _} -> json conn, %{path: ""}
26 - end
22 + def import_file(conn, %{"image_url" => ""}), do: json conn, %{path: ""}
23 + def import_file(conn, %{"image_url" => image_url}) do
24 + image = HTTPoison.get!(image_url)
25 + file = %{
26 + data: image.body,
27 + filename: "imported-" <> Utilities.parameterize(image_url),
28 + content_type: (image.headers |> Enum.into(%{}) |> Map.new(fn {k, v} -> {String.downcase(k), v} end))["content-type"]
29 + }
30 +
31 + do_upload_file(conn, file)
27 32 end
33 + def import_file(conn, _), do: json conn, %{path: ""}
34 +
35 + def upload_file(conn, %{"file" => ""}), do: json conn, %{path: ""}
36 + def upload_file(conn, %{"file" => file}), do: do_upload_file(conn, file)
28 37 def upload_file(conn, _), do: json conn, %{path: ""}
29 38
30 39 def show_file(conn, %{"slug" => slug}) do
  @@ -32,6 +41,13 @@ defmodule Thesis.ApiController do
32 41 do_show_file(conn, file)
33 42 end
34 43
44 + defp do_upload_file(conn, file) do
45 + case uploader.upload(file) do
46 + {:ok, path} -> json conn, %{path: path}
47 + {:error, _} -> json conn, %{path: ""}
48 + end
49 + end
50 +
35 51 defp do_show_file(conn, nil) do
36 52 conn
37 53 |> put_resp_content_type("text/plain; charset=UTF-8")
  @@ -29,14 +29,28 @@ defmodule Thesis.File do
29 29 @required_attributes [:slug, :content_type, :filename, :data]
30 30
31 31 @doc """
32 - Changeset for File structs.
32 + Changeset for File structs, updated via a Plug Upload.
33 33 """
34 - def changeset(file, %Plug.Upload{} = f) do
34 + def changeset(file, %Plug.Upload{} = upload) do
35 35 file
36 - |> cast(%{content_type: f.content_type}, [:content_type])
37 - |> cast(%{filename: f.filename}, [:filename])
38 - |> cast(%{data: File.read!(f.path)}, [:data])
39 - |> cast(%{slug: generate_slug(f.filename)}, [:slug])
36 + |> cast(%{data: File.read!(upload.path)}, [:data])
37 + |> do_changeset(upload)
38 + end
39 +
40 + @doc """
41 + Changeset for File structs, updated via a map.
42 + """
43 + def changeset(file, %{data: data} = upload) do
44 + file
45 + |> cast(%{data: data}, [:data])
46 + |> do_changeset(upload)
47 + end
48 +
49 + defp do_changeset(file, changes) do
50 + file
51 + |> cast(%{content_type: changes.content_type}, [:content_type])
52 + |> cast(%{filename: changes.filename}, [:filename])
53 + |> cast(%{slug: generate_slug(changes.filename)}, [:slug])
40 54 |> validate_required(@required_attributes)
41 55 end
Loading more files…