Fix Json transformation for nested objects
This commit is contained in:
parent
42dc0771d2
commit
afea1367db
3
Build.py
3
Build.py
|
@ -2,12 +2,13 @@
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||||
os.makedirs('./Dist', exist_ok=True)
|
os.makedirs('./Dist', exist_ok=True)
|
||||||
|
|
||||||
with open('./Friendiiverse.html', 'r') as Base:
|
with open('./Friendiiverse.html', 'r') as Base:
|
||||||
Base = Base.read()
|
Base = Base.read()
|
||||||
|
|
||||||
def FragReplace(Find, Replace, Pattern='*.*', Folder='./'):
|
def FragReplace(Find, Replace, Pattern='*.*', Folder='./Source/'):
|
||||||
global Base
|
global Base
|
||||||
for File in Path('./').rglob(Pattern):
|
for File in Path('./').rglob(Pattern):
|
||||||
with open(File, 'r') as Frag:
|
with open(File, 'r') as Frag:
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
var TransSchemas = {
|
||||||
|
Mastodon: {
|
||||||
|
Account: {
|
||||||
|
"__": "Author",
|
||||||
|
"url": "Url",
|
||||||
|
},
|
||||||
|
Status: {
|
||||||
|
"__": "Note",
|
||||||
|
"account": {"__": "Account"},
|
||||||
|
"content": "Content",
|
||||||
|
"created_at": "Time",
|
||||||
|
"url": "Url",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
var TransParsers = {
|
||||||
|
Mastodon: {
|
||||||
|
Account(Data) {
|
||||||
|
return JsonTransform(Data, TransSchemas.Mastodon.Author, TransSchemas.Mastodon);
|
||||||
|
},
|
||||||
|
Status(Data) {
|
||||||
|
return JsonTransform(Data, TransSchemas.Mastodon.Status, TransSchemas.Mastodon);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
|
@ -0,0 +1,6 @@
|
||||||
|
var FakeApi = {
|
||||||
|
//
|
||||||
|
Mastodon: {
|
||||||
|
//"timelines/public":
|
||||||
|
},
|
||||||
|
};
|
|
@ -6,7 +6,7 @@
|
||||||
<link rel="stylesheet" href="./Style.css"/>
|
<link rel="stylesheet" href="./Style.css"/>
|
||||||
<script>
|
<script>
|
||||||
// Credentials hardcoding for now
|
// Credentials hardcoding for now
|
||||||
var MastodonUrl = 'https://mastodon.uno';
|
var MastodonUrl = 'https://mastodon.social';
|
||||||
var FriendicaUrl = 'https://poliverso.org';
|
var FriendicaUrl = 'https://poliverso.org';
|
||||||
var FriendicaCredentials = 'redacted:redacted';
|
var FriendicaCredentials = 'redacted:redacted';
|
||||||
|
|
||||||
|
@ -34,10 +34,11 @@ var UseFakeApi = true;
|
||||||
<script>NoscriptView.remove();</script>
|
<script>NoscriptView.remove();</script>
|
||||||
<script src="./Utils.js"></script>
|
<script src="./Utils.js"></script>
|
||||||
<script src="./Strings.js"></script>
|
<script src="./Strings.js"></script>
|
||||||
<script src="./Translations.js"></script>
|
<script src="./ApiTransform.js"></script>
|
||||||
|
<script src="./FakeApi.js"></script>
|
||||||
<script src="./Main.js"></script>
|
<script src="./Main.js"></script>
|
||||||
<script>(function(){
|
<script>(function(){
|
||||||
if (Debug) {
|
if (Debug && new URLSearchParams(window.location.hash).get('#Eruda')) {
|
||||||
var El = document.createElement('script');
|
var El = document.createElement('script');
|
||||||
El.src="https://cdn.jsdelivr.net/npm/eruda";
|
El.src="https://cdn.jsdelivr.net/npm/eruda";
|
||||||
document.body.appendChild(El);
|
document.body.appendChild(El);
|
|
@ -1,36 +1,34 @@
|
||||||
var CurrTasks = {};
|
var CurrTasks = {};
|
||||||
|
|
||||||
var CurrentTimeline = [];
|
function DoAsync(First, Then, Data) {
|
||||||
var CurrentTimelineExp = 0;
|
var Job = RndId();
|
||||||
|
CurrTasks[Job] = {
|
||||||
function LogDebug(Data, Status) {
|
Remains: 0,
|
||||||
if (Debug) {
|
Return(Data) {
|
||||||
for (var i=0; i<Data.length; i++) {
|
this.Remains -= 1;
|
||||||
try {
|
this.Result = Data;
|
||||||
Data[i] = JSON.parse(Data[i]);
|
},
|
||||||
} catch(_){};
|
|
||||||
};
|
};
|
||||||
console[{l: "log", e: "error"}[Status]](Data);
|
// Call all First functs
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function WaitTasks(First, Then, Data) {
|
|
||||||
var Run = RndId();
|
|
||||||
CurrTasks[Run] = {Remains: 0};
|
|
||||||
ForceList(First).forEach(function(Fun, Data){
|
ForceList(First).forEach(function(Fun, Data){
|
||||||
var Task = RndId();
|
var Task = RndId();
|
||||||
var Proc = [Run, Task];
|
var Proc = [Job, Task];
|
||||||
CurrTasks[Run].Remains += 1;
|
CurrTasks[Job][Task] = {};
|
||||||
Data ? Fun(Proc, Data) : Fun(Proc);
|
CurrTasks[Job].Remains += 1;
|
||||||
|
//Fun(Proc, Data);
|
||||||
|
Data ? Fun(Data, Proc) : Fun(Proc);
|
||||||
});
|
});
|
||||||
CurrTasks[Run].Interval = setInterval(function(Run, Then){
|
// Continuosly check when First functs completed
|
||||||
if (CurrTasks[Run].Remains === 0) {
|
CurrTasks[Job].Interval = setInterval(function(Job, Then){
|
||||||
clearInterval(CurrTasks[Run].Interval);
|
if (CurrTasks[Job].Remains <= 0) {
|
||||||
|
clearInterval(CurrTasks[Job].Interval);
|
||||||
|
// Call all Then functs
|
||||||
ForceList(Then).forEach(function(Fun){
|
ForceList(Then).forEach(function(Fun){
|
||||||
Fun(CurrTasks[Run].Result);
|
Fun(CurrTasks[Job].Result);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}, 50, Run, Then);
|
}, 50, Job, Then);
|
||||||
|
return Job;
|
||||||
};
|
};
|
||||||
|
|
||||||
function HttpCodeGood(Code) {
|
function HttpCodeGood(Code) {
|
||||||
|
@ -74,32 +72,6 @@ function ApiCall(Data, Proc) {
|
||||||
Req.send();
|
Req.send();
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
function MastodonParse(Data, Type) {
|
|
||||||
var Trans = {
|
|
||||||
Status(Data) {
|
|
||||||
return JsonTranslate(Data, TransSchemas.Mastodon.Status);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return Trans[Type](Data);
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
function DisplayMastodonTimeline(Timeline) {
|
|
||||||
ApiCall({Target: "Mastodon", Method: Timeline, CallFine: function(Res){
|
|
||||||
DataView.innerHTML = Res.responseText;
|
|
||||||
JSON.parse(DataView.innerHTML).forEach(function(Item){
|
|
||||||
TimelineView.innerHTML += `<div class=PostView>
|
|
||||||
<a href="${Item.external_url}">${Item.created_at}</a>
|
|
||||||
${Item.friendica_author.url}
|
|
||||||
${Item.friendica_html}
|
|
||||||
</div>`;
|
|
||||||
});
|
|
||||||
}});
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
function DisplayFriendicaTimeline(Timeline) {
|
function DisplayFriendicaTimeline(Timeline) {
|
||||||
ApiCall({Target: "Friendica", Method: Timeline, CallFine: function(Res){
|
ApiCall({Target: "Friendica", Method: Timeline, CallFine: function(Res){
|
||||||
DataView.innerHTML = Res.responseText;
|
DataView.innerHTML = Res.responseText;
|
||||||
|
@ -116,27 +88,18 @@ function DisplayFriendicaTimeline(Timeline) {
|
||||||
};
|
};
|
||||||
|
|
||||||
function FetchMastodon(Proc) {
|
function FetchMastodon(Proc) {
|
||||||
return ApiCall({Target: "Mastodon", Method: "timelines/public", CallFine: function(Res){
|
ApiCall({Target: "Mastodon", Method: "timelines/public", CallFine: function(Res){
|
||||||
//console.log(JSON.parse(Res.responseText)[0])
|
var Notes = [ TransParsers.Mastodon.Status( JSON.parse(Res.responseText)[0] ) ];
|
||||||
var New = [ TransParsers.Mastodon.Status( JSON.parse(Res.responseText)[0] ) ];
|
LogDebug(Notes, 'l');
|
||||||
console.log(New)
|
CurrTasks[Proc[0]].Return(Notes);
|
||||||
//return [
|
|
||||||
// TransParsers.Mastodon.Status(JSON.parse(Res.responseText)[0])
|
|
||||||
//];
|
|
||||||
//CurrentTimeline = CurrentTimeline.concat([TransParsers.Mastodon.Status(JSON.parse(Res.responseText)[0])]);
|
|
||||||
//CurrentTimelineExp -= 1;
|
|
||||||
CurrTasks[Res.Proc[0]].Remains -= 1;
|
|
||||||
// TODO: store data in global object
|
|
||||||
CurrTasks[Res.Proc[0]].Result = New;
|
|
||||||
}}, Proc);
|
}}, Proc);
|
||||||
};
|
};
|
||||||
|
|
||||||
function FillTimeline(Notes) {
|
function FillTimeline(Notes) {
|
||||||
console.log('notes', Notes)
|
|
||||||
Notes.forEach(function(Note){
|
Notes.forEach(function(Note){
|
||||||
TimelineView.innerHTML += `<div class=PostView>
|
TimelineView.innerHTML += `<div class="NoteView">
|
||||||
<a href="${Note.Url}">${Note.Time}</a>
|
<a href="${Note.Url}">${Note.Time}</a>
|
||||||
${Note.Author}
|
${Note.Author.Url}
|
||||||
${Note.Content}
|
${Note.Content}
|
||||||
</div>`;
|
</div>`;
|
||||||
});
|
});
|
||||||
|
@ -148,7 +111,10 @@ PlazasView.innerHTML = `
|
||||||
<ul>
|
<ul>
|
||||||
<li onclick="DisplayFriendicaTimeline('statuses/networkpublic_timeline');">Federation</li>
|
<li onclick="DisplayFriendicaTimeline('statuses/networkpublic_timeline');">Federation</li>
|
||||||
<li onclick="DisplayFriendicaTimeline('statuses/public_timeline');">${FriendicaUrl}</li>
|
<li onclick="DisplayFriendicaTimeline('statuses/public_timeline');">${FriendicaUrl}</li>
|
||||||
<li onclick="WaitTasks(FetchMastodon, FillTimeline);">${MastodonUrl}</li>
|
<li onclick="DoAsync(FetchMastodon, FillTimeline);">
|
||||||
|
<img src=""/>
|
||||||
|
${MastodonUrl}
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
|
@ -20,7 +20,7 @@ footer {
|
||||||
white-space: break-spaces;
|
white-space: break-spaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
.PostView {
|
.NoteView {
|
||||||
border: 4px solid purple;
|
border: 4px solid purple;
|
||||||
margin: 12px;
|
margin: 12px;
|
||||||
}
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
function ForceList(Item) {
|
||||||
|
return (Array.isArray(Item) ? Item : [Item]);
|
||||||
|
};
|
||||||
|
|
||||||
|
function RndId() {
|
||||||
|
return `${Date.now()}${Math.random()}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
function LogDebug(Data, Status) {
|
||||||
|
if (Debug) {
|
||||||
|
if (!Status) {
|
||||||
|
Status = 'l';
|
||||||
|
};
|
||||||
|
for (var i=0; i<Data.length; i++) {
|
||||||
|
try {
|
||||||
|
Data[i] = JSON.parse(Data[i]);
|
||||||
|
} catch(_){};
|
||||||
|
};
|
||||||
|
console[{l: "log", e: "error"}[Status.toLowerCase()]](Data);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Transform JSON tree into a new using a template schema
|
||||||
|
function JsonTransform(TreeOld, SchemaCurr, SchemaRoot) {
|
||||||
|
var TreeNew = {};
|
||||||
|
Object.keys(TreeOld).forEach(function(KeyOld){
|
||||||
|
var Content = TreeOld[KeyOld];
|
||||||
|
var KeyNew = ((typeof(SchemaCurr) == 'object' && KeyOld in SchemaCurr) ? SchemaCurr[KeyOld] : KeyOld);
|
||||||
|
if (typeof(Content) == 'object' && Content !== null) {
|
||||||
|
if (Array.isArray(Content)) {
|
||||||
|
// Lists
|
||||||
|
var ListNew = [];
|
||||||
|
Content.forEach(function(Value){
|
||||||
|
ListNew.push(JsonTransform(Value, KeyNew));
|
||||||
|
});
|
||||||
|
TreeNew[KeyNew] = ListNew;
|
||||||
|
} else {
|
||||||
|
// Dicts
|
||||||
|
if (!KeyNew.__) {
|
||||||
|
KeyNew.__ = KeyOld;
|
||||||
|
};
|
||||||
|
TreeNew[KeyNew.__] = JsonTransform(Content, SchemaRoot[KeyNew.__], SchemaRoot);
|
||||||
|
TreeNew[SchemaRoot[KeyNew.__].__] = TreeNew[KeyNew.__];
|
||||||
|
delete TreeNew[KeyNew.__];
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Values
|
||||||
|
TreeNew[KeyNew] = Content;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return TreeNew;
|
||||||
|
};
|
33
Test.txt
33
Test.txt
|
@ -1,33 +0,0 @@
|
||||||
function ApiCall(f) {
|
|
||||||
var Req = new XMLHttpRequest();
|
|
||||||
Req.onloadend = function(){ f(this) };
|
|
||||||
Req.open('GET', `https://mastodon.social/api/v1/timelines/public`, true);
|
|
||||||
Req.send();
|
|
||||||
};
|
|
||||||
|
|
||||||
function Retry(Text, f) {
|
|
||||||
console.log(f)
|
|
||||||
if (Text) {
|
|
||||||
return Text;
|
|
||||||
} else {
|
|
||||||
setTimeout(f, 50, Text, f);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
function PrintRes(Res) {
|
|
||||||
var Text = Res.responseText;
|
|
||||||
setTimeout(Retry, 50, Text, Retry);
|
|
||||||
return Res.responseText;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
function PrintRes(Res) {
|
|
||||||
console.log(Res.responseText);
|
|
||||||
return Res.responseText;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
function FetchContent() {
|
|
||||||
return ApiCall(PrintRes);
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,51 +0,0 @@
|
||||||
var TransSchemas = {
|
|
||||||
Mastodon: {
|
|
||||||
Account: {
|
|
||||||
"__": "Author",
|
|
||||||
"url": "Url",
|
|
||||||
},
|
|
||||||
Status: {
|
|
||||||
"__": "Note",
|
|
||||||
//"account": {"__": "Account"},
|
|
||||||
"content": "Content",
|
|
||||||
"created_at": "Time",
|
|
||||||
"url": "Url",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
var TransParsers = {
|
|
||||||
Mastodon: {
|
|
||||||
Account(Data) {
|
|
||||||
return JsonTranslate(Data, TransSchemas.Mastodon.Author);
|
|
||||||
},
|
|
||||||
Status(Data) {
|
|
||||||
return JsonTranslate(Data, TransSchemas.Mastodon.Status);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function JsonTranslate(TreeOld, Schema) {
|
|
||||||
var TreeNew = {};
|
|
||||||
Object.keys(TreeOld).forEach(function(KeyOld){
|
|
||||||
var Content = TreeOld[KeyOld];
|
|
||||||
var KeyNew = ((typeof(Schema) == 'object' && KeyOld in Schema) ? Schema[KeyOld] : KeyOld);
|
|
||||||
if (typeof(Content) == 'object' && Content !== null) {
|
|
||||||
if (Array.isArray(Content)) {
|
|
||||||
// Lists
|
|
||||||
//New[NewKey] = Content;
|
|
||||||
//Content.forEach(function());
|
|
||||||
} else {
|
|
||||||
// Dicts
|
|
||||||
if (!KeyNew.__) {
|
|
||||||
KeyNew.__ = KeyOld;
|
|
||||||
};
|
|
||||||
TreeNew[KeyNew.__] = JsonTranslate(Content, KeyNew);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// Values
|
|
||||||
TreeNew[KeyNew] = Content;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
return TreeNew;
|
|
||||||
};
|
|
Loading…
Reference in New Issue