Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
gajim
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Weblate
gajim
Commits
541167aa
Commit
541167aa
authored
16 years ago
by
steve-e
Browse files
Options
Downloads
Patches
Plain Diff
Move IdleCommand from resolver.py to idlequeue.py
parent
0f612605
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/common/resolver.py
+14
-120
14 additions, 120 deletions
src/common/resolver.py
src/common/xmpp/idlequeue.py
+112
-0
112 additions, 0 deletions
src/common/xmpp/idlequeue.py
with
126 additions
and
120 deletions
src/common/resolver.py
+
14
−
120
View file @
541167aa
...
@@ -20,14 +20,10 @@
...
@@ -20,14 +20,10 @@
import
sys
import
sys
import
os
import
os
import
re
import
re
import
logging
log
=
logging
.
getLogger
(
'
gajim.c.resolver
'
)
from
xmpp.idlequeue
import
*
from
xmpp.idlequeue
import
IdleCommand
# needed for nslookup
if
os
.
name
==
'
nt
'
:
from
subprocess
import
*
# python24 only. we ask this for Windows
elif
os
.
name
==
'
posix
'
:
import
fcntl
# it is good to check validity of arguments, when calling system commands
# it is good to check validity of arguments, when calling system commands
ns_type_pattern
=
re
.
compile
(
'
^[a-z]+$
'
)
ns_type_pattern
=
re
.
compile
(
'
^[a-z]+$
'
)
...
@@ -35,14 +31,13 @@ ns_type_pattern = re.compile('^[a-z]+$')
...
@@ -35,14 +31,13 @@ ns_type_pattern = re.compile('^[a-z]+$')
# match srv host_name
# match srv host_name
host_pattern
=
re
.
compile
(
'
^[a-z0-9\-._]*[a-z0-9]\.[a-z]{2,}$
'
)
host_pattern
=
re
.
compile
(
'
^[a-z0-9\-._]*[a-z0-9]\.[a-z]{2,}$
'
)
USE_LIBASYNCNS
=
False
try
:
try
:
#raise ImportError("Manually disabled libasync")
#raise ImportError("Manually disabled libasync")
import
libasyncns
import
libasyncns
USE_LIBASYNCNS
=
True
USE_LIBASYNCNS
=
True
log
.
info
(
"
libasyncns-python loaded
"
)
log
.
info
(
"
libasyncns-python loaded
"
)
except
ImportError
:
except
ImportError
:
USE_LIBASYNCNS
=
False
log
.
debug
(
"
Import of libasyncns-python failed, getaddrinfo will block
"
,
exc_info
=
True
)
log
.
debug
(
"
Import of libasyncns-python failed, getaddrinfo will block
"
,
exc_info
=
True
)
# FIXME: Remove these prints before release, replace with a warning dialog.
# FIXME: Remove these prints before release, replace with a warning dialog.
...
@@ -98,11 +93,11 @@ class CommonResolver():
...
@@ -98,11 +93,11 @@ class CommonResolver():
def
start_resolve
(
self
,
host
,
type
):
def
start_resolve
(
self
,
host
,
type
):
pass
pass
# FIXME: API usage is not consistent! This one requires that process is called
class
LibAsyncNSResolver
(
CommonResolver
):
class
LibAsyncNSResolver
(
CommonResolver
):
'''
'''
Asynchronous resolver using libasyncns-python. process() method has to be
called
Asynchronous resolver using libasyncns-python. process() method has to be
in order to proceed the pending requests.
called
in order to proceed the pending requests.
Based on patch submitted by Damien Thebault.
Based on patch submitted by Damien Thebault.
'''
'''
def
__init__
(
self
):
def
__init__
(
self
):
...
@@ -126,7 +121,6 @@ class LibAsyncNSResolver(CommonResolver):
...
@@ -126,7 +121,6 @@ class LibAsyncNSResolver(CommonResolver):
CommonResolver
.
_on_ready
(
self
,
host
,
type
,
result_list
)
CommonResolver
.
_on_ready
(
self
,
host
,
type
,
result_list
)
def
process
(
self
):
def
process
(
self
):
try
:
try
:
self
.
asyncns
.
wait
(
False
)
self
.
asyncns
.
wait
(
False
)
...
@@ -157,6 +151,7 @@ class LibAsyncNSResolver(CommonResolver):
...
@@ -157,6 +151,7 @@ class LibAsyncNSResolver(CommonResolver):
resq
.
userdata
[
'
callback
'
](
resq
.
userdata
[
'
dname
'
],
rl
)
resq
.
userdata
[
'
callback
'
](
resq
.
userdata
[
'
dname
'
],
rl
)
return
True
return
True
class
NSLookupResolver
(
CommonResolver
):
class
NSLookupResolver
(
CommonResolver
):
'''
'''
Asynchronous DNS resolver calling nslookup. Processing of pending requests
Asynchronous DNS resolver calling nslookup. Processing of pending requests
...
@@ -264,112 +259,14 @@ class NSLookupResolver(CommonResolver):
...
@@ -264,112 +259,14 @@ class NSLookupResolver(CommonResolver):
result_list
=
self
.
parse_srv_result
(
host
,
result
)
result_list
=
self
.
parse_srv_result
(
host
,
result
)
CommonResolver
.
_on_ready
(
self
,
host
,
type
,
result_list
)
CommonResolver
.
_on_ready
(
self
,
host
,
type
,
result_list
)
def
start_resolve
(
self
,
host
,
type
):
def
start_resolve
(
self
,
host
,
type
):
'''
spawn new nslookup process and start waiting for results
'''
'''
spawn new nslookup process and start waiting for results
'''
ns
=
NsLookup
(
self
.
_on_ready
,
host
,
type
)
ns
=
NsLookup
(
self
.
_on_ready
,
host
,
type
)
ns
.
set_idlequeue
(
self
.
idlequeue
)
ns
.
set_idlequeue
(
self
.
idlequeue
)
ns
.
commandtimeout
=
10
ns
.
commandtimeout
=
10
ns
.
start
()
ns
.
start
()
# TODO: move IdleCommand class in other file, maybe helpers ?
class
IdleCommand
(
IdleObject
):
def
__init__
(
self
,
on_result
):
# how long (sec.) to wait for result ( 0 - forever )
# it is a class var, instead of a constant and we can override it.
self
.
commandtimeout
=
0
# when we have some kind of result (valid, ot not) we call this handler
self
.
result_handler
=
on_result
# if it is True, we can safetely execute the command
self
.
canexecute
=
True
self
.
idlequeue
=
None
self
.
result
=
''
def
set_idlequeue
(
self
,
idlequeue
):
self
.
idlequeue
=
idlequeue
def
_return_result
(
self
):
if
self
.
result_handler
:
self
.
result_handler
(
self
.
result
)
self
.
result_handler
=
None
def
_compose_command_args
(
self
):
return
[
'
echo
'
,
'
da
'
]
def
_compose_command_line
(
self
):
'''
return one line representation of command and its arguments
'''
return
reduce
(
lambda
left
,
right
:
left
+
'
'
+
right
,
self
.
_compose_command_args
())
def
wait_child
(
self
):
if
self
.
pipe
.
poll
()
is
None
:
# result timeout
if
self
.
endtime
<
self
.
idlequeue
.
current_time
():
self
.
_return_result
()
self
.
pipe
.
stdout
.
close
()
self
.
pipe
.
stdin
.
close
()
else
:
# child is still active, continue to wait
self
.
idlequeue
.
set_alarm
(
self
.
wait_child
,
0.1
)
else
:
# child has quit
self
.
result
=
self
.
pipe
.
stdout
.
read
()
self
.
_return_result
()
self
.
pipe
.
stdout
.
close
()
self
.
pipe
.
stdin
.
close
()
def
start
(
self
):
if
not
self
.
canexecute
:
self
.
result
=
''
self
.
_return_result
()
return
if
os
.
name
==
'
nt
'
:
self
.
_start_nt
()
elif
os
.
name
==
'
posix
'
:
self
.
_start_posix
()
def
_start_nt
(
self
):
# if gajim is started from noninteraactive shells stdin is closed and
# cannot be forwarded, so we have to keep it open
self
.
pipe
=
Popen
(
self
.
_compose_command_args
(),
stdout
=
PIPE
,
bufsize
=
1024
,
shell
=
True
,
stderr
=
STDOUT
,
stdin
=
PIPE
)
if
self
.
commandtimeout
>=
0
:
self
.
endtime
=
self
.
idlequeue
.
current_time
()
+
self
.
commandtimeout
self
.
idlequeue
.
set_alarm
(
self
.
wait_child
,
0.1
)
def
_start_posix
(
self
):
self
.
pipe
=
os
.
popen
(
self
.
_compose_command_line
())
self
.
fd
=
self
.
pipe
.
fileno
()
fcntl
.
fcntl
(
self
.
pipe
,
fcntl
.
F_SETFL
,
os
.
O_NONBLOCK
)
self
.
idlequeue
.
plug_idle
(
self
,
False
,
True
)
if
self
.
commandtimeout
>=
0
:
self
.
idlequeue
.
set_read_timeout
(
self
.
fd
,
self
.
commandtimeout
)
def
end
(
self
):
self
.
idlequeue
.
unplug_idle
(
self
.
fd
)
try
:
self
.
pipe
.
close
()
except
:
pass
def
pollend
(
self
):
self
.
idlequeue
.
remove_timeout
(
self
.
fd
)
self
.
end
()
self
.
_return_result
()
def
pollin
(
self
):
try
:
res
=
self
.
pipe
.
read
()
except
Exception
,
e
:
res
=
''
if
res
==
''
:
return
self
.
pollend
()
else
:
self
.
result
+=
res
def
read_timeout
(
self
):
self
.
end
()
self
.
_return_result
()
class
NsLookup
(
IdleCommand
):
class
NsLookup
(
IdleCommand
):
def
__init__
(
self
,
on_result
,
host
=
'
_xmpp-client
'
,
type
=
'
srv
'
):
def
__init__
(
self
,
on_result
,
host
=
'
_xmpp-client
'
,
type
=
'
srv
'
):
IdleCommand
.
__init__
(
self
,
on_result
)
IdleCommand
.
__init__
(
self
,
on_result
)
...
@@ -378,11 +275,11 @@ class NsLookup(IdleCommand):
...
@@ -378,11 +275,11 @@ class NsLookup(IdleCommand):
self
.
type
=
type
.
lower
()
self
.
type
=
type
.
lower
()
if
not
host_pattern
.
match
(
self
.
host
):
if
not
host_pattern
.
match
(
self
.
host
):
# invalid host name
# invalid host name
print
>>
sys
.
stderr
,
'
Invalid host: %s
'
%
self
.
host
log
.
error
(
'
Invalid host: %s
'
%
self
.
host
)
self
.
canexecute
=
False
self
.
canexecute
=
False
return
return
if
not
ns_type_pattern
.
match
(
self
.
type
):
if
not
ns_type_pattern
.
match
(
self
.
type
):
print
>>
sys
.
stderr
,
'
Invalid querytype: %s
'
%
self
.
type
log
.
error
(
'
Invalid querytype: %s
'
%
self
.
type
)
self
.
canexecute
=
False
self
.
canexecute
=
False
return
return
...
@@ -396,15 +293,12 @@ class NsLookup(IdleCommand):
...
@@ -396,15 +293,12 @@ class NsLookup(IdleCommand):
# below lines is on how to use API and assist in testing
# below lines is on how to use API and assist in testing
if
__name__
==
'
__main__
'
:
if
__name__
==
'
__main__
'
:
if
os
.
name
==
'
posix
'
:
idlequeue
=
IdleQueue
()
elif
os
.
name
==
'
nt
'
:
idlequeue
=
SelectIdleQueue
()
# testing Resolver class
import
gobject
import
gobject
import
gtk
import
gtk
from
xmpp
import
idlequeue
resolver
=
Resolver
(
idlequeue
)
idlequeue
=
idlequeue
.
get_idlequeue
()
resolver
=
get_resolver
(
idlequeue
)
def
clicked
(
widget
):
def
clicked
(
widget
):
global
resolver
global
resolver
...
...
This diff is collapsed.
Click to expand it.
src/common/xmpp/idlequeue.py
+
112
−
0
View file @
541167aa
...
@@ -20,12 +20,19 @@ import os
...
@@ -20,12 +20,19 @@ import os
import
select
import
select
import
logging
import
logging
log
=
logging
.
getLogger
(
'
gajim.c.x.idlequeue
'
)
log
=
logging
.
getLogger
(
'
gajim.c.x.idlequeue
'
)
# needed for get_idleqeue
try
:
try
:
import
gobject
import
gobject
HAVE_GOBJECT
=
True
HAVE_GOBJECT
=
True
except
ImportError
:
except
ImportError
:
HAVE_GOBJECT
=
False
HAVE_GOBJECT
=
False
# needed for idlecommand
if
os
.
name
==
'
nt
'
:
from
subprocess
import
*
# python24 only. we ask this for Windows
elif
os
.
name
==
'
posix
'
:
import
fcntl
FLAG_WRITE
=
20
# write only
FLAG_WRITE
=
20
# write only
FLAG_READ
=
19
# read only
FLAG_READ
=
19
# read only
...
@@ -36,6 +43,7 @@ PENDING_READ = 3 # waiting read event
...
@@ -36,6 +43,7 @@ PENDING_READ = 3 # waiting read event
PENDING_WRITE
=
4
# waiting write event
PENDING_WRITE
=
4
# waiting write event
IS_CLOSED
=
16
# channel closed
IS_CLOSED
=
16
# channel closed
def
get_idlequeue
():
def
get_idlequeue
():
'''
Get an appropriate idlequeue
'''
'''
Get an appropriate idlequeue
'''
if
os
.
name
==
'
nt
'
:
if
os
.
name
==
'
nt
'
:
...
@@ -74,6 +82,110 @@ class IdleObject:
...
@@ -74,6 +82,110 @@ class IdleObject:
pass
pass
class
IdleCommand
(
IdleObject
):
'''
Can be subclassed to execute commands asynchronously by the idlequeue.
Result will be optained via file descriptor of created pipe
'''
def
__init__
(
self
,
on_result
):
IdleObject
.
__init__
(
self
)
# how long (sec.) to wait for result ( 0 - forever )
# it is a class var, instead of a constant and we can override it.
self
.
commandtimeout
=
0
# when we have some kind of result (valid, ot not) we call this handler
self
.
result_handler
=
on_result
# if it is True, we can safetely execute the command
self
.
canexecute
=
True
self
.
idlequeue
=
None
self
.
result
=
''
def
set_idlequeue
(
self
,
idlequeue
):
self
.
idlequeue
=
idlequeue
def
_return_result
(
self
):
if
self
.
result_handler
:
self
.
result_handler
(
self
.
result
)
self
.
result_handler
=
None
def
_compose_command_args
(
self
):
return
[
'
echo
'
,
'
da
'
]
def
_compose_command_line
(
self
):
'''
return one line representation of command and its arguments
'''
return
reduce
(
lambda
left
,
right
:
left
+
'
'
+
right
,
self
.
_compose_command_args
())
def
wait_child
(
self
):
if
self
.
pipe
.
poll
()
is
None
:
# result timeout
if
self
.
endtime
<
self
.
idlequeue
.
current_time
():
self
.
_return_result
()
self
.
pipe
.
stdout
.
close
()
self
.
pipe
.
stdin
.
close
()
else
:
# child is still active, continue to wait
self
.
idlequeue
.
set_alarm
(
self
.
wait_child
,
0.1
)
else
:
# child has quit
self
.
result
=
self
.
pipe
.
stdout
.
read
()
self
.
_return_result
()
self
.
pipe
.
stdout
.
close
()
self
.
pipe
.
stdin
.
close
()
def
start
(
self
):
if
not
self
.
canexecute
:
self
.
result
=
''
self
.
_return_result
()
return
if
os
.
name
==
'
nt
'
:
self
.
_start_nt
()
elif
os
.
name
==
'
posix
'
:
self
.
_start_posix
()
def
_start_nt
(
self
):
# if gajim is started from noninteraactive shells stdin is closed and
# cannot be forwarded, so we have to keep it open
self
.
pipe
=
Popen
(
self
.
_compose_command_args
(),
stdout
=
PIPE
,
bufsize
=
1024
,
shell
=
True
,
stderr
=
STDOUT
,
stdin
=
PIPE
)
if
self
.
commandtimeout
>=
0
:
self
.
endtime
=
self
.
idlequeue
.
current_time
()
+
self
.
commandtimeout
self
.
idlequeue
.
set_alarm
(
self
.
wait_child
,
0.1
)
def
_start_posix
(
self
):
self
.
pipe
=
os
.
popen
(
self
.
_compose_command_line
())
self
.
fd
=
self
.
pipe
.
fileno
()
fcntl
.
fcntl
(
self
.
pipe
,
fcntl
.
F_SETFL
,
os
.
O_NONBLOCK
)
self
.
idlequeue
.
plug_idle
(
self
,
False
,
True
)
if
self
.
commandtimeout
>=
0
:
self
.
idlequeue
.
set_read_timeout
(
self
.
fd
,
self
.
commandtimeout
)
def
end
(
self
):
self
.
idlequeue
.
unplug_idle
(
self
.
fd
)
try
:
self
.
pipe
.
close
()
except
:
pass
def
pollend
(
self
):
self
.
idlequeue
.
remove_timeout
(
self
.
fd
)
self
.
end
()
self
.
_return_result
()
def
pollin
(
self
):
try
:
res
=
self
.
pipe
.
read
()
except
Exception
,
e
:
res
=
''
if
res
==
''
:
return
self
.
pollend
()
else
:
self
.
result
+=
res
def
read_timeout
(
self
):
self
.
end
()
self
.
_return_result
()
class
IdleQueue
:
class
IdleQueue
:
'''
'''
IdleQueue provide three distinct time based features. Uses select.poll()
IdleQueue provide three distinct time based features. Uses select.poll()
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment