Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
poezio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
204
Issues
204
List
Boards
Labels
Service Desk
Milestones
Merge Requests
9
Merge Requests
9
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
poezio
poezio
Commits
6fab04a6
Commit
6fab04a6
authored
Oct 31, 2010
by
louiz@4325f9fc-e183-4c21-96ce-0ab188b42d13
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Basic search in the roster (based on contact JIDs)
parent
2863eebd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
140 additions
and
22 deletions
+140
-22
src/gui.py
src/gui.py
+40
-11
src/roster.py
src/roster.py
+10
-3
src/tab.py
src/tab.py
+34
-2
src/window.py
src/window.py
+56
-6
No files found.
src/gui.py
View file @
6fab04a6
...
...
@@ -39,7 +39,7 @@ from config import config
from
tab
import
MucTab
,
InfoTab
,
PrivateTab
,
RosterInfoTab
,
ConversationTab
from
user
import
User
from
room
import
Room
from
roster
import
Roster
,
RosterGroup
from
roster
import
Roster
,
RosterGroup
,
roster
from
contact
import
Contact
,
Resource
from
message
import
Message
from
text_buffer
import
TextBuffer
...
...
@@ -81,7 +81,7 @@ class Gui(object):
else
RosterInfoTab
(
self
.
stdscr
)
default_tab
.
on_gain_focus
()
self
.
tabs
=
[
default_tab
]
self
.
roster
=
Roster
()
#
self.roster = Roster()
# a unique buffer used to store global informations
# that are displayed in almost all tabs, in an
# information window.
...
...
@@ -150,6 +150,8 @@ class Gui(object):
self
.
xmpp
.
add_event_handler
(
"roster_update"
,
self
.
on_roster_update
)
self
.
xmpp
.
add_event_handler
(
"changed_status"
,
self
.
on_presence
)
# self.__debug_fill_roster()
def
grow_information_win
(
self
):
"""
"""
...
...
@@ -172,7 +174,7 @@ class Gui(object):
def
on_got_offline
(
self
,
presence
):
jid
=
presence
[
'from'
]
contact
=
self
.
roster
.
get_contact_by_jid
(
jid
.
bare
)
contact
=
roster
.
get_contact_by_jid
(
jid
.
bare
)
if
not
contact
:
return
resource
=
contact
.
get_resource_by_fulljid
(
jid
.
full
)
...
...
@@ -184,7 +186,7 @@ class Gui(object):
def
on_got_online
(
self
,
presence
):
jid
=
presence
[
'from'
]
contact
=
self
.
roster
.
get_contact_by_jid
(
jid
.
bare
)
contact
=
roster
.
get_contact_by_jid
(
jid
.
bare
)
if
not
contact
:
# Todo, handle presence comming from contacts not in roster
return
...
...
@@ -471,8 +473,7 @@ class Gui(object):
"""
"""
jid
=
presence
[
'from'
]
# contact = ros
contact
=
self
.
roster
.
get_contact_by_jid
(
jid
.
bare
)
contact
=
roster
.
get_contact_by_jid
(
jid
.
bare
)
if
not
contact
:
return
resource
=
contact
.
get_resource_by_fulljid
(
jid
.
full
)
...
...
@@ -485,6 +486,34 @@ class Gui(object):
if
isinstance
(
self
.
current_tab
(),
RosterInfoTab
):
self
.
refresh_window
()
def
__debug_fill_roster
(
self
):
for
i
in
range
(
10
):
jid
=
'contact%s@fion%s.org'
%
(
i
,
i
)
contact
=
Contact
(
jid
)
contact
.
set_ask
(
'wat'
)
contact
.
set_subscription
(
'both'
)
roster
.
add_contact
(
contact
,
jid
)
contact
.
set_name
(
'%s %s fion'
%
(
i
,
i
))
roster
.
edit_groups_of_contact
(
contact
,
[
'hello'
])
for
i
in
range
(
10
):
jid
=
'test%s@bernard%s.org'
%
(
i
,
i
)
contact
=
Contact
(
jid
)
contact
.
set_ask
(
'wat'
)
contact
.
set_subscription
(
'both'
)
roster
.
add_contact
(
contact
,
jid
)
contact
.
set_name
(
'%s test'
%
(
i
))
roster
.
edit_groups_of_contact
(
contact
,
[
'hello'
])
for
i
in
range
(
10
):
jid
=
'pouet@top%s.org'
%
(
i
)
contact
=
Contact
(
jid
)
contact
.
set_ask
(
'wat'
)
contact
.
set_subscription
(
'both'
)
roster
.
add_contact
(
contact
,
jid
)
contact
.
set_name
(
'%s oula'
%
(
i
))
roster
.
edit_groups_of_contact
(
contact
,
[
'hello'
])
if
isinstance
(
self
.
current_tab
(),
RosterInfoTab
):
self
.
refresh_window
()
def
on_roster_update
(
self
,
iq
):
"""
A subscription changed, or we received a roster item
...
...
@@ -492,10 +521,10 @@ class Gui(object):
"""
for
item
in
iq
.
findall
(
'{jabber:iq:roster}query/{jabber:iq:roster}item'
):
jid
=
item
.
attrib
[
'jid'
]
contact
=
self
.
roster
.
get_contact_by_jid
(
jid
)
contact
=
roster
.
get_contact_by_jid
(
jid
)
if
not
contact
:
contact
=
Contact
(
jid
)
self
.
roster
.
add_contact
(
contact
,
jid
)
roster
.
add_contact
(
contact
,
jid
)
if
'ask'
in
item
.
attrib
:
contact
.
set_ask
(
item
.
attrib
[
'ask'
])
else
:
...
...
@@ -507,7 +536,7 @@ class Gui(object):
if
item
.
attrib
[
'subscription'
]:
contact
.
set_subscription
(
item
.
attrib
[
'subscription'
])
groups
=
item
.
findall
(
'{jabber:iq:roster}group'
)
self
.
roster
.
edit_groups_of_contact
(
contact
,
[
group
.
text
for
group
in
groups
])
roster
.
edit_groups_of_contact
(
contact
,
[
group
.
text
for
group
in
groups
])
if
isinstance
(
self
.
current_tab
(),
RosterInfoTab
):
self
.
refresh_window
()
...
...
@@ -602,7 +631,7 @@ class Gui(object):
Refresh everything
"""
self
.
current_tab
().
set_color_state
(
theme
.
COLOR_TAB_CURRENT
)
self
.
current_tab
().
refresh
(
self
.
tabs
,
self
.
information_buffer
,
self
.
roster
)
self
.
current_tab
().
refresh
(
self
.
tabs
,
self
.
information_buffer
,
roster
)
self
.
doupdate
()
def
open_new_room
(
self
,
room
,
nick
,
focus
=
True
):
...
...
@@ -738,7 +767,7 @@ class Gui(object):
own_nick
=
room
.
own_nick
r
=
Room
(
complete_jid
,
own_nick
)
# PrivateRoom here
new_tab
=
PrivateTab
(
self
.
stdscr
,
r
,
self
.
information_win_size
)
# insert it in the
room
s
# insert it in the
tab
s
if
self
.
current_tab
().
nb
==
0
:
self
.
tabs
.
append
(
new_tab
)
else
:
...
...
src/roster.py
View file @
6fab04a6
...
...
@@ -24,6 +24,9 @@ from contact import Contact, Resource
class
Roster
(
object
):
def
__init__
(
self
):
self
.
_contact_filter
=
None
# A tuple(function, *args)
# function to filter contacts,
# on search, for example
self
.
_contacts
=
{}
# key = bare jid; value = Contact()
self
.
_roster_groups
=
[]
...
...
@@ -112,7 +115,7 @@ class Roster(object):
continue
length
+=
1
# One for the group's line itself
if
not
group
.
folded
:
for
contact
in
group
.
get_contacts
():
for
contact
in
group
.
get_contacts
(
self
.
_contact_filter
):
# We do not count the offline contacts (depending on config)
if
config
.
get
(
'roster_show_offline'
,
'false'
)
==
'false'
and
\
contact
.
get_nb_resources
()
==
0
:
...
...
@@ -178,7 +181,7 @@ class RosterGroup(object):
assert
contact
not
in
self
.
_contacts
self
.
_contacts
.
append
(
contact
)
def
get_contacts
(
self
):
def
get_contacts
(
self
,
contact_filter
):
def
compare_contact
(
a
):
if
not
a
.
get_highest_priority_resource
():
return
0
...
...
@@ -186,7 +189,9 @@ class RosterGroup(object):
if
show
not
in
PRESENCE_PRIORITY
:
return
5
return
PRESENCE_PRIORITY
[
show
]
return
sorted
(
self
.
_contacts
,
key
=
compare_contact
,
reverse
=
True
)
contact_list
=
self
.
_contacts
if
not
contact_filter
\
else
[
contact
for
contact
in
self
.
_contacts
if
contact_filter
[
0
](
contact
,
contact_filter
[
1
])]
return
sorted
(
contact_list
,
key
=
compare_contact
,
reverse
=
True
)
def
toggle_folded
(
self
):
self
.
folded
=
not
self
.
folded
...
...
@@ -203,3 +208,5 @@ class RosterGroup(object):
if
contact
.
get_highest_priority_resource
():
l
+=
1
return
l
roster
=
Roster
()
src/tab.py
View file @
6fab04a6
...
...
@@ -29,7 +29,7 @@ import window
import
theme
import
curses
from
config
import
config
from
roster
import
RosterGroup
from
roster
import
RosterGroup
,
roster
from
contact
import
Contact
,
Resource
class
Tab
(
object
):
...
...
@@ -395,6 +395,7 @@ class RosterInfoTab(Tab):
"KEY_UP"
:
self
.
move_cursor_up
,
"KEY_DOWN"
:
self
.
move_cursor_down
,
"o"
:
self
.
toggle_offline_show
,
"^F"
:
self
.
start_search
,
}
Tab
.
__init__
(
self
,
stdscr
)
self
.
name
=
"Roster"
...
...
@@ -439,11 +440,14 @@ class RosterInfoTab(Tab):
def
on_input
(
self
,
key
):
if
self
.
input
.
input_mode
:
ret
=
self
.
input
.
do_command
(
key
)
roster
.
_contact_filter
=
(
jid_and_name_match
,
self
.
input
.
text
)
# if the input is empty, go back to command mode
if
self
.
input
.
is_empty
():
if
self
.
input
.
is_empty
()
and
not
self
.
input
.
_instructions
:
self
.
input
.
input_mode
=
False
curses
.
curs_set
(
0
)
self
.
input
.
rewrite_text
()
if
self
.
input
.
_instructions
:
return
True
return
ret
if
key
in
self
.
single_key_commands
:
return
self
.
single_key_commands
[
key
]()
...
...
@@ -458,6 +462,7 @@ class RosterInfoTab(Tab):
else
:
config
.
set_and_save
(
option
,
'false'
)
return
True
def
on_slash
(
self
):
"""
'/' is pressed, we enter "input mode"
...
...
@@ -501,10 +506,27 @@ class RosterInfoTab(Tab):
isinstance
(
selected_row
,
Contact
):
selected_row
.
toggle_folded
()
return
True
def
on_enter
(
self
):
selected_row
=
self
.
roster_win
.
get_selected_row
()
return
selected_row
def
start_search
(
self
):
"""
Start the search. The input should appear with a short instruction
in it.
"""
curses
.
curs_set
(
1
)
roster
.
_contact_filter
=
(
jid_and_name_match
,
self
.
input
.
text
)
self
.
input
.
input_mode
=
True
self
.
input
.
start_command
(
self
.
on_search_terminate
,
self
.
on_search_terminate
,
'[search]'
)
return
True
def
on_search_terminate
(
self
,
txt
):
curses
.
curs_set
(
0
)
roster
.
_contact_filter
=
None
return
True
def
just_before_refresh
(
self
):
return
...
...
@@ -578,3 +600,13 @@ class ConversationTab(Tab):
def
just_before_refresh
(
self
):
return
def
jid_and_name_match
(
contact
,
txt
):
"""
A function used to know if a contact in the roster should
be shown in the roster
"""
# TODO: search in nickname, and use libdiff
if
txt
in
contact
.
get_bare_jid
():
return
True
return
False
src/window.py
View file @
6fab04a6
...
...
@@ -28,7 +28,7 @@ from config import config
from
threading
import
Lock
from
contact
import
Contact
,
Resource
from
roster
import
RosterGroup
from
roster
import
RosterGroup
,
roster
from
message
import
Line
from
tab
import
MIN_WIDTH
,
MIN_HEIGHT
...
...
@@ -546,8 +546,8 @@ class Input(Win):
'M-f'
:
self
.
jump_word_right
,
"KEY_BACKSPACE"
:
self
.
key_backspace
,
'^?'
:
self
.
key_backspace
,
'^J'
:
self
.
get_text
,
'
\n
'
:
self
.
get_text
,
'^J'
:
self
.
on_enter
,
'
\n
'
:
self
.
on_enter
,
}
Win
.
__init__
(
self
,
height
,
width
,
y
,
x
,
stdscr
)
...
...
@@ -564,6 +564,51 @@ class Input(Win):
self
.
hit_list
=
[]
# current possible completion (normal)
self
.
last_completion
=
None
# Contains the last nickname completed,
# if last key was a tab
# These are used when the user is entering a comand
self
.
_on_cancel
=
None
self
.
_on_terminate
=
None
self
.
_instructions
=
""
# a string displayed before the input, read-only
def
on_enter
(
self
):
"""
Called when Enter is pressed
"""
if
not
self
.
_instructions
:
return
self
.
get_text
()
self
.
on_terminate
()
return
True
def
start_command
(
self
,
on_cancel
,
on_terminate
,
instructions
):
"""
Start a command, with an instruction, and two callbacks.
on_terminate is called when the command is successfull
on_cancel is called when the command is canceled
"""
assert
isinstance
(
instructions
,
str
)
self
.
_on_cancel
=
on_cancel
self
.
_on_terminate
=
on_terminate
self
.
_instructions
=
instructions
def
cancel_command
(
self
):
"""
Call it to cancel the current command
"""
self
.
_on_cancel
()
self
.
_on_cancel
=
None
self
.
_on_terminate
=
None
self
.
_instructions
=
''
return
self
.
get_text
()
def
on_terminate
(
self
):
"""
Call it to terminate the command. Returns the content of the input
"""
txt
=
self
.
get_text
()
self
.
_on_terminate
(
txt
)
self
.
_on_terminate
=
None
self
.
_on_cancel
=
None
self
.
_instructions
=
''
return
txt
def
is_empty
(
self
):
return
len
(
self
.
text
)
==
0
...
...
@@ -881,11 +926,17 @@ class Input(Win):
with
g_lock
:
self
.
clear_text
()
if
self
.
input_mode
:
self
.
addstr
(
self
.
_instructions
,
curses
.
color_pair
(
theme
.
COLOR_INFORMATION_BAR
))
if
self
.
_instructions
:
self
.
addstr
(
' '
)
self
.
addstr
(
self
.
text
[
self
.
line_pos
:
self
.
line_pos
+
self
.
width
-
1
])
else
:
self
.
addstr
(
self
.
help_text
,
curses
.
color_pair
(
theme
.
COLOR_INFORMATION_BAR
))
self
.
finish_line
(
theme
.
COLOR_INFORMATION_BAR
)
self
.
addstr
(
0
,
self
.
pos
,
''
)
# WTF, this works but .move() doesn't…
cursor_pos
=
self
.
pos
if
self
.
_instructions
:
cursor_pos
+=
1
+
len
(
self
.
_instructions
)
self
.
addstr
(
0
,
cursor_pos
,
''
)
# WTF, this works but .move() doesn't…
self
.
_refresh
()
def
refresh
(
self
):
...
...
@@ -992,11 +1043,10 @@ class RosterWin(Win):
y
+=
1
if
group
.
folded
:
continue
for
contact
in
group
.
get_contacts
():
for
contact
in
group
.
get_contacts
(
roster
.
_contact_filter
):
if
config
.
get
(
'roster_show_offline'
,
'false'
)
==
'false'
and
\
contact
.
get_nb_resources
()
==
0
:
continue
if
y
-
1
==
self
.
pos
:
self
.
selected_row
=
contact
if
y
-
self
.
start_pos
+
1
==
self
.
height
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment