I see people making requests about how a poll system should function on cohost, and I'm gonna double down with a stupid non-serious request and say staff should give us regular polls BUT give it some electoral college type bullshit so the more users there are in your country the less your vote is worth. I want every poll on this website to be decided by one dude in Lithuania, for no reason other than it's funny
#Cohost Global Feed
also: ##The Cohost Global Feed, #The Cohost Global Feed, ###The Cohost Global Feed, #Global Cohost Feed, #The Global Cohost Feed, #global feed
I started reading quite a lot of manga this year. I loved Claymore, Nichijou and Spy x Family!
Now starting to read Horimiya
That's exciting 'cos I like the BEAM (there are only so many runtimes that handle concurrency gracefully, and I think I currently like Elixir+OTP's approach the most), and Elixir is a neat language. But, for the longest time, the only traction I could get on it was messing around with Phoenix or other Applications.
Applications are all fine and good, but they are, critically, Multiple Files. Why might this matter? 'cos my 10+ year coding brain likes to prototype things in single files where possible, and then go to multiple files if I start breaking out of the 375ish line range.
So, last week I found out about how Elixir scripts can call Mix.install in order to set up dependencies for themselves, which lead me down a rabbit hole, where I've built an SSG to act as the base for my wife's website, as well as building a CLI trello status client thingy
Not going to pretend this code is, like, platonically ideal, but experiments like this are nice to be able to do.
(code below the fold for the curious)
Mix.install([ {:jason, "~> 1.4.0" }, {:httpoison, "~> 2.1"}, {:tz, "~> 0.26.0"} ], config: [])
conf = (File.read!("secrets.json")) |> Jason.decode!()
Calendar.put_time_zone_database(Tz.TimeZoneDatabase)
{:ok, time} = DateTime.now("America/Denver")
defmodule Trello.Endpoints do
def get_lists_on_board(id, %{ "APIKey" => key, "APIToken" => token}) do
"https://api.trello.com/1/boards/#{id}/lists/?key=#{key}&token=#{token}"
end
def get_list_cards(id, %{ "APIKey" => key, "APIToken" => token}) do
"https://api.trello.com/1/lists/#{id}/cards?key=#{key}&token=#{token}"
end
end
defmodule Trello.Client do
def get_list_cards!(id, conf) do
url = Trello.Endpoints.get_list_cards(id, conf)
{:ok, resp} = HTTPoison.get(url)
{:ok, cards} = Jason.decode resp.body
cards
end
end
defmodule Trello.Status do
alias IO.ANSI
defp color_for(label) do
case label do
"yellow" -> :yellow_background
"green" -> :green_background
"red" -> :red_background
_ -> :reset
end
end
defp has_color(card) do
Map.has_key?(card, "color")
end
def show(cards) do
for c <- cards do
color = Enum.find(c["labels"], %{"color" => :other}, &has_color/1) |> then(fn (lbl) -> color_for(lbl["color"]) end)
out = ANSI.format([color, " ", :reset, " ", c["name"]] )
IO.puts out
end
end
end
defmodule Status do
use GenServer
alias IO.ANSI
def start_link(conf) do
GenServer.start_link(__MODULE__, conf)
end
@impl true
def init(conf) do
Process.send_after(self(), :refresh, 1_000)
{:ok, %{ conf: conf }}
end
@impl true
def handle_info(:refresh, %{conf: conf} = state) do
cards = Trello.Client.get_list_cards!(conf["Today"]["ListId"], conf["Trello"])
{:ok, time} = DateTime.now("America/Denver")
IO.puts ANSI.format([:clear, ANSI.cursor(1,1), "Refreshed at: #{Calendar.strftime time, "%I:%M %p"}"])
IO.puts ""
Trello.Status.show cards
Process.send_after(self(), :refresh, 60_000)
{:noreply, state}
end
end
children = [ %{ id: Status, start: {Status, :start_link, [conf]} } ]
{:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)
# Loop forever
receive do _ -> 1 end