mirror of
https://github.com/dino/dino.git
synced 2025-07-04 00:02:11 -04:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
322cafdc46 | ||
|
8a1d58cb6f | ||
|
bf0fecf04f | ||
|
1c72f95988 | ||
|
6c258c2f28 | ||
|
aa90175852 | ||
|
d9c1eca888 | ||
|
8b4b2b584f | ||
|
565df4c237 | ||
|
8b508bb6de | ||
|
9646630e1e | ||
|
48404edf47 |
@ -1,31 +0,0 @@
|
||||
include(PkgConfigWithFallback)
|
||||
find_pkg_config_with_fallback(Soup
|
||||
PKG_CONFIG_NAME libsoup-2.4
|
||||
LIB_NAMES soup-2.4
|
||||
INCLUDE_NAMES libsoup/soup.h
|
||||
INCLUDE_DIR_SUFFIXES libsoup-2.4 libsoup-2.4/include libsoup libsoup/include
|
||||
DEPENDS GIO
|
||||
)
|
||||
|
||||
if(Soup_FOUND AND NOT Soup_VERSION)
|
||||
find_file(Soup_VERSION_HEADER "libsoup/soup-version.h" HINTS ${Soup_INCLUDE_DIRS})
|
||||
mark_as_advanced(Soup_VERSION_HEADER)
|
||||
|
||||
if(Soup_VERSION_HEADER)
|
||||
file(STRINGS "${Soup_VERSION_HEADER}" Soup_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MAJOR_VERSION "${Soup_MAJOR_VERSION}")
|
||||
file(STRINGS "${Soup_VERSION_HEADER}" Soup_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MINOR_VERSION "${Soup_MINOR_VERSION}")
|
||||
file(STRINGS "${Soup_VERSION_HEADER}" Soup_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MICRO_VERSION "${Soup_MICRO_VERSION}")
|
||||
set(Soup_VERSION "${Soup_MAJOR_VERSION}.${Soup_MINOR_VERSION}.${Soup_MICRO_VERSION}")
|
||||
unset(Soup_MAJOR_VERSION)
|
||||
unset(Soup_MINOR_VERSION)
|
||||
unset(Soup_MICRO_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Soup
|
||||
REQUIRED_VARS Soup_LIBRARY
|
||||
VERSION_VAR Soup_VERSION)
|
31
cmake/FindSoup2.cmake
Normal file
31
cmake/FindSoup2.cmake
Normal file
@ -0,0 +1,31 @@
|
||||
include(PkgConfigWithFallback)
|
||||
find_pkg_config_with_fallback(Soup2
|
||||
PKG_CONFIG_NAME libsoup-2.4
|
||||
LIB_NAMES soup-2.4
|
||||
INCLUDE_NAMES libsoup/soup.h
|
||||
INCLUDE_DIR_SUFFIXES libsoup-2.4 libsoup-2.4/include libsoup libsoup/include
|
||||
DEPENDS GIO
|
||||
)
|
||||
|
||||
if(Soup2_FOUND AND NOT Soup2_VERSION)
|
||||
find_file(Soup2_VERSION_HEADER "libsoup/soup-version.h" HINTS ${Soup_INCLUDE_DIRS})
|
||||
mark_as_advanced(Soup2_VERSION_HEADER)
|
||||
|
||||
if(Soup_VERSION_HEADER)
|
||||
file(STRINGS "${Soup2_VERSION_HEADER}" Soup2_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MAJOR_VERSION "${Soup2_MAJOR_VERSION}")
|
||||
file(STRINGS "${Soup2_VERSION_HEADER}" Soup2_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MINOR_VERSION "${Soup2_MINOR_VERSION}")
|
||||
file(STRINGS "${Soup2_VERSION_HEADER}" Soup2_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup_MICRO_VERSION "${Soup2_MICRO_VERSION}")
|
||||
set(Soup_VERSION "${Soup2_MAJOR_VERSION}.${Soup2_MINOR_VERSION}.${Soup2_MICRO_VERSION}")
|
||||
unset(Soup2_MAJOR_VERSION)
|
||||
unset(Soup2_MINOR_VERSION)
|
||||
unset(Soup2_MICRO_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Soup2
|
||||
REQUIRED_VARS Soup2_LIBRARY
|
||||
VERSION_VAR Soup2_VERSION)
|
31
cmake/FindSoup3.cmake
Normal file
31
cmake/FindSoup3.cmake
Normal file
@ -0,0 +1,31 @@
|
||||
include(PkgConfigWithFallback)
|
||||
find_pkg_config_with_fallback(Soup3
|
||||
PKG_CONFIG_NAME libsoup-3.0
|
||||
LIB_NAMES soup-3.0
|
||||
INCLUDE_NAMES libsoup/soup.h
|
||||
INCLUDE_DIR_SUFFIXES libsoup-2.4 libsoup-2.4/include libsoup libsoup/include
|
||||
DEPENDS GIO
|
||||
)
|
||||
|
||||
if(Soup3_FOUND AND NOT Soup3_VERSION)
|
||||
find_file(Soup3_VERSION_HEADER "libsoup/soup-version.h" HINTS ${Soup3_INCLUDE_DIRS})
|
||||
mark_as_advanced(Soup3_VERSION_HEADER)
|
||||
|
||||
if(Soup3_VERSION_HEADER)
|
||||
file(STRINGS "${Soup3_VERSION_HEADER}" Soup3_MAJOR_VERSION REGEX "^#define SOUP_MAJOR_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MAJOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup3_MAJOR_VERSION "${Soup3_MAJOR_VERSION}")
|
||||
file(STRINGS "${Soup3_VERSION_HEADER}" Soup3_MINOR_VERSION REGEX "^#define SOUP_MINOR_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MINOR_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup3_MINOR_VERSION "${Soup3_MINOR_VERSION}")
|
||||
file(STRINGS "${Soup3_VERSION_HEADER}" Soup3_MICRO_VERSION REGEX "^#define SOUP_MICRO_VERSION +\\(?([0-9]+)\\)?$")
|
||||
string(REGEX REPLACE "^#define SOUP_MICRO_VERSION \\(?([0-9]+)\\)?$" "\\1" Soup3_MICRO_VERSION "${Soup3_MICRO_VERSION}")
|
||||
set(Soup3_VERSION "${Soup3_MAJOR_VERSION}.${Soup3_MINOR_VERSION}.${Soup3_MICRO_VERSION}")
|
||||
unset(Soup3_MAJOR_VERSION)
|
||||
unset(Soup3_MINOR_VERSION)
|
||||
unset(Soup3_MICRO_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Soup3
|
||||
REQUIRED_VARS Soup3_LIBRARY
|
||||
VERSION_VAR Soup3_VERSION)
|
@ -20,6 +20,7 @@ function(find_packages result)
|
||||
find_package(${pkg} ${pkg_version} REQUIRED)
|
||||
list(APPEND _res ${${pkg}_PKG_CONFIG_NAME})
|
||||
list(APPEND _res_libs ${${pkg}_LIBRARIES})
|
||||
set(${pkg}_VERSION "${${pkg}_VERSION}" PARENT_SCOPE)
|
||||
endforeach(pkg)
|
||||
foreach(pkg ${ARGS_OPTIONAL})
|
||||
string(REPLACE ">=" ";" pkg_ ${pkg})
|
||||
@ -38,6 +39,7 @@ function(find_packages result)
|
||||
if(${pkg}_FOUND)
|
||||
list(APPEND _res ${${pkg}_PKG_CONFIG_NAME})
|
||||
list(APPEND _res_libs ${${pkg}_LIBRARIES})
|
||||
set(${pkg}_VERSION "${${pkg}_VERSION}" PARENT_SCOPE)
|
||||
endif()
|
||||
endforeach(pkg)
|
||||
set(${result} "${_res}" PARENT_SCOPE)
|
||||
|
33
cmake/SoupVersion.cmake
Normal file
33
cmake/SoupVersion.cmake
Normal file
@ -0,0 +1,33 @@
|
||||
find_package(Nice QUIET)
|
||||
if (Nice_FOUND AND NOT SOUP_VERSION AND NOT USE_SOUP3)
|
||||
file(GET_RUNTIME_DEPENDENCIES
|
||||
RESOLVED_DEPENDENCIES_VAR Nice_DEPENDENCIES
|
||||
UNRESOLVED_DEPENDENCIES_VAR Nice_UNRESOLVED_DEPENDENCIES
|
||||
LIBRARIES ${Nice_LIBRARY}
|
||||
PRE_INCLUDE_REGEXES "soup|gupnp"
|
||||
PRE_EXCLUDE_REGEXES "."
|
||||
)
|
||||
foreach (lib ${Nice_DEPENDENCIES})
|
||||
if (lib MATCHES ".*/libsoup-3.*")
|
||||
set(SOUP_VERSION 3)
|
||||
endif ()
|
||||
endforeach ()
|
||||
foreach (lib ${Nice_DEPENDENCIES})
|
||||
if (lib MATCHES ".*/libsoup-2.*")
|
||||
set(SOUP_VERSION 2)
|
||||
endif ()
|
||||
endforeach ()
|
||||
set(SOUP_VERSION ${SOUP_VERSION} CACHE STRING "Version of libsoup to use")
|
||||
set_property(CACHE SOUP_VERSION PROPERTY STRINGS "2" "3")
|
||||
message(STATUS "Using Soup${SOUP_VERSION} to provide Soup")
|
||||
elseif (NOT SOUP_VERSION)
|
||||
find_package(Soup2 QUIET)
|
||||
find_package(Soup3 QUIET)
|
||||
# Only use libsoup 3 if specifically requested or when libsoup 2 is not available
|
||||
if (Soup3_FOUND AND NOT Soup2_FOUND OR USE_SOUP3)
|
||||
set(SOUP_VERSION 3)
|
||||
else ()
|
||||
set(SOUP_VERSION 2)
|
||||
endif ()
|
||||
endif ()
|
||||
set(Soup "Soup${SOUP_VERSION}")
|
6
configure
vendored
6
configure
vendored
@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
OPTS=`getopt -o "h" --long \
|
||||
help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsignal-in-tree,\
|
||||
help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsignal-in-tree,with-libsoup3,\
|
||||
enable-plugin:,disable-plugin:,\
|
||||
prefix:,program-prefix:,exec-prefix:,lib-suffix:,\
|
||||
bindir:,libdir:,includedir:,datadir:,\
|
||||
@ -22,6 +22,7 @@ DISABLE_FAST_VAPI=
|
||||
LIB_SUFFIX=
|
||||
NO_DEBUG=
|
||||
FETCH_ONLY=
|
||||
USE_SOUP3=
|
||||
|
||||
EXEC_PREFIX=
|
||||
BINDIR=
|
||||
@ -56,6 +57,7 @@ Configuration:
|
||||
--release Configure to build an optimized release version
|
||||
--with-libsignal-in-tree Build libsignal-protocol-c in tree and link it
|
||||
statically.
|
||||
--with-libsoup3 Build with libsoup-3.0
|
||||
--with-tests Also build tests.
|
||||
|
||||
Plugin configuration:
|
||||
@ -111,6 +113,7 @@ while true; do
|
||||
--valac-flags ) VALAC_FLAGS="$2"; shift; shift ;;
|
||||
--lib-suffix ) LIB_SUFFIX="$2"; shift; shift ;;
|
||||
--with-libsignal-in-tree ) BUILD_LIBSIGNAL_IN_TREE=yes; shift ;;
|
||||
--with-libsoup3 ) USE_SOUP3=yes; shift ;;
|
||||
--disable-fast-vapi ) DISABLE_FAST_VAPI=yes; shift ;;
|
||||
--no-debug ) NO_DEBUG=yes; shift ;;
|
||||
--fetch-only ) FETCH_ONLY=yes; shift ;;
|
||||
@ -256,6 +259,7 @@ cmake -G "$cmake_type" \
|
||||
-DDISABLED_PLUGINS="$DISABLED_PLUGINS" \
|
||||
-DBUILD_TESTS="$BUILD_TESTS" \
|
||||
-DBUILD_LIBSIGNAL_IN_TREE="$BUILD_LIBSIGNAL_IN_TREE" \
|
||||
-DUSE_SOUP3="$USE_SOUP3" \
|
||||
-DVALA_EXECUTABLE="$VALAC" \
|
||||
-DCMAKE_VALA_FLAGS="$VALACFLAGS" \
|
||||
-DDISABLE_FAST_VAPI="$DISABLE_FAST_VAPI" \
|
||||
|
@ -89,7 +89,7 @@ DEPENDS
|
||||
${CMAKE_BINARY_DIR}/exports/dino_i18n.h
|
||||
)
|
||||
|
||||
add_definitions(${VALA_CFLAGS} -DDINO_SYSTEM_PLUGIN_DIR="${PLUGIN_INSTALL_DIR}" -DDINO_SYSTEM_LIBDIR_NAME="${LIBDIR_NAME}" -DG_LOG_DOMAIN="libdino")
|
||||
add_definitions(${VALA_CFLAGS} -DDINO_SYSTEM_PLUGIN_DIR="${PLUGIN_INSTALL_DIR}" -DDINO_SYSTEM_LIBDIR_NAME="${LIBDIR_NAME}" -DG_LOG_DOMAIN="libdino" -DDINO_VERSION=\"${PROJECT_VERSION}\")
|
||||
add_library(libdino SHARED ${LIBDINO_VALA_C} ${CMAKE_BINARY_DIR}/exports/dino_i18n.h)
|
||||
add_dependencies(libdino dino-vapi)
|
||||
target_link_libraries(libdino xmpp-vala qlite ${LIBDINO_PACKAGES} m)
|
||||
|
@ -1,7 +1,13 @@
|
||||
using Dino.Entities;
|
||||
|
||||
namespace Dino {
|
||||
|
||||
extern const string VERSION;
|
||||
public string get_version() { return VERSION; }
|
||||
public string get_short_version() {
|
||||
if (!VERSION.contains("~")) return VERSION;
|
||||
return VERSION.split("~")[0] + "+";
|
||||
}
|
||||
|
||||
public interface Application : GLib.Application {
|
||||
|
||||
|
@ -70,6 +70,7 @@ public class FileTransfer : Object {
|
||||
public State state { get; set; default=State.NOT_STARTED; }
|
||||
public int provider { get; set; }
|
||||
public string info { get; set; }
|
||||
public Cancellable cancellable { get; default=new Cancellable(); }
|
||||
|
||||
private Database? db;
|
||||
private string storage_dir;
|
||||
|
@ -45,7 +45,10 @@ public class Dino.PeerState : Object {
|
||||
this.stream_interactor = stream_interactor;
|
||||
this.calls = stream_interactor.get_module(Calls.IDENTITY);
|
||||
|
||||
var session_info_type = stream_interactor.module_manager.get_module(call.account, Xep.JingleRtp.Module.IDENTITY).session_info_type;
|
||||
Xep.JingleRtp.Module jinglertp_module = stream_interactor.module_manager.get_module(call.account, Xep.JingleRtp.Module.IDENTITY);
|
||||
if (jinglertp_module == null) return;
|
||||
|
||||
var session_info_type = jinglertp_module.session_info_type;
|
||||
session_info_type.mute_update_received.connect((session,mute, name) => {
|
||||
if (this.sid != session.sid) return;
|
||||
|
||||
|
@ -246,7 +246,15 @@ public class FileManager : StreamInteractionModule, Object {
|
||||
File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename));
|
||||
|
||||
OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION);
|
||||
yield os.splice_async(input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE|OutputStreamSpliceFlags.CLOSE_TARGET);
|
||||
uint8[] buffer = new uint8[1024];
|
||||
ssize_t read;
|
||||
while ((read = yield input_stream.read_async(buffer, Priority.LOW, file_transfer.cancellable)) > 0) {
|
||||
buffer.length = (int) read;
|
||||
yield os.write_async(buffer, Priority.LOW, file_transfer.cancellable);
|
||||
buffer.length = 1024;
|
||||
}
|
||||
yield input_stream.close_async(Priority.LOW, file_transfer.cancellable);
|
||||
yield os.close_async(Priority.LOW, file_transfer.cancellable);
|
||||
file_transfer.path = file.get_basename();
|
||||
file_transfer.input_stream = yield file.read_async();
|
||||
|
||||
@ -292,14 +300,15 @@ public class FileManager : StreamInteractionModule, Object {
|
||||
if (is_sender_trustworthy(file_transfer, conversation)) {
|
||||
try {
|
||||
yield get_file_meta(file_provider, file_transfer, conversation, receive_data);
|
||||
|
||||
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
|
||||
yield download_file_internal(file_provider, file_transfer, conversation);
|
||||
}
|
||||
} catch (Error e) {
|
||||
warning("Error downloading file: %s", e.message);
|
||||
file_transfer.state = FileTransfer.State.FAILED;
|
||||
}
|
||||
if (file_transfer.size >= 0 && file_transfer.size < 5000000) {
|
||||
download_file_internal.begin(file_provider, file_transfer, conversation, (_, res) => {
|
||||
download_file_internal.end(res);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
conversation.last_active = file_transfer.time;
|
||||
|
@ -48,7 +48,7 @@ public abstract class Gee.TestCase : Object {
|
||||
}
|
||||
|
||||
public GLib.TestSuite get_suite () {
|
||||
return this.suite;
|
||||
return (owned) this.suite;
|
||||
}
|
||||
|
||||
private class Adaptor {
|
||||
|
@ -212,7 +212,7 @@ OPTIONS
|
||||
${MAIN_EXTRA_OPTIONS}
|
||||
)
|
||||
|
||||
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\" -DDINO_VERSION=\"${PROJECT_VERSION}\")
|
||||
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\")
|
||||
add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET} src/emojichooser.c)
|
||||
add_dependencies(dino ${GETTEXT_PACKAGE}-translations)
|
||||
target_include_directories(dino PRIVATE src)
|
||||
|
@ -42,7 +42,7 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
||||
|
||||
startup.connect(() => {
|
||||
if (print_version) {
|
||||
print(@"Dino $(Dino.VERSION)\n");
|
||||
print(@"Dino $(Dino.get_version())\n");
|
||||
Process.exit(0);
|
||||
}
|
||||
|
||||
@ -270,7 +270,7 @@ public class Dino.Ui.Application : Gtk.Application, Dino.Application {
|
||||
}
|
||||
|
||||
private void show_about_window() {
|
||||
string? version = Dino.VERSION.strip().length == 0 ? null : Dino.VERSION;
|
||||
string? version = Dino.get_version().strip().length == 0 ? null : Dino.get_version();
|
||||
if (version != null && !version.contains("git")) {
|
||||
switch (version.substring(0, 3)) {
|
||||
case "0.2": version = @"$version - <span font_style='italic'>Mexican Caribbean Coral Reefs</span>"; break;
|
||||
|
@ -19,6 +19,7 @@ public class FileDefaultWidget : EventBox {
|
||||
|
||||
public ModelButton file_open_button;
|
||||
public ModelButton file_save_button;
|
||||
public ModelButton cancel_button;
|
||||
|
||||
private FileTransfer.State state;
|
||||
|
||||
@ -27,6 +28,7 @@ public class FileDefaultWidget : EventBox {
|
||||
this.leave_notify_event.connect(on_pointer_left_event);
|
||||
file_open_button = new ModelButton() { text=_("Open"), visible=true };
|
||||
file_save_button = new ModelButton() { text=_("Save as…"), visible=true };
|
||||
cancel_button = new ModelButton() { text=_("Cancel"), visible=true };
|
||||
}
|
||||
|
||||
public void update_file_info(string? mime_type, FileTransfer.State state, long size) {
|
||||
@ -59,6 +61,18 @@ public class FileDefaultWidget : EventBox {
|
||||
mime_label.label = _("Downloading %s…").printf(get_size_string(size));
|
||||
spinner.active = true;
|
||||
image_stack.set_visible_child_name("spinner");
|
||||
|
||||
// Create a menu
|
||||
Gtk.PopoverMenu popover_menu = new Gtk.PopoverMenu();
|
||||
Box file_menu_box = new Box(Orientation.VERTICAL, 0) { margin=10, visible=true };
|
||||
file_menu_box.add(cancel_button);
|
||||
popover_menu.add(file_menu_box);
|
||||
file_menu.popover = popover_menu;
|
||||
file_menu.button_release_event.connect(() => {
|
||||
popover_menu.visible = true;
|
||||
return true;
|
||||
});
|
||||
popover_menu.closed.connect(on_pointer_left);
|
||||
break;
|
||||
case FileTransfer.State.NOT_STARTED:
|
||||
if (mime_description != null) {
|
||||
@ -84,7 +98,7 @@ public class FileDefaultWidget : EventBox {
|
||||
if (state == FileTransfer.State.NOT_STARTED) {
|
||||
image_stack.set_visible_child_name("download_image");
|
||||
}
|
||||
if (state == FileTransfer.State.COMPLETE) {
|
||||
if (state == FileTransfer.State.COMPLETE || state == FileTransfer.State.IN_PROGRESS) {
|
||||
file_menu.opacity = 1;
|
||||
}
|
||||
return false;
|
||||
|
@ -131,6 +131,7 @@ public class FileDefaultWidgetController : Object {
|
||||
widget.button_release_event.connect(on_clicked);
|
||||
widget.file_open_button.clicked.connect(open_file);
|
||||
widget.file_save_button.clicked.connect(save_file);
|
||||
widget.cancel_button.clicked.connect(cancel_download);
|
||||
}
|
||||
|
||||
public void set_file_transfer(FileTransfer file_transfer, StreamInteractor stream_interactor) {
|
||||
@ -186,6 +187,10 @@ public class FileDefaultWidgetController : Object {
|
||||
}
|
||||
}
|
||||
|
||||
private void cancel_download() {
|
||||
file_transfer.cancellable.cancel();
|
||||
}
|
||||
|
||||
private bool on_clicked(EventButton event_button) {
|
||||
switch (state) {
|
||||
case FileTransfer.State.COMPLETE:
|
||||
|
@ -259,7 +259,7 @@ public static string parse_add_markup_theme(string s_, string? highlight_word, b
|
||||
theme_dependent = true;
|
||||
quote_match_info.fetch_pos(0, out start, out end);
|
||||
return parse_add_markup_theme(s[0:start], highlight_word, parse_links, parse_text_markup, parse_quotes, dark_theme, ref theme_dependent, already_escaped) +
|
||||
@"<span color='$dim_color'>$gt " + parse_add_markup_theme(s[start + gt.length + 1:end], highlight_word, parse_links, parse_text_markup, false, dark_theme, ref theme_dependent, already_escaped) + "</span>" +
|
||||
@"<span color='$dim_color'>$gt" + parse_add_markup_theme(s[start + gt.length:end], highlight_word, parse_links, parse_text_markup, false, dark_theme, ref theme_dependent, already_escaped) + "</span>" +
|
||||
parse_add_markup_theme(s[end:s.length], highlight_word, parse_links, parse_text_markup, parse_quotes, dark_theme, ref theme_dependent, already_escaped);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,19 @@
|
||||
include(SoupVersion)
|
||||
find_packages(HTTP_FILES_PACKAGES REQUIRED
|
||||
Gee
|
||||
GLib
|
||||
GModule
|
||||
GObject
|
||||
GTK3
|
||||
Soup
|
||||
${Soup}
|
||||
)
|
||||
|
||||
set(HTTP_FILES_DEFINITIONS)
|
||||
|
||||
if(${Soup}_VERSION VERSION_GREATER_EQUAL "3.0")
|
||||
set(HTTP_FILES_DEFINITIONS ${HTTP_FILES_DEFINITIONS} SOUP_3_0)
|
||||
endif()
|
||||
|
||||
vala_precompile(HTTP_FILES_VALA_C
|
||||
SOURCES
|
||||
src/file_provider.vala
|
||||
@ -19,6 +26,8 @@ CUSTOM_VAPIS
|
||||
${CMAKE_BINARY_DIR}/exports/qlite.vapi
|
||||
PACKAGES
|
||||
${HTTP_FILES_PACKAGES}
|
||||
DEFINITIONS
|
||||
${HTTP_FILES_DEFINITIONS}
|
||||
)
|
||||
|
||||
add_definitions(${VALA_CFLAGS})
|
||||
|
@ -46,6 +46,38 @@ public class FileProvider : Dino.FileProvider, Object {
|
||||
}
|
||||
}
|
||||
|
||||
private class LimitInputStream : InputStream {
|
||||
InputStream inner;
|
||||
int64 remaining_size;
|
||||
|
||||
public LimitInputStream(InputStream inner, int64 max_size) {
|
||||
this.inner = inner;
|
||||
this.remaining_size = max_size;
|
||||
}
|
||||
|
||||
private ssize_t check_limit(ssize_t read) throws IOError {
|
||||
this.remaining_size -= read;
|
||||
if (remaining_size < 0) throw new IOError.FAILED("Stream length exceeded limit");
|
||||
return read;
|
||||
}
|
||||
|
||||
public override ssize_t read(uint8[] buffer, Cancellable? cancellable = null) throws IOError {
|
||||
return check_limit(inner.read(buffer, cancellable));
|
||||
}
|
||||
|
||||
public override async ssize_t read_async(uint8[]? buffer, int io_priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws IOError {
|
||||
return check_limit(yield inner.read_async(buffer, io_priority, cancellable));
|
||||
}
|
||||
|
||||
public override bool close(Cancellable? cancellable = null) throws IOError {
|
||||
return inner.close(cancellable);
|
||||
}
|
||||
|
||||
public override async bool close_async(int io_priority = GLib.Priority.DEFAULT, Cancellable? cancellable = null) throws IOError {
|
||||
return yield inner.close_async(io_priority, cancellable);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_file_message(Entities.Message message, Conversation conversation) {
|
||||
var additional_info = message.id.to_string();
|
||||
|
||||
@ -64,24 +96,28 @@ public class FileProvider : Dino.FileProvider, Object {
|
||||
if (http_receive_data == null) return file_meta;
|
||||
|
||||
var session = new Soup.Session();
|
||||
session.user_agent = @"Dino/$(Dino.get_short_version()) ";
|
||||
var head_message = new Soup.Message("HEAD", http_receive_data.url);
|
||||
head_message.request_headers.append("Accept-Encoding", "identity");
|
||||
|
||||
if (head_message != null) {
|
||||
try {
|
||||
#if SOUP_3_0
|
||||
yield session.send_async(head_message, GLib.Priority.LOW, null);
|
||||
#else
|
||||
yield session.send_async(head_message, null);
|
||||
#endif
|
||||
} catch (Error e) {
|
||||
throw new FileReceiveError.GET_METADATA_FAILED("HEAD request failed");
|
||||
}
|
||||
|
||||
string? content_type = null, content_length = null;
|
||||
head_message.response_headers.foreach((name, val) => {
|
||||
if (name == "Content-Type") content_type = val;
|
||||
if (name == "Content-Length") content_length = val;
|
||||
if (name.down() == "content-type") content_type = val;
|
||||
if (name.down() == "content-length") content_length = val;
|
||||
});
|
||||
file_meta.mime_type = content_type;
|
||||
if (content_length != null) {
|
||||
file_meta.size = int.parse(content_length);
|
||||
}
|
||||
file_meta.size = int64.parse(content_length);
|
||||
}
|
||||
|
||||
return file_meta;
|
||||
@ -95,11 +131,21 @@ public class FileProvider : Dino.FileProvider, Object {
|
||||
HttpFileReceiveData? http_receive_data = receive_data as HttpFileReceiveData;
|
||||
if (http_receive_data == null) assert(false);
|
||||
|
||||
try {
|
||||
var session = new Soup.Session();
|
||||
Soup.Request request = session.request(http_receive_data.url);
|
||||
session.user_agent = @"Dino/$(Dino.get_short_version()) ";
|
||||
var get_message = new Soup.Message("GET", http_receive_data.url);
|
||||
|
||||
return yield request.send_async(null);
|
||||
try {
|
||||
#if SOUP_3_0
|
||||
InputStream stream = yield session.send_async(get_message, GLib.Priority.LOW, file_transfer.cancellable);
|
||||
#else
|
||||
InputStream stream = yield session.send_async(get_message, file_transfer.cancellable);
|
||||
#endif
|
||||
if (file_meta.size != -1) {
|
||||
return new LimitInputStream(stream, file_meta.size);
|
||||
} else {
|
||||
return stream;
|
||||
}
|
||||
} catch (Error e) {
|
||||
throw new FileReceiveError.DOWNLOAD_FAILED("Downloading file error: %s".printf(e.message));
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ public class HttpFileSender : FileSender, Object {
|
||||
}
|
||||
}
|
||||
|
||||
#if !SOUP_3_0
|
||||
private static void transfer_more_bytes(InputStream stream, Soup.MessageBody body) {
|
||||
uint8[] bytes = new uint8[4096];
|
||||
ssize_t read = stream.read(bytes);
|
||||
@ -83,25 +84,35 @@ public class HttpFileSender : FileSender, Object {
|
||||
bytes.length = (int)read;
|
||||
body.append_buffer(new Soup.Buffer.take(bytes));
|
||||
}
|
||||
#endif
|
||||
|
||||
private async void upload(FileTransfer file_transfer, HttpFileSendData file_send_data, FileMeta file_meta) throws FileSendError {
|
||||
Xmpp.XmppStream? stream = stream_interactor.get_stream(file_transfer.account);
|
||||
if (stream == null) return;
|
||||
|
||||
Soup.Message message = new Soup.Message("PUT", file_send_data.url_up);
|
||||
message.request_headers.set_content_type(file_meta.mime_type, null);
|
||||
message.request_headers.set_content_length(file_meta.size);
|
||||
var session = new Soup.Session();
|
||||
session.user_agent = @"Dino/$(Dino.get_short_version()) ";
|
||||
var put_message = new Soup.Message("PUT", file_send_data.url_up);
|
||||
#if SOUP_3_0
|
||||
put_message.set_request_body(file_meta.mime_type, file_transfer.input_stream, (ssize_t) file_meta.size);
|
||||
#else
|
||||
put_message.request_headers.set_content_type(file_meta.mime_type, null);
|
||||
put_message.request_headers.set_content_length(file_meta.size);
|
||||
put_message.request_body.set_accumulate(false);
|
||||
put_message.wrote_headers.connect(() => transfer_more_bytes(file_transfer.input_stream, put_message.request_body));
|
||||
put_message.wrote_chunk.connect(() => transfer_more_bytes(file_transfer.input_stream, put_message.request_body));
|
||||
#endif
|
||||
foreach (var entry in file_send_data.headers.entries) {
|
||||
message.request_headers.append(entry.key, entry.value);
|
||||
put_message.request_headers.append(entry.key, entry.value);
|
||||
}
|
||||
message.request_body.set_accumulate(false);
|
||||
message.wrote_headers.connect(() => transfer_more_bytes(file_transfer.input_stream, message.request_body));
|
||||
message.wrote_chunk.connect(() => transfer_more_bytes(file_transfer.input_stream, message.request_body));
|
||||
Soup.Session session = new Soup.Session();
|
||||
try {
|
||||
yield session.send_async(message);
|
||||
if (message.status_code < 200 || message.status_code >= 300) {
|
||||
throw new FileSendError.UPLOAD_FAILED("HTTP status code %s".printf(message.status_code.to_string()));
|
||||
#if SOUP_3_0
|
||||
yield session.send_async(put_message, GLib.Priority.LOW, file_transfer.cancellable);
|
||||
#else
|
||||
yield session.send_async(put_message, file_transfer.cancellable);
|
||||
#endif
|
||||
if (put_message.status_code < 200 || put_message.status_code >= 300) {
|
||||
throw new FileSendError.UPLOAD_FAILED("HTTP status code %s".printf(put_message.status_code.to_string()));
|
||||
}
|
||||
} catch (Error e) {
|
||||
throw new FileSendError.UPLOAD_FAILED("HTTP upload error: %s".printf(e.message));
|
||||
|
@ -76,7 +76,7 @@ public class Handler {
|
||||
int err = 0;
|
||||
|
||||
X509.PrivateKey private_key = X509.PrivateKey.create();
|
||||
err = private_key.generate(PKAlgorithm.RSA, 2048);
|
||||
err = private_key.generate(PKAlgorithm.ECDSA, 256);
|
||||
throw_if_error(err);
|
||||
|
||||
var start_time = new DateTime.now_local().add_days(1);
|
||||
|
@ -221,7 +221,8 @@ namespace GnuTLS {
|
||||
public enum PKAlgorithm {
|
||||
UNKNOWN,
|
||||
RSA,
|
||||
DSA;
|
||||
DSA,
|
||||
ECDSA;
|
||||
}
|
||||
|
||||
[CCode (cname = "gnutls_digest_algorithm_t", cprefix = "GNUTLS_DIG_", has_type_id = false)]
|
||||
|
@ -15,15 +15,15 @@ find_packages(RTP_PACKAGES REQUIRED
|
||||
|
||||
set(RTP_DEFINITIONS)
|
||||
|
||||
if(GstRtp_VERSION VERSION_GREATER "1.16")
|
||||
if(GstRtp_VERSION VERSION_GREATER_EQUAL "1.16")
|
||||
set(RTP_DEFINITIONS ${RTP_DEFINITIONS} GST_1_16)
|
||||
endif()
|
||||
|
||||
if(GstRtp_VERSION VERSION_GREATER "1.18")
|
||||
if(GstRtp_VERSION VERSION_GREATER_EQUAL "1.18")
|
||||
set(RTP_DEFINITIONS ${RTP_DEFINITIONS} GST_1_18)
|
||||
endif()
|
||||
|
||||
if(GLib_VERSION VERSION_GREATER "2.64")
|
||||
if(GLib_VERSION VERSION_GREATER_EQUAL "2.64")
|
||||
set(RTP_DEFINITIONS ${RTP_DEFINITIONS} GLIB_2_64)
|
||||
endif()
|
||||
|
||||
|
@ -354,6 +354,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
|
||||
int best_height = 0;
|
||||
for (int i = 0; i < device.caps.get_size(); i++) {
|
||||
unowned Gst.Structure? that = device.caps.get_structure(i);
|
||||
Value? best_fraction_now = null;
|
||||
if (!that.has_name("video/x-raw")) continue;
|
||||
int num = 0, den = 0, width = 0, height = 0;
|
||||
if (!that.has_field("framerate")) continue;
|
||||
@ -369,7 +370,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
|
||||
int fps = den > 0 ? (num/den) : 0;
|
||||
int in_fps = in_den > 0 ? (in_num/in_den) : 0;
|
||||
if (in_fps > fps) {
|
||||
best_fraction = fraction;
|
||||
best_fraction_now = fraction;
|
||||
num = in_num;
|
||||
den = in_den;
|
||||
}
|
||||
@ -386,6 +387,7 @@ public class Dino.Plugins.Rtp.Device : MediaDevice, Object {
|
||||
best_width = width;
|
||||
best_height = height;
|
||||
best_index = i;
|
||||
best_fraction = best_fraction_now;
|
||||
}
|
||||
}
|
||||
Gst.Caps res = caps_copy_nth(device.caps, best_index);
|
||||
|
@ -382,9 +382,27 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||
int fps = 0;
|
||||
for (int i = 0; i < device.device.caps.get_size(); i++) {
|
||||
unowned Gst.Structure structure = device.device.caps.get_structure(i);
|
||||
int num = 0, den = 0;
|
||||
if (structure.has_field("framerate") && structure.get_fraction("framerate", out num, out den)) fps = int.max(fps, num / den);
|
||||
|
||||
if (structure.has_field("framerate")) {
|
||||
Value framerate = structure.get_value("framerate");
|
||||
if (framerate.type() == typeof(Gst.Fraction)) {
|
||||
int num = Gst.Value.get_fraction_numerator(framerate);
|
||||
int den = Gst.Value.get_fraction_denominator(framerate);
|
||||
fps = int.max(fps, num / den);
|
||||
} else if (framerate.type() == typeof(Gst.ValueList)) {
|
||||
for(uint j = 0; j < Gst.ValueList.get_size(framerate); j++) {
|
||||
Value fraction = Gst.ValueList.get_value(framerate, j);
|
||||
int num = Gst.Value.get_fraction_numerator(fraction);
|
||||
int den = Gst.Value.get_fraction_denominator(fraction);
|
||||
fps = int.max(fps, num / den);
|
||||
}
|
||||
} else {
|
||||
debug("Unknown type for framerate %s on device %s", framerate.type_name(), device.display_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug("Max framerate for device %s: %d", device.display_name, fps);
|
||||
return fps;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ public abstract class Gee.TestCase : Object {
|
||||
}
|
||||
|
||||
public GLib.TestSuite get_suite () {
|
||||
return this.suite;
|
||||
return (owned) this.suite;
|
||||
}
|
||||
|
||||
private class Adaptor {
|
||||
|
@ -56,7 +56,7 @@ public abstract class Gee.TestCase : Object {
|
||||
}
|
||||
|
||||
public GLib.TestSuite get_suite () {
|
||||
return this.suite;
|
||||
return (owned) this.suite;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user