Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
jio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Alain Takoudjou
jio
Commits
39feb6e5
Commit
39feb6e5
authored
Aug 24, 2017
by
Alain Takoudjou
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
replicated opml now check signature and use new parser storage
parent
badea138
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
996 additions
and
1023 deletions
+996
-1023
examples/scenario_monitor.html
examples/scenario_monitor.html
+2
-0
examples/scenario_monitor.js
examples/scenario_monitor.js
+500
-726
src/jio.storage/replicatedopmltreestorage.js
src/jio.storage/replicatedopmltreestorage.js
+482
-290
src/jio.storage/webhttpstorage.js
src/jio.storage/webhttpstorage.js
+12
-7
No files found.
examples/scenario_monitor.html
View file @
39feb6e5
...
@@ -7,6 +7,8 @@
...
@@ -7,6 +7,8 @@
<script
src=
"../node_modules/rsvp/dist/rsvp-2.0.4.js"
></script>
<script
src=
"../node_modules/rsvp/dist/rsvp-2.0.4.js"
></script>
<script
src=
"../dist/jio-latest.js"
></script>
<script
src=
"../dist/jio-latest.js"
></script>
<script
src=
"../src/jio.storage/replicatedopmltreestorage.js"
></script>
<script
src=
"../src/jio.storage/webhttpstorage.js"
></script>
<link
rel=
"stylesheet"
href=
"../node_modules/grunt-contrib-qunit/test/libs/qunit.css"
type=
"text/css"
media=
"screen"
/>
<link
rel=
"stylesheet"
href=
"../node_modules/grunt-contrib-qunit/test/libs/qunit.css"
type=
"text/css"
media=
"screen"
/>
<script
src=
"../node_modules/grunt-contrib-qunit/test/libs/qunit.js"
type=
"text/javascript"
></script>
<script
src=
"../node_modules/grunt-contrib-qunit/test/libs/qunit.js"
type=
"text/javascript"
></script>
...
...
examples/scenario_monitor.js
View file @
39feb6e5
...
@@ -12,6 +12,10 @@
...
@@ -12,6 +12,10 @@
module
=
QUnit
.
module
,
module
=
QUnit
.
module
,
rusha
=
new
Rusha
(),
rusha
=
new
Rusha
(),
i
,
i
,
opml_mock_options
,
rss_mock_options
,
opml_mock_options2
=
{},
rss_mock_options2
=
{},
name_list
=
[
'
get
'
,
'
put
'
,
'
remove
'
,
'
buildQuery
'
,
name_list
=
[
'
get
'
,
'
put
'
,
'
remove
'
,
'
buildQuery
'
,
'
putAttachment
'
,
'
getAttachment
'
,
'
allAttachments
'
];
'
putAttachment
'
,
'
getAttachment
'
,
'
allAttachments
'
];
...
@@ -24,66 +28,41 @@
...
@@ -24,66 +28,41 @@
}
}
}
}
function
RSSMockStorage
(
spec
)
{
function
ParserMockStorage
(
spec
)
{
this
.
_rss_storage
=
jIO
.
createJIO
({
this
.
_sub_storage
=
jIO
.
createJIO
({
type
:
"
rss
"
,
type
:
"
parser
"
,
url
:
"
http://example.com/rss.xml
"
document_id
:
spec
.
document_id
,
attachment_id
:
spec
.
attachment_id
,
parser
:
spec
.
parser
,
sub_storage
:
spec
.
sub_storage
});
});
this
.
_options
=
spec
.
options
;
if
(
spec
.
parser
===
"
opml
"
)
{
resetCount
(
spec
.
options
.
count
);
if
(
spec
.
document_id
===
"
http://example2.com/opml.xml
"
)
{
this
.
_options
=
opml_mock_options2
;
}
else
{
this
.
_options
=
opml_mock_options
;
}
}
}
else
if
(
spec
.
parser
===
"
rss
"
)
{
RSSMockStorage
.
prototype
.
hasCapacity
=
function
(
name
)
{
if
(
spec
.
document_id
===
"
http://example2.com/rss.xml
"
)
{
return
this
.
_rss_storage
.
hasCapacity
(
name
);
this
.
_options
=
rss_mock_options2
;
};
}
else
{
this
.
_options
=
rss_mock_options
;
function
WEBMockStorage
(
spec
)
{
this
.
_web_storage
=
jIO
.
createJIO
({
type
:
"
webhttp
"
,
url
:
"
http://example.com/
"
});
this
.
_options
=
spec
.
options
;
resetCount
(
spec
.
options
.
count
);
}
}
}
WEBMockStorage
.
prototype
.
hasCapacity
=
function
(
name
)
{
resetCount
(
this
.
_options
.
count
);
return
this
.
_web_storage
.
hasCapacity
(
name
);
};
function
OPMLMockStorage
(
spec
)
{
this
.
_opml_storage
=
jIO
.
createJIO
({
type
:
"
opml
"
,
url
:
"
http://example.com/opml.xml
"
});
this
.
_options
=
spec
.
options
;
resetCount
(
spec
.
options
.
count
);
}
}
OPML
MockStorage
.
prototype
.
hasCapacity
=
function
(
name
)
{
Parser
MockStorage
.
prototype
.
hasCapacity
=
function
(
name
)
{
return
this
.
_
opml
_storage
.
hasCapacity
(
name
);
return
this
.
_
sub
_storage
.
hasCapacity
(
name
);
};
};
function
mockFunction
(
name
)
{
function
mockFunction
(
name
)
{
WEBMockStorage
.
prototype
[
name
]
=
function
()
{
ParserMockStorage
.
prototype
[
name
]
=
function
()
{
this
.
_options
.
count
[
name
]
+=
1
;
if
(
this
.
_options
.
mock
.
hasOwnProperty
(
name
))
{
return
this
.
_options
.
mock
[
name
].
apply
(
this
,
arguments
);
}
return
this
.
_web_storage
[
name
].
apply
(
this
.
_web_storage
,
arguments
);
};
RSSMockStorage
.
prototype
[
name
]
=
function
()
{
this
.
_options
.
count
[
name
]
+=
1
;
this
.
_options
.
count
[
name
]
+=
1
;
if
(
this
.
_options
.
mock
.
hasOwnProperty
(
name
))
{
if
(
this
.
_options
.
mock
.
hasOwnProperty
(
name
))
{
return
this
.
_options
.
mock
[
name
].
apply
(
this
,
arguments
);
return
this
.
_options
.
mock
[
name
].
apply
(
this
,
arguments
);
}
}
return
this
.
_rss_storage
[
name
].
apply
(
this
.
_rss_storage
,
arguments
);
return
this
.
_sub_storage
[
name
].
apply
(
this
.
_sub_storage
,
arguments
);
};
OPMLMockStorage
.
prototype
[
name
]
=
function
()
{
this
.
_options
.
count
[
name
]
+=
1
;
if
(
this
.
_options
.
mock
.
hasOwnProperty
(
name
))
{
return
this
.
_options
.
mock
[
name
].
apply
(
this
,
arguments
);
}
return
this
.
_opml_storage
[
name
].
apply
(
this
.
_opml_storage
,
arguments
);
};
};
}
}
...
@@ -91,9 +70,7 @@
...
@@ -91,9 +70,7 @@
mockFunction
(
name_list
[
i
]);
mockFunction
(
name_list
[
i
]);
}
}
jIO
.
addStorage
(
'
opmlmock
'
,
OPMLMockStorage
);
jIO
.
addStorage
(
'
parsermock
'
,
ParserMockStorage
);
jIO
.
addStorage
(
'
rssmock
'
,
RSSMockStorage
);
jIO
.
addStorage
(
'
webmock
'
,
WEBMockStorage
);
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// Helpers
// Helpers
...
@@ -110,9 +87,7 @@
...
@@ -110,9 +87,7 @@
for
(
i
=
0
;
i
<
result
.
data
.
rows
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
result
.
data
.
rows
.
length
;
i
+=
1
)
{
promise_list
.
push
(
RSVP
.
all
([
promise_list
.
push
(
RSVP
.
all
([
result
.
data
.
rows
[
i
].
id
,
result
.
data
.
rows
[
i
].
id
,
storage
.
get
(
result
.
data
.
rows
[
i
].
id
),
storage
.
get
(
result
.
data
.
rows
[
i
].
id
)
storage
.
getAttachment
(
result
.
data
.
rows
[
i
].
id
,
result
.
data
.
rows
[
i
].
doc
.
name
)
]));
]));
}
}
return
RSVP
.
all
(
promise_list
);
return
RSVP
.
all
(
promise_list
);
...
@@ -146,82 +121,9 @@
...
@@ -146,82 +121,9 @@
this
.
server
.
autoRespond
=
true
;
this
.
server
.
autoRespond
=
true
;
this
.
server
.
autoRespondAfter
=
5
;
this
.
server
.
autoRespondAfter
=
5
;
this
.
rss_mock_options
=
{
mock
:
{
remove
:
function
()
{
throw
new
Error
(
'
remove not supported
'
);
},
removeAttachment
:
function
()
{
throw
new
Error
(
'
removeAttachment not supported
'
);
},
allAttachments
:
function
()
{
return
{
data
:
null
};
},
putAttachment
:
function
()
{
throw
new
Error
(
'
putAttachment not supported
'
);
}
},
count
:
{}
};
this
.
opml_mock_options
=
{
mock
:
{
remove
:
function
()
{
throw
new
Error
(
'
remove not supported
'
);
},
removeAttachment
:
function
()
{
throw
new
Error
(
'
removeAttachment not supported
'
);
},
allAttachments
:
function
()
{
return
{
data
:
null
};
},
putAttachment
:
function
()
{
throw
new
Error
(
'
putAttachment not supported
'
);
}
},
count
:
{}
};
this
.
web_mock_options
=
{
mock
:
{
remove
:
function
()
{
throw
new
Error
(
'
remove not supported
'
);
},
removeAttachment
:
function
()
{
throw
new
Error
(
'
removeAttachment not supported
'
);
},
allAttachments
:
function
()
{
return
{
data
:
null
};
},
putAttachment
:
function
()
{
throw
new
Error
(
'
putAttachment not supported
'
);
}
},
count
:
{}
};
this
.
sub_opml_storage
=
{
type
:
"
opmlmock
"
,
options
:
this
.
opml_mock_options
,
url
:
"
http://example.com/opml.xml
"
,
sub_storage_list
:
[
{
type
:
"
rssmock
"
,
url
:
"
http://example.com/rss.xml
"
,
has_include_docs
:
true
,
options
:
this
.
rss_mock_options
},
{
type
:
"
webmock
"
,
url
:
"
http://example.com/
"
,
has_include_docs
:
true
,
options
:
this
.
web_mock_options
}
],
basic_login
:
"
YWRtaW46endfEzrJUZGw=
"
};
this
.
jio
=
jIO
.
createJIO
({
this
.
jio
=
jIO
.
createJIO
({
type
:
"
replicatedopml
"
,
type
:
"
replicatedopml
"
,
opml_storage_list
:
[
remote_parser_storage_type
:
"
parsermock
"
,
this
.
sub_opml_storage
],
local_sub_storage
:
{
local_sub_storage
:
{
type
:
"
query
"
,
type
:
"
query
"
,
sub_storage
:
{
sub_storage
:
{
...
@@ -243,9 +145,28 @@
...
@@ -243,9 +145,28 @@
'
</head>
'
+
'
</head>
'
+
'
<body>
'
+
'
<body>
'
+
'
<outline text="OPML Item List">
'
+
'
<outline text="OPML Item List">
'
+
'
<outline text="instance foo"
type="link" u
rl="http://example.com/
'
+
'
<outline text="instance foo"
xmlU
rl="http://example.com/
'
+
'
rss.xml" dateCreated="Thu, 12 Sep 2003 23:35:52 GMT"
'
+
'
rss.xml" dateCreated="Thu, 12 Sep 2003 23:35:52 GMT"
'
+
'
htmlUrl="http://example.com/" title="opml item foo" />
'
+
'
htmlUrl="http://example.com/" title="opml item foo" type="link"/>
'
+
'
</outline>
'
+
'
</body>
'
+
'
</opml>
'
]);
this
.
server
.
respondWith
(
"
GET
"
,
"
http://example2.com/opml.xml
"
,
[
200
,
{
"
Content-Type
"
:
"
text/xml
"
},
'
<?xml version="1.0" encoding="ISO-8859-1"?>
'
+
'
<opml version="1.0">
'
+
'
<head>
'
+
'
<title>opml foo</title>
'
+
'
<dateCreated>Thu, 12 Sep 2003 23:35:52 GMT</dateCreated>
'
+
'
<dateModified>Fri, 12 Sep 2003 23:45:37 GMT</dateModified>
'
+
'
</head>
'
+
'
<body>
'
+
'
<outline text="OPML Item List">
'
+
'
<outline text="instance foo" xmlUrl="http://example2.com/
'
+
'
rss.xml" dateCreated="Thu, 12 Sep 2003 23:35:52 GMT"
'
+
'
htmlUrl="http://example2.com/" title="opml item foo" type="link"/>
'
+
'
</outline>
'
+
'
</outline>
'
+
'
</body>
'
+
'
</body>
'
+
'
</opml>
'
'
</opml>
'
...
@@ -273,21 +194,64 @@
...
@@ -273,21 +194,64 @@
'
</rss>
'
'
</rss>
'
]);
]);
this
.
server
.
respondWith
(
"
GET
"
,
"
http://example.com/_document_list
"
,
[
200
,
this
.
server
.
respondWith
(
"
GET
"
,
"
http://example2.com/rss.xml
"
,
[
200
,
{
"
Content-Type
"
:
"
text/plain
"
},
{
"
Content-Type
"
:
"
text/xml
"
},
'
monitor.status
'
'
<?xml version="1.0" encoding="UTF-8" ?>
'
+
'
<rss version="2.0">
'
+
'
<channel>
'
+
'
<title>instance foo</title>
'
+
'
<description>This is an example of an RSS feed</description>
'
+
'
<link>http://www.domain.com/link.htm</link>
'
+
'
<lastBuildDate>Mon, 28 Aug 2006 11:12:55 -0400 </lastBuildDate>
'
+
'
<pubDate>Tue, 29 Aug 2006 09:00:00 -0400</pubDate>
'
+
'
<item>
'
+
'
<title>Item Example</title>
'
+
'
<category>ERROR</category>
'
+
'
<description>This is an example of an Item</description>
'
+
'
<link>http://www.domain.com/link.htm</link>
'
+
'
<guid isPermaLink="false">11026875</guid>
'
+
'
<pubDate>Tue, 29 Aug 2006 09:00:00 -0400</pubDate>
'
+
'
</item>
'
+
'
</channel>
'
+
'
</rss>
'
]);
]);
this
.
server
.
respondWith
(
opml_mock_options
=
{
"
GET
"
,
mock
:
{
"
http://example.com/monitor.status.json
"
,
remove
:
function
()
{
[
200
,
throw
new
Error
(
'
remove not supported
'
);
{
"
Content-Type
"
:
"
application/json
"
},
},
'
{"title": "document fooo", "status": "ERROR",
'
+
removeAttachment
:
function
()
{
'
"date": "Tue, 29 Aug 2006 09:00:00 -0400",
'
+
throw
new
Error
(
'
removeAttachment not supported
'
);
'
"type": "global", "foo_p": "fooo parameter",
'
+
},
'
"bar_p": "bar parameter", "total_error": 12345}
'
]
allAttachments
:
function
()
{
);
return
{
data
:
null
};
},
putAttachment
:
function
()
{
throw
new
Error
(
'
putAttachment not supported
'
);
}
},
count
:
{}
};
rss_mock_options
=
{
mock
:
{
remove
:
function
()
{
throw
new
Error
(
'
remove not supported
'
);
},
removeAttachment
:
function
()
{
throw
new
Error
(
'
removeAttachment not supported
'
);
},
allAttachments
:
function
()
{
return
{
data
:
null
};
},
putAttachment
:
function
()
{
throw
new
Error
(
'
putAttachment not supported
'
);
}
},
count
:
{}
};
console
.
log
(
new
Blob
([
JSON
.
stringify
({
toto
:
""
})]));
},
},
teardown
:
function
()
{
teardown
:
function
()
{
this
.
server
.
restore
();
this
.
server
.
restore
();
...
@@ -303,24 +267,19 @@
...
@@ -303,24 +267,19 @@
stop
();
stop
();
var
test
=
this
;
var
test
=
this
;
test
.
opml_mock_options
.
mock
.
buildQuery
=
function
()
{
return
[];
};
this
.
jio
.
repair
()
this
.
jio
.
repair
()
.
then
(
function
()
{
.
then
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
isEmptyStorage
(
test
.
jio
),
isEmptyStorage
(
test
.
jio
),
deepEqual
(
test
.
jio
.
__storage
.
_remote_storage_dict
,
{},
'
SubStorage empty
'
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
opml_mock_options
.
count
,
opml_mock_options
.
count
,
{
buildQuery
:
1
}
),
equalsubStorageCallCount
(
test
.
rss_mock_options
.
count
,
{}
{}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
web
_mock_options
.
count
,
rss
_mock_options
.
count
,
{}
{}
)
)
]);
]);
...
@@ -333,113 +292,90 @@
...
@@ -333,113 +292,90 @@
});
});
});
});
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// complete sync - one opml,
2
sub storages
// complete sync - one opml,
one
sub storages
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
test
(
"
complete storage sync
"
,
function
()
{
test
(
"
complete storage sync
"
,
function
()
{
expect
(
4
);
expect
(
3
);
stop
();
stop
();
var
test
=
this
,
var
test
=
this
,
doc_id
=
"
http://example.com/rss.xml
"
,
opml_doc
=
{
doc
=
{
title
:
"
opml item foo
"
,
title
:
"
opml item foo
"
,
htmlurl
:
"
http://example.com/
"
,
url
:
"
http://example.com/opml.xml
"
,
url
:
"
http://example.com/rss.xml
"
,
portal_type
:
"
opml
"
,
basic_login
:
"
cred foo
"
,
active
:
true
},
opml_id
=
generateHash
(
opml_doc
.
url
),
opml_outline_id
=
"
/1/0/0
"
,
opml_outline
=
{
opml_title
:
"
opml foo
"
,
dateCreated
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
dateModified
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
,
text
:
"
instance foo
"
,
text
:
"
instance foo
"
,
type
:
"
link
"
,
type
:
"
link
"
,
opml_title
:
"
opml foo
"
,
htmlUrl
:
"
http://example.com/
"
,
created_date
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
xmlUrl
:
"
http://example.com/rss.xml
"
,
modified_date
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
title
:
"
opml item foo
"
,
},
portal_type
:
"
opml-outline
"
,
parent_id
=
generateHash
(
test
.
sub_opml_storage
.
url
),
parent_id
:
opml_id
,
opml_item_id
=
generateHash
(
parent_id
+
doc_id
),
parent_url
:
opml_doc
.
url
,
opml_item
=
{
reference
:
generateHash
(
opml_id
+
opml_outline_id
),
name
:
doc_id
,
active
:
true
opml_title
:
doc
.
opml_title
,
},
parent_id
:
parent_id
,
promise_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
reference
:
generateHash
(
parent_id
+
doc_id
),
"
/0/0
"
),
creation_date
:
doc
.
created_date
,
promise_item
=
{
title
:
doc
.
title
,
link
:
"
http://www.domain.com/link.htm
"
,
type
:
"
opml-item
"
,
title
:
"
Item Example
"
,
url
:
test
.
sub_opml_storage
.
url
,
category
:
"
ERROR
"
,
signature
:
generateHash
(
JSON
.
stringify
(
doc
))
description
:
"
This is an example of an Item
"
,
},
guid
:
"
1102345
"
,
full_opml
=
new
Blob
([
JSON
.
stringify
(
doc
)]),
guid_isPermaLink
:
"
false
"
,
rss_id
=
"
1102345
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
rss_doc
=
{
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
"
link
"
:
"
http://www.domain.com/link.htm
"
,
channel
:
"
This is an example of an RSS feed
"
,
"
date
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
channel_item
:
"
instance foo
"
,
"
title
"
:
"
Item Example
"
,
parent_id
:
opml_outline
.
reference
,
"
category
"
:
"
ERROR
"
,
reference
:
promise_id
,
"
description
"
:
"
This is an example of an Item
"
,
status
:
"
ERROR
"
,
"
guid
"
:
"
1102345
"
,
portal_type
:
"
promise
"
,
"
siteTitle
"
:
"
instance foo
"
,
active
:
true
"
reference
"
:
"
This is an example of an RSS feed
"
,
"
siteLink
"
:
"
http://www.domain.com/link.htm
"
,
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
},
},
// Sub OPML document (rss)
rss_item_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
rss_feed_url
=
"
http://example.com/rss.xml
"
,
"
/0
"
),
rss_item_id
=
generateHash
(
opml_item
.
reference
+
rss_feed_url
+
rss_id
),
rss_item
=
{
rss_item
=
{
name
:
rss_id
,
title
:
"
instance foo
"
,
opml_title
:
opml_item
.
opml_title
,
description
:
"
This is an example of an RSS feed
"
,
parent_title
:
opml_item
.
title
,
link
:
"
http://www.domain.com/link.htm
"
,
parent_id
:
opml_item
.
reference
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
parent_id
:
opml_outline
.
reference
,
reference
:
rss_item_id
,
reference
:
rss_item_id
,
title
:
rss_doc
.
title
,
portal_type
:
"
rss
"
,
type
:
rss_doc
.
type
||
"
rssmock-item
"
,
active
:
true
url
:
rss_feed_url
,
};
status
:
rss_doc
.
category
,
creation_date
:
rss_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
rss_doc
))
},
full_rss
=
new
Blob
([
JSON
.
stringify
(
rss_doc
)]),
json_id
=
"
monitor.status
"
,
json_doc
=
{
title
:
"
document fooo
"
,
status
:
"
ERROR
"
,
date
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
type
:
"
global
"
,
foo_p
:
"
fooo parameter
"
,
bar_p
:
"
bar parameter
"
,
total_error
:
12345
},
// Sub OPML document (webhttp)
http_url
=
"
http://example.com/
"
,
json_item_id
=
generateHash
(
opml_item
.
reference
+
http_url
+
json_id
),
json_item
=
{
name
:
json_id
,
opml_title
:
opml_item
.
opml_title
,
parent_title
:
opml_item
.
title
,
parent_id
:
opml_item
.
reference
,
reference
:
json_item_id
,
title
:
json_doc
.
title
,
type
:
json_doc
.
type
,
url
:
http_url
,
status
:
json_doc
.
status
,
creation_date
:
json_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
json_doc
))
},
full_json
=
new
Blob
([
JSON
.
stringify
(
json_doc
)]);
test
.
jio
.
repair
()
test
.
jio
.
put
(
opml_doc
.
url
,
opml_doc
)
.
then
(
function
()
{
return
test
.
jio
.
repair
();
})
.
then
(
function
()
{
.
then
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
[[
opml_item_id
,
opml_item
,
full_opml
],
equalStorage
(
test
.
jio
,
[
[
rss_item_id
,
rss_item
,
full_rss
],
[
opml_doc
.
url
,
opml_doc
],
[
json_item_id
,
json_item
,
full_json
]]),
[
opml_outline
.
reference
,
opml_outline
],
equalsubStorageCallCount
(
[
rss_item_id
,
rss_item
],
test
.
opml_mock_options
.
count
,
[
promise_id
,
promise_item
]
{
buildQuery
:
1
}
]),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
rss
_mock_options
.
count
,
opml
_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
web
_mock_options
.
count
,
rss
_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
)
)
]);
]);
...
@@ -453,130 +389,125 @@
...
@@ -453,130 +389,125 @@
});
});
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// document update
//
remote
document update
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
test
(
"
remote document modified
"
,
function
()
{
test
(
"
remote document modified
"
,
function
()
{
expect
(
4
);
expect
(
3
);
stop
();
stop
();
var
test
=
this
,
var
test
=
this
,
doc_id
=
"
http://example.com/rss.xml
"
,
opml_doc
=
{
doc
=
{
title
:
"
opml item foo
"
,
title
:
"
opml item foo
"
,
htmlurl
:
"
http://example.com/
"
,
url
:
"
http://example.com/opml.xml
"
,
url
:
"
http://example.com/rss.xml
"
,
portal_type
:
"
opml
"
,
basic_login
:
"
cred foo
"
,
active
:
true
},
opml_id
=
generateHash
(
opml_doc
.
url
),
opml_outline_id
=
"
/1/0/0
"
,
opml_outline
=
{
opml_title
:
"
opml foo
"
,
dateCreated
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
dateModified
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
,
text
:
"
instance foo
"
,
text
:
"
instance foo
"
,
type
:
"
link
"
,
type
:
"
link
"
,
opml_title
:
"
opml foo
"
,
htmlUrl
:
"
http://example.com/
"
,
created_date
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
xmlUrl
:
"
http://example.com/rss.xml
"
,
modified_date
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
title
:
"
opml item foo
"
,
portal_type
:
"
opml-outline
"
,
parent_id
:
opml_id
,
parent_url
:
opml_doc
.
url
,
reference
:
generateHash
(
opml_id
+
opml_outline_id
),
active
:
true
},
promise_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
"
/0/0
"
),
promise_item
=
{
link
:
"
http://www.domain.com/link.htm
"
,
title
:
"
Item Example
"
,
category
:
"
ERROR
"
,
description
:
"
This is an example of an Item
"
,
guid
:
"
1102345
"
,
guid_isPermaLink
:
"
false
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
channel
:
"
This is an example of an RSS feed
"
,
channel_item
:
"
instance foo
"
,
parent_id
:
opml_outline
.
reference
,
reference
:
promise_id
,
status
:
"
ERROR
"
,
portal_type
:
"
promise
"
,
active
:
true
},
rss_item_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
"
/0
"
),
rss_item
=
{
title
:
"
instance foo
"
,
description
:
"
This is an example of an RSS feed
"
,
link
:
"
http://www.domain.com/link.htm
"
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
parent_id
:
opml_outline
.
reference
,
reference
:
rss_item_id
,
portal_type
:
"
rss
"
,
active
:
true
},
},
parent_id
=
generateHash
(
test
.
sub_opml_storage
.
url
),
updated_promise
=
JSON
.
parse
(
JSON
.
stringify
(
promise_item
));
opml_item_id
=
generateHash
(
parent_id
+
doc_id
),
opml_item
=
{
test
.
jio
.
put
(
opml_doc
.
url
,
opml_doc
)
name
:
doc_id
,
.
then
(
function
()
{
opml_title
:
doc
.
opml_title
,
return
test
.
jio
.
repair
();
parent_id
:
parent_id
,
})
reference
:
generateHash
(
parent_id
+
doc_id
),
.
then
(
function
()
{
creation_date
:
doc
.
created_date
,
rss_mock_options
.
mock
.
buildQuery
=
function
()
{
title
:
doc
.
title
,
return
[
type
:
"
opml-item
"
,
{
url
:
test
.
sub_opml_storage
.
url
,
"
id
"
:
"
/0
"
,
signature
:
generateHash
(
JSON
.
stringify
(
doc
))
"
value
"
:
{},
"
doc
"
:
{
"
title
"
:
"
instance foo
"
,
"
description
"
:
"
This is an example of an RSS feed
"
,
"
link
"
:
"
http://www.domain.com/link.htm
"
,
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
"
pubDate
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
}
},
},
full_opml
=
new
Blob
([
JSON
.
stringify
(
doc
)]),
{
rss_id
=
"
1102345
"
,
"
id
"
:
"
/0/0
"
,
rss_doc
=
{
"
value
"
:
{},
"
doc
"
:
{
"
link
"
:
"
http://www.domain.com/link.htm
"
,
"
link
"
:
"
http://www.domain.com/link.htm
"
,
"
date
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
"
pubDate
"
:
"
Tue, 29 Aug 2006 10:00:00 -0400
"
,
//Changed
"
title
"
:
"
Item Example
"
,
"
title
"
:
"
Item Example
"
,
"
category
"
:
"
ERROR
"
,
"
category
"
:
"
OK
"
,
// changed to OK
"
description
"
:
"
This is an example of an Item
"
,
"
description
"
:
"
This is an example of an Item
"
,
"
guid
"
:
"
1102345
"
,
"
guid
"
:
"
1102345
"
,
"
siteTitle
"
:
"
instance foo
"
,
"
guid_isPermaLink
"
:
"
false
"
"
reference
"
:
"
This is an example of an RSS feed
"
,
}
"
siteLink
"
:
"
http://www.domain.com/link.htm
"
,
}
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
];
},
// Sub OPML document (rss)
rss_feed_url
=
test
.
sub_opml_storage
.
sub_storage_list
[
0
].
url
,
rss_item_id
=
generateHash
(
opml_item
.
reference
+
rss_feed_url
+
rss_id
),
rss_item2
=
{
name
:
rss_id
,
opml_title
:
opml_item
.
opml_title
,
parent_title
:
opml_item
.
title
,
parent_id
:
opml_item
.
reference
,
reference
:
rss_item_id
,
title
:
rss_doc
.
title
,
type
:
rss_doc
.
type
||
"
rssmock-item
"
,
url
:
rss_feed_url
,
status
:
rss_doc
.
category
,
creation_date
:
rss_doc
.
date
},
rss_doc2
=
JSON
.
parse
(
JSON
.
stringify
(
rss_doc
)),
full_rss2
,
json_id
=
"
monitor.status
"
,
json_doc
=
{
title
:
"
document fooo
"
,
status
:
"
ERROR
"
,
date
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
type
:
"
global
"
,
foo_p
:
"
fooo parameter
"
,
bar_p
:
"
bar parameter
"
,
total_error
:
12345
},
// Sub OPML document (webhttp)
http_url
=
"
http://example.com/
"
,
json_item_id
=
generateHash
(
opml_item
.
reference
+
http_url
+
json_id
),
json_item
=
{
name
:
json_id
,
opml_title
:
opml_item
.
opml_title
,
parent_title
:
opml_item
.
title
,
parent_id
:
opml_item
.
reference
,
reference
:
json_item_id
,
title
:
json_doc
.
title
,
type
:
json_doc
.
type
,
url
:
http_url
,
status
:
json_doc
.
status
,
creation_date
:
json_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
json_doc
))
},
full_json
=
new
Blob
([
JSON
.
stringify
(
json_doc
)]);
/* Update rss document */
rss_doc2
.
date
=
"
new rss date
"
;
// new signature
rss_item2
.
signature
=
generateHash
(
JSON
.
stringify
(
rss_doc2
));
// modified date
rss_item2
.
creation_date
=
rss_doc2
.
date
;
// get the full rss item
full_rss2
=
new
Blob
([
JSON
.
stringify
(
rss_doc2
)]);
test
.
jio
.
repair
()
.
then
(
function
()
{
test
.
rss_mock_options
.
mock
.
buildQuery
=
function
()
{
return
[{
id
:
rss_id
,
doc
:
rss_doc2
,
value
:
{}}];
};
};
resetCount
(
test
.
opml_mock_options
.
count
);
updated_promise
.
pubDate
=
"
Tue, 29 Aug 2006 10:00:00 -0400
"
;
resetCount
(
test
.
rss_mock_options
.
count
);
updated_promise
.
category
=
"
OK
"
;
resetCount
(
test
.
web_mock_options
.
count
);
updated_promise
.
status
=
"
OK
"
;
resetCount
(
opml_mock_options
.
count
);
resetCount
(
rss_mock_options
.
count
);
return
test
.
jio
.
repair
();
return
test
.
jio
.
repair
();
})
})
.
then
(
function
()
{
.
then
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
[[
opml_item_id
,
opml_item
,
full_opml
],
equalStorage
(
test
.
jio
,
[
[
rss_item_id
,
rss_item2
,
full_rss2
],
[
opml_doc
.
url
,
opml_doc
],
[
json_item_id
,
json_item
,
full_json
]]),
[
opml_outline
.
reference
,
opml_outline
],
[
rss_item_id
,
rss_item
],
[
promise_id
,
updated_promise
]
]),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
opml_mock_options
.
count
,
opml_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
rss_mock_options
.
count
,
rss_mock_options
.
count
,
{
buildQuery
:
1
}
),
equalsubStorageCallCount
(
test
.
web_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
)
)
]);
]);
...
@@ -594,127 +525,112 @@
...
@@ -594,127 +525,112 @@
// remote document deleted - non exist in result
// remote document deleted - non exist in result
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
test
(
"
remote document deleted: empty result
"
,
function
()
{
test
(
"
remote document deleted: empty result
"
,
function
()
{
expect
(
5
);
expect
(
4
);
stop
();
stop
();
var
test
=
this
,
var
test
=
this
,
doc_id
=
"
http://example.com/rss.xml
"
,
opml_doc
=
{
doc
=
{
title
:
"
opml item foo
"
,
title
:
"
opml item foo
"
,
htmlurl
:
"
http://example.com/
"
,
url
:
"
http://example.com/opml.xml
"
,
url
:
"
http://example.com/rss.xml
"
,
portal_type
:
"
opml
"
,
basic_login
:
"
cred foo
"
,
active
:
true
},
opml_id
=
generateHash
(
opml_doc
.
url
),
opml_outline_id
=
"
/1/0/0
"
,
opml_outline
=
{
opml_title
:
"
opml foo
"
,
dateCreated
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
dateModified
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
,
text
:
"
instance foo
"
,
text
:
"
instance foo
"
,
type
:
"
link
"
,
type
:
"
link
"
,
opml_title
:
"
opml foo
"
,
htmlUrl
:
"
http://example.com/
"
,
created_date
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
xmlUrl
:
"
http://example.com/rss.xml
"
,
modified_date
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
title
:
"
opml item foo
"
,
},
portal_type
:
"
opml-outline
"
,
parent_id
=
generateHash
(
test
.
sub_opml_storage
.
url
),
parent_id
:
opml_id
,
opml_item_id
=
generateHash
(
parent_id
+
doc_id
),
parent_url
:
opml_doc
.
url
,
opml_item
=
{
reference
:
generateHash
(
opml_id
+
opml_outline_id
),
name
:
doc_id
,
active
:
true
opml_title
:
doc
.
opml_title
,
},
parent_id
:
parent_id
,
promise_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
reference
:
generateHash
(
parent_id
+
doc_id
),
"
/0/0
"
),
creation_date
:
doc
.
created_date
,
promise_item
=
{
title
:
doc
.
title
,
link
:
"
http://www.domain.com/link.htm
"
,
type
:
"
opml-item
"
,
title
:
"
Item Example
"
,
url
:
test
.
sub_opml_storage
.
url
,
category
:
"
ERROR
"
,
signature
:
generateHash
(
JSON
.
stringify
(
doc
))
description
:
"
This is an example of an Item
"
,
},
guid
:
"
1102345
"
,
full_opml
=
new
Blob
([
JSON
.
stringify
(
doc
)]),
guid_isPermaLink
:
"
false
"
,
rss_id
=
"
1102345
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
rss_doc
=
{
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
"
link
"
:
"
http://www.domain.com/link.htm
"
,
channel
:
"
This is an example of an RSS feed
"
,
"
date
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
channel_item
:
"
instance foo
"
,
"
title
"
:
"
Item Example
"
,
parent_id
:
opml_outline
.
reference
,
"
category
"
:
"
ERROR
"
,
reference
:
promise_id
,
"
description
"
:
"
This is an example of an Item
"
,
status
:
"
ERROR
"
,
"
guid
"
:
"
1102345
"
,
portal_type
:
"
promise
"
,
"
siteTitle
"
:
"
instance foo
"
,
active
:
true
"
reference
"
:
"
This is an example of an RSS feed
"
,
"
siteLink
"
:
"
http://www.domain.com/link.htm
"
,
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
},
},
// Sub OPML document (rss)
rss_item_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
rss_feed_url
=
"
http://example.com/rss.xml
"
,
"
/0
"
),
rss_item_id
=
generateHash
(
opml_item
.
reference
+
rss_feed_url
+
rss_id
),
rss_item
=
{
rss_item
=
{
name
:
rss_id
,
title
:
"
instance foo
"
,
opml_title
:
opml_item
.
opml_title
,
description
:
"
This is an example of an RSS feed
"
,
parent_title
:
opml_item
.
title
,
link
:
"
http://www.domain.com/link.htm
"
,
parent_id
:
opml_item
.
reference
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
parent_id
:
opml_outline
.
reference
,
reference
:
rss_item_id
,
reference
:
rss_item_id
,
title
:
rss_doc
.
title
,
portal_type
:
"
rss
"
,
type
:
rss_doc
.
type
||
"
rssmock-item
"
,
active
:
true
url
:
rss_feed_url
,
};
status
:
rss_doc
.
category
,
creation_date
:
rss_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
rss_doc
))
},
full_rss
=
new
Blob
([
JSON
.
stringify
(
rss_doc
)]),
json_id
=
"
monitor.status
"
,
json_doc
=
{
title
:
"
document fooo
"
,
status
:
"
ERROR
"
,
date
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
type
:
"
global
"
,
foo_p
:
"
fooo parameter
"
,
bar_p
:
"
bar parameter
"
,
total_error
:
12345
},
// Sub OPML document (webhttp)
http_url
=
"
http://example.com/
"
,
json_item_id
=
generateHash
(
opml_item
.
reference
+
http_url
+
json_id
),
json_item
=
{
name
:
json_id
,
opml_title
:
opml_item
.
opml_title
,
parent_title
:
opml_item
.
title
,
parent_id
:
opml_item
.
reference
,
reference
:
json_item_id
,
title
:
json_doc
.
title
,
type
:
json_doc
.
type
,
url
:
http_url
,
status
:
json_doc
.
status
,
creation_date
:
json_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
json_doc
))
},
full_json
=
new
Blob
([
JSON
.
stringify
(
json_doc
)]);
new
RSVP
.
Queue
(
)
test
.
jio
.
put
(
opml_doc
.
url
,
opml_doc
)
.
then
(
function
()
{
.
then
(
function
()
{
return
test
.
jio
.
repair
();
return
test
.
jio
.
repair
();
})
})
.
then
(
function
()
{
.
then
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
[[
opml_item_id
,
opml_item
,
full_opml
],
equalStorage
(
test
.
jio
,
[
[
rss_item_id
,
rss_item
,
full_rss
],
[
opml_doc
.
url
,
opml_doc
],
[
json_item_id
,
json_item
,
full_json
]])
[
opml_outline
.
reference
,
opml_outline
],
[
rss_item_id
,
rss_item
],
[
promise_id
,
promise_item
]
])
]);
]);
})
})
.
then
(
function
()
{
.
then
(
function
()
{
test
.
rss_mock_options
.
mock
.
buildQuery
=
function
()
{
rss_mock_options
.
mock
.
buildQuery
=
function
()
{
return
[];
return
[{
"
id
"
:
"
/0
"
,
"
value
"
:
{},
"
doc
"
:
{
"
title
"
:
"
instance foo
"
,
"
description
"
:
"
This is an example of an RSS feed
"
,
"
link
"
:
"
http://www.domain.com/link.htm
"
,
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
"
pubDate
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
}
}];
};
};
resetCount
(
test
.
opml_mock_options
.
count
);
resetCount
(
opml_mock_options
.
count
);
resetCount
(
test
.
rss_mock_options
.
count
);
resetCount
(
rss_mock_options
.
count
);
resetCount
(
test
.
web_mock_options
.
count
);
return
test
.
jio
.
repair
();
return
test
.
jio
.
repair
();
})
})
.
then
(
function
()
{
.
then
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
[[
opml_item_id
,
opml_item
,
full_opml
],
equalStorage
(
test
.
jio
,
[
[
json_item_id
,
json_item
,
full_json
]]),
[
opml_doc
.
url
,
opml_doc
],
[
opml_outline
.
reference
,
opml_outline
],
[
rss_item_id
,
rss_item
]
]),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
opml_mock_options
.
count
,
opml_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
rss_mock_options
.
count
,
rss_mock_options
.
count
,
{
buildQuery
:
1
}
),
equalsubStorageCallCount
(
test
.
web_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
)
)
]);
]);
...
@@ -727,336 +643,194 @@
...
@@ -727,336 +643,194 @@
});
});
});
});
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///
//
some document remove - id has changed
//
complete sync - more than one opml with sub storages
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
///
test
(
"
remote document removed
"
,
function
()
{
test
(
"
multi opml storage sync
"
,
function
()
{
expect
(
5
);
expect
(
5
);
stop
();
stop
();
var
test
=
this
,
var
test
=
this
,
doc_id
=
"
http://example.com/rss.xml
"
,
opml_doc
=
{
doc
=
{
title
:
"
opml item foo
"
,
title
:
"
opml item foo
"
,
htmlurl
:
"
http://example.com/
"
,
url
:
"
http://example.com/opml.xml
"
,
url
:
"
http://example.com/rss.xml
"
,
portal_type
:
"
opml
"
,
basic_login
:
"
cred foo
"
,
active
:
true
},
opml_id
=
generateHash
(
opml_doc
.
url
),
opml_outline_id
=
"
/1/0/0
"
,
opml_outline
=
{
opml_title
:
"
opml foo
"
,
dateCreated
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
dateModified
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
,
text
:
"
instance foo
"
,
text
:
"
instance foo
"
,
type
:
"
link
"
,
type
:
"
link
"
,
opml_title
:
"
opml foo
"
,
htmlUrl
:
"
http://example.com/
"
,
created_date
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
xmlUrl
:
"
http://example.com/rss.xml
"
,
modified_date
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
title
:
"
opml item foo
"
,
},
portal_type
:
"
opml-outline
"
,
parent_id
=
generateHash
(
test
.
sub_opml_storage
.
url
),
parent_id
:
opml_id
,
opml_item_id
=
generateHash
(
parent_id
+
doc_id
),
parent_url
:
opml_doc
.
url
,
opml_item
=
{
reference
:
generateHash
(
opml_id
+
opml_outline_id
),
name
:
doc_id
,
active
:
true
opml_title
:
doc
.
opml_title
,
},
parent_id
:
parent_id
,
promise_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
reference
:
generateHash
(
parent_id
+
doc_id
),
"
/0/0
"
),
creation_date
:
doc
.
created_date
,
promise_item
=
{
title
:
doc
.
title
,
link
:
"
http://www.domain.com/link.htm
"
,
type
:
"
opml-item
"
,
title
:
"
Item Example
"
,
url
:
test
.
sub_opml_storage
.
url
,
category
:
"
ERROR
"
,
signature
:
generateHash
(
JSON
.
stringify
(
doc
))
description
:
"
This is an example of an Item
"
,
},
guid
:
"
1102345
"
,
full_opml
=
new
Blob
([
JSON
.
stringify
(
doc
)]),
guid_isPermaLink
:
"
false
"
,
rss_id
=
"
1102345
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
rss_doc
=
{
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
"
link
"
:
"
http://www.domain.com/link.htm
"
,
channel
:
"
This is an example of an RSS feed
"
,
"
date
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
channel_item
:
"
instance foo
"
,
"
title
"
:
"
Item Example
"
,
parent_id
:
opml_outline
.
reference
,
"
category
"
:
"
ERROR
"
,
reference
:
promise_id
,
"
description
"
:
"
This is an example of an Item
"
,
status
:
"
ERROR
"
,
"
guid
"
:
"
1102345
"
,
portal_type
:
"
promise
"
,
"
siteTitle
"
:
"
instance foo
"
,
active
:
true
"
reference
"
:
"
This is an example of an RSS feed
"
,
"
siteLink
"
:
"
http://www.domain.com/link.htm
"
,
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
},
},
// Sub OPML document (rss)
rss_item_id
=
generateHash
(
opml_outline
.
reference
+
opml_outline
.
xmlUrl
+
rss_feed_url
=
"
http://example.com/rss.xml
"
,
"
/0
"
),
rss_item_id
=
generateHash
(
opml_item
.
reference
+
rss_feed_url
+
rss_id
),
rss_item
=
{
rss_item
=
{
name
:
rss_id
,
title
:
"
instance foo
"
,
opml_title
:
opml_item
.
opml_title
,
description
:
"
This is an example of an RSS feed
"
,
parent_title
:
opml_item
.
title
,
link
:
"
http://www.domain.com/link.htm
"
,
parent_id
:
opml_item
.
reference
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
parent_id
:
opml_outline
.
reference
,
reference
:
rss_item_id
,
reference
:
rss_item_id
,
title
:
rss_doc
.
title
,
portal_type
:
"
rss
"
,
type
:
rss_doc
.
type
||
"
rssmock-item
"
,
active
:
true
url
:
rss_feed_url
,
status
:
rss_doc
.
category
,
creation_date
:
rss_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
rss_doc
))
},
full_rss
=
new
Blob
([
JSON
.
stringify
(
rss_doc
)]),
json_id
=
"
monitor.status
"
,
json_doc
=
{
title
:
"
document fooo
"
,
status
:
"
ERROR
"
,
date
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
type
:
"
global
"
,
foo_p
:
"
fooo parameter
"
,
bar_p
:
"
bar parameter
"
,
total_error
:
12345
},
},
// Sub OPML document (webhttp)
opml_doc2
=
{
http_url
=
"
http://example.com/
"
,
title
:
"
opml item bar
"
,
json_item_id
=
generateHash
(
opml_item
.
reference
+
http_url
+
json_id
),
url
:
"
http://example2.com/opml.xml
"
,
json_item
=
{
portal_type
:
"
opml
"
,
name
:
json_id
,
basic_login
:
"
cred bar
"
,
opml_title
:
opml_item
.
opml_title
,
active
:
true
parent_title
:
opml_item
.
title
,
parent_id
:
opml_item
.
reference
,
reference
:
json_item_id
,
title
:
json_doc
.
title
,
type
:
json_doc
.
type
,
url
:
http_url
,
status
:
json_doc
.
status
,
creation_date
:
json_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
json_doc
))
},
},
full_json
=
new
Blob
([
JSON
.
stringify
(
json_doc
)]),
opml_id2
=
generateHash
(
opml_doc2
.
url
),
/* rss doc 2 with different id */
opml_outline2
=
{
rss_id2
=
"
1102345-new
"
,
opml_title
:
"
opml foo
"
,
rss_item2_id
=
generateHash
(
opml_item
.
reference
+
rss_feed_url
+
rss_id2
),
dateCreated
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
rss_item2
=
JSON
.
parse
(
JSON
.
stringify
(
rss_item
));
dateModified
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
,
rss_item2
.
name
=
rss_id2
;
rss_item2
.
reference
=
rss_item2_id
;
test
.
jio
.
repair
()
.
then
(
function
()
{
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
[[
opml_item_id
,
opml_item
,
full_opml
],
[
rss_item_id
,
rss_item
,
full_rss
],
[
json_item_id
,
json_item
,
full_json
]])
]);
})
.
then
(
function
()
{
test
.
rss_mock_options
.
mock
.
buildQuery
=
function
()
{
// return a different document
return
[{
id
:
rss_id2
,
doc
:
rss_doc
,
value
:
{}}];
};
resetCount
(
test
.
opml_mock_options
.
count
);
resetCount
(
test
.
rss_mock_options
.
count
);
resetCount
(
test
.
web_mock_options
.
count
);
return
test
.
jio
.
repair
();
})
.
then
(
function
()
{
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
[[
opml_item_id
,
opml_item
,
full_opml
],
[
json_item_id
,
json_item
,
full_json
],
[
rss_item2_id
,
rss_item2
,
full_rss
]]),
equalsubStorageCallCount
(
test
.
opml_mock_options
.
count
,
{
buildQuery
:
1
}
),
equalsubStorageCallCount
(
test
.
rss_mock_options
.
count
,
{
buildQuery
:
1
}
),
equalsubStorageCallCount
(
test
.
web_mock_options
.
count
,
{
buildQuery
:
1
}
)
]);
})
.
fail
(
function
(
error
)
{
console
.
log
(
error
);
ok
(
false
,
error
);
})
.
always
(
function
()
{
start
();
});
});
///////////////////////////////////////////////////////
// complete sync - 2 opmls, 3 sub storages
///////////////////////////////////////////////////////
test
(
"
multi opml storage sync
"
,
function
()
{
expect
(
6
);
stop
();
var
test
=
this
,
doc_id
=
"
http://example.com/rss.xml
"
,
doc
=
{
title
:
"
opml item foo
"
,
htmlurl
:
"
http://example.com/
"
,
url
:
"
http://example.com/rss.xml
"
,
text
:
"
instance foo
"
,
text
:
"
instance foo
"
,
type
:
"
link
"
,
type
:
"
link
"
,
opml_title
:
"
opml foo
"
,
htmlUrl
:
"
http://example2.com/
"
,
created_date
:
"
Thu, 12 Sep 2003 23:35:52 GMT
"
,
xmlUrl
:
"
http://example2.com/rss.xml
"
,
modified_date
:
"
Fri, 12 Sep 2003 23:45:37 GMT
"
title
:
"
opml item foo
"
,
},
portal_type
:
"
opml-outline
"
,
full_opml
=
new
Blob
([
JSON
.
stringify
(
doc
)]),
parent_id
:
opml_id2
,
rss_id
=
"
1102345
"
,
parent_url
:
opml_doc2
.
url
,
rss_doc
=
{
reference
:
generateHash
(
opml_id2
+
opml_outline_id
),
"
link
"
:
"
http://www.domain.com/link.htm
"
,
active
:
true
"
date
"
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
},
"
title
"
:
"
Item Example
"
,
promise_id2
=
generateHash
(
opml_outline2
.
reference
+
"
category
"
:
"
ERROR
"
,
opml_outline2
.
xmlUrl
+
"
/0/0
"
),
"
description
"
:
"
This is an example of an Item
"
,
promise_item2
=
{
"
guid
"
:
"
1102345
"
,
link
:
"
http://www.domain.com/link.htm
"
,
"
siteTitle
"
:
"
instance foo
"
,
title
:
"
Item Example
"
,
"
reference
"
:
"
This is an example of an RSS feed
"
,
category
:
"
ERROR
"
,
"
siteLink
"
:
"
http://www.domain.com/link.htm
"
,
description
:
"
This is an example of an Item
"
,
"
lastBuildDate
"
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
guid
:
"
11026875
"
,
},
guid_isPermaLink
:
"
false
"
,
full_rss
=
new
Blob
([
JSON
.
stringify
(
rss_doc
)]),
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
json_id
=
"
monitor.status
"
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
json_doc
=
{
channel
:
"
This is an example of an RSS feed
"
,
title
:
"
document fooo
"
,
channel_item
:
"
instance foo
"
,
parent_id
:
opml_outline2
.
reference
,
reference
:
promise_id2
,
status
:
"
ERROR
"
,
status
:
"
ERROR
"
,
date
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
portal_type
:
"
promise
"
,
type
:
"
global
"
,
active
:
true
foo_p
:
"
fooo parameter
"
,
bar_p
:
"
bar parameter
"
,
total_error
:
12345
},
},
full_json
=
new
Blob
([
JSON
.
stringify
(
json_doc
)]),
rss_item_id2
=
generateHash
(
opml_outline2
.
reference
+
item_dict
=
{},
opml_outline2
.
xmlUrl
+
"
/0
"
),
rss_url
=
"
http://example.com/rss.xml
"
,
rss_item2
=
{
rss2_url
=
"
http://example2.com/rss.xml
"
,
title
:
"
instance foo
"
,
http_url
=
"
http://example.com/
"
;
description
:
"
This is an example of an RSS feed
"
,
link
:
"
http://www.domain.com/link.htm
"
,
lastBuildDate
:
"
Mon, 28 Aug 2006 11:12:55 -0400
"
,
pubDate
:
"
Tue, 29 Aug 2006 09:00:00 -0400
"
,
parent_id
:
opml_outline2
.
reference
,
reference
:
rss_item_id2
,
portal_type
:
"
rss
"
,
active
:
true
};
// update storage with 2 opmls
opml_mock_options2
=
{
// opml2 has only rss feed substorage
this
.
sub_opml_storage2
=
{
type
:
"
opmlmock
"
,
options
:
{
mock
:
{
mock
:
{
remove
:
function
()
{
throw
new
Error
(
'
remove not supported
'
);
},
},
count
:
{}
removeAttachment
:
function
()
{
throw
new
Error
(
'
removeAttachment not supported
'
);
},
},
url
:
"
http://example2.com/opml.xml
"
,
allAttachments
:
function
()
{
sub_storage_list
:
[
return
{
data
:
null
};
{
type
:
"
rssmock
"
,
url
:
"
http://example2.com/rss.xml
"
,
has_include_docs
:
true
,
options
:
{
mock
:
{
},
},
count
:
{}
putAttachment
:
function
()
{
}
throw
new
Error
(
'
putAttachment not supported
'
);
}
}
]
},
count
:
{}
};
};
this
.
jio
=
jIO
.
createJIO
({
rss_mock_options2
=
{
type
:
"
replicatedopml
"
,
mock
:
{
opml_storage_list
:
[
remove
:
function
()
{
this
.
sub_opml_storage
,
throw
new
Error
(
'
remove not supported
'
);
this
.
sub_opml_storage2
},
],
removeAttachment
:
function
()
{
local_sub_storage
:
{
throw
new
Error
(
'
removeAttachment not supported
'
);
type
:
"
query
"
,
},
sub_storage
:
{
allAttachments
:
function
()
{
type
:
"
uuid
"
,
return
{
data
:
null
};
sub_storage
:
{
},
type
:
"
memory
"
putAttachment
:
function
()
{
}
throw
new
Error
(
'
putAttachment not supported
'
);
}
}
}
});
},
count
:
{}
/* Expected item in indexeddb*/
item_dict
.
opml
=
{
parent_id
:
generateHash
(
test
.
sub_opml_storage
.
url
),
reference
:
generateHash
(
generateHash
(
test
.
sub_opml_storage
.
url
)
+
doc_id
),
name
:
doc_id
,
opml_title
:
doc
.
opml_title
,
creation_date
:
doc
.
created_date
,
title
:
doc
.
title
,
type
:
"
opml-item
"
,
url
:
test
.
sub_opml_storage
.
url
,
signature
:
generateHash
(
JSON
.
stringify
(
doc
))
};
item_dict
.
opml2
=
{
parent_id
:
generateHash
(
test
.
sub_opml_storage2
.
url
),
reference
:
generateHash
(
generateHash
(
test
.
sub_opml_storage2
.
url
)
+
doc_id
),
name
:
doc_id
,
opml_title
:
doc
.
opml_title
,
creation_date
:
doc
.
created_date
,
title
:
doc
.
title
,
type
:
"
opml-item
"
,
url
:
test
.
sub_opml_storage2
.
url
,
signature
:
generateHash
(
JSON
.
stringify
(
doc
))
};
item_dict
.
rss
=
{
name
:
rss_id
,
opml_title
:
item_dict
.
opml
.
opml_title
,
parent_title
:
item_dict
.
opml
.
title
,
parent_id
:
item_dict
.
opml
.
reference
,
reference
:
generateHash
(
item_dict
.
opml
.
reference
+
rss_url
+
rss_id
),
title
:
rss_doc
.
title
,
type
:
rss_doc
.
type
||
"
rssmock-item
"
,
url
:
rss_url
,
status
:
rss_doc
.
category
,
creation_date
:
rss_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
rss_doc
))
};
item_dict
.
rss2
=
{
name
:
rss_id
,
opml_title
:
item_dict
.
opml2
.
opml_title
,
parent_title
:
item_dict
.
opml2
.
title
,
parent_id
:
item_dict
.
opml2
.
reference
,
reference
:
generateHash
(
item_dict
.
opml2
.
reference
+
rss2_url
+
rss_id
),
title
:
rss_doc
.
title
,
type
:
"
rssmock-item
"
,
url
:
rss2_url
,
status
:
rss_doc
.
category
,
creation_date
:
rss_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
rss_doc
))
};
item_dict
.
json
=
{
name
:
json_id
,
opml_title
:
item_dict
.
opml
.
opml_title
,
parent_title
:
item_dict
.
opml
.
title
,
parent_id
:
item_dict
.
opml
.
reference
,
reference
:
generateHash
(
item_dict
.
opml
.
reference
+
http_url
+
json_id
),
title
:
json_doc
.
title
,
type
:
json_doc
.
type
,
url
:
http_url
,
status
:
json_doc
.
status
,
creation_date
:
json_doc
.
date
,
signature
:
generateHash
(
JSON
.
stringify
(
json_doc
))
};
};
new
RSVP
.
Queue
()
test
.
jio
.
put
(
opml_doc
.
url
,
opml_doc
)
.
then
(
function
()
{
return
test
.
jio
.
put
(
opml_doc2
.
url
,
opml_doc2
);
})
.
then
(
function
()
{
.
then
(
function
()
{
return
test
.
jio
.
repair
();
return
test
.
jio
.
repair
();
})
})
.
then
(
function
()
{
.
then
(
function
()
{
return
RSVP
.
all
([
return
RSVP
.
all
([
equalStorage
(
test
.
jio
,
equalStorage
(
test
.
jio
,
[
[[
item_dict
.
opml
.
reference
,
item_dict
.
opml
,
full_opml
],
[
opml_doc
.
url
,
opml_doc
],
[
item_dict
.
rss
.
reference
,
item_dict
.
rss
,
full_rss
],
[
opml_doc2
.
url
,
opml_doc2
],
[
item_dict
.
json
.
reference
,
item_dict
.
json
,
full_json
],
[
opml_outline
.
reference
,
opml_outline
],
[
item_dict
.
opml2
.
reference
,
item_dict
.
opml2
,
full_opml
],
[
rss_item_id
,
rss_item
],
[
item_dict
.
rss2
.
reference
,
item_dict
.
rss2
,
full_rss
]]
[
promise_id
,
promise_item
],
),
[
opml_outline2
.
reference
,
opml_outline2
],
equalsubStorageCallCount
(
[
rss_item_id2
,
rss_item2
],
test
.
opml_mock_options
.
count
,
[
promise_id2
,
promise_item2
]
{
buildQuery
:
1
}
]),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
rss
_mock_options
.
count
,
opml
_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
web
_mock_options
.
count
,
rss
_mock_options
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
sub_opml_storage2
.
options
.
count
,
opml_mock_options2
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
),
),
equalsubStorageCallCount
(
equalsubStorageCallCount
(
test
.
sub_opml_storage2
.
sub_storage_list
[
0
].
options
.
count
,
rss_mock_options2
.
count
,
{
buildQuery
:
1
}
{
buildQuery
:
1
}
)
)
]);
]);
...
...
src/jio.storage/replicatedopmltreestorage.js
View file @
39feb6e5
...
@@ -5,7 +5,7 @@
...
@@ -5,7 +5,7 @@
*/
*/
/*jslint nomen: true */
/*jslint nomen: true */
/*global jIO, RSVP, Rusha,
Blob, console
*/
/*global jIO, RSVP, Rusha,
console, Blob
*/
(
function
(
jIO
,
RSVP
,
Rusha
,
Blob
,
console
)
{
(
function
(
jIO
,
RSVP
,
Rusha
,
Blob
,
console
)
{
"
use strict
"
;
"
use strict
"
;
...
@@ -16,19 +16,8 @@
...
@@ -16,19 +16,8 @@
*
*
* {
* {
* "type": "replicatedopml",
* "type": "replicatedopml",
* "opml_storage_list": [
* "remote_storage_unreachable_status": "WARNING",
* {
* "remote_opml_check_time_interval": 86400000,
* "type": "opml",
* "url": "http://some.url.com",
* "sub_storage_list": [
* {"type": "rss", "url_attribute": "xmlUrl"},
* {"type": "webdav": "url_path": "/"},
* {"type": "webdav", "url_path": "/data/"},
* {"type": "webhttp": "url_path": "/storage"}
* ],
* "basic_login": "XUSODISOIDOISUJDD=="
* }
* ],
* local_sub_storage: {
* local_sub_storage: {
* type: "query",
* type: "query",
* sub_storage: {
* sub_storage: {
...
@@ -41,7 +30,7 @@
...
@@ -41,7 +30,7 @@
*/
*/
var
rusha
=
new
Rusha
(),
var
rusha
=
new
Rusha
(),
KNOWN_SUB_STORAGE_LIST
=
[
'
rss
'
,
'
dav
'
,
'
webhttp
'
]
;
OPML_ATTACHMENT_NAME
=
"
__opml__
"
;
function
generateHash
(
str
)
{
function
generateHash
(
str
)
{
return
rusha
.
digestFromString
(
str
);
return
rusha
.
digestFromString
(
str
);
...
@@ -61,48 +50,28 @@
...
@@ -61,48 +50,28 @@
* @constructor
* @constructor
*/
*/
function
ReplicatedOPMLStorage
(
spec
)
{
function
ReplicatedOPMLStorage
(
spec
)
{
var
i
,
if
(
typeof
spec
.
type
!==
'
string
'
)
{
j
;
function
checkSubStorage
(
sub_storage_spec
)
{
if
(
typeof
sub_storage_spec
.
url
!==
'
string
'
&&
typeof
sub_storage_spec
.
url_path
!==
'
string
'
&&
typeof
sub_storage_spec
.
url_attribute
!==
'
string
'
)
{
throw
new
TypeError
(
"
one or more OPML sub storage(s) has no 'url' set
"
);
}
if
(
typeof
sub_storage_spec
.
type
!==
'
string
'
)
{
throw
new
TypeError
(
throw
new
TypeError
(
"
one or more OPML sub storage(s) has no attribute 'type' set
"
"
ReplicatedOPMLStorage 'type' is not a string
"
);
);
}
}
}
if
(
typeof
spec
.
opml_storage_list
!==
'
object
'
)
{
throw
new
TypeError
(
"
ReplicatedOPMLStorage 'opml_storage_list'
"
+
"
is not of type object
"
);
}
if
(
spec
.
local_sub_storage
===
undefined
)
{
if
(
spec
.
local_sub_storage
===
undefined
)
{
throw
new
TypeError
(
"
ReplicatedOPMLStorage 'local_sub_storage'
"
+
throw
new
TypeError
(
"
ReplicatedOPMLStorage 'local_sub_storage'
"
+
"
is not defined
"
);
"
is not defined
"
);
}
}
this
.
_local_sub_storage
=
jIO
.
createJIO
(
spec
.
local_sub_storage
);
this
.
_local_sub_storage
=
jIO
.
createJIO
(
spec
.
local_sub_storage
);
this
.
_remote_storage_unreachable_status
=
spec
.
remote_storage_unreachable_status
;
this
.
_remote_storage_dict
=
{};
this
.
_remote_storage_dict
=
{};
this
.
_opml_storage_list
=
spec
.
opml_storage_list
;
this
.
_remote_parser_storage_type
=
spec
.
remote_parser_storage_type
;
for
(
i
=
0
;
i
<
this
.
_opml_storage_list
.
length
;
i
+=
1
)
{
if
(
this
.
_remote_parser_storage_type
===
undefined
)
{
if
(
typeof
this
.
_opml_storage_list
[
i
].
url
!==
'
string
'
)
{
this
.
_remote_parser_storage_type
=
"
parser
"
;
throw
new
TypeError
(
"
opml storage 'url' is not of type string
"
);
}
if
(
this
.
_opml_storage_list
[
i
].
sub_storage_list
!==
undefined
)
{
for
(
j
=
0
;
j
<
this
.
_opml_storage_list
[
i
].
sub_storage_list
.
length
;
j
+=
1
)
{
checkSubStorage
(
this
.
_opml_storage_list
[
i
].
sub_storage_list
[
j
]);
}
}
}
this
.
_remote_opml_check_time_interval
=
/*if (spec.opml_storage_list[i].type !== 'opml') {
spec
.
remote_opml_check_time_interval
;
throw new TypeError("ReplicatedOPMLStorage 'type' should be 'opml'");
if
(
this
.
_remote_opml_check_time_interval
===
undefined
)
{
}*/
// one day in miliseconds
this
.
_remote_opml_check_time_interval
=
86400000
;
}
}
}
}
...
@@ -116,10 +85,15 @@
...
@@ -116,10 +85,15 @@
arguments
);
arguments
);
};
};
/*ReplicatedOPMLStorage.prototype.put = function () {
ReplicatedOPMLStorage
.
prototype
.
put
=
function
(
id
,
doc
)
{
return this._local_sub_storage.put.apply(this._local_sub_storage,
if
(
!
doc
.
hasOwnProperty
(
'
portal_type
'
)
||
doc
.
portal_type
!==
'
opml
'
)
{
arguments);
throw
new
TypeError
(
"
Cannot put object which portal_type is not 'opml'
"
);
};*/
}
if
(
doc
.
active
===
undefined
)
{
doc
.
active
=
true
;
}
return
this
.
_local_sub_storage
.
put
(
id
,
doc
);
};
ReplicatedOPMLStorage
.
prototype
.
hasCapacity
=
function
(
capacity
)
{
ReplicatedOPMLStorage
.
prototype
.
hasCapacity
=
function
(
capacity
)
{
if
(
capacity
===
'
include
'
)
{
if
(
capacity
===
'
include
'
)
{
...
@@ -134,44 +108,105 @@
...
@@ -134,44 +108,105 @@
arguments
);
arguments
);
};
};
ReplicatedOPMLStorage
.
prototype
.
allAttachments
=
function
()
{
ReplicatedOPMLStorage
.
prototype
.
remove
=
function
(
id
)
{
return
this
.
_local_sub_storage
.
allAttachments
.
apply
(
this
.
_local_sub_storage
,
var
storage
=
this
.
_local_sub_storage
;
arguments
);
return
storage
.
get
(
id
)
};
.
push
(
function
(
doc
)
{
if
(
doc
.
portal_type
!==
'
opml
'
)
{
throw
new
TypeError
(
"
Object with portal_type
"
+
doc
.
portal_type
+
"
is frozen, cannot remove it.
"
);
}
function
removeOPMLTree
(
url
)
{
var
remove_id_list
=
[],
remove_signature_id_list
=
[];
remove_signature_id_list
.
push
({
id
:
url
,
name
:
url
});
return
storage
.
allDocs
({
select_list
:
[
"
xmlUrl
"
,
"
url
"
],
query
:
'
(portal_type:"opml-outline") AND (parent_url:"
'
+
url
+
'
")
'
})
.
push
(
function
(
document_result
)
{
var
i
,
query_list
=
[];
for
(
i
=
0
;
i
<
document_result
.
data
.
total_rows
;
i
+=
1
)
{
query_list
.
push
(
'
(parent_id:"
'
+
document_result
.
data
.
rows
[
i
].
id
+
'
")
'
);
function
getSubOpmlStorageDescription
(
storage_spec
,
opml_doc
,
basic_login
)
{
remove_id_list
.
push
(
document_result
.
data
.
rows
[
i
].
id
);
remove_signature_id_list
.
push
({
id
:
document_result
.
data
.
rows
[
i
].
id
,
name
:
document_result
.
data
.
rows
[
i
].
value
.
xmlUrl
});
remove_signature_id_list
.
push
({
id
:
document_result
.
data
.
rows
[
i
].
id
,
name
:
document_result
.
data
.
rows
[
i
].
value
.
url
});
}
// cleanup all sub opml items
if
(
query_list
.
length
>
0
)
{
return
storage
.
allDocs
({
query
:
query_list
.
join
(
"
OR
"
)});
}
return
{
data
:
{
total_rows
:
0
}};
})
.
push
(
function
(
sub_item_result
)
{
var
j
,
i
,
k
,
remove_queue
=
new
RSVP
.
Queue
();
if
(
storage_spec
.
basic_login
===
undefined
&&
basic_login
!==
undefined
)
{
function
removeItem
(
key
)
{
storage_spec
.
basic_login
=
basic_login
;
remove_queue
.
push
(
function
()
{
return
storage
.
remove
(
key
);
});
}
}
if
(
KNOWN_SUB_STORAGE_LIST
.
indexOf
(
storage_spec
.
type
)
!==
-
1
)
{
function
removeAttachmentItem
(
id
,
name
)
{
if
(
storage_spec
.
url_attribute
!==
undefined
&&
remove_queue
opml_doc
.
hasOwnProperty
(
storage_spec
.
url_attribute
))
{
.
push
(
function
()
{
storage_spec
.
url
=
opml_doc
[
storage_spec
.
url_attribute
];
return
storage
.
removeAttachment
(
id
,
name
);
}
else
if
(
storage_spec
.
url_path
!==
undefined
)
{
})
storage_spec
.
url_path
=
storage_spec
.
url_path
.
replace
(
.
push
(
undefined
,
function
(
error
)
{
new
RegExp
(
"
^[/]+
"
),
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
""
(
error
.
status_code
===
404
))
{
return
undefined
;
}
throw
error
;
});
}
// remove signatures
for
(
k
=
0
;
k
<
remove_signature_id_list
.
length
;
k
+=
1
)
{
removeAttachmentItem
(
remove_signature_id_list
[
k
].
id
,
remove_signature_id_list
[
k
].
name
);
);
storage_spec
.
url
=
opml_doc
.
url
.
replace
(
new
RegExp
(
"
[/]+$
"
),
""
)
+
"
/
"
+
storage_spec
.
url_path
;
}
// XXX - for compatibility, remove url with jio_private path
storage_spec
.
url
=
storage_spec
.
url
.
replace
(
"
jio_private
"
,
"
private
"
);
if
(
storage_spec
.
type
===
"
dav
"
)
{
storage_spec
=
{
type
:
"
query
"
,
sub_storage
:
{
type
:
"
drivetojiomapping
"
,
sub_storage
:
storage_spec
}
}
};
// remove opml-outline sub-items (rss)
for
(
j
=
0
;
j
<
sub_item_result
.
data
.
total_rows
;
j
+=
1
)
{
removeItem
(
sub_item_result
.
data
.
rows
[
j
].
id
);
}
}
// remove opml-outline
for
(
i
=
0
;
i
<
remove_id_list
.
length
;
i
+=
1
)
{
removeItem
(
remove_id_list
[
i
]);
}
}
return
storage_spec
;
return
remove_queue
;
})
.
push
(
function
()
{
return
storage
.
remove
(
url
);
});
}
}
return
removeOPMLTree
(
id
);
});
};
ReplicatedOPMLStorage
.
prototype
.
allAttachments
=
function
()
{
return
this
.
_local_sub_storage
.
allAttachments
.
apply
(
this
.
_local_sub_storage
,
arguments
);
};
function
getStorageUrl
(
storage_spec
)
{
function
getStorageUrl
(
storage_spec
)
{
var
spec
=
storage_spec
;
var
spec
=
storage_spec
;
...
@@ -179,93 +214,146 @@
...
@@ -179,93 +214,146 @@
if
(
spec
.
url
!==
undefined
)
{
if
(
spec
.
url
!==
undefined
)
{
return
spec
.
url
;
return
spec
.
url
;
}
}
if
(
spec
.
document_id
!==
undefined
)
{
return
spec
.
document_id
;
}
spec
=
spec
.
sub_storage
;
spec
=
spec
.
sub_storage
;
}
}
throw
new
Error
(
"
No url found on sub storage:
"
+
throw
new
Error
(
"
No url found on sub storage:
"
+
JSON
.
stringify
(
storage_spec
));
JSON
.
stringify
(
storage_spec
));
}
}
function
loadSubStorage
(
context
,
spec
,
parent_id
,
opml_doc
,
basic_login
)
{
function
getDocumentAsAttachment
(
context
,
attachment_id
,
name
)
{
return
context
.
_local_sub_storage
.
getAttachment
(
attachment_id
,
name
)
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
return
undefined
;
}
console
.
error
(
error
);
})
.
push
(
function
(
attachment
)
{
if
(
attachment
)
{
return
jIO
.
util
.
readBlobAsText
(
attachment
)
.
then
(
function
(
evt
)
{
return
JSON
.
parse
(
evt
.
target
.
result
);
});
}
return
{};
});
}
function
updateSubStorageStatus
(
context
,
signature_dict
,
next_status
)
{
var
key
,
update_status_queue
=
new
RSVP
.
Queue
();
function
updateStatus
(
id
)
{
update_status_queue
.
push
(
function
()
{
return
context
.
_local_sub_storage
.
get
(
id
);
})
.
push
(
function
(
doc
)
{
if
(
doc
.
portal_type
===
"
promise
"
)
{
doc
.
category
=
next_status
;
return
context
.
_local_sub_storage
.
put
(
id
,
doc
);
}
if
(
doc
.
status
!==
undefined
)
{
doc
.
status
=
next_status
;
return
context
.
_local_sub_storage
.
put
(
id
,
doc
);
}
});
}
for
(
key
in
signature_dict
)
{
if
(
signature_dict
.
hasOwnProperty
(
key
))
{
if
(
signature_dict
[
key
].
status
!==
next_status
)
{
updateStatus
(
key
);
signature_dict
[
key
].
status
=
next_status
;
}
}
}
return
update_status_queue
.
push
(
function
()
{
return
signature_dict
;
});
}
function
loadSubStorage
(
context
,
storage_spec
,
parent_id
,
type
)
{
var
sub_storage
,
var
sub_storage
,
storage_spec
,
options
=
{},
result_dict
,
result_dict
,
storage_key
,
storage_key
,
url
;
url
;
if
(
spec
.
has_include_docs
===
true
)
{
options
=
{
include_docs
:
true
};
}
try
{
storage_spec
=
getSubOpmlStorageDescription
(
spec
,
opml_doc
,
basic_login
);
url
=
getStorageUrl
(
storage_spec
);
url
=
getStorageUrl
(
storage_spec
);
storage_key
=
generateHash
(
parent_id
+
url
);
storage_key
=
generateHash
(
parent_id
+
url
);
sub_storage
=
createStorage
(
context
,
storage_spec
,
storage_key
);
sub_storage
=
createStorage
(
context
,
storage_spec
,
storage_key
);
}
catch
(
error
)
{
console
.
log
(
error
);
throw
error
;
}
result_dict
=
{
result_dict
=
{
parent_id
:
parent_id
,
parent_id
:
parent_id
,
parent_title
:
opml_doc
.
title
,
type
:
type
||
storage_spec
.
type
,
opml_title
:
opml_doc
.
opml_title
,
current_signature
:
{},
type
:
storage_spec
.
type
,
result
:
{
data
:
{
total_rows
:
0
}},
current_doc
:
{},
result
:
{
data
:
{
total_rows
:
0
}
},
url
:
url
url
:
url
};
};
return
sub_storage
.
allDocs
(
options
)
return
sub_storage
.
allDocs
(
{
include_docs
:
true
}
)
.
push
(
undefined
,
function
(
error
)
{
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
(
error
.
status_code
===
404
))
{
console
.
log
(
error
);
return
undefined
;
}
//throw error;
//throw error;
// throw will cancel all others allDocs, this is not wanted
console
.
error
(
error
);
console
.
log
(
error
);
return
undefined
;
return
undefined
;
})
})
.
push
(
function
(
result
)
{
.
push
(
function
(
result
)
{
if
(
result
===
undefined
)
{
if
(
result
===
undefined
)
{
return
{
data
:
{
total_rows
:
0
}};
if
(
context
.
_remote_storage_unreachable_status
!==
undefined
)
{
// update status of local documents
// and set unreachable status
return
getDocumentAsAttachment
(
context
,
parent_id
,
url
)
.
push
(
function
(
signature_document
)
{
return
updateSubStorageStatus
(
context
,
signature_document
,
context
.
_remote_storage_unreachable_status
);
})
.
push
(
function
(
signature_dict
)
{
return
signature_dict
;
});
}
return
{};
}
}
result_dict
.
result
=
result
;
result_dict
.
result
=
result
;
return
context
.
_local_sub_storage
.
allDocs
({
return
getDocumentAsAttachment
(
select_list
:
[
"
signature
"
],
context
,
query
:
'
(parent_id: "
'
+
parent_id
+
'
") AND (url:"
'
+
url
+
'
")
'
parent_id
,
});
url
);
})
})
.
push
(
function
(
all_document
)
{
.
push
(
function
(
signature_document
)
{
var
i
;
result_dict
.
current_signature
=
signature_document
;
for
(
i
=
0
;
i
<
all_document
.
data
.
total_rows
;
i
+=
1
)
{
result_dict
.
current_doc
[
all_document
.
data
.
rows
[
i
].
id
]
=
all_document
.
data
.
rows
[
i
].
value
;
}
return
result_dict
;
return
result_dict
;
});
});
}
}
function
getOpmlTree
(
context
,
opml_url
,
opml_spec
)
{
function
getOpmlTree
(
context
,
opml_url
,
opml_spec
,
basic_login
)
{
var
opml_storage
,
var
opml_storage
,
opml_document_list
=
[],
opml_document_list
=
[],
document_attachment_dict
=
{},
delete_key_list
=
[],
delete_key_list
=
[],
current_opml_dict
=
{},
attachment_document_list
=
[],
opml_result_list
,
current_signature_dict
=
{},
fetch_remote_opml
=
false
,
id
;
id
;
id
=
generateHash
(
opml_url
);
id
=
generateHash
(
opml_url
);
opml_storage
=
createStorage
(
context
,
opml_spec
,
id
);
opml_storage
=
createStorage
(
context
,
opml_spec
,
id
);
return
getDocumentAsAttachment
(
context
,
opml_url
,
OPML_ATTACHMENT_NAME
)
.
push
(
function
(
opml_doc
)
{
var
current_time
=
new
Date
().
getTime
();
if
(
opml_doc
.
expire_time
!==
undefined
)
{
fetch_remote_opml
=
(
opml_doc
.
expire_time
-
current_time
)
<
0
;
}
else
{
fetch_remote_opml
=
true
;
}
if
(
fetch_remote_opml
)
{
return
opml_storage
.
allDocs
({
include_docs
:
true
})
return
opml_storage
.
allDocs
({
include_docs
:
true
})
.
push
(
undefined
,
function
(
error
)
{
.
push
(
undefined
,
function
(
error
)
{
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
if
((
error
instanceof
jIO
.
util
.
jIOError
)
&&
...
@@ -273,175 +361,244 @@
...
@@ -273,175 +361,244 @@
return
{
data
:
{
total_rows
:
0
}};
return
{
data
:
{
total_rows
:
0
}};
}
}
//throw error;
//throw error;
// throw will cancel all remaning tasks
console
.
error
(
error
);
return
{
data
:
{
total_rows
:
0
}};
return
{
data
:
{
total_rows
:
0
}};
})
})
.
push
(
function
(
opml_result
)
{
.
push
(
function
(
opml_result
)
{
return
RSVP
.
all
([
opml_result_list
=
opml_result
;
opml_result
,
if
(
opml_result
.
data
.
total_rows
>
0
)
{
context
.
_local_sub_storage
.
allDocs
({
attachment_document_list
.
push
({
select_list
:
[
"
signature
"
],
id
:
opml_url
,
query
:
'
(parent_id: "
'
+
id
+
'
")
'
name
:
OPML_ATTACHMENT_NAME
,
})
doc
:
{
]);
expire_time
:
new
Date
().
getTime
()
+
context
.
_remote_opml_check_time_interval
,
data
:
opml_result
}
});
return
getDocumentAsAttachment
(
context
,
id
,
opml_url
);
}
return
{};
})
})
.
push
(
function
(
result_list
)
{
.
push
(
function
(
signature_dict
)
{
var
i
;
current_signature_dict
=
signature_dict
;
for
(
i
=
0
;
i
<
result_list
[
1
].
data
.
total_rows
;
i
+=
1
)
{
});
current_opml_dict
[
result_list
[
1
].
data
.
rows
[
i
].
id
]
=
result_list
[
1
].
data
.
rows
[
i
].
value
;
}
}
return
result_list
[
0
]
;
opml_result_list
=
opml_doc
.
data
;
})
})
.
push
(
function
(
opml_result_list
)
{
.
push
(
function
()
{
var
j
,
var
i
,
i
,
item
,
item
,
signature
,
signature
,
doc_signature_dict
=
{},
skip_add
=
false
,
skip_add
=
false
,
id_hash
,
id_hash
,
result_list
=
[];
result_list
=
[],
header_dict
=
{};
if
(
opml_result_list
.
data
.
total_rows
>
0
&&
fetch_remote_opml
)
{
header_dict
=
{
dateCreated
:
opml_result_list
.
data
.
rows
[
0
].
doc
.
dateCreated
,
dateModified
:
opml_result_list
.
data
.
rows
[
0
].
doc
.
dateModified
,
opml_title
:
opml_result_list
.
data
.
rows
[
0
].
doc
.
title
};
}
for
(
i
=
0
;
i
<
opml_result_list
.
data
.
total_rows
;
i
+=
1
)
{
for
(
i
=
1
;
i
<
opml_result_list
.
data
.
total_rows
;
i
+=
1
)
{
item
=
opml_result_list
.
data
.
rows
[
i
];
item
=
opml_result_list
.
data
.
rows
[
i
];
if
(
item
.
doc
.
xmlUrl
!==
undefined
)
{
id_hash
=
generateHash
(
id
+
item
.
id
);
id_hash
=
generateHash
(
id
+
item
.
id
);
signature
=
generateHash
(
JSON
.
stringify
(
item
.
doc
));
for
(
j
=
0
;
j
<
opml_spec
.
sub_storage_list
.
length
;
j
+=
1
)
{
result_list
.
push
(
loadSubStorage
(
result_list
.
push
(
loadSubStorage
(
context
,
context
,
opml_spec
.
sub_storage_list
[
j
],
{
type
:
context
.
_remote_parser_storage_type
,
document_id
:
item
.
doc
.
xmlUrl
,
attachment_id
:
'
enclosure
'
,
parser
:
'
rss
'
,
sub_storage
:
{
type
:
"
http
"
}
},
id_hash
,
id_hash
,
item
.
doc
,
'
promise
'
opml_spec
.
basic_login
));
// Load private docs
if
(
item
.
doc
.
url
!==
undefined
)
{
result_list
.
push
(
loadSubStorage
(
context
,
{
type
:
'
webhttp
'
,
url
:
item
.
doc
.
url
.
replace
(
'
jio_private
'
,
'
private
'
),
basic_login
:
basic_login
},
id_hash
));
));
}
}
if
(
current_opml_dict
.
hasOwnProperty
(
id_hash
))
{
if
(
fetch_remote_opml
)
{
if
(
current_opml_dict
[
id_hash
].
signature
===
signature
)
{
// Append this document signature to the list
// the document was not modified, delete and skip add
signature
=
generateHash
(
JSON
.
stringify
(
item
.
doc
));
delete
current_opml_dict
[
id_hash
];
doc_signature_dict
[
id_hash
]
=
{
signature
:
signature
};
if
(
current_signature_dict
.
hasOwnProperty
(
id_hash
))
{
if
(
current_signature_dict
[
id_hash
].
signature
===
signature
)
{
// remote document was not modified, delete and skip add
delete
current_signature_dict
[
id_hash
];
skip_add
=
true
;
skip_add
=
true
;
}
}
delete
current_opml
_dict
[
id_hash
];
delete
current_signature
_dict
[
id_hash
];
}
}
Object
.
assign
(
item
.
doc
,
{
portal_type
:
"
opml-outline
"
,
parent_id
:
id
,
parent_url
:
opml_url
,
reference
:
id_hash
,
active
:
true
});
Object
.
assign
(
item
.
doc
,
header_dict
);
if
(
!
skip_add
)
{
if
(
!
skip_add
)
{
opml_document_list
.
push
({
opml_document_list
.
push
({
id
:
id_hash
,
id
:
id_hash
,
doc
:
{
type
:
"
opml-item
"
,
name
:
item
.
id
,
reference
:
id_hash
,
parent_id
:
id
,
creation_date
:
item
.
doc
.
created_date
,
url
:
opml_url
,
title
:
item
.
doc
.
title
,
parent_title
:
undefined
,
opml_title
:
item
.
doc
.
opml_title
,
status
:
undefined
,
signature
:
signature
}
});
document_attachment_dict
[
id_hash
]
=
{
name
:
item
.
id
,
doc
:
item
.
doc
doc
:
item
.
doc
}
;
})
;
}
}
}
}
}
}
if
(
fetch_remote_opml
&&
Object
.
keys
(
doc_signature_dict
).
length
>
0
)
{
attachment_document_list
.
push
({
id
:
opml_url
,
name
:
opml_url
,
doc
:
doc_signature_dict
});
delete_key_list
.
push
.
apply
(
delete_key_list
,
delete_key_list
.
push
.
apply
(
delete_key_list
,
Object
.
keys
(
current_opml_dict
));
Object
.
keys
(
current_signature_dict
));
}
return
RSVP
.
all
(
result_list
);
return
RSVP
.
all
(
result_list
);
})
})
.
push
(
function
(
result_list
)
{
.
push
(
function
(
result_list
)
{
var
i
,
var
i
,
j
;
j
,
start
,
extra_dict
,
item_signature_dict
=
{};
function
applyItemToTree
(
item
,
item_result
)
{
function
applyItemToTree
(
item
,
item_result
,
portal_type
,
extra_dict
)
{
var
id_hash
,
var
id_hash
,
element
,
element
=
item
.
doc
,
signature
;
signature
,
item_id
=
item
.
guid
||
item
.
id
,
status
=
(
element
.
status
||
element
.
category
);
id_hash
=
generateHash
(
item_result
.
parent_id
+
id_hash
=
generateHash
(
item_result
.
parent_id
+
item_result
.
url
+
item
.
id
);
item_result
.
url
+
item_id
);
if
(
item
.
doc
!==
undefined
)
{
element
=
item
.
doc
;
}
else
{
element
=
item
.
value
;
}
if
(
extra_dict
!==
undefined
)
{
Object
.
assign
(
element
,
extra_dict
);
}
// Generating document signature
// Generating document signature
signature
=
generateHash
(
JSON
.
stringify
(
element
));
signature
=
generateHash
(
JSON
.
stringify
(
element
));
item_signature_dict
[
id_hash
]
=
{
signature
:
signature
,
status
:
status
};
if
(
item_result
.
current_doc
.
hasOwnProperty
(
id_hash
))
{
if
(
item_result
.
current_signature
.
hasOwnProperty
(
id_hash
))
{
if
(
item_result
.
current_doc
[
id_hash
].
signature
===
signature
)
{
if
(
item_result
.
current_signature
[
id_hash
].
signature
// the document was not modified delete and return
===
signature
)
{
delete
item_result
.
current_doc
[
id_hash
];
// the document was not modified return
delete
item_result
.
current_signature
[
id_hash
];
return
;
return
;
}
}
// the document exists and has changed
// the document exists and has changed
delete
item_result
.
current_
doc
[
id_hash
];
delete
item_result
.
current_
signature
[
id_hash
];
}
}
opml_document_list
.
push
({
Object
.
assign
(
element
,
{
id
:
id_hash
,
doc
:
{
parent_id
:
item_result
.
parent_id
,
parent_id
:
item_result
.
parent_id
,
name
:
item
.
id
,
portal_type
:
portal_type
||
element
.
type
||
item_result
.
type
,
type
:
(
element
.
type
||
item_result
.
type
+
"
-item
"
)
,
status
:
status
,
reference
:
id_hash
,
reference
:
id_hash
,
creation_date
:
element
.
date
||
element
[
"
start-date
"
],
active
:
true
url
:
item_result
.
url
,
status
:
(
element
.
status
||
element
.
category
),
title
:
(
element
.
source
||
element
.
title
),
parent_title
:
item_result
.
parent_title
,
opml_title
:
item_result
.
opml_title
,
signature
:
signature
}
});
});
document_attachment_dict
[
id_hash
]
=
{
opml_document_list
.
push
(
{
name
:
item
.
id
,
id
:
id_hash
,
doc
:
element
doc
:
element
};
}
)
;
}
}
for
(
i
=
0
;
i
<
result_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
result_list
.
length
;
i
+=
1
)
{
for
(
j
=
0
;
j
<
result_list
[
i
].
result
.
data
.
total_rows
;
j
+=
1
)
{
extra_dict
=
undefined
;
start
=
0
;
if
(
result_list
[
i
].
result
.
data
.
total_rows
>
0
)
{
if
(
result_list
[
i
].
type
===
"
promise
"
)
{
// the first element of rss is the header
extra_dict
=
{
lastBuildDate
:
result_list
[
i
].
result
.
data
.
rows
[
0
].
doc
.
lastBuildDate
,
channel
:
result_list
[
i
].
result
.
data
.
rows
[
0
].
doc
.
description
,
channel_item
:
result_list
[
i
].
result
.
data
.
rows
[
0
].
doc
.
title
};
applyItemToTree
(
result_list
[
i
].
result
.
data
.
rows
[
0
],
result_list
[
i
],
"
rss
"
);
start
=
1
;
}
for
(
j
=
start
;
j
<
result_list
[
i
].
result
.
data
.
total_rows
;
j
+=
1
)
{
applyItemToTree
(
applyItemToTree
(
result_list
[
i
].
result
.
data
.
rows
[
j
],
result_list
[
i
].
result
.
data
.
rows
[
j
],
result_list
[
i
]
result_list
[
i
],
undefined
,
extra_dict
);
);
}
}
delete_key_list
.
push
.
apply
(
delete_key_list
,
attachment_document_list
.
push
({
Object
.
keys
(
result_list
[
i
].
current_doc
));
id
:
result_list
[
i
].
parent_id
,
name
:
result_list
[
i
].
url
,
doc
:
item_signature_dict
});
item_signature_dict
=
{};
delete_key_list
.
push
.
apply
(
delete_key_list
,
Object
.
keys
(
result_list
[
i
].
current_signature
)
);
}
else
if
(
Object
.
keys
(
result_list
[
i
].
current_signature
).
length
>
0
)
{
// if the remote data is empty and current_signature is not empty,
// push to storage in case the status was changed
// this help for speed optimisation
attachment_document_list
.
push
({
id
:
result_list
[
i
].
parent_id
,
name
:
result_list
[
i
].
url
,
doc
:
result_list
[
i
].
current_signature
});
}
}
}
return
[
opml_document_list
,
d
ocument_attachment_dict
,
delete_key
_list
];
return
[
opml_document_list
,
d
elete_key_list
,
attachment_document
_list
];
});
});
}
}
function
pushDocumentToStorage
(
context
,
document_list
,
attachment_dic
t
,
function
pushDocumentToStorage
(
context
,
document_list
,
delete_key_lis
t
,
delete_key
_list
)
{
attachment_document
_list
)
{
var
document_queue
=
new
RSVP
.
Queue
(),
var
document_queue
=
new
RSVP
.
Queue
(),
i
;
i
;
function
pushDocument
(
id
,
element
,
attachment
)
{
function
pushDocument
(
id
,
element
)
{
document_queue
document_queue
.
push
(
function
()
{
.
push
(
function
()
{
return
context
.
_local_sub_storage
.
put
(
id
,
element
);
return
context
.
_local_sub_storage
.
put
(
id
,
element
);
})
.
push
(
function
()
{
return
context
.
_local_sub_storage
.
putAttachment
(
id
,
attachment
.
name
,
new
Blob
([
JSON
.
stringify
(
attachment
.
doc
)])
);
});
});
}
}
for
(
i
=
0
;
i
<
document_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
document_list
.
length
;
i
+=
1
)
{
pushDocument
(
pushDocument
(
document_list
[
i
].
id
,
document_list
[
i
].
id
,
document_list
[
i
].
doc
,
document_list
[
i
].
doc
attachment_dict
[
document_list
[
i
].
id
]
);
);
}
}
return
document_queue
return
document_queue
...
@@ -452,18 +609,6 @@
...
@@ -452,18 +609,6 @@
// remove all document which were not updated
// remove all document which were not updated
function
removeDocument
(
key
)
{
function
removeDocument
(
key
)
{
remove_queue
remove_queue
.
push
(
function
()
{
return
context
.
_local_sub_storage
.
get
(
key
);
})
.
push
(
undefined
,
function
(
error
)
{
throw
error
;
})
.
push
(
function
(
element
)
{
return
context
.
_local_sub_storage
.
removeAttachment
(
key
,
element
.
name
);
})
.
push
(
function
()
{
.
push
(
function
()
{
return
context
.
_local_sub_storage
.
remove
(
key
);
return
context
.
_local_sub_storage
.
remove
(
key
);
})
})
...
@@ -480,17 +625,60 @@
...
@@ -480,17 +625,60 @@
removeDocument
(
delete_key_list
[
k
]);
removeDocument
(
delete_key_list
[
k
]);
}
}
return
remove_queue
;
return
remove_queue
;
})
.
push
(
function
()
{
var
j
,
signature_queue
=
new
RSVP
.
Queue
();
function
pushAttachment
(
id
,
name
,
element
)
{
signature_queue
.
push
(
function
()
{
return
context
.
_local_sub_storage
.
putAttachment
(
id
,
name
,
new
Blob
([
JSON
.
stringify
(
element
)],
{
type
:
'
application/json
'
})
);
})
.
push
(
undefined
,
function
(
error
)
{
console
.
error
(
error
);
});
}
for
(
j
=
0
;
j
<
attachment_document_list
.
length
;
j
+=
1
)
{
pushAttachment
(
attachment_document_list
[
j
].
id
,
attachment_document_list
[
j
].
name
,
attachment_document_list
[
j
].
doc
);
}
});
});
}
}
function
syncOpmlStorage
(
context
)
{
function
syncOpmlStorage
(
context
)
{
return
context
.
_local_sub_storage
.
allDocs
({
query
:
'
(portal_type:"opml") AND (active:true)
'
,
select_list
:
[
"
url
"
,
"
basic_login
"
]
})
.
push
(
function
(
storage_result
)
{
var
i
,
var
i
,
opml_queue
=
new
RSVP
.
Queue
();
opml_queue
=
new
RSVP
.
Queue
();
function
syncFullOpml
(
url
,
storage_spec
)
{
function
syncFullOpml
(
storage_spec
)
{
return
opml_queue
opml_queue
.
push
(
function
()
{
.
push
(
function
()
{
return
getOpmlTree
(
context
,
url
,
storage_spec
);
return
getOpmlTree
(
context
,
storage_spec
.
url
,
{
type
:
context
.
_remote_parser_storage_type
,
document_id
:
storage_spec
.
url
,
attachment_id
:
'
enclosure
'
,
parser
:
'
opml
'
,
sub_storage
:
{
type
:
"
http
"
}
},
storage_spec
.
basic_login
);
})
})
.
push
(
function
(
result_list
)
{
.
push
(
function
(
result_list
)
{
return
pushDocumentToStorage
(
return
pushDocumentToStorage
(
...
@@ -501,11 +689,15 @@
...
@@ -501,11 +689,15 @@
);
);
});
});
}
}
for
(
i
=
0
;
i
<
context
.
_opml_storage_list
.
length
;
i
+=
1
)
{
for
(
i
=
0
;
i
<
storage_result
.
data
.
total_rows
;
i
+=
1
)
{
syncFullOpml
(
context
.
_opml_storage_list
[
i
].
url
,
syncFullOpml
({
context
.
_opml_storage_list
[
i
]);
type
:
storage_result
.
data
.
rows
[
i
].
value
.
type
,
url
:
storage_result
.
data
.
rows
[
i
].
value
.
url
,
basic_login
:
storage_result
.
data
.
rows
[
i
].
value
.
basic_login
});
}
}
return
opml_queue
;
return
opml_queue
;
});
}
}
ReplicatedOPMLStorage
.
prototype
.
repair
=
function
()
{
ReplicatedOPMLStorage
.
prototype
.
repair
=
function
()
{
...
...
src/jio.storage/webhttpstorage.js
View file @
39feb6e5
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
throw
new
jIO
.
util
.
jIOError
(
"
id
"
+
id
+
"
is forbidden (no begin /)
"
,
throw
new
jIO
.
util
.
jIOError
(
"
id
"
+
id
+
"
is forbidden (no begin /)
"
,
400
);
400
);
}
}
if
(
id
.
lastIndexOf
(
"
/
"
)
!
==
(
id
.
length
-
1
))
{
if
(
id
.
lastIndexOf
(
"
/
"
)
=
==
(
id
.
length
-
1
))
{
throw
new
jIO
.
util
.
jIOError
(
"
id
"
+
id
+
"
is forbidden (no end /)
"
,
throw
new
jIO
.
util
.
jIOError
(
"
id
"
+
id
+
"
is forbidden (no end /)
"
,
400
);
400
);
}
}
...
@@ -84,14 +84,19 @@
...
@@ -84,14 +84,19 @@
}
}
WEBHTTPStorage
.
prototype
.
get
=
function
(
id
)
{
WEBHTTPStorage
.
prototype
.
get
=
function
(
id
)
{
var
context
=
this
,
var
context
=
this
;
element
;
id
=
restrictDocumentId
(
id
);
id
=
restrictDocumentId
(
id
);
element
=
getJsonDocument
(
context
,
id
);
return
getJsonDocument
(
context
,
id
)
if
(
element
!==
undefined
)
{
.
push
(
function
(
element
)
{
return
element
.
doc
;
return
element
.
doc
;
},
function
(
error
)
{
if
((
error
.
target
!==
undefined
)
&&
(
error
.
target
.
status
===
404
))
{
throw
new
jIO
.
util
.
jIOError
(
"
Cannot find document
"
,
404
);
}
}
throw
error
;
});
};
};
WEBHTTPStorage
.
prototype
.
hasCapacity
=
function
(
capacity
)
{
WEBHTTPStorage
.
prototype
.
hasCapacity
=
function
(
capacity
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment