From 4d1f8e4edabd1fc40fc2cc908009df43b5a1a6ab Mon Sep 17 00:00:00 2001 From: "psyc://psyced.org/~lynX" <@> Date: Mon, 20 Apr 2009 09:52:06 +0200 Subject: [PATCH] twitter subscription listing --- CHANGESTODO | 4 + world/default/en/html.textdb | 18 +++++ world/net/place/archetype.gen | 1 + world/net/twitter/listing.c | 126 +++++++++++++++++++++++++++++++ world/net/twitter/polly.c | 2 +- world/static/twitter/listing.css | 31 ++++++++ 6 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 world/net/twitter/listing.c create mode 100644 world/static/twitter/listing.css 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_tail_twitter +|
+ +_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}