ruleset io.picolabs.plan.introspect {
meta {
name "introspections"
use module io.picolabs.wrangler alias wrangler
use module io.picolabs.subscription alias subs
use module io.picolabs.plan.apps alias app
shares introspect, channels, channel, subscriptions, subscription
}
global {
rsRID = "io.picolabs.plan.ruleset"
introspect = function(_headers){
netid = wrangler:name()
repo_name = netid + "/bazaar"
subs_count = subs:established()
.length()
pECI = wrangler:parent_eci()
pName = pECI.isnull() => null | wrangler:picoQuery(pECI,"io.picolabs.wrangler","name")
apps = app:app_list()
apps_link = <<apps.html>>
rs_link = <<rulesets>>
cs_link = <<channels>>
ss_link = <<#{subs_count || "no"} subscription#{subs_count==1 => "" | "s"}>>
child_count = wrangler:children().length()
one_child = child_count==1 => wrangler:children().head() | false
child_eci = child_count==1 && one_child{"eci"}
repo_pico = child_count==1 && one_child{"name"}==repo_name
app:html_page("manage introspections","",
<<
Manage introspections
Overview
Your pico is named "#{netid}"#{
pName => << and its parent pico is named "#{pName}".>> | "."}
It has #{wrangler:installedRIDs().length()} #{rs_link},
of which #{apps.length()} are apps.
The apps can be managed with #{apps_link}.
It has #{wrangler:channels().length()} #{cs_link}.
It has #{ss_link}.
>>
+ //TODO Relationships can be managed with #{app:app_anchor("io.picolabs.plan.relate")}.
<<
It has #{child_count} child pico#{
repo_pico => <<: "#{repo_name}"
del.
>> | (one_child => "" | "s.")
}
>>
+ (repo_pico => <<
You have a child pico which hosts apps from a repository that it maintains.
>> | "")
+ <<Technical
>>
,_headers)
}
by = function(key){
function(a,b){a{key}.encode() cmp b{key}.encode()}
}
channels = function(_headers){
cs = wrangler:channels()
.filter(function(c){c{"familyChannelPicoID"}.isnull()})
one_channel = function(c){
<<
#{c{"id"}} |
#{c{"tags"}.join(", ")} |
>>
}
app:html_page("Your channels","",
<<Your channels
ECI |
tags |
#{cs.sort(by("id")).map(one_channel).join("")}
>>
,_headers)
}
channel = function(eci,_headers){
this_c = wrangler:channels()
.filter(function(c){c{"id"}==eci})
.head()
app:html_page(eci,"",
<<Your #{eci}
channel
ECI |
#{this_c{"id"}} |
tags |
#{this_c{"tags"}.join(", ")} |
raw |
#{this_c.encode()} |
>>
,_headers)
}
participant_name = function(eci){
thisPico = ctx:channels.any(function(c){c{"id"}==eci})
thisPico => "yourself" | ctx:query(eci,"io.picolabs.wrangler","name")
}
subs_tags = function(s){
wrangler:channels()
.filter(function(c){c{"id"}==s{"Rx"}})
.head()
{"tags"}.join(", ")
}
subscriptions = function(_headers){
ss = subs:established()
one_subs = function(s){
<<
#{s{"Id"}} |
#{s{"Rx_role"}} |
#{s{"Tx_role"}} |
#{s{"Tx"}.participant_name()} |
#{subs_tags(s)} |
>>
}
wellKnown_Rx = subs:wellKnown_Rx().get("id")
app:html_page("Your subscriptions","",
<<Your subscriptions
The well-known ECI for new subscriptions is #{wellKnown_Rx}
.
You have #{ss.length() || "no"} subscriptions.
Id |
your role |
their role |
with |
channel tags |
#{ss.sort(by("Id")).map(one_subs).join("")}
>>
,_headers)
}
subscription = function(_headers,Id){
this_s = subs:established("Id",Id).head()
Rx = this_s{"Rx"}
app:html_page(Id,"",
<<Your #{Id}
subscription
Id |
#{this_s{"Id"}} |
your channel |
#{Rx} |
their channel |
#{this_s{"Tx"}} |
your role |
#{this_s{"Rx_role"}} |
their role |
#{this_s{"Tx_role"}} |
with |
#{this_s{"Tx"}.participant_name()} |
channel tags |
#{subs_tags(this_s)} |
>>
,_headers)
}
tags = ["app","introspections"] // to over-ride apps channel
}
rule initialize {
select when io_picolabs_plan_introspect factory_reset
pre {
has_ruleset_ruleset = wrangler:installedRIDs() >< rsRID
evd_for_rid = function(rid){
rid.replace(re#[.-]#g,"_")
}
}
every {
wrangler:createChannel(
tags,
{"allow":[{"domain":evd_for_rid(meta:rid),"name":"*"},
{"domain":evd_for_rid(rsRID),"name":"*"}],"deny":[]},
{"allow":[{"rid":meta:rid,"name":"*"},
{"rid":rsRID,"name":"*"}],"deny":[]}
)
}
fired {
raise io_picolabs_plan_introspect event "channel_created"
raise wrangler event "install_ruleset_request" attributes {
"absoluteURL":meta:rulesetURI,"rid":rsRID,
} if not has_ruleset_ruleset
}
}
rule keepChannelsClean {
select when io_picolabs_plan_introspect channel_created
foreach wrangler:channels(tags).reverse().tail() setting(chan)
wrangler:deleteChannel(chan.get("id"))
}
}