mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Sync to trunk.
This commit is contained in:
commit
79eccec4df
@ -10,7 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
class DN_se(BasicNewsRecipe):
|
class DN_se(BasicNewsRecipe):
|
||||||
title = 'Dagens Nyheter'
|
title = 'Dagens Nyheter'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
description = 'News from Sveden'
|
description = 'News from Sweden'
|
||||||
publisher = 'Dagens Nyheter'
|
publisher = 'Dagens Nyheter'
|
||||||
category = 'news, politics, Sveden'
|
category = 'news, politics, Sveden'
|
||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
|
@ -10,7 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
|
|
||||||
class OGlobo(BasicNewsRecipe):
|
class OGlobo(BasicNewsRecipe):
|
||||||
title = 'O Globo'
|
title = 'O Globo'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic and Sujata Raman'
|
||||||
description = 'News from Brasil'
|
description = 'News from Brasil'
|
||||||
publisher = 'O Globo'
|
publisher = 'O Globo'
|
||||||
category = 'news, politics, Brasil'
|
category = 'news, politics, Brasil'
|
||||||
@ -30,15 +30,26 @@ class OGlobo(BasicNewsRecipe):
|
|||||||
|
|
||||||
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
|
||||||
|
|
||||||
keep_only_tags = [dict(name='div', attrs={'id':'ltintb'})]
|
extra_css = '''
|
||||||
|
cite{color:#007BB5; font-size:xx-small; font-style:italic;}
|
||||||
|
body{font-family:Arial,Helvetica,sans-serif;font-size:x-small;}
|
||||||
|
h3{font-size:large; color:#082963; font-weight:bold;}
|
||||||
|
#ident{color:#0179B4; font-size:xx-small;}
|
||||||
|
p{color:#000000;font-weight:normal;}
|
||||||
|
.commentario p{color:#007BB5; font-style:italic;}
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
keep_only_tags = [dict(name='div', attrs={'id':'ltintb'}),
|
||||||
|
dict(name='a', attrs={'class':['img imgLoader','img ftr imgLoader']}),]
|
||||||
|
|
||||||
remove_tags = [
|
remove_tags = [
|
||||||
dict(name='script')
|
dict(name='script')
|
||||||
,dict(name='object')
|
,dict(name='object')
|
||||||
,dict(name='form')
|
,dict(name='form')
|
||||||
,dict(name='div', attrs={'id':['linksPatGoogle','rdpm','cor','com','env','rcm_st']})
|
,dict(name='div', attrs={'id':['linksPatGoogle','rdpm','cor','com','env','rcm_st','coment',]})
|
||||||
,dict(name='div', attrs={'class':'box-zap-anu2'})
|
,dict(name='div', attrs={'class':'box-zap-anu2'})
|
||||||
,dict(name='a')
|
,dict(name='a', attrs={'class':'assine'})
|
||||||
,dict(name='link')
|
,dict(name='link')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
|
|||||||
class SVD_se(BasicNewsRecipe):
|
class SVD_se(BasicNewsRecipe):
|
||||||
title = 'Svenska Dagbladet'
|
title = 'Svenska Dagbladet'
|
||||||
__author__ = 'Darko Miletic'
|
__author__ = 'Darko Miletic'
|
||||||
description = 'News from Sveden'
|
description = 'News from Sweden'
|
||||||
publisher = 'Svenska Dagbladet'
|
publisher = 'Svenska Dagbladet'
|
||||||
category = 'news, politics, Sveden'
|
category = 'news, politics, Sveden'
|
||||||
oldest_article = 2
|
oldest_article = 2
|
||||||
|
@ -24,7 +24,8 @@ class LinuxFreeze(Command):
|
|||||||
is64bit = platform.architecture()[0] == '64bit'
|
is64bit = platform.architecture()[0] == '64bit'
|
||||||
arch = 'x86_64' if is64bit else 'i686'
|
arch = 'x86_64' if is64bit else 'i686'
|
||||||
ffi = '/usr/lib/libffi.so.5' if is64bit else '/usr/lib/gcc/i686-pc-linux-gnu/4.4.1/libffi.so.4'
|
ffi = '/usr/lib/libffi.so.5' if is64bit else '/usr/lib/gcc/i686-pc-linux-gnu/4.4.1/libffi.so.4'
|
||||||
|
stdcpp = '/usr/lib/gcc/%s-pc-linux-gnu/%s/libstdc++.so.6'%(arch, '4.4.2'
|
||||||
|
if is64bit else '4.4.1')
|
||||||
|
|
||||||
QTDIR = '/usr/lib/qt4'
|
QTDIR = '/usr/lib/qt4'
|
||||||
QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml',
|
QTDLLS = ('QtCore', 'QtGui', 'QtNetwork', 'QtSvg', 'QtXml',
|
||||||
@ -57,8 +58,7 @@ class LinuxFreeze(Command):
|
|||||||
'/usr/lib/libjpeg.so.7',
|
'/usr/lib/libjpeg.so.7',
|
||||||
'/usr/lib/libxslt.so.1',
|
'/usr/lib/libxslt.so.1',
|
||||||
'/usr/lib/libgthread-2.0.so.0',
|
'/usr/lib/libgthread-2.0.so.0',
|
||||||
'/usr/lib/gcc/***-pc-linux-gnu/4.4.1/libstdc++.so.6'.replace('***',
|
stdcpp,
|
||||||
arch),
|
|
||||||
ffi,
|
ffi,
|
||||||
'/usr/lib/libpng12.so.0',
|
'/usr/lib/libpng12.so.0',
|
||||||
'/usr/lib/libexslt.so.0',
|
'/usr/lib/libexslt.so.0',
|
||||||
|
@ -6,7 +6,7 @@ __copyright__ = '2008, Kovid Goyal <kovid at kovidgoyal.net>'
|
|||||||
import sys, os, shutil, cPickle, textwrap, stat
|
import sys, os, shutil, cPickle, textwrap, stat
|
||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
|
||||||
from calibre import __version__, __appname__, prints
|
from calibre import __appname__, prints
|
||||||
|
|
||||||
|
|
||||||
entry_points = {
|
entry_points = {
|
||||||
@ -491,36 +491,36 @@ complete -o filenames -F _'''%(opts,exts) + name + ' ' + name +"\n\n"
|
|||||||
|
|
||||||
VIEWER = '''\
|
VIEWER = '''\
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Version=%s
|
Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=LRF Viewer
|
Name=LRF Viewer
|
||||||
GenericName=Viewer for LRF files
|
GenericName=Viewer for LRF files
|
||||||
Comment=Viewer for LRF files (SONY ebook format files)
|
Comment=Viewer for LRF files (SONY ebook format files)
|
||||||
TryExec=lrfviewer
|
TryExec=lrfviewer
|
||||||
Exec=lrfviewer %%F
|
Exec=lrfviewer %F
|
||||||
Icon=calibre-viewer
|
Icon=calibre-viewer
|
||||||
MimeType=application/x-sony-bbeb;
|
MimeType=application/x-sony-bbeb;
|
||||||
Categories=Graphics;Viewer;
|
Categories=Graphics;Viewer;
|
||||||
'''%(__version__,)
|
'''
|
||||||
|
|
||||||
EVIEWER = '''\
|
EVIEWER = '''\
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Version=%s
|
Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=E-book Viewer
|
Name=E-book Viewer
|
||||||
GenericName=Viewer for E-books
|
GenericName=Viewer for E-books
|
||||||
Comment=Viewer for E-books
|
Comment=Viewer for E-books
|
||||||
TryExec=ebook-viewer
|
TryExec=ebook-viewer
|
||||||
Exec=ebook-viewer %%F
|
Exec=ebook-viewer %F
|
||||||
Icon=calibre-viewer
|
Icon=calibre-viewer
|
||||||
MimeType=application/epub+zip;
|
MimeType=application/epub+zip;
|
||||||
Categories=Graphics;Viewer;
|
Categories=Graphics;Viewer;
|
||||||
'''%(__version__,)
|
'''
|
||||||
|
|
||||||
|
|
||||||
GUI = '''\
|
GUI = '''\
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Version=%s
|
Version=1.0
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=calibre
|
Name=calibre
|
||||||
GenericName=E-book library management
|
GenericName=E-book library management
|
||||||
@ -529,7 +529,7 @@ TryExec=calibre
|
|||||||
Exec=calibre
|
Exec=calibre
|
||||||
Icon=calibre-gui
|
Icon=calibre-gui
|
||||||
Categories=Office;
|
Categories=Office;
|
||||||
'''%(__version__,)
|
'''
|
||||||
|
|
||||||
MIME = '''\
|
MIME = '''\
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
#
|
#
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: calibre 0.6.18\n"
|
"Project-Id-Version: calibre 0.6.19\n"
|
||||||
"POT-Creation-Date: 2009-10-20 17:23+MDT\n"
|
"POT-Creation-Date: 2009-10-20 18:49+MDT\n"
|
||||||
"PO-Revision-Date: 2009-10-20 17:23+MDT\n"
|
"PO-Revision-Date: 2009-10-20 18:49+MDT\n"
|
||||||
"Last-Translator: Automatically generated\n"
|
"Last-Translator: Automatically generated\n"
|
||||||
"Language-Team: LANGUAGE\n"
|
"Language-Team: LANGUAGE\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -5243,7 +5243,7 @@ msgstr ""
|
|||||||
msgid "No matches found for this book"
|
msgid "No matches found for this book"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:60
|
#: /home/kovid/work/calibre/src/calibre/gui2/search_box.py:71
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
You should have received a copy of the GNU Lesser General Public
|
You should have received a copy of the GNU Lesser General Public
|
||||||
License along with this library; if not, write to the Free Software
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
'''0.12 update - allow selection of binding interface
|
'''0.12 update - allow selection of binding interface
|
||||||
@ -101,7 +101,7 @@ _LISTENER_TIME = 200
|
|||||||
_BROWSER_TIME = 500
|
_BROWSER_TIME = 500
|
||||||
|
|
||||||
# Some DNS constants
|
# Some DNS constants
|
||||||
|
|
||||||
_MDNS_ADDR = '224.0.0.251'
|
_MDNS_ADDR = '224.0.0.251'
|
||||||
_MDNS_PORT = 5353;
|
_MDNS_PORT = 5353;
|
||||||
_DNS_PORT = 53;
|
_DNS_PORT = 53;
|
||||||
@ -208,7 +208,7 @@ class BadTypeInNameException(Exception):
|
|||||||
|
|
||||||
class DNSEntry(object):
|
class DNSEntry(object):
|
||||||
'''A DNS entry'''
|
'''A DNS entry'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz):
|
def __init__(self, name, type, clazz):
|
||||||
self.key = string.lower(name)
|
self.key = string.lower(name)
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -256,10 +256,10 @@ class DNSEntry(object):
|
|||||||
|
|
||||||
class DNSQuestion(DNSEntry):
|
class DNSQuestion(DNSEntry):
|
||||||
'''A DNS question entry'''
|
'''A DNS question entry'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz):
|
def __init__(self, name, type, clazz):
|
||||||
if not name.endswith('.local.'):
|
if not name.endswith('.local.'):
|
||||||
raise NonLocalNameException
|
raise NonLocalNameException('DNSQuestion: Not a local name '+name)
|
||||||
DNSEntry.__init__(self, name, type, clazz)
|
DNSEntry.__init__(self, name, type, clazz)
|
||||||
|
|
||||||
def answeredBy(self, rec):
|
def answeredBy(self, rec):
|
||||||
@ -273,7 +273,7 @@ class DNSQuestion(DNSEntry):
|
|||||||
|
|
||||||
class DNSRecord(DNSEntry):
|
class DNSRecord(DNSEntry):
|
||||||
'''A DNS record - like a DNS entry, but has a TTL'''
|
'''A DNS record - like a DNS entry, but has a TTL'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz, ttl):
|
def __init__(self, name, type, clazz, ttl):
|
||||||
DNSEntry.__init__(self, name, type, clazz)
|
DNSEntry.__init__(self, name, type, clazz)
|
||||||
self.ttl = ttl
|
self.ttl = ttl
|
||||||
@ -334,7 +334,7 @@ class DNSRecord(DNSEntry):
|
|||||||
|
|
||||||
class DNSAddress(DNSRecord):
|
class DNSAddress(DNSRecord):
|
||||||
'''A DNS address record'''
|
'''A DNS address record'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz, ttl, address):
|
def __init__(self, name, type, clazz, ttl, address):
|
||||||
DNSRecord.__init__(self, name, type, clazz, ttl)
|
DNSRecord.__init__(self, name, type, clazz, ttl)
|
||||||
self.address = address
|
self.address = address
|
||||||
@ -378,10 +378,10 @@ class DNSHinfo(DNSRecord):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
'''String representation'''
|
'''String representation'''
|
||||||
return self.cpu + ' ' + self.os
|
return self.cpu + ' ' + self.os
|
||||||
|
|
||||||
class DNSPointer(DNSRecord):
|
class DNSPointer(DNSRecord):
|
||||||
'''A DNS pointer record'''
|
'''A DNS pointer record'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz, ttl, alias):
|
def __init__(self, name, type, clazz, ttl, alias):
|
||||||
DNSRecord.__init__(self, name, type, clazz, ttl)
|
DNSRecord.__init__(self, name, type, clazz, ttl)
|
||||||
self.alias = alias
|
self.alias = alias
|
||||||
@ -402,7 +402,7 @@ class DNSPointer(DNSRecord):
|
|||||||
|
|
||||||
class DNSText(DNSRecord):
|
class DNSText(DNSRecord):
|
||||||
'''A DNS text record'''
|
'''A DNS text record'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz, ttl, text):
|
def __init__(self, name, type, clazz, ttl, text):
|
||||||
DNSRecord.__init__(self, name, type, clazz, ttl)
|
DNSRecord.__init__(self, name, type, clazz, ttl)
|
||||||
self.text = text
|
self.text = text
|
||||||
@ -426,7 +426,7 @@ class DNSText(DNSRecord):
|
|||||||
|
|
||||||
class DNSService(DNSRecord):
|
class DNSService(DNSRecord):
|
||||||
'''A DNS service record'''
|
'''A DNS service record'''
|
||||||
|
|
||||||
def __init__(self, name, type, clazz, ttl, priority, weight, port, server):
|
def __init__(self, name, type, clazz, ttl, priority, weight, port, server):
|
||||||
DNSRecord.__init__(self, name, type, clazz, ttl)
|
DNSRecord.__init__(self, name, type, clazz, ttl)
|
||||||
self.priority = priority
|
self.priority = priority
|
||||||
@ -453,7 +453,7 @@ class DNSService(DNSRecord):
|
|||||||
|
|
||||||
class DNSIncoming(object):
|
class DNSIncoming(object):
|
||||||
'''Object representation of an incoming DNS packet'''
|
'''Object representation of an incoming DNS packet'''
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
'''Constructor from string holding bytes of packet'''
|
'''Constructor from string holding bytes of packet'''
|
||||||
self.offset = 0
|
self.offset = 0
|
||||||
@ -464,7 +464,7 @@ class DNSIncoming(object):
|
|||||||
self.numAnswers = 0
|
self.numAnswers = 0
|
||||||
self.numAuthorities = 0
|
self.numAuthorities = 0
|
||||||
self.numAdditionals = 0
|
self.numAdditionals = 0
|
||||||
|
|
||||||
self.readHeader()
|
self.readHeader()
|
||||||
self.readQuestions()
|
self.readQuestions()
|
||||||
self.readOthers()
|
self.readOthers()
|
||||||
@ -491,7 +491,7 @@ class DNSIncoming(object):
|
|||||||
name = self.readName()
|
name = self.readName()
|
||||||
info = struct.unpack(format, self.data[self.offset:self.offset+length])
|
info = struct.unpack(format, self.data[self.offset:self.offset+length])
|
||||||
self.offset += length
|
self.offset += length
|
||||||
|
|
||||||
question = DNSQuestion(name, info[0], info[1])
|
question = DNSQuestion(name, info[0], info[1])
|
||||||
self.questions.append(question)
|
self.questions.append(question)
|
||||||
|
|
||||||
@ -561,7 +561,7 @@ class DNSIncoming(object):
|
|||||||
|
|
||||||
if rec is not None:
|
if rec is not None:
|
||||||
self.answers.append(rec)
|
self.answers.append(rec)
|
||||||
|
|
||||||
def isQuery(self):
|
def isQuery(self):
|
||||||
'''Returns true if this is a query'''
|
'''Returns true if this is a query'''
|
||||||
return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
|
return (self.flags & _FLAGS_QR_MASK) == _FLAGS_QR_QUERY
|
||||||
@ -574,7 +574,7 @@ class DNSIncoming(object):
|
|||||||
'''Reads a UTF-8 string of a given length from the packet'''
|
'''Reads a UTF-8 string of a given length from the packet'''
|
||||||
result = self.data[offset:offset+len].decode('utf-8')
|
result = self.data[offset:offset+len].decode('utf-8')
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def readName(self):
|
def readName(self):
|
||||||
'''Reads a domain name from the packet'''
|
'''Reads a domain name from the packet'''
|
||||||
result = ''
|
result = ''
|
||||||
@ -607,11 +607,11 @@ class DNSIncoming(object):
|
|||||||
self.offset = off
|
self.offset = off
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class DNSOutgoing(object):
|
class DNSOutgoing(object):
|
||||||
'''Object representation of an outgoing packet'''
|
'''Object representation of an outgoing packet'''
|
||||||
|
|
||||||
def __init__(self, flags, multicast = 1):
|
def __init__(self, flags, multicast = 1):
|
||||||
self.finished = 0
|
self.finished = 0
|
||||||
self.id = 0
|
self.id = 0
|
||||||
@ -620,7 +620,7 @@ class DNSOutgoing(object):
|
|||||||
self.names = {}
|
self.names = {}
|
||||||
self.data = []
|
self.data = []
|
||||||
self.size = 12
|
self.size = 12
|
||||||
|
|
||||||
self.questions = []
|
self.questions = []
|
||||||
self.answers = []
|
self.answers = []
|
||||||
self.authorities = []
|
self.authorities = []
|
||||||
@ -660,7 +660,7 @@ class DNSOutgoing(object):
|
|||||||
format = '!H'
|
format = '!H'
|
||||||
self.data.insert(index, struct.pack(format, value))
|
self.data.insert(index, struct.pack(format, value))
|
||||||
self.size += 2
|
self.size += 2
|
||||||
|
|
||||||
def writeShort(self, value):
|
def writeShort(self, value):
|
||||||
'''Writes an unsigned short to the packet'''
|
'''Writes an unsigned short to the packet'''
|
||||||
format = '!H'
|
format = '!H'
|
||||||
@ -739,7 +739,7 @@ class DNSOutgoing(object):
|
|||||||
self.size += 2
|
self.size += 2
|
||||||
record.write(self)
|
record.write(self)
|
||||||
self.size -= 2
|
self.size -= 2
|
||||||
|
|
||||||
length = len(''.join(self.data[index:]))
|
length = len(''.join(self.data[index:]))
|
||||||
self.insertShort(index, length) # Here is the short we adjusted for
|
self.insertShort(index, length) # Here is the short we adjusted for
|
||||||
|
|
||||||
@ -758,7 +758,7 @@ class DNSOutgoing(object):
|
|||||||
self.writeRecord(authority, 0)
|
self.writeRecord(authority, 0)
|
||||||
for additional in self.additionals:
|
for additional in self.additionals:
|
||||||
self.writeRecord(additional, 0)
|
self.writeRecord(additional, 0)
|
||||||
|
|
||||||
self.insertShort(0, len(self.additionals))
|
self.insertShort(0, len(self.additionals))
|
||||||
self.insertShort(0, len(self.authorities))
|
self.insertShort(0, len(self.authorities))
|
||||||
self.insertShort(0, len(self.answers))
|
self.insertShort(0, len(self.answers))
|
||||||
@ -773,7 +773,7 @@ class DNSOutgoing(object):
|
|||||||
|
|
||||||
class DNSCache(object):
|
class DNSCache(object):
|
||||||
'''A cache of DNS entries'''
|
'''A cache of DNS entries'''
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.cache = {}
|
self.cache = {}
|
||||||
|
|
||||||
@ -856,11 +856,17 @@ class Engine(threading.Thread):
|
|||||||
self.condition.wait(self.timeout)
|
self.condition.wait(self.timeout)
|
||||||
self.condition.release()
|
self.condition.release()
|
||||||
else:
|
else:
|
||||||
|
from calibre.constants import DEBUG
|
||||||
try:
|
try:
|
||||||
rr, wr, er = select.select(rs, [], [], self.timeout)
|
rr, wr, er = select.select(rs, [], [], self.timeout)
|
||||||
for socket in rr:
|
for socket in rr:
|
||||||
try:
|
try:
|
||||||
self.readers[socket].handle_read()
|
self.readers[socket].handle_read()
|
||||||
|
except NonLocalNameException, err:
|
||||||
|
print err
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
if DEBUG:
|
||||||
|
traceback.print_exc()
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
except:
|
except:
|
||||||
@ -872,7 +878,7 @@ class Engine(threading.Thread):
|
|||||||
result = self.readers.keys()
|
result = self.readers.keys()
|
||||||
self.condition.release()
|
self.condition.release()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def addReader(self, reader, socket):
|
def addReader(self, reader, socket):
|
||||||
self.condition.acquire()
|
self.condition.acquire()
|
||||||
self.readers[socket] = reader
|
self.readers[socket] = reader
|
||||||
@ -897,7 +903,7 @@ class Listener(object):
|
|||||||
|
|
||||||
It requires registration with an Engine object in order to have
|
It requires registration with an Engine object in order to have
|
||||||
the read() method called when a socket is availble for reading.'''
|
the read() method called when a socket is availble for reading.'''
|
||||||
|
|
||||||
def __init__(self, zeroconf):
|
def __init__(self, zeroconf):
|
||||||
self.zeroconf = zeroconf
|
self.zeroconf = zeroconf
|
||||||
self.zeroconf.engine.addReader(self, self.zeroconf.socket)
|
self.zeroconf.engine.addReader(self, self.zeroconf.socket)
|
||||||
@ -924,7 +930,7 @@ class Listener(object):
|
|||||||
class Reaper(threading.Thread):
|
class Reaper(threading.Thread):
|
||||||
'''A Reaper is used by this module to remove cache entries that
|
'''A Reaper is used by this module to remove cache entries that
|
||||||
have expired.'''
|
have expired.'''
|
||||||
|
|
||||||
def __init__(self, zeroconf):
|
def __init__(self, zeroconf):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.zeroconf = zeroconf
|
self.zeroconf = zeroconf
|
||||||
@ -953,7 +959,7 @@ class ServiceBrowser(threading.Thread):
|
|||||||
The listener object will have its addService() and
|
The listener object will have its addService() and
|
||||||
removeService() methods called when this browser
|
removeService() methods called when this browser
|
||||||
discovers changes in the services availability.'''
|
discovers changes in the services availability.'''
|
||||||
|
|
||||||
def __init__(self, zeroconf, type, listener):
|
def __init__(self, zeroconf, type, listener):
|
||||||
'''Creates a browser for a specific type'''
|
'''Creates a browser for a specific type'''
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
@ -964,7 +970,7 @@ class ServiceBrowser(threading.Thread):
|
|||||||
self.nextTime = currentTimeMillis()
|
self.nextTime = currentTimeMillis()
|
||||||
self.delay = _BROWSER_TIME
|
self.delay = _BROWSER_TIME
|
||||||
self.list = []
|
self.list = []
|
||||||
|
|
||||||
self.done = 0
|
self.done = 0
|
||||||
|
|
||||||
self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
|
self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, _CLASS_IN))
|
||||||
@ -1024,12 +1030,12 @@ class ServiceBrowser(threading.Thread):
|
|||||||
|
|
||||||
if event is not None:
|
if event is not None:
|
||||||
event(self.zeroconf)
|
event(self.zeroconf)
|
||||||
|
|
||||||
|
|
||||||
class ServiceInfo(object):
|
class ServiceInfo(object):
|
||||||
'''Service information'''
|
'''Service information'''
|
||||||
|
|
||||||
def __init__(self, type, name, address=None, port=None, weight=0,
|
def __init__(self, type, name, address=None, port=None, weight=0,
|
||||||
priority=0, properties=None, server=None):
|
priority=0, properties=None, server=None):
|
||||||
'''Create a service description.
|
'''Create a service description.
|
||||||
|
|
||||||
@ -1095,7 +1101,7 @@ class ServiceInfo(object):
|
|||||||
index += 1
|
index += 1
|
||||||
strs.append(text[index:index+length])
|
strs.append(text[index:index+length])
|
||||||
index += length
|
index += length
|
||||||
|
|
||||||
for s in strs:
|
for s in strs:
|
||||||
eindex = s.find('=')
|
eindex = s.find('=')
|
||||||
if eindex == -1:
|
if eindex == -1:
|
||||||
@ -1118,7 +1124,7 @@ class ServiceInfo(object):
|
|||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
self.properties = None
|
self.properties = None
|
||||||
|
|
||||||
def getType(self):
|
def getType(self):
|
||||||
'''Type accessor'''
|
'''Type accessor'''
|
||||||
return self.type
|
return self.type
|
||||||
@ -1208,7 +1214,7 @@ class ServiceInfo(object):
|
|||||||
result = 1
|
result = 1
|
||||||
finally:
|
finally:
|
||||||
zeroconf.removeListener(self)
|
zeroconf.removeListener(self)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
@ -1233,7 +1239,7 @@ class ServiceInfo(object):
|
|||||||
result += self.text[:17] + '...'
|
result += self.text[:17] + '...'
|
||||||
result += ']'
|
result += ']'
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class Zeroconf(object):
|
class Zeroconf(object):
|
||||||
'''Implementation of Zeroconf Multicast DNS Service Discovery
|
'''Implementation of Zeroconf Multicast DNS Service Discovery
|
||||||
@ -1273,7 +1279,7 @@ class Zeroconf(object):
|
|||||||
# the SO_REUSE* options have been set, so ignore it
|
# the SO_REUSE* options have been set, so ignore it
|
||||||
#
|
#
|
||||||
pass
|
pass
|
||||||
#self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.intf) + socket.inet_aton('0.0.0.0'))
|
#self.socket.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(self.intf) + socket.inet_aton('0.0.0.0'))
|
||||||
self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
|
self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
|
||||||
|
|
||||||
self.listeners = []
|
self.listeners = []
|
||||||
@ -1284,7 +1290,7 @@ class Zeroconf(object):
|
|||||||
self.cache = DNSCache()
|
self.cache = DNSCache()
|
||||||
|
|
||||||
self.condition = threading.Condition()
|
self.condition = threading.Condition()
|
||||||
|
|
||||||
self.engine = Engine(self)
|
self.engine = Engine(self)
|
||||||
self.listener = Listener(self)
|
self.listener = Listener(self)
|
||||||
self.reaper = Reaper(self)
|
self.reaper = Reaper(self)
|
||||||
@ -1479,7 +1485,7 @@ class Zeroconf(object):
|
|||||||
record = entry
|
record = entry
|
||||||
else:
|
else:
|
||||||
self.cache.add(record)
|
self.cache.add(record)
|
||||||
|
|
||||||
self.updateRecord(now, record)
|
self.updateRecord(now, record)
|
||||||
|
|
||||||
def handleQuery(self, msg, addr, port):
|
def handleQuery(self, msg, addr, port):
|
||||||
@ -1493,14 +1499,14 @@ class Zeroconf(object):
|
|||||||
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, 0)
|
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA, 0)
|
||||||
for question in msg.questions:
|
for question in msg.questions:
|
||||||
out.addQuestion(question)
|
out.addQuestion(question)
|
||||||
|
|
||||||
for question in msg.questions:
|
for question in msg.questions:
|
||||||
if question.type == _TYPE_PTR:
|
if question.type == _TYPE_PTR:
|
||||||
if question.name == '_services._dns-sd._udp.local.':
|
if question.name == '_services._dns-sd._udp.local.':
|
||||||
for stype in self.servicetypes.keys():
|
for stype in self.servicetypes.keys():
|
||||||
if out is None:
|
if out is None:
|
||||||
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
|
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
|
||||||
out.addAnswer(msg, DNSPointer('_services._dns-sd._udp.local.', _TYPE_PTR, _CLASS_IN, _DNS_TTL, stype))
|
out.addAnswer(msg, DNSPointer('_services._dns-sd._udp.local.', _TYPE_PTR, _CLASS_IN, _DNS_TTL, stype))
|
||||||
for service in self.services.values():
|
for service in self.services.values():
|
||||||
if question.name == service.type:
|
if question.name == service.type:
|
||||||
if out is None:
|
if out is None:
|
||||||
@ -1510,16 +1516,16 @@ class Zeroconf(object):
|
|||||||
try:
|
try:
|
||||||
if out is None:
|
if out is None:
|
||||||
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
|
out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA)
|
||||||
|
|
||||||
# Answer A record queries for any service addresses we know
|
# Answer A record queries for any service addresses we know
|
||||||
if question.type == _TYPE_A or question.type == _TYPE_ANY:
|
if question.type == _TYPE_A or question.type == _TYPE_ANY:
|
||||||
for service in self.services.values():
|
for service in self.services.values():
|
||||||
if service.server == question.name.lower():
|
if service.server == question.name.lower():
|
||||||
out.addAnswer(msg, DNSAddress(question.name, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
|
out.addAnswer(msg, DNSAddress(question.name, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
|
||||||
|
|
||||||
service = self.services.get(question.name.lower(), None)
|
service = self.services.get(question.name.lower(), None)
|
||||||
if not service: continue
|
if not service: continue
|
||||||
|
|
||||||
if question.type == _TYPE_SRV or question.type == _TYPE_ANY:
|
if question.type == _TYPE_SRV or question.type == _TYPE_ANY:
|
||||||
out.addAnswer(msg, DNSService(question.name, _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.priority, service.weight, service.port, service.server))
|
out.addAnswer(msg, DNSService(question.name, _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.priority, service.weight, service.port, service.server))
|
||||||
if question.type == _TYPE_TXT or question.type == _TYPE_ANY:
|
if question.type == _TYPE_TXT or question.type == _TYPE_ANY:
|
||||||
@ -1528,7 +1534,7 @@ class Zeroconf(object):
|
|||||||
out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
|
out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address))
|
||||||
except:
|
except:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
if out is not None and out.answers:
|
if out is not None and out.answers:
|
||||||
out.id = msg.id
|
out.id = msg.id
|
||||||
self.send(out, addr, port)
|
self.send(out, addr, port)
|
||||||
@ -1553,11 +1559,11 @@ class Zeroconf(object):
|
|||||||
self.unregisterAllServices()
|
self.unregisterAllServices()
|
||||||
self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
|
self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0'))
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
|
|
||||||
# Test a few module features, including service registration, service
|
# Test a few module features, including service registration, service
|
||||||
# query (for Zoe), and service unregistration.
|
# query (for Zoe), and service unregistration.
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print 'Multicast DNS Service Discovery for Python, version', __version__
|
print 'Multicast DNS Service Discovery for Python, version', __version__
|
||||||
r = Zeroconf()
|
r = Zeroconf()
|
||||||
print '1. Testing registration of a service...'
|
print '1. Testing registration of a service...'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user