Commit b5209079 authored by Martin's avatar Martin

Merge tag 'upstream/1.0.0-alpha3'

parents 11b3ed3e 5f648fb6
......@@ -88,9 +88,11 @@ Execute gajim with --verbose
That is all, **enjoy**!
(C) 2003-2017
(C) 2003-2018
The Gajim Team
[https://gajim.org](https://gajim.org)
We use original art and parts of sounds and other art from Psi, Gossip, Gnomebaker, Gaim and some icons from various gnome-icons (mostly Dropline Etiquette) we found at art.gnome.org If you think we're violating a license please inform us. Thank you.
\ No newline at end of file
We use original art and parts of sounds and other art from Psi, Gossip, Gnomebaker, Gaim
and some icons from various gnome-icons (mostly Dropline Etiquette) we found at art.gnome.org.
If you think we're violating a license please inform us. Thank you.
environment:
matrix:
- MSYS: "C:\\msys64\\mingw32.exe"
- MSYS: C:/msys64/mingw32
branches:
only:
......@@ -15,24 +14,20 @@ clone_depth: 1
install:
- ps: |
function bash($command) {
Write-Host $command -NoNewline
cmd /c start /wait C:\msys64\usr\bin\sh.exe --login -c $command
Write-Host " - OK" -ForegroundColor Green
}
bash 'pacman -Sy --noconfirm git'
bash 'git clone C:/projects/gajim C:/msys64/home/appveyor/gajim'
- cmd: '%MSYS% C:/msys64/home/appveyor/gajim/win/build.sh'
# Ugly workaround, because i found no way to tell when mingw32.exe returns
- cmd: timeout 900
# Push Installer Exe
- ps: $env:TIME_STRING=(get-date -UFormat "%Y-%m-%d").ToString()
- ps: $env:BUILDROOT="C:\msys64\home\appveyor\gajim\win\_build_root"
- ps: Push-AppveyorArtifact "$($env:BUILDROOT)/Gajim.exe" -FileName "Gajim-Master-$($env:TIME_STRING).exe"
- ps: Push-AppveyorArtifact "$($env:BUILDROOT)/Gajim-Portable.exe" -FileName "Gajim-Portable-Master-$($env:TIME_STRING).exe"
$env:MSYSTEM="MINGW32"
$env:TIME_STRING=(get-date -UFormat "%Y-%m-%d").ToString()
$env:BUILDROOT="C:\msys64\home\appveyor\gajim\win\_build_root"
function bash($command) {
Write-Host $command -NoNewline
C:\msys64\usr\bin\sh.exe --login -c $command
}
bash 'pacman -Sy --noconfirm git'
bash 'git clone C:/projects/gajim C:/msys64/home/appveyor/gajim'
bash 'C:/msys64/home/appveyor/gajim/win/build.sh'
Push-AppveyorArtifact "$($env:BUILDROOT)/Gajim.exe" -FileName "Gajim-Master-$($env:TIME_STRING).exe"
Push-AppveyorArtifact "$($env:BUILDROOT)/Gajim-Portable.exe" -FileName "Gajim-Portable-Master-$($env:TIME_STRING).exe"
build: off
......
.Dd August 26, 2015
.Dd January 21, 2018
.Dt GAJIM-HISTORY-MANAGER 1 URM
.Os UNIX
.Sh NAME
......@@ -46,7 +46,7 @@ and
.Pa THANKS ,
for a complete list.
.Sh COPYRIGHT
Copyright (C) 2003-2015 Gajim Team
Copyright (C) 2003-2018 Gajim Team
.Pp
.Nm
is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 only.
......@@ -59,7 +59,7 @@ You should have received a copy of the GNU General Public License along with
If not, see <https://www.gnu.org/licenses/>.
.Sh FEEDBACK
You can report bugs or feature requests in our bug tracker at
.Em trac.gajim.org
.Em https://dev.gajim.org/gajim/gajim/issues
or in the
.Em gajim-devel
mailing list; if you want to send us a patch, please do so in our bug tracker.
......@@ -80,7 +80,7 @@ More mailing lists at
https://lists.gajim.org/cgi-bin/listinfo
.Ed
.Sh BUGS
Please submit bugs at https://trac.gajim.org/
Please submit bugs at https://dev.gajim.org/gajim/gajim/issues
.Sh SEE ALSO
.Xr gajim 1
.Xr gajim-remote 1
.Dd August 26, 2015
.Dd January 21, 2018
.Dt GAJIM-REMOTE 1 URM
.Os UNIX
.Sh NAME
......@@ -89,7 +89,7 @@ and
.Pa THANKS ,
for a complete list.
.Sh COPYRIGHT
Copyright (C) 2003-2015 Gajim Team
Copyright (C) 2003-2018 Gajim Team
.Pp
.Nm
is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 only.
......@@ -102,7 +102,7 @@ You should have received a copy of the GNU General Public License along with
If not, see <https://www.gnu.org/licenses/>.
.Sh FEEDBACK
You can report bugs or feature requests in our bug tracker at
.Em trac.gajim.org
.Em https://dev.gajim.org/gajim/gajim/issues
or in the
.Em gajim-devel
mailing list; if you want to send us a patch, please do so in our bug tracker.
......@@ -123,7 +123,7 @@ More mailing lists at
https://lists.gajim.org/cgi-bin/listinfo
.Ed
.Sh BUGS
Please submit bugs at https://trac.gajim.org/
Please submit bugs at https://dev.gajim.org/gajim/gajim/issues
.Sh SEE ALSO
.Xr gajim 1
.Xr gajim-history-manager 1
.Dd September 02, 2017
.Dd January 21, 2018
.Dt GAJIM 1 URM
.Os UNIX
.Sh NAME
......@@ -93,7 +93,7 @@ and
with contributions and patches merged from many individuals around the world.
See the About Dialog for a complete list.
.Sh COPYRIGHT
Copyright (C) 2003-2017 Gajim Team
Copyright (C) 2003-2018 Gajim Team
.Pp
.Nm
is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 3 only.
......
import subprocess
__version__ = "0.98.2"
__version__ = "0.98.3"
try:
node = subprocess.Popen('git rev-parse --short=12 HEAD', shell=True,
......
......@@ -37,11 +37,11 @@ class AccountsWindow(Gtk.ApplicationWindow):
self.set_titlebar(self.headerbar)
menu = Gio.Menu()
menu.append('Merge Accounts', 'app.merge')
menu.append('Use PGP Agent', 'app.agent')
menu.append(_('Merge Accounts'), 'app.merge')
menu.append(_('Use PGP Agent'), 'app.agent')
self.menu_button.set_menu_model(menu)
button = get_image_button('list-add-symbolic', 'Add')
button = get_image_button('list-add-symbolic', _('Add'))
button.set_action_name('app.add-account')
self.actionbar.pack_start(button)
......@@ -341,7 +341,7 @@ class Account(Gtk.Box):
self.add(self.label)
if account != app.ZEROCONF_ACC_NAME:
button = get_image_button('list-remove-symbolic', 'Remove')
button = get_image_button('list-remove-symbolic', _('Remove'))
button.connect('clicked', parent.on_remove_account, account)
self.add(button)
......
......@@ -18,9 +18,6 @@
## along with Gajim. If not, see <http://www.gnu.org/licenses/>.
##
import sys
import os
from gi.repository import Gtk
from gajim.common import app
......@@ -277,3 +274,15 @@ class AppActions():
app.interface.handle_event(dict_['account'], dict_['jid'],
dict_['type_'])
# Other Actions
def toggle_ipython(self, action, param):
"""
Show/hide the ipython window
"""
win = app.ipython_window
if win and win.window.is_visible():
win.present()
else:
app.interface.create_ipython_window()
This diff is collapsed.
......@@ -371,8 +371,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
self._schedule_activity_timers()
self.encryption = self.get_encryption_state()
if self.parent_win:
self.add_window_actions()
# PluginSystem: adding GUI extension point for ChatControlBase
# instance object (also subclasses, eg. ChatControl or GroupchatControl)
......@@ -391,7 +389,7 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
# to properly use the super, because of the old code.
CommandTools.__init__(self)
def add_window_actions(self):
def add_actions(self):
action = Gio.SimpleAction.new_stateful(
"set-encryption-%s" % self.control_id,
GLib.VariantType.new("s"),
......@@ -404,6 +402,24 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
action.connect('activate', self._on_history)
self.parent_win.window.add_action(action)
action = Gio.SimpleAction.new(
'send-file-%s' % self.control_id, None)
action.connect('activate', self._on_send_file)
action.set_enabled(False)
self.parent_win.window.add_action(action)
action = Gio.SimpleAction.new(
'send-file-httpupload-%s' % self.control_id, None)
action.connect('activate', self._on_send_httpupload)
action.set_enabled(False)
self.parent_win.window.add_action(action)
action = Gio.SimpleAction.new(
'send-file-jingle-%s' % self.control_id, None)
action.connect('activate', self._on_send_jingle)
action.set_enabled(False)
self.parent_win.window.add_action(action)
# Actions
def _on_history(self, action, param):
......@@ -458,17 +474,16 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
return state
def set_encryption_menu_icon(self):
for child in self.encryption_menu.get_children():
if isinstance(child, Gtk.Image):
image = child
break
image = self.encryption_menu.get_image()
if image is None:
image = Gtk.Image()
self.encryption_menu.set_image(image)
if not self.encryption:
icon = gtkgui_helpers.get_icon_pixmap(
'channel-insecure-symbolic', color=[Color.BLACK])
image.set_from_icon_name('channel-insecure-symbolic',
Gtk.IconSize.MENU)
else:
icon = gtkgui_helpers.get_icon_pixmap('channel-secure-symbolic')
image.set_from_pixbuf(icon)
image.set_from_icon_name('channel-secure-symbolic',
Gtk.IconSize.MENU)
def set_speller(self):
if not app.HAVE_SPELL or not app.config.get('use_speller'):
......@@ -731,6 +746,44 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
self.drag_entered_conv = True
self.conv_textview.tv.set_editable(True)
def drag_data_file_transfer(self, contact, selection, widget):
# get file transfer preference
ft_pref = app.config.get_per('accounts', self.account,
'filetransfer_preference')
win = self.parent_win.window
con = app.connections[self.account]
httpupload = win.lookup_action(
'send-file-httpupload-%s' % self.control_id)
jingle = win.lookup_action('send-file-jingle-%s' % self.control_id)
# we may have more than one file dropped
uri_splitted = selection.get_uris()
for uri in uri_splitted:
path = helpers.get_file_path_from_dnd_dropped_uri(uri)
if not os.path.isfile(path): # is it a file?
continue
if self.type_id == message_control.TYPE_GC:
# groupchat only supports httpupload on drag and drop
if httpupload.get_enabled():
# use httpupload
con.check_file_before_transfer(
path, self.encryption, contact,
self.session, groupchat=True)
else:
if httpupload.get_enabled() and jingle.get_enabled():
if ft_pref == 'httpupload':
con.check_file_before_transfer(
path, self.encryption, contact, self.session)
else:
ft = app.interface.instances['file_transfers']
ft.send_file(self.account, contact, path)
elif httpupload.get_enabled():
con.check_file_before_transfer(
path, self.encryption, contact, self.session)
elif jingle.get_enabled():
ft = app.interface.instances['file_transfers']
ft.send_file(self.account, contact, path)
def get_seclabel(self):
label = None
if self.seclabel_combo is not None:
......@@ -1044,16 +1097,6 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
def on_clear_formatting_menuitem_activate(self, widget):
self.msg_textview.clear_tags()
def on_actions_button_clicked(self, widget):
"""
Popup action menu
"""
menu = self.prepare_context_menu(hide_buttonbar_items=True)
menu.show_all()
menu.attach_to_widget(widget, None)
gtkgui_helpers.popup_emoticons_under_button(menu, widget,
self.parent_win)
def update_tags(self):
self.conv_textview.update_tags()
......@@ -1076,14 +1119,40 @@ class ChatControlBase(MessageControl, ChatCommandProcessor, CommandTools):
app.interface.instances['logs'] = \
history_window.HistoryWindow(jid, self.account)
def _on_send_file(self, gc_contact=None):
def _on_send_file(self, action, param):
# get file transfer preference
ft_pref = app.config.get_per('accounts', self.account,
'filetransfer_preference')
win = self.parent_win.window
httpupload = win.lookup_action(
'send-file-httpupload-%s' % self.control_id)
jingle = win.lookup_action('send-file-jingle-%s' % self.control_id)
if httpupload.get_enabled() and jingle.get_enabled():
if ft_pref == 'httpupload':
httpupload.activate()
else:
jingle.activate()
elif httpupload.get_enabled():
httpupload.activate()
elif jingle.get_enabled():
jingle.activate()
def _on_send_httpupload(self, action, param):
app.interface.send_httpupload(self)
def _on_send_jingle(self, action, param):
self._on_send_file_jingle()
def _on_send_file_jingle(self, gc_contact=None):
"""
gc_contact can be set when we are in a groupchat control
"""
def _on_ok(c):
app.interface.instances['file_transfers'].show_file_send_request(
self.account, c)
if self.TYPE_ID == message_control.TYPE_PM:
if self.type_id == message_control.TYPE_PM:
gc_contact = self.gc_contact
if gc_contact:
# gc or pm
......
......@@ -46,7 +46,7 @@ from nbxmpp import (NS_XHTML_IM, NS_ESESSION, NS_CHATSTATES,
FEATURE_BLACKLIST = [NS_CHATSTATES, NS_XHTML_IM, NS_ESESSION,
NS_JINGLE_ICE_UDP, NS_JINGLE_RTP_AUDIO, NS_JINGLE_RTP_VIDEO,
NS_JINGLE_FILE_TRANSFER_5]
from gajim.common import app
# Query entry status codes
NEW = 0
QUERIED = 1
......@@ -108,37 +108,16 @@ def compute_caps_hash(identities, features, dataforms=None, hash_method='sha-1')
"""
if dataforms is None:
dataforms = []
def sort_identities_func(i1, i2):
cat1 = i1['category']
cat2 = i2['category']
if cat1 < cat2:
return -1
if cat1 > cat2:
return 1
type1 = i1.get('type', '')
type2 = i2.get('type', '')
if type1 < type2:
return -1
if type1 > type2:
return 1
lang1 = i1.get('xml:lang', '')
lang2 = i2.get('xml:lang', '')
if lang1 < lang2:
return -1
if lang1 > lang2:
return 1
return 0
def sort_dataforms_func(d1, d2):
f1 = d1.getField('FORM_TYPE')
f2 = d2.getField('FORM_TYPE')
if f1 and f2 and (f1.getValue() < f2.getValue()):
return -1
return 1
def sort_identities_key(i):
return (i['category'], i.get('type', ''), i.get('xml:lang', ''))
def sort_dataforms_key(dataform):
f = dataform.getField('FORM_TYPE')
return (bool(f), f.getValue())
S = ''
from functools import cmp_to_key
identities.sort(key=cmp_to_key(sort_identities_func))
identities.sort(key=sort_identities_key)
for i in identities:
c = i['category']
type_ = i.get('type', '')
......@@ -148,7 +127,7 @@ def compute_caps_hash(identities, features, dataforms=None, hash_method='sha-1')
features.sort()
for f in features:
S += '%s<' % f
dataforms.sort(key=cmp_to_key(sort_dataforms_func))
dataforms.sort(key=sort_dataforms_key)
for dataform in dataforms:
# fields indexed by var
fields = {}
......@@ -457,6 +436,7 @@ class MucCapsCache:
identities, features, data = [], [], []
query_childs = stanza.getQueryChildren()
if not query_childs:
from gajim.common import app
app.log('gajim.muc').warning('%s returned empty disco info', jid)
return
......
......@@ -339,8 +339,7 @@ class Config:
'keyname': [ opt_str, '', '', True ],
'enable_esessions': [opt_bool, True, _('Enable ESessions encryption for this account.'), True],
'autonegotiate_esessions': [opt_bool, False, _('Should Gajim automatically start an encrypted session when possible?')],
#keep tls, ssl and plain lowercase
'connection_types': [ opt_str, 'tls', _('Ordered list (space separated) of connection type to try. Can contain tls, ssl or plain')],
'allow_plaintext_connection': [ opt_bool, False, _('Allow plaintext connections')],
'tls_version': [ opt_str, '1.2', '' ],
'cipher_list': [ opt_str, 'HIGH:!aNULL:RC4-SHA', '' ],
'authentication_mechanisms': [ opt_str, '', _('List (space separated) of authentication mechanisms to try. Can contain ANONYMOUS, EXTERNAL, GSSAPI, SCRAM-SHA-1-PLUS, SCRAM-SHA-1, DIGEST-MD5, PLAIN, X-MESSENGER-OAUTH2 or XEP-0078') ],
......@@ -409,6 +408,8 @@ class Config:
'oauth2_redirect_url': [ opt_str, 'https%3A%2F%2Fgajim.org%2Fmsnauth%2Findex.cgi', _('redirect_url for OAuth 2.0 authentication.')],
'opened_chat_controls': [opt_str, '', _('Space separated list of JIDs for which we want to re-open a chat window on next startup.')],
'recent_groupchats': [ opt_str, '' ],
'httpupload_verify': [ opt_bool, True, _('HTTP Upload: Enable HTTPS Verification')],
'filetransfer_preference' : [ opt_str, 'httpupload', _('Preferred file transfer mechanism for file drag&drop on chat window. Can be \'httpupload\' (default) or \'jingle\'')],
}, {}),
'statusmsg': ({
'message': [ opt_str, '' ],
......
This diff is collapsed.
......@@ -54,6 +54,7 @@ from gajim.common.protocol.caps import ConnectionCaps
from gajim.common.protocol.bytestream import ConnectionSocks5Bytestream
from gajim.common.protocol.bytestream import ConnectionIBBytestream
from gajim.common.message_archiving import ConnectionArchive313