diff --git a/CHANGESTODO b/CHANGESTODO
index 090d13f..3300ab8 100644
--- a/CHANGESTODO
+++ b/CHANGESTODO
@@ -52,6 +52,10 @@ ________________________________________________________________________
_message_private
halo
.
+
+- the linking blues...
+ tgX sagt: on reconnect i didn't get any _echo_place_enter_login's from this room, then no response for _request_do_enter, and after a _request_do_leave i get replies for enter/leave but instead of _echo_place_enter/leave i get _notice_place_enter/leave
+
________________________________________________________________________
== psyced 1.0 ==========================================================
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
diff --git a/world/default/en/html.textdb b/world/default/en/html.textdb
index 33b8540..91c5c51 100644
--- a/world/default/en/html.textdb
+++ b/world/default/en/html.textdb
@@ -1423,6 +1423,24 @@ _HTML_examine_friend_new
_HTML_examine_button_call
| {_TEXT_button_call}
+_HTML_listing_head_twitter
+|
twitter polly listing of available feeds
+|
+|
+|
+
+_HTML_listing_item_twitter
+|
+|
+|## [_nick]
+|[_name]
+|[_description]
+|[_uniform_context]
+|
+
_HTML_call
|
|
diff --git a/world/net/place/archetype.gen b/world/net/place/archetype.gen
index d5c2b53..d2be82b 100644
--- a/world/net/place/archetype.gen
+++ b/world/net/place/archetype.gen
@@ -1790,6 +1790,7 @@ cmd(a, args, b, source, vars) {
return 1;
# endif
case "hc":
+ case "histclean": // in case you don't remember exactly.. it's ok
case "histclear": // wieso um alles in der welt soll das jeder dürfen?
// liest denn keiner die cvs kommentare? da stands
// drin.. ok wir sind realistisch und schreiben es
diff --git a/world/net/twitter/listing.c b/world/net/twitter/listing.c
new file mode 100644
index 0000000..af90246
--- /dev/null
+++ b/world/net/twitter/listing.c
@@ -0,0 +1,126 @@
+// vim:foldmethod=marker:syntax=lpc:noexpandtab
+//
+// http://localhost:33333/net/twitter/listing shows a list of friends
+
+#include
+#include
+#include
+
+volatile object fetcha;
+volatile mixed wurst;
+
+parse(string body) {
+ if (!body || body == "") {
+ P1(("%O failed to get its listing.\n", ME))
+ return;
+ }
+//#if DEBUG > 0
+ rm(DATA_PATH "twitter/friends.json");
+ write_file(DATA_PATH "twitter/friends.json", body);
+ P4((body))
+//#endif
+ unless (pointerp(wurst = parse_json(body))) {
+ P1(("%O failed to parse its listing.\n", ME))
+ return;
+ }
+#ifdef DEVELOPMENT
+ write_file(DATA_PATH "twitter/friends.parsed", sprintf("%O\n", wurst));
+#endif
+ P1(("%O sorting %O subscription names ", ME, sizeof(wurst)))
+ wurst = sort_array(wurst, (:
+ unless (mappingp($1)) return 0;
+ unless (mappingp($2)) return 1;
+// PT(("%O got %O vs %O\n", ME, $1, $2))
+ P1(("."))
+ return lower_case($2["screen_name"] || "") >
+ lower_case($1["screen_name"] || "");
+ :) );
+ P1((" done!\n"))
+}
+
+htget(prot, query, headers, qs, data, noprocess) {
+ string nick;
+ mapping d; //, s;
+ int i;
+
+ //sTextPath(query["layout"] || "twitter", query["lang"], "html");
+ localize(query["lang"], "html");
+
+ unless (pointerp(wurst)) {
+ hterror(R_TEMPOVERL,
+ "Haven't successfully retrieved data yet.");
+ return;
+ }
+ htok(prot); // outputs utf-8 header, but..
+ w("_HTML_listing_head_twitter");
+ for (i=sizeof(wurst)-1; i>=0; i--) {
+ d = wurst[i];
+ unless (mappingp(d)) {
+ P1(("%O got a broken entry: %O.\n", ME, d))
+ continue;
+ }
+//
+// user "foebud" has no updates ;)
+//
+// s = d["status"];
+// unless (mappingp(s)) {
+// P1(("%O got a statusless entry: %O.\n", ME, d))
+// continue;
+// }
+ unless (nick = d["screen_name"]) {
+ P1(("%O got a nickless tweeter.\n", ME))
+ continue;
+ }
+ w("_HTML_listing_item_twitter", 0, ([
+ // should i send text as _action?
+ "_nick": nick,
+ "_amount_updates": d["statuses_count"],
+ // _count_subscribers seems to be better for this
+ // or should it be _recipients? _targets?
+ "_amount_followers": d["followers_count"],
+ "_amount_sources": d["friends_count"],
+ // shows how old listing is.. hmm
+ //"_description_update": s["text"] || "",
+ "_color": "#"+ d["profile_sidebar_fill_color"],
+ "_description": d["description"] || "",
+ "_uniform_context": SERVER_UNIFORM +"@"+ nick,
+ "_page": d["url"] || "",
+ "_name": d["name"] || "",
+ // "_contact_twitter": d["id"],
+ "_reference_reply": d["in_reply_to_screen_name"],
+ // "_twit": d["id"],
+ "_uniform_photo": d["profile_image_url"] || "",
+ "_uniform_photo_background":
+ d["profile_background_image_url"] || ""
+ ]));
+ }
+ w("_HTML_listing_tail_twitter");
+ return 1;
+}
+
+fetch() {
+ fetcha -> content( #'parse, 0, 1 );
+ fetcha -> fetch("http://twitter.com/statuses/friends.json?count=200");
+}
+
+create() {
+ mapping config;
+ object o = find_object(CONFIG_PATH "config");
+
+ if (o) config = o->qConfig();
+ if (!config) {
+ P1(("\nNo configuration for twitter gateway found in %O.\n", o))
+ //destruct(ME);
+ return 1;
+ }
+
+ string body = read_file(DATA_PATH "twitter/friends.json");
+ if (body) return parse(body);
+
+ // we could even choose to inherit this instead...
+ fetcha = clone_object(NET_PATH "http/fetch");
+ //fetcha -> sAgent(SERVER_VERSION " builtin Twitter to PSYC gateway");
+ fetcha -> sAuth(config["nickname"], config["password"]);
+ call_out( #'fetch, 14 );
+}
+
diff --git a/world/net/twitter/polly.c b/world/net/twitter/polly.c
index f8acbcd..722cccb 100644
--- a/world/net/twitter/polly.c
+++ b/world/net/twitter/polly.c
@@ -86,7 +86,7 @@ parse(string body, mapping headers) {
fetch() {
feed -> content( #'parse, 0, 1 );
feed -> fetch("http://twitter.com/statuses/friends_timeline.json"
- "?count="+( lastid? ("44&since_id="+ lastid) : "44"));
+ "?count="+( lastid? ("11&since_id="+ lastid) : "11"));
call_out( #'fetch, 6 * 59 ); // odd is better
}
diff --git a/world/static/twitter/listing.css b/world/static/twitter/listing.css
new file mode 100644
index 0000000..6c2dc84
--- /dev/null
+++ b/world/static/twitter/listing.css
@@ -0,0 +1,31 @@
+* {
+ margin:0;padding:0;border-width:0;border-color:transparent;
+}
+a {
+ text-decoration:none;
+ color:#06a;
+}
+a:hover {
+ text-decoration:overline;
+}
+body{
+ font-family: 'Lucida Grande',helvetica,sans-serif;
+ color:#333;
+ background-color:#cc6;
+ margin:44px;
+}
+.listing {
+ background-color:#ddd;
+ border-left: 2px solid black;
+ border-right: 2px solid black;
+}
+
+.listing li:first-child{ border-top:1px dashed black; }
+.listing li{position:relative;padding:7;border-bottom:1px dashed black;line-height:1.1em;}
+.listing li:hover,ol.listing li.hover{background-color:white;}
+
+._photo{display:block;width:50px;height:50px;position:absolute;right:7;margin:0 0 0 0;}
+._photo img{width:48px;height:48px;}
+._description{font-size:70%;}
+._uniform{font-size:80%;}
+._uniform a{color:#c30}