mirror of
https://github.com/ChronosX88/psyced.git
synced 2024-11-08 19:41:00 +00:00
twitter newsfeed daemon
This commit is contained in:
parent
a32a31794e
commit
217f34fd42
17
CHANGESTODO
17
CHANGESTODO
@ -35,6 +35,23 @@ ________________________________________________________________________
|
||||
im psyc://psyced.org/~lynx Context festgestellt.
|
||||
|
||||
? who's gonna clean up the mess of having too many websites ?
|
||||
|
||||
- when provided with a _focus pointing to yourself, _request_execute will
|
||||
still try to forward a command to the "current place" - a uniform or
|
||||
object is passed to parsecmd(data, dest) but dest is ignored later in cmd()
|
||||
|
||||
- _source_relay should point to tg, not foo (only happens with local users)
|
||||
.
|
||||
:_source.psyc://x-net.hu/~foo
|
||||
:_target.psyc://3e44aa49.XXX:-52801/
|
||||
:_source_relay.psyc://x-net.hu/~foo
|
||||
|
||||
:_nick.tg
|
||||
:_time_INTERNAL.1239787956
|
||||
:_nick_target.psyc://x-net.hu/~foo
|
||||
_message_private
|
||||
halo
|
||||
.
|
||||
________________________________________________________________________
|
||||
== psyced 1.0 ==========================================================
|
||||
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|
||||
|
@ -696,6 +696,9 @@ _message_public
|
||||
_message_friends
|
||||
|[_nick] {_TEXT_action_shouts}: [_data]
|
||||
|
||||
_message_twitter
|
||||
|[_nick] ... [_data]
|
||||
|
||||
_message_echo_private
|
||||
|You tell [_nick_target]: [_data]
|
||||
|
||||
|
@ -95,6 +95,7 @@
|
||||
// nosave? static? volatile. only for variables, not methods!
|
||||
// another nice word for the opposite of persistent would be "shed"
|
||||
#define volatile nosave
|
||||
#define persistent
|
||||
|
||||
// every lpc dialect has its own foreach syntax. aint that cute?
|
||||
#define each(ITERATOR, LIST) foreach(ITERATOR : LIST)
|
||||
|
@ -372,6 +372,8 @@ object compile_object(string file) {
|
||||
// match both http:/ and https:/ objects ;D
|
||||
if (abbrev("http", file)) {
|
||||
rob = clone_object(HTTP_PATH "fetch");
|
||||
// driver has the habit of removing double slash in object name
|
||||
file = replace(file, ":/", "://");
|
||||
if (rob) rob->fetch(file[..<3]);
|
||||
return rob;
|
||||
}
|
||||
|
@ -83,6 +83,7 @@
|
||||
|
||||
// nosave? static? volatile. no idea if pike has something like this
|
||||
#define volatile static
|
||||
#define persistent
|
||||
|
||||
// every lpc dialect has its own foreach syntax. aint that cute?
|
||||
#define each(ITEM, LIST) foreach(LIST; ; ITEM)
|
||||
|
@ -2,8 +2,8 @@
|
||||
//
|
||||
// generic HTTP GET client, mostly used for RSS -
|
||||
// but we could fetch any page or data with it, really
|
||||
// tobij even made the object have the URL as its object name. fancy! ;)
|
||||
//
|
||||
// tobij even allowed the object to have the URL as its object name. fancy! ;)
|
||||
|
||||
#include <ht/http.h>
|
||||
#include <net.h>
|
||||
#include <uniform.h>
|
||||
@ -24,7 +24,7 @@ volatile string modificationtime, etag, http_message;
|
||||
volatile string useragent = SERVER_VERSION;
|
||||
volatile int http_status, port, fetching, ssl;
|
||||
volatile string buffer, thehost, url, fetched, host, resource;
|
||||
volatile string basicauth;
|
||||
volatile string basicauth = "";
|
||||
|
||||
int parse_status(string all);
|
||||
int parse_header(string all);
|
||||
@ -33,22 +33,23 @@ int buffer_content(string all);
|
||||
string qHost() { return thehost; }
|
||||
|
||||
void fetch(string murl) {
|
||||
if (url) return;
|
||||
url = replace(murl, ":/", "://");
|
||||
P3(("%O: fetch(%O)\n", ME, url))
|
||||
connect();
|
||||
if (url) return;
|
||||
// accept.c does this for us:
|
||||
//url = replace(murl, ":/", "://");
|
||||
// so we can use this method also in a normal way
|
||||
url = murl;
|
||||
P3(("%O: fetch(%O)\n", ME, url))
|
||||
connect();
|
||||
}
|
||||
|
||||
object load() { return ME; }
|
||||
|
||||
void setHTTPBasicAuth(string user, string password) {
|
||||
basicauth = "Authorization: Basic " + encode_base64(user + ":" + password) + "\r\n";
|
||||
void sAuth(string user, string password) {
|
||||
basicauth = "Authorization: Basic "+
|
||||
encode_base64(user +":"+ password) +"\r\n";
|
||||
}
|
||||
|
||||
string sAgent(string a) {
|
||||
PT(("sAgent(%O) in %O\n", a, ME))
|
||||
return useragent = a;
|
||||
}
|
||||
string sAgent(string a) { return useragent = a; }
|
||||
|
||||
// net/place/news code follows.
|
||||
|
||||
@ -65,7 +66,7 @@ void connect() {
|
||||
thehost = lower_case(thehost);
|
||||
ssl = t == "s";
|
||||
}
|
||||
P3(("URL, THEHOST: %O, %O\n", url, thehost))
|
||||
PT(("URL, THEHOST: %O, %O\n", url, thehost))
|
||||
unless (port)
|
||||
unless (sscanf(thehost, "%s:%d", thehost, port) == 2)
|
||||
port = ssl? HTTPS_SERVICE: HTTP_SERVICE;
|
||||
@ -84,7 +85,7 @@ varargs int real_logon(int arg) {
|
||||
unless (url) return -3;
|
||||
unless (resource) sscanf(url, "%s://%s/%s", scheme, host, resource);
|
||||
|
||||
buffer = "";
|
||||
buffer = basicauth;
|
||||
if (modificationtime)
|
||||
buffer += "If-Modified-Since: "+ modificationtime + "\r\n";
|
||||
if (useragent) buffer += "User-Agent: "+ useragent +"\r\n";
|
||||
@ -93,7 +94,7 @@ varargs int real_logon(int arg) {
|
||||
// we won't need connection: close w/ http/1.0
|
||||
//emit("Connection: close\r\n\r\n");
|
||||
PT(("%O using %O\n", ME, buffer))
|
||||
emit("GET /"+ resource +" HTTP/1.0\r\n"
|
||||
emit("GET /"+ resource +" HTTP/1.1\r\n"
|
||||
"Host: "+ host +"\r\n"
|
||||
+ buffer +
|
||||
"\r\n");
|
||||
|
@ -367,6 +367,7 @@ mapping jsonObject()
|
||||
}
|
||||
|
||||
if (nextClean() != ':') {
|
||||
PT(("jsonFAIL: '%c' at %O\n", nextClean(), myIndex))
|
||||
THROW("Expected a ':' after a key.\n");
|
||||
}
|
||||
|
||||
|
@ -1315,6 +1315,7 @@ case "_message_echo_private":
|
||||
// fall thru
|
||||
case "_message_echo_public":
|
||||
case "_message_echo":
|
||||
case "_message_twitter":
|
||||
case "_message_public":
|
||||
// avoid treating this as _message here
|
||||
break;
|
||||
@ -1323,6 +1324,9 @@ case "_message_audio":
|
||||
// not being displayed to users other than psyc clients
|
||||
data = 0;
|
||||
break;
|
||||
// we should judge our messages by their routing method, not by their
|
||||
// name! thus, the _public and _private distinction has to exist only
|
||||
// for display. FIXME
|
||||
case "_message":
|
||||
// this is only visible in person.c, not user.c
|
||||
// therefore probably useless
|
||||
|
@ -1354,6 +1354,7 @@ msg(source, mc, data, mapping vars) {
|
||||
else unless (!source
|
||||
|| qAllowExternal(&source, mc, vars) // mayExternal hook
|
||||
|| MEMBER(source)
|
||||
|| source == "/" // allow root to send everywhere
|
||||
|| isValidRelay(source)
|
||||
|| isValidRelay(vars["_source_relay"])
|
||||
|| isValidRelay(vars["_context"])) {
|
||||
|
106
world/net/twitter/polly.c
Normal file
106
world/net/twitter/polly.c
Normal file
@ -0,0 +1,106 @@
|
||||
// vim:foldmethod=marker:syntax=lpc:noexpandtab
|
||||
//
|
||||
// yeah yeah twitter.. why twitter?
|
||||
// http://about.psyc.eu/Twitter
|
||||
|
||||
#include <net.h>
|
||||
|
||||
persistent int lastid;
|
||||
|
||||
volatile object feed;
|
||||
|
||||
parse(string body) {
|
||||
mixed wurst;
|
||||
string nick;
|
||||
object o;
|
||||
mapping d, p;
|
||||
int i;
|
||||
|
||||
//body = read_file("/net/twitter/many.json");
|
||||
if (!body || body == "") {
|
||||
P1(("%O failed to get its timeline.\n", ME))
|
||||
return;
|
||||
}
|
||||
//#if DEBUG > 0
|
||||
rm(DATA_PATH "timeline.json");
|
||||
write_file(DATA_PATH "timeline.json", body);
|
||||
P4((body))
|
||||
//#endif
|
||||
unless (pointerp(wurst = parse_json(body))) {
|
||||
P1(("%O failed to parse its timeline.\n", ME))
|
||||
return;
|
||||
}
|
||||
i=sizeof(wurst)-1;
|
||||
if (wurst[i]["id"] <= lastid) {
|
||||
P1(("%O received old stuff.\n", ME))
|
||||
return;
|
||||
}
|
||||
lastid = wurst[i]["id"];
|
||||
save_object(DATA_PATH "twitter");
|
||||
for (; i>=0; i--) {
|
||||
d = wurst[i];
|
||||
unless (mappingp(d)) {
|
||||
P1(("%O got a broken tweet: %O.\n", ME, d))
|
||||
continue;
|
||||
}
|
||||
p = d["user"];
|
||||
unless (mappingp(p)) {
|
||||
P1(("%O got a userless tweet.\n", ME))
|
||||
continue;
|
||||
}
|
||||
unless (nick = p["screen_name"]) {
|
||||
P1(("%O got a nickless tweeter.\n", ME))
|
||||
continue;
|
||||
}
|
||||
PT((" %O", nick))
|
||||
o = find_place(nick);
|
||||
|
||||
// _notice_update_twitter ?
|
||||
sendmsg(o, "_message_twitter", d["text"], ([
|
||||
// should i send text as _action?
|
||||
"_nick": nick,
|
||||
// _count seems to be the better word for this
|
||||
"_amount_followers": p["followers_count"],
|
||||
"_color": "#"+ p["profile_text_color"],
|
||||
"_description": p["description"],
|
||||
"_uniform_photo": p["profile_image_url"],
|
||||
"_page": p["url"],
|
||||
"_name": p["name"],
|
||||
// "_contact_twitter": p["id"],
|
||||
"_description_agent_HTML": d["source"],
|
||||
"_reference_reply": d["in_reply_to_screen_name"],
|
||||
// "_twit": d["id"],
|
||||
]), "/"); // send as root
|
||||
|
||||
// der spiegel u.a. twittern übrigens in latin-1
|
||||
// während psyc utf-8 erwartet.. eine char guess engine
|
||||
// muss her.. FIXME
|
||||
}
|
||||
}
|
||||
|
||||
fetch() {
|
||||
feed -> content( #'parse, 0, 1 );
|
||||
feed -> fetch("http://twitter.com/statuses/friends_timeline.json"
|
||||
"?since_id="+ lastid +"&count=123");
|
||||
call_out( #'fetch, 9 * 60 );
|
||||
}
|
||||
|
||||
create() {
|
||||
mapping config;
|
||||
object o = find_object(CONFIG_PATH "config");
|
||||
|
||||
if (o) config = o->qConfig();
|
||||
if (!config) {
|
||||
P1(("No configuration for twitter gateway found.\n");
|
||||
destruct(ME);
|
||||
return;
|
||||
}
|
||||
restore_object(DATA_PATH "twitter");
|
||||
|
||||
// we could even choose to inherit this instead...
|
||||
feed = clone_object(HTTP_PATH "fetch");
|
||||
//feed -> sAgent(SERVER_VERSION " builtin Twitter to PSYC gateway");
|
||||
feed -> sAuth(config["nickname"], config["password"]);
|
||||
call_out( #'fetch, 14 );
|
||||
}
|
||||
|
@ -753,6 +753,7 @@ case "_message_announcement":
|
||||
case "_message_behaviour_warning":
|
||||
case "_message_behaviour_punishment":
|
||||
case "_message_behaviour":
|
||||
case "_message_twitter":
|
||||
unless (stringp(data)) variant = "_default";
|
||||
else variant = "";
|
||||
#ifdef USE_THE_NICK
|
||||
|
Loading…
Reference in New Issue
Block a user