Hi,

Here is the log of the chatroom at http://farsides.com/chat/ (or 
irc://irc.freenode.net/#farsides) for the 2011-06-25.


2011-06-25 00:05:38+0000 antoviaque (antoviaque) is now online
2011-06-25 02:46:34+0000 antoviaque (antoviaque) is now online
2011-06-25 05:55:42+0000 <dachary> antoviaque: blanchard : unless you object, I 
would like to change the topic of my work on sunday. I originaly planned to 
attempt a first CSS/HTML integration of the new mockups. I think working on 
#179 + #180 is a better use of my time. Because the mockups are still being 
actively discussed at http://tickets.farsides.com/issues/94 it is a good idea 
to delay the implementation until things are clarified.
2011-06-25 07:00:08+0000 dachary (dachary) is now online
2011-06-25 08:57:01+0000 arbrandes (arbrandes) is now online
2011-06-25 09:01:32+0000 dachary (dachary) is now online
2011-06-25 09:05:17+0000 <dachary> arbrandes: hi
2011-06-25 09:05:36+0000 <arbrandes> Good morning, people on the far side of 
the world
2011-06-25 09:05:38+0000 <arbrandes> hey dachary!
2011-06-25 09:06:14+0000 <arbrandes> Are you guys familiar with Gary Larson's 
"The Far Side?"  http://28.media.tumblr.com/tumblr_liqbnfrQVN1qhk2m2o1_500.jpg
2011-06-25 09:06:25+0000 <dachary> I've been thinking about the best way of 
changing cardstories to support displaying the list of connected players during 
the past 3 hours.
2011-06-25 09:06:32+0000 <blanchard> hi arbrandes
2011-06-25 09:07:02+0000 <dachary> It's not trivial because at the moment 
cardstories only notifies the client when the game state change or the list of 
games changes. 
2011-06-25 09:07:02+0000 <arbrandes> hey blanchard
2011-06-25 09:07:07+0000 <blanchard> of course ! Larson's comics is the true 
root of the studio ;)
2011-06-25 09:07:10+0000 <dachary> blanchard: hi
2011-06-25 09:07:18+0000 <arbrandes> blanchard, ahhhh, cool
2011-06-25 09:09:29+0000 <dachary> the server currently has only two GET 
methods to retrieve information : GET the list of games for a given player, GET 
the state of a game for a given player
2011-06-25 09:14:46+0000 <dachary> it makes a simple protocol
2011-06-25 09:15:13+0000 <dachary> where you get all the relevant information 
at once
2011-06-25 09:15:23+0000 <dachary> it is not fine grained
2011-06-25 09:17:23+0000 <dachary> but the information is small enough 
2011-06-25 09:18:39+0000 <dachary> transmitting only the changed information 
would create a more complex protocol for a gain that is uncertain
2011-06-25 09:24:26+0000 <dachary> At present GET (game or lobby) returns a 
hash map with the required information. 
2011-06-25 09:24:34+0000 <dachary> it says nothing  about the game as a whole
2011-06-25 09:27:16+0000 <dachary> I'm thinking about changing it to return an 
array where the first element is general information about the server (list of 
connected players, chat lines etc.)
2011-06-25 09:34:43+0000 <dachary> and the second is the required information
2011-06-25 09:37:38+0000 tempuramerino (tempuramerino) is now online
2011-06-25 09:55:39+0000 tempuramerino (tempuramerino) is now online
2011-06-25 10:01:22+0000 tempuramerino (tempuramerino) is now online
2011-06-25 10:03:37+0000 dachary (dachary) is now online
2011-06-25 10:08:10+0000 <arbrandes> dachary, correct me if I'm wrong, please.  
The plugin system is essentially a filter for the requests: is filters/modifies 
requests before it gets to the main service, and filters/modifies the response 
before it gets to the client.
2011-06-25 10:08:19+0000 <arbrandes> *it filters
2011-06-25 10:10:28+0000 <dachary> arbrandes: it is a filter, yes. It can 
modify the incoming request (function preprocess)
2011-06-25 10:10:51+0000 <dachary> it can also modify the result before it is 
returned back to the client (function postprocess)
2011-06-25 10:11:26+0000 <arbrandes> dachary, ok, thanks, just a reality check. 
 I'm currently figuring out where django's sessionid cookie will fit in.
