Current section

Files

Jump to
urbit_ex lib gall graph_store.ex
Raw

lib/gall/graph_store.ex

defmodule UrbitEx.GraphStore do
alias UrbitEx.Utils
alias UrbitEx.{Resource, Post, Node}
# this works for both groups and channels, "leave" is distinct for some reason
def join_resource(resource) do
%{
join: %{
resource: resource,
ship: resource.ship
}
}
end
def leave_group(resource) do
%{
leave: %{
ship: resource.ship,
name: resource.name
}
}
end
def leave_channel(resource) do
%{
leave: %{
resource: resource
}
}
end
def create_group(name, title, description, "open", opts) do
banned_ranks = Keyword.get(opts, :banned_ranks) || []
banned_ships = Keyword.get(opts, :banned_ships) || []
banned_ranks = Enum.map(banned_ranks, &Utils.add_tilde/1)
banned_ships = Enum.map(banned_ships, &Utils.add_tilde/1)
%{
create: %{
name: name |> Utils.group_name(),
title: title,
description: description,
policy: %{
open: %{
banRanks: banned_ranks,
banned: banned_ships
}
}
}
}
end
def create_group(name, title, description, "invite", opts) do
invitees = Keyword.get(opts, :invitees) || []
invitees = Enum.map(invitees, &Utils.add_tilde/1)
%{
create: %{
name: name |> String.downcase() |> String.replace(" ", "-"),
title: title,
description: description,
policy: %{
invite: %{
pending: invitees
}
}
}
}
end
def delete_group(resource) do
%{
remove: %{
ship: resource.ship,
name: resource.name
}
}
end
def change_group_policy(resource, type) do
%{
changePolicy: %{
diff: %{
replace: policy_change(type)
},
resource: resource
}
}
end
defp policy_change(:to_public), do: %{open: %{banned: [], banRanks: []}}
defp policy_change(:to_private), do: %{invite: %{pending: []}}
def ban_from_group(resource, type, targets) do
%{
changePolicy: %{
resource: resource,
diff: %{
open: banned_target(type, targets)
}
}
}
end
defp banned_target(:ships, targets), do: %{banShips: targets}
defp banned_target(:ranks, targets), do: %{banRanks: targets}
def invite_to_group(resource, invitees, message) do
%{
invite: %{
ships: invitees,
description: message,
resource: resource
}
}
end
def kick_from_group(group, ships) do
%{
removeMembers: %{
resource: group,
ships: ships
}
}
end
def accept_invite() do
end
def leave_channel(resource) do
%{
leave: %{
resource: %{
ship: resource.ship,
name: resource.name
}
}
}
end
def create_channel(ship, group, title, name, description, type, association, invitees) do
channel_name = if String.starts_with?(name, "dm"), do: name, else: Utils.channel_name(name)
%{
create: %{
title: title,
description: description,
module: type,
mark: "graph-validator-#{type}",
resource:
Resource.new(
ship,
channel_name
),
associated: branch_channel(association, group, invitees)
}
}
end
defp branch_channel(:group, group, _), do: %{group: group}
defp branch_channel(:private, _, invitees), do: %{policy: %{invite: %{pending: invitees}}}
# {"create":{"resource":{"ship":"~daclug-misryc-sibbyr-sictyl--riddyt-socted-fitret-litzod","name":"private-5496"},"title":"private","description":"channel","associated":{"policy":{"invite":{"pending":[]}}},"module":"publish","mark":"graph-validator-publish"}}
# POST https://yago.live/spider/graph-view-action/graph-create/json.json
# body = {"create":{"resource":{"ship":"~mirtyl-wacdec","name":"personal-notebook-4426"},"title":"Personal notebook","description":"This is a no group notebook","associated":{"policy":{"invite":{"pending":[]}}},"module":"publish","mark":"graph-validator-publish"}}
def delete_channel(resource), do: %{delete: %{resource: resource}}
def enable_group_feed(resource, permission) do
%{
"create-group-feed": %{
resource: resource,
vip: permission
}
}
end
def disable_group_feed(resource) do
%{
"disable-group-feed": %{
resource: resource
}
}
end
# TODO
def change_graph_permissions(group, channel, allowed) do
%{
addTag: %{
resource: group,
tag: %{
app: "graph",
resource: "/ship/#{channel["ship"]}/#{channel["name"]}",
tag: "writers"
},
ships: allowed
}
}
end
# TODO figure out what "lmao-113" is from. Gotta scry the details before modifying I guess
def change_feed_permissions(resource, permissions) do
%{
add: %{
group: "/ship/~daclug-misryc-sibbyr-sictyl--riddyt-socted-fitret-litzod/lmao",
resource: %{
resource: "/ship/#{resource.ship}/lmao-113",
"app-name": "graph"
},
metadata: %{
preview: false,
vip: permissions,
title: "Group Feed",
description: "",
creator: "~daclug-misryc-sibbyr-sictyl--riddyt-socted-fitret-litzod",
picture: "",
hidden: true,
config: %{
graph: "post"
},
"date-created": "~2021.5.21..10.42.12..357e",
color: "000000"
}
}
}
end
# feed posts use this too
def send_message(author, resource, message, custom) do
contents = if custom, do: custom, else: Utils.tokenize(message)
contents
|> build_post(author)
|> build_node()
|> wrap_node(resource)
end
def add_collection_link(author, resource, text, url) do
build_collection_link(text, url)
|> build_post(author)
|> build_node()
|> wrap_node(resource)
end
def add_notebook_post(author, resource, title, text, custom) do
contents = if custom, do: custom, else: build_notebook_post(title, text)
container = build_post([], author)
post_wrapper = build_post([], author) |> Map.put(:index, "#{container.index}/1")
comments_wrapper = build_post([], author) |> Map.put(:index, "#{container.index}/2")
post = build_post(contents, author) |> Map.put(:index, "#{container.index}/1/1")
post_node = build_child_node(post, 1)
post_wrapper_node = build_child_node(post_wrapper, 1, post_node)
comments_wrapper_node = build_child_node(comments_wrapper, 2)
container_node =
build_node(container, Map.merge(post_wrapper_node, comments_wrapper_node))
|> wrap_node(resource)
end
def edit_post(author, resource, new_index, title, text, custom) do
contents = if custom, do: custom, else: build_notebook_post(title, text)
post = build_post(contents, author) |> Map.put(:index, new_index)
post_node =
build_node(post)
|> wrap_node(resource)
end
# to delete graphs with wrappers you need to specify all indexes
def add_comment(author, resource, index, text, custom) do
contents = if custom, do: custom, else: Utils.tokenize(text)
comment_wrapper = build_post([], author)
comment_wrapper = Map.put(comment_wrapper, :index, "#{index}/2#{comment_wrapper.index}")
comment =
build_post(contents, author)
|> Map.put(:index, "#{comment_wrapper.index}/1")
comment_node = build_child_node(comment, 1)
build_node(comment_wrapper, comment_node)
|> wrap_node(resource)
end
def edit_comment(author, resource, new_index, text, custom) do
contents = if custom, do: custom, else: Utils.tokenize(text)
post = build_post(contents, author) |> Map.put(:index, new_index)
post_node =
build_node(post)
|> wrap_node(resource)
end
defp build_collection_link(text, url) do
[%{text: text}, %{url: url}]
end
defp build_notebook_post(title, body), do: [%{text: title} | Utils.tokenize(body)]
defp build_post(contents, author) do
timestamp = System.os_time(:millisecond)
index = "/#{Utils.calculate_index(timestamp)}"
# need some logic here to check if already there
author = "~#{author}"
%UrbitEx.Post{
author: author,
contents: contents,
"time-sent": timestamp,
index: index
}
end
defp build_node(post, children \\ nil) do
%{post.index => %{post: post, children: children}}
end
defp build_child_node(post, index, children \\ nil) do
%{index => %{post: post, children: children}}
end
defp wrap_node(node, resource) do
%{
"add-nodes": %{
resource: resource,
nodes: node
}
}
end
# comments remove too indices, main and main/1
def remove_node(resource, indices) do
%{
"remove-posts": %{
resource: %{
name: resource.name,
ship: resource.ship
},
indices: indices
}
}
end
# changed!! POST https://u.spandrell.com/spider/graph-update/graph-add-nodes/graph-view-action.json
# {"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"muh-notebook-9743"},"nodes":{"/170141184504948745424527023347231887458":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948745424527023347231887458","time-sent":1615275701119,"contents":[],"hash":null,"signatures":[]},"children":{"1":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948745424527023347231887458/1","time-sent":1615275701119,"contents":[],"hash":null,"signatures":[]},"children":{"1":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948745424527023347231887458/1/1","time-sent":1615275701119,"contents":[{"text":"new poast"},{"text":"this is a new poast\n#lmao"}],"hash":null,"signatures":[]},"children":null}}},"2":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948745424527023347231887458/2","time-sent":1615275701119,"contents":[],"hash":null,"signatures":[]},"children":null}}}}}}}]
def update_notebook_post(resource) do
%{
"add-nodes": %{
resource: %{
ship: resource.ship,
name: resource.name
},
nodes: %{
"/170141184504948745424527023347231887458/1/2": %{
post: %{
author: "~mirtyl-wacdec",
index: "/170141184504948745424527023347231887458/1/2",
"time-sent": 1_615_275_746_889,
contents: [%{text: "new poast"}, %{text: "this is a new poast\n#lmao\n#lol "}],
hash: nil,
signatures: []
},
children: nil
}
}
}
}
end
# PUT [{"action":"ack","event-id":82},{"id":23,"action":"poke","ship":"mirtyl-wacdec","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"muh-notebook-9743"},"nodes":{"/170141184504948745424527023347231887458/1/2":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948745424527023347231887458/1/2","time-sent":1615275746889,"contents":[{"text":"new poast"},{"text":"this is a new poast\n#lmao\n#lol "}],"hash":null,"signatures":[]},"children":null}}}}}]
# update again
# PUT [{"action":"ack","event-id":88},{"id":26,"action":"poke","ship":"mirtyl-wacdec","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"muh-notebook-9743"},"nodes":{"/170141184504948745424527023347231887458/1/3":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948745424527023347231887458/1/3","time-sent":1615275805518,"contents":[{"text":"new poast"},{"text":"this is a new poast\n#lmao\n#lol \n#rofl"}],"hash":null,"signatures":[]},"children":null}}}}}]
# PUT [{"action":"ack","event-id":99},{"id":30,"action":"poke","ship":"mirtyl-wacdec","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"muh-collection-1789"},"nodes":{"/170141184504948749091001875437742366654":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504948749091001875437742366654","time-sent":1615275899879,"contents":[{"text":"lmao"},{"url":"https://google.com"}],"hash":null,"signatures":[]},"children":null}}}}}]
def add_comment() do
%{
"add-nodes": %{
resource: %{
ship: "~mirtyl-wacdec",
name: "muh-collection-1789"
},
nodes: %{
"/170141184504948749091001875437742366654/170141184504948751310200527737222554714": %{
post: %{
author: "~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod",
index:
"/170141184504948749091001875437742366654/170141184504948751310200527737222554714",
"time-sent": 1_615_276_020_182,
contents: [],
hash: nil,
signatures: []
},
children: %{
"1": %{
post: %{
author: "~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod",
index:
"/170141184504948749091001875437742366654/170141184504948751310200527737222554714/1",
"time-sent": 1_615_276_020_182,
contents: [%{text: "this is a comment"}],
hash: nil,
signatures: []
},
children: nil
}
}
}
}
}
}
end
# {"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"notebook-603"},"nodes":{"/170141184505030265165923689698921807872/2/170141184505064317422462376388154670186":{"post":{"author":"~daclug-misryc-sibbyr-sictyl--riddyt-socted-fitret-litzod","index":"/170141184505030265165923689698921807872/2/170141184505064317422462376388154670186","time-sent":1621540871681,"contents":[],"hash":null,"signatures":[]},"children":{"1":{"post":{"author":"~daclug-misryc-sibbyr-sictyl--riddyt-socted-fitret-litzod","index":"/170141184505030265165923689698921807872/2/170141184505064317422462376388154670186/1","time-sent":1621540871681,"contents":[{"text":"is it really"}],"hash":null,"signatures":[]},"children":null}}}}}}
# PUT [{"action":"ack","event-id":46},{"id":17,"action":"poke","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"muh-collection-1789"},"nodes":{"/170141184504948749091001875437742366654/170141184504948751310200527737222554714":{"post":{"author":"~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","index":"/170141184504948749091001875437742366654/170141184504948751310200527737222554714","time-sent":1615276020182,"contents":[],"hash":null,"signatures":[]},"children":{"1":{"post":{"author":"~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","index":"/170141184504948749091001875437742366654/170141184504948751310200527737222554714/1","time-sent":1615276020182,"contents":[{"text":"this is a comment"}],"hash":null,"signatures":[]},"children":null}}}}}}}]
def edit_comment() do
%{
"add-nodes": %{
resource: %{
ship: "~mirtyl-wacdec",
name: "muh-collection-1789"
},
nodes: %{
"/170141184504948749091001875437742366654/170141184504948751310200527737222554714/2": %{
post: %{
author: "~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod",
index:
"/170141184504948749091001875437742366654/170141184504948751310200527737222554714/2",
"time-sent": 1_615_276_049_236,
contents: [%{text: "this is a comment updated"}],
hash: nil,
signatures: []
},
children: nil
}
}
}
}
end
# PUT [{"action":"ack","event-id":50},{"id":18,"action":"poke","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"muh-collection-1789"},"nodes":{"/170141184504948749091001875437742366654/170141184504948751310200527737222554714/2":{"post":{"author":"~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","index":"/170141184504948749091001875437742366654/170141184504948751310200527737222554714/2","time-sent":1615276049236,"contents":[{"text":"this is a comment updated"}],"hash":null,"signatures":[]},"children":null}}}}}]
def start_dm(ship, name, target) do
%{
create: %{
resource: %{
ship: ship,
# name: "dm--#{Utils.remove_tilde(target)}"
name: name
},
title: "#{ship} <-> #{target |> Utils.abbreviate_patp() |> Utils.remove_tilde()}",
description: "",
associated: %{
policy: %{
invite: %{
pending: [target]
}
}
},
module: "chat",
mark: "graph-validator-chat"
}
}
end
# POST https://yago.live/spider/graph-view-action/graph-create/json.json
# body = {"create":{"resource":{"ship":"~mirtyl-wacdec","name":"dm--rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod"},"title":"~mirtyl-wacdec <-> ~rithet_samzod","description":"","associated":{"policy":{"invite":{"pending":["~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod"]}}},"module":"chat","mark":"graph-validator-chat"}}
def accept_dm() do
end
# PUT [{"action":"ack","event-id":120},{"id":30,"action":"poke","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"group-view","mark":"group-view-action","json":{"join":{"resource":{"ship":"~mirtyl-wacdec","name":"dm--rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod"},"ship":"~mirtyl-wacdec"}}}]
# PUT [{"action":"ack","event-id":122},{"id":31,"action":"poke","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"invite-store","mark":"invite-action","json":{"accept":{"term":"graph","uid":"0v5.8ldmf.rk74q.j0er6.4dtmd.udoic"}}}]
# PUT [{"id":1,"action":"subscribe","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"metadata-pull-hook","path":"/preview/ship/~mirtyl-wacdec/dm--rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod"}]
# PUT [{"action":"ack","event-id":128},{"id":32,"action":"poke","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"hark-store","mark":"hark-action","json":{"seen":null}}]
# {"json":{"invite-update":{"invite":{"term":"graph","uid":"0v2.nvabp.k67c3.cjl0s.g76c5.v6280","invite":{"resource":{"name":"dm--rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","ship":"mirtyl-wacdec"},"text":"","ship":"mirtyl-wacdec","recipient":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"graph-push-hook"}}}},"id":2,"response":"diff"}
def decline_dm do
# [{"action":"ack","event-id":27},{"id":15,"action":"poke","ship":"rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","app":"invite-store","mark":"invite-action","json":{"decline":{"term":"graph","uid":"0v2.nvabp.k67c3.cjl0s.g76c5.v6280"}}}]
end
def scry_messages do
# http://localhost:8080/~/scry/graph-store/newest/~darrux-landes/outdoors/100.json
end
# POST https://comet.yago.live/spider/graph-view-action/graph-delete/json.json
# body = {"delete":{"resource":{"ship":"~rithet-rilnyr-sidwer-liswer--tipden-litsef-lonsup-samzod","name":"channel-one-8028"}}}
end
# create dms
# POST /spider/graph-view-action/graph-create/json.json
# {"create":{"resource":{"ship":"~mirtyl-wacdec","name":"dm--tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod"},"title":"~mirtyl-wacdec <-> ~tandes_litzod","description":"","associated":{"policy":{"invite":{"pending":["~tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod"]}}},"module":"chat","mark":"graph-validator-chat"}}
# fetch dms
# GET https://yago.live/~/scry/graph-store/newest/~mirtyl-wacdec/dm--tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod/15.json
# send DM
# PUT [{"action":"ack","event-id":33},{"id":16,"action":"poke","ship":"mirtyl-wacdec","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~mirtyl-wacdec","name":"dm--tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod"},"nodes":{"/170141184504910234694444015480145788796":{"post":{"author":"~mirtyl-wacdec","index":"/170141184504910234694444015480145788796","time-sent":1613188030258,"contents":[{"text":"hi"}],"hash":null,"signatures":[]},"children":null}}}}}]
# fetch specific DMs
# GET https://yago.live/~/scry/graph-store/node-siblings/older/~mirtyl-wacdec/dm--tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod/20/170.141.184.504.910.234.694.444.015.480.145.788.796.json
# delete DM
# POST https://yago.live/spider/graph-view-action/graph-delete/json.json
# {"delete":{"resource":{"ship":"~mirtyl-wacdec","name":"dm--tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod"}}}
# reject invite
# PUT [{"action":"ack","event-id":56},{"id":17,"action":"poke","ship":"mirtyl-wacdec","app":"invite-store","mark":"invite-action","json":{"decline":{"term":"graph","uid":"0v7.k1eeo.hmdao.dih0v.8b9rn.95sgo"}}}]
# accept invite
# PUT
# [{"action":"ack","event-id":26},{"id":15,"action":"poke","ship":"tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod","app":"group-view","mark":"group-view-action","json":{"join":{"resource":{"ship":"~mirtyl-wacdec","name":"dm--tandes-filned-rolbud-norlyn--walder-lartug-fabfet-litzod"},"ship":"~mirtyl-wacdec"}}}]
#
# # join channel
# POST http://localhost/spider/graph-view-action/graph-join/json.json
# {"join":{"resource":{"ship":"~docteg-mothep","name":"wyb-3307"},"ship":"~docteg-mothep"}}
# # post comment PUT
# [{"action":"ack","event-id":128},{"id":17,"action":"poke","ship":"watsup-biches-docteg-mothep","app":"graph-push-hook","mark":"graph-update","json":{"add-nodes":{"resource":{"ship":"~docteg-mothep","name":"wyb-3307"},"nodes":{"/170141184504899137545973617207218530156":{"post":{"author":"~watsup-biches-docteg-mothep","index":"/170141184504899137545973617207218530156","time-sent":1612586452634,"contents":[{"text":"moon is up"}],"hash":null,"signatures":[]},"children":null}}}}}]
# # comments received as Event stream messages, e.g.:
# {"json":{"graph-update":{"add-nodes":{"resource":{"name":"wyb-3307","ship":"docteg-mothep"},"nodes":{"/170141184504899137443778655038867614203":{"post":{"index":"/170141184504899137443778655038867614203","author":"pondef-sanwet-rinfyn-sopnyx--tarbes-hacnem-picrus-marzod","time-sent":1612586447094,"signatures":[],"contents":[{"text":"i never see an asian girl who's like a solid 7 "}],"hash":null},"children":null}}}}},"id":14,"response":"diff"}
# {"json":{"graph-update":{"add-nodes":{"resource":{"name":"wyb-3307","ship":"docteg-mothep"},"nodes":{"/170141184504899139926507493175362456649":{"post":{"index":"/170141184504899139926507493175362456649","author":"docteg-mothep","time-sent":1612586581683,"signatures":[],"contents":[{"mention":"pondef-sanwet-rinfyn-sopnyx--tarbes-hacnem-picrus-marzod"},{"text":"what are we supposed to respond to that"}],"hash":null},"children":null}}}}},"id":14,"response":"diff"}
# deleted graph nodes show as {post: hash} (post is a string instead of an object)
# decline invite!
# [{"action":"ack","event-id":27},{"id":16,"action":"poke","ship":"mirtyl-wacdec","app":"invite-store","mark":"invite-action","json":{"decline":{"term":"graph","uid":"0v7.4th00.dn5k5.aat1q.k0klp.tu2iv"}}}]