diff options
-rw-r--r-- | CHANGELOG | 12 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | README | 31 | ||||
-rw-r--r-- | doc/en/install.txt | 40 | ||||
-rw-r--r-- | doc/en/keys.txt | 161 | ||||
-rw-r--r-- | doc/en/usage.txt | 343 | ||||
-rw-r--r-- | doc/images/conversation.png | bin | 0 -> 12992 bytes | |||
-rw-r--r-- | doc/images/data_forms.png | bin | 0 -> 8624 bytes | |||
-rw-r--r-- | doc/images/list.png | bin | 0 -> 7768 bytes | |||
-rw-r--r-- | doc/images/muc.png | bin | 0 -> 42090 bytes | |||
-rw-r--r-- | doc/images/private.png | bin | 0 -> 9145 bytes | |||
-rw-r--r-- | doc/images/roster.png | bin | 0 -> 14736 bytes | |||
-rw-r--r-- | doc/images/tab_bar.png | bin | 0 -> 956 bytes | |||
-rw-r--r-- | src/core.py | 27 | ||||
-rw-r--r-- | src/tabs.py | 67 | ||||
-rw-r--r-- | src/windows.py | 44 | ||||
-rwxr-xr-x | update.sh | 9 |
17 files changed, 640 insertions, 99 deletions
@@ -4,11 +4,23 @@ http://dev.louiz.org/project/poezio/roadmap * Poezio 0.7.2 - dev +- Huge speed improvements in both memory usage, text + refresh speed and interface resize. - Chatstate notifications (in private AND in MUCs) - /message command to talk to any JID - /version command to get the software version of an entity - /bind command, and keys can be bound in the config file - Multiline edition +- xhtml-im messages can be sent and received +- 256 colors support +- themes are easier to create and load. They can use + up to 256 colors +- completion now works not only at the end of the input +- /affiliation and /role commands to administrate MUCs +- /export command to export your roster in a file +- data forms support (only for room configuration at the moment) +- documentation is now written in asciidoc format +- a *lot* of bugfixes * Poezio 0.7.1 - 2 Feb 2010 @@ -12,8 +12,9 @@ clean: find ./ -name \*.pyc -delete find ./ -name \*~ -delete find ./ -name "#*#" -delete + find ./ -name "*.html" -delete -install: +install: all mkdir -p $(DESTDIR)$(prefix) install -d $(DESTDIR)$(LOCALEDIR) $(DESTDIR)$(BINDIR) $(DESTDIR)$(DATADIR)/poezio $(DESTDIR)$(DATADIR)/poezio/data $(DESTDIR)$(DATADIR)/poezio/src/ $(DESTDIR)$(DATADIR)/poezio/src $(DESTDIR)$(DATADIR)/poezio/data/themes $(DESTDIR)$(MANDIR)/man1 @@ -39,4 +40,4 @@ doc: pot: xgettext src/*.py --from-code=utf-8 --keyword=_ -o locale/poezio.pot -.PHONY : doc
\ No newline at end of file +.PHONY : doc @@ -28,9 +28,9 @@ You need python 3.0 (and the associated devel package, to build C modules) or higher, and the SleekXMPP python library. In the developpement version, you’ll need this fork of SleekXMPP http://github.com/louiz/SleekXMPP. -Additionally, you’ll need asciidoc to build the html documentation pages. -You can read the documentation using the .txt files, as well, if you don’t -have asciidoc, or read it on the web. +Additionally, you’ll need asciidoc and source-highlight to build the html +documentation pages. To read the documentation without these dependance, +just read the .txt files, or read it on the webpage. The simplest way to have up-to-date dependencies and to be able to test this developpement version is to use the update.sh script that downloads @@ -45,13 +45,16 @@ you can then launch poezio with $ ./launch.sh or you can install it with (as root or with sudo) + $ make install + (`make uninstall' works, don't worry ;)) you can now simply launch `poezio' -You can edit the config file (~/.config/poezio/poezio.cfg by default) +You can edit the configuration file (~/.config/poezio/poezio.cfg by default) or data/default_config.cfg (if you want to edit the config before the -first launch). The default config file is fully commented. +first launch). The default config file is fully commented, but you can +also read the “configure” documentation page. Please, see the online documentation for more information on installing, configuring or using poezio: @@ -66,7 +69,7 @@ feature you want. ======================= Authors ======================= -Florent Le Coz (louiz’) <louiz@louiz.org> (main developper) +Florent Le Coz (louiz’) <louiz@louiz.org> (developper) Mathieu Pasquet (mathieui) <mathieui@mathieui.net> (developper) @@ -140,13 +143,15 @@ we merge it to “master” as well, of course). Thanks ======================= = People = - Todd Eisenberger (todd@teisen.be) - Plugin system - Link Mauve - Code, testing - Gaëtan Ribémont (http://www.bonbref.com) - Logo design - Ovart - Testing - Koshie - Donation - Gapan - Makefile - FlashCode (weechat dev) - Useful advices on how to use ncurses efficiently + - Todd Eisenberger (todd@teisen.be) - Plugin system + - Link Mauve - Code, testing + - Gaëtan Ribémont (http://www.bonbref.com) - Logo design + - Ovart - Testing + - Koshie - Donation + - Gapan - Makefile + - FlashCode (weechat dev) - Useful advices on how to use ncurses efficiently + - And all the people using and testing poezio, and especially the one present + on the jabber chatroom doing bug reports and/or feature requests. = Project = Gajim - send_vcard method and common.py diff --git a/doc/en/install.txt b/doc/en/install.txt index 75cc0ea8..4338afef 100644 --- a/doc/en/install.txt +++ b/doc/en/install.txt @@ -5,31 +5,44 @@ Install Poezio in the GNU/Linux distributions ------------------------------------- -As far as I know, Poezio is available in the following distributions, you just have to install it by using the package manager of the distribution, if you're using one of these. - -* *Archlinux*: A poezio and poezio-git packages are in AUR (use your favourite AUR wrapper to install them) -* *Frugalware*: Just use pacmang-g2 to install the poezio package. (Thanks to its maintainer, Kooda) +As far as I know, Poezio is available in the following distributions, you just + have to install it by using the package manager of the distribution, if you're + using one of these. + +* *Archlinux*: A poezio and poezio-git packages are in AUR (use your favourite + AUR wrapper to install them) +* *Frugalware*: Just use pacmang-g2 to install the poezio package. (Thanks to + its maintainer, Kooda) * *Debian*: Use an other distro. -(If an other distribution provides a poezio package, please tell us and we will add it to the list) +(If an other distribution provides a poezio package, please tell us and we will + add it to the list) Install poezio from the sources ------------------------------- -You can download poezio's https://dev.louiz.org/project/poezio/download[stable sources] or fetch the development version (trunk), using git: +You can download poezio's https://dev.louiz.org/project/poezio/download[stable + sources] or fetch the development version (trunk), using git: ============================ git clone https://git.louiz.org/poezio ============================ -In order for poezio to correctly work, you need the libs SleekXMPP and dnspython. You can install them by downloading it from the https://github.com/fritzy/SleekXMPP/[SleekXMPP] page and the http://www.dnspython.org/[dnspython] page , but you'll need the development versions. Alternatively, you can download poezio's sources including SleekXMPP and dnspython, that's the easier way. +In order for poezio to correctly work, you need the libs SleekXMPP and + dnspython. You can install them by downloading it from the + https://github.com/fritzy/SleekXMPP/[SleekXMPP] page and the + http://www.dnspython.org/[dnspython] page , but you'll need the development + versions. Alternatively, you can download poezio's sources including SleekXMPP + and dnspython, that's the easier way. -As for dnspython, you will have to use our python3 fork, or poke them to accept patches. +As for dnspython, you will have to use our python3 fork, or poke them to accept + patches. === Dependencies === -If you want to install SleekXMPP and dnspython yourself, follow these instructions. Else, go to the next section. +If you want to install SleekXMPP and dnspython yourself, follow these + instructions. Else, go to the next section. Download SleekXMPP @@ -51,7 +64,8 @@ python3 setup.py build su -c "python3 setup.py install" ============================ -Clone the repository at http://hg.louiz.org/dnspython (this is a fork, because upstream is unresponsive and didn’t fix an important bug). +Clone the repository at http://hg.louiz.org/dnspython (this is a fork, because + upstream is unresponsive and didn’t fix an important bug). ============================ hg clone http://hg.louiz.org/dnspython @@ -68,12 +82,14 @@ su -c "python3 setup.py install" === Poezio installation === -If you skipped the installation of the dependencies and you only want to test poezio without a system-wide install, do, in the _poezio_ directory: +If you skipped the installation of the dependencies and you only want to test + poezio without a system-wide install, do, in the _poezio_ directory: ============================ sh update.sh ============================ -If you have git and hg installed, it will download and update locally the libraries for you. +If you have git and hg installed, it will download and update locally the + libraries for you. If you don't want to install poezio but just test it, do: diff --git a/doc/en/keys.txt b/doc/en/keys.txt index eaae961d..109e5df5 100644 --- a/doc/en/keys.txt +++ b/doc/en/keys.txt @@ -7,12 +7,14 @@ configure them. By default, most keys manipulating the input (where you type your messages and commands) behave like emacs does. -Note that keys are case sensitive. Ctrl-X is not the same than Ctrl-x +NOTE: keys are case sensitive. Ctrl-X is not the same than Ctrl-x + Key bindings listing -------------------- Some key bindings are available only in some tabs, others are global. + Global keys ~~~~~~~~~~~ These keys work in *any* tab. @@ -21,44 +23,185 @@ These keys work in *any* tab. *Ctrl-p*:: Go to the previous tab. -*Alt-number*:: Go to tab number x. +*Alt-number*:: Go to the tab with that number. *Alt-j*:: Waits for you to type a two-digits number. Go to tab number xx. +*Alt-e*:: Go to the tab with a higher priority (private message > + highlight > message > non-empty input). + +*Alt-z*:: Go to the previously selected tab. + +*Alt-r*:: Go to the roster tab. + +*F7*:: Shrink the information buffer. + +*F8*:: Grow the information buffer. + +*Ctrl-l*:: Refresh the screen. + + Input keys ~~~~~~~~~~ These keys concern only the inputs. +NOTE: The clipboard is common to all inputs. This lets you cut a text +from one input to paste it into an other one. + *Ctrl-a*:: Move the cursor to the beginning of line. *Ctrl-e*:: Move the cursor to the end of line. +*Ctrl-u*:: Delete the text from the start of the input until the cursor + and save it to the clipboard. + +*Ctrl-k*:: Delete the text from the cursor until the end of the input + and save it to the clipboard. + +*Ctrl-y*:: Insert the content of the clipboard at the cursor position. + + Chat tab input keys ~~~~~~~~~~~~~~~~~~~~~ -These keys work in any conversation tab (MultiUserChat, Private or Conversation tabs) +These keys work in any conversation tab (MultiUserChat, Private or +Conversation tabs). *Key Up*:: Use the previous message from the message history. *Key Down*:: Use the next message from the message history. -*Page Up*:: Scroll up in the conversation by x lines, where x is the height of the conversation window - 1. +*Page Up*:: Scroll up in the conversation by x lines, where x is the +height of the conversation window - 1. + +*Page Down*:: Like Page Up, but down. + +*Alt-/*:: Complete what you’re typing using the "recent" words from the + current conversation, if any. + +*Alt-v*:: Move the separator at the bottom of the tab. + + +MultiUserChat tab input keys +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +These keys work only in the MultiUserChat tab. + +*Alt-u*:: Scroll the user list down. + +*Alt-y*:: Scroll the user list up. + +*tabulation*:: Complete a nick. + +*Ctrl-c*:: Insert xhtml formatting. You have to press Ctrl-c then a character + listed below: +- 1: Red +- 2: Green +- 3: Yellow/Orange +- 4: Blue +- 5: Pink +- 6: Turquoise +- b: Bold +- o: Stop formatting + + +MultiUserChat List tab input keys +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These keys work only in the MultiUserChat List tab (obtained with /list <server>). + +*Up*:: Go up one row. + +*Down*:: Go down one row. + +*j*:: Join the MultiUserChat currently selected. + +*J*:: Join the MultiUserChat currently selected, without giving focus to iuts tab. + +*Ctrl-M*:: Join the MultiUserChat currently selected (same as "j"). + +*PageUp*:: Scroll a page of chats up. + +*PageDown*:: Scroll a page of messages down. + + +Roster tab input keys +~~~~~~~~~~~~~~~~~~~~~ + +These keys work only in the Roster tab (the tab number 0). + +*/*:: Open a prompt for commands. + +*s*:: Start a search on the contacts. + +*S*:: Start a (slow) search with approximation on the contacts. + +*Alt-u*:: Move the cursor to the next group. + +*Alt-y*:: Move the cursor to the previous group. + +*Ctrl-c*:: Cancel the input (search or command) + +NOTE: The following will not work if you can still write things in the +input (meaning you previously typed _s_ or _/_): + +*Space*:: Fold/Unfold the current item. + +*Up*:: Move the cursor down one contact. + +*Down*:: Move the cursor up one contact. + +*o*:: Show the offline contacts. + +*PageUp*:: Scroll a page of contacts up. + +*PageDown*:: Scroll a page of contacts down. + + +Data Forms tab keys +~~~~~~~~~~~~~~~~~~~ +*Ctrl+y*:: Validate the form, send it and close the tab. + +*Ctrl+g*:: Cancel that form (do not send your changes) and close the + tab. + +*Up*:: Select the next field. + +*Down*:: Select the previous field. + +*Right/Left*:: Switch between possible values, in a jid-multi, + list-multi, list-single or text-multi field. + +*Space*:: Select that option + + +MultiUserChat List tab input keys +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +These keys work only in the MultiUserChat List tab (obtained with /list +<server>). + +*Up*:: Go up one row. + +*Down*:: Go down one row. + +*j*:: Join the MultiUserChat currently selected. + +*J*:: Join the MultiUserChat currently selected, without giving focus to + iuts tab. -*Page Down*:: Likfe Page Up, but down. +*Ctrl-M*:: Join the MultiUserChat currently selected (same as _j_). -*Alt-/*:: Complete what you’re typing using the "recent" words from the current conversation, if any. Key configuration ----------------- Bindings are keyboard shortcut aliases. You can use them to define your own keys to replace the default ones. -where ^x means Control + x -and M-x means Alt + x +where _^x_ means _Control + x_ +and _M-x_ means _Alt + x_ To know exactly what the code of a key is, just run ================== python3 src/keyboard.py ================== -And enter any keys +And enter any key. .Turn Alt-i into a tab key (completion, etc) ================== diff --git a/doc/en/usage.txt b/doc/en/usage.txt new file mode 100644 index 00000000..f11ab5ed --- /dev/null +++ b/doc/en/usage.txt @@ -0,0 +1,343 @@ +Usage +===== + +This page is the main page of the documentation for poezio, explaining how to + use it and describing its interfaces. + +Poezio is composed of tabs which can be of various types. Each tab type has +a distinct interface, list of commands and list of key shortcuts, in addition +to the global commands and key shortcuts. + +Tabs +---- +On all tabs, you get a line showing the the list of all opened tabs. Each tab +has a number, each time you open a new tab, it gets the next available number. + + +image::../images/tab_bar.png[title="Example of 5 opened tabs"] + +The tab numbered _0_ is always the _roster_ tab, the other tabs can be of any +type. + + +The status of a tab is represented by its color: + +* *[navy]#blue#* (tab _0_): an inactive tab of any type, nothing new to see + there. +* *[purple]#purple#* (tab _1_): a MultiUserChat tab with at least one new + unread message. +* *[green]#green#* (tab _2_): a tab of a private conversation with a new + message to read. +* *[teal]#cyan#* (tab _3_): the current tab. +* *[red]#red#* (tab _4_): a MultiUserChat tab with at least one new hightlight + message. + +You can go from one tab to another in many ways: + +* Ctrl+n and Ctrl+p +* <<command-win, win>> command +* <<command-next, next>> and <<command-prev, prev>> commands +* Alt+ a number +* Alt+j followed by a two-digits number +* Alt+e, this will jump to the next tab with the highest priority. Priority + applies in this order: private message > highlight message > normal message. + +Roster tab +~~~~~~~~~~ +This is a unique tab, always numbered _0_. It contains the list of your +contacts. You can add/remove/edit/search contacts from there, and you can open +a conversation with one of them. + +Use the _arrows_ to browse the list, the _space_ key to fold or unfold a group +or a contact. + +image::../images/roster.png["The roster tab", title="The roster tab"] + +* _1_: The area where information messages are displayed. +* _2_: The actual list of contacts. The first level is group, the second is the +* contacts and the third is the resources of you online contacts. +* _3_: More informations about the selected contact. + +MultiUserChat tab +~~~~~~~~~~~~~~~~~ + +This tab contains a multi-users conversation. + +image::../images/muc.png["The MUC tab", title="The MUC tab"] + +* _1_: The conversation window, this is where all the messages and events + related to the muc will be displayed. It can be scrolled up and down with + PageUp and PageDown. +* _2_: The participant list. Participants are listed by their role first, and + then alphabetically. + In the default theme, The nick colors mean: + - Red: moderator + - Blue: participant + - gray: visitor + + + + The status of each participant is symbolized using the _color_ of the + character on the left of its nick. + That character also shows the chatstate of each participant: + - _|_: inactive + - _X_: composing + - _A_: active + - _p_: paused +* _3_: Your information in that MUC (the name of the room, your nick, your role + and affiliation). +* _4_: The topic of the room. + +You can configure the room (if you have the rights to do it) using the +_/configure_ command, open a private conversation with someone using the +_/query_ command, change or view the topic using the _/topic_ command… + +Private tab +~~~~~~~~~~~ +This is the tab opened with the _/query_ command, letting you talk in private +with a participant of a multi-users chat. + +image::../images/private.png["The private tab", title="The private tab"] + +This is just a simple one to one conversation, with a line showing the status, +name and chatstate of the participant. + +Conversation tab +~~~~~~~~~~~~~~~~ +A tab opened from the roster, to talk in private with one of your contacts. + +image::../images/conversation.png["The conversation tab", title="The conversation tab"] + +This is also just a simple one to one conversation, with a line showing the status, +name and chatstate of the participant, as well as a line at the top showing the +status message of the contact. + +Dataforms tab +~~~~~~~~~~~~~ + +This tab lets you view a form receive from a remote entity, edit the values and +send everything back. It is mostly used to configure MUCs with the _/configure_ +command but can actually be used for almost anything. + +image::../images/data_forms.png["The dataform tab", title="The dataform tab"] + +Use the _up_ and _down_ keys to go from one field to the other, and edit the +value using the _space_, _left_ or _right_ keys, or by entering text. + +You can then send the completed form using _Ctrl+y_ or cancel using _Ctrl+g_. + +List tab +~~~~~~~~ + +This tab lists all public rooms on a MUC service. It is currently very limited +but will be improved in the future. There currently is no way to search a room +or even to sort them. + +image::../images/list.png["The list tab", title="The list tab"] + +Use the _up_ and _down_ or _PageUp_ and _PageDown_ keys to browse the list, and +use _Enter_ or _j_ to join the selected room. + +Commands +-------- + +Commands start with the _/_ character and can take a list of any number +of arguments, separated by spaces. If an argument should contain a space, +you can use the _"_ character to surround this argument. + +The commands described in this page are shown like this: + +=========================================================== +/command <mandatory argument> [optional argument] +=========================================================== + +You can get the same help as below with the _/help_ command. + + +Global commands +~~~~~~~~~~~~~~~ + +These commands work in *any* tab. + +*/help [command]*:: If called without an argument, this command will list the + available commands. If it has a valid command as an argument, this command + will show the usage and the help for the given command. + +*/join [room_name][@server][/nick] [password]*:: Join the specified room. You + can specify a nickname after a slash (/). If no nickname is specified, you + will use the default_nick in the configuration file. You can omit the room + name: you will then join the room you're looking at (useful if you were + kicked). You can also provide a room_name without specifying a server, the + server of the room you're currently in will be used. You can also provide a + password to join the room. + +- Examples: +* /join room@server.tld +* /join room@server.tld/John +* /join room2 +* /join /me_again +* /join +* /join room@server.tld/my_nick password +* /join / password + +*/exit*:: Just disconnect from the server and exit poezio. + +*/quit*:: Like /exit. + +[[command-next]] +*/next*:: Go to the next room. + +[[command-prev]] +*/prev*:: Go to the previous room. + +[[command-win]] +*/win <number>*:: Go to the specified room. + +*/w <number>*:: Like /win. + +*/status <availability> [status message]*:: Set your availability and + (optionaly) your status message. The <availability> argument is one of + "available, chat, away, afk, dnd, busy, xa" and the optional [status] argument + will be your status message.' + +*/bookmark [roomname][/nick]*:: Bookmark the specified room (you will then + auto-join it on each poezio start). This commands uses almost the same syntax + as /join. Type /help join for syntax examples. Note that when typing /bookmark + on its own, the room will be bookmarked with the nickname you're currently + using in this room (instead of default_nick). + +*/set <option> [value]*:: Sets the value to the option in your configuration + file. You can, for example, change your default nickname by doing "/set + default_nick toto" or your resource with "/set resource blabla". You can also + set an empty value (nothing) by providing no [value] after <option>. + +*/theme*:: Reload the theme defined in the config file. + +*/list [server.tld]*:: Get the list of public chatrooms in the specified server +. + +*/message <jid> [optional message]*:: Open a conversation with the specified + JID (event if it is not in our roster), and send a message to him, if + specified. + +*/version <jid>*:: Get the software version of the given JID (usually its XMPP + client and Operating System). + +*/server_cycle [server.tld] [message]*:: Disconnect and reconnect in all the + rooms of server.tld. + +*/bind <key> <eq>*:: Bind a key to another key or to a "command". For example, + "/bind ^H KEY_UP" makes Control + h behave the same way as the Up key. See the + link:keys.html[key bindings documentation page] for more details. + +NOTE: The following command will work everywhere, except in the Roster tab. + +*/close*:: Close the tab. + +Chat tab commands +~~~~~~~~~~~~~~~~~ + +These commands will work in any conversation tab (MultiUserChat, Private, or + Conversation tabs). + +*/say <message>*:: Just send the message (only useful it you want your message + to begin with a _/_). Note that you can also send message starting with a _/_ + by starting it with _//_. + +MultiUserChat tab commands +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*/ignore <nickname>*:: Ignore a specified nickname. + +*/unignore <nickname>*:: Remove the specified nickname from the ignore list. + +*/kick <nick> [reason]*:: Kick the user with the specified nickname. You can + also give an optional reason. + +*/topic <subject>*:: Change the subject of the room. You might want to knwow + that entering "/topic [tab]" will autocomplete the topic. + +*/query <nick> [message]*:: Open a private conversation with <nick>. This nick + has to be present in the room you’re currently in. If you specified a message + after the nickname, it will be sent to this user. + +*/part [message]*:: Disconnect you from a room. You can specify an optional + message. + +*/close [message]*:: Disconnect you from a room (if you are connected) and + close the tab. You can specify an optional message if you are still connected. + +*/nick <nickname>*:: Change your nickname in the current room. + +*/recolor*:: Re-assign a color to all the participants in the current room, + based on the last time they talked. Use this if the participants currently + talking have too many identical colors. + +*/cycle [message]*:: Leave the current room an rejoint it immediatly. You can + specify an optional quit message. + +*/info <nickname>*:: Display some information about the user in the room: + his/her role, affiliation, status, and status message. + +*/version <nickname or jid>*:: Get the software version of the given nick in + room or the given jid (usually its XMPP client and Operating System). + +*/configure*:: Configure the current room through a form. + +*/names*:: Get the list of the users in the room, their number, and the list + of the people assuming different roles. + +*/clear*:: Clear the current buffer. + +Private tab commands +~~~~~~~~~~~~~~~~~~~~ + +*/info*:: Display some info about this user in the MultiUserChat. + +*/unquery*:: Close the tab. + +*/version*:: Get the software version of the current interlocutor (usually its + XMPP client and Operating System). + +Normal Conversation tab commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +*/info*:: Display the status of this contact. + +*/unquery*:: Close the tab. + +*/version*:: Get the software version of the current interlocutor (usually its + XMPP client and Operating System). + +Roster tab commands +~~~~~~~~~~~~~~~~~~~ + +*/accept [jid]*:: Authorize the provided JID (or the selected contact in the + roster) to see your presence. + +*/deny [jid]*:: Prevent the provided JID (or the selected contact in the + roster) from seeing your presence. + +*/add <jid>*:: Add the specified JID to your roster and authorize him to see + your presence. If he accepts you, the subscription will be mutual (and if he + doesn’t, you can still /deny him). + +*/name <jid> <name>*:: Set the given JID’s name. + +*/groupadd <jid> <group>*:: Add the given JID to the given group (if the group + does not exist, it will be created). + +*/groupremove <jid> <group>*:: Remove the given JID from the given group (if + the group is empty after that, it will get deleted). + +*/remove [jid]*:: Remove the specified JID from your roster. This will + unsubscribe you from its presence, cancel its subscription to yours, and + remove the item from your roster. + +NOTE: The following commands do not comply with any XEP or whatever, but they + can still prove useful when you are migrating to an other JID. + +*/export [/path/to/file]*:: Export your contacts into /path/to/file if + specified, or $HOME/poezio_contacts if not. + +*/import [/path/to/file]*:: Import your contacts from /path/to/file if + specified, or $HOME/poezio_contacts if not. + diff --git a/doc/images/conversation.png b/doc/images/conversation.png Binary files differnew file mode 100644 index 00000000..f5347178 --- /dev/null +++ b/doc/images/conversation.png diff --git a/doc/images/data_forms.png b/doc/images/data_forms.png Binary files differnew file mode 100644 index 00000000..d6e53cd9 --- /dev/null +++ b/doc/images/data_forms.png diff --git a/doc/images/list.png b/doc/images/list.png Binary files differnew file mode 100644 index 00000000..768ca41f --- /dev/null +++ b/doc/images/list.png diff --git a/doc/images/muc.png b/doc/images/muc.png Binary files differnew file mode 100644 index 00000000..1e431e4a --- /dev/null +++ b/doc/images/muc.png diff --git a/doc/images/private.png b/doc/images/private.png Binary files differnew file mode 100644 index 00000000..7d604dc2 --- /dev/null +++ b/doc/images/private.png diff --git a/doc/images/roster.png b/doc/images/roster.png Binary files differnew file mode 100644 index 00000000..d853c1cb --- /dev/null +++ b/doc/images/roster.png diff --git a/doc/images/tab_bar.png b/doc/images/tab_bar.png Binary files differnew file mode 100644 index 00000000..fc482ffd --- /dev/null +++ b/doc/images/tab_bar.png diff --git a/src/core.py b/src/core.py index afdd1c14..cabd1580 100644 --- a/src/core.py +++ b/src/core.py @@ -117,16 +117,20 @@ class Core(object): 'prev': (self.rotate_rooms_left, _("Usage: /prev\nPrev: Go to the previous room."), None), 'win': (self.command_win, _("Usage: /win <number>\nWin: Go to the specified room."), self.completion_win), 'w': (self.command_win, _("Usage: /w <number>\nW: Go to the specified room."), self.completion_win), - 'status': (self.command_status, _('Usage: /status <availability> [status message]\nStatus: Sets your availability and (optionaly) your status message. The <availability> argument is one of \"available, chat, away, afk, dnd, busy, xa\" and the optional [status] argument will be your status message.'), self.completion_status), - 'bookmark': (self.command_bookmark, _("Usage: /bookmark [roomname][/nick]\nBookmark: Bookmark the specified room (you will then auto-join it on each poezio start). This commands uses the same syntaxe as /join. Type /help join for syntaxe examples. Note that when typing \"/bookmark\" on its own, the room will be bookmarked with the nickname you\'re currently using in this room (instead of default_nick)"), None), - 'set': (self.command_set, _("Usage: /set <option> [value]\nSet: Sets the value to the option in your configuration file. You can, for example, change your default nickname by doing `/set default_nick toto` or your resource with `/set resource blabla`. You can also set an empty value (nothing) by providing no [value] after <option>."), None), - 'theme': (self.command_theme, _('Usage: /theme\nTheme: Reload the theme defined in the config file.'), None), - 'list': (self.command_list, _('Usage: /list\nList: get the list of public chatrooms on the specified server'), self.completion_list), - 'message': (self.command_message, _('Usage: /message <jid> [optional message]\nMessage: Open a conversation with the specified JID (even if it is not in our roster), and send a message to it, if specified'), None), - 'version': (self.command_version, _('Usage: /version <jid>\nVersion: get the software version of the given JID (usually its XMPP client and Operating System)'), None), - 'connect': (self.command_reconnect, _('Usage: /connect\nConnect: disconnect from the remote server if you are currently connected and then connect to it again'), None), - 'server_cycle': (self.command_server_cycle, _('Usage: /server_cycle [domain] [message]\nServer Cycle: disconnect and reconnects in all the rooms in domain.'), None), - 'bind': (self.command_bind, _('Usage: /bind <key> <equ>\nBind: bind a key to an other key or to a “command”. For example "/bind ^H KEY_UP" makes Control + h do the same same than the Up key.'), None), + 'show': (self.command_status, _('Usage: /show <availability> [status message]\nShow: Sets your availability and (optionally) your status message. The <availability> argument is one of \"available, chat, away, afk, dnd, busy, xa\" and the optional [status message] argument will be your status message.'), self.completion_status), + 'status': (self.command_status, _('Usage: /status <availability> [status message]\nStatus: Sets your availability and (optionally) your status message. The <availability> argument is one of \"available, chat, away, afk, dnd, busy, xa\" and the optional [status message] argument will be your status message.'), self.completion_status), + 'away': (self.command_away, _("Usage: /away [message]\nAway: Sets your availability to away and (optionally) your status message. This is equivalent to '/status away [message]'"), None), + 'busy': (self.command_busy, _("Usage: /busy [message]\nBusy: Sets your availability to busy and (optionally) your status message. This is equivalent to '/status busy [message]'"), None), + 'available': (self.command_avail, _("Usage: /available [message]\nAvailable: Sets your availability to available and (optionally) your status message. This is equivalent to '/status available [message]'"), None), + 'bookmark': (self.command_bookmark, _("Usage: /bookmark [roomname][/nick]\nBookmark: Bookmark the specified room (you will then auto-join it on each poezio start). This commands uses almost the same syntaxe as /join. Type /help join for syntaxe examples. Note that when typing \"/bookmark\" on its own, the room will be bookmarked with the nickname you\'re currently using in this room (instead of default_nick)"), None), + 'set': (self.command_set, _("Usage: /set <option> [value]\nSet: Set the value of the option in your configuration file. You can, for example, change your default nickname by doing `/set default_nick toto` or your resource with `/set resource blabla`. You can also set an empty value (nothing) by providing no [value] after <option>."), None), + 'theme': (self.command_theme, _('Usage: /theme [theme_name]\nTheme: Reload the theme defined in the config file. If theme_name is provided, set that theme before reloading it.'), None), + 'list': (self.command_list, _('Usage: /list\nList: Get the list of public chatrooms on the specified server.'), self.completion_list), + 'message': (self.command_message, _('Usage: /message <jid> [optional message]\nMessage: Open a conversation with the specified JID (even if it is not in our roster), and send a message to it, if the message is specified.'), None), + 'version': (self.command_version, _('Usage: /version <jid>\nVersion: Get the software version of the given JID (usually its XMPP client and Operating System).'), None), + 'connect': (self.command_reconnect, _('Usage: /connect\nConnect: Disconnect from the remote server if you are currently connected and then connect to it again.'), None), + 'server_cycle': (self.command_server_cycle, _('Usage: /server_cycle [domain] [message]\nServer Cycle: Disconnect and reconnect in all the rooms in domain.'), None), + 'bind': (self.command_bind, _('Usage: /bind <key> <equ>\nBind: Bind a key to an other key or to a “command”. For example "/bind ^H KEY_UP" makes Control + h do the same same as the Up key.'), None), 'load': (self.command_load, _('Usage: /load <plugin>\nLoad: Load the specified plugin'), self.plugin_manager.completion_load), 'unload': (self.command_unload, _('Usage: /unload <plugin>\nUnload: Unload the specified plugin'), self.plugin_manager.completion_unload), 'plugins': (self.command_plugins, _('Usage: /plugins\nPlugins: Show the plugins in use.'), None), @@ -1224,6 +1228,9 @@ class Core(object): self.xmpp.plugin['xep_0030'].get_items(jid=server, block=False, callback=list_tab.on_muc_list_item_received) def command_theme(self, arg): + args = arg.split() + if len(args) == 1: + self.command_set('theme %s' % (args[0],)) warning = theming.reload_theme() if warning: self.information(warning, 'Warning') diff --git a/src/tabs.py b/src/tabs.py index e5df2e7d..6f100741 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -293,7 +293,7 @@ class ChatTab(Tab): self.key_func['^M'] = self.on_enter self.commands['say'] = (self.command_say, _("""Usage: /say <message>\nSay: Just send the message. - Useful if you want your message to begin with a '/'"""), None) + Useful if you want your message to begin with a '/'."""), None) self.chat_state = None def last_words_completion(self): @@ -430,20 +430,20 @@ class MucTab(ChatTab): self.commands['unignore'] = (self.command_unignore, _("Usage: /unignore <nickname>\nUnignore: Remove the specified nickname from the ignore list."), self.completion_unignore) self.commands['kick'] = (self.command_kick, _("Usage: /kick <nick> [reason]\nKick: Kick the user with the specified nickname. You also can give an optional reason."), None) self.commands['role'] = (self.command_role, _("Usage: /role <nick> <role> [reason]\nRole: Set the role of an user. Roles can be: none, visitor, participant, moderator. You also can give an optional reason."), None) - self.commands['affiliation'] = (self.command_affiliation, _("Usage: /affiliation <nick> <affiliation> [reason]\nAffiliation: Set the affiliation of an user. Affiliations can be: outcast, none, member, admin, owner. You also can give an optional reason."), None) - self.commands['topic'] = (self.command_topic, _("Usage: /topic <subject>\nTopic: Change the subject of the room"), self.completion_topic) - self.commands['query'] = (self.command_query, _('Usage: /query <nick> [message]\nQuery: Open a private conversation with <nick>. This nick has to be present in the room you\'re currently in. If you specified a message after the nickname, it will immediately be sent to this user'), None) - self.commands['part'] = (self.command_part, _("Usage: /part [message]\nPart: disconnect from a room. You can specify an optional message."), None) - self.commands['close'] = (self.command_close, _("Usage: /close [message]\nClose: disconnect from a room and close the tab. You can specify an optional message if you are still connected."), None) - self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room"), None) + self.commands['affiliation'] = (self.command_affiliation, _("Usage: /affiliation <nick> <affiliation> [reason]\nAffiliation: Set the affiliation of an user. Affiliations can be: none, member, admin, owner. You also can give an optional reason."), None) + self.commands['topic'] = (self.command_topic, _("Usage: /topic <subject>\nTopic: Change the subject of the room."), self.completion_topic) + self.commands['query'] = (self.command_query, _('Usage: /query <nick> [message]\nQuery: Open a private conversation with <nick>. This nick has to be present in the room you\'re currently in. If you specified a message after the nickname, it will immediately be sent to this user.'), None) + self.commands['part'] = (self.command_part, _("Usage: /part [message]\nPart: Disconnect from a room. You can specify an optional message."), None) + self.commands['close'] = (self.command_close, _("Usage: /close [message]\nClose: Disconnect from a room and close the tab. You can specify an optional message if you are still connected."), None) + self.commands['nick'] = (self.command_nick, _("Usage: /nick <nickname>\nNick: Change your nickname in the current room."), None) self.commands['recolor'] = (self.command_recolor, _('Usage: /recolor\nRecolor: Re-assign a color to all participants of the current room, based on the last time they talked. Use this if the participants currently talking have too many identical colors.'), None) - self.commands['cycle'] = (self.command_cycle, _('Usage: /cycle [message]\nCycle: Leaves the current room and rejoin it immediately'), None) - self.commands['info'] = (self.command_info, _('Usage: /info <nickname>\nInfo: Display some information about the user in the MUC: his/here role, affiliation, status and status message.'), None) + self.commands['cycle'] = (self.command_cycle, _('Usage: /cycle [message]\nCycle: Leave the current room and rejoin it immediately.'), None) + self.commands['info'] = (self.command_info, _('Usage: /info <nickname>\nInfo: Display some information about the user in the MUC: its/his/her role, affiliation, status and status message.'), None) self.commands['configure'] = (self.command_configure, _('Usage: /configure\nConfigure: Configure the current room, through a form.'), None) - self.commands['version'] = (self.command_version, _('Usage: /version <jid or nick>\nVersion: get the software version of the given JID or nick in room (usually its XMPP client and Operating System)'), None) - self.commands['names'] = (self.command_names, _('Usage: /names\nNames: get the list of the users in the room, and the list of the people assuming the different roles.'), None) + self.commands['version'] = (self.command_version, _('Usage: /version <jid or nick>\nVersion: Get the software version of the given JID or nick in room (usually its XMPP client and Operating System).'), None) + self.commands['names'] = (self.command_names, _('Usage: /names\nNames: Get the list of the users in the room, and the list of the people assuming the different roles.'), None) self.commands['clear'] = (self.command_clear, - _("""Usage: /clear\nClear: clears the current buffer'"""), None) + _('Usage: /clear\nClear: Clear the current buffer.'), None) self.resize() def scroll_user_list_up(self): @@ -661,7 +661,12 @@ class MucTab(ChatTab): if not len(args): self.core.command_help('kick') else: - self.command_role(arg+ ' none') + if len(args) > 1: + msg = ' '+args[1] + self.core.information("-%s-" % msg) + else: + msg = '' + self.command_role(args[0]+ ' none'+msg) def command_role(self, arg): """ @@ -1192,10 +1197,10 @@ class PrivateTab(ChatTab): # keys self.key_func['^I'] = self.completion # commands - self.commands['info'] = (self.command_info, _('Usage: /info\nInfo: Display some information about the user in the MUC: '), None) - self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"), None) - self.commands['close'] = (self.command_unquery, _("Usage: /close\nClose: close the tab"), None) - self.commands['version'] = (self.command_version, _('Usage: /version\nVersion: get the software version of the current interlocutor (usually its XMPP client and Operating System)'), None) + self.commands['info'] = (self.command_info, _('Usage: /info\nInfo: Display some information about the user in the MUC: its/his/her role, affiliation, status and status message.'), None) + self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: Close the tab."), None) + self.commands['close'] = (self.command_unquery, _("Usage: /close\nClose: Close the tab."), None) + self.commands['version'] = (self.command_version, _('Usage: /version\nVersion: Get the software version of the current interlocutor (usually its XMPP client and Operating System).'), None) self.resize() self.parent_muc = self.core.get_tab_by_name(JID(name).bare, MucTab) self.on = True @@ -1399,15 +1404,15 @@ class RosterInfoTab(Tab): self.key_func["o"] = self.toggle_offline_show self.key_func["s"] = self.start_search self.key_func["S"] = self.start_search_slow - self.commands['deny'] = (self.command_deny, _("Usage: /deny [jid]\nDeny: Use this command to remove and deny your presence to the provided JID (or the selected contact in your roster), who is asking you to be in his/here roster"), self.completion_deny) - self.commands['accept'] = (self.command_accept, _("Usage: /accept [jid]\nAccept: Use this command to authorize the provided JID (or the selected contact in your roster), to see your presence, and to ask to subscribe to it (mutual presence subscription)."), self.completion_deny) - self.commands['add'] = (self.command_add, _("Usage: /add <jid>\nAdd: Use this command to add the specified JID to your roster. The reverse authorization will automatically be accepted if the remote JID accepts your subscription, leading to a mutual presence subscription."), None) - self.commands['name'] = (self.command_name, _("Usage: /name <jid> <name>\nSet the given JID's name"), self.completion_name) - self.commands['groupadd'] = (self.command_groupadd, _("Usage: /groupadd <jid> <group>\nAdd the given JID to the given group"), self.completion_groupadd) - self.commands['groupremove'] = (self.command_groupremove, _("Usage: /groupremove <jid> <group>\nRemove the given JID from the given group"), self.completion_groupremove) - self.commands['remove'] = (self.command_remove, _("Usage: /remove [jid]\nRemove: Use this command to remove the specified JID from your roster. This wil unsubscribe you from its presence, cancel its subscription to yours, and remove the item from your roster"), self.completion_remove) - self.commands['export'] = (self.command_export, _("Usage: /export [/path/to/file]\nExport: Use this command to export your contacts into /path/to/file if specified, or $HOME/poezio_contacts if not."), None) - self.commands['import'] = (self.command_import, _("Usage: /import [/path/to/file]\nImport: Use this command to import your contacts from /path/to/file if specified, or $HOME/poezio_contacts if not."), None) + self.commands['deny'] = (self.command_deny, _("Usage: /deny [jid]\nDeny: Deny your presence to the provided JID (or the selected contact in your roster), who is asking you to be in his/here roster."), self.completion_deny) + self.commands['accept'] = (self.command_accept, _("Usage: /accept [jid]\nAccept: Allow the provided JID (or the selected contact in your roster), to see your presence."), self.completion_deny) + self.commands['add'] = (self.command_add, _("Usage: /add <jid>\nAdd: Add the specified JID to your roster, ask him to allow you to see his presence, and allow him to see your presence."), None) + self.commands['name'] = (self.command_name, _("Usage: /name <jid> <name>\nSet the given JID's name."), self.completion_name) + self.commands['groupadd'] = (self.command_groupadd, _("Usage: /groupadd <jid> <group>\nAdd the given JID to the given group."), self.completion_groupadd) + self.commands['groupremove'] = (self.command_groupremove, _("Usage: /groupremove <jid> <group>\nRemove the given JID from the given group."), self.completion_groupremove) + self.commands['remove'] = (self.command_remove, _("Usage: /remove [jid]\nRemove: Remove the specified JID from your roster. This wil unsubscribe you from its presence, cancel its subscription to yours, and remove the item from your roster."), self.completion_remove) + self.commands['export'] = (self.command_export, _("Usage: /export [/path/to/file]\nExport: Export your contacts into /path/to/file if specified, or $HOME/poezio_contacts if not."), None) + self.commands['import'] = (self.command_import, _("Usage: /import [/path/to/file]\nImport: Import your contacts from /path/to/file if specified, or $HOME/poezio_contacts if not."), None) self.commands['clear_infos'] = (self.command_clear_infos, _("Usage: /clear_infos\nClear Infos: Use this command to clear the info buffer."), None) self.resize() @@ -1872,10 +1877,10 @@ class ConversationTab(ChatTab): # keys self.key_func['^I'] = self.completion # commands - self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: close the tab"), None) - self.commands['close'] = (self.command_unquery, _("Usage: /close\Close: close the tab"), None) - self.commands['version'] = (self.command_version, _('Usage: /version\nVersion: get the software version of the current interlocutor (usually its XMPP client and Operating System)'), None) - self.commands['info'] = (self.command_info, _('Usage: /info\nInfo: get the status of the contact.'), None) + self.commands['unquery'] = (self.command_unquery, _("Usage: /unquery\nUnquery: Close the tab."), None) + self.commands['close'] = (self.command_unquery, _("Usage: /close\Close: Close the tab."), None) + self.commands['version'] = (self.command_version, _('Usage: /version\nVersion: Get the software version of the current interlocutor (usually its XMPP client and Operating System).'), None) + self.commands['info'] = (self.command_info, _('Usage: /info\nInfo: Get the status of the contact.'), None) self.resize() def completion(self): @@ -2029,7 +2034,7 @@ class MucListTab(Tab): self.key_func['j'] = self.join_selected self.key_func['J'] = self.join_selected_no_focus self.key_func['^M'] = self.join_selected - self.commands['close'] = (self.close, _("Usage: /close\nClose: Just close this tab"), None) + self.commands['close'] = (self.close, _("Usage: /close\nClose: Just close this tab."), None) self.resize() def refresh(self): diff --git a/src/windows.py b/src/windows.py index 9fa3e705..2253b871 100644 --- a/src/windows.py +++ b/src/windows.py @@ -367,14 +367,14 @@ class ConversationInfoWin(InfoWin): The line above the information window, displaying informations about the user we are talking to """ - color_show = {'xa':get_theme().COLOR_STATUS_XA, - 'none':get_theme().COLOR_STATUS_ONLINE, - '':get_theme().COLOR_STATUS_ONLINE, - 'available':get_theme().COLOR_STATUS_ONLINE, - 'dnd':get_theme().COLOR_STATUS_DND, - 'away':get_theme().COLOR_STATUS_AWAY, - 'chat':get_theme().COLOR_STATUS_CHAT, - 'unavailable':get_theme().COLOR_STATUS_UNAVAILABLE + color_show = {'xa': lambda: get_theme().COLOR_STATUS_XA, + 'none': lambda: get_theme().COLOR_STATUS_ONLINE, + '': lambda: get_theme().COLOR_STATUS_ONLINE, + 'available': lambda: get_theme().COLOR_STATUS_ONLINE, + 'dnd': lambda: get_theme().COLOR_STATUS_DND, + 'away': lambda: get_theme().COLOR_STATUS_AWAY, + 'chat': lambda: get_theme().COLOR_STATUS_CHAT, + 'unavailable': lambda: get_theme().COLOR_STATUS_UNAVAILABLE } def __init__(self): @@ -416,7 +416,7 @@ class ConversationInfoWin(InfoWin): presence = "unavailable" else: presence = resource.get_presence() - color = RosterWin.color_show[presence] + color = RosterWin.color_show[presence]() self.addstr('[', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.addstr(" ", to_curses_attr(color)) self.addstr(']', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) @@ -634,7 +634,7 @@ class TextWin(Win): self._win.attrset(0) for y, line in enumerate(lines): if not line: - self.write_line_separator() + self.write_line_separator(y) else: self.write_text(y, (3 if line.msg.nickname else 1) + len(line.msg.str_time)+len(truncate_nick(line.msg.nickname) or ''), line.msg.txt[line.start_pos:line.end_pos]) if y != self.height-1: @@ -642,8 +642,8 @@ class TextWin(Win): self._win.attrset(0) self._refresh() - def write_line_separator(self): - self.addnstr('- '*(self.width//2-1)+'-', self.width, to_curses_attr(get_theme().COLOR_NEW_TEXT_SEPARATOR)) + def write_line_separator(self, y): + self.addnstr(y, 0, '- '*(self.width//2-1)+'-', self.width, to_curses_attr(get_theme().COLOR_NEW_TEXT_SEPARATOR)) def write_text(self, y, x, txt): """ @@ -1328,14 +1328,14 @@ class VerticalSeparator(Win): self.rewrite_line() class RosterWin(Win): - color_show = {'xa':get_theme().COLOR_STATUS_XA, - 'none':get_theme().COLOR_STATUS_ONLINE, - '':get_theme().COLOR_STATUS_ONLINE, - 'available':get_theme().COLOR_STATUS_ONLINE, - 'dnd':get_theme().COLOR_STATUS_DND, - 'away':get_theme().COLOR_STATUS_AWAY, - 'chat':get_theme().COLOR_STATUS_CHAT, - 'unavailable':get_theme().COLOR_STATUS_UNAVAILABLE + color_show = {'xa': lambda: get_theme().COLOR_STATUS_XA, + 'none': lambda: get_theme().COLOR_STATUS_ONLINE, + '': lambda: get_theme().COLOR_STATUS_ONLINE, + 'available': lambda: get_theme().COLOR_STATUS_ONLINE, + 'dnd':lambda: get_theme().COLOR_STATUS_DND, + 'away': lambda: get_theme().COLOR_STATUS_AWAY, + 'chat': lambda: get_theme().COLOR_STATUS_CHAT, + 'unavailable': lambda: get_theme().COLOR_STATUS_UNAVAILABLE } def __init__(self): @@ -1473,7 +1473,7 @@ class RosterWin(Win): else: presence = resource.get_presence() nb = ' (%s)' % (contact.get_nb_resources(),) - color = RosterWin.color_show[presence] + color = RosterWin.color_show[presence]() if contact.get_name(): display_name = '%s (%s)%s' % (contact.get_name(), contact.get_bare_jid(), nb,) @@ -1496,7 +1496,7 @@ class RosterWin(Win): """ Draw a specific resource line """ - color = RosterWin.color_show[resource.get_presence()] + color = RosterWin.color_show[resource.get_presence()]() self.addstr(y, 4, " ", to_curses_attr(color)) if colored: self.addstr(y, 6, resource.get_jid().full, to_curses_attr(get_theme().COLOR_SELECTED_ROW)) @@ -9,6 +9,15 @@ echo 'Updating poezio' git pull origin master +make +if [ $? -ne 0 ] +then + echo -e "It seems that you do not have the python development"\ + "files.\nSearch for a package named python3-dev or python3-devel"\ + "in your repos." + exit -1 +fi + if [ -e "SleekXMPP" ] then echo "Updating SleekXMPP" |