2011-06-25 10:11:41+0000 <arbrandes> On the client side, player_id is always 
the email, right?  At least, currently.
2011-06-25 10:12:16+0000 <dachary> in addition to being a filter, it can also 
listen to game events, independently of incoming HTTP requests
2011-06-25 10:13:08+0000 <dachary> currently, yes
2011-06-25 10:14:27+0000 <dachary> in the django context I assume it will be 
the django user name (client side) 
2011-06-25 10:14:29+0000 <arbrandes> So one alternative would be to have 
player_id be django's sessionid, and have the auth plugin "translate" it.
2011-06-25 10:14:58+0000 <dachary> the django sessionid is already in the 
django cookie right ? 
2011-06-25 10:15:13+0000 <arbrandes> dachary, yes, the cookie is actually 
called "sessionid"
2011-06-25 10:15:18+0000 <dachary> good
2011-06-25 10:15:36+0000 <dachary> then player_id do not need to carry the 
session hash, it's already available in the cookie
2011-06-25 10:15:55+0000 <dachary> player_id can be (and should be from the 
client point of view) a user readable name for the player
2011-06-25 10:16:29+0000 <dachary> the authentication will be done using the 
hash found in the sessionid 
2011-06-25 10:17:27+0000 <dachary> here is the logic I have in minde:
2011-06-25 10:17:32+0000 <dachary> s/minde/mind/
2011-06-25 10:17:32+0000 <arbrandes> Ok, so I'm assuming you mean I'll pass in 
an additional query in the GET
2011-06-25 10:17:43+0000 <arbrandes> ?sessionid=xxxxx
2011-06-25 10:19:26+0000 <dachary> arbrandes: the cardstories server (the auth 
plugin dedicated to django) can retrieve the cookie, you don't need to set it 
in the sessionid query parameter
2011-06-25 10:21:27+0000 <dachary> a) the query player_id=foobar with cookie 
sessionid=484 is sent, b) the djangoauth module intercepts the request, c) it 
asks django what is the user serial number for session 484, d) django replies : 
this is user 2020, e) the djangoauth module changes the player_id=foobar into 
player_id=2020 and forwards the request
2011-06-25 10:21:46+0000 <dachary> does that make sense ? 
2011-06-25 10:22:13+0000 <dachary> (i'm in a train, the communication may lag, 
sorry about that ;-)
2011-06-25 10:22:27+0000 <arbrandes> yes, it does.  And it does the reverse on 
postprocess
2011-06-25 10:22:34+0000 <dachary> exactly !
2011-06-25 10:22:50+0000 <arbrandes> np about the lag :)
2011-06-25 10:23:32+0000 <dachary> as in the auth module currently, it looks up 
all user_id and change them back to readable names. Only it does not have to 
rely on the sessionid cookie for that because there is nothing confidential or 
security related in transforming numerical ids into readable names.
2011-06-25 10:24:05+0000 <arbrandes> so the database IDs used in the service's 
main tables (/tmp/cardstories.sqlite) will end up being django's user table's 
ids.
2011-06-25 10:24:34+0000 <dachary> the django auth module needs a function that 
looks very much like the /plugins/auth/auth.py postprocess function
2011-06-25 10:24:43+0000 <dachary> exactly
2011-06-25 10:25:14+0000 <dachary> cardstories end up using the same numerical 
ids as django
2011-06-25 10:25:50+0000 <arbrandes> Ok, sounds good to me, thanks for the help
2011-06-25 10:25:51+0000 <dachary> arbrandes: I realize there is no example 
showing how to make a http request in cardstories currently
2011-06-25 10:26:19+0000 <dachary> there is a very simple way to do this, would 
you like me to provide you with an example ? 
2011-06-25 10:26:58+0000 <dachary> unless you have an example you will need to 
figure out the deferred way of doing things in twisted, which is probably a 
little overkill for now
2011-06-25 10:26:59+0000 <arbrandes> dachary, sure, if it's not too much 
trouble.  I was going to try and figure it out on my own, but if you already 
have something in mind, it'll make my life easier. :)
2011-06-25 10:27:26+0000 <arbrandes> Yep, I was going to read up on the 
deferred/yield stuff
2011-06-25 10:27:34+0000 <dachary> ok, i'll do that right now. If the 
communication breaks you will have it in 3 hours time
2011-06-25 10:27:43+0000 <arbrandes> Which I'm not familiar with yet
2011-06-25 10:28:41+0000 <arbrandes> dachary, thanks a lot, I'm going to start 
on the rest of the plugin
2011-06-25 10:28:47+0000 <dachary> arbrandes: I suggest learning the deferred 
without thinking about yield as a first step.
2011-06-25 10:29:11+0000 <dachary> trying to learn both at the same time (yield 
+ deferred) just makes things a little more difficult
2011-06-25 10:29:59+0000 <arbrandes> dachary, ok, thanks of the tip.  I assume 
this is all well documented in the python docs
2011-06-25 10:31:45+0000 <dachary> arbrandes: yes it is. But the syntax of the 
deferred is not what's difficult about it. Using them requires a specific 
architecture that impacts all the code.
2011-06-25 10:33:09+0000 <arbrandes> arbrandes, I understand the implications.  
I'll also certainly have many questions later on. :)
2011-06-25 10:34:24+0000 <dachary> I'd be happy to answer them. I wish I had 
someone to ask the first time i tried to use them. I did not realize the full 
extend of what they provide and made a few mistakes that could have been easily 
avoided.
2011-06-25 10:36:39+0000 <arbrandes> Thanks, I'll be very glad to have your 
assistance.  Now, to python!! :)
2011-06-25 10:43:05+0000 <dachary> arbrandes: http://pastebin.com/fMgHyHdL
2011-06-25 10:44:26+0000 <dachary> it's not efficient because it makes one http 
request per id 
2011-06-25 10:44:26+0000 <dachary> but it won't be much trouble to improve it 
afterwards, performances is probably not your biggest concern at the moment ;-)
2011-06-25 10:45:50+0000 <dachary> if an error occurs, the report will be 
caught in site.py 
2011-06-25 10:45:53+0000 <dachary>        # catch errors and dump a trace ...
2011-06-25 10:45:53+0000 <dachary>         def failed(reason):
2011-06-25 10:45:54+0000 <dachary>             reason.printTraceback()
2011-06-25 10:46:02+0000 <dachary> it will both be printed in the logs
2011-06-25 10:46:14+0000 <dachary> and returned to the user 
2011-06-25 10:46:19+0000 <arbrandes> Thanks again, I'll try to understand 
what's going on as I go.
2011-06-25 10:47:12+0000 <arbrandes> There will be other improvements possible, 
such as showing the user's actual names, which are already being stored in 
django's db.
2011-06-25 10:47:49+0000 <arbrandes> But one thing at a time... :)
2011-06-25 10:49:48+0000 <dachary> arbrandes: at present you plan to return the 
login name right ? And you're saying that an improvement would be to return the 
actual user name instead of the login name ? I'm asking to make sure I 
understand correctly ;-)
2011-06-25 10:51:15+0000 <arbrandes> dachary, from what I understand the login 
name (in this case, email) will always need to be returned.  I'm just saying 
that at some point in the future it might be nice to display the actual names 
of the players that won a game, instead of just their emails.
2011-06-25 10:52:24+0000 <arbrandes> (which is why a user's name was in 
antoviaque's mockup, I suppose :)
2011-06-25 10:53:05+0000 <dachary> the client does not need the email
2011-06-25 10:53:05+0000 <dachary> it needs a name, whatever name django 
decides it must display is fine
2011-06-25 10:53:05+0000 <dachary> hum
2011-06-25 10:53:07+0000 <dachary> now that you mention it...
2011-06-25 10:53:13+0000 <dachary> I may have overlooked a few things :-P
2011-06-25 10:53:26+0000 <arbrandes> 
http://tickets.farsides.com/attachments/92/welcome_login.png
2011-06-25 10:53:42+0000 <arbrandes> And the name must be unique, so that the 
auth plugin can work
2011-06-25 10:53:44+0000 <arbrandes> right?
2011-06-25 10:54:11+0000 <dachary> yes that's why names show in the mockups
2011-06-25 10:54:13+0000 <arbrandes> But there may be other non-unique data 
that could be passed between client and server.
2011-06-25 10:54:27+0000 <arbrandes> Or no?
2011-06-25 10:56:19+0000 * dachary thinking
2011-06-25 10:57:07+0000 <arbrandes> This is, of course, just an idea, I think 
I understand enough of the rest to make an auth plugin that works (especially 
with your postprocess with the ready-made defer stuff, heheh)
2011-06-25 11:02:26+0000 dachary (dachary) is now online
2011-06-25 11:03:05+0000 <dachary> (12:57:37 PM) dachary: the player_id and 
owner_id parameters : they are ignored and sessionid is used instead
2011-06-25 11:03:53+0000 <dachary> (12:58:37 PM) dachary: the invited parameter 
holds the list of players that must be invited and they must be looked up by 
django, therefore they must be unique names that django can match (emails ? 
login names ? ) to its user database.
2011-06-25 11:03:53+0000 <dachary> (12:59:34 PM) dachary: arbrandes: does 
django ask for the user email during the registration ? 
2011-06-25 11:04:54+0000 <arbrandes> dachary, yes, I'm working on the 
assumption that the user's email is his/her "login name".
2011-06-25 11:05:36+0000 <arbrandes> dachary, but I'm also recording the user's 
real name, which I inferred was necessary from the login mockup on #150.
2011-06-25 11:05:47+0000 <dachary> ok
2011-06-25 11:06:27+0000 <dachary> arbrandes: is this the usual way of creating 
a user in django ? (i.e. to use the email as the account name instead of having 
the combination login + email + realname ) 
2011-06-25 11:06:36+0000 <arbrandes> I have a question, though: there's a 
"create" method on the current auth 
2011-06-25 11:06:47+0000 <arbrandes> ... sorry cut off, i'll get back to it
2011-06-25 11:06:48+0000 <arbrandes> to answer your question:
2011-06-25 11:07:25+0000 <arbrandes> The usual way of creating a user in django 
is with username+email
2011-06-25 11:08:22+0000 <arbrandes> But from the mockups, I inferred that just 
email was the preferred authentication mode.  Or was I wrong in thinking that?
2011-06-25 11:08:54+0000 <arbrandes> (and also from the current auth scheme)
2011-06-25 11:09:22+0000 <dachary> it's not wrong. Actually the simpler for you 
the better. If you had decided that it was simpler to use the usual django auth 
method, that would have been fine. 
2011-06-25 11:10:07+0000 <dachary> Whatever you have with regard to 
registration is fine with me ;-) There are no requirements but to make it as 
simple as possible.
2011-06-25 11:10:58+0000 <dachary> the current auth really is a placeholder 
that is not fit for anything but tests, which bring us back to the question you 
had on create
2011-06-25 11:11:02+0000 <arbrandes> It was a bit of trouble to use just email, 
actually, but it's working now. :)  But getting back to the question I started 
asking:
2011-06-25 11:11:23+0000 <arbrandes> Will the djangoauth plugin need to 
actually create users?
2011-06-25 11:11:51+0000 <arbrandes> What I have in place now is that when the 
user gets to the actual cardstories client, his/her user is already created.
2011-06-25 11:11:58+0000 <dachary> no
2011-06-25 11:12:02+0000 <arbrandes> BUT... how about invitations?
2011-06-25 11:12:53+0000 <arbrandes> It's just that I haven't looked into how 
the invitations work yet, and I was wondering if for every invitation sent out 
a user is created.
2011-06-25 11:13:04+0000 <arbrandes> Created previous to his/her login, I mean.
2011-06-25 11:13:07+0000 <dachary> good point. 
2011-06-25 11:13:17+0000 <arbrandes> Which would be a problem because of 
passwords.
2011-06-25 11:14:24+0000 <dachary> what about this:
2011-06-25 11:14:39+0000 <arbrandes> And by "problem", I just mean that a 
proper mockur/user story would have to be decided on.
2011-06-25 11:14:40+0000 <arbrandes> *mockup
2011-06-25 11:18:08+0000 <dachary> the invitations must be emails. When 
preprocess sees invitations, it calls htp://djangohost/invite?email= + email of 
invited person. The invite django function does the following: create a user + 
return the user. When the user receives an invitation via mail, it will login 
if it already had an account or ask for a password reminder.
2011-06-25 11:19:28+0000 <dachary> that is, the djangoauth must not create a 
user for invited people, it should expect that django does it when and if 
necessary.
2011-06-25 11:20:04+0000 <dachary> of course, for the invited person going to 
the "lost password" page as a first step is less than friendly
2011-06-25 11:20:23+0000 <arbrandes> Ok, this is doable.  But what exactly do 
you mean by "it will login" and "ask for a password reminder"?
2011-06-25 11:20:33+0000 <arbrandes> Yeah, this is what I was referring to
2011-06-25 11:20:37+0000 <dachary> but it can be improved later on
2011-06-25 11:21:21+0000 <arbrandes> How about the login part?  Do you mean 
automatically login in a user from a link in the email?
2011-06-25 11:21:48+0000 <dachary> no, I mean that the user will need to login 
if he is not logged in
2011-06-25 11:22:03+0000 <arbrandes> And to already improve on the password 
reminder, we could just use a random password and email it with the invite.
2011-06-25 11:22:24+0000 <arbrandes> a *simple* random password, I mean, heheheh
2011-06-25 11:22:25+0000 <dachary> the link will be to the game and it will 
show the "anonymous" view by default. If the user wants to participate he will 
need to login. 
2011-06-25 11:23:30+0000 <dachary> arbrandes: I think we can just ignore this 
problem for now. I feel it's independant enough and that we don't need to 
resolve it right now. Do you think it must be handled right now ? 
2011-06-25 11:25:20+0000 <arbrandes> dachary, if you mean the whole invitation 
problem, I agree as long as it doesn't break anything: will invitations still 
work if the user is not created right away?
2011-06-25 11:26:00+0000 <arbrandes> which was my original question, actually :)
2011-06-25 11:26:17+0000 <dachary> No, I just mean the improvement of the user 
story when a user is invited. The invited user must be created otherwise there 
will be no way to invite a user, even with a complicated user story.
2011-06-25 11:27:43+0000 <dachary> I don't see how the invitations will work if 
the user is not created when the djangoauth plugin requests the translation of 
a mail invitation into a django user id. 
2011-06-25 11:28:25+0000 <arbrandes> Ok, so the user is created and returned on 
invite by the plugin, and new users will click on 'forgot password' when they 
want to log in.
2011-06-25 11:31:13+0000 <dachary> I think this is the simplest way to 
implement the invitations. But maybe there is even simpler. 
2011-06-25 11:31:15+0000 <dachary> communications will soon break. Train is 
accelerating to 300km/h and that's too much for 3G :-)
2011-06-25 11:31:36+0000 <arbrandes> dachary, lol, ok
2011-06-25 11:32:00+0000 <dachary> I was supposed to do nothing today but I 
very much enjoyed discussing this topic with you arbrandes. Thanks :-)
2011-06-25 11:33:04+0000 <arbrandes> dachary, me too!  I'm starting to get a 
grasp on the whole thing, thanks for the help.
2011-06-25 11:33:52+0000 <dachary> one last question : how difficult was it to 
make the auth work with facebook ? 
2011-06-25 11:33:59+0000 <dachary> arbrandes: ^
2011-06-25 11:34:33+0000 <arbrandes> dachary, I haven't looked into it, yet, 
sorry.  All the work I've done is just on getting simple registration working.
2011-06-25 11:34:45+0000 <dachary> ok
2011-06-25 11:35:15+0000 <dachary> ttyl !
2011-06-25 11:35:25+0000 <arbrandes> dachary, but from what I've seen, I 
believe this is the hard part.  FB will be wholly on Django's side.  Ok, later!
2011-06-25 11:36:29+0000 <dachary> Would it be hard because it's not 
implemented yet or because it's implemented and complex or because django makes 
it difficult or something else ? 
2011-06-25 11:37:43+0000 * dachary shouldn't ask questions a few seconds before 
breakup ;-) arbrandes ^
2011-06-25 11:38:06+0000 <arbrandes> dachary, it was difficult to get all the 
pieces working together.   Django is a bit brittle (as all frameworks are), and 
in addition, it took me a while to understand how to best couple it with 
cardstories (everything from directory placement to user model).
2011-06-25 11:38:32+0000 <dachary> ok, got it
2011-06-25 11:38:59+0000 <dachary> I'm gone for real now otherwise your next 
answer will be lost to me ;-)
2011-06-25 11:39:33+0000 <arbrandes> Also, the HTML/CSS of the log in form took 
me a while, in order to have the default values ("Your name", "[email protected]") 
put in and removed in time.   
2011-06-25 11:39:35+0000 <arbrandes> Ok then, see you, hehehehe
2011-06-25 11:40:32+0000 <dachary> (got that ;-)
2011-06-25 12:17:14+0000 dachary (dachary) is now online
2011-06-25 12:18:51+0000 tempuramerino (tempuramerino) is now online
2011-06-25 12:23:18+0000 arbrandes (arbrandes) is now online
2011-06-25 13:49:37+0000 dachary (dachary) is now online
2011-06-25 14:24:09+0000 arbrandes (arbrandes) is now online
2011-06-25 16:01:35+0000 romulo (romulo) is now online
2011-06-25 16:01:38+0000 <romulo> hi there
2011-06-25 16:01:41+0000 <romulo> good morning
2011-06-25 17:30:58+0000 <arbrandes> Hey romulo, how's the war with the 
Federation coming along?  (Star Trek joke, sorry ;)
2011-06-25 17:31:36+0000 <romulo> lol
2011-06-25 17:31:36+0000 <romulo> =p
2011-06-25 17:32:14+0000 <arbrandes> By the way, to whom it may concern, I 
think I finally understand the usefulness of unit tests as documentation.
2011-06-25 17:34:03+0000 <arbrandes> I was naively coding up the djangoauth 
plugin as copy-pasted from the auth plugin, and when writing the tests I saw a 
simple thing I would never have found in any other way.
2011-06-25 17:34:27+0000 <arbrandes> This is to say, I think I understand 
dachary's position on unit tests over inline documentation.
2011-06-25 17:35:52+0000 <arbrandes> Unfortunately, writing tests is MUCH 
harder. :P
2011-06-25 17:48:12+0000 <romulo> arbrandes, at my pov, unit tests are GREAT 
for docs, but inline documentation is also important. The problem with unit 
tests is that if you have a function that transform some math algorithm, you 
will never figure out how it works. Tests (at my POV) are meant to check 
correctness and results, not to ensure the method works.
2011-06-25 17:49:22+0000 <arbrandes> romulo, sure, which means BOTH are 
necessary, hehehe...
2011-06-25 17:49:57+0000 <romulo> exactly
2011-06-25 18:00:13+0000 <romulo> arbrandes, have you seen antoviaque  or 
dachary?
2011-06-25 18:03:43+0000 arbrandes_ (arbrandes_) is now online
2011-06-25 18:04:43+0000 antoviaque (antoviaque) is now online
2011-06-25 18:14:16+0000 <arbrandes_> romulo, dachary was last seen in a TGV
2011-06-25 18:14:25+0000 <arbrandes_> Haven't heard from antoviaque today
2011-06-25 18:18:15+0000 <dachary> hi
2011-06-25 18:22:27+0000 <romulo> dachary, hi there
2011-06-25 18:31:31+0000 <dachary> arbrandes_: It means a lot to me that you 
understand my position regarding unittests ;-)
2011-06-25 18:33:43+0000 <arbrandes_> dachary, I was on the fence, but then, 
because of test_auth.py, I saw that I needed to return the user id as an int(). 
 I am now convinced, because there was no other way I would've caught this 
