Skip to content

Commit

Permalink
VENOM-302: Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
naxuroqa committed Apr 8, 2018
1 parent 3a33368 commit 6628fa2
Show file tree
Hide file tree
Showing 15 changed files with 525 additions and 131 deletions.
26 changes: 22 additions & 4 deletions src/core/Logger.vala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@
*/

namespace Venom {
namespace TermColor {
public const string BLACK = "\x1B[30m";
public const string RED = "\x1B[31m";
public const string GREEN = "\x1B[32m";
public const string YELLOW = "\x1B[33m";
public const string BLUE = "\x1B[34m";
public const string MAGENTA = "\x1B[35m";
public const string CYAN = "\x1B[36m";
public const string WHITE = "\x1B[37m";

public const string RESET = "\x1B[0m";

public const string INFO = TermColor.GREEN;
public const string WARNING = TermColor.YELLOW;
public const string ERROR = TermColor.RED;
public const string FATAL = TermColor.MAGENTA;
}

public enum LogLevel {
DEBUG,
INFO,
Expand All @@ -32,13 +50,13 @@ namespace Venom {
case DEBUG:
return "DEBUG";
case INFO:
return "\x1B[32m" + "INFO " + "\x1B[0m";
return TermColor.INFO + "INFO " + TermColor.RESET;
case WARNING:
return "\x1B[33m" + "WARN " + "\x1B[0m";
return TermColor.WARNING + "WARN " + TermColor.RESET;
case ERROR:
return "\x1B[31m" + "ERROR" + "\x1B[0m";
return TermColor.ERROR + "ERROR" + TermColor.RESET;
case FATAL:
return "\x1B[35m" + "FATAL" + "\x1B[0m";
return TermColor.FATAL + "FATAL" + TermColor.RESET;
default:
assert_not_reached();
}
Expand Down
4 changes: 2 additions & 2 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ venom_source = files(
'ui/ContactListWidget.vala',
'ui/ConversationWindow.vala',
'ui/CreateGroupchatWidget.vala',
'ui/DownloadsEntry.vala',
'ui/DownloadsWidget.vala',
'ui/FileTransferEntry.vala',
'ui/FileTransferWidget.vala',
'ui/FriendInfoWidget.vala',
'ui/FriendRequestWidget.vala',
'ui/MessageWidget.vala',
Expand Down
220 changes: 219 additions & 1 deletion src/tox/ToxAdapterFiletransferListener.vala
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,238 @@

namespace Venom {
public class ToxAdapterFiletransferListenerImpl : ToxAdapterFiletransferListener, GLib.Object {
private const int MAX_AVATAR_SIZE = 250 * 1024;

private unowned ToxSession session;
private ILogger logger;
private NotificationListener notification_listener;

private unowned GLib.HashTable<uint32, IContact> friends;
private GLib.HashTable<IContact, GLib.HashTable<uint32, FileTransfer> > filetransfers;

private FileTransfers transfers;

public ToxAdapterFiletransferListenerImpl(ILogger logger, NotificationListener notification_listener) {
public ToxAdapterFiletransferListenerImpl(ILogger logger, FileTransfers transfers, NotificationListener notification_listener) {
logger.d("ToxAdapterFiletransferListenerImpl created.");
this.logger = logger;
this.notification_listener = notification_listener;
this.transfers = transfers;

filetransfers = new GLib.HashTable<IContact, GLib.HashTable<uint32, FileTransfer> >(null, null);
}

~ToxAdapterFiletransferListenerImpl() {
logger.d("ToxAdapterFiletransferListenerImpl destroyed.");
}

public void attach_to_session(ToxSession session) {
this.session = session;
session.set_filetransfer_listener(this);
friends = session.get_friends();
}

public virtual void on_file_recv_data(uint32 friend_number, uint32 file_number, uint64 file_size, string filename) {
logger.d("on_file_recv_data");

try {
session.file_control(friend_number, file_number, ToxCore.FileControl.RESUME);
var contact = friends.@get(friend_number);
var transfer = new FileTransferImpl.File(logger, file_size, "New file from \"%s\"".printf(contact.get_name_string()));
set_filetransfer(friend_number, file_number, transfer);
transfers.add(transfer);

logger.d("file_control resume sent");
} catch (Error e) {
logger.e("file_control failed: " + e.message);
return;
}
}

public virtual void on_file_recv_avatar(uint32 friend_number, uint32 file_number, uint64 file_size) {
logger.d("on_file_recv_avatar");
if (file_size > MAX_AVATAR_SIZE) {
logger.i("avatar > MAX_AVATAR_SIZE, dropping transfer request");
drop_file_recv_avatar(friend_number, file_number);
return;
}

try {
session.file_control(friend_number, file_number, ToxCore.FileControl.RESUME);
var contact = friends.@get(friend_number);
var transfer = new FileTransferImpl.Avatar(logger, file_size, "New avatar from \"%s\"".printf(contact.get_name_string()));
set_filetransfer(friend_number, file_number, transfer);
transfers.add(transfer);

logger.d("file_control resume sent");
} catch (Error e) {
logger.e("file_control failed: " + e.message);
return;
}
}

private void drop_file_recv_avatar(uint32 friend_number, uint32 file_number) {
try {
session.file_control(friend_number, file_number, ToxCore.FileControl.CANCEL);
} catch (Error e) {
logger.e("dropping transfer request failed: " + e.message);
}
}

private void set_filetransfer(uint32 friend_number, uint32 file_number, FileTransfer transfer) {
var contact = friends.@get(friend_number);
var friend_transfers = init_friend_transfers(contact);
friend_transfers.@set(file_number, transfer);
}

private HashTable<uint32, FileTransfer> init_friend_transfers(IContact contact) {
var friend_transfers = filetransfers.@get(contact);
if (friend_transfers == null) {
friend_transfers = new GLib.HashTable<uint32, FileTransfer>(null, null);
filetransfers.@set(contact, friend_transfers);
}
return friend_transfers;
}

public virtual void on_file_recv_chunk(uint32 friend_number, uint32 file_number, uint64 position, uint8[] data) {
var contact = friends.@get(friend_number);
var friend_transfers = filetransfers.@get(contact);
if (friend_transfers == null) {
logger.e("on_file_recv_chunk no transfer found for contact");
return;
}
var transfer = friend_transfers.@get(file_number);
if (transfer == null) {
logger.e("on_file_recv_chunk no transfer found for file number");
return;
}
if (data.length > 0) {
transfer.set_file_data(position, data);
} else {
var c = contact as Contact;
try {
friend_transfers.remove(file_number);
unowned uint8[] buf = transfer.get_file_data();
var file = File.new_for_path(@"avatar-$(friend_number).png");
file.replace_contents(buf, null, false, FileCreateFlags.NONE, null, null);
c.tox_image = new Gdk.Pixbuf.from_file_at_scale(file.get_path(), 44, 44, true);
c.changed();
} catch (Error e) {
logger.e("set image failed: " + e.message);
}
}
}
}

public interface FileTransfers : GLib.Object {
public signal void added(FileTransfer transfer, uint position);
public signal void removed(FileTransfer transfer, uint position);

public abstract void add(FileTransfer transfer);
public abstract void remove(FileTransfer transfer);

public abstract uint get_size();
public abstract FileTransfer get_item(uint position);

public abstract unowned GLib.List<FileTransfer> get_transfers();
}

public class FileTransfersImpl : FileTransfers, GLib.Object {
private GLib.List<FileTransfer> transfers;
public FileTransfersImpl() {
transfers = new GLib.List<FileTransfer>();
}
public virtual void add(FileTransfer transfer) {
var position = get_size();
transfers.append(transfer);
added(transfer, position);
}
public virtual void remove(FileTransfer transfer) {
var position = index(transfer);
transfers.remove(transfer);
removed(transfer, position);
}
public virtual uint get_size() {
return transfers.length();
}
public virtual FileTransfer get_item(uint position) {
return transfers.nth_data(position);
}
public virtual uint index(FileTransfer transfer) {
return transfers.index(transfer);
}
public virtual unowned GLib.List<FileTransfer> get_transfers() {
return transfers;
}
}

public interface FileTransfer : GLib.Object {
public signal void status_changed();
public signal void progress_changed();

public abstract bool is_avatar();
public abstract string get_description();
public abstract uint64 get_transmitted_size();
public abstract uint64 get_file_size();
public abstract unowned uint8[] get_file_data();
public abstract void set_file_data(uint64 offset, uint8[] data);
}

public class FileTransferImpl : FileTransfer, GLib.Object {
private uint8[] file_data;
private uint64 transmitted_size;
private ILogger logger;
private string description;
//private bool _is_avatar;

public FileTransferImpl.File(ILogger logger, uint64 file_size, string filename) {
this.logger = logger;
this.description = filename;
file_data = new uint8[file_size];
transmitted_size = 0;
//_is_avatar = false;
}

public FileTransferImpl.Avatar(ILogger logger, uint64 file_size, string description) {
this.logger = logger;
this.description = description;
file_data = new uint8[file_size];
transmitted_size = 0;
//_is_avatar = true;
}

private static void copy_with_offset(uint8[] dest, uint8[] src, uint64 offset) {
unowned uint8[] dest_ptr = dest[offset : dest.length];
GLib.Memory.copy(dest_ptr, src, src.length);
}

public virtual bool is_avatar() {
return false; //_is_avatar;
}

public virtual string get_description() {
return description;
}

public virtual uint64 get_transmitted_size() {
return transmitted_size;
}

public virtual uint64 get_file_size() {
return file_data.length;
}

public virtual void set_file_data(uint64 offset, uint8[] data) {
if (data.length + offset > file_data.length) {
logger.e("set_data overflow");
return;
}
copy_with_offset(file_data, data, offset);
transmitted_size += data.length;
progress_changed();
}

public virtual unowned uint8[] get_file_data() {
return file_data;
}
}
}
44 changes: 35 additions & 9 deletions src/tox/ToxSession.vala
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace Venom {
public abstract void conference_set_title(uint32 conference_number, string title) throws ToxError;
public abstract string conference_get_title(uint32 conference_number) throws ToxError;

public abstract void file_control(uint32 friend_number, uint32 file_number, FileControl control) throws ToxError;

public abstract unowned GLib.HashTable<uint32, IContact> get_friends();
}

Expand Down Expand Up @@ -96,7 +98,10 @@ namespace Venom {
}

public interface ToxAdapterFiletransferListener : GLib.Object {
public abstract void on_file_recv_data(uint32 friend_number, uint32 file_number, uint64 file_size, string filename);
public abstract void on_file_recv_avatar(uint32 friend_number, uint32 file_number, uint64 file_size);

public abstract void on_file_recv_chunk(uint32 friend_number, uint32 file_number, uint64 position, uint8[] data);
}

public class ToxSessionImpl : GLib.Object, ToxSession {
Expand Down Expand Up @@ -127,7 +132,7 @@ namespace Venom {
var options_error = ToxCore.ErrOptionsNew.OK;
var options = new ToxCore.Options(ref options_error);

//options.log_callback = on_tox_message;
options.log_callback = on_tox_message;
friends = new GLib.HashTable<uint32, IContact>(null, null);

var savedata = iohandler.load_sessiondata();
Expand Down Expand Up @@ -173,6 +178,7 @@ namespace Venom {
handle.callback_conference_namelist_change(on_conference_namelist_change_cb);

handle.callback_file_recv(on_file_recv_cb);
handle.callback_file_recv_chunk(on_file_recv_chunk_cb);

init_dht_nodes();
sessionThread = new ToxSessionThreadImpl(this, logger, dht_nodes);
Expand All @@ -194,7 +200,8 @@ namespace Venom {
}

public void on_tox_message(Tox self, ToxCore.LogLevel level, string file, uint32 line, string func, string message) {
var msg = "%s: %s".printf(func, message);
var tag = TermColor.YELLOW + "TOX" + TermColor.RESET;
var msg = @"[$tag] $message ($func $file:$line)";
switch (level) {
case ToxCore.LogLevel.TRACE:
case ToxCore.LogLevel.DEBUG:
Expand Down Expand Up @@ -366,14 +373,25 @@ namespace Venom {
private static void on_file_recv_cb(Tox self, uint32 friend_number, uint32 file_number, uint32 kind, uint64 file_size, uint8[] filename, void *user_data) {
var session = (ToxSessionImpl) user_data;
var kind_type = (FileKind) kind;
session.logger.d(@"on_file_recv_cb: $friend_number/$file_number (%s) $file_size kB (%s)".printf(kind_type.to_string(), (string) filename));
// switch (kind_type) {
// case FileKind.DATA:
// Idle.add(() => { session.download_listener.on_file_recv_data(friend_number, file_number, file_size, filename); return false; });
// case FileKind.AVATAR:
// Idle.add(() => { session.download_listener.on_file_recv_avatar(friend_number, file_number, file_size); return false; });
// }
var kiB = file_size / 1024f;
var filename_str = copy_data_string(filename);
var kind_type_str = kind_type.to_string();
session.logger.d(@"on_file_recv_cb: $friend_number/$file_number ($kind_type_str) $kiB kiB ($filename_str)");
switch (kind_type) {
case FileKind.DATA:
Idle.add(() => { session.filetransfer_listener.on_file_recv_data(friend_number, file_number, file_size, filename_str); return false; });
break;
case FileKind.AVATAR:
Idle.add(() => { session.filetransfer_listener.on_file_recv_avatar(friend_number, file_number, file_size); return false; });
break;
}
}

private static void on_file_recv_chunk_cb(Tox self, uint32 friend_number, uint32 file_number, uint64 position, uint8[] data, void* user_data) {
var session = (ToxSessionImpl) user_data;
session.logger.d(@"on_file_recv_chunk_cb: $friend_number/$file_number $position");
var data_copy = copy_data(data, data.length);
Idle.add(() => { session.filetransfer_listener.on_file_recv_chunk(friend_number, file_number, position, data_copy); return false; });
}

private static UserStatus from_connection_status(Connection connection_status) {
Expand Down Expand Up @@ -507,6 +525,14 @@ namespace Venom {
}
}

public virtual void file_control(uint32 friend_number, uint32 file_number, FileControl control) throws ToxError {
var e = ErrFileControl.OK;
handle.file_control(friend_number, file_number, control, ref e);
if (e != ErrFileControl.OK) {
throw new ToxError.GENERIC(e.to_string());
}
}

private void conference_set_title_private(uint32 conference_number, string title) throws ToxError {
var e = ErrConferenceTitle.OK;
handle.conference_set_title(conference_number, title, ref e);
Expand Down

0 comments on commit 6628fa2

Please sign in to comment.