1
0
Fork 0
mirror of git://git.psyced.org/git/pypsyc synced 2024-08-15 03:20:04 +00:00

last state we had in cvs

This commit is contained in:
psyc://psyced.org/~lynX 2010-02-24 09:50:45 +01:00
commit 0f02e9cd76
128 changed files with 9224 additions and 0 deletions

View file

@ -0,0 +1,230 @@
# usage: twistd -noy ircd.py
import sys
from twisted.application import service, internet
from pypsyc.center import ServerCenter
from pypsyc.net import PSYCServerFactory
from pypsyc.objects import PSYCReceiver
from pypsyc.objects.server import Person, Place, GroupSlave
from pypsyc import parseURL
from twisted.protocols import irc
from twisted.internet.protocol import ServerFactory
"""
watch out, the main purpose of this thing is to debug the context slave
system
"""
class IRCD(irc.IRC, PSYCReceiver):
center = None
password = ''
nick = ''
url = ''
source = None
def __init__(self, center, hostname):
self.center = center
self.hostname = hostname
def connectionMade(self):
peer = self.transport.getPeer()
self.source = 'object:%s:%d'%(peer.host, peer.port)
self.center.register_object(self.source, self)
def connectionLost(self, reason):
if self.url:
self.irc_QUIT(None, None)
elif self.nick is '':
print 'closing unknown connection'
def sendNumeric(self, numeric, msg):
self.sendLine(':%s %s %s :%s'%(self.hostname, numeric, self.nick, msg))
# def sendLine(self, line):
# irc.IRC.sendLine(self, line.encode('iso-8859-1'))
def sendMessage(self, source, target, cmd, data = None):
s = ':%s %s %s'%(self.url2prefix(source), target, cmd)
if data:
s += ' :%s'%data
self.sendLine(s)
def sNotice(self, data):
self.sendLine(':%s NOTICE %s :%s'%(self.hostname, self.nick, data))
"""helper functions"""
def expandUrl(self, target):
"""quick and dirty is_uniform check"""
if target.find(':') is -1:
if target[0] == '#':
return self.hostname + '/@%s'%target[1:]
return self.hostname + '/~%s'%target
if target[0] == '#':
return target[1:]
return target
def minimizeUrl(self, source):
if source.startswith(self.hostname):
# remark: +2 to skip trailing /@
return source[len(self.hostname) + 2:]
return source
def url2prefix(self, url):
if url.find(':') != -1:
u = parseURL(url)
if u['resource'][0] == '~':
ident = u['resource'][1:]
else:
ident = '*'
host = u['host']
else:
ident = url # its a local nick
host = 'localuser'
return '%s!%s@%s'%(url, ident, host)
"""irc_ command hooks"""
def irc_USER(self, prefix, params):
pass
def irc_PASS(self, prefix, params):
self.password = params[0]
def irc_NICK(self, prefix, params):
self.nick = params[0]
self.center.msg({'_source' : self.source,
'_target' : self.expandUrl(self.nick),
'_password' : self.password},
'_request_link', '')
def irc_PRIVMSG(self, prefix, params):
target = params[0]
mc = '_message_private'
if target[0] == '#':
mc = '_message_public'
self.center.msg({ '_source' : self.source,
'_target' : self.expandUrl(target),
'_nick' : self.nick},
mc, params[-1])
def irc_JOIN(self, prefix, params):
chan = params[0]
self.center.msg({ '_source' : self.source,
'_target' : self.expandUrl(chan),
'_nick' : self.nick},
'_request_enter', '')
def irc_PART(self, prefix, params):
chan = params[0]
self.center.msg({ '_source' : self.source,
'_target' : self.expandUrl(chan),
'_nick' : self.nick},
'_request_leave', '')
def irc_QUIT(self, prefix, params):
self.center.msg({ '_source' : self.source,
'_target' : self.url },
'_request_unlink', '')
def irc_unknown(self, prefix, command, params):
if command == 'ROSTER':
self.center.msg({ '_source' : self.source,
'_target' : self.url },
'_request_roster', '')
elif command == 'FRIEND':
self.center.msg({ '_source' : self.source,
'_target' : self.expandUrl(params[0]) },
'_request_friendship', 'Lass uns Freunde sein')
else:
print 'unknown irc cmd %s'%command
"""pypsyc msg API"""
def msgUnknownMethod(self, vars, mc, data):
print 'unsupported %s from %s'%(mc, vars['_source'])
def msg_notice_link(self, vars, mc, data):
self.url = vars['_source']
self.sendNumeric(irc.RPL_WELCOME, 'Hello, %s'%self.nick)
self.sendNumeric(irc.RPL_YOURHOST, 'Welcome to %s'%self.hostname)
self.sendNumeric(irc.RPL_MYINFO, '%s is a pyPSYC daemon IRC interface'%self.hostname)
def msg_message_private(self, vars, mc, data):
if vars['_target'] is self.source:
t = self.nick
else: # should not happen
raise
# TODO: might be appropriate to use self.privmsg()
# self.privmsg(vars['_source'], self.nick, None, data)
s = self.minimizeUrl(vars['_source'])
self.sendMessage(s, 'PRIVMSG', t, data)
def msg_message_echo_private(self, vars, mc, data):
pass # echo is not common in irc
def msg_message_public(self, vars, mc, data):
if vars['_source'] != self.url: # skip echo
if vars.has_key('_context'):
t = '#' + self.minimizeUrl(vars['_context'])
else:
t = '#' + self.minimizeUrl(vars['_source'])
s = self.minimizeUrl(vars['_source'])
# TODO: might be appropriate to use self.privmsg()
# self.privmsg(vars['_source'], None, t, data)
self.sendMessage(s, 'PRIVMSG', t, data)
else:
pass # echo is not common in IRC
def msg_echo_place_enter(self, vars, mc, data):
t = '#' + self.minimizeUrl(vars['_source'])
self.sendMessage(self.nick, 'JOIN', t)
def msg_echo_place_leave(self, vars, mc, data):
t = '#' + self.minimizeUrl(vars['_source'])
self.sendMessage(self.nick, 'PART', t)
def msg_status_place_members(self, vars, mc, data):
t = '#' + self.minimizeUrl(vars['_source'])
self.names(self.nick, t, map(self.minimizeUrl, vars['_list_members']))
def msg_notice_unlink(self, vars, mc, data):
if vars['_source'] == self.url:
self.url = None
self.transport.loseConnection()
def msg_notice_place_enter(self, vars, mc, data):
s = vars['_source']
c = '#' + self.minimizeUrl(vars['_context'])
if s == self.url:
return # we dont like being joined via notice!
self.join(self.url2prefix(self.minimizeUrl(s)), c)
def msg_notice_place_leave(self, vars, mc, data):
s = vars['_source']
c = '#' + self.minimizeUrl(vars['_context'])
self.part(self.url2prefix(self.minimizeUrl(s)), c)
def msg_notice_roster(self, vars, mc, data):
friends = vars['_list_friends']
places = vars['_list_places']
if friends:
self.sNotice('Friends')
for friend in vars['_list_friends']:
self.sNotice('~ %s'%friend)
if places:
self.sNotice('Places')
for place in places:
self.sNotice('@ %s'%place)
def msg_request_friendship(self, vars, mc, data):
sni = self.minimizeUrl(vars['_source'])
self.notice(sni, self.nick,
'%s wants to be your friend'%(sni))
def msg_notice_friendship_established(self, vars, mc, data):
sni = self.minimizeUrl(vars['_source'])
self.notice(sni, self.nick,
'%s is now your friend'%(sni))
class IRCDFactory(ServerFactory):
center = None
def __init__(self, center, location):
self.center = center
self.location = location
def buildProtocol(self, addr):
p = IRCD(self.center, self.location)
p.factory = self
return p
class MyServerCenter(ServerCenter):
def create_user(self, netname):
return Person(netname, self)
def create_place(self, netname):
return Place(netname, self)
def create_context(self, netname):
return GroupSlave(netname, self)
root = 'psyc://ente' # TODO: this does belong into a config file!
application = service.Application('psycserver')
center = MyServerCenter(root)
factory = PSYCServerFactory(center, None, root)
psycServer = internet.TCPServer(4404, factory)
ircfactory = IRCDFactory(center, root)
ircServer = internet.TCPServer(6667, ircfactory)
myService = service.IServiceCollection(application)
psycServer.setServiceParent(myService)
ircServer.setServiceParent(myService)

View file

@ -0,0 +1,9 @@
Purpose:
this is designed to be a news distributing server only. It fetches RSS feeds
Running:
twistd -noy rss_server.py
This code depends on
- rss.py from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/277099
- feedparser.py from http://diveintomark.org/projects/feed_parser/
- twisted python (python is less fun without)

View file

@ -0,0 +1,131 @@
# usage: twistd -noy rss_server.py
from twisted.application import service, internet
from twisted.internet import reactor
from pypsyc.center import ServerCenter
from pypsyc.net import PSYCServerFactory
from pypsyc.objects.server import Place
from pypsyc import parseUNL
try:
from rss import FeederFactory
except ImportError:
print 'error while importing rss.py'
print 'make sure you have rss.py from ',
print 'from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/277099'
print 'and feedparser.py from ',
print 'http://diveintomark.org/projects/feed_parser/'
class PlaceFeeder(FeederFactory):
def getFeeds(self):
return []
class Feedplace(Place):
channel = None
silent = True
def __init__(self, netname, center, feed):
Place.__init__(self, netname, center)
self.feed = feed
self.error = 0 # number of times that we didnt succeed
self.fetched = 0 # number of times we fetched sucessfully
self.fetched_items = 0 # the average number of new items per fetch
self.fetch_interval = 15 * 60 # initial feed interval
self.feeder = PlaceFeeder(False)
self.news = []
reactor.callLater(5, self.fetchFeed)
def fetchFeed(self):
d = self.feeder.start([(self.feed, '')])
d.addCallback(self.gotFeed)
d.addErrback(self.gotError)
def gotError(self, error):
self.error += 1
# TODO: react on feeds that are temp/perm unreachable
reactor.callLater(self.fetch_interval, self.fetchFeed)
print 'looks as if feed %s is unreachable'%self.feed
print error
def gotFeed(self, data):
self.fetched += 1
new = []
items = {}
if self.channel is None:
self.channel = data['channel']
self.castmsg({ '_nick' : self.netname,
'_topic' : self.showTopic()},
'_status_place_topic',
'Topic by [_nick]: [_topic]')
for item in data['items']:
# diff by url
href = item['link']
new.append(href)
items[href] = item
diff = filter(lambda x: x not in self.news, new)
for href in diff:
item = items[href]
v = {'_news_headline' : item['title_detail']['value'],
'_page_news' : href,
'_channel_title' : data['channel']['title'] }
self.castmsg(v, '_notice_news_headline_rss',
'([_channel_title]) [_news_headline]\n[_page_news]')
self.news = new
# feeds whose average number of new items is < x
# can be polled with less frequency
self.fetched_items += len(diff)
avg = float(self.fetched_items) / self.fetched
print 'avg no of new items per fetch for %s is %f'%(self.feed, avg)
if avg < 1.5: # x
# lower frequency
self.fetch_interval *= avg
elif avg > 4.5 and self.fetched > 10: # y
# increase frequenzy
self.fetch_interval /= 2
print 'callLater in %d'%(self.fetch_interval)
reactor.callLater(self.fetch_interval, self.fetchFeed)
def showMembers(self):
return []
def showTopic(self):
if self.channel is not None:
return 'feed \'%s\' available from %s'%(self.channel['title'],
self.feed)
else:
return 'stand by while fetching feed %s'%self.feed
def msg_message_public(self, vars, mc, data):
pass # they're not for talking
class MyServerCenter(ServerCenter):
feeds = {}
def create_user(self, netname):
return False
def create_place(self, netname):
u = parseUNL(netname)
res = u['resource'][1:]
if self.feeds.has_key(res):
return Feedplace(netname, center, self.feeds[res])
return False
def create_context(self, netname):
return False
def setFeeds(self, feeds):
self.feeds = feeds
def getFeeds(self):
return self.feeds
root = 'psyc://ente'
application = service.Application('psyc news distributor')
center = MyServerCenter(root)
factory = PSYCServerFactory(center, None, root)
psycServer = internet.TCPServer(4404, factory)
center.setFeeds({ 'heise' : 'http://www.heise.de/newsticker/heise.rdf' })
myService = service.IServiceCollection(application)
psycServer.setServiceParent(myService)

View file

@ -0,0 +1,28 @@
"""p2p manager and client as described in the old PSYC whitepaper at
http://psyc.pages.de/whitepaper/
probably broken currently"""
from pypsyc.center import ServerCenter, ClientCenter
from pypsyc.objects.PSYCObject import PSYCClient
from pypsyc.objects.Advanced import AdvancedManager, AdvancedPlace
import sys
import asyncore
location = 'psyc://adamantine.aquarium'
type = sys.argv[1]
if type == 'manager':
center = ServerCenter([location + ':4405/', location + ':4406',
location + ':4407', location + ':4408'])
center2 = ServerCenter([location])
AdvancedManager(location + '/@advanced', center2)
if type == 'client':
center = ClientCenter()
me = PSYCClient(location + '/~fippo', center)
me.online()
AdvancedPlace(location + "/@advanced", center)
me.sendmsg({'_target' : location + '/@advanced',
'_source' : location + '/~fippo'},
'_request_enter', '')
while center:
asyncore.poll(timeout=0.5)