(probably not even with inline documentation), except running it and waiting 
for an error.
2011-06-25 18:34:27+0000 <arbrandes_> An error which  wouldn't happen right 
away, since this is Python and so dynamically typed, but an error nonetheless.
2011-06-25 18:34:39+0000 <dachary> :-)
2011-06-25 18:35:06+0000 <romulo> i guess both are important, and also, 100% on 
coverage is a must.
2011-06-25 19:06:06+0000 antoviaque (antoviaque) is now online
2011-06-25 22:50:08+0000 <arbrandes_> antoviaque and dachary, whenever you get 
the chance, take  a look at 
http://farsides.com/members/arbrandes/activity/948/.  I'd love to have a little 
feedback on what's been done so far regarding #150.  I'm going to sign out now, 
but hopefully we can discuss it here tomorrow.  Thanks!
2011-06-25 22:50:28+0000 <dachary> cheers
2011-06-25 22:52:04+0000 <arbrandes_> :) gotta go eat something, I'm starving.  
later, man!
2011-06-25 22:52:05+0000 <dachary> arbrandes_: trying now
2011-06-25 22:52:10+0000 <dachary> later !
_______________________________________________
Farsides mailing list - [email protected]

Wiki:  http://farsides.com/
List:  http://farsides.com/ml/
Forum: http://farsides.com/forum/
Ideas: http://farsides.com/ideas/
Chat:  http://farsides.com/chat/

Reply via email to