mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-25 23:49:35 -05:00
Merge branch 'master' into TheWire-rework-ui
This commit is contained in:
commit
bcaef29d49
37
build_scripts/Windows-msys2/build/build-webui.bat
Normal file
37
build_scripts/Windows-msys2/build/build-webui.bat
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
@echo off
|
||||||
|
|
||||||
|
setlocal
|
||||||
|
|
||||||
|
:: Initialize environment
|
||||||
|
call "%~dp0..\env.bat"
|
||||||
|
if errorlevel 1 goto error_env
|
||||||
|
call "%EnvPath%\env.bat"
|
||||||
|
if errorlevel 1 goto error_env
|
||||||
|
call "%EnvPath%\env.bat"
|
||||||
|
if errorlevel 1 goto error_env
|
||||||
|
call "%EnvPath%\env-msys2.bat"
|
||||||
|
if errorlevel 1 goto error_env
|
||||||
|
|
||||||
|
:: Initialize base environment
|
||||||
|
call "%~dp0env-base.bat" %*
|
||||||
|
if errorlevel 2 exit /B 2
|
||||||
|
if errorlevel 1 goto error_env
|
||||||
|
|
||||||
|
:: Initialize environment
|
||||||
|
call "%~dp0env.bat" %*
|
||||||
|
if errorlevel 2 exit /B 2
|
||||||
|
if errorlevel 1 goto error_env
|
||||||
|
|
||||||
|
call "%~dp0..\tools\webui.bat"
|
||||||
|
|
||||||
|
:error
|
||||||
|
|
||||||
|
title %COMSPEC%
|
||||||
|
|
||||||
|
if errorlevel 1 echo.& echo Webui generation failed& echo.
|
||||||
|
exit /B %ERRORLEVEL%
|
||||||
|
|
||||||
|
:error_env
|
||||||
|
echo Failed to initialize environment.
|
||||||
|
endlocal
|
||||||
|
exit /B 1
|
@ -18,7 +18,7 @@ if errorlevel 2 exit /B 2
|
|||||||
if errorlevel 1 goto error_env
|
if errorlevel 1 goto error_env
|
||||||
|
|
||||||
:: Install needed things
|
:: Install needed things
|
||||||
%EnvMSYS2Cmd% "pacman --noconfirm --needed -S make git mingw-w64-%RsMSYS2Architecture%-toolchain mingw-w64-%RsMSYS2Architecture%-qt5 mingw-w64-%RsMSYS2Architecture%-miniupnpc mingw-w64-%RsMSYS2Architecture%-sqlcipher mingw-w64-%RsMSYS2Architecture%-libmicrohttpd mingw-w64-%RsMSYS2Architecture%-xapian-core mingw-w64-%RsMSYS2Architecture%-cmake mingw-w64-%RsMSYS2Architecture%-rapidjson"
|
%EnvMSYS2Cmd% "pacman --noconfirm --needed -S make git mingw-w64-%RsMSYS2Architecture%-toolchain mingw-w64-%RsMSYS2Architecture%-qt5 mingw-w64-%RsMSYS2Architecture%-miniupnpc mingw-w64-%RsMSYS2Architecture%-sqlcipher mingw-w64-%RsMSYS2Architecture%-xapian-core mingw-w64-%RsMSYS2Architecture%-cmake mingw-w64-%RsMSYS2Architecture%-rapidjson"
|
||||||
|
|
||||||
:: Plugins
|
:: Plugins
|
||||||
if "%ParamPlugins%"=="1" %EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-speex mingw-w64-%RsMSYS2Architecture%-speexdsp mingw-w64-%RsMSYS2Architecture%-curl mingw-w64-%RsMSYS2Architecture%-libxslt mingw-w64-%RsMSYS2Architecture%-opencv mingw-w64-%RsMSYS2Architecture%-ffmpeg"
|
if "%ParamPlugins%"=="1" %EnvMSYS2Cmd% "pacman --noconfirm --needed -S mingw-w64-%RsMSYS2Architecture%-speex mingw-w64-%RsMSYS2Architecture%-speexdsp mingw-w64-%RsMSYS2Architecture%-curl mingw-w64-%RsMSYS2Architecture%-libxslt mingw-w64-%RsMSYS2Architecture%-opencv mingw-w64-%RsMSYS2Architecture%-ffmpeg"
|
||||||
@ -52,6 +52,12 @@ set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=%RsBuildConfig%"
|
|||||||
if "%ParamAutologin%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=rs_autologin"
|
if "%ParamAutologin%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=rs_autologin"
|
||||||
if "%ParamPlugins%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=retroshare_plugins"
|
if "%ParamPlugins%"=="1" set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=retroshare_plugins"
|
||||||
|
|
||||||
|
:: Dump the active build config into a file
|
||||||
|
echo %RS_QMAKE_CONFIG% > buildinfo.txt
|
||||||
|
echo %RsBuildConfig% >> buildinfo.txt
|
||||||
|
echo %RsArchitecture% >> buildinfo.txt
|
||||||
|
echo Qt %QtVersion% >> buildinfo.txt
|
||||||
|
|
||||||
call "%ToolsPath%\msys2-path.bat" "%SourcePath%" MSYS2SourcePath
|
call "%ToolsPath%\msys2-path.bat" "%SourcePath%" MSYS2SourcePath
|
||||||
call "%ToolsPath%\msys2-path.bat" "%EnvMSYS2Path%" MSYS2EnvMSYS2Path
|
call "%ToolsPath%\msys2-path.bat" "%EnvMSYS2Path%" MSYS2EnvMSYS2Path
|
||||||
%EnvMSYS2Cmd% "qmake "%MSYS2SourcePath%/RetroShare.pro" -r -spec win32-g++ %RS_QMAKE_CONFIG%"
|
%EnvMSYS2Cmd% "qmake "%MSYS2SourcePath%/RetroShare.pro" -r -spec win32-g++ %RS_QMAKE_CONFIG%"
|
||||||
@ -65,6 +71,11 @@ title Build - %SourceName%-%RsBuildConfig% [make]
|
|||||||
|
|
||||||
%EnvMSYS2Cmd% "make -j %NUMBER_OF_PROCESSORS%"
|
%EnvMSYS2Cmd% "make -j %NUMBER_OF_PROCESSORS%"
|
||||||
|
|
||||||
|
:: Webui
|
||||||
|
if "%ParamWebui%"=="1" (
|
||||||
|
call "%~dp0..\tools\webui.bat"
|
||||||
|
)
|
||||||
|
|
||||||
:error
|
:error
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ set ParamDebug=0
|
|||||||
set ParamAutologin=0
|
set ParamAutologin=0
|
||||||
set ParamPlugins=0
|
set ParamPlugins=0
|
||||||
set ParamTor=0
|
set ParamTor=0
|
||||||
|
set ParamWebui=0
|
||||||
set RS_QMAKE_CONFIG=
|
set RS_QMAKE_CONFIG=
|
||||||
|
|
||||||
:parameter_loop
|
:parameter_loop
|
||||||
@ -25,6 +26,8 @@ if "%~1" NEQ "" (
|
|||||||
set ParamPlugins=1
|
set ParamPlugins=1
|
||||||
) else if "%%~a"=="tor" (
|
) else if "%%~a"=="tor" (
|
||||||
set ParamTor=1
|
set ParamTor=1
|
||||||
|
) else if "%%~a"=="webui" (
|
||||||
|
set ParamWebui=1
|
||||||
) else if "%%~a"=="CONFIG+" (
|
) else if "%%~a"=="CONFIG+" (
|
||||||
set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% %1
|
set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% %1
|
||||||
) else (
|
) else (
|
||||||
@ -75,12 +78,15 @@ if "%ParamTor%"=="1" (
|
|||||||
set RsType=
|
set RsType=
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if "%ParamWebui%"=="1" (
|
||||||
|
set RS_QMAKE_CONFIG=%RS_QMAKE_CONFIG% "CONFIG+=rs_jsonapi" "CONFIG+=rs_webui"
|
||||||
|
)
|
||||||
|
|
||||||
exit /B 0
|
exit /B 0
|
||||||
|
|
||||||
:usage
|
:usage
|
||||||
echo.
|
echo.
|
||||||
echo Usage: 32^|64 release^|debug [version autologin plugins]
|
echo Usage: 32^|64 release^|debug [version autologin plugins webui]
|
||||||
echo.
|
echo.
|
||||||
echo Mandatory parameter
|
echo Mandatory parameter
|
||||||
echo 32^|64 32-bit or 64-bit Version
|
echo 32^|64 32-bit or 64-bit Version
|
||||||
@ -89,6 +95,7 @@ echo.
|
|||||||
echo Optional parameter (need clean when changed)
|
echo Optional parameter (need clean when changed)
|
||||||
echo autologin Build with autologin
|
echo autologin Build with autologin
|
||||||
echo plugins Build plugins
|
echo plugins Build plugins
|
||||||
|
echo webui Enable JsonAPI and pack webui files
|
||||||
echo.
|
echo.
|
||||||
echo Parameter for pack
|
echo Parameter for pack
|
||||||
echo tor Pack tor version
|
echo tor Pack tor version
|
||||||
|
@ -20,6 +20,7 @@ set RsBuildPath=%BuildPath%\Qt-%QtVersion%-%RsArchitecture%-%RsBuildConfig%
|
|||||||
set RsDeployPath=%DeployPath%\Qt-%QtVersion%%RsType%-%RsArchitecture%-%RsBuildConfig%
|
set RsDeployPath=%DeployPath%\Qt-%QtVersion%%RsType%-%RsArchitecture%-%RsBuildConfig%
|
||||||
set RsPackPath=%DeployPath%
|
set RsPackPath=%DeployPath%
|
||||||
set RsArchiveAdd=
|
set RsArchiveAdd=
|
||||||
|
set RsWebuiPath=%RootPath%\%SourceName%-webui
|
||||||
|
|
||||||
if not exist "%~dp0env-mod.bat" goto no_mod
|
if not exist "%~dp0env-mod.bat" goto no_mod
|
||||||
call "%~dp0env-mod.bat"
|
call "%~dp0env-mod.bat"
|
||||||
|
@ -23,7 +23,7 @@ call "%ToolsPath%\find-in-path.bat" GitPath git.exe
|
|||||||
if "%GitPath%"=="" echo Git executable not found in PATH.& exit /B 1
|
if "%GitPath%"=="" echo Git executable not found in PATH.& exit /B 1
|
||||||
|
|
||||||
:: Get compiled revision
|
:: Get compiled revision
|
||||||
set GetRsVersion=%SourcePath%\build_scripts\Windows\tools\get-rs-version.bat
|
set GetRsVersion=%SourcePath%\build_scripts\Windows-msys2\tools\get-rs-version.bat
|
||||||
if not exist "%GetRsVersion%" (
|
if not exist "%GetRsVersion%" (
|
||||||
echo File not found
|
echo File not found
|
||||||
echo %GetRsVersion%
|
echo %GetRsVersion%
|
||||||
|
@ -17,6 +17,9 @@ call "%~dp0env.bat" %*
|
|||||||
if errorlevel 2 exit /B 2
|
if errorlevel 2 exit /B 2
|
||||||
if errorlevel 1 goto error_env
|
if errorlevel 1 goto error_env
|
||||||
|
|
||||||
|
:: Install ntldd
|
||||||
|
%EnvMSYS2Cmd% "pacman --noconfirm --needed -S make git mingw-w64-%RsMSYS2Architecture%-ntldd-git"
|
||||||
|
|
||||||
:: Remove deploy path
|
:: Remove deploy path
|
||||||
if exist "%RsDeployPath%" rmdir /S /Q "%RsDeployPath%"
|
if exist "%RsDeployPath%" rmdir /S /Q "%RsDeployPath%"
|
||||||
|
|
||||||
@ -24,7 +27,7 @@ if exist "%RsDeployPath%" rmdir /S /Q "%RsDeployPath%"
|
|||||||
if not exist "%RsBuildPath%\Makefile" echo Project is not compiled.& goto error
|
if not exist "%RsBuildPath%\Makefile" echo Project is not compiled.& goto error
|
||||||
|
|
||||||
:: Get compiled revision
|
:: Get compiled revision
|
||||||
set GetRsVersion=%SourcePath%\build_scripts\Windows\tools\get-rs-version.bat
|
set GetRsVersion=%SourcePath%\build_scripts\Windows-msys2\tools\get-rs-version.bat
|
||||||
if not exist "%GetRsVersion%" (
|
if not exist "%GetRsVersion%" (
|
||||||
%cecho% error "File not found"
|
%cecho% error "File not found"
|
||||||
echo %GetRsVersion%
|
echo %GetRsVersion%
|
||||||
@ -100,16 +103,13 @@ echo copy binaries
|
|||||||
copy "%RsBuildPath%\retroshare-gui\src\%RsBuildConfig%\RetroShare*.exe" "%RsDeployPath%" %Quite%
|
copy "%RsBuildPath%\retroshare-gui\src\%RsBuildConfig%\RetroShare*.exe" "%RsDeployPath%" %Quite%
|
||||||
copy "%RsBuildPath%\retroshare-nogui\src\%RsBuildConfig%\retroshare*-nogui.exe" "%RsDeployPath%" %Quite%
|
copy "%RsBuildPath%\retroshare-nogui\src\%RsBuildConfig%\retroshare*-nogui.exe" "%RsDeployPath%" %Quite%
|
||||||
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
|
copy "%RsBuildPath%\retroshare-service\src\%RsBuildConfig%\retroshare*-service.exe" "%RsDeployPath%" %Quite%
|
||||||
|
copy "%RsBuildPath%\supportlibs\cmark\build\src\libcmark.dll" "%RsDeployPath%" %Quite%
|
||||||
|
|
||||||
echo copy extensions
|
echo copy extensions
|
||||||
for /D %%D in ("%RsBuildPath%\plugins\*") do (
|
for /D %%D in ("%RsBuildPath%\plugins\*") do (
|
||||||
call :copy_extension "%%D" "%RsDeployPath%\Data\%Extensions%"
|
call :copy_extension "%%D" "%RsDeployPath%\Data\%Extensions%"
|
||||||
call :copy_dependencies "%RsDeployPath%\Data\%Extensions%\%%~nxD.dll" "%RsDeployPath%"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
echo copy dependencies
|
|
||||||
call :copy_dependencies "%RsDeployPath%\retroshare.exe" "%RsDeployPath%"
|
|
||||||
|
|
||||||
echo copy Qt DLL's
|
echo copy Qt DLL's
|
||||||
copy "%RsMinGWPath%\bin\Qt%QtMainVersion1%Svg%QtMainVersion2%.dll" "%RsDeployPath%" %Quite%
|
copy "%RsMinGWPath%\bin\Qt%QtMainVersion1%Svg%QtMainVersion2%.dll" "%RsDeployPath%" %Quite%
|
||||||
|
|
||||||
@ -128,7 +128,9 @@ if exist "%QtSharePath%\plugins\styles\qwindowsvistastyle.dll" (
|
|||||||
|
|
||||||
copy "%QtSharePath%\plugins\imageformats\*.dll" "%RsDeployPath%\imageformats" %Quite%
|
copy "%QtSharePath%\plugins\imageformats\*.dll" "%RsDeployPath%\imageformats" %Quite%
|
||||||
del /Q "%RsDeployPath%\imageformats\*d?.dll" %Quite%
|
del /Q "%RsDeployPath%\imageformats\*d?.dll" %Quite%
|
||||||
for %%D in ("%RsDeployPath%\imageformats\*.dll") do (
|
|
||||||
|
echo copy dependencies
|
||||||
|
for /R "%RsDeployPath%" %%D in (*.dll, *.exe) do (
|
||||||
call :copy_dependencies "%%D" "%RsDeployPath%"
|
call :copy_dependencies "%%D" "%RsDeployPath%"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -161,10 +163,18 @@ copy "%SourcePath%\libbitdht\src\bitdht\bdboot.txt" "%RsDeployPath%" %Quite%
|
|||||||
echo copy changelog.txt
|
echo copy changelog.txt
|
||||||
copy "%SourcePath%\retroshare-gui\src\changelog.txt" "%RsDeployPath%" %Quite%
|
copy "%SourcePath%\retroshare-gui\src\changelog.txt" "%RsDeployPath%" %Quite%
|
||||||
|
|
||||||
if exist "%SourcePath%\libresapi\src\webui" (
|
echo copy buildinfo.txt
|
||||||
|
copy "%RsBuildPath%\buildinfo.txt" "%RsDeployPath%" %Quite%
|
||||||
|
|
||||||
|
if "%ParamWebui%"=="1" (
|
||||||
|
if exist "%RsWebuiPath%\webui" (
|
||||||
echo copy webui
|
echo copy webui
|
||||||
mkdir "%RsDeployPath%\webui"
|
mkdir "%RsDeployPath%\webui"
|
||||||
xcopy /S "%SourcePath%\libresapi\src\webui" "%RsDeployPath%\webui" %Quite%
|
xcopy /S "%RsWebuiPath%\webui" "%RsDeployPath%\webui" %Quite%
|
||||||
|
) else (
|
||||||
|
%cecho% error "Webui is enabled, but no webui data found at %RsWebuiPath%\webui"
|
||||||
|
goto error
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if "%ParamTor%"=="1" (
|
if "%ParamTor%"=="1" (
|
||||||
@ -204,14 +214,11 @@ if exist "%~1\%RsBuildConfig%\%~n1.dll" (
|
|||||||
goto :EOF
|
goto :EOF
|
||||||
|
|
||||||
:copy_dependencies
|
:copy_dependencies
|
||||||
set CopyDependenciesCopiedSomething=0
|
for /F "usebackq" %%A in (`%ToolsPath%\depends.bat %1`) do (
|
||||||
for /F "usebackq" %%A in (`%ToolsPath%\depends.bat list %1`) do (
|
|
||||||
if not exist "%~2\%%A" (
|
if not exist "%~2\%%A" (
|
||||||
if exist "%RsMinGWPath%\bin\%%A" (
|
if exist "%RsMinGWPath%\bin\%%A" (
|
||||||
set CopyDependenciesCopiedSomething=1
|
|
||||||
copy "%RsMinGWPath%\bin\%%A" %2 %Quite%
|
copy "%RsMinGWPath%\bin\%%A" %2 %Quite%
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
if "%CopyDependenciesCopiedSomething%"=="1" goto copy_dependencies
|
|
||||||
goto :EOF
|
goto :EOF
|
||||||
|
2
build_scripts/Windows-msys2/env/env.bat
vendored
2
build_scripts/Windows-msys2/env/env.bat
vendored
@ -7,9 +7,7 @@ set EnvToolsPath=%EnvRootPath%\tools
|
|||||||
set EnvTempPath=%EnvRootPath%\tmp
|
set EnvTempPath=%EnvRootPath%\tmp
|
||||||
set EnvDownloadPath=%EnvRootPath%\download
|
set EnvDownloadPath=%EnvRootPath%\download
|
||||||
|
|
||||||
set EnvWgetExe=%EnvToolsPath%\wget.exe
|
|
||||||
set EnvSevenZipExe=%EnvToolsPath%\7z.exe
|
set EnvSevenZipExe=%EnvToolsPath%\7z.exe
|
||||||
set EnvDependsExe=%EnvToolsPath%\depends.exe
|
|
||||||
set EnvCEchoExe=%EnvToolsPath%\cecho.exe
|
set EnvCEchoExe=%EnvToolsPath%\cecho.exe
|
||||||
set cecho=call "%ToolsPath%\cecho.bat"
|
set cecho=call "%ToolsPath%\cecho.bat"
|
||||||
|
|
||||||
|
@ -6,22 +6,6 @@ set CEchoUrl=https://github.com/lordmulder/cecho/releases/download/2015-10-10/ce
|
|||||||
set CEchoInstall=cecho.2015-10-10.zip
|
set CEchoInstall=cecho.2015-10-10.zip
|
||||||
set SevenZipUrl=https://sourceforge.net/projects/sevenzip/files/7-Zip/18.05/7z1805.msi/download
|
set SevenZipUrl=https://sourceforge.net/projects/sevenzip/files/7-Zip/18.05/7z1805.msi/download
|
||||||
set SevenZipInstall=7z1805.msi
|
set SevenZipInstall=7z1805.msi
|
||||||
set WgetUrl=https://eternallybored.org/misc/wget/1.19.4/32/wget.exe
|
|
||||||
set WgetInstall=wget.exe
|
|
||||||
set DependsUrl=http://www.dependencywalker.com/depends22_x86.zip
|
|
||||||
set DependsInstall=depends22_x86.zip
|
|
||||||
set SigcheckInstall=Sigcheck.zip
|
|
||||||
set SigcheckUrl=https://download.sysinternals.com/files/%SigcheckInstall%
|
|
||||||
|
|
||||||
if not exist "%EnvToolsPath%\wget.exe" (
|
|
||||||
echo Download Wget installation
|
|
||||||
|
|
||||||
if not exist "%EnvDownloadPath%\%WgetInstall%" call "%ToolsPath%\winhttpjs.bat" %WgetUrl% -saveTo "%EnvDownloadPath%\%WgetInstall%"
|
|
||||||
if not exist "%EnvDownloadPath%\%WgetInstall%" %cecho% error "Cannot download Wget installation" & goto error
|
|
||||||
|
|
||||||
echo Copy Wget
|
|
||||||
copy "%EnvDownloadPath%\wget.exe" "%EnvToolsPath%"
|
|
||||||
)
|
|
||||||
|
|
||||||
if not exist "%EnvToolsPath%\7z.exe" (
|
if not exist "%EnvToolsPath%\7z.exe" (
|
||||||
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
|
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
|
||||||
@ -56,32 +40,6 @@ if not exist "%EnvToolsPath%\cecho.exe" (
|
|||||||
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
|
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
|
||||||
)
|
)
|
||||||
|
|
||||||
if not exist "%EnvToolsPath%\depends.exe" (
|
|
||||||
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
|
|
||||||
mkdir "%EnvTempPath%"
|
|
||||||
|
|
||||||
%cecho% info "Download Dependency Walker installation"
|
|
||||||
|
|
||||||
if not exist "%EnvDownloadPath%\%DependsInstall%" call "%ToolsPath%\winhttpjs.bat" %DependsUrl% -saveTo "%EnvDownloadPath%\%DependsInstall%"
|
|
||||||
if not exist "%EnvDownloadPath%\%DependsInstall%" %cecho% error "Cannot download Dependendy Walker installation" & goto error
|
|
||||||
|
|
||||||
%cecho% info "Unpack Dependency Walker"
|
|
||||||
"%EnvSevenZipExe%" x -o"%EnvTempPath%" "%EnvDownloadPath%\%DependsInstall%"
|
|
||||||
copy "%EnvTempPath%\*" "%EnvToolsPath%"
|
|
||||||
|
|
||||||
call "%ToolsPath%\remove-dir.bat" "%EnvTempPath%"
|
|
||||||
)
|
|
||||||
|
|
||||||
if not exist "%EnvToolsPath%\sigcheck.exe" (
|
|
||||||
%cecho% info "Download Sigcheck installation"
|
|
||||||
|
|
||||||
if not exist "%EnvDownloadPath%\%SigcheckInstall%" call "%ToolsPath%\download-file.bat" "%SigcheckUrl%" "%EnvDownloadPath%\%SigcheckInstall%"
|
|
||||||
if not exist "%EnvDownloadPath%\%SigcheckInstall%" %cecho% error "Cannot download Sigcheck installation" & goto error
|
|
||||||
|
|
||||||
%cecho% info "Unpack Sigcheck"
|
|
||||||
"%EnvSevenZipExe%" x -o"%EnvToolsPath%" "%EnvDownloadPath%\%SigcheckInstall%" sigcheck.exe
|
|
||||||
)
|
|
||||||
|
|
||||||
:exit
|
:exit
|
||||||
endlocal
|
endlocal
|
||||||
exit /B 0
|
exit /B 0
|
||||||
|
@ -1,40 +1,22 @@
|
|||||||
:: Usage:
|
:: Usage:
|
||||||
:: call depends.bat [list^|missing] file
|
:: call depends.bat file
|
||||||
|
|
||||||
if "%2"=="" (
|
if "%1"=="" (
|
||||||
echo Usage: %~nx0 [list^|missing] File
|
echo Usage: %~nx0 File
|
||||||
exit /B 1
|
exit /B 1
|
||||||
)
|
)
|
||||||
|
|
||||||
setlocal
|
setlocal
|
||||||
|
pushd %~dp1
|
||||||
|
|
||||||
if not exist "%EnvDependsExe%" echo depends.exe not found in %EnvToolsPath%.& exit /B 1
|
%EnvMSYS2Cmd% "ntldd --recursive $0 | cut -f1 -d"=" | awk '{$1=$1};1'" %~nx1 > %~sdp0depends.tmp
|
||||||
|
|
||||||
set CutPath=
|
for /F %%A in (%~sdp0depends.tmp) do (
|
||||||
call "%ToolsPath%\find-in-path.bat" CutPath cut.exe
|
|
||||||
if "%CutPath%"=="" echo cut.exe not found in PATH.& exit /B 1
|
|
||||||
|
|
||||||
start /wait "" "%EnvDependsExe%" /c /oc:"%~dp0depends.tmp" %2
|
|
||||||
if "%1"=="missing" (
|
|
||||||
cut.exe --delimiter=, --fields=1,2 "%~dp0depends.tmp" >"%~dp0depends1.tmp"
|
|
||||||
for /F "tokens=1,2 delims=," %%A in (%~sdp0depends1.tmp) do (
|
|
||||||
if "%%A"=="?" (
|
|
||||||
echo %%~B
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%1"=="list" (
|
|
||||||
cut.exe --delimiter=, --fields=2 "%~dp0depends.tmp" >"%~dp0depends1.tmp"
|
|
||||||
for /F "tokens=1 delims=," %%A in (%~sdp0depends1.tmp) do (
|
|
||||||
if "%%A" NEQ "Module" (
|
|
||||||
echo %%~A
|
echo %%~A
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if exist "%~dp0depends.tmp" del /Q "%~dp0depends.tmp"
|
if exist "%~dp0depends.tmp" del /Q "%~dp0depends.tmp"
|
||||||
if exist "%~dp0depends1.tmp" del /Q "%~dp0depends1.tmp"
|
|
||||||
|
|
||||||
|
popd
|
||||||
endlocal
|
endlocal
|
||||||
exit /B 0
|
exit /B 0
|
@ -7,7 +7,6 @@ if "%~2"=="" (
|
|||||||
exit /B 1
|
exit /B 1
|
||||||
)
|
)
|
||||||
|
|
||||||
::"%EnvCurlExe%" -L -k "%~1" -o "%~2"
|
powershell -NoLogo -NoProfile -Command (New-Object System.Net.WebClient).DownloadFile(\""%~1\"", \""%~2\"")
|
||||||
"%EnvWgetExe%" --no-check-certificate --continue "%~1" --output-document="%~2"
|
|
||||||
|
|
||||||
exit /B %ERRORLEVEL%
|
exit /B %ERRORLEVEL%
|
||||||
|
@ -27,7 +27,7 @@ set VersionMinor=
|
|||||||
set VersionMini=
|
set VersionMini=
|
||||||
set VersionExtra=
|
set VersionExtra=
|
||||||
|
|
||||||
for /F "tokens=1,2,3,* delims=.-" %%A in ('%EnvToolsPath%\sigcheck.exe -nobanner -n %Executable%') do (
|
for /F "USEBACKQ tokens=1,2,3,* delims=.-" %%A in (`powershell -NoLogo -NoProfile -Command ^(Get-Item "%Executable%"^).VersionInfo.FileVersion`) do (
|
||||||
set VersionMajor=%%A
|
set VersionMajor=%%A
|
||||||
set VersionMinor=%%B
|
set VersionMinor=%%B
|
||||||
set VersionMini=%%C
|
set VersionMini=%%C
|
||||||
|
20
build_scripts/Windows-msys2/tools/webui.bat
Normal file
20
build_scripts/Windows-msys2/tools/webui.bat
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
setlocal
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo === webui
|
||||||
|
echo.
|
||||||
|
title Build webui
|
||||||
|
|
||||||
|
if not exist "%RsWebuiPath%" (
|
||||||
|
echo Checking out webui source into %RsWebuiPath%
|
||||||
|
%EnvMSYS2Cmd% "pacman --noconfirm --needed -S git"
|
||||||
|
git clone https://github.com/RetroShare/RSNewWebUI.git "%RsWebuiPath%"
|
||||||
|
) else (
|
||||||
|
echo Webui source found at %RsWebuiPath%
|
||||||
|
)
|
||||||
|
|
||||||
|
pushd "%RsWebuiPath%\webui-src\make-src"
|
||||||
|
%EnvMSYS2Cmd% "sh build.sh"
|
||||||
|
popd
|
||||||
|
|
||||||
|
endlocal
|
@ -1,584 +0,0 @@
|
|||||||
@if (@X) == (@Y) @end /* JScript comment
|
|
||||||
@echo off
|
|
||||||
|
|
||||||
rem :: the first argument is the script name as it will be used for proper help message
|
|
||||||
cscript //E:JScript //nologo "%~f0" "%~nx0" %*
|
|
||||||
|
|
||||||
exit /b %errorlevel%
|
|
||||||
|
|
||||||
@if (@X)==(@Y) @end JScript comment */
|
|
||||||
|
|
||||||
// used resources
|
|
||||||
|
|
||||||
// update 12.10.15
|
|
||||||
// osvikvi(https://github.com/osvikvi) has nodited that the -password option is not set , so this is fixed
|
|
||||||
|
|
||||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa384058(v=vs.85).aspx
|
|
||||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa384055(v=vs.85).aspx
|
|
||||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa384059(v=vs.85).aspx
|
|
||||||
|
|
||||||
// global variables and constants
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------
|
|
||||||
// -- asynch requests not included --
|
|
||||||
// ----------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
//todo - save responceStream instead of responceBody !!
|
|
||||||
//todo - set all winthttp options ->//https://msdn.microsoft.com/en-us/library/windows/desktop/aa384108(v=vs.85).aspx
|
|
||||||
//todo - log all options
|
|
||||||
//todo - improve help message . eventual verbose option
|
|
||||||
|
|
||||||
|
|
||||||
var ARGS = WScript.Arguments;
|
|
||||||
var scriptName = ARGS.Item(0);
|
|
||||||
|
|
||||||
var url = "";
|
|
||||||
var saveTo = "";
|
|
||||||
|
|
||||||
var user = 0;
|
|
||||||
var pass = 0;
|
|
||||||
|
|
||||||
var proxy = 0;
|
|
||||||
var bypass = 0;
|
|
||||||
var proxy_user = 0;
|
|
||||||
var proxy_pass = 0;
|
|
||||||
|
|
||||||
var certificate = 0;
|
|
||||||
|
|
||||||
var force = true;
|
|
||||||
|
|
||||||
var body = "";
|
|
||||||
|
|
||||||
//ActiveX objects
|
|
||||||
var WinHTTPObj = new ActiveXObject("WinHttp.WinHttpRequest.5.1");
|
|
||||||
var FileSystemObj = new ActiveXObject("Scripting.FileSystemObject");
|
|
||||||
var AdoDBObj = new ActiveXObject("ADODB.Stream");
|
|
||||||
|
|
||||||
// HttpRequest SetCredentials flags.
|
|
||||||
var proxy_settings = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
HTTPREQUEST_SETCREDENTIALS_FOR_SERVER = 0;
|
|
||||||
HTTPREQUEST_SETCREDENTIALS_FOR_PROXY = 1;
|
|
||||||
|
|
||||||
//timeouts and their default values
|
|
||||||
var RESOLVE_TIMEOUT = 0;
|
|
||||||
var CONNECT_TIMEOUT = 90000;
|
|
||||||
var SEND_TIMEOUT = 90000;
|
|
||||||
var RECEIVE_TIMEOUT = 90000;
|
|
||||||
|
|
||||||
//HttpRequestMethod
|
|
||||||
var http_method = 'GET';
|
|
||||||
|
|
||||||
//header
|
|
||||||
var header_file = "";
|
|
||||||
|
|
||||||
//report
|
|
||||||
var reportfile = "";
|
|
||||||
|
|
||||||
//test-this:
|
|
||||||
var use_stream = false;
|
|
||||||
|
|
||||||
//autologon policy
|
|
||||||
var autologon_policy = 1; //0,1,2
|
|
||||||
|
|
||||||
|
|
||||||
//headers will be stored as multi-dimensional array
|
|
||||||
var headers = [];
|
|
||||||
|
|
||||||
//user-agent
|
|
||||||
var ua = "";
|
|
||||||
|
|
||||||
//escape URL
|
|
||||||
var escape = false;
|
|
||||||
|
|
||||||
function printHelp() {
|
|
||||||
WScript.Echo(scriptName + " - sends HTTP request and saves the request body as a file and/or a report of the sent request");
|
|
||||||
WScript.Echo(scriptName + " url [-force yes|no] [-user username -password password] [-proxy proxyserver:port] [-bypass bypass_list]");
|
|
||||||
WScript.Echo(" [-proxyuser proxy_username -proxypassword proxy_password] [-certificate certificateString]");
|
|
||||||
WScript.Echo(" [-method GET|POST|PATCH|DELETE|HEAD|OPTIONS|CONNECT]");
|
|
||||||
WScript.Echo(" [-saveTo file] - to print response to console use con");
|
|
||||||
|
|
||||||
WScript.Echo(" [-sendTimeout int(milliseconds)]");
|
|
||||||
WScript.Echo(" [-resolveTimeout int(milliseconds)]");
|
|
||||||
WScript.Echo(" [-connectTimeout int(milliseconds)]");
|
|
||||||
WScript.Echo(" [-receiveTimeout int(milliseconds)]");
|
|
||||||
|
|
||||||
WScript.Echo(" [-autologonPolicy 1|2|3]");
|
|
||||||
WScript.Echo(" [-proxySettings 1|2|3] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa384059(v=vs.85).aspx)");
|
|
||||||
|
|
||||||
//header
|
|
||||||
WScript.Echo(" [-headers-file header_file]");
|
|
||||||
//reportfile
|
|
||||||
WScript.Echo(" [-reportfile reportfile]");
|
|
||||||
WScript.Echo(" [-ua user-agent]");
|
|
||||||
WScript.Echo(" [-ua-file user-agent-file]");
|
|
||||||
|
|
||||||
WScript.Echo(" [-escape yes|no]");
|
|
||||||
|
|
||||||
WScript.Echo(" [-body body-string]");
|
|
||||||
WScript.Echo(" [-body-file body-file]");
|
|
||||||
|
|
||||||
WScript.Echo("-force - decide to not or to overwrite if the local files exists");
|
|
||||||
|
|
||||||
WScript.Echo("proxyserver:port - the proxy server");
|
|
||||||
WScript.Echo("bypass- bypass list");
|
|
||||||
WScript.Echo("proxy_user , proxy_password - credentials for proxy server");
|
|
||||||
WScript.Echo("user , password - credentials for the server");
|
|
||||||
WScript.Echo("certificate - location of SSL certificate");
|
|
||||||
WScript.Echo("method - what HTTP method will be used.Default is GET");
|
|
||||||
WScript.Echo("saveTo - save the responce as binary file");
|
|
||||||
WScript.Echo(" ");
|
|
||||||
WScript.Echo("Header file should contain key:value pairs.Lines starting with \"#\" will be ignored.");
|
|
||||||
WScript.Echo("value should NOT be enclosed with quotes");
|
|
||||||
WScript.Echo(" ");
|
|
||||||
WScript.Echo("Examples:");
|
|
||||||
|
|
||||||
WScript.Echo(scriptName + " http://somelink.com/somefile.zip -saveTo c:\\somefile.zip -certificate \"LOCAL_MACHINE\\Personal\\My Middle-Tier Certificate\"");
|
|
||||||
WScript.Echo(scriptName + " http://somelink.com/something.html -method POST -certificate \"LOCAL_MACHINE\\Personal\\My Middle-Tier Certificate\" -header c:\\header_file -reportfile c:\\reportfile.txt");
|
|
||||||
WScript.Echo(scriptName + "\"http://somelink\" -method POST -header hdrs.txt -reportfile reportfile2.txt -saveTo responsefile2 -ua \"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36\" -body-file some.json");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseArgs() {
|
|
||||||
//
|
|
||||||
if (ARGS.Length < 2) {
|
|
||||||
WScript.Echo("insufficient arguments");
|
|
||||||
printHelp();
|
|
||||||
WScript.Quit(43);
|
|
||||||
}
|
|
||||||
// !!!
|
|
||||||
url = ARGS.Item(1);
|
|
||||||
// !!!
|
|
||||||
if (ARGS.Length % 2 != 0) {
|
|
||||||
WScript.Echo("illegal arguments");
|
|
||||||
printHelp();
|
|
||||||
WScript.Quit(44);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 2; i < ARGS.Length - 1; i = i + 2) {
|
|
||||||
var arg = ARGS.Item(i).toLowerCase();
|
|
||||||
var next = ARGS.Item(i + 1);
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
switch (arg) { // the try-catch is set mainly because of the parseInts
|
|
||||||
case "-force":
|
|
||||||
if (next == "no") {
|
|
||||||
force = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "-escape":
|
|
||||||
if (next == "yes") {
|
|
||||||
escape = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "-saveto":
|
|
||||||
saveTo = next;
|
|
||||||
break;
|
|
||||||
case "-user":
|
|
||||||
case "-u":
|
|
||||||
user = next;
|
|
||||||
break;
|
|
||||||
case "-pass":
|
|
||||||
case "-password":
|
|
||||||
case "-p":
|
|
||||||
pass = next;
|
|
||||||
break;
|
|
||||||
case "-proxy":
|
|
||||||
proxy = next;
|
|
||||||
break;
|
|
||||||
case "-bypass":
|
|
||||||
bypass = next;
|
|
||||||
break;
|
|
||||||
case "-proxyuser":
|
|
||||||
case "-pu":
|
|
||||||
proxy_user = next;
|
|
||||||
break;
|
|
||||||
case "-proxypassword":
|
|
||||||
case "-pp":
|
|
||||||
proxy_pass = next;
|
|
||||||
break;
|
|
||||||
case "-ua":
|
|
||||||
ua = next;
|
|
||||||
break;
|
|
||||||
case "-ua-file":
|
|
||||||
ua = readFile(next);
|
|
||||||
break;
|
|
||||||
case "-body":
|
|
||||||
body = next;
|
|
||||||
break;
|
|
||||||
case "-usestream":
|
|
||||||
//WScript.Echo("~~");
|
|
||||||
if (next.toLowerCase() === "yes") {
|
|
||||||
use_stream = true
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case "-body-file":
|
|
||||||
body = readFile(next);
|
|
||||||
break;
|
|
||||||
case "-certificate":
|
|
||||||
certificate = next;
|
|
||||||
break;
|
|
||||||
case "-method":
|
|
||||||
switch (next.toLowerCase()) {
|
|
||||||
case "post":
|
|
||||||
http_method = 'POST';
|
|
||||||
break;
|
|
||||||
case "get":
|
|
||||||
http_method = 'GET';
|
|
||||||
break;
|
|
||||||
case "head":
|
|
||||||
http_method = 'HEAD';
|
|
||||||
break;
|
|
||||||
case "put":
|
|
||||||
http_method = 'PUT';
|
|
||||||
break;
|
|
||||||
case "options":
|
|
||||||
http_method = 'OPTIONS';
|
|
||||||
break;
|
|
||||||
case "connect":
|
|
||||||
http_method = 'CONNECT';
|
|
||||||
break;
|
|
||||||
case "patch":
|
|
||||||
http_method = 'PATCH';
|
|
||||||
break;
|
|
||||||
case "delete":
|
|
||||||
http_method = 'DELETE';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WScript.Echo("Invalid http method passed " + next);
|
|
||||||
WScript.Echo("possible values are GET,POST,DELETE,PUT,CONNECT,PATCH,HEAD,OPTIONS");
|
|
||||||
WScript.Quit(1326);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "-headers-file":
|
|
||||||
case "-header":
|
|
||||||
headers = readPropFile(next);
|
|
||||||
break;
|
|
||||||
case "-reportfile":
|
|
||||||
reportfile = next;
|
|
||||||
break;
|
|
||||||
//timeouts
|
|
||||||
case "-sendtimeout":
|
|
||||||
SEND_TIMEOUT = parseInt(next);
|
|
||||||
break;
|
|
||||||
case "-connecttimeout":
|
|
||||||
CONNECT_TIMEOUT = parseint(next);
|
|
||||||
break;
|
|
||||||
case "-resolvetimeout":
|
|
||||||
RESOLVE_TIMEOUT = parseInt(next);
|
|
||||||
break;
|
|
||||||
case "-receivetimeout":
|
|
||||||
RECEIVE_TIMEOUT = parseInt(next);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "-autologonpolicy":
|
|
||||||
autologon_policy = parseInt(next);
|
|
||||||
if (autologon_policy > 2 || autologon_policy < 0) {
|
|
||||||
WScript.Echo("out of autologon policy range");
|
|
||||||
WScript.Quit(87);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case "-proxysettings":
|
|
||||||
proxy_settings = parseInt(next);
|
|
||||||
if (proxy_settings > 2 || proxy_settings < 0) {
|
|
||||||
WScript.Echo("out of proxy settings range");
|
|
||||||
WScript.Quit(87);
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WScript.Echo("Invalid command line switch: " + arg);
|
|
||||||
WScript.Quit(1405);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
WScript.Echo(err.message);
|
|
||||||
WScript.Quit(1348);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stripTrailingSlash = function(path) {
|
|
||||||
while (path.substr(path.length - 1, path.length) == '\\') {
|
|
||||||
path = path.substr(0, path.length - 1);
|
|
||||||
}
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
function existsItem(path) {
|
|
||||||
return FileSystemObj.FolderExists(path) || FileSystemObj.FileExists(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteItem(path) {
|
|
||||||
if (FileSystemObj.FileExists(path)) {
|
|
||||||
FileSystemObj.DeleteFile(path);
|
|
||||||
return true;
|
|
||||||
} else if (FileSystemObj.FolderExists(path)) {
|
|
||||||
FileSystemObj.DeleteFolder(stripTrailingSlash(path));
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------
|
|
||||||
//----------------------
|
|
||||||
//----------
|
|
||||||
//-----
|
|
||||||
//--
|
|
||||||
function request(url) {
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
WinHTTPObj.Open(http_method, url, false);
|
|
||||||
if (proxy != 0 && bypass != 0) {
|
|
||||||
WinHTTPObj.SetProxy(proxy_settings, proxy, bypass);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxy != 0) {
|
|
||||||
WinHTTPObj.SetProxy(proxy_settings, proxy);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user != 0 && pass != 0) {
|
|
||||||
WinHTTPObj.SetCredentials(user, pass, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (proxy_user != 0 && proxy_pass != 0) {
|
|
||||||
WinHTTPObj.SetCredentials(proxy_user, proxy_pass, HTTPREQUEST_SETCREDENTIALS_FOR_PROXY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (certificate != 0) {
|
|
||||||
WinHTTPObj.SetClientCertificate(certificate);
|
|
||||||
}
|
|
||||||
|
|
||||||
//set autologin policy
|
|
||||||
WinHTTPObj.SetAutoLogonPolicy(autologon_policy);
|
|
||||||
//set timeouts
|
|
||||||
WinHTTPObj.SetTimeouts(RESOLVE_TIMEOUT, CONNECT_TIMEOUT, SEND_TIMEOUT, RECEIVE_TIMEOUT);
|
|
||||||
|
|
||||||
if (headers.length !== 0) {
|
|
||||||
WScript.Echo("Sending with headers:");
|
|
||||||
for (var i = 0; i < headers.length; i++) {
|
|
||||||
WinHTTPObj.SetRequestHeader(headers[i][0], headers[i][1]);
|
|
||||||
WScript.Echo(headers[i][0] + ":" + headers[i][1]);
|
|
||||||
}
|
|
||||||
WScript.Echo("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ua !== "") {
|
|
||||||
//user-agent option from:
|
|
||||||
//WinHttpRequestOption enumeration
|
|
||||||
// other options can be added like bellow
|
|
||||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa384108(v=vs.85).aspx
|
|
||||||
WinHTTPObj.Option(0) = ua;
|
|
||||||
}
|
|
||||||
if (escape) {
|
|
||||||
WinHTTPObj.Option(3) = true;
|
|
||||||
}
|
|
||||||
if (trim(body) === "") {
|
|
||||||
WinHTTPObj.Send();
|
|
||||||
} else {
|
|
||||||
WinHTTPObj.Send(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
var status = WinHTTPObj.Status
|
|
||||||
} catch (err) {
|
|
||||||
WScript.Echo(err.message);
|
|
||||||
WScript.Quit(666);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////
|
|
||||||
// report //
|
|
||||||
////////////////////////
|
|
||||||
|
|
||||||
if (reportfile != "") {
|
|
||||||
|
|
||||||
//var report_string="";
|
|
||||||
var n = "\r\n";
|
|
||||||
var report_string = "Status:" + n;
|
|
||||||
report_string = report_string + " " + WinHTTPObj.Status;
|
|
||||||
report_string = report_string + " " + WinHTTPObj.StatusText + n;
|
|
||||||
report_string = report_string + " " + n;
|
|
||||||
report_string = report_string + "Response:" + n;
|
|
||||||
report_string = report_string + WinHTTPObj.ResponseText + n;
|
|
||||||
report_string = report_string + " " + n;
|
|
||||||
report_string = report_string + "Headers:" + n;
|
|
||||||
report_string = report_string + WinHTTPObj.GetAllResponseHeaders() + n;
|
|
||||||
|
|
||||||
WinHttpRequestOption_UserAgentString = 0; // Name of the user agent
|
|
||||||
WinHttpRequestOption_URL = 1; // Current URL
|
|
||||||
WinHttpRequestOption_URLCodePage = 2; // Code page
|
|
||||||
WinHttpRequestOption_EscapePercentInURL = 3; // Convert percents
|
|
||||||
// in the URL
|
|
||||||
// rest of the options can be seen and eventually added using this as reference
|
|
||||||
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa384108(v=vs.85).aspx
|
|
||||||
|
|
||||||
report_string = report_string + "URL:" + n;
|
|
||||||
report_string = report_string + WinHTTPObj.Option(WinHttpRequestOption_URL) + n;
|
|
||||||
|
|
||||||
report_string = report_string + "URL Code Page:" + n;
|
|
||||||
report_string = report_string + WinHTTPObj.Option(WinHttpRequestOption_URLCodePage) + n;
|
|
||||||
|
|
||||||
report_string = report_string + "User Agent:" + n;
|
|
||||||
report_string = report_string + WinHTTPObj.Option(WinHttpRequestOption_UserAgentString) + n;
|
|
||||||
|
|
||||||
report_string = report_string + "Escapped URL:" + n;
|
|
||||||
report_string = report_string + WinHTTPObj.Option(WinHttpRequestOption_EscapePercentInURL) + n;
|
|
||||||
|
|
||||||
prepareateFile(force, reportfile);
|
|
||||||
|
|
||||||
WScript.Echo("Writing report to " + reportfile);
|
|
||||||
|
|
||||||
writeFile(reportfile, report_string);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (status) {
|
|
||||||
case 200:
|
|
||||||
WScript.Echo("Status: 200 OK");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WScript.Echo("Status: " + status);
|
|
||||||
WScript.Echo("Status was not OK. More info -> https://en.wikipedia.org/wiki/List_of_HTTP_status_codes");
|
|
||||||
}
|
|
||||||
|
|
||||||
//if as binary
|
|
||||||
if (saveTo.toLowerCase() === "con") {
|
|
||||||
WScript.Echo(WinHTTPObj.ResponseText);
|
|
||||||
}
|
|
||||||
if (saveTo !== "" && saveTo.toLowerCase() !== "con") {
|
|
||||||
prepareateFile(force, saveTo);
|
|
||||||
try {
|
|
||||||
|
|
||||||
if (use_stream) {
|
|
||||||
writeBinFile(saveTo, WinHTTPObj.ResponseStream);
|
|
||||||
} else {
|
|
||||||
writeBinFile(saveTo, WinHTTPObj.ResponseBody);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
WScript.Echo("Failed to save the file as binary.Attempt to save it as text");
|
|
||||||
AdoDBObj.Close();
|
|
||||||
prepareateFile(true, saveTo);
|
|
||||||
writeFile(saveTo, WinHTTPObj.ResponseText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
WScript.Quit(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--
|
|
||||||
//-----
|
|
||||||
//----------
|
|
||||||
//----------------------
|
|
||||||
//-------------------------------
|
|
||||||
|
|
||||||
function prepareateFile(force, file) {
|
|
||||||
if (force && existsItem(file)) {
|
|
||||||
if (!deleteItem(file)) {
|
|
||||||
WScript.Echo("Unable to delete " + file);
|
|
||||||
WScript.Quit(8);
|
|
||||||
}
|
|
||||||
} else if (existsItem(file)) {
|
|
||||||
WScript.Echo("Item " + file + " already exist");
|
|
||||||
WScript.Quit(9);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeBinFile(fileName, data) {
|
|
||||||
AdoDBObj.Type = 1;
|
|
||||||
AdoDBObj.Open();
|
|
||||||
AdoDBObj.Position = 0;
|
|
||||||
AdoDBObj.Write(data);
|
|
||||||
AdoDBObj.SaveToFile(fileName, 2);
|
|
||||||
AdoDBObj.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeFile(fileName, data) {
|
|
||||||
AdoDBObj.Type = 2;
|
|
||||||
AdoDBObj.CharSet = "iso-8859-1";
|
|
||||||
AdoDBObj.Open();
|
|
||||||
AdoDBObj.Position = 0;
|
|
||||||
AdoDBObj.WriteText(data);
|
|
||||||
AdoDBObj.SaveToFile(fileName, 2);
|
|
||||||
AdoDBObj.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function readFile(fileName) {
|
|
||||||
//check existence
|
|
||||||
try {
|
|
||||||
if (!FileSystemObj.FileExists(fileName)) {
|
|
||||||
WScript.Echo("file " + fileName + " does not exist!");
|
|
||||||
WScript.Quit(13);
|
|
||||||
}
|
|
||||||
if (FileSystemObj.GetFile(fileName).Size === 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
var fileR = FileSystemObj.OpenTextFile(fileName, 1);
|
|
||||||
var content = fileR.ReadAll();
|
|
||||||
fileR.Close();
|
|
||||||
return content;
|
|
||||||
} catch (err) {
|
|
||||||
WScript.Echo("Error while reading file: " + fileName);
|
|
||||||
WScript.Echo(err.message);
|
|
||||||
WScript.Echo("Will return empty string");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function readPropFile(fileName) {
|
|
||||||
//check existence
|
|
||||||
resultArray = [];
|
|
||||||
if (!FileSystemObj.FileExists(fileName)) {
|
|
||||||
WScript.Echo("(headers)file " + fileName + " does not exist!");
|
|
||||||
WScript.Quit(15);
|
|
||||||
}
|
|
||||||
if (FileSystemObj.GetFile(fileName).Size === 0) {
|
|
||||||
return resultArray;
|
|
||||||
}
|
|
||||||
var fileR = FileSystemObj.OpenTextFile(fileName, 1);
|
|
||||||
var line = "";
|
|
||||||
var k = "";
|
|
||||||
var v = "";
|
|
||||||
var lineN = 0;
|
|
||||||
var index = 0;
|
|
||||||
try {
|
|
||||||
WScript.Echo("parsing headers form " + fileName + " property file ");
|
|
||||||
while (!fileR.AtEndOfStream) {
|
|
||||||
line = fileR.ReadLine();
|
|
||||||
lineN++;
|
|
||||||
index = line.indexOf(":");
|
|
||||||
if (line.indexOf("#") === 0 || trim(line) === "") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (index === -1 || index === line.length - 1 || index === 0) {
|
|
||||||
WScript.Echo("Invalid line " + lineN);
|
|
||||||
WScript.Quit(93);
|
|
||||||
}
|
|
||||||
k = trim(line.substring(0, index));
|
|
||||||
v = trim(line.substring(index + 1, line.length));
|
|
||||||
resultArray.push([k, v]);
|
|
||||||
}
|
|
||||||
fileR.Close();
|
|
||||||
return resultArray;
|
|
||||||
} catch (err) {
|
|
||||||
WScript.Echo("Error while reading headers file: " + fileName);
|
|
||||||
WScript.Echo(err.message);
|
|
||||||
WScript.Echo("Will return empty array");
|
|
||||||
return resultArray;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function trim(str) {
|
|
||||||
return str.replace(/^\s+/, '').replace(/\s+$/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
parseArgs();
|
|
||||||
request(url);
|
|
||||||
}
|
|
||||||
main();
|
|
@ -1604,6 +1604,12 @@ ChatLobbyId DistributedChatService::createChatLobby(const std::string& lobby_nam
|
|||||||
#endif
|
#endif
|
||||||
ChatLobbyId lobby_id ;
|
ChatLobbyId lobby_id ;
|
||||||
{
|
{
|
||||||
|
if (!rsIdentity->isOwnId(lobby_identity))
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " lobby_identity RsGxsId id must be own" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mDistributedChatMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
// create a unique id.
|
// create a unique id.
|
||||||
|
@ -1424,9 +1424,15 @@ int p3FileDatabase::SearchBoolExp(RsRegularExpression::Expression *exp, std::lis
|
|||||||
return !results.empty() ;
|
return !results.empty() ;
|
||||||
|
|
||||||
}
|
}
|
||||||
bool p3FileDatabase::search(const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const
|
|
||||||
|
bool p3FileDatabase::search(
|
||||||
|
const RsFileHash &hash, FileSearchFlags hintflags, FileInfo &info) const
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mFLSMtx) ;
|
RS_STACK_MUTEX(mFLSMtx);
|
||||||
|
|
||||||
|
if( (hintflags & RS_FILE_HINTS_EXTRA) &&
|
||||||
|
mExtraFiles->search(hash, hintflags, info) )
|
||||||
|
return true;
|
||||||
|
|
||||||
if(hintflags & RS_FILE_HINTS_LOCAL)
|
if(hintflags & RS_FILE_HINTS_LOCAL)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* libretroshare: retroshare core library *
|
* libretroshare: retroshare core library *
|
||||||
* *
|
* *
|
||||||
* Copyright (C) 2008 Robert Fernie <retroshare@lunamutt.com> *
|
* Copyright (C) 2008 Robert Fernie <retroshare@lunamutt.com> *
|
||||||
* Copyright (C) 2018-2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
* Copyright (C) 2018-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
|
||||||
* *
|
* *
|
||||||
* This program is free software: you can redistribute it and/or modify *
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU Lesser General Public License as *
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
@ -21,6 +21,9 @@
|
|||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
#ifdef WINDOWS_SYS
|
#ifdef WINDOWS_SYS
|
||||||
#include "util/rswin.h"
|
#include "util/rswin.h"
|
||||||
#endif
|
#endif
|
||||||
@ -245,12 +248,8 @@ bool ftExtraList::cleanupOldFiles()
|
|||||||
/* remove items */
|
/* remove items */
|
||||||
for(std::list<RsFileHash>::iterator rit = toRemove.begin(); rit != toRemove.end(); ++rit)
|
for(std::list<RsFileHash>::iterator rit = toRemove.begin(); rit != toRemove.end(); ++rit)
|
||||||
{
|
{
|
||||||
if (mFiles.end() != (it = mFiles.find(*rit)))
|
if (mFiles.end() != (it = mFiles.find(*rit))) mFiles.erase(it);
|
||||||
{
|
mHashOfHash.erase(makeEncryptedHash(*rit));
|
||||||
cleanupEntry(it->second.info.path, it->second.info.transfer_info_flags);
|
|
||||||
mFiles.erase(it);
|
|
||||||
}
|
|
||||||
mHashOfHash.erase(makeEncryptedHash(*rit)) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
@ -258,46 +257,39 @@ bool ftExtraList::cleanupOldFiles()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ftExtraList::cleanupEntry(std::string /*path*/, TransferRequestFlags /*flags*/)
|
|
||||||
{
|
|
||||||
// if (flags & RS_FILE_CONFIG_CLEANUP_DELETE)
|
|
||||||
// {
|
|
||||||
// /* Delete the file? - not yet! */
|
|
||||||
// }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***
|
|
||||||
* Hash file, and add to the files,
|
|
||||||
* file is removed after period.
|
|
||||||
**/
|
|
||||||
|
|
||||||
bool ftExtraList::hashExtraFile(
|
bool ftExtraList::hashExtraFile(
|
||||||
std::string path, uint32_t period, TransferRequestFlags flags )
|
std::string path, uint32_t period, TransferRequestFlags flags )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_ELIST
|
constexpr rstime_t max_int = std::numeric_limits<int>::max();
|
||||||
std::cerr << "ftExtraList::hashExtraFile() path: " << path;
|
const rstime_t now = time(nullptr);
|
||||||
std::cerr << " period: " << period;
|
const rstime_t timeOut = now + period;
|
||||||
std::cerr << " flags: " << flags;
|
|
||||||
|
|
||||||
std::cerr << std::endl;
|
if(timeOut > max_int)
|
||||||
#endif
|
|
||||||
|
|
||||||
auto failure = [](std::string errMsg)
|
|
||||||
{
|
{
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " " << errMsg << std::endl;
|
/* Under the hood period is stored as int FileInfo::age so we do this
|
||||||
|
* check here to detect 2038 year problem
|
||||||
|
* https://en.wikipedia.org/wiki/Year_2038_problem */
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " period: " << period << " > "
|
||||||
|
<< max_int - now << std::errc::value_too_large << std::endl;
|
||||||
return false;
|
return false;
|
||||||
};
|
}
|
||||||
|
|
||||||
if(!RsDirUtil::fileExists(path))
|
if(!RsDirUtil::fileExists(path))
|
||||||
return failure("file: " + path + "not found");
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " path: " << path
|
||||||
|
<< std::errc::no_such_file_or_directory << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(RsDirUtil::checkDirectory(path))
|
if(RsDirUtil::checkDirectory(path))
|
||||||
return failure("Cannot add a directory: " + path + "as extra file");
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " path: " << path
|
||||||
|
<< std::errc::is_a_directory << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
FileDetails details(path, period, flags);
|
FileDetails details(path, period, flags);
|
||||||
details.info.age = static_cast<int>(time(nullptr) + period);
|
details.info.age = static_cast<int>(timeOut);
|
||||||
|
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(extMutex);
|
RS_STACK_MUTEX(extMutex);
|
||||||
@ -492,8 +484,7 @@ bool ftExtraList::loadList(std::list<RsItem *>& load)
|
|||||||
|
|
||||||
if (ts > (rstime_t)fi->file.age)
|
if (ts > (rstime_t)fi->file.age)
|
||||||
{
|
{
|
||||||
/* to old */
|
/* too old */
|
||||||
cleanupEntry(fi->file.path, TransferRequestFlags(fi->flags));
|
|
||||||
delete (*it);
|
delete (*it);
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
#include "pqi/p3cfgmgr.h"
|
#include "pqi/p3cfgmgr.h"
|
||||||
#include "util/rstime.h"
|
#include "util/rstime.h"
|
||||||
|
|
||||||
class FileDetails
|
class RS_DEPRECATED_FOR(FileInfo) FileDetails
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileDetails()
|
FileDetails()
|
||||||
@ -130,7 +130,11 @@ public:
|
|||||||
* file is removed after period.
|
* file is removed after period.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
bool hashExtraFile(std::string path, uint32_t period, TransferRequestFlags flags);
|
/**
|
||||||
|
* Hash file, and add to the files, file is removed after period.
|
||||||
|
*/
|
||||||
|
bool hashExtraFile(
|
||||||
|
std::string path, uint32_t period, TransferRequestFlags flags );
|
||||||
bool hashExtraFileDone(std::string path, FileInfo &info);
|
bool hashExtraFileDone(std::string path, FileInfo &info);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
@ -165,7 +169,6 @@ private:
|
|||||||
/* Worker Functions */
|
/* Worker Functions */
|
||||||
void hashAFile();
|
void hashAFile();
|
||||||
bool cleanupOldFiles();
|
bool cleanupOldFiles();
|
||||||
bool cleanupEntry(std::string path, TransferRequestFlags flags);
|
|
||||||
|
|
||||||
mutable RsMutex extMutex;
|
mutable RsMutex extMutex;
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
#include "crypto/chacha20.h"
|
#include "crypto/chacha20.h"
|
||||||
//const int ftserverzone = 29539;
|
//const int ftserverzone = 29539;
|
||||||
@ -293,7 +295,8 @@ bool ftServer::getFileData(const RsFileHash& hash, uint64_t offset, uint32_t& re
|
|||||||
|
|
||||||
bool ftServer::alreadyHaveFile(const RsFileHash& hash, FileInfo &info)
|
bool ftServer::alreadyHaveFile(const RsFileHash& hash, FileInfo &info)
|
||||||
{
|
{
|
||||||
return mFileDatabase->search(hash, RS_FILE_HINTS_LOCAL, info);
|
return mFileDatabase->search(
|
||||||
|
hash, RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_LOCAL, info );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ftServer::FileRequest(
|
bool ftServer::FileRequest(
|
||||||
@ -819,6 +822,14 @@ bool ftServer::ExtraFileRemove(const RsFileHash& hash)
|
|||||||
bool ftServer::ExtraFileHash(
|
bool ftServer::ExtraFileHash(
|
||||||
std::string localpath, rstime_t period, TransferRequestFlags flags )
|
std::string localpath, rstime_t period, TransferRequestFlags flags )
|
||||||
{
|
{
|
||||||
|
constexpr rstime_t uintmax = std::numeric_limits<uint32_t>::max();
|
||||||
|
if(period > uintmax)
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " period: " << period << " > "
|
||||||
|
<< uintmax << std::errc::value_too_large << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return mFtExtra->hashExtraFile(
|
return mFtExtra->hashExtraFile(
|
||||||
localpath, static_cast<uint32_t>(period), flags );
|
localpath, static_cast<uint32_t>(period), flags );
|
||||||
}
|
}
|
||||||
|
@ -419,10 +419,8 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
|
|||||||
/* check signature timeperiod */
|
/* check signature timeperiod */
|
||||||
if ((msgMeta.mPublishTs < key.startTS) || (key.endTS != 0 && msgMeta.mPublishTs > key.endTS))
|
if ((msgMeta.mPublishTs < key.startTS) || (key.endTS != 0 && msgMeta.mPublishTs > key.endTS))
|
||||||
{
|
{
|
||||||
#ifdef GXS_SECURITY_DEBUG
|
RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId
|
||||||
std::cerr << " GxsSecurity::validateNxsMsg() TS out of range";
|
<< " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ public:
|
|||||||
bool withMeta = false ) = 0;
|
bool withMeta = false ) = 0;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Retrieves all groups stored
|
* Retrieves all groups stored. Caller owns the memory and is supposed to delete the RsNxsGrp pointers after use.
|
||||||
* @param grp retrieved groups
|
* @param grp retrieved groups
|
||||||
* @param withMeta if true the meta handle of nxs grps is intitialised
|
* @param withMeta if true the meta handle of nxs grps is intitialised
|
||||||
* @param cache whether to store retrieval in mem for faster later retrieval
|
* @param cache whether to store retrieval in mem for faster later retrieval
|
||||||
|
@ -236,14 +236,17 @@ void RsGenExchange::tick()
|
|||||||
|
|
||||||
if (!grpIds.empty())
|
if (!grpIds.empty())
|
||||||
{
|
{
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
|
for(auto& groupId:grpIds)
|
||||||
gc->mGrpIdList = grpIds;
|
{
|
||||||
|
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED,groupId, false);
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||||
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
|
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
|
||||||
std::cerr << " " << *it << std::endl;
|
std::cerr << " " << *it << std::endl;
|
||||||
#endif
|
#endif
|
||||||
mNotifications.push_back(gc);
|
mNotifications.push_back(gc);
|
||||||
|
}
|
||||||
|
|
||||||
// also notify the network exchange service that these groups no longer exist.
|
// also notify the network exchange service that these groups no longer exist.
|
||||||
|
|
||||||
@ -251,10 +254,10 @@ void RsGenExchange::tick()
|
|||||||
mNetService->removeGroups(grpIds) ;
|
mNetService->removeGroups(grpIds) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msgIds.empty())
|
for(auto it(msgIds.begin());it!=msgIds.end();++it)
|
||||||
|
for(auto& msgId:it->second)
|
||||||
{
|
{
|
||||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_MESSAGE_DELETED,it->first, msgId, false);
|
||||||
c->msgChangeMap = msgIds;
|
|
||||||
mNotifications.push_back(c);
|
mNotifications.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,7 +773,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
|
|||||||
hash.addData(allMsgData, allMsgDataLen);
|
hash.addData(allMsgData, allMsgDataLen);
|
||||||
RsFileHash hashId;
|
RsFileHash hashId;
|
||||||
hash.Complete(hashId);
|
hash.Complete(hashId);
|
||||||
msg->msgId = hashId;
|
msg->msgId = RsGxsMessageId(hashId);
|
||||||
|
|
||||||
// assign msg id to msg meta
|
// assign msg id to msg meta
|
||||||
msg->metaData->mMsgId = msg->msgId;
|
msg->metaData->mMsgId = msg->msgId;
|
||||||
@ -934,7 +937,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
|
|||||||
RsReputationLevel::LOCALLY_NEGATIVE )
|
RsReputationLevel::LOCALLY_NEGATIVE )
|
||||||
{
|
{
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << details.mReputation.mOverallReputationLevel <<") indicate that you banned this ID." << std::endl;
|
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << static_cast<int>(details.mReputation.mOverallReputationLevel) <<") indicate that you banned this ID." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
idValidate = false ;
|
idValidate = false ;
|
||||||
}
|
}
|
||||||
@ -1110,6 +1113,7 @@ static void addMessageChanged(std::map<RsGxsGroupId, std::set<RsGxsMessageId> >
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
||||||
{
|
{
|
||||||
std::cerr << "*********************************** RsGenExchange::receiveChanges()" << std::endl;
|
std::cerr << "*********************************** RsGenExchange::receiveChanges()" << std::endl;
|
||||||
@ -1155,6 +1159,7 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
|
|
||||||
if(rsEvents) rsEvents->postEvent(std::move(evt));
|
if(rsEvents) rsEvents->postEvent(std::move(evt));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
|
bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
|
||||||
{
|
{
|
||||||
@ -1683,8 +1688,7 @@ void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId)
|
|||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx);
|
RS_STACK_MUTEX(mGenMtx);
|
||||||
|
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY, true);
|
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY,grpId, true);
|
||||||
gc->mGrpIdList.push_back(grpId);
|
|
||||||
mNotifications.push_back(gc);
|
mNotifications.push_back(gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1692,8 +1696,8 @@ void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId)
|
|||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx);
|
RS_STACK_MUTEX(mGenMtx);
|
||||||
|
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED, false);
|
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED,grpId, false);
|
||||||
gc->mGrpIdList.push_back(grpId);
|
|
||||||
mNotifications.push_back(gc);
|
mNotifications.push_back(gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1793,6 +1797,7 @@ void RsGenExchange::updateGroup(uint32_t& token, RsGxsGrpItem* grpItem)
|
|||||||
if(!checkGroupMetaConsistency(grpItem->meta))
|
if(!checkGroupMetaConsistency(grpItem->meta))
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl;
|
std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl;
|
||||||
|
delete grpItem;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2049,11 +2054,13 @@ void RsGenExchange::processMsgMetaChanges()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!msgIds.empty()) {
|
if (!msgIds.empty())
|
||||||
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx);
|
RS_STACK_MUTEX(mGenMtx);
|
||||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
|
||||||
c->msgChangeMap = msgIds;
|
for(auto it(msgIds.begin());it!=msgIds.end();++it)
|
||||||
mNotifications.push_back(c);
|
for(auto& msg_id:it->second)
|
||||||
|
mNotifications.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, it->first, msg_id, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2099,17 +2106,11 @@ void RsGenExchange::processGrpMetaChanges()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!grpChanged.empty())
|
for(auto& groupId:grpChanged)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx);
|
RS_STACK_MUTEX(mGenMtx);
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
|
|
||||||
gc->mGrpIdList = grpChanged;
|
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED,groupId, true));
|
||||||
mNotifications.push_back(gc);
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
|
||||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
|
||||||
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
|
|
||||||
std::cerr << " " << *it << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2186,7 +2187,7 @@ void RsGenExchange::publishMsgs()
|
|||||||
mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem));
|
mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
|
std::map<RsGxsGroupId, std::list<RsGxsMsgItem*> > msgChangeMap;
|
||||||
std::map<uint32_t, RsGxsMsgItem*>::iterator mit = mMsgsToPublish.begin();
|
std::map<uint32_t, RsGxsMsgItem*>::iterator mit = mMsgsToPublish.begin();
|
||||||
|
|
||||||
for(; mit != mMsgsToPublish.end(); ++mit)
|
for(; mit != mMsgsToPublish.end(); ++mit)
|
||||||
@ -2315,9 +2316,12 @@ void RsGenExchange::publishMsgs()
|
|||||||
|
|
||||||
mPublishedMsgs[token] = *msg->metaData;
|
mPublishedMsgs[token] = *msg->metaData;
|
||||||
|
|
||||||
|
RsGxsMsgItem *msg_item = dynamic_cast<RsGxsMsgItem*>(mSerialiser->deserialise(msg->msg.bin_data,&msg->msg.bin_len)) ;
|
||||||
|
msg_item->meta = *msg->metaData;
|
||||||
|
|
||||||
delete msg ;
|
delete msg ;
|
||||||
|
|
||||||
msgChangeMap[grpId].insert(msgId);
|
msgChangeMap[grpId].push_back(msg_item);
|
||||||
|
|
||||||
delete[] metaDataBuff;
|
delete[] metaDataBuff;
|
||||||
|
|
||||||
@ -2356,13 +2360,14 @@ void RsGenExchange::publishMsgs()
|
|||||||
// entries are invalid
|
// entries are invalid
|
||||||
mMsgsToPublish.clear();
|
mMsgsToPublish.clear();
|
||||||
|
|
||||||
if(!msgChangeMap.empty())
|
for(auto it(msgChangeMap.begin());it!=msgChangeMap.end();++it)
|
||||||
|
for(auto& msg_item: it->second)
|
||||||
{
|
{
|
||||||
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED, false);
|
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED,msg_item->meta.mGroupId, msg_item->meta.mMsgId, false);
|
||||||
ch->msgChangeMap = msgChangeMap;
|
ch->mNewMsgItem = msg_item;
|
||||||
|
|
||||||
mNotifications.push_back(ch);
|
mNotifications.push_back(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */,
|
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */,
|
||||||
@ -2387,9 +2392,8 @@ void RsGenExchange::processGroupUpdatePublish()
|
|||||||
|
|
||||||
// first build meta request map for groups to be updated
|
// first build meta request map for groups to be updated
|
||||||
RsGxsGrpMetaTemporaryMap grpMeta;
|
RsGxsGrpMetaTemporaryMap grpMeta;
|
||||||
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
|
|
||||||
|
|
||||||
for(; vit != mGroupUpdatePublish.end(); ++vit)
|
for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit)
|
||||||
{
|
{
|
||||||
GroupUpdatePublish& gup = *vit;
|
GroupUpdatePublish& gup = *vit;
|
||||||
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
||||||
@ -2402,8 +2406,7 @@ void RsGenExchange::processGroupUpdatePublish()
|
|||||||
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
||||||
|
|
||||||
// now
|
// now
|
||||||
vit = mGroupUpdatePublish.begin();
|
for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit)
|
||||||
for(; vit != mGroupUpdatePublish.end(); ++vit)
|
|
||||||
{
|
{
|
||||||
GroupUpdatePublish& gup = *vit;
|
GroupUpdatePublish& gup = *vit;
|
||||||
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
||||||
@ -2494,15 +2497,15 @@ void RsGenExchange::processGroupDelete()
|
|||||||
grpDeleted.push_back(note.second);
|
grpDeleted.push_back(note.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!grpDeleted.empty())
|
for(auto& groupId:grpDeleted)
|
||||||
{
|
{
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHED, false);
|
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED, groupId,false);
|
||||||
gc->mGrpIdList = grpDeleted;
|
|
||||||
mNotifications.push_back(gc);
|
mNotifications.push_back(gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
mGroupDeletePublish.clear();
|
mGroupDeletePublish.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsGenExchange::processMessageDelete()
|
void RsGenExchange::processMessageDelete()
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGenMtx) ;
|
RS_STACK_MUTEX(mGenMtx) ;
|
||||||
@ -2521,31 +2524,24 @@ void RsGenExchange::processMessageDelete()
|
|||||||
mDataStore->removeMsgs( (*vit).mMsgs );
|
mDataStore->removeMsgs( (*vit).mMsgs );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// std::list<RsGxsGroupId> grpDeleted;
|
||||||
|
// std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
|
||||||
|
// for(; mit != toNotify.end(); ++mit)
|
||||||
|
// {
|
||||||
|
// GrpNote& note = mit->second;
|
||||||
|
// uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
|
||||||
|
// : RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
|
||||||
|
//
|
||||||
|
// mGrpNotify.insert(std::make_pair(mit->first, note.second));
|
||||||
|
// mDataAccess->updatePublicRequestStatus(mit->first, status);
|
||||||
|
//
|
||||||
|
// if(note.first)
|
||||||
|
// grpDeleted.push_back(note.second);
|
||||||
|
// }
|
||||||
|
|
||||||
#warning csoler: TODO: notify for deleted messages
|
for(uint32_t i=0;i<mMsgDeletePublish.size();++i)
|
||||||
#ifdef SUSPENDED
|
for(auto it(mMsgDeletePublish[i].mMsgs.begin());it!=mMsgDeletePublish[i].mMsgs.end();++it)
|
||||||
std::list<RsGxsGroupId> grpDeleted;
|
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_MESSAGE_DELETED,it->first, false));
|
||||||
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
|
|
||||||
for(; mit != toNotify.end(); ++mit)
|
|
||||||
{
|
|
||||||
GrpNote& note = mit->second;
|
|
||||||
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
|
|
||||||
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
|
|
||||||
|
|
||||||
mGrpNotify.insert(std::make_pair(mit->first, note.second));
|
|
||||||
mDataAccess->updatePublicRequestStatus(mit->first, status);
|
|
||||||
|
|
||||||
if(note.first)
|
|
||||||
grpDeleted.push_back(note.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!grpDeleted.empty())
|
|
||||||
{
|
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
|
|
||||||
gc->mGrpIdList = grpDeleted;
|
|
||||||
mNotifications.push_back(gc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mMsgDeletePublish.clear();
|
mMsgDeletePublish.clear();
|
||||||
}
|
}
|
||||||
@ -2805,17 +2801,8 @@ void RsGenExchange::publishGrps()
|
|||||||
grpChanged.push_back(note.second);
|
grpChanged.push_back(note.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!grpChanged.empty())
|
for(auto& groupId:grpChanged)
|
||||||
{
|
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW,groupId, true));
|
||||||
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
|
|
||||||
gc->mGrpIdList = grpChanged;
|
|
||||||
mNotifications.push_back(gc);
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
|
||||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
|
||||||
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
|
|
||||||
std::cerr << " " << *it << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is done off-mutex to avoid possible cross deadlocks with the net service.
|
// This is done off-mutex to avoid possible cross deadlocks with the net service.
|
||||||
@ -3072,12 +3059,20 @@ void RsGenExchange::processRecvdMessages()
|
|||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << " storing remaining messages" << std::endl;
|
std::cerr << " storing remaining messages" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
mDataStore->storeMessage(msgs_to_store);
|
|
||||||
|
|
||||||
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
|
for(auto& nxs_msg: msgs_to_store)
|
||||||
c->msgChangeMap = msgIds;
|
{
|
||||||
|
RsGxsMsgItem *item = dynamic_cast<RsGxsMsgItem*>(mSerialiser->deserialise(nxs_msg->msg.bin_data,&nxs_msg->msg.bin_len));
|
||||||
|
item->meta = *nxs_msg->metaData;
|
||||||
|
|
||||||
|
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, item->meta.mGroupId, item->meta.mMsgId,false);
|
||||||
|
c->mNewMsgItem = item;
|
||||||
|
|
||||||
mNotifications.push_back(c);
|
mNotifications.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mDataStore->storeMessage(msgs_to_store); // we do that late because it destroys the items in msgs_to_store
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Done off-mutex to avoid cross deadlocks in the netservice that might call the RsGenExchange as an observer..
|
// Done off-mutex to avoid cross deadlocks in the netservice that might call the RsGenExchange as an observer..
|
||||||
@ -3205,11 +3200,17 @@ void RsGenExchange::processRecvdGroups()
|
|||||||
vit = tmp ;
|
vit = tmp ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!grpIds.empty())
|
if(!grps_to_store.empty())
|
||||||
{
|
{
|
||||||
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
|
for(auto Grp:grps_to_store)
|
||||||
c->mGrpIdList = grpIds;
|
{
|
||||||
|
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, Grp->grpId, false);
|
||||||
|
|
||||||
|
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(Grp->grp.bin_data,&Grp->grp.bin_len));
|
||||||
|
|
||||||
mNotifications.push_back(c);
|
mNotifications.push_back(c);
|
||||||
|
}
|
||||||
|
|
||||||
mDataStore->storeGroup(grps_to_store);
|
mDataStore->storeGroup(grps_to_store);
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
std::cerr << " adding the following grp ids to notification: " << std::endl;
|
||||||
@ -3230,39 +3231,42 @@ void RsGenExchange::performUpdateValidation()
|
|||||||
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsGxsGrpMetaTemporaryMap grpMetas;
|
RsNxsGrpDataTemporaryMap grpDatas;
|
||||||
|
|
||||||
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
|
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
|
||||||
for(; vit != mGroupUpdates.end(); ++vit)
|
grpDatas.insert(std::make_pair(vit->newGrp->grpId, (RsNxsGrp*)NULL));
|
||||||
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
|
|
||||||
|
|
||||||
if(!grpMetas.empty())
|
if(grpDatas.empty() || !mDataStore->retrieveNxsGrps(grpDatas,true,false))
|
||||||
mDataStore->retrieveGxsGrpMetaData(grpMetas);
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
|
|
||||||
vit = mGroupUpdates.begin();
|
|
||||||
for(; vit != mGroupUpdates.end(); ++vit)
|
|
||||||
{
|
{
|
||||||
GroupUpdate& gu = *vit;
|
if(grpDatas.empty())
|
||||||
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(gu.newGrp->grpId);
|
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: no group in list!" << std::endl;
|
||||||
gu.oldGrpMeta = mit->second;
|
else
|
||||||
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
|
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: cannot retrieve froup data for these groups!" << std::endl;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vit = mGroupUpdates.begin();
|
|
||||||
|
|
||||||
RsNxsGrpDataTemporaryList grps ;
|
RsNxsGrpDataTemporaryList grps ;
|
||||||
|
|
||||||
for(; vit != mGroupUpdates.end(); ++vit)
|
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
|
||||||
{
|
{
|
||||||
GroupUpdate& gu = *vit;
|
GroupUpdate& gu = *vit;
|
||||||
|
|
||||||
if(gu.validUpdate)
|
auto mit = grpDatas.find(gu.newGrp->grpId);
|
||||||
|
|
||||||
|
if(mit == grpDatas.end())
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " Validation of group update failed for group " << gu.newGrp->grpId << " because previous grp version cannot be found." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
RsGxsGrpMetaData *oldGrpMeta(mit->second->metaData);
|
||||||
|
RsNxsGrp *oldGrp(mit->second);
|
||||||
|
|
||||||
|
if(updateValid(*oldGrpMeta, *gu.newGrp))
|
||||||
{
|
{
|
||||||
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
|
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
|
||||||
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
|
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
|
||||||
@ -3270,42 +3274,39 @@ void RsGenExchange::performUpdateValidation()
|
|||||||
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
|
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
|
||||||
// is received.
|
// is received.
|
||||||
|
|
||||||
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
|
gu.newGrp->metaData->mSubscribeFlags = oldGrpMeta->mSubscribeFlags ;
|
||||||
|
|
||||||
// Also keep private keys if present
|
// Also keep private keys if present
|
||||||
|
|
||||||
if(!gu.newGrp->metaData->keys.private_keys.empty())
|
if(!gu.newGrp->metaData->keys.private_keys.empty())
|
||||||
std::cerr << "(EE) performUpdateValidation() group " <<gu.newGrp->metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl;
|
std::cerr << "(EE) performUpdateValidation() group " <<gu.newGrp->metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl;
|
||||||
else
|
else
|
||||||
gu.newGrp->metaData->keys.private_keys = gu.oldGrpMeta->keys.private_keys ;
|
gu.newGrp->metaData->keys.private_keys = oldGrpMeta->keys.private_keys ;
|
||||||
|
|
||||||
|
// Now prepare notification of the client
|
||||||
|
|
||||||
|
RsGxsGroupChange *c = new RsGxsGroupChange(RsGxsNotify::TYPE_UPDATED,gu.newGrp->metaData->mGroupId,false);
|
||||||
|
|
||||||
|
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(gu.newGrp->grp.bin_data,&gu.newGrp->grp.bin_len));
|
||||||
|
c->mNewGroupItem->meta = *gu.newGrp->metaData; // gu.newGrp will be deleted because mDataStore will destroy it on update
|
||||||
|
|
||||||
|
c->mOldGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(oldGrp->grp.bin_data,&oldGrp->grp.bin_len));
|
||||||
|
c->mOldGroupItem->meta = *oldGrpMeta; // no need to delete mit->second, as it will be deleted automatically in the temporary map
|
||||||
|
|
||||||
|
mNotifications.push_back(c);
|
||||||
|
|
||||||
|
// finally, add the group to the list to send to mDataStore
|
||||||
|
|
||||||
grps.push_back(gu.newGrp);
|
grps.push_back(gu.newGrp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delete gu.newGrp;
|
delete gu.newGrp; // delete here because mDataStore will not take care of this one. no need to delete mit->second, as it will be deleted automatically in the temporary map
|
||||||
gu.newGrp = NULL ;
|
gu.newGrp = NULL ;
|
||||||
}
|
}
|
||||||
|
|
||||||
gu.oldGrpMeta = NULL ;
|
|
||||||
}
|
}
|
||||||
// notify the client
|
|
||||||
|
|
||||||
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
|
|
||||||
|
|
||||||
for(uint32_t i=0;i<mGroupUpdates.size();++i)
|
|
||||||
if(mGroupUpdates[i].newGrp != NULL)
|
|
||||||
{
|
|
||||||
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
|
||||||
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
mNotifications.push_back(c);
|
|
||||||
|
|
||||||
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
|
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
|
||||||
|
|
||||||
mDataStore->updateGroup(grps);
|
mDataStore->updateGroup(grps);
|
||||||
|
|
||||||
#ifdef GEN_EXCH_DEBUG
|
#ifdef GEN_EXCH_DEBUG
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "rsnxsobserver.h"
|
#include "rsnxsobserver.h"
|
||||||
#include "retroshare/rsgxsservice.h"
|
#include "retroshare/rsgxsservice.h"
|
||||||
#include "rsitems/rsnxsitems.h"
|
#include "rsitems/rsnxsitems.h"
|
||||||
|
#include "gxs/rsgxsnotify.h"
|
||||||
#include "rsgxsutil.h"
|
#include "rsgxsutil.h"
|
||||||
|
|
||||||
template<class GxsItem, typename Identity = std::string>
|
template<class GxsItem, typename Identity = std::string>
|
||||||
@ -262,12 +263,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta);
|
bool getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta);
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
/*!
|
/*!
|
||||||
* Gxs services should call this for automatic handling of
|
* Gxs services should call this for automatic handling of
|
||||||
* changes, send
|
* changes, send
|
||||||
* @param changes
|
* @param changes
|
||||||
*/
|
*/
|
||||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes);
|
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief acceptNewGroup
|
* \brief acceptNewGroup
|
||||||
@ -748,9 +751,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void processRecvdData();
|
void processRecvdData();
|
||||||
|
@ -1038,7 +1038,7 @@ bool RsGxsDataAccess::getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokRe
|
|||||||
// Because msgs are stored in a std::vector we build a map to convert each vector to its position in metaV.
|
// Because msgs are stored in a std::vector we build a map to convert each vector to its position in metaV.
|
||||||
|
|
||||||
std::vector<bool> keep(metaV.size(),true); // this vector will tell wether we keep or not a given Meta
|
std::vector<bool> keep(metaV.size(),true); // this vector will tell wether we keep or not a given Meta
|
||||||
std::map<RsMessageId,uint32_t> index_in_metaV; // holds the index of each group Id in metaV
|
std::map<RsGxsMessageId,uint32_t> index_in_metaV; // holds the index of each group Id in metaV
|
||||||
|
|
||||||
for(uint32_t i=0;i<metaV.size();++i)
|
for(uint32_t i=0;i<metaV.size();++i)
|
||||||
index_in_metaV[metaV[i]->mMsgId] = i;
|
index_in_metaV[metaV[i]->mMsgId] = i;
|
||||||
|
@ -320,9 +320,9 @@ static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
|
|||||||
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|
||||||
|| defined(NXS_NET_DEBUG_8)
|
|| defined(NXS_NET_DEBUG_8)
|
||||||
|
|
||||||
static const RsPeerId peer_to_print = RsPeerId(std::string("")) ;
|
static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ;
|
||||||
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("")) ; // use this to allow to this group id only, or "" for all IDs
|
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs
|
||||||
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_CHANNELS ; // use this to allow to this service id only, or 0 for all services
|
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_GXSCIRCLE; // use this to allow to this service id only, or 0 for all services
|
||||||
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
|
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
|
||||||
|
|
||||||
class nullstream: public std::ostream {};
|
class nullstream: public std::ostream {};
|
||||||
@ -3598,6 +3598,10 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
|||||||
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
|
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
|
||||||
msg->pos = 0;
|
msg->pos = 0;
|
||||||
|
|
||||||
|
#ifdef NXS_NET_DEBUG_0
|
||||||
|
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " sending msg Id " << msg->msgId << " in Group " << msg->grpId << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
newTr->mItems.push_back(msg);
|
newTr->mItems.push_back(msg);
|
||||||
msgSize++;
|
msgSize++;
|
||||||
#endif
|
#endif
|
||||||
|
107
libretroshare/src/gxs/rsgxsnotify.h
Normal file
107
libretroshare/src/gxs/rsgxsnotify.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* libretroshare/src/gxs/: rsgxsnotify.h *
|
||||||
|
* *
|
||||||
|
* libretroshare: retroshare core library *
|
||||||
|
* *
|
||||||
|
* Copyright (C) 2015 Retroshare Team <retroshare.project@gmail.com> *
|
||||||
|
* *
|
||||||
|
* This program is free software: you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU Lesser General Public License as *
|
||||||
|
* published by the Free Software Foundation, either version 3 of the *
|
||||||
|
* License, or (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU Lesser General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License *
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
||||||
|
* *
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* The aim of this class is to implement notifications internally to GXS, which are
|
||||||
|
* mostly used by RsGenExchange to send information to specific services. These services
|
||||||
|
* then interpret these changes and turn them into human-readable/processed service-specific changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "retroshare/rsids.h"
|
||||||
|
|
||||||
|
class RsGxsNotify
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsGxsNotify(const RsGxsGroupId& gid): mGroupId(gid){}
|
||||||
|
virtual ~RsGxsNotify()=default;
|
||||||
|
|
||||||
|
enum NotifyType
|
||||||
|
{
|
||||||
|
TYPE_UNKNOWN = 0x00,
|
||||||
|
TYPE_PUBLISHED = 0x01,
|
||||||
|
TYPE_RECEIVED_NEW = 0x02,
|
||||||
|
TYPE_PROCESSED = 0x03,
|
||||||
|
TYPE_RECEIVED_PUBLISHKEY = 0x04,
|
||||||
|
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
|
||||||
|
TYPE_STATISTICS_CHANGED = 0x06,
|
||||||
|
TYPE_UPDATED = 0x07,
|
||||||
|
TYPE_MESSAGE_DELETED = 0x08,
|
||||||
|
TYPE_GROUP_DELETED = 0x09,
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual NotifyType getType() = 0;
|
||||||
|
|
||||||
|
RsGxsGroupId mGroupId; // Group id of the group we're talking about. When the group is deleted, it's useful to know which group
|
||||||
|
// that was although there is no pointers to the actual group data anymore.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Relevant to group changes
|
||||||
|
*/
|
||||||
|
class RsGxsGroupChange : public RsGxsNotify
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsGxsGroupChange(NotifyType type, const RsGxsGroupId& gid,bool metaChange) : RsGxsNotify(gid),mNewGroupItem(nullptr),mOldGroupItem(nullptr), mNotifyType(type), mMetaChange(metaChange) {}
|
||||||
|
virtual ~RsGxsGroupChange() override { delete mOldGroupItem; delete mNewGroupItem ; }
|
||||||
|
|
||||||
|
NotifyType getType() override { return mNotifyType;}
|
||||||
|
bool metaChange() { return mMetaChange; }
|
||||||
|
|
||||||
|
RsGxsGrpItem *mNewGroupItem; // Valid when a group has changed, or a new group is received.
|
||||||
|
RsGxsGrpItem *mOldGroupItem; // only valid when mNotifyType is TYPE_UPDATED
|
||||||
|
|
||||||
|
protected:
|
||||||
|
NotifyType mNotifyType;
|
||||||
|
bool mMetaChange;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RsGxsDistantSearchResultChange: public RsGxsNotify
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& gid) : RsGxsNotify(gid), mRequestId(id){}
|
||||||
|
|
||||||
|
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
|
||||||
|
|
||||||
|
TurtleRequestId mRequestId ;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Relevant to message changes
|
||||||
|
*/
|
||||||
|
class RsGxsMsgChange : public RsGxsNotify
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsGxsMsgChange(NotifyType type, const RsGxsGroupId& gid, const RsGxsMessageId& msg_id,bool metaChange)
|
||||||
|
: RsGxsNotify(gid), mMsgId(msg_id), mNewMsgItem(nullptr),NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
||||||
|
|
||||||
|
RsGxsMessageId mMsgId;
|
||||||
|
RsGxsMsgItem *mNewMsgItem;
|
||||||
|
|
||||||
|
NotifyType getType(){ return NOTIFY_TYPE;}
|
||||||
|
bool metaChange() { return mMetaChange; }
|
||||||
|
private:
|
||||||
|
const NotifyType NOTIFY_TYPE;
|
||||||
|
bool mMetaChange;
|
||||||
|
};
|
||||||
|
|
@ -656,6 +656,9 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
#ifdef DEBUG_GXSTRANS
|
#ifdef DEBUG_GXSTRANS
|
||||||
std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl;
|
std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
std::list<RsGxsGroupId> grps_to_request;
|
||||||
|
GxsMsgReq msgs_to_request;
|
||||||
|
|
||||||
for( auto it = changes.begin(); it != changes.end(); ++it )
|
for( auto it = changes.begin(); it != changes.end(); ++it )
|
||||||
{
|
{
|
||||||
RsGxsGroupChange* grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
RsGxsGroupChange* grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
||||||
@ -666,18 +669,15 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
#ifdef DEBUG_GXSTRANS
|
#ifdef DEBUG_GXSTRANS
|
||||||
std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl;
|
std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
requestGroupsData(&(grpChange->mGrpIdList));
|
grps_to_request.push_back(grpChange->mGroupId);
|
||||||
}
|
}
|
||||||
else if(msgChange)
|
else if(msgChange)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_GXSTRANS
|
#ifdef DEBUG_GXSTRANS
|
||||||
std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl;
|
std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
uint32_t token;
|
|
||||||
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
msgs_to_request[msgChange->mGroupId].insert(msgChange->mMsgId);
|
||||||
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca,
|
|
||||||
opts, msgChange->msgChangeMap );
|
|
||||||
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
|
|
||||||
|
|
||||||
#ifdef DEBUG_GXSTRANS
|
#ifdef DEBUG_GXSTRANS
|
||||||
for( GxsMsgReq::const_iterator it = msgChange->msgChangeMap.begin();
|
for( GxsMsgReq::const_iterator it = msgChange->msgChangeMap.begin();
|
||||||
@ -698,6 +698,20 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
}
|
}
|
||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!msgs_to_request.empty())
|
||||||
|
{
|
||||||
|
uint32_t token;
|
||||||
|
RsTokReqOptions opts;
|
||||||
|
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
|
||||||
|
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca, opts, msgs_to_request);
|
||||||
|
|
||||||
|
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!grps_to_request.empty())
|
||||||
|
requestGroupsData(&grps_to_request);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t p3GxsTrans::AuthenPolicy()
|
uint32_t p3GxsTrans::AuthenPolicy()
|
||||||
|
@ -672,6 +672,7 @@ HEADERS += rsitems/rsnxsitems.h \
|
|||||||
util/rsdbbind.h \
|
util/rsdbbind.h \
|
||||||
util/contentvalue.h \
|
util/contentvalue.h \
|
||||||
gxs/rsgxsutil.h \
|
gxs/rsgxsutil.h \
|
||||||
|
gxs/rsgxsnotify.h \
|
||||||
gxs/gxssecurity.h \
|
gxs/gxssecurity.h \
|
||||||
gxs/rsgds.h \
|
gxs/rsgds.h \
|
||||||
gxs/rsgxs.h \
|
gxs/rsgxs.h \
|
||||||
@ -869,7 +870,7 @@ rs_jsonapi {
|
|||||||
genrestbedheader.name = Generating restbed header.
|
genrestbedheader.name = Generating restbed header.
|
||||||
genrestbedheader.input = genrestbedlib.output
|
genrestbedheader.input = genrestbedlib.output
|
||||||
genrestbedheader.output = $${RESTBED_HEADER_FILE}
|
genrestbedheader.output = $${RESTBED_HEADER_FILE}
|
||||||
genrestbedheader.CONFIG += target_predeps combine no_link
|
genrestbedheader.CONFIG += target_predeps no_link
|
||||||
genrestbedheader.variable_out = HEADERS
|
genrestbedheader.variable_out = HEADERS
|
||||||
genrestbedheader.commands = cd $${RESTBED_BUILD_PATH} && $(MAKE) install
|
genrestbedheader.commands = cd $${RESTBED_BUILD_PATH} && $(MAKE) install
|
||||||
QMAKE_EXTRA_COMPILERS += genrestbedheader
|
QMAKE_EXTRA_COMPILERS += genrestbedheader
|
||||||
|
@ -42,39 +42,19 @@ using std::dec;
|
|||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//#define PQI_HDL_DEBUG_UR 1
|
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
|
||||||
static double getCurrentTS()
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifndef WINDOWS_SYS
|
|
||||||
struct timeval cts_tmp;
|
|
||||||
gettimeofday(&cts_tmp, NULL);
|
|
||||||
double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0;
|
|
||||||
#else
|
|
||||||
struct _timeb timebuf;
|
|
||||||
_ftime( &timebuf);
|
|
||||||
double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0;
|
|
||||||
#endif
|
|
||||||
return cts;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct RsLog::logInfo pqihandlerzoneInfo = {RsLog::Default, "pqihandler"};
|
struct RsLog::logInfo pqihandlerzoneInfo = {RsLog::Default, "pqihandler"};
|
||||||
#define pqihandlerzone &pqihandlerzoneInfo
|
#define pqihandlerzone &pqihandlerzoneInfo
|
||||||
|
|
||||||
//static const int PQI_HANDLER_NB_PRIORITY_LEVELS = 10 ;
|
//static const int PQI_HANDLER_NB_PRIORITY_LEVELS = 10 ;
|
||||||
//static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
|
//static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
|
||||||
|
|
||||||
/****
|
//#define UPDATE_RATES_DEBUG 1
|
||||||
#define DEBUG_TICK 1
|
// #define DEBUG_TICK 1
|
||||||
#define RSITEM_DEBUG 1
|
// #define RSITEM_DEBUG 1
|
||||||
****/
|
|
||||||
|
|
||||||
pqihandler::pqihandler() : coreMtx("pqihandler")
|
pqihandler::pqihandler() : coreMtx("pqihandler")
|
||||||
{
|
{
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
// setup minimal total+individual rates.
|
// setup minimal total+individual rates.
|
||||||
rateIndiv_out = 0.01;
|
rateIndiv_out = 0.01;
|
||||||
@ -97,7 +77,7 @@ int pqihandler::tick()
|
|||||||
int moreToTick = 0;
|
int moreToTick = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
// tick all interfaces...
|
// tick all interfaces...
|
||||||
std::map<RsPeerId, SearchModule *>::iterator it;
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
||||||
@ -127,9 +107,13 @@ int pqihandler::tick()
|
|||||||
|
|
||||||
if(now > mLastRateCapUpdate + 5)
|
if(now > mLastRateCapUpdate + 5)
|
||||||
{
|
{
|
||||||
|
std::map<RsPeerId, RsConfigDataRates> rateMap;
|
||||||
|
std::map<RsPeerId, RsConfigDataRates>::iterator it;
|
||||||
|
|
||||||
|
|
||||||
// every 5 secs, update the max rates for all modules
|
// every 5 secs, update the max rates for all modules
|
||||||
|
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
for(std::map<RsPeerId, SearchModule *>::iterator it = mods.begin(); it != mods.end(); ++it)
|
for(std::map<RsPeerId, SearchModule *>::iterator it = mods.begin(); it != mods.end(); ++it)
|
||||||
{
|
{
|
||||||
// This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates
|
// This is rather inelegant, but pqihandler has searchModules that are dynamically allocated, so the max rates
|
||||||
@ -149,7 +133,7 @@ int pqihandler::tick()
|
|||||||
|
|
||||||
bool pqihandler::queueOutRsItem(RsItem *item)
|
bool pqihandler::queueOutRsItem(RsItem *item)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
uint32_t size ;
|
uint32_t size ;
|
||||||
locked_HandleRsItem(item, size);
|
locked_HandleRsItem(item, size);
|
||||||
@ -166,7 +150,7 @@ bool pqihandler::queueOutRsItem(RsItem *item)
|
|||||||
int pqihandler::status()
|
int pqihandler::status()
|
||||||
{
|
{
|
||||||
std::map<RsPeerId, SearchModule *>::iterator it;
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
{ // for output
|
{ // for output
|
||||||
std::string out = "pqihandler::status() Active Modules:\n";
|
std::string out = "pqihandler::status() Active Modules:\n";
|
||||||
@ -192,7 +176,7 @@ int pqihandler::status()
|
|||||||
|
|
||||||
bool pqihandler::AddSearchModule(SearchModule *mod)
|
bool pqihandler::AddSearchModule(SearchModule *mod)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
// if peerid used -> error.
|
// if peerid used -> error.
|
||||||
//std::map<RsPeerId, SearchModule *>::iterator it;
|
//std::map<RsPeerId, SearchModule *>::iterator it;
|
||||||
if (mod->peerid != mod->pqi->PeerId())
|
if (mod->peerid != mod->pqi->PeerId())
|
||||||
@ -223,7 +207,7 @@ bool pqihandler::AddSearchModule(SearchModule *mod)
|
|||||||
|
|
||||||
bool pqihandler::RemoveSearchModule(SearchModule *mod)
|
bool pqihandler::RemoveSearchModule(SearchModule *mod)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
std::map<RsPeerId, SearchModule *>::iterator it;
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
||||||
for(it = mods.begin(); it != mods.end(); ++it)
|
for(it = mods.begin(); it != mods.end(); ++it)
|
||||||
{
|
{
|
||||||
@ -313,7 +297,7 @@ int pqihandler::ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRat
|
|||||||
total.mQueueOut = 0;
|
total.mQueueOut = 0;
|
||||||
|
|
||||||
/* Lock once rates have been retrieved */
|
/* Lock once rates have been retrieved */
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
std::map<RsPeerId, SearchModule *>::iterator it;
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
||||||
for(it = mods.begin(); it != mods.end(); ++it)
|
for(it = mods.begin(); it != mods.end(); ++it)
|
||||||
@ -340,10 +324,6 @@ int pqihandler::ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRat
|
|||||||
// internal fn to send updates
|
// internal fn to send updates
|
||||||
int pqihandler::UpdateRates()
|
int pqihandler::UpdateRates()
|
||||||
{
|
{
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
|
||||||
uint64_t t_now;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::map<RsPeerId, SearchModule *>::iterator it;
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
||||||
|
|
||||||
float avail_in = getMaxRate(true);
|
float avail_in = getMaxRate(true);
|
||||||
@ -353,18 +333,15 @@ int pqihandler::UpdateRates()
|
|||||||
float used_bw_out = 0;
|
float used_bw_out = 0;
|
||||||
|
|
||||||
/* Lock once rates have been retrieved */
|
/* Lock once rates have been retrieved */
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
int num_sm = mods.size();
|
int num_sm = mods.size();
|
||||||
float used_bw_in_table[num_sm]; /* table of in bandwidth currently used by each module */
|
float used_bw_in_table[num_sm]; /* table of in bandwidth currently used by each module */
|
||||||
float used_bw_out_table[num_sm]; /* table of out bandwidth currently used by each module */
|
float used_bw_out_table[num_sm]; /* table of out bandwidth currently used by each module */
|
||||||
|
|
||||||
int effectiveUploadsSm = 0;
|
// loop through modules to get the used bandwidth
|
||||||
int effectiveDownloadsSm = 0;
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates Looping through modules" << std::endl;
|
||||||
// loop through modules to get the used bandwith and the number of modules that are affectively transfering
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
|
||||||
std::cerr << "Looping through modules" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -372,49 +349,33 @@ int pqihandler::UpdateRates()
|
|||||||
for(it = mods.begin(); it != mods.end(); ++it)
|
for(it = mods.begin(); it != mods.end(); ++it)
|
||||||
{
|
{
|
||||||
SearchModule *mod = (it -> second);
|
SearchModule *mod = (it -> second);
|
||||||
float crate_in = mod -> pqi -> getRate(true);
|
|
||||||
|
|
||||||
traffInSum += mod -> pqi -> getTraffic(true);
|
traffInSum += mod -> pqi -> getTraffic(true);
|
||||||
traffOutSum += mod -> pqi -> getTraffic(false);
|
traffOutSum += mod -> pqi -> getTraffic(false);
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
float crate_in = mod -> pqi -> getRate(true);
|
||||||
if(crate_in > 0.0)
|
|
||||||
std::cerr << " got in rate for peer " << it->first << " : " << crate_in << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((crate_in > 0.01 * avail_in) || (crate_in > 0.1))
|
|
||||||
{
|
|
||||||
++effectiveDownloadsSm;
|
|
||||||
}
|
|
||||||
|
|
||||||
float crate_out = mod -> pqi -> getRate(false);
|
float crate_out = mod -> pqi -> getRate(false);
|
||||||
if ((crate_out > 0.01 * avail_out) || (crate_out > 0.1))
|
|
||||||
{
|
|
||||||
++effectiveUploadsSm;
|
|
||||||
}
|
|
||||||
|
|
||||||
used_bw_in += crate_in;
|
used_bw_in += crate_in;
|
||||||
used_bw_out += crate_out;
|
used_bw_out += crate_out;
|
||||||
|
|
||||||
/* fill the table of bandwidth */
|
/* fill the table of used bandwidths */
|
||||||
used_bw_in_table[index] = crate_in;
|
used_bw_in_table[index] = crate_in;
|
||||||
used_bw_out_table[index] = crate_out;
|
used_bw_out_table[index] = crate_out;
|
||||||
|
|
||||||
++index;
|
++index;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
t_now = 1000 * getCurrentTS();
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates Sorting used_bw_out_table: " << num_sm << " entries" << std::endl;
|
||||||
std::cerr << dec << t_now << " pqihandler::UpdateRates(): Sorting used_bw_out_table: " << num_sm << " entries" << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Sort the used bw in/out table in ascending order */
|
/* Sort the used bw in/out table in ascending order */
|
||||||
std::sort(used_bw_in_table, used_bw_in_table + num_sm);
|
std::sort(used_bw_in_table, used_bw_in_table + num_sm);
|
||||||
std::sort(used_bw_out_table, used_bw_out_table + num_sm);
|
std::sort(used_bw_out_table, used_bw_out_table + num_sm);
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
t_now = 1000 * getCurrentTS();
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates used_bw_out " << used_bw_out << std::endl;
|
||||||
std::cerr << dec << t_now << " pqihandler::UpdateRates(): Done." << std::endl;
|
|
||||||
std::cerr << dec << t_now << " pqihandler::UpdateRates(): used_bw_out " << used_bw_out << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Calculate the optimal out_max value, taking into account avail_out and the out bw requested by modules */
|
/* Calculate the optimal out_max value, taking into account avail_out and the out bw requested by modules */
|
||||||
@ -441,9 +402,8 @@ int pqihandler::UpdateRates()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
t_now = 1000 * getCurrentTS();
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates mod_index " << mod_index << " out_max_bw " << out_max_bw << " remaining out bw " << out_remaining_bw << std::endl;
|
||||||
std::cerr << dec << t_now << " pqihandler::UpdateRates(): mod_index " << mod_index << " out_max_bw " << out_max_bw << " remaining out bw " << out_remaining_bw << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate only half the remaining out bw, if any, to make it smoother */
|
/* Allocate only half the remaining out bw, if any, to make it smoother */
|
||||||
@ -473,67 +433,70 @@ int pqihandler::UpdateRates()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
t_now = 1000 * getCurrentTS();
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates mod_index " << mod_index << " in_max_bw " << in_max_bw << " remaining in bw " << in_remaining_bw << std::endl;
|
||||||
std::cerr << dec << t_now << " pqihandler::UpdateRates(): mod_index " << mod_index << " in_max_bw " << in_max_bw << " remaining in bw " << in_remaining_bw << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Allocate only half the remaining in bw, if any, to make it smoother */
|
/* Allocate only half the remaining in bw, if any, to make it smoother */
|
||||||
in_max_bw = in_max_bw + in_remaining_bw / 2;
|
in_max_bw = in_max_bw + in_remaining_bw / 2;
|
||||||
|
|
||||||
|
// store current total in and ou used bw
|
||||||
#ifdef DEBUG_QOS
|
|
||||||
// std::cerr << "Totals (In) Used B/W " << used_bw_in;
|
|
||||||
// std::cerr << " Available B/W " << avail_in;
|
|
||||||
// std::cerr << " Effective transfers " << effectiveDownloadsSm << std::endl;
|
|
||||||
// std::cerr << "Totals (Out) Used B/W " << used_bw_out;
|
|
||||||
// std::cerr << " Available B/W " << avail_out;
|
|
||||||
// std::cerr << " Effective transfers " << effectiveUploadsSm << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
locked_StoreCurrentRates(used_bw_in, used_bw_out);
|
locked_StoreCurrentRates(used_bw_in, used_bw_out);
|
||||||
|
|
||||||
//computing average rates for effective transfers
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
float max_in_effective = avail_in / num_sm;
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates setting new out_max " << out_max_bw << " in_max " << in_max_bw << std::endl;
|
||||||
if (effectiveDownloadsSm != 0) {
|
|
||||||
max_in_effective = avail_in / effectiveDownloadsSm;
|
|
||||||
}
|
|
||||||
float max_out_effective = avail_out / num_sm;
|
|
||||||
if (effectiveUploadsSm != 0) {
|
|
||||||
max_out_effective = avail_out / effectiveUploadsSm;
|
|
||||||
}
|
|
||||||
|
|
||||||
//modify the in and out limit
|
|
||||||
#ifdef PQI_HDL_DEBUG_UR
|
|
||||||
t_now = 1000 * getCurrentTS();
|
|
||||||
std::cerr << dec << t_now << " pqihandler::UpdateRates(): setting new out_max " << out_max_bw << " in_max " << in_max_bw << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// retrieve down (from peer point of view) bandwidth limits set by peers in their own settings
|
||||||
|
std::map<RsPeerId, RsConfigDataRates> rateMap;
|
||||||
|
rsConfig->getAllBandwidthRates(rateMap);
|
||||||
|
std::map<RsPeerId, RsConfigDataRates>::iterator rateMap_it;
|
||||||
|
|
||||||
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
|
// Dump RsConfigurationDataRates
|
||||||
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates RsConfigDataRates dump" << std::endl;
|
||||||
|
for (rateMap_it = rateMap.begin(); rateMap_it != rateMap.end(); rateMap_it++)
|
||||||
|
RsDbg () << "UPDATE_RATES pqihandler::UpdateRates PeerId " << rateMap_it->first.toStdString() << " mAllowedOut " << rateMap_it->second.mAllowedOut << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// update max rates taking into account the limits set by peers in their own settings
|
||||||
for(it = mods.begin(); it != mods.end(); ++it)
|
for(it = mods.begin(); it != mods.end(); ++it)
|
||||||
{
|
{
|
||||||
SearchModule *mod = (it -> second);
|
SearchModule *mod = (it -> second);
|
||||||
|
|
||||||
|
// for our down bandwidth we set the max to the calculated value without taking into account the max set by peers: they will control their up bw on their side
|
||||||
mod -> pqi -> setMaxRate(true, in_max_bw);
|
mod -> pqi -> setMaxRate(true, in_max_bw);
|
||||||
|
|
||||||
|
// for our up bandwidth we limit to the maximum down bw provided by peers via BwCtrl because we don't want to clog our outqueues, the SSL buffers, and our friends inbound queues
|
||||||
|
if ((rateMap_it = rateMap.find(mod->pqi->PeerId())) != rateMap.end())
|
||||||
|
{
|
||||||
|
if (rateMap_it->second.mAllowedOut > 0)
|
||||||
|
{
|
||||||
|
if (out_max_bw > rateMap_it->second.mAllowedOut)
|
||||||
|
mod -> pqi -> setMaxRate(false, rateMap_it->second.mAllowedOut);
|
||||||
|
else
|
||||||
mod -> pqi -> setMaxRate(false, out_max_bw);
|
mod -> pqi -> setMaxRate(false, out_max_bw);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
mod -> pqi -> setMaxRate(false, out_max_bw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UPDATE_RATES_DEBUG
|
||||||
//cap the rates
|
// dump maxRates
|
||||||
for(it = mods.begin(); it != mods.end(); ++it)
|
for(it = mods.begin(); it != mods.end(); ++it)
|
||||||
{
|
{
|
||||||
SearchModule *mod = (it -> second);
|
SearchModule *mod = (it -> second);
|
||||||
if (mod -> pqi -> getMaxRate(false) < max_out_effective) mod -> pqi -> setMaxRate(false, max_out_effective);
|
RsDbg() << "UPDATE_RATES pqihandler::UpdateRates PeerID " << (mod ->pqi -> PeerId()).toStdString() << " new bandwidth limits up " << mod -> pqi -> getMaxRate(false) << " down " << mod -> pqi -> getMaxRate(true) << std::endl;
|
||||||
if (mod -> pqi -> getMaxRate(false) > avail_out) mod -> pqi -> setMaxRate(false, avail_out);
|
|
||||||
if (mod -> pqi -> getMaxRate(true) < max_in_effective) mod -> pqi -> setMaxRate(true, max_in_effective);
|
|
||||||
if (mod -> pqi -> getMaxRate(true) > avail_in) mod -> pqi -> setMaxRate(true, avail_in);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pqihandler::getCurrentRates(float &in, float &out)
|
void pqihandler::getCurrentRates(float &in, float &out)
|
||||||
{
|
{
|
||||||
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
RS_STACK_MUTEX(coreMtx); /**************** LOCKED MUTEX ****************/
|
||||||
|
|
||||||
in = rateTotal_in;
|
in = rateTotal_in;
|
||||||
out = rateTotal_out;
|
out = rateTotal_out;
|
||||||
|
@ -1110,11 +1110,17 @@ int pqissl::SSL_Connection_Complete()
|
|||||||
if(rsEvents)
|
if(rsEvents)
|
||||||
{
|
{
|
||||||
X509 *x509 = SSL_get_peer_certificate(ssl_connection);
|
X509 *x509 = SSL_get_peer_certificate(ssl_connection);
|
||||||
|
|
||||||
|
if(x509)
|
||||||
|
{
|
||||||
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
|
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
|
||||||
ev->mSslId = RsX509Cert::getCertSslId(*x509);
|
ev->mSslId = RsX509Cert::getCertSslId(*x509);
|
||||||
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
|
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
|
||||||
|
|
||||||
|
if(!ev->mSslId.isNull())
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string out;
|
std::string out;
|
||||||
rs_sprintf(out, "pqissl::SSL_Connection_Complete()\nIssues with SSL Connect(%d)!\n", err);
|
rs_sprintf(out, "pqissl::SSL_Connection_Complete()\nIssues with SSL Connect(%d)!\n", err);
|
||||||
|
@ -658,7 +658,8 @@ public:
|
|||||||
* @brief Get file details
|
* @brief Get file details
|
||||||
* @jsonapi{development}
|
* @jsonapi{development}
|
||||||
* @param[in] hash file identifier
|
* @param[in] hash file identifier
|
||||||
* @param[in] hintflags filtering hint (RS_FILE_HINTS_EXTRA|...|RS_FILE_HINTS_LOCAL)
|
* @param[in] hintflags filtering hint ( RS_FILE_HINTS_UPLOAD|...|
|
||||||
|
* RS_FILE_HINTS_EXTRA|RS_FILE_HINTS_LOCAL )
|
||||||
* @param[out] info storage for file information
|
* @param[out] info storage for file information
|
||||||
* @return true if file found, false otherwise
|
* @return true if file found, false otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -310,11 +310,13 @@ public:
|
|||||||
* @param[in] channelId id of the channel of which the content is requested
|
* @param[in] channelId id of the channel of which the content is requested
|
||||||
* @param[out] posts storage for posts
|
* @param[out] posts storage for posts
|
||||||
* @param[out] comments storage for the comments
|
* @param[out] comments storage for the comments
|
||||||
|
* @param[out] votes storage for votes
|
||||||
* @return false if something failed, true otherwhise
|
* @return false if something failed, true otherwhise
|
||||||
*/
|
*/
|
||||||
virtual bool getChannelAllContent( const RsGxsGroupId& channelId,
|
virtual bool getChannelAllContent( const RsGxsGroupId& channelId,
|
||||||
std::vector<RsGxsChannelPost>& posts,
|
std::vector<RsGxsChannelPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) = 0;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get channel messages and comments corresponding to the given IDs.
|
* @brief Get channel messages and comments corresponding to the given IDs.
|
||||||
@ -326,12 +328,14 @@ public:
|
|||||||
* @param[in] contentsIds ids of requested contents
|
* @param[in] contentsIds ids of requested contents
|
||||||
* @param[out] posts storage for posts
|
* @param[out] posts storage for posts
|
||||||
* @param[out] comments storage for the comments
|
* @param[out] comments storage for the comments
|
||||||
|
* @param[out] votes storage for the votes
|
||||||
* @return false if something failed, true otherwhise
|
* @return false if something failed, true otherwhise
|
||||||
*/
|
*/
|
||||||
virtual bool getChannelContent( const RsGxsGroupId& channelId,
|
virtual bool getChannelContent( const RsGxsGroupId& channelId,
|
||||||
const std::set<RsGxsMessageId>& contentsIds,
|
const std::set<RsGxsMessageId>& contentsIds,
|
||||||
std::vector<RsGxsChannelPost>& posts,
|
std::vector<RsGxsChannelPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) = 0;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get channel comments corresponding to the given IDs.
|
* @brief Get channel comments corresponding to the given IDs.
|
||||||
@ -571,6 +575,9 @@ public:
|
|||||||
RS_DEPRECATED_FOR(getChannelsInfo)
|
RS_DEPRECATED_FOR(getChannelsInfo)
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups) = 0;
|
||||||
|
|
||||||
|
RS_DEPRECATED_FOR(getChannelContent)
|
||||||
|
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &votes) = 0;
|
||||||
|
|
||||||
RS_DEPRECATED_FOR(getChannelContent)
|
RS_DEPRECATED_FOR(getChannelContent)
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
|
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) = 0;
|
||||||
|
|
||||||
|
@ -46,24 +46,22 @@ extern RsGxsCircles* rsGxsCircles;
|
|||||||
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
|
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
|
||||||
{
|
{
|
||||||
UNKNOWN = 0, /// Used to detect uninizialized values.
|
UNKNOWN = 0, /// Used to detect uninizialized values.
|
||||||
PUBLIC = 1, /// Public distribution
|
PUBLIC = 1, /// Public distribution, based on GxsIds
|
||||||
EXTERNAL = 2, /// Restricted to an external circle
|
EXTERNAL = 2, /// Restricted to an external circle, based on GxsIds
|
||||||
|
|
||||||
/** Restricted to a group of friend nodes, the administrator of the circle
|
NODES_GROUP = 3, /// Restricted to a group of friend nodes, the administrator of the circle behave as a hub for them
|
||||||
* behave as a hub for them */
|
/// Based on PGP nodes ids.
|
||||||
NODES_GROUP = 3,
|
|
||||||
|
|
||||||
LOCAL = 4, /// not distributed at all
|
LOCAL = 4, /// not distributed at all
|
||||||
|
|
||||||
/** Self-restricted. Used only at creation time of self-restricted circles
|
/** Self-restricted. Used only at creation time of self-restricted circles
|
||||||
* when the circle id isn't known yet. Once the circle id is known the type
|
* when the circle id isn't known yet. Once the circle id is known the type
|
||||||
* is set to EXTERNAL, and the external circle id is set to the id of the
|
* is set to EXTERNAL, and the external circle id is set to the id of the
|
||||||
* circle itself.
|
* circle itself. Based on GxsIds.
|
||||||
*/
|
*/
|
||||||
EXT_SELF = 5,
|
EXT_SELF = 5,
|
||||||
|
|
||||||
/// distributed to nodes signed by your own PGP key only.
|
YOUR_EYES_ONLY = 6 /// distributed to nodes signed by your own PGP key only.
|
||||||
YOUR_EYES_ONLY = 6
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: convert to enum class
|
// TODO: convert to enum class
|
||||||
@ -98,22 +96,32 @@ struct RsGxsCircleGroup : RsSerializable
|
|||||||
~RsGxsCircleGroup() override;
|
~RsGxsCircleGroup() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class RsGxsCircleSubscriptionType:uint8_t {
|
||||||
|
UNKNOWN = 0x00,
|
||||||
|
SUBSCRIBE = 0x01,
|
||||||
|
UNSUBSCRIBE = 0x02
|
||||||
|
};
|
||||||
|
|
||||||
struct RsGxsCircleMsg : RsSerializable
|
struct RsGxsCircleMsg : RsSerializable
|
||||||
{
|
{
|
||||||
RsMsgMetaData mMeta;
|
RsMsgMetaData mMeta;
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
|
// This item is actually totally unused, so we can change it no problem
|
||||||
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
|
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
|
||||||
/* This is horrible and should be changed into yet to be defined something
|
/* This is horrible and should be changed into yet to be defined something
|
||||||
* reasonable in next non-retrocompatible version */
|
* reasonable in next non-retrocompatible version */
|
||||||
std::string stuff;
|
std::string stuff;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
RsGxsCircleSubscriptionType mSubscriptionType;
|
||||||
|
|
||||||
/// @see RsSerializable
|
/// @see RsSerializable
|
||||||
void serial_process( RsGenericSerializer::SerializeJob j,
|
void serial_process( RsGenericSerializer::SerializeJob j,
|
||||||
RsGenericSerializer::SerializeContext& ctx) override
|
RsGenericSerializer::SerializeContext& ctx) override
|
||||||
{
|
{
|
||||||
RS_SERIAL_PROCESS(mMeta);
|
RS_SERIAL_PROCESS(mMeta);
|
||||||
RS_SERIAL_PROCESS(stuff);
|
RS_SERIAL_PROCESS(mSubscriptionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
~RsGxsCircleMsg() override;
|
~RsGxsCircleMsg() override;
|
||||||
@ -121,15 +129,29 @@ struct RsGxsCircleMsg : RsSerializable
|
|||||||
|
|
||||||
struct RsGxsCircleDetails : RsSerializable
|
struct RsGxsCircleDetails : RsSerializable
|
||||||
{
|
{
|
||||||
RsGxsCircleDetails() :
|
RsGxsCircleDetails() : mCircleType(RsGxsCircleType::EXTERNAL), mAmIAllowed(false),mAmIAdmin(false) {}
|
||||||
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
|
|
||||||
mAmIAllowed(false),mAmIAdmin(false) {}
|
|
||||||
~RsGxsCircleDetails() override;
|
~RsGxsCircleDetails() override;
|
||||||
|
|
||||||
|
// helper functions.
|
||||||
|
bool isIdInCircle(const RsGxsId& id) const { return mAllowedGxsIds.find(id) != mAllowedGxsIds.end(); }
|
||||||
|
bool isIdInInviteeList(const RsGxsId& id) const
|
||||||
|
{
|
||||||
|
auto it = mSubscriptionFlags.find(id);
|
||||||
|
return (it != mSubscriptionFlags.end()) && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
|
||||||
|
}
|
||||||
|
bool isIdRequestingMembership(const RsGxsId& id) const
|
||||||
|
{
|
||||||
|
auto it = mSubscriptionFlags.find(id);
|
||||||
|
return it != mSubscriptionFlags.end() && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
|
||||||
|
}
|
||||||
|
bool isGxsIdBased() const { return mCircleType==RsGxsCircleType::PUBLIC || mCircleType==RsGxsCircleType::EXTERNAL || mCircleType==RsGxsCircleType::EXT_SELF; }
|
||||||
|
|
||||||
|
// Members
|
||||||
|
|
||||||
RsGxsCircleId mCircleId;
|
RsGxsCircleId mCircleId;
|
||||||
std::string mCircleName;
|
std::string mCircleName;
|
||||||
|
|
||||||
uint32_t mCircleType;
|
RsGxsCircleType mCircleType;
|
||||||
RsGxsCircleId mRestrictedCircleId;
|
RsGxsCircleId mRestrictedCircleId;
|
||||||
|
|
||||||
/** true when one of load GXS ids belong to the circle allowed list (admin
|
/** true when one of load GXS ids belong to the circle allowed list (admin
|
||||||
@ -165,32 +187,54 @@ struct RsGxsCircleDetails : RsSerializable
|
|||||||
|
|
||||||
enum class RsGxsCircleEventCode: uint8_t
|
enum class RsGxsCircleEventCode: uint8_t
|
||||||
{
|
{
|
||||||
|
// Notifications be only have 4 different possibilities:
|
||||||
|
//
|
||||||
|
// invitee list join/leave and
|
||||||
|
// membership request / leave request
|
||||||
|
//
|
||||||
|
// From there, depending on what the client displays, it is possible to interpret these
|
||||||
|
// as "some user joined the circle", or "membership pending for that Id", etc, depending
|
||||||
|
// on whether the current node owns the circle, or the admin is or is not yours.
|
||||||
|
//
|
||||||
|
// These should be decided in the UI based on what the circle cache is displaying.
|
||||||
|
//
|
||||||
UNKNOWN = 0x00,
|
UNKNOWN = 0x00,
|
||||||
|
|
||||||
/** mCircleId contains the circle id and mGxsId is the id requesting
|
/**
|
||||||
* membership */
|
* Sent when we receive a membership request msg for a particular circle.
|
||||||
|
*
|
||||||
|
* mCircleId contains the circle id and mGxsId is the id requesting membership */
|
||||||
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
|
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
|
||||||
|
|
||||||
/** mCircleId is the circle that invites me, and mGxsId is my own Id that is
|
/**
|
||||||
* invited */
|
* Sent when the ID has been added to the circle invitee list.
|
||||||
CIRCLE_MEMBERSHIP_INVITE = 0x02,
|
*
|
||||||
|
* mCircleId is the circle that invites me, and mGxsId is my own Id that is invited */
|
||||||
|
CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST = 0x02,
|
||||||
|
|
||||||
/** mCircleId contains the circle id and mGxsId is the id dropping
|
/**
|
||||||
* membership */
|
* Sent when a GxsId annouces its will to not be in the circle.
|
||||||
|
*
|
||||||
|
* mCircleId contains the circle id and mGxsId is the id dropping membership */
|
||||||
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
|
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
|
||||||
|
|
||||||
/// mCircleId contains the circle id and mGxsId is the id of the new member
|
/**
|
||||||
CIRCLE_MEMBERSHIP_JOIN = 0x04,
|
* Sent when the Id has been removed from the invitee list.
|
||||||
|
*
|
||||||
|
* mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
|
||||||
|
CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST = 0x04,
|
||||||
|
|
||||||
/** mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
|
/**
|
||||||
CIRCLE_MEMBERSHIP_REVOQUED= 0x05,
|
* Means a new circle has been received.
|
||||||
|
*
|
||||||
/** mCircleId contains the circle id */
|
* mCircleId contains the circle id */
|
||||||
NEW_CIRCLE = 0x06,
|
NEW_CIRCLE = 0x05,
|
||||||
|
|
||||||
/** no additional information. Simply means that the info previously from the cache has changed. */
|
|
||||||
CACHE_DATA_UPDATED = 0x07,
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Means that the circle cache has updated, and membership status that is displayed should probably be updated to.
|
||||||
|
*
|
||||||
|
* no additional information. Simply means that the info previously from the cache has changed. */
|
||||||
|
CACHE_DATA_UPDATED = 0x06,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RsGxsCircleEvent: RsEvent
|
struct RsGxsCircleEvent: RsEvent
|
||||||
|
@ -112,6 +112,7 @@ enum class RsForumEventCode: uint8_t
|
|||||||
SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed
|
SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed
|
||||||
READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread
|
READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread
|
||||||
STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed
|
STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed
|
||||||
|
MODERATOR_LIST_CHANGED = 0x08, /// forum moderation list has changed.
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RsGxsForumEvent: RsEvent
|
struct RsGxsForumEvent: RsEvent
|
||||||
@ -123,6 +124,8 @@ struct RsGxsForumEvent: RsEvent
|
|||||||
RsForumEventCode mForumEventCode;
|
RsForumEventCode mForumEventCode;
|
||||||
RsGxsGroupId mForumGroupId;
|
RsGxsGroupId mForumGroupId;
|
||||||
RsGxsMessageId mForumMsgId;
|
RsGxsMessageId mForumMsgId;
|
||||||
|
std::list<RsGxsId> mModeratorsAdded;
|
||||||
|
std::list<RsGxsId> mModeratorsRemoved;
|
||||||
|
|
||||||
///* @see RsEvent @see RsSerializable
|
///* @see RsEvent @see RsSerializable
|
||||||
void serial_process(
|
void serial_process(
|
||||||
@ -133,6 +136,9 @@ struct RsGxsForumEvent: RsEvent
|
|||||||
RS_SERIAL_PROCESS(mForumEventCode);
|
RS_SERIAL_PROCESS(mForumEventCode);
|
||||||
RS_SERIAL_PROCESS(mForumGroupId);
|
RS_SERIAL_PROCESS(mForumGroupId);
|
||||||
RS_SERIAL_PROCESS(mForumMsgId);
|
RS_SERIAL_PROCESS(mForumMsgId);
|
||||||
|
RS_SERIAL_PROCESS(mForumMsgId);
|
||||||
|
RS_SERIAL_PROCESS(mModeratorsAdded);
|
||||||
|
RS_SERIAL_PROCESS(mModeratorsRemoved);
|
||||||
}
|
}
|
||||||
|
|
||||||
~RsGxsForumEvent() override;
|
~RsGxsForumEvent() override;
|
||||||
|
@ -116,12 +116,14 @@ struct RsGxsIface
|
|||||||
*/
|
*/
|
||||||
virtual uint16_t serviceType() const =0;
|
virtual uint16_t serviceType() const =0;
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
/*!
|
/*!
|
||||||
* Gxs services should call this for automatic handling of
|
* Gxs services should call this for automatic handling of
|
||||||
* changes, send
|
* changes, send
|
||||||
* @param changes
|
* @param changes
|
||||||
*/
|
*/
|
||||||
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @return handle to token service for this GXS service
|
* @return handle to token service for this GXS service
|
||||||
|
@ -72,6 +72,7 @@ public:
|
|||||||
|
|
||||||
~RsGxsIfaceHelper() = default;
|
~RsGxsIfaceHelper() = default;
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
/*!
|
/*!
|
||||||
* Gxs services should call this for automatic handling of
|
* Gxs services should call this for automatic handling of
|
||||||
* changes, send
|
* changes, send
|
||||||
@ -81,6 +82,7 @@ public:
|
|||||||
{
|
{
|
||||||
mGxs.receiveChanges(changes);
|
mGxs.receiveChanges(changes);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Generic Lists */
|
/* Generic Lists */
|
||||||
|
|
||||||
|
@ -34,8 +34,6 @@
|
|||||||
#include "serialiser/rstypeserializer.h"
|
#include "serialiser/rstypeserializer.h"
|
||||||
#include "util/rstime.h"
|
#include "util/rstime.h"
|
||||||
|
|
||||||
typedef Sha1CheckSum RsGxsMessageId;
|
|
||||||
|
|
||||||
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
|
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
|
||||||
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
|
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
|
||||||
typedef std::map<RsGxsGrpMsgIdPair, std::set<RsGxsMessageId> > MsgRelatedIdResult;
|
typedef std::map<RsGxsGrpMsgIdPair, std::set<RsGxsMessageId> > MsgRelatedIdResult;
|
||||||
|
@ -32,69 +32,6 @@ typedef uint32_t TurtleRequestId;
|
|||||||
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
|
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
|
||||||
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
|
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
|
||||||
|
|
||||||
/*!
|
|
||||||
* The aim of this class is to abstract how changes are represented so they can
|
|
||||||
* be determined outside the client API without explcitly enumerating all
|
|
||||||
* possible changes at the interface
|
|
||||||
*/
|
|
||||||
struct RsGxsNotify
|
|
||||||
{
|
|
||||||
enum NotifyType
|
|
||||||
{
|
|
||||||
TYPE_UNKNOWN = 0x00,
|
|
||||||
TYPE_PUBLISHED = 0x01,
|
|
||||||
TYPE_RECEIVED_NEW = 0x02,
|
|
||||||
TYPE_PROCESSED = 0x03,
|
|
||||||
TYPE_RECEIVED_PUBLISHKEY = 0x04,
|
|
||||||
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
|
|
||||||
TYPE_STATISTICS_CHANGED = 0x06
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual ~RsGxsNotify() {}
|
|
||||||
virtual NotifyType getType() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Relevant to group changes
|
|
||||||
*/
|
|
||||||
class RsGxsGroupChange : public RsGxsNotify
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RsGxsGroupChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
|
||||||
std::list<RsGxsGroupId> mGrpIdList;
|
|
||||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
|
||||||
bool metaChange() { return mMetaChange; }
|
|
||||||
private:
|
|
||||||
const NotifyType NOTIFY_TYPE;
|
|
||||||
bool mMetaChange;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RsGxsDistantSearchResultChange: public RsGxsNotify
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& group_id) : mRequestId(id),mGroupId(group_id){}
|
|
||||||
|
|
||||||
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
|
|
||||||
|
|
||||||
TurtleRequestId mRequestId ;
|
|
||||||
RsGxsGroupId mGroupId;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Relevant to message changes
|
|
||||||
*/
|
|
||||||
class RsGxsMsgChange : public RsGxsNotify
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RsGxsMsgChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
|
|
||||||
NotifyType getType(){ return NOTIFY_TYPE;}
|
|
||||||
bool metaChange() { return mMetaChange; }
|
|
||||||
private:
|
|
||||||
const NotifyType NOTIFY_TYPE;
|
|
||||||
bool mMetaChange;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // RSGXSSERVICE_H
|
#endif // RSGXSSERVICE_H
|
||||||
|
@ -328,6 +328,7 @@ using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, R
|
|||||||
using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
|
using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
|
||||||
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
|
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
|
||||||
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
|
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
|
||||||
|
using RsGxsMessageId = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::GXS_MSG >;
|
||||||
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
|
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
|
||||||
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
|
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
|
||||||
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
|
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;
|
||||||
|
@ -116,10 +116,12 @@ const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001;
|
|||||||
const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001;
|
const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001;
|
||||||
|
|
||||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
|
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
|
||||||
const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
|
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
|
||||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
|
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
|
||||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
|
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
|
||||||
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED = RS_FEED_TYPE_CIRCLE | 0x0005;
|
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED = RS_FEED_TYPE_CIRCLE | 0x0005;
|
||||||
|
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOKED = RS_FEED_TYPE_CIRCLE | 0x0006;
|
||||||
|
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED= RS_FEED_TYPE_CIRCLE | 0x0007;
|
||||||
|
|
||||||
const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001;
|
const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001;
|
||||||
|
|
||||||
|
@ -154,13 +154,15 @@ public:
|
|||||||
virtual bool getBoardAllContent(
|
virtual bool getBoardAllContent(
|
||||||
const RsGxsGroupId& boardId,
|
const RsGxsGroupId& boardId,
|
||||||
std::vector<RsPostedPost>& posts,
|
std::vector<RsPostedPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) = 0;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) = 0;
|
||||||
|
|
||||||
virtual bool getBoardContent(
|
virtual bool getBoardContent(
|
||||||
const RsGxsGroupId& boardId,
|
const RsGxsGroupId& boardId,
|
||||||
const std::set<RsGxsMessageId>& contentsIds,
|
const std::set<RsGxsMessageId>& contentsIds,
|
||||||
std::vector<RsPostedPost>& posts,
|
std::vector<RsPostedPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) = 0;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) = 0;
|
||||||
|
|
||||||
virtual bool editBoard(RsPostedGroup& board) =0;
|
virtual bool editBoard(RsPostedGroup& board) =0;
|
||||||
|
|
||||||
@ -176,6 +178,11 @@ public:
|
|||||||
virtual bool getGroupData( const uint32_t& token,
|
virtual bool getGroupData( const uint32_t& token,
|
||||||
std::vector<RsPostedGroup> &groups ) = 0;
|
std::vector<RsPostedGroup> &groups ) = 0;
|
||||||
|
|
||||||
|
RS_DEPRECATED_FOR(getBoardsContent)
|
||||||
|
virtual bool getPostData(
|
||||||
|
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
||||||
|
std::vector<RsGxsComment>& cmts, std::vector<RsGxsVote>& vots) = 0;
|
||||||
|
|
||||||
RS_DEPRECATED_FOR(getBoardsContent)
|
RS_DEPRECATED_FOR(getBoardsContent)
|
||||||
virtual bool getPostData(
|
virtual bool getPostData(
|
||||||
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
const uint32_t& token, std::vector<RsPostedPost>& posts,
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#define USE_NEW_CHUNK_CHECKING_CODE
|
#define USE_NEW_CHUNK_CHECKING_CODE
|
||||||
|
|
||||||
typedef Sha1CheckSum RsFileHash ;
|
typedef Sha1CheckSum RsFileHash ;
|
||||||
typedef Sha1CheckSum RsMessageId ;
|
|
||||||
|
|
||||||
const uint32_t FT_STATE_FAILED = 0x0000 ;
|
const uint32_t FT_STATE_FAILED = 0x0000 ;
|
||||||
const uint32_t FT_STATE_OKAY = 0x0001 ;
|
const uint32_t FT_STATE_OKAY = 0x0001 ;
|
||||||
|
@ -35,7 +35,9 @@ RsItem *RsGxsCircleSerialiser::create_item(uint16_t service, uint8_t item_sub_id
|
|||||||
switch(item_sub_id)
|
switch(item_sub_id)
|
||||||
{
|
{
|
||||||
case RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM: return new RsGxsCircleGroupItem();
|
case RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM: return new RsGxsCircleGroupItem();
|
||||||
|
#ifdef TO_REMOVE
|
||||||
case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM: return new RsGxsCircleMsgItem();
|
case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM: return new RsGxsCircleMsgItem();
|
||||||
|
#endif
|
||||||
case RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM: return new RsGxsCircleSubscriptionRequestItem();
|
case RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM: return new RsGxsCircleSubscriptionRequestItem();
|
||||||
default:
|
default:
|
||||||
return NULL ;
|
return NULL ;
|
||||||
@ -46,20 +48,27 @@ void RsGxsCircleSubscriptionRequestItem::clear()
|
|||||||
{
|
{
|
||||||
time_stamp = 0 ;
|
time_stamp = 0 ;
|
||||||
time_out = 0 ;
|
time_out = 0 ;
|
||||||
subscription_type = SUBSCRIPTION_REQUEST_UNKNOWN;
|
subscription_type = RsGxsCircleSubscriptionType::UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
void RsGxsCircleMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
void RsGxsCircleMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
{
|
{
|
||||||
//RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"mMsg.stuff") ;//Should be this but not retrocompatible...
|
//RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"mMsg.stuff") ;//Should be this but not retrocompatible...
|
||||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"msg.stuff") ;
|
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"msg.stuff") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RsGxsCircleMsgItem::clear()
|
||||||
|
{
|
||||||
|
mMsg.stuff.clear();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void RsGxsCircleSubscriptionRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
void RsGxsCircleSubscriptionRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
{
|
{
|
||||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_stamp,"time_stamp") ;
|
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_stamp,"time_stamp") ;
|
||||||
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_out ,"time_out") ;
|
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_out ,"time_out") ;
|
||||||
RsTypeSerializer::serial_process<uint8_t> (j,ctx,subscription_type ,"subscription_type") ;
|
RsTypeSerializer::serial_process<RsGxsCircleSubscriptionType> (j,ctx,subscription_type ,"subscription_type") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
@ -69,11 +78,6 @@ void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,Rs
|
|||||||
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,subCircleSet,"subCircleSet") ;
|
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,subCircleSet,"subCircleSet") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsGxsCircleMsgItem::clear()
|
|
||||||
{
|
|
||||||
mMsg.stuff.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RsGxsCircleGroupItem::clear()
|
void RsGxsCircleGroupItem::clear()
|
||||||
{
|
{
|
||||||
pgpIdSet.TlvClear();
|
pgpIdSet.TlvClear();
|
||||||
|
@ -64,6 +64,7 @@ public:
|
|||||||
RsTlvGxsCircleIdSet subCircleSet;
|
RsTlvGxsCircleIdSet subCircleSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
class RsGxsCircleMsgItem : public RsGxsMsgItem
|
class RsGxsCircleMsgItem : public RsGxsMsgItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -76,6 +77,7 @@ public:
|
|||||||
|
|
||||||
RsGxsCircleMsg mMsg;
|
RsGxsCircleMsg mMsg;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem
|
class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem
|
||||||
{
|
{
|
||||||
@ -86,17 +88,11 @@ public:
|
|||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
enum {
|
|
||||||
SUBSCRIPTION_REQUEST_UNKNOWN = 0x00,
|
|
||||||
SUBSCRIPTION_REQUEST_SUBSCRIBE = 0x01,
|
|
||||||
SUBSCRIPTION_REQUEST_UNSUBSCRIBE = 0x02
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
|
||||||
|
|
||||||
uint32_t time_stamp ;
|
uint32_t time_stamp ;
|
||||||
uint32_t time_out ;
|
uint32_t time_out ;
|
||||||
uint8_t subscription_type ;
|
RsGxsCircleSubscriptionType subscription_type ;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGxsCircleSerialiser : public RsServiceSerializer
|
class RsGxsCircleSerialiser : public RsServiceSerializer
|
||||||
|
@ -92,11 +92,15 @@ template<class ID_CLASS,uint32_t TLV_TYPE> class RS_DEPRECATED_FOR(std::set<>) t
|
|||||||
ids.insert(id) ;
|
ids.insert(id) ;
|
||||||
}
|
}
|
||||||
if(*offset != tlvend)
|
if(*offset != tlvend)
|
||||||
|
{
|
||||||
std::cerr << "(EE) deserialisaiton error in " << __PRETTY_FUNCTION__ << std::endl;
|
std::cerr << "(EE) deserialisaiton error in " << __PRETTY_FUNCTION__ << std::endl;
|
||||||
else if(!ok)
|
ok = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ok)
|
||||||
std::cerr << "(WW) something wrong in ID_CLASS.deserialise in " << __PRETTY_FUNCTION__ << std::endl;
|
std::cerr << "(WW) something wrong in ID_CLASS.deserialise in " << __PRETTY_FUNCTION__ << std::endl;
|
||||||
|
|
||||||
return *offset == tlvend ;
|
return ok;
|
||||||
}
|
}
|
||||||
virtual std::ostream &print(std::ostream &out, uint16_t /* indent */) const
|
virtual std::ostream &print(std::ostream &out, uint16_t /* indent */) const
|
||||||
{
|
{
|
||||||
|
@ -503,8 +503,16 @@ bool RsTypeSerializer::from_JSON( const std::string& /*memberName*/,
|
|||||||
// Binary blocks //
|
// Binary blocks //
|
||||||
//============================================================================//
|
//============================================================================//
|
||||||
|
|
||||||
|
#if __cplusplus < 201703L
|
||||||
|
/* Solve weird undefined reference error with C++ < 17 see:
|
||||||
|
* https://stackoverflow.com/questions/8016780/undefined-reference-to-static-constexpr-char
|
||||||
|
*/
|
||||||
|
/*static*/ decltype(RsTypeSerializer::RawMemoryWrapper::base64_key) constexpr
|
||||||
|
RsTypeSerializer::RawMemoryWrapper::base64_key;
|
||||||
|
|
||||||
/*static*/ /* without this Android compilation breaks */
|
/*static*/ /* without this Android compilation breaks */
|
||||||
constexpr uint32_t RsTypeSerializer::RawMemoryWrapper::MAX_SERIALIZED_CHUNK_SIZE;
|
constexpr uint32_t RsTypeSerializer::RawMemoryWrapper::MAX_SERIALIZED_CHUNK_SIZE;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*static*/
|
/*static*/
|
||||||
void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
||||||
@ -542,18 +550,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
ctx.mOffset += second;
|
ctx.mOffset += second;
|
||||||
break;
|
break;
|
||||||
case RsGenericSerializer::DESERIALIZE:
|
case RsGenericSerializer::DESERIALIZE:
|
||||||
if(first || second)
|
freshMemCheck();
|
||||||
{
|
|
||||||
/* Items are created anew before deserialization so buffer pointer
|
|
||||||
* must be null and size 0 at this point */
|
|
||||||
|
|
||||||
RsWarn() << __PRETTY_FUNCTION__ << " DESERIALIZE got uninitialized "
|
|
||||||
<< " or pre-allocated buffer! Buffer pointer: " << first
|
|
||||||
<< " must be null and size: " << second << " must be 0 at "
|
|
||||||
<< "this point. Does your item costructor initialize them "
|
|
||||||
<< "properly?" << std::endl;
|
|
||||||
print_stacktrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
RS_SERIAL_PROCESS(second);
|
RS_SERIAL_PROCESS(second);
|
||||||
if(!ctx.mOk) break;
|
if(!ctx.mOk) break;
|
||||||
@ -597,43 +594,33 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
if(!ctx.mOk) break;
|
if(!ctx.mOk) break;
|
||||||
std::string encodedValue;
|
std::string encodedValue;
|
||||||
RsBase64::encode(first, second, encodedValue, true, false);
|
RsBase64::encode(first, second, encodedValue, true, false);
|
||||||
ctx.mJson.SetString(
|
ctx.mOk = ctx.mOk &&
|
||||||
encodedValue.data(),
|
RsTypeSerializer::to_JSON(base64_key, encodedValue, ctx.mJson);
|
||||||
static_cast<rapidjson::SizeType>(encodedValue.length()) );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RsGenericSerializer::FROM_JSON:
|
case RsGenericSerializer::FROM_JSON:
|
||||||
{
|
{
|
||||||
const bool yelding = !!(
|
freshMemCheck();
|
||||||
RsSerializationFlags::YIELDING & ctx.mFlags );
|
|
||||||
if(!(ctx.mOk || yelding))
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(!ctx.mJson.IsString())
|
|
||||||
{
|
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " "
|
|
||||||
<< std::errc::invalid_argument << std::endl;
|
|
||||||
print_stacktrace();
|
|
||||||
|
|
||||||
ctx.mOk = false;
|
const auto failure = [&]() -> void { ctx.mOk = false; clear(); };
|
||||||
clear();
|
const bool yielding = !!(
|
||||||
break;
|
RsSerializationFlags::YIELDING & ctx.mFlags );
|
||||||
}
|
if(!(ctx.mOk || yielding)) return failure();
|
||||||
if( ctx.mJson.GetStringLength() >
|
|
||||||
|
std::string encodedValue;
|
||||||
|
if(!RsTypeSerializer::from_JSON(
|
||||||
|
base64_key, encodedValue, ctx.mJson )) return failure();
|
||||||
|
|
||||||
|
if( encodedValue.length() >
|
||||||
RsBase64::encodedSize(MAX_SERIALIZED_CHUNK_SIZE, true) )
|
RsBase64::encodedSize(MAX_SERIALIZED_CHUNK_SIZE, true) )
|
||||||
{
|
{
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " "
|
RsErr() << __PRETTY_FUNCTION__ << " "
|
||||||
<< std::errc::message_size << std::endl;
|
<< std::errc::message_size << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
|
||||||
ctx.mOk = false;
|
return failure();
|
||||||
clear();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string encodedValue = ctx.mJson.GetString();
|
|
||||||
std::vector<uint8_t> decoded;
|
std::vector<uint8_t> decoded;
|
||||||
auto ec = RsBase64::decode(encodedValue, decoded);
|
auto ec = RsBase64::decode(encodedValue, decoded);
|
||||||
if(ec)
|
if(ec)
|
||||||
@ -641,9 +628,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
RsErr() << __PRETTY_FUNCTION__ << " " << ec << std::endl;
|
RsErr() << __PRETTY_FUNCTION__ << " " << ec << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
|
||||||
ctx.mOk = false;
|
return failure();
|
||||||
clear();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto decodedSize = decoded.size();
|
const auto decodedSize = decoded.size();
|
||||||
@ -654,11 +639,8 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(decodedSize != second)
|
first = reinterpret_cast<uint8_t*>(malloc(decodedSize));
|
||||||
{
|
|
||||||
first = reinterpret_cast<uint8_t*>(realloc(first, decodedSize));
|
|
||||||
second = static_cast<uint32_t>(decodedSize);
|
second = static_cast<uint32_t>(decodedSize);
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(first, decoded.data(), second);
|
memcpy(first, decoded.data(), second);
|
||||||
break;
|
break;
|
||||||
@ -674,6 +656,24 @@ void RsTypeSerializer::RawMemoryWrapper::clear()
|
|||||||
second = 0;
|
second = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RsTypeSerializer::RawMemoryWrapper::freshMemCheck()
|
||||||
|
{
|
||||||
|
if(first || second)
|
||||||
|
{
|
||||||
|
/* Items are created anew before deserialization so buffer pointer
|
||||||
|
* must be null and size 0 at this point */
|
||||||
|
|
||||||
|
RsWarn() << __PRETTY_FUNCTION__ << " got uninitialized "
|
||||||
|
<< " or pre-allocated buffer! Buffer pointer: " << first
|
||||||
|
<< " must be null and size: " << second << " must be 0 at "
|
||||||
|
<< "this point. Does your item costructor initialize them "
|
||||||
|
<< "properly?" << std::endl;
|
||||||
|
print_stacktrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//============================================================================//
|
//============================================================================//
|
||||||
// std::error_condition //
|
// std::error_condition //
|
||||||
//============================================================================//
|
//============================================================================//
|
||||||
|
@ -59,12 +59,17 @@ struct RsTypeSerializer
|
|||||||
/// Maximum supported size 10MB
|
/// Maximum supported size 10MB
|
||||||
static constexpr uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024;
|
static constexpr uint32_t MAX_SERIALIZED_CHUNK_SIZE = 10*1024*1024;
|
||||||
|
|
||||||
|
/** Key used for JSON serialization.
|
||||||
|
* @note Changing this value breaks JSON API retro-compatibility */
|
||||||
|
static constexpr char base64_key[] = "base64";
|
||||||
|
|
||||||
/// @see RsSerializable
|
/// @see RsSerializable
|
||||||
void serial_process(
|
void serial_process(
|
||||||
RsGenericSerializer::SerializeJob j,
|
RsGenericSerializer::SerializeJob j,
|
||||||
RsGenericSerializer::SerializeContext& ctx ) override;
|
RsGenericSerializer::SerializeContext& ctx ) override;
|
||||||
private:
|
private:
|
||||||
void clear();
|
void clear();
|
||||||
|
bool freshMemCheck();
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Most types are not valid sequence containers
|
/// Most types are not valid sequence containers
|
||||||
@ -777,7 +782,7 @@ struct RsTypeSerializer
|
|||||||
{
|
{
|
||||||
if(!yielding)
|
if(!yielding)
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
|
RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName
|
||||||
<< "\" not found in JSON:" << std::endl
|
<< "\" not found in JSON:" << std::endl
|
||||||
<< jDoc << std::endl << std::endl;
|
<< jDoc << std::endl << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
@ -790,7 +795,7 @@ struct RsTypeSerializer
|
|||||||
|
|
||||||
if(!v.IsObject())
|
if(!v.IsObject())
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " \"" << memberName
|
RsErr() << __PRETTY_FUNCTION__ << " \"" << memberName
|
||||||
<< "\" has wrong type in JSON, object expected, got:"
|
<< "\" has wrong type in JSON, object expected, got:"
|
||||||
<< std::endl << jDoc << std::endl << std::endl;
|
<< std::endl << jDoc << std::endl << std::endl;
|
||||||
print_stacktrace();
|
print_stacktrace();
|
||||||
|
@ -239,7 +239,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* iterate through and grab any new messages */
|
/* iterate through and grab any new messages */
|
||||||
std::list<RsGxsGroupId> unprocessedGroups;
|
std::set<RsGxsGroupId> unprocessedGroups;
|
||||||
|
|
||||||
std::vector<RsGxsNotify *>::iterator it;
|
std::vector<RsGxsNotify *>::iterator it;
|
||||||
for(it = changes.begin(); it != changes.end(); ++it)
|
for(it = changes.begin(); it != changes.end(); ++it)
|
||||||
@ -252,19 +252,15 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
{
|
{
|
||||||
/* message received */
|
/* message received */
|
||||||
if (rsEvents)
|
if (rsEvents)
|
||||||
{
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
|
||||||
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
|
||||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||||
ev->mChannelMsgId = *mit1;
|
|
||||||
ev->mChannelGroupId = mit->first;
|
ev->mChannelMsgId = msgChange->mMsgId;
|
||||||
|
ev->mChannelGroupId = msgChange->mGroupId;
|
||||||
ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE;
|
ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!msgChange->metaChange())
|
if (!msgChange->metaChange())
|
||||||
{
|
{
|
||||||
@ -273,25 +269,21 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
|
||||||
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
|
||||||
{
|
|
||||||
#ifdef GXSCHANNELS_DEBUG
|
#ifdef GXSCHANNELS_DEBUG
|
||||||
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
|
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
bool enabled = false;
|
|
||||||
if (autoDownloadEnabled(mit->first, enabled) && enabled)
|
|
||||||
{
|
{
|
||||||
#ifdef GXSCHANNELS_DEBUG
|
#ifdef GXSCHANNELS_DEBUG
|
||||||
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
|
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* problem is most of these will be comments and votes,
|
/* problem is most of these will be comments and votes, should make it occasional - every 5mins / 10minutes TODO */
|
||||||
* should make it occasional - every 5mins / 10minutes TODO */
|
// We do not call if(autoDownLoadEnabled()) here, because it would be too costly when
|
||||||
unprocessedGroups.push_back(mit->first);
|
// many msgs are received from the same group. We back the groupIds and then request one by one.
|
||||||
}
|
|
||||||
|
unprocessedGroups.insert(msgChange->mGroupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,73 +295,54 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
switch (grpChange->getType())
|
switch (grpChange->getType())
|
||||||
{
|
{
|
||||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||||
{
|
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||||
ev->mChannelGroupId = *git;
|
ev->mChannelGroupId = grpChange->mGroupId;
|
||||||
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
|
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||||
{
|
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||||
ev->mChannelGroupId = *git;
|
ev->mChannelGroupId = grpChange->mGroupId;
|
||||||
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
|
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_PUBLISHED:
|
case RsGxsNotify::TYPE_PUBLISHED:
|
||||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||||
{
|
{
|
||||||
/* group received */
|
/* group received */
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
RS_STACK_MUTEX(mKnownChannelsMutex);
|
RS_STACK_MUTEX(mKnownChannelsMutex);
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
|
if(mKnownChannels.find(grpChange->mGroupId) == mKnownChannels.end())
|
||||||
{
|
{
|
||||||
if(mKnownChannels.find(*git) == mKnownChannels.end())
|
mKnownChannels.insert(std::make_pair(grpChange->mGroupId,time(NULL))) ;
|
||||||
{
|
|
||||||
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
|
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
|
|
||||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||||
ev->mChannelGroupId = *git;
|
ev->mChannelGroupId = grpChange->mGroupId;
|
||||||
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
|
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
|
std::cerr << "(II) Not notifying already known channel " << grpChange->mGroupId << std::endl;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
|
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
|
||||||
{
|
{
|
||||||
/* group received */
|
/* group received */
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
|
||||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
auto ev = std::make_shared<RsGxsChannelEvent>();
|
||||||
ev->mChannelGroupId = *git;
|
ev->mChannelGroupId = grpChange->mGroupId;
|
||||||
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
|
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
|
||||||
|
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -395,8 +368,16 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
delete *it;
|
delete *it;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!unprocessedGroups.empty())
|
std::list<RsGxsGroupId> grps;
|
||||||
request_SpecificSubscribedGroups(unprocessedGroups);
|
for(auto& grp_id:unprocessedGroups)
|
||||||
|
{
|
||||||
|
bool enabled = false;
|
||||||
|
if (autoDownloadEnabled(grp_id, enabled) && enabled) // costly call, that's why it's packed down here.
|
||||||
|
grps.push_back(grp_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!grps.empty())
|
||||||
|
request_SpecificSubscribedGroups(grps);
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3GxsChannels::service_tick()
|
void p3GxsChannels::service_tick()
|
||||||
@ -471,16 +452,17 @@ bool p3GxsChannels::groupShareKeys(
|
|||||||
|
|
||||||
bool p3GxsChannels::getPostData(
|
bool p3GxsChannels::getPostData(
|
||||||
const uint32_t &token, std::vector<RsGxsChannelPost> &msgs,
|
const uint32_t &token, std::vector<RsGxsChannelPost> &msgs,
|
||||||
std::vector<RsGxsComment> &cmts )
|
std::vector<RsGxsComment> &cmts,
|
||||||
|
std::vector<RsGxsVote> &vots)
|
||||||
{
|
{
|
||||||
#ifdef GXSCHANNELS_DEBUG
|
#ifdef GXSCHANNELS_DEBUG
|
||||||
std::cerr << __PRETTY_FUNCTION__ << std::cerr << std::endl;
|
RsDbg() << __PRETTY_FUNCTION__ << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GxsMsgDataMap msgData;
|
GxsMsgDataMap msgData;
|
||||||
if(!RsGenExchange::getMsgData(token, msgData))
|
if(!RsGenExchange::getMsgData(token, msgData))
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ <<" ERROR in request" << std::endl;
|
RsErr() << __PRETTY_FUNCTION__ << " ERROR in request" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,39 +496,62 @@ bool p3GxsChannels::getPostData(
|
|||||||
cmt = cmtItem->mMsg;
|
cmt = cmtItem->mMsg;
|
||||||
cmt.mMeta = mi->meta;
|
cmt.mMeta = mi->meta;
|
||||||
#ifdef GXSCOMMENT_DEBUG
|
#ifdef GXSCOMMENT_DEBUG
|
||||||
std::cerr << "p3GxsChannels::getPostData Found Comment:" << std::endl;
|
RsDbg() << __PRETTY_FUNCTION__ << " Found Comment:" << std::endl;
|
||||||
cmt.print(std::cerr," ", "cmt");
|
cmt.print(std::cerr," ", "cmt");
|
||||||
#endif
|
#endif
|
||||||
cmts.push_back(cmt);
|
cmts.push_back(cmt);
|
||||||
delete cmtItem;
|
delete cmtItem;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
RsGxsVoteItem* votItem =
|
||||||
|
dynamic_cast<RsGxsVoteItem*>(*vit);
|
||||||
|
if(votItem)
|
||||||
|
{
|
||||||
|
RsGxsVote vot;
|
||||||
|
RsGxsMsgItem *mi = (*vit);
|
||||||
|
vot = votItem->mMsg;
|
||||||
|
vot.mMeta = mi->meta;
|
||||||
|
vots.push_back(vot);
|
||||||
|
delete votItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RsGxsMsgItem* msg = (*vit);
|
RsGxsMsgItem* msg = (*vit);
|
||||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||||
std::cerr << __PRETTY_FUNCTION__
|
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2;
|
||||||
|
RsErr() << __PRETTY_FUNCTION__
|
||||||
<< " Not a GxsChannelPostItem neither a "
|
<< " Not a GxsChannelPostItem neither a "
|
||||||
<< "RsGxsCommentItem PacketService=" << std::hex
|
<< "RsGxsCommentItem neither a RsGxsVoteItem"
|
||||||
<< (int)msg->PacketService() << std::dec
|
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
||||||
<< " PacketSubType=" << std::hex
|
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
||||||
<< (int)msg->PacketSubType() << std::dec
|
<< " type name =" << typeid(*msg).name()
|
||||||
<< " , deleting!" << std::endl;
|
<< " , deleting!" << std::endl;
|
||||||
delete *vit;
|
delete *vit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3GxsChannels::getPostData(
|
||||||
|
const uint32_t& token, std::vector<RsGxsChannelPost>& posts, std::vector<RsGxsComment>& cmts )
|
||||||
|
{
|
||||||
|
std::vector<RsGxsVote> vots;
|
||||||
|
return getPostData(token, posts, cmts, vots);
|
||||||
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::getPostData(
|
bool p3GxsChannels::getPostData(
|
||||||
const uint32_t& token, std::vector<RsGxsChannelPost>& posts )
|
const uint32_t& token, std::vector<RsGxsChannelPost>& posts )
|
||||||
{
|
{
|
||||||
std::vector<RsGxsComment> cmts;
|
std::vector<RsGxsComment> cmts;
|
||||||
return getPostData(token, posts, cmts);
|
std::vector<RsGxsVote> vots;
|
||||||
|
return getPostData(token, posts, cmts, vots);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Not currently used
|
//Not currently used
|
||||||
@ -724,8 +729,7 @@ void p3GxsChannels::request_AllSubscribedGroups()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void p3GxsChannels::request_SpecificSubscribedGroups(
|
void p3GxsChannels::request_SpecificSubscribedGroups( const std::list<RsGxsGroupId> &groups )
|
||||||
const std::list<RsGxsGroupId> &groups )
|
|
||||||
{
|
{
|
||||||
#ifdef GXSCHANNELS_DEBUG
|
#ifdef GXSCHANNELS_DEBUG
|
||||||
std::cerr << "p3GxsChannels::request_SpecificSubscribedGroups()";
|
std::cerr << "p3GxsChannels::request_SpecificSubscribedGroups()";
|
||||||
@ -738,8 +742,7 @@ void p3GxsChannels::request_SpecificSubscribedGroups(
|
|||||||
|
|
||||||
uint32_t token = 0;
|
uint32_t token = 0;
|
||||||
|
|
||||||
if(!RsGenExchange::getTokenService()->
|
if(!RsGenExchange::getTokenService()-> requestGroupInfo(token, ansType, opts, groups))
|
||||||
requestGroupInfo(token, ansType, opts, groups))
|
|
||||||
{
|
{
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " Failed requesting groups info!"
|
std::cerr << __PRETTY_FUNCTION__ << " Failed requesting groups info!"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@ -1112,7 +1115,8 @@ bool p3GxsChannels::getContentSummaries(
|
|||||||
|
|
||||||
bool p3GxsChannels::getChannelAllContent( const RsGxsGroupId& channelId,
|
bool p3GxsChannels::getChannelAllContent( const RsGxsGroupId& channelId,
|
||||||
std::vector<RsGxsChannelPost>& posts,
|
std::vector<RsGxsChannelPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments )
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes )
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
@ -1121,13 +1125,14 @@ bool p3GxsChannels::getChannelAllContent( const RsGxsGroupId& channelId,
|
|||||||
if( !requestMsgInfo(token, opts,std::list<RsGxsGroupId>({channelId})) || waitToken(token) != RsTokenService::COMPLETE )
|
if( !requestMsgInfo(token, opts,std::list<RsGxsGroupId>({channelId})) || waitToken(token) != RsTokenService::COMPLETE )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return getPostData(token, posts, comments);
|
return getPostData(token, posts, comments,votes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
||||||
const std::set<RsGxsMessageId>& contentIds,
|
const std::set<RsGxsMessageId>& contentIds,
|
||||||
std::vector<RsGxsChannelPost>& posts,
|
std::vector<RsGxsChannelPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments )
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes )
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
@ -1139,7 +1144,7 @@ bool p3GxsChannels::getChannelContent( const RsGxsGroupId& channelId,
|
|||||||
if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE )
|
if( !requestMsgInfo(token, opts, msgIds) || waitToken(token) != RsTokenService::COMPLETE )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return getPostData(token, posts, comments);
|
return getPostData(token, posts, comments, votes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsChannels::getChannelComments(const RsGxsGroupId &channelId,
|
bool p3GxsChannels::getChannelComments(const RsGxsGroupId &channelId,
|
||||||
@ -1314,8 +1319,9 @@ bool p3GxsChannels::createVoteV2(
|
|||||||
std::set<RsGxsMessageId> s({commentId});
|
std::set<RsGxsMessageId> s({commentId});
|
||||||
std::vector<RsGxsChannelPost> posts;
|
std::vector<RsGxsChannelPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
if(!getChannelContent(channelId, s, posts, comments))
|
if(!getChannelContent(channelId, s, posts, comments, votes))
|
||||||
{
|
{
|
||||||
errorMessage = "You cannot vote on comment "
|
errorMessage = "You cannot vote on comment "
|
||||||
+ commentId.toStdString() + " of channel with Id "
|
+ commentId.toStdString() + " of channel with Id "
|
||||||
@ -1475,8 +1481,9 @@ bool p3GxsChannels::createPostV2(
|
|||||||
std::set<RsGxsMessageId> s({origPostId});
|
std::set<RsGxsMessageId> s({origPostId});
|
||||||
std::vector<RsGxsChannelPost> posts;
|
std::vector<RsGxsChannelPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
if(!getChannelContent(channelId,s,posts,comments))
|
if(!getChannelContent(channelId,s,posts,comments,votes))
|
||||||
{
|
{
|
||||||
errorMessage = "You cannot edit post " + origPostId.toStdString()
|
errorMessage = "You cannot edit post " + origPostId.toStdString()
|
||||||
+ " of channel with Id " + channelId.toStdString()
|
+ " of channel with Id " + channelId.toStdString()
|
||||||
@ -1546,9 +1553,11 @@ bool p3GxsChannels::createCommentV2(
|
|||||||
|
|
||||||
std::vector<RsGxsChannelPost> posts;
|
std::vector<RsGxsChannelPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
if(!getChannelContent( // does the post thread exist?
|
if(!getChannelContent( // does the post thread exist?
|
||||||
channelId,std::set<RsGxsMessageId>({threadId}), posts, comments ))
|
channelId, std::set<RsGxsMessageId>({threadId}),
|
||||||
|
posts, comments, votes) )
|
||||||
return failure( "You cannot comment post " + threadId.toStdString() +
|
return failure( "You cannot comment post " + threadId.toStdString() +
|
||||||
" of channel with Id " + channelId.toStdString() +
|
" of channel with Id " + channelId.toStdString() +
|
||||||
": this post does not exists locally!" );
|
": this post does not exists locally!" );
|
||||||
@ -1560,19 +1569,18 @@ bool p3GxsChannels::createCommentV2(
|
|||||||
": supplied threadId is not a thread, or parentMsgId is"
|
": supplied threadId is not a thread, or parentMsgId is"
|
||||||
" not a comment!");
|
" not a comment!");
|
||||||
|
|
||||||
if(!getChannelContent( // does the post thread exist?
|
if(!getChannelContent( // does the post parent exist?
|
||||||
channelId, std::set<RsGxsMessageId>({parentId}),
|
channelId, std::set<RsGxsMessageId>({parentId}),
|
||||||
posts, comments ))
|
posts, comments, votes) )
|
||||||
return failure( "You cannot comment post " + parentId.toStdString() +
|
return failure( "You cannot comment post " + parentId.toStdString() +
|
||||||
": supplied parent doesn't exists locally!" );
|
": supplied parent doesn't exists locally!" );
|
||||||
|
|
||||||
if(!origCommentId.isNull())
|
if(!origCommentId.isNull())
|
||||||
{
|
{
|
||||||
std::set<RsGxsMessageId> s({origCommentId});
|
std::set<RsGxsMessageId> s({origCommentId});
|
||||||
std::vector<RsGxsChannelPost> posts;
|
std::vector<RsGxsComment> cmts;
|
||||||
std::vector<RsGxsComment> comments;
|
|
||||||
|
|
||||||
if( !getChannelContent(channelId, s, posts, comments) ||
|
if( !getChannelContent(channelId, s, posts, cmts, votes) ||
|
||||||
comments.size() != 1 )
|
comments.size() != 1 )
|
||||||
return failure( "You cannot edit comment " +
|
return failure( "You cannot edit comment " +
|
||||||
origCommentId.toStdString() +
|
origCommentId.toStdString() +
|
||||||
|
@ -82,9 +82,10 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups);
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsGxsChannelGroup> &groups ) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts);
|
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &vots) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts, std::vector<RsGxsComment> &cmts) override;
|
||||||
|
virtual bool getPostData(const uint32_t &token, std::vector<RsGxsChannelPost> &posts) override;
|
||||||
//Not currently used
|
//Not currently used
|
||||||
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsGxsChannelPost> &posts);
|
||||||
|
|
||||||
@ -188,13 +189,15 @@ virtual bool ExtraFileRemove(const RsFileHash &hash);
|
|||||||
/// Implementation of @see RsGxsChannels::getChannelAllMessages
|
/// Implementation of @see RsGxsChannels::getChannelAllMessages
|
||||||
bool getChannelAllContent(const RsGxsGroupId& channelId,
|
bool getChannelAllContent(const RsGxsGroupId& channelId,
|
||||||
std::vector<RsGxsChannelPost>& posts,
|
std::vector<RsGxsChannelPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) override;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::getChannelMessages
|
/// Implementation of @see RsGxsChannels::getChannelMessages
|
||||||
bool getChannelContent(const RsGxsGroupId& channelId,
|
bool getChannelContent(const RsGxsGroupId& channelId,
|
||||||
const std::set<RsGxsMessageId>& contentIds,
|
const std::set<RsGxsMessageId>& contentIds,
|
||||||
std::vector<RsGxsChannelPost>& posts,
|
std::vector<RsGxsChannelPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) override;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) override;
|
||||||
|
|
||||||
/// Implementation of @see RsGxsChannels::getChannelComments
|
/// Implementation of @see RsGxsChannels::getChannelComments
|
||||||
virtual bool getChannelComments(const RsGxsGroupId &channelId,
|
virtual bool getChannelComments(const RsGxsGroupId &channelId,
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -128,11 +128,20 @@ public:
|
|||||||
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
|
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CircleEntryCacheStatus: uint8_t {
|
||||||
|
UNKNOWN = 0x00, // Used to detect uninitialized memory
|
||||||
|
NO_DATA_YET = 0x01, // Used in the constuctor
|
||||||
|
LOADING = 0x02, // When the token request to load cache has been sent and no data is present
|
||||||
|
UPDATING = 0x03, // Starting from this level the cache entry can be used
|
||||||
|
CHECKING_MEMBERSHIP = 0x04, // Means we're actually looking into msgs to update membership status
|
||||||
|
UP_TO_DATE = 0x05 // Everything should be loaded here.
|
||||||
|
};
|
||||||
|
|
||||||
class RsGxsCircleCache
|
class RsGxsCircleCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
RsGxsCircleCache();
|
RsGxsCircleCache();
|
||||||
|
|
||||||
bool loadBaseCircle(const RsGxsCircleGroup &circle);
|
bool loadBaseCircle(const RsGxsCircleGroup &circle);
|
||||||
bool loadSubCircle(const RsGxsCircleCache &subcircle);
|
bool loadSubCircle(const RsGxsCircleCache &subcircle);
|
||||||
|
|
||||||
@ -142,23 +151,30 @@ class RsGxsCircleCache
|
|||||||
bool addAllowedPeer(const RsPgpId &pgpid);
|
bool addAllowedPeer(const RsPgpId &pgpid);
|
||||||
bool addLocalFriend(const RsPgpId &pgpid);
|
bool addLocalFriend(const RsPgpId &pgpid);
|
||||||
|
|
||||||
|
// Cache related data
|
||||||
|
|
||||||
|
rstime_t mLastUpdatedMembershipTS ; // Last time the subscribe messages have been requested. Should be reset when new messages arrive.
|
||||||
|
rstime_t mLastUpdateTime; // Last time the cache entry was loaded
|
||||||
|
CircleEntryCacheStatus mStatus; // Overall state of the cache entry
|
||||||
|
bool mAllIdsHere ; // True when all ids are knwon and available.
|
||||||
|
|
||||||
|
// GxsCircle related data
|
||||||
|
|
||||||
RsGxsCircleId mCircleId;
|
RsGxsCircleId mCircleId;
|
||||||
std::string mCircleName;
|
std::string mCircleName;
|
||||||
|
|
||||||
uint32_t mCircleType;
|
RsGxsCircleType mCircleType;
|
||||||
bool mIsExternal;
|
bool mIsExternal;
|
||||||
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
|
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
|
||||||
|
|
||||||
uint32_t mGroupStatus;
|
uint32_t mGroupStatus;
|
||||||
uint32_t mGroupSubscribeFlags;
|
uint32_t mGroupSubscribeFlags;
|
||||||
|
|
||||||
rstime_t mUpdateTime;
|
|
||||||
#ifdef SUBSCIRCLES
|
#ifdef SUBSCIRCLES
|
||||||
std::set<RsGxsCircleId> mUnprocessedCircles;
|
std::set<RsGxsCircleId> mUnprocessedCircles;
|
||||||
std::set<RsGxsCircleId> mProcessedCircles;
|
std::set<RsGxsCircleId> mProcessedCircles;
|
||||||
#endif
|
#endif
|
||||||
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus;
|
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus;
|
||||||
rstime_t mLastUpdatedMembershipTS ; // last time the subscribe messages have been requested. Should be reset when new messages arrive.
|
|
||||||
|
|
||||||
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
|
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
|
||||||
std::set<RsPgpId> mAllowedNodes;
|
std::set<RsPgpId> mAllowedNodes;
|
||||||
@ -169,6 +185,28 @@ class RsGxsCircleCache
|
|||||||
|
|
||||||
class PgpAuxUtils;
|
class PgpAuxUtils;
|
||||||
|
|
||||||
|
class RsCirclesMemCache : public std::map<RsGxsCircleId,RsGxsCircleCache>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsCirclesMemCache() : std::map<RsGxsCircleId,RsGxsCircleCache>(){}
|
||||||
|
|
||||||
|
bool is_cached(const RsGxsCircleId& id) { return end() != find(id) ; }
|
||||||
|
RsGxsCircleCache& ref(const RsGxsCircleId& id) { return operator[](id) ; }
|
||||||
|
|
||||||
|
void printStats() { std::cerr << "CircleMemCache: " << size() << " elements." << std::endl; }
|
||||||
|
|
||||||
|
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(RsGxsCircleCache&))
|
||||||
|
{
|
||||||
|
for(auto& it:*this)
|
||||||
|
(c.*method)(it.second);
|
||||||
|
}
|
||||||
|
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(const RsGxsCircleCache&))
|
||||||
|
{
|
||||||
|
for(const auto& it:*this)
|
||||||
|
(c.*method)(it.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
|
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
|
||||||
public GxsTokenQueue, public RsTickEvent
|
public GxsTokenQueue, public RsTickEvent
|
||||||
{
|
{
|
||||||
@ -264,7 +302,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id,uint32_t request_type) ;
|
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ;
|
||||||
static uint32_t circleAuthenPolicy();
|
static uint32_t circleAuthenPolicy();
|
||||||
|
|
||||||
/** Notifications **/
|
/** Notifications **/
|
||||||
@ -319,20 +357,18 @@ public:
|
|||||||
std::list<RsGxsCircleId> mCirclePersonalIdList;
|
std::list<RsGxsCircleId> mCirclePersonalIdList;
|
||||||
|
|
||||||
/***** Caching Circle Info, *****/
|
/***** Caching Circle Info, *****/
|
||||||
// initial load queue
|
|
||||||
std::list<RsGxsCircleId> mCacheLoad_ToCache;
|
|
||||||
|
|
||||||
// waiting for subcircle to load. (first is part of each of the second list)
|
// waiting for subcircle to load. (first is part of each of the second list)
|
||||||
// TODO.
|
// TODO.
|
||||||
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
|
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
|
||||||
|
|
||||||
// Circles that are being loaded.
|
std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups.
|
||||||
std::map<RsGxsCircleId, RsGxsCircleCache> mLoadingCache;
|
RsCirclesMemCache mCircleCache;
|
||||||
|
//RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data
|
||||||
|
|
||||||
// actual cache.
|
void debug_dumpCache(); // debug method to overview what's going on
|
||||||
RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache;
|
bool debug_dumpCacheEntry(RsGxsCircleCache &cache);
|
||||||
|
private:
|
||||||
private:
|
|
||||||
|
|
||||||
std::string genRandomId();
|
std::string genRandomId();
|
||||||
|
|
||||||
@ -345,8 +381,9 @@ public:
|
|||||||
uint32_t mDummyIdToken;
|
uint32_t mDummyIdToken;
|
||||||
std::list<RsGxsId> mDummyPgpLinkedIds;
|
std::list<RsGxsId> mDummyPgpLinkedIds;
|
||||||
std::list<RsGxsId> mDummyOwnIds;
|
std::list<RsGxsId> mDummyOwnIds;
|
||||||
bool mCacheUpdated ;
|
bool mShouldSendCacheUpdateNotification ;
|
||||||
rstime_t mLastCacheUpdateEvent;
|
rstime_t mLastCacheUpdateEvent;
|
||||||
|
rstime_t mLastDebugPrintTS;
|
||||||
|
|
||||||
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
RS_SET_CONTEXT_DEBUG_LEVEL(2)
|
||||||
};
|
};
|
||||||
|
@ -189,22 +189,18 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
for(it = changes.begin(); it != changes.end(); ++it)
|
for(it = changes.begin(); it != changes.end(); ++it)
|
||||||
{
|
{
|
||||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
|
||||||
|
|
||||||
if (msgChange)
|
if (msgChange)
|
||||||
{
|
{
|
||||||
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */
|
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */
|
||||||
if (rsEvents)
|
if (rsEvents)
|
||||||
{
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& msgChangeMap = msgChange->msgChangeMap;
|
|
||||||
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
|
||||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||||
ev->mForumMsgId = *mit1;
|
ev->mForumMsgId = msgChange->mMsgId;
|
||||||
ev->mForumGroupId = mit->first;
|
ev->mForumGroupId = msgChange->mGroupId;
|
||||||
ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE;
|
ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOT_USED_YET
|
#ifdef NOT_USED_YET
|
||||||
if (!msgChange->metaChange())
|
if (!msgChange->metaChange())
|
||||||
@ -247,85 +243,91 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
switch (grpChange->getType())
|
switch (grpChange->getType())
|
||||||
{
|
{
|
||||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||||
{
|
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||||
ev->mForumGroupId = *git;
|
ev->mForumGroupId = grpChange->mGroupId;
|
||||||
ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED;
|
ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_PUBLISHED:
|
case RsGxsNotify::TYPE_PUBLISHED:
|
||||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||||
{
|
{
|
||||||
/* group received */
|
/* group received */
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
|
|
||||||
RS_STACK_MUTEX(mKnownForumsMutex);
|
RS_STACK_MUTEX(mKnownForumsMutex);
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
|
if(mKnownForums.find(grpChange->mGroupId) == mKnownForums.end())
|
||||||
{
|
{
|
||||||
if(mKnownForums.find(*git) == mKnownForums.end())
|
mKnownForums.insert( std::make_pair(grpChange->mGroupId, time(nullptr)));
|
||||||
{
|
|
||||||
mKnownForums.insert(
|
|
||||||
std::make_pair(*git, time(nullptr)));
|
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
|
|
||||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||||
ev->mForumGroupId = *git;
|
ev->mForumGroupId = grpChange->mGroupId;
|
||||||
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
|
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RsInfo() << __PRETTY_FUNCTION__
|
RsInfo() << __PRETTY_FUNCTION__
|
||||||
<< " Not notifying already known forum "
|
<< " Not notifying already known forum "
|
||||||
<< *git << std::endl;
|
<< grpChange->mGroupId << std::endl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||||
{
|
{
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
ev->mForumGroupId = grpChange->mGroupId;
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
|
||||||
|
rsEvents->postEvent(ev);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RsGxsNotify::TYPE_UPDATED:
|
||||||
|
{
|
||||||
|
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
|
||||||
|
|
||||||
|
RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mOldGroupItem);
|
||||||
|
RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mNewGroupItem);
|
||||||
|
|
||||||
|
if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr)
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl;
|
||||||
|
delete grpChange;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First of all, we check if there is a difference between the old and new list of moderators
|
||||||
|
|
||||||
|
std::list<RsGxsId> added_mods, removed_mods;
|
||||||
|
|
||||||
|
for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids)
|
||||||
|
if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end())
|
||||||
|
added_mods.push_back(gxs_id);
|
||||||
|
|
||||||
|
for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids)
|
||||||
|
if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end())
|
||||||
|
removed_mods.push_back(gxs_id);
|
||||||
|
|
||||||
|
if(!added_mods.empty() || !removed_mods.empty())
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsForumEvent>();
|
auto ev = std::make_shared<RsGxsForumEvent>();
|
||||||
ev->mForumGroupId = *git;
|
|
||||||
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
|
ev->mForumGroupId = new_forum_grp_item->meta.mGroupId;
|
||||||
|
ev->mModeratorsAdded = added_mods;
|
||||||
|
ev->mModeratorsRemoved = removed_mods;
|
||||||
|
ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED;
|
||||||
|
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
|
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
#ifdef NOT_USED_YET
|
|
||||||
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
|
|
||||||
{
|
|
||||||
/* group received */
|
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
|
||||||
auto ev = std::make_shared<RsGxsChannelEvent>();
|
|
||||||
|
|
||||||
ev->mChannelGroupId = *git;
|
|
||||||
ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY;
|
|
||||||
|
|
||||||
rsEvents->sendEvent(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,22 +606,7 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(changes[i]);
|
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(changes[i]);
|
||||||
|
|
||||||
if (msgChange && !msgChange->metaChange())
|
if (msgChange && !msgChange->metaChange())
|
||||||
{
|
RsWarn() << __PRETTY_FUNCTION__ << " Found a Msg data change in p3IdService. This is quite unexpected." << std::endl;
|
||||||
#ifdef DEBUG_IDS
|
|
||||||
std::cerr << "p3IdService::notifyChanges() Found Message Change Notification";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
|
||||||
|
|
||||||
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_IDS
|
|
||||||
std::cerr << "p3IdService::notifyChanges() Msgs for Group: " << mit->first;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(changes[i]);
|
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(changes[i]);
|
||||||
|
|
||||||
@ -631,16 +616,13 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
|
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
|
|
||||||
|
|
||||||
for(auto git = groupList.begin(); git != groupList.end();++git)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_IDS
|
#ifdef DEBUG_IDS
|
||||||
std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git;
|
std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
const RsGxsGroupId& gid(groupChange->mGroupId);
|
||||||
|
|
||||||
if(!rsReputations->isIdentityBanned(RsGxsId(*git)))
|
if(!rsReputations->isIdentityBanned(RsGxsId(gid)))
|
||||||
{
|
{
|
||||||
// notify that a new identity is received, if needed
|
// notify that a new identity is received, if needed
|
||||||
|
|
||||||
@ -654,12 +636,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
case RsGxsNotify::TYPE_PUBLISHED:
|
case RsGxsNotify::TYPE_PUBLISHED:
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsIdentityEvent>();
|
auto ev = std::make_shared<RsGxsIdentityEvent>();
|
||||||
ev->mIdentityId = *git;
|
ev->mIdentityId = gid;
|
||||||
ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY;
|
ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
|
|
||||||
// also time_stamp the key that this group represents
|
// also time_stamp the key that this group represents
|
||||||
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
||||||
should_subscribe = true;
|
should_subscribe = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -667,12 +649,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsIdentityEvent>();
|
auto ev = std::make_shared<RsGxsIdentityEvent>();
|
||||||
ev->mIdentityId = *git;
|
ev->mIdentityId = gid;
|
||||||
ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY;
|
ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
|
|
||||||
// also time_stamp the key that this group represents
|
// also time_stamp the key that this group represents
|
||||||
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
|
||||||
should_subscribe = true;
|
should_subscribe = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -684,12 +666,11 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
if(should_subscribe)
|
if(should_subscribe)
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
RsGenExchange::subscribeToGroup(token, *git, true);
|
RsGenExchange::subscribeToGroup(token, gid, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
delete changes[i];
|
delete changes[i];
|
||||||
}
|
}
|
||||||
|
@ -1192,6 +1192,10 @@ bool p3MsgService::MessageSend(MessageInfo &info)
|
|||||||
|
|
||||||
imsg[msg->msgId] = msg;
|
imsg[msg->msgId] = msg;
|
||||||
|
|
||||||
|
// Update info for caller
|
||||||
|
info.msgId = std::to_string(msg->msgId);
|
||||||
|
info .msgflags = msg->msgFlags;
|
||||||
|
|
||||||
RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD);
|
RsServer::notify()->notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,11 +117,7 @@ void p3PhotoService::groupsChanged(std::list<RsGxsGroupId>& grpIds)
|
|||||||
while(!mGroupChange.empty())
|
while(!mGroupChange.empty())
|
||||||
{
|
{
|
||||||
RsGxsGroupChange* gc = mGroupChange.back();
|
RsGxsGroupChange* gc = mGroupChange.back();
|
||||||
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
|
grpIds.push_back(gc->mGroupId);
|
||||||
std::list<RsGxsGroupId>::iterator lit = gList.begin();
|
|
||||||
for(; lit != gList.end(); ++lit) {
|
|
||||||
grpIds.push_back(*lit);
|
|
||||||
}
|
|
||||||
|
|
||||||
mGroupChange.pop_back();
|
mGroupChange.pop_back();
|
||||||
delete gc;
|
delete gc;
|
||||||
@ -136,7 +132,8 @@ void p3PhotoService::msgsChanged(GxsMsgIdResult& msgs)
|
|||||||
while(!mMsgChange.empty())
|
while(!mMsgChange.empty())
|
||||||
{
|
{
|
||||||
RsGxsMsgChange* mc = mMsgChange.back();
|
RsGxsMsgChange* mc = mMsgChange.back();
|
||||||
msgs = mc->msgChangeMap;
|
|
||||||
|
msgs[mc->mGroupId].insert(mc->mMsgId);
|
||||||
mMsgChange.pop_back();
|
mMsgChange.pop_back();
|
||||||
delete mc;
|
delete mc;
|
||||||
}
|
}
|
||||||
|
@ -98,9 +98,6 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
|
|
||||||
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
|
|
||||||
{
|
|
||||||
#ifdef POSTBASE_DEBUG
|
#ifdef POSTBASE_DEBUG
|
||||||
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
|
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -108,19 +105,17 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
// To start with we are just going to trigger updates on these groups.
|
// To start with we are just going to trigger updates on these groups.
|
||||||
// FUTURE OPTIMISATION.
|
// FUTURE OPTIMISATION.
|
||||||
// It could be taken a step further and directly request these msgs for an update.
|
// It could be taken a step further and directly request these msgs for an update.
|
||||||
addGroupForProcessing(mit->first);
|
addGroupForProcessing(msgChange->mGroupId);
|
||||||
|
|
||||||
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
|
||||||
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedMsgId = *mit1;
|
ev->mPostedMsgId = msgChange->mMsgId;
|
||||||
ev->mPostedGroupId = mit->first;
|
ev->mPostedGroupId = msgChange->mGroupId;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
|
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
RsGxsGroupChange *grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
RsGxsGroupChange *grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
|
||||||
|
|
||||||
@ -131,67 +126,52 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
|
|||||||
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
|
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
const RsGxsGroupId& group_id(grpChange->mGroupId);
|
||||||
|
|
||||||
switch(grpChange->getType())
|
switch(grpChange->getType())
|
||||||
{
|
{
|
||||||
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
|
||||||
{
|
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedGroupId = *git;
|
ev->mPostedGroupId = group_id;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
|
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
|
||||||
{
|
|
||||||
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
|
|
||||||
std::list<RsGxsGroupId>::iterator git;
|
|
||||||
|
|
||||||
for (git = grpList.begin(); git != grpList.end(); ++git)
|
|
||||||
{
|
{
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedGroupId = *git;
|
ev->mPostedGroupId = group_id;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
|
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsNotify::TYPE_PUBLISHED:
|
case RsGxsNotify::TYPE_PUBLISHED:
|
||||||
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
case RsGxsNotify::TYPE_RECEIVED_NEW:
|
||||||
{
|
{
|
||||||
/* group received */
|
/* group received */
|
||||||
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
|
|
||||||
|
|
||||||
for (auto git = grpList.begin(); git != grpList.end(); ++git)
|
if(mKnownPosted.find(group_id) == mKnownPosted.end())
|
||||||
{
|
{
|
||||||
if(mKnownPosted.find(*git) == mKnownPosted.end())
|
mKnownPosted.insert(std::make_pair(group_id, time(nullptr)));
|
||||||
{
|
|
||||||
mKnownPosted.insert(std::make_pair(*git, time(nullptr)));
|
|
||||||
IndicateConfigChanged();
|
IndicateConfigChanged();
|
||||||
|
|
||||||
auto ev = std::make_shared<RsGxsPostedEvent>();
|
auto ev = std::make_shared<RsGxsPostedEvent>();
|
||||||
ev->mPostedGroupId = *git;
|
ev->mPostedGroupId = group_id;
|
||||||
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
|
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
|
||||||
rsEvents->postEvent(ev);
|
rsEvents->postEvent(ev);
|
||||||
|
|
||||||
#ifdef POSTBASE_DEBUG
|
#ifdef POSTBASE_DEBUG
|
||||||
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
|
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
RsInfo() << __PRETTY_FUNCTION__
|
RsInfo() << __PRETTY_FUNCTION__
|
||||||
<< " Not notifying already known forum "
|
<< " Not notifying already known forum "
|
||||||
<< *git << std::endl;
|
<< group_id << std::endl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -351,11 +331,7 @@ void p3PostBase::addGroupForProcessing(RsGxsGroupId grpId)
|
|||||||
{
|
{
|
||||||
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
|
||||||
// no point having multiple lookups queued.
|
// no point having multiple lookups queued.
|
||||||
if (mBgGroupList.end() == std::find(mBgGroupList.begin(),
|
mBgGroupList.insert(grpId);
|
||||||
mBgGroupList.end(), grpId))
|
|
||||||
{
|
|
||||||
mBgGroupList.push_back(grpId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,8 +364,8 @@ void p3PostBase::background_requestUnprocessedGroup()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grpId = mBgGroupList.front();
|
grpId = *mBgGroupList.begin();
|
||||||
mBgGroupList.pop_front();
|
mBgGroupList.erase(grpId);
|
||||||
mBgProcessing = true;
|
mBgProcessing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -483,8 +459,6 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
|||||||
|
|
||||||
// generate vector of changes to push to the GUI.
|
// generate vector of changes to push to the GUI.
|
||||||
std::vector<RsGxsNotify *> changes;
|
std::vector<RsGxsNotify *> changes;
|
||||||
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
|
||||||
|
|
||||||
|
|
||||||
RsGxsGroupId groupId;
|
RsGxsGroupId groupId;
|
||||||
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
|
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
|
||||||
@ -535,7 +509,7 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* but we need to notify GUI about them */
|
/* but we need to notify GUI about them */
|
||||||
msgChanges->msgChangeMap[mit->first].insert((*vit)->meta.mMsgId);
|
changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, mit->first,(*vit)->meta.mMsgId, false));
|
||||||
}
|
}
|
||||||
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
|
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
|
||||||
{
|
{
|
||||||
@ -631,22 +605,7 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* push updates of new Posts */
|
/* push updates of new Posts */
|
||||||
if (msgChanges->msgChangeMap.size() > 0)
|
|
||||||
{
|
|
||||||
#ifdef POSTBASE_DEBUG
|
|
||||||
std::cerr << "p3PostBase::background_processNewMessages() -> receiveChanges()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
changes.push_back(msgChanges);
|
|
||||||
//receiveHelperChanges(changes);
|
|
||||||
|
|
||||||
notifyChanges(changes);
|
notifyChanges(changes);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete(msgChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* request the summary info from the parents */
|
/* request the summary info from the parents */
|
||||||
uint32_t token_b;
|
uint32_t token_b;
|
||||||
@ -711,7 +670,6 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
|||||||
|
|
||||||
// generate vector of changes to push to the GUI.
|
// generate vector of changes to push to the GUI.
|
||||||
std::vector<RsGxsNotify *> changes;
|
std::vector<RsGxsNotify *> changes;
|
||||||
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
|
|
||||||
|
|
||||||
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); ++mit)
|
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); ++mit)
|
||||||
{
|
{
|
||||||
@ -754,7 +712,8 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
stats.increment(it->second);
|
stats.increment(it->second);
|
||||||
msgChanges->msgChangeMap[mit->first].insert(vit->mMsgId);
|
|
||||||
|
changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED,mit->first,vit->mMsgId, false));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -786,21 +745,7 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (msgChanges->msgChangeMap.size() > 0)
|
|
||||||
{
|
|
||||||
#ifdef POSTBASE_DEBUG
|
|
||||||
std::cerr << "p3PostBase::background_updateVoteCounts() -> receiveChanges()";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
changes.push_back(msgChanges);
|
|
||||||
//receiveHelperChanges(changes);
|
|
||||||
notifyChanges(changes);
|
notifyChanges(changes);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete(msgChanges);
|
|
||||||
}
|
|
||||||
|
|
||||||
// DONE!.
|
// DONE!.
|
||||||
background_cleanup();
|
background_cleanup();
|
||||||
|
@ -125,7 +125,7 @@ private:
|
|||||||
|
|
||||||
bool mBgProcessing;
|
bool mBgProcessing;
|
||||||
bool mBgIncremental;
|
bool mBgIncremental;
|
||||||
std::list<RsGxsGroupId> mBgGroupList;
|
std::set<RsGxsGroupId> mBgGroupList;
|
||||||
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
|
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
|
||||||
|
|
||||||
std::map<RsGxsGroupId,rstime_t> mKnownPosted;
|
std::map<RsGxsGroupId,rstime_t> mKnownPosted;
|
||||||
|
@ -94,19 +94,23 @@ bool p3Posted::getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &g
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msgs, std::vector<RsGxsComment> &cmts)
|
bool p3Posted::getPostData(
|
||||||
|
const uint32_t &token, std::vector<RsPostedPost> &msgs,
|
||||||
|
std::vector<RsGxsComment> &cmts,
|
||||||
|
std::vector<RsGxsVote> &vots)
|
||||||
{
|
{
|
||||||
#ifdef POSTED_DEBUG
|
#ifdef POSTED_DEBUG
|
||||||
std::cerr << "p3Posted::getPostData()";
|
RsDbg() << __PRETTY_FUNCTION__ << std::endl;
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GxsMsgDataMap msgData;
|
GxsMsgDataMap msgData;
|
||||||
bool ok = RsGenExchange::getMsgData(token, msgData);
|
|
||||||
rstime_t now = time(NULL);
|
rstime_t now = time(NULL);
|
||||||
|
if(!RsGenExchange::getMsgData(token, msgData))
|
||||||
if(ok)
|
|
||||||
{
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " ERROR in request" << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
GxsMsgDataMap::iterator mit = msgData.begin();
|
GxsMsgDataMap::iterator mit = msgData.begin();
|
||||||
|
|
||||||
for(; mit != msgData.end(); ++mit)
|
for(; mit != msgData.end(); ++mit)
|
||||||
@ -116,10 +120,12 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
|
|||||||
|
|
||||||
for(; vit != msgItems.end(); ++vit)
|
for(; vit != msgItems.end(); ++vit)
|
||||||
{
|
{
|
||||||
RsGxsPostedPostItem* postItem = dynamic_cast<RsGxsPostedPostItem*>(*vit);
|
RsGxsPostedPostItem* postItem =
|
||||||
|
dynamic_cast<RsGxsPostedPostItem*>(*vit);
|
||||||
|
|
||||||
if(postItem)
|
if(postItem)
|
||||||
{
|
{
|
||||||
|
// TODO Really needed all of these lines?
|
||||||
RsPostedPost msg = postItem->mPost;
|
RsPostedPost msg = postItem->mPost;
|
||||||
msg.mMeta = postItem->meta;
|
msg.mMeta = postItem->meta;
|
||||||
postItem->toPostedPost(msg, true);
|
postItem->toPostedPost(msg, true);
|
||||||
@ -130,7 +136,8 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RsGxsCommentItem* cmtItem = dynamic_cast<RsGxsCommentItem*>(*vit);
|
RsGxsCommentItem* cmtItem =
|
||||||
|
dynamic_cast<RsGxsCommentItem*>(*vit);
|
||||||
if(cmtItem)
|
if(cmtItem)
|
||||||
{
|
{
|
||||||
RsGxsComment cmt;
|
RsGxsComment cmt;
|
||||||
@ -138,19 +145,35 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
|
|||||||
cmt = cmtItem->mMsg;
|
cmt = cmtItem->mMsg;
|
||||||
cmt.mMeta = mi->meta;
|
cmt.mMeta = mi->meta;
|
||||||
#ifdef GXSCOMMENT_DEBUG
|
#ifdef GXSCOMMENT_DEBUG
|
||||||
std::cerr << "p3Posted::getPostData Found Comment:" << std::endl;
|
RsDbg() << __PRETTY_FUNCTION__ << " Found Comment:" << std::endl;
|
||||||
cmt.print(std::cerr," ", "cmt");
|
cmt.print(std::cerr," ", "cmt");
|
||||||
#endif
|
#endif
|
||||||
cmts.push_back(cmt);
|
cmts.push_back(cmt);
|
||||||
delete cmtItem;
|
delete cmtItem;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
RsGxsVoteItem* votItem =
|
||||||
|
dynamic_cast<RsGxsVoteItem*>(*vit);
|
||||||
|
if(votItem)
|
||||||
|
{
|
||||||
|
RsGxsVote vot;
|
||||||
|
RsGxsMsgItem *mi = (*vit);
|
||||||
|
vot = votItem->mMsg;
|
||||||
|
vot.mMeta = mi->meta;
|
||||||
|
vots.push_back(vot);
|
||||||
|
delete votItem;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RsGxsMsgItem* msg = (*vit);
|
RsGxsMsgItem* msg = (*vit);
|
||||||
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
//const uint16_t RS_SERVICE_GXS_TYPE_CHANNELS = 0x0217;
|
||||||
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
//const uint8_t RS_PKT_SUBTYPE_GXSCHANNEL_POST_ITEM = 0x03;
|
||||||
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_COMMENT_ITEM = 0xf1;
|
||||||
std::cerr << "Not a PostedPostItem neither a RsGxsCommentItem"
|
//const uint8_t RS_PKT_SUBTYPE_GXSCOMMENT_VOTE_ITEM = 0xf2;
|
||||||
|
RsErr() << __PRETTY_FUNCTION__
|
||||||
|
<< "Not a PostedPostItem neither a "
|
||||||
|
<< "RsGxsCommentItem neither a RsGxsVoteItem"
|
||||||
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
<< " PacketService=" << std::hex << (int)msg->PacketService() << std::dec
|
||||||
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
<< " PacketSubType=" << std::hex << (int)msg->PacketSubType() << std::dec
|
||||||
<< " type name =" << typeid(*msg).name()
|
<< " type name =" << typeid(*msg).name()
|
||||||
@ -161,13 +184,23 @@ bool p3Posted::getPostData(const uint32_t &token, std::vector<RsPostedPost> &msg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "p3GxsChannels::getPostData() ERROR in request";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Posted::getPostData(
|
||||||
|
const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts)
|
||||||
|
{
|
||||||
|
std::vector<RsGxsVote> vots;
|
||||||
|
return getPostData( token, posts, cmts, vots);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Posted::getPostData(
|
||||||
|
const uint32_t &token, std::vector<RsPostedPost> &posts)
|
||||||
|
{
|
||||||
|
std::vector<RsGxsComment> cmts;
|
||||||
|
std::vector<RsGxsVote> vots;
|
||||||
|
return getPostData( token, posts, cmts, vots);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Not currently used
|
//Not currently used
|
||||||
@ -324,7 +357,8 @@ bool p3Posted::getBoardsInfo(
|
|||||||
|
|
||||||
bool p3Posted::getBoardAllContent( const RsGxsGroupId& groupId,
|
bool p3Posted::getBoardAllContent( const RsGxsGroupId& groupId,
|
||||||
std::vector<RsPostedPost>& posts,
|
std::vector<RsPostedPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments )
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes )
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
@ -333,13 +367,14 @@ bool p3Posted::getBoardAllContent( const RsGxsGroupId& groupId,
|
|||||||
if( !requestMsgInfo(token, opts, std::list<RsGxsGroupId>({groupId})) || waitToken(token) != RsTokenService::COMPLETE )
|
if( !requestMsgInfo(token, opts, std::list<RsGxsGroupId>({groupId})) || waitToken(token) != RsTokenService::COMPLETE )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return getPostData(token, posts, comments);
|
return getPostData(token, posts, comments, votes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3Posted::getBoardContent( const RsGxsGroupId& groupId,
|
bool p3Posted::getBoardContent( const RsGxsGroupId& groupId,
|
||||||
const std::set<RsGxsMessageId>& contentsIds,
|
const std::set<RsGxsMessageId>& contentsIds,
|
||||||
std::vector<RsPostedPost>& posts,
|
std::vector<RsPostedPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments )
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes )
|
||||||
{
|
{
|
||||||
uint32_t token;
|
uint32_t token;
|
||||||
RsTokReqOptions opts;
|
RsTokReqOptions opts;
|
||||||
@ -351,7 +386,7 @@ bool p3Posted::getBoardContent( const RsGxsGroupId& groupId,
|
|||||||
if( !requestMsgInfo(token, opts, msgIds) ||
|
if( !requestMsgInfo(token, opts, msgIds) ||
|
||||||
waitToken(token) != RsTokenService::COMPLETE ) return false;
|
waitToken(token) != RsTokenService::COMPLETE ) return false;
|
||||||
|
|
||||||
return getPostData(token, posts, comments);
|
return getPostData(token, posts, comments, votes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3Posted::getBoardsSummaries(std::list<RsGroupMetaData>& boards )
|
bool p3Posted::getBoardsSummaries(std::list<RsGroupMetaData>& boards )
|
||||||
|
@ -53,22 +53,26 @@ virtual void notifyChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
#ifdef TO_REMOVE
|
||||||
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
||||||
{
|
{
|
||||||
return RsGxsIfaceHelper::receiveChanges(changes);
|
return RsGxsIfaceHelper::receiveChanges(changes);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool getBoardsInfo(const std::list<RsGxsGroupId>& boardsIds,
|
bool getBoardsInfo(const std::list<RsGxsGroupId>& boardsIds,
|
||||||
std::vector<RsPostedGroup>& groupsInfo ) override;
|
std::vector<RsPostedGroup>& groupsInfo ) override;
|
||||||
|
|
||||||
bool getBoardAllContent(const RsGxsGroupId& groupId,
|
bool getBoardAllContent(const RsGxsGroupId& groupId,
|
||||||
std::vector<RsPostedPost>& posts,
|
std::vector<RsPostedPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) override;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) override;
|
||||||
|
|
||||||
bool getBoardContent(const RsGxsGroupId& groupId,
|
bool getBoardContent(const RsGxsGroupId& groupId,
|
||||||
const std::set<RsGxsMessageId>& contentsIds,
|
const std::set<RsGxsMessageId>& contentsIds,
|
||||||
std::vector<RsPostedPost>& posts,
|
std::vector<RsPostedPost>& posts,
|
||||||
std::vector<RsGxsComment>& comments ) override;
|
std::vector<RsGxsComment>& comments,
|
||||||
|
std::vector<RsGxsVote>& votes ) override;
|
||||||
|
|
||||||
bool getBoardsSummaries(std::list<RsGroupMetaData>& groupInfo) override;
|
bool getBoardsSummaries(std::list<RsGroupMetaData>& groupInfo) override;
|
||||||
|
|
||||||
@ -80,9 +84,10 @@ virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
|
|||||||
|
|
||||||
bool createBoard(RsPostedGroup& board) override;
|
bool createBoard(RsPostedGroup& board) override;
|
||||||
|
|
||||||
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups);
|
virtual bool getGroupData(const uint32_t &token, std::vector<RsPostedGroup> &groups) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts);
|
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts, std::vector<RsGxsVote> &vots) override;
|
||||||
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) { std::vector<RsGxsComment> cmts; return getPostData( token, posts, cmts);}
|
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts, std::vector<RsGxsComment> &cmts) override;
|
||||||
|
virtual bool getPostData(const uint32_t &token, std::vector<RsPostedPost> &posts) override;
|
||||||
//Not currently used
|
//Not currently used
|
||||||
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts);
|
//virtual bool getRelatedPosts(const uint32_t &token, std::vector<RsPostedPost> &posts);
|
||||||
|
|
||||||
|
@ -21,8 +21,6 @@
|
|||||||
* *
|
* *
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
#include "util/rsbase64.h"
|
#include "util/rsbase64.h"
|
||||||
#include "util/rsdebug.h"
|
#include "util/rsdebug.h"
|
||||||
|
|
||||||
@ -40,6 +38,12 @@
|
|||||||
rs_view_ptr<const uint8_t> data, size_t len, std::string& outString,
|
rs_view_ptr<const uint8_t> data, size_t len, std::string& outString,
|
||||||
bool padding, bool urlSafe )
|
bool padding, bool urlSafe )
|
||||||
{
|
{
|
||||||
|
if(!data || !len)
|
||||||
|
{
|
||||||
|
outString.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const char* sDict = urlSafe ? uDict : bDict;
|
const char* sDict = urlSafe ? uDict : bDict;
|
||||||
|
|
||||||
// Workaround if input and output are the same buffer.
|
// Workaround if input and output are the same buffer.
|
||||||
@ -137,9 +141,11 @@
|
|||||||
|
|
||||||
/*static*/ size_t RsBase64::encodedSize(size_t decodedSize, bool padding)
|
/*static*/ size_t RsBase64::encodedSize(size_t decodedSize, bool padding)
|
||||||
{
|
{
|
||||||
if(padding) return 4 * (decodedSize + 2) / 3;
|
if(!decodedSize) return 0;
|
||||||
return static_cast<size_t>(
|
|
||||||
std::ceil(4L * static_cast<double>(decodedSize) / 3L) );
|
// Thanks https://stackoverflow.com/a/45401395
|
||||||
|
if(padding) return ceilDivision(decodedSize, 3) * 4;
|
||||||
|
return ceilDivision(decodedSize * 8, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ std::tuple<size_t, std::error_condition> RsBase64::decodedSize(
|
/*static*/ std::tuple<size_t, std::error_condition> RsBase64::decodedSize(
|
||||||
|
@ -137,4 +137,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
static inline bool isBase64Char(char c)
|
static inline bool isBase64Char(char c)
|
||||||
{ return rDict[static_cast<uint8_t>(c)] >= 0; }
|
{ return rDict[static_cast<uint8_t>(c)] >= 0; }
|
||||||
|
|
||||||
|
/** Perform ceil division without floating point operations */
|
||||||
|
static inline size_t ceilDivision(size_t dividend, size_t divisor)
|
||||||
|
{ return (dividend + divisor - 1) / divisor; }
|
||||||
};
|
};
|
||||||
|
@ -32,6 +32,8 @@ std::ostream &operator<<(std::ostream& out, const std::error_condition& err);
|
|||||||
# include <sstream>
|
# include <sstream>
|
||||||
# include <string>
|
# include <string>
|
||||||
|
|
||||||
|
# include "util/rsjson.h"
|
||||||
|
|
||||||
enum class RsLoggerCategories
|
enum class RsLoggerCategories
|
||||||
{
|
{
|
||||||
DEBUG = ANDROID_LOG_DEBUG,
|
DEBUG = ANDROID_LOG_DEBUG,
|
||||||
@ -46,6 +48,18 @@ struct t_RsLogger
|
|||||||
{
|
{
|
||||||
inline t_RsLogger() = default;
|
inline t_RsLogger() = default;
|
||||||
|
|
||||||
|
/** Offer variadic style too, as a benefit this has better atomicity then
|
||||||
|
* << style, but doesn't supports manipulators and things like std::endl
|
||||||
|
* @see https://stackoverflow.com/a/27375675 */
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
inline t_RsLogger(Arg&& arg, Args&&... args)
|
||||||
|
{
|
||||||
|
ostr << std::forward<Arg>(arg);
|
||||||
|
using expander = int[];
|
||||||
|
(void)expander{0, (void(ostr << std::forward<Args>(args)), 0)...};
|
||||||
|
mFlush();
|
||||||
|
}
|
||||||
|
|
||||||
/** On other platforms expose the type of underlying stream.
|
/** On other platforms expose the type of underlying stream.
|
||||||
* On Android it cannot work like that so return the class type itself
|
* On Android it cannot work like that so return the class type itself
|
||||||
* just for code compatibility with other platforms */
|
* just for code compatibility with other platforms */
|
||||||
@ -55,17 +69,16 @@ struct t_RsLogger
|
|||||||
inline stream_type& operator<<(const T& val)
|
inline stream_type& operator<<(const T& val)
|
||||||
{ ostr << val; return *this; }
|
{ ostr << val; return *this; }
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline stream_type& operator<<(const RsJson& val)
|
||||||
|
{ ostr << val; return *this; }
|
||||||
|
|
||||||
/// needed for manipulators and things like std::endl
|
/// needed for manipulators and things like std::endl
|
||||||
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
||||||
{
|
{
|
||||||
if(pf == static_cast<std::ostream& (*)(std::ostream&)>(
|
if(pf == static_cast<std::ostream& (*)(std::ostream&)>(
|
||||||
&std::endl< char, std::char_traits<char> > ))
|
&std::endl< char, std::char_traits<char> > ))
|
||||||
{
|
mFlush();
|
||||||
__android_log_write(
|
|
||||||
static_cast<int>(CATEGORY),
|
|
||||||
"RetroShare", ostr.str().c_str() );
|
|
||||||
ostr.str() = "";
|
|
||||||
}
|
|
||||||
else ostr << pf;
|
else ostr << pf;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
@ -78,6 +91,14 @@ struct t_RsLogger
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::ostringstream ostr;
|
std::ostringstream ostr;
|
||||||
|
|
||||||
|
void mFlush()
|
||||||
|
{
|
||||||
|
__android_log_write(
|
||||||
|
static_cast<int>(CATEGORY),
|
||||||
|
"RetroShare", ostr.str().c_str() );
|
||||||
|
ostr.str() = "";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // def __ANDROID__
|
#else // def __ANDROID__
|
||||||
@ -99,38 +120,56 @@ enum class RsLoggerCategories
|
|||||||
template <RsLoggerCategories CATEGORY>
|
template <RsLoggerCategories CATEGORY>
|
||||||
struct t_RsLogger
|
struct t_RsLogger
|
||||||
{
|
{
|
||||||
inline t_RsLogger() = default;
|
|
||||||
|
|
||||||
/// Expose the type of underlying stream
|
/// Expose the type of underlying stream
|
||||||
using stream_type = decltype(std::cerr);
|
using stream_type = decltype(std::cerr);
|
||||||
|
|
||||||
|
/// Return underlying stream to write avoiding additional prefixes
|
||||||
|
static inline stream_type& uStream() { return std::cerr; }
|
||||||
|
|
||||||
|
inline t_RsLogger() = default;
|
||||||
|
|
||||||
|
/** Offer variadic style too, as a benefit this has better atomicity then
|
||||||
|
* << style, but doesn't supports manipulators and things like std::endl
|
||||||
|
* @see https://stackoverflow.com/a/27375675 */
|
||||||
|
template <typename Arg, typename... Args>
|
||||||
|
inline t_RsLogger(Arg&& arg, Args&&... args)
|
||||||
|
{
|
||||||
|
std::ostringstream ostr;
|
||||||
|
ostr << getPrefix() << std::forward<Arg>(arg);
|
||||||
|
using expander = int[];
|
||||||
|
(void)expander{0, (void(ostr << std::forward<Args>(args)), 0)...};
|
||||||
|
ostr << std::endl;
|
||||||
|
uStream() << ostr.str();
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline stream_type& operator<<(const T& val)
|
inline stream_type& operator<<(const T& val)
|
||||||
|
{ return uStream() << getPrefix() << val; }
|
||||||
|
|
||||||
|
/// needed for manipulators and things like std::endl
|
||||||
|
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
||||||
|
{ return uStream() << pf; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string getPrefix()
|
||||||
{
|
{
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
const auto now = system_clock::now();
|
const auto now = system_clock::now();
|
||||||
const auto sec = time_point_cast<seconds>(now);
|
const auto sec = time_point_cast<seconds>(now);
|
||||||
const auto msec = duration_cast<milliseconds>(now - sec);
|
const auto msec = duration_cast<milliseconds>(now - sec);
|
||||||
std::stringstream tstream;
|
std::ostringstream tstream;
|
||||||
tstream << static_cast<char>(CATEGORY) << " "
|
tstream << static_cast<char>(CATEGORY) << " "
|
||||||
<< sec.time_since_epoch().count() << "."
|
<< sec.time_since_epoch().count() << "."
|
||||||
<< std::setfill('0') << std::setw(3) << msec.count()
|
<< std::setfill('0') << std::setw(3) << msec.count()
|
||||||
<< " " << val;
|
<< " ";
|
||||||
return std::cerr << tstream.str();
|
return tstream.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// needed for manipulators and things like std::endl
|
|
||||||
stream_type& operator<<(std::ostream& (*pf)(std::ostream&))
|
|
||||||
{ return std::cerr << pf; }
|
|
||||||
|
|
||||||
/// Return underlying stream to write avoiding additional prefixes
|
|
||||||
inline stream_type& uStream() const { return std::cerr; }
|
|
||||||
};
|
};
|
||||||
#endif // def __ANDROID__
|
#endif // def __ANDROID__
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comfortable debug message loggin, supports chaining like std::cerr but can
|
* Comfortable debug message logging, supports chaining like std::cerr but can
|
||||||
* be easly and selectively disabled at compile time to reduce generated binary
|
* be easly and selectively disabled at compile time to reduce generated binary
|
||||||
* size and performance impact without too many \#ifdef around.
|
* size and performance impact without too many \#ifdef around.
|
||||||
*
|
*
|
||||||
@ -190,6 +229,8 @@ struct RsNoDbg
|
|||||||
{
|
{
|
||||||
inline RsNoDbg() = default;
|
inline RsNoDbg() = default;
|
||||||
|
|
||||||
|
template <typename T, typename... Args> inline RsNoDbg(T, Args...) {}
|
||||||
|
|
||||||
/** Defined as the type itself just for code compatibility with other
|
/** Defined as the type itself just for code compatibility with other
|
||||||
* logging classes */
|
* logging classes */
|
||||||
using stream_type = RsNoDbg;
|
using stream_type = RsNoDbg;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
typedef rapidjson::Document RsJson;
|
typedef rapidjson::Document RsJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print out RsJson to a stream, use std::stringstream to get the string
|
* Print out RsJson to a stream, use std::ostringstream to get the string
|
||||||
* @param[out] out output stream
|
* @param[out] out output stream
|
||||||
* @param[in] jDoc JSON document to print
|
* @param[in] jDoc JSON document to print
|
||||||
* @return same output stream passed as out parameter
|
* @return same output stream passed as out parameter
|
||||||
|
@ -60,7 +60,12 @@ public:
|
|||||||
|
|
||||||
bool is_cached(const Key &key) const;
|
bool is_cached(const Key &key) const;
|
||||||
bool fetch(const Key &key, Value &data);
|
bool fetch(const Key &key, Value &data);
|
||||||
Value &ref(const Key &key); // like map[] installs empty one if non-existent.
|
|
||||||
|
// Like map[] installs empty one if non-existent.
|
||||||
|
|
||||||
|
Value& ref(const Key &key);
|
||||||
|
Value& operator[](const Key& key) { return ref(key); }
|
||||||
|
|
||||||
bool store(const Key &key, const Value &data);
|
bool store(const Key &key, const Value &data);
|
||||||
bool erase(const Key &key); // clean up cache.
|
bool erase(const Key &key); // clean up cache.
|
||||||
|
|
||||||
@ -71,6 +76,7 @@ public:
|
|||||||
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
|
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
|
||||||
|
|
||||||
uint32_t size() const { return mDataMap.size() ; }
|
uint32_t size() const { return mDataMap.size() ; }
|
||||||
|
void printStats(std::ostream& out);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool update_lrumap(const Key &key, rstime_t old_ts, rstime_t new_ts);
|
bool update_lrumap(const Key &key, rstime_t old_ts, rstime_t new_ts);
|
||||||
@ -96,7 +102,6 @@ private:
|
|||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
// some statistics.
|
// some statistics.
|
||||||
void printStats(std::ostream &out);
|
|
||||||
void clearStats();
|
void clearStats();
|
||||||
|
|
||||||
mutable uint32_t mStats_inserted;
|
mutable uint32_t mStats_inserted;
|
||||||
|
@ -452,7 +452,7 @@ void FeedReaderDialog::calculateFeedItem(QTreeWidgetItem *item, uint32_t &unread
|
|||||||
font.setBold(unreadCountItem != 0);
|
font.setBold(unreadCountItem != 0);
|
||||||
item->setFont(i, font);
|
item->setFont(i, font);
|
||||||
|
|
||||||
item->setTextColor(COLUMN_FEED_NAME, deactivated ? colorDeactivated : colorActivated);
|
item->setData(COLUMN_FEED_NAME, Qt::ForegroundRole, deactivated ? colorDeactivated : colorActivated);
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon icon = item->data(COLUMN_FEED_DATA, ROLE_FEED_ICON).value<QIcon>();
|
QIcon icon = item->data(COLUMN_FEED_DATA, ROLE_FEED_ICON).value<QIcon>();
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "chat/ChatTabWidget.h"
|
#include "chat/ChatTabWidget.h"
|
||||||
#include "chat/CreateLobbyDialog.h"
|
#include "chat/CreateLobbyDialog.h"
|
||||||
#include "common/RSTreeWidgetItem.h"
|
#include "common/RSTreeWidgetItem.h"
|
||||||
|
#include "common/RSElidedItemDelegate.h"
|
||||||
#include "gui/RetroShareLink.h"
|
#include "gui/RetroShareLink.h"
|
||||||
#include "gui/gxs/GxsIdDetails.h"
|
#include "gui/gxs/GxsIdDetails.h"
|
||||||
#include "gui/Identity/IdEditDialog.h"
|
#include "gui/Identity/IdEditDialog.h"
|
||||||
@ -157,6 +158,7 @@ ChatLobbyWidget::ChatLobbyWidget(QWidget *parent, Qt::WindowFlags flags)
|
|||||||
ui.lobbyTreeWidget->setColumnHidden(COLUMN_USER_COUNT,true) ;
|
ui.lobbyTreeWidget->setColumnHidden(COLUMN_USER_COUNT,true) ;
|
||||||
ui.lobbyTreeWidget->setColumnHidden(COLUMN_TOPIC,true) ;
|
ui.lobbyTreeWidget->setColumnHidden(COLUMN_TOPIC,true) ;
|
||||||
ui.lobbyTreeWidget->setSortingEnabled(true) ;
|
ui.lobbyTreeWidget->setSortingEnabled(true) ;
|
||||||
|
ui.lobbyTreeWidget->setItemDelegateForColumn(COLUMN_NAME, new RSElidedItemDelegate());
|
||||||
|
|
||||||
float fact = QFontMetricsF(font()).height()/14.0f;
|
float fact = QFontMetricsF(font()).height()/14.0f;
|
||||||
|
|
||||||
@ -386,6 +388,8 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
|||||||
item->setData(COLUMN_DATA, ROLE_FLAGS, lobby_flags.toUInt32());
|
item->setData(COLUMN_DATA, ROLE_FLAGS, lobby_flags.toUInt32());
|
||||||
item->setData(COLUMN_DATA, ROLE_AUTOSUBSCRIBE, autoSubscribe);
|
item->setData(COLUMN_DATA, ROLE_AUTOSUBSCRIBE, autoSubscribe);
|
||||||
|
|
||||||
|
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||||
|
// As palette is not updated by stylesheet
|
||||||
QColor color = treeWidget->palette().color(QPalette::Active, QPalette::Text);
|
QColor color = treeWidget->palette().color(QPalette::Active, QPalette::Text);
|
||||||
|
|
||||||
if (!subscribed) {
|
if (!subscribed) {
|
||||||
@ -395,7 +399,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (int column = 0; column < COLUMN_COUNT; ++column) {
|
for (int column = 0; column < COLUMN_COUNT; ++column) {
|
||||||
item->setTextColor(column, color);
|
item->setData(column, Qt::ForegroundRole, color);
|
||||||
}
|
}
|
||||||
QString tooltipstr = QObject::tr("Subject:")+" "+item->text(COLUMN_TOPIC)+"\n"
|
QString tooltipstr = QObject::tr("Subject:")+" "+item->text(COLUMN_TOPIC)+"\n"
|
||||||
+QObject::tr("Participants:")+" "+QString::number(count)+"\n"
|
+QObject::tr("Participants:")+" "+QString::number(count)+"\n"
|
||||||
@ -407,7 +411,7 @@ static void updateItem(QTreeWidget *treeWidget, QTreeWidgetItem *item, ChatLobby
|
|||||||
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
|
tooltipstr += QObject::tr("\nSecurity: no anonymous IDs") ;
|
||||||
QColor foreground = QColor(0, 128, 0); // green
|
QColor foreground = QColor(0, 128, 0); // green
|
||||||
for (int column = 0; column < COLUMN_COUNT; ++column)
|
for (int column = 0; column < COLUMN_COUNT; ++column)
|
||||||
item->setTextColor(column, foreground);
|
item->setData(column, Qt::ForegroundRole, foreground);
|
||||||
}
|
}
|
||||||
item->setToolTip(0,tooltipstr) ;
|
item->setToolTip(0,tooltipstr) ;
|
||||||
}
|
}
|
||||||
|
@ -415,9 +415,8 @@ void SearchDialog::download()
|
|||||||
std::cout << *it << "-" << std::endl;
|
std::cout << *it << "-" << std::endl;
|
||||||
|
|
||||||
QColor foreground = textColorDownloading();
|
QColor foreground = textColorDownloading();
|
||||||
QBrush brush(foreground);
|
|
||||||
for (int i = 0; i < item->columnCount(); ++i)
|
for (int i = 0; i < item->columnCount(); ++i)
|
||||||
item->setForeground(i, brush);
|
item->setData(i, Qt::ForegroundRole, foreground );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1269,10 +1268,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
|||||||
foreground = textColorHighSources();
|
foreground = textColorHighSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
QBrush brush(foreground);
|
|
||||||
for (int i = 0; i < item->columnCount(); ++i)
|
for (int i = 0; i < item->columnCount(); ++i)
|
||||||
{
|
{
|
||||||
item->setForeground(i, brush);
|
item->setData(i, Qt::ForegroundRole, foreground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1355,10 +1353,9 @@ void SearchDialog::insertFile(qulonglong searchId, const FileDetail& file, int s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (setForeground) {
|
if (setForeground) {
|
||||||
QBrush brush(foreground);
|
|
||||||
for (int i = 0; i < item->columnCount(); ++i)
|
for (int i = 0; i < item->columnCount(); ++i)
|
||||||
{
|
{
|
||||||
item->setForeground(i, brush);
|
item->setData(i, Qt::ForegroundRole, foreground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ public:
|
|||||||
TransferUserNotify(QObject *parent = 0);
|
TransferUserNotify(QObject *parent = 0);
|
||||||
|
|
||||||
virtual bool hasSetting(QString *name, QString *group);
|
virtual bool hasSetting(QString *name, QString *group);
|
||||||
|
virtual QString textInfo() const override { return tr("completed transfer(s)"); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual QIcon getIcon();
|
virtual QIcon getIcon();
|
||||||
|
@ -183,6 +183,7 @@ IdDialog::IdDialog(QWidget *parent) : MainPage(parent), ui(new Ui::IdDialog)
|
|||||||
|
|
||||||
mExternalOtherCircleItem = NULL ;
|
mExternalOtherCircleItem = NULL ;
|
||||||
mExternalBelongingCircleItem = NULL ;
|
mExternalBelongingCircleItem = NULL ;
|
||||||
|
mMyCircleItem = NULL ;
|
||||||
|
|
||||||
/* Setup UI helper */
|
/* Setup UI helper */
|
||||||
mStateHelper = new UIStateHelper(this);
|
mStateHelper = new UIStateHelper(this);
|
||||||
@ -437,12 +438,11 @@ void IdDialog::handleEvent_main_thread(std::shared_ptr<const RsEvent> event)
|
|||||||
|
|
||||||
switch(e->mCircleEventType)
|
switch(e->mCircleEventType)
|
||||||
{
|
{
|
||||||
case RsGxsCircleEventCode::NEW_CIRCLE:
|
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE:
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST:
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST:
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
|
case RsGxsCircleEventCode::NEW_CIRCLE:
|
||||||
case RsGxsCircleEventCode::CACHE_DATA_UPDATED:
|
case RsGxsCircleEventCode::CACHE_DATA_UPDATED:
|
||||||
|
|
||||||
updateCircles();
|
updateCircles();
|
||||||
@ -598,6 +598,10 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
|||||||
|
|
||||||
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
|
mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true);
|
||||||
|
|
||||||
|
std::vector<bool> expanded_top_level_items;
|
||||||
|
std::set<RsGxsCircleId> expanded_circle_items;
|
||||||
|
saveExpandedCircleItems(expanded_top_level_items,expanded_circle_items);
|
||||||
|
|
||||||
#ifdef QT_BUG_CRASH_IN_TAKECHILD_WORKAROUND
|
#ifdef QT_BUG_CRASH_IN_TAKECHILD_WORKAROUND
|
||||||
// These 3 lines are normally not needed. But apparently a bug (in Qt ??) causes Qt to crash when takeChild() is called. If we remove everything from the
|
// These 3 lines are normally not needed. But apparently a bug (in Qt ??) causes Qt to crash when takeChild() is called. If we remove everything from the
|
||||||
// tree widget before updating it, takeChild() is never called, but the all tree is filled again from scratch. This is less efficient obviously, and
|
// tree widget before updating it, takeChild() is never called, but the all tree is filled again from scratch. This is less efficient obviously, and
|
||||||
@ -858,6 +862,7 @@ void IdDialog::loadCircles(const std::list<RsGroupMetaData>& groupInfo)
|
|||||||
else
|
else
|
||||||
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,FilesDefs::getIconFromQtResourcePath(IMAGE_UNKNOWN)) ;
|
item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,FilesDefs::getIconFromQtResourcePath(IMAGE_UNKNOWN)) ;
|
||||||
}
|
}
|
||||||
|
restoreExpandedCircleItems(expanded_top_level_items,expanded_circle_items);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members, int col)
|
//static void mark_matching_tree(QTreeWidget *w, const std::set<RsGxsId>& members, int col)
|
||||||
@ -936,13 +941,25 @@ void IdDialog::revokeCircleMembership()
|
|||||||
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
if(!getItemCircleId(ui->treeWidget_membership->currentItem(),circle_id))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if(circle_id.isNull())
|
||||||
|
{
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " : got a null circle ID. Cannot revoke an identity from that circle!" << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
|
RsGxsId gxs_id_to_revoke(qobject_cast<QAction*>(sender())->data().toString().toStdString());
|
||||||
|
|
||||||
|
if(gxs_id_to_revoke.isNull())
|
||||||
|
RsErr() << __PRETTY_FUNCTION__ << " : got a null ID. Cannot revoke it from circle " << circle_id << "!" << std::endl;
|
||||||
|
else
|
||||||
RsThread::async([circle_id,gxs_id_to_revoke]()
|
RsThread::async([circle_id,gxs_id_to_revoke]()
|
||||||
{
|
{
|
||||||
// 1 - get message data from p3GxsForums
|
// 1 - get message data from p3GxsForums
|
||||||
|
|
||||||
rsGxsCircles->revokeIdsFromCircle(std::set<RsGxsId>( { gxs_id_to_revoke } ),circle_id);
|
std::set<RsGxsId> ids;
|
||||||
|
ids.insert(gxs_id_to_revoke);
|
||||||
|
|
||||||
|
rsGxsCircles->revokeIdsFromCircle(ids,circle_id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1371,17 +1388,18 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
|||||||
|
|
||||||
if(isBanned)
|
if(isBanned)
|
||||||
{
|
{
|
||||||
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::red));
|
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||||
item->setForeground(RSID_COL_KEYID,QBrush(Qt::red));
|
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red));
|
||||||
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::red));
|
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red));
|
||||||
item->setForeground(RSID_COL_VOTES,QBrush(Qt::red));
|
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red));
|
||||||
|
item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QColor(Qt::red));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::black));
|
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QVariant());
|
||||||
item->setForeground(RSID_COL_KEYID,QBrush(Qt::black));
|
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QVariant());
|
||||||
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::black));
|
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QVariant());
|
||||||
item->setForeground(RSID_COL_VOTES,QBrush(Qt::black));
|
item->setData(RSID_COL_VOTES , Qt::ForegroundRole, QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
|
item->setData(RSID_COL_KEYID, Qt::UserRole,QVariant(item_flags)) ;
|
||||||
@ -1406,9 +1424,10 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
|
|||||||
|
|
||||||
if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
|
if(idd.mFlags & RS_IDENTITY_FLAGS_IS_DEPRECATED)
|
||||||
{
|
{
|
||||||
item->setForeground(RSID_COL_NICKNAME,QBrush(Qt::red));
|
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||||
item->setForeground(RSID_COL_KEYID,QBrush(Qt::red));
|
item->setData(RSID_COL_NICKNAME, Qt::ForegroundRole, QColor(Qt::red));
|
||||||
item->setForeground(RSID_COL_IDTYPE,QBrush(Qt::red));
|
item->setData(RSID_COL_KEYID , Qt::ForegroundRole, QColor(Qt::red));
|
||||||
|
item->setData(RSID_COL_IDTYPE , Qt::ForegroundRole, QColor(Qt::red));
|
||||||
|
|
||||||
tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ;
|
tooltip += tr("\nThis identity has a unsecure fingerprint (It's probably quite old).\nYou should get rid of it now and use a new one.\nThese identities will soon be not supported anymore.") ;
|
||||||
}
|
}
|
||||||
@ -2450,3 +2469,53 @@ void IdDialog::on_closeInfoFrameButton_clicked()
|
|||||||
{
|
{
|
||||||
ui->inviteFrame->setVisible(false);
|
ui->inviteFrame->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to use indexes here because saving items is not possible since they can be re-created.
|
||||||
|
|
||||||
|
void IdDialog::saveExpandedCircleItems(std::vector<bool>& expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const
|
||||||
|
{
|
||||||
|
expanded_root_items.clear();
|
||||||
|
expanded_root_items.resize(3,false);
|
||||||
|
expanded_circle_items.clear();
|
||||||
|
|
||||||
|
auto saveTopLevel = [&](const QTreeWidgetItem* top_level_item,uint32_t index){
|
||||||
|
if(!top_level_item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(top_level_item->isExpanded())
|
||||||
|
{
|
||||||
|
expanded_root_items[index] = true;
|
||||||
|
|
||||||
|
for(int row=0;row<top_level_item->childCount();++row)
|
||||||
|
if(top_level_item->child(row)->isExpanded())
|
||||||
|
expanded_circle_items.insert(RsGxsCircleId(top_level_item->child(row)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
saveTopLevel(mExternalBelongingCircleItem,0);
|
||||||
|
saveTopLevel(mExternalOtherCircleItem,1);
|
||||||
|
saveTopLevel(mMyCircleItem,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IdDialog::restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items)
|
||||||
|
{
|
||||||
|
auto restoreTopLevel = [=](QTreeWidgetItem* top_level_item,uint32_t index){
|
||||||
|
if(!top_level_item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
top_level_item->setExpanded(expanded_root_items[index]);
|
||||||
|
|
||||||
|
for(int row=0;row<top_level_item->childCount();++row)
|
||||||
|
{
|
||||||
|
RsGxsCircleId circle_id(RsGxsCircleId(top_level_item->child(row)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString()));
|
||||||
|
bool expanded = expanded_circle_items.find(circle_id) != expanded_circle_items.end();
|
||||||
|
|
||||||
|
top_level_item->child(row)->setExpanded(expanded_circle_items.find(circle_id) != expanded_circle_items.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
restoreTopLevel(mExternalBelongingCircleItem,0);
|
||||||
|
restoreTopLevel(mExternalOtherCircleItem,1);
|
||||||
|
restoreTopLevel(mMyCircleItem,2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -145,6 +145,9 @@ private:
|
|||||||
QTreeWidgetItem *mMyCircleItem;
|
QTreeWidgetItem *mMyCircleItem;
|
||||||
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
|
RsGxsUpdateBroadcastBase *mCirclesBroadcastBase ;
|
||||||
|
|
||||||
|
void saveExpandedCircleItems(std::vector<bool> &expanded_root_items, std::set<RsGxsCircleId>& expanded_circle_items) const;
|
||||||
|
void restoreExpandedCircleItems(const std::vector<bool>& expanded_root_items,const std::set<RsGxsCircleId>& expanded_circle_items);
|
||||||
|
|
||||||
std::map<uint32_t, CircleUpdateOrder> mCircleUpdates ;
|
std::map<uint32_t, CircleUpdateOrder> mCircleUpdates ;
|
||||||
|
|
||||||
RsGxsGroupId mId;
|
RsGxsGroupId mId;
|
||||||
|
@ -120,7 +120,7 @@
|
|||||||
<enum>Qt::NoFocus</enum>
|
<enum>Qt::NoFocus</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset resource="../icons.qrc">
|
||||||
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
<normaloff>:/icons/help_64.png</normaloff>:/icons/help_64.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="checkable">
|
<property name="checkable">
|
||||||
@ -268,7 +268,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QTabWidget" name="rightTabWidget">
|
<widget class="QTabWidget" name="rightTabWidget">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="personTab">
|
<widget class="QWidget" name="personTab">
|
||||||
<attribute name="icon">
|
<attribute name="icon">
|
||||||
@ -289,8 +289,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>634</width>
|
<width>1372</width>
|
||||||
<height>523</height>
|
<height>719</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
<layout class="QVBoxLayout" name="scrollAreaWidgetContentsVLayout">
|
||||||
@ -1052,7 +1052,7 @@ border-image: url(:/images/closepressed.png)
|
|||||||
</action>
|
</action>
|
||||||
<action name="chatIdentity">
|
<action name="chatIdentity">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../images.qrc">
|
<iconset>
|
||||||
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
|
<normaloff>:/images/toaster/chat.png</normaloff>:/images/toaster/chat.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -1094,8 +1094,8 @@ border-image: url(:/images/closepressed.png)
|
|||||||
<tabstop>idTreeWidget</tabstop>
|
<tabstop>idTreeWidget</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources>
|
<resources>
|
||||||
<include location="../images.qrc"/>
|
|
||||||
<include location="../icons.qrc"/>
|
<include location="../icons.qrc"/>
|
||||||
|
<include location="../images.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
@ -486,7 +486,7 @@ void MainWindow::initStackedPage()
|
|||||||
for (notifyIt = notify.begin(); notifyIt != notify.end(); ++notifyIt) {
|
for (notifyIt = notify.begin(); notifyIt != notify.end(); ++notifyIt) {
|
||||||
UserNotify *userNotify = notifyIt->first->getUserNotify();
|
UserNotify *userNotify = notifyIt->first->getUserNotify();
|
||||||
if (userNotify) {
|
if (userNotify) {
|
||||||
userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second);
|
userNotify->initialize(ui->toolBarPage, notifyIt->second.first, notifyIt->second.second,userNotify->textInfo());
|
||||||
connect(userNotify, SIGNAL(countChanged()), this, SLOT(updateTrayCombine()));
|
connect(userNotify, SIGNAL(countChanged()), this, SLOT(updateTrayCombine()));
|
||||||
userNotifyList.push_back(userNotify);
|
userNotifyList.push_back(userNotify);
|
||||||
}
|
}
|
||||||
|
@ -251,14 +251,20 @@ void NewsFeed::handleForumEvent(std::shared_ptr<const RsEvent> event)
|
|||||||
|
|
||||||
switch(pe->mForumEventCode)
|
switch(pe->mForumEventCode)
|
||||||
{
|
{
|
||||||
|
case RsForumEventCode::MODERATOR_LIST_CHANGED:
|
||||||
|
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_UPDATED_FORUM, pe->mForumGroupId,pe->mModeratorsAdded,pe->mModeratorsRemoved, false, true));
|
||||||
|
break;
|
||||||
|
|
||||||
case RsForumEventCode::UPDATED_FORUM:
|
case RsForumEventCode::UPDATED_FORUM:
|
||||||
case RsForumEventCode::NEW_FORUM:
|
case RsForumEventCode::NEW_FORUM:
|
||||||
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, false, true));
|
addFeedItem(new GxsForumGroupItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, false, true));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsForumEventCode::UPDATED_MESSAGE:
|
case RsForumEventCode::UPDATED_MESSAGE:
|
||||||
case RsForumEventCode::NEW_MESSAGE:
|
case RsForumEventCode::NEW_MESSAGE:
|
||||||
addFeedItem(new GxsForumMsgItem(this, NEWSFEED_FORUMNEWLIST, pe->mForumGroupId, pe->mForumMsgId, false, true));
|
addFeedItem(new GxsForumMsgItem(this, NEWSFEED_NEW_FORUM, pe->mForumGroupId, pe->mForumMsgId, false, true));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,47 +294,120 @@ void NewsFeed::handleChannelEvent(std::shared_ptr<const RsEvent> event)
|
|||||||
|
|
||||||
void NewsFeed::handleCircleEvent(std::shared_ptr<const RsEvent> event)
|
void NewsFeed::handleCircleEvent(std::shared_ptr<const RsEvent> event)
|
||||||
{
|
{
|
||||||
|
// Gives the backend a few secs to load the cache data while not blocking the UI. This is not so nice, but there's no proper
|
||||||
|
// other way to do that.
|
||||||
|
|
||||||
|
RsThread::async( [event,this]()
|
||||||
|
{
|
||||||
const RsGxsCircleEvent *pe = dynamic_cast<const RsGxsCircleEvent*>(event.get());
|
const RsGxsCircleEvent *pe = dynamic_cast<const RsGxsCircleEvent*>(event.get());
|
||||||
if(!pe)
|
if(!pe)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RsGxsCircleDetails details;
|
|
||||||
|
|
||||||
if(pe->mCircleId.isNull()) // probably an item for cache update
|
if(pe->mCircleId.isNull()) // probably an item for cache update
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
if(!rsGxsCircles->getCircleDetails(pe->mCircleId,details))
|
RsGxsCircleDetails details;
|
||||||
|
bool loaded = false;
|
||||||
|
|
||||||
|
for(int i=0;i<5 && !loaded;++i)
|
||||||
|
if(rsGxsCircles->getCircleDetails(pe->mCircleId,details))
|
||||||
|
{
|
||||||
|
std::cerr << "Cache item loaded for circle " << pe->mCircleId << std::endl;
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "Cache item for circle " << pe->mCircleId << " not loaded. Waiting " << i << "s" << std::endl;
|
||||||
|
rstime::rs_usleep(1000*1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!loaded)
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl;
|
std::cerr << "(EE) Cannot get information about circle " << pe->mCircleId << ". Not in cache?" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the circle is one of which we belong to. If so, then notify in the GUI about other members leaving/subscribing
|
if(!details.isGxsIdBased()) // not handled yet.
|
||||||
|
return;
|
||||||
|
|
||||||
if(details.mAmIAllowed || details.mAmIAdmin)
|
// Check if the circle is one of which we belong to or we are an admin of.
|
||||||
|
// If so, then notify in the GUI about other members leaving/subscribing, according
|
||||||
|
// to the following rules. The names correspond to the RS_FEED_CIRCLE_* variables:
|
||||||
|
//
|
||||||
|
// Message-based notifications:
|
||||||
|
//
|
||||||
|
// +---------------------------+----------------------------+
|
||||||
|
// | Membership request | Membership cancellation |
|
||||||
|
// +-------------+-------------+-------------+--------------+
|
||||||
|
// | Admin | Not admin | Admin | Not admin |
|
||||||
|
// +--------------------+-------------+-------------+----------------------------+
|
||||||
|
// | in invitee list | MEMB_JOIN | MEMB_JOIN | MEMB_LEAVE | MEMB_LEAVE |
|
||||||
|
// +--------------------+-------------+-------------+-------------+--------------+
|
||||||
|
// |not in invitee list | MEMB_REQ | X | X | X |
|
||||||
|
// +--------------------+-------------+-------------+-------------+--------------+
|
||||||
|
//
|
||||||
|
// Note: in this case, the GxsId never belongs to you, since you dont need to handle
|
||||||
|
// notifications for actions you took yourself (leave/join a circle)
|
||||||
|
//
|
||||||
|
// GroupData-based notifications, the GxsId belongs to you:
|
||||||
|
//
|
||||||
|
// +---------------------------+----------------------------+
|
||||||
|
// | GxsId joins invitee list | GxsId leaves invitee list |
|
||||||
|
// +-------------+-------------+-------------+--------------+
|
||||||
|
// | Id is yours| Id is not | Id is yours | Id is not |
|
||||||
|
// +--------------------+-------------+-------------+-------------+--------------+
|
||||||
|
// | Has Member request | MEMB_ACCEPT | (MEMB_JOIN) | MEMB_REVOKED| (MEMB_LEAVE) |
|
||||||
|
// +--------------------+-------------+-------------+-------------+--------------+
|
||||||
|
// | No Member request | INVITE_REC | X | INVITE_REM | X |
|
||||||
|
// +--------------------+-------------+-------------+-------------+--------------+
|
||||||
|
//
|
||||||
|
// Note: In this case you're never an admin of the circle, since these notification
|
||||||
|
// would be a direct consequence of your own actions.
|
||||||
|
|
||||||
|
RsQThreadUtils::postToObject( [event,details,this]()
|
||||||
{
|
{
|
||||||
|
const RsGxsCircleEvent *pe = static_cast<const RsGxsCircleEvent*>(event.get());
|
||||||
|
|
||||||
switch(pe->mCircleEventType)
|
switch(pe->mCircleEventType)
|
||||||
{
|
{
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REQUEST:
|
||||||
// only show membership requests if we're an admin of that circle
|
// only show membership requests if we're an admin of that circle
|
||||||
if(details.mAmIAdmin)
|
if(details.isIdInInviteeList(pe->mGxsId))
|
||||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ),true);
|
|
||||||
break;
|
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_JOIN:
|
|
||||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_JOIN),true);
|
||||||
|
else if(details.mAmIAdmin)
|
||||||
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REQ),true);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_LEAVE:
|
||||||
|
|
||||||
|
if(details.isIdInInviteeList(pe->mGxsId))
|
||||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true);
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_LEAVE),true);
|
||||||
break;
|
break;
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_INVITE:
|
|
||||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVIT_REC),true);
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST:
|
||||||
|
if(rsIdentity->isOwnId(pe->mGxsId))
|
||||||
|
{
|
||||||
|
if(details.isIdRequestingMembership(pe->mGxsId))
|
||||||
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED),true);
|
||||||
|
else
|
||||||
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVITE_REC),true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_REVOQUED:
|
|
||||||
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED),true);
|
case RsGxsCircleEventCode::CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST:
|
||||||
|
if(rsIdentity->isOwnId(pe->mGxsId))
|
||||||
|
{
|
||||||
|
if(details.isIdRequestingMembership(pe->mGxsId))
|
||||||
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_MEMB_REVOKED),true);
|
||||||
|
else
|
||||||
|
addFeedItemIfUnique(new GxsCircleItem(this, NEWSFEED_CIRCLELIST, pe->mCircleId, pe->mGxsId, RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED),true);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}, this ); }); // damn!
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewsFeed::handleConnectionEvent(std::shared_ptr<const RsEvent> event)
|
void NewsFeed::handleConnectionEvent(std::shared_ptr<const RsEvent> event)
|
||||||
|
@ -31,8 +31,10 @@
|
|||||||
|
|
||||||
const uint32_t NEWSFEED_PEERLIST = 0x0001;
|
const uint32_t NEWSFEED_PEERLIST = 0x0001;
|
||||||
|
|
||||||
const uint32_t NEWSFEED_FORUMNEWLIST = 0x0002;
|
const uint32_t NEWSFEED_NEW_FORUM = 0x0002;
|
||||||
const uint32_t NEWSFEED_FORUMMSGLIST = 0x0003;
|
const uint32_t NEWSFEED_NEW_FORUM_MSG = 0x0003;
|
||||||
|
const uint32_t NEWSFEED_UPDATED_FORUM = 0x000f;
|
||||||
|
|
||||||
const uint32_t NEWSFEED_CHANNELNEWLIST = 0x0004;
|
const uint32_t NEWSFEED_CHANNELNEWLIST = 0x0004;
|
||||||
//const uint32_t NEWSFEED_CHANNELMSGLIST = 0x0005;
|
//const uint32_t NEWSFEED_CHANNELMSGLIST = 0x0005;
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -271,25 +271,29 @@ void PeopleDialog::insertCircles(uint32_t token)
|
|||||||
std::list<RsGroupMetaData> gSummaryList;
|
std::list<RsGroupMetaData> gSummaryList;
|
||||||
std::list<RsGroupMetaData>::iterator gsIt;
|
std::list<RsGroupMetaData>::iterator gsIt;
|
||||||
|
|
||||||
if (!rsGxsCircles->getGroupSummary(token,gSummaryList)) {
|
if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
|
||||||
|
{
|
||||||
std::cerr << "PeopleDialog::insertExtCircles() Error getting GroupSummary";
|
std::cerr << "PeopleDialog::insertExtCircles() Error getting GroupSummary";
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}//if (!rsGxsCircles->getGroupSummary(token,gSummaryList))
|
}
|
||||||
|
|
||||||
for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt) {
|
for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt) {
|
||||||
RsGroupMetaData gsItem = (*gsIt);
|
RsGroupMetaData gsItem = (*gsIt);
|
||||||
|
|
||||||
RsGxsCircleDetails details ;
|
RsGxsCircleDetails details ;
|
||||||
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details)){
|
if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(gsItem.mGroupId), details))
|
||||||
|
{
|
||||||
std::cerr << "(EE) Cannot get details for circle id " << gsItem.mGroupId << ". Circle item is not created!" << std::endl;
|
std::cerr << "(EE) Cannot get details for circle id " << gsItem.mGroupId << ". Circle item is not created!" << std::endl;
|
||||||
continue ;
|
continue ;
|
||||||
}//if(!rsGxsCircles->getCircleDetails(RsGxsCircleId(git->mGroupId), details))
|
}
|
||||||
|
|
||||||
if (details.mCircleType != GXS_CIRCLE_TYPE_EXTERNAL){
|
if (details.mCircleType != RsGxsCircleType::EXTERNAL)
|
||||||
|
{
|
||||||
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
|
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
|
||||||
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end()) {
|
if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
|
||||||
|
{
|
||||||
std::cerr << "PeopleDialog::insertExtCircles() add new Internal GroupId: " << gsItem.mGroupId;
|
std::cerr << "PeopleDialog::insertExtCircles() add new Internal GroupId: " << gsItem.mGroupId;
|
||||||
std::cerr << " GroupName: " << gsItem.mGroupName;
|
std::cerr << " GroupName: " << gsItem.mGroupName;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -307,7 +311,9 @@ void PeopleDialog::insertCircles(uint32_t token)
|
|||||||
QPixmap pixmap = gitem->getImage();
|
QPixmap pixmap = gitem->getImage();
|
||||||
pictureFlowWidgetInternal->addSlide( pixmap );
|
pictureFlowWidgetInternal->addSlide( pixmap );
|
||||||
_intListCir << gitem;
|
_intListCir << gitem;
|
||||||
} else {//if((itFound=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
|
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
|
||||||
std::cerr << " GroupName: " << gsItem.mGroupName;
|
std::cerr << " GroupName: " << gsItem.mGroupName;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -318,8 +324,10 @@ void PeopleDialog::insertCircles(uint32_t token)
|
|||||||
//int index = _intListCir.indexOf(cirWidget);
|
//int index = _intListCir.indexOf(cirWidget);
|
||||||
//QPixmap pixmap = cirWidget->getImage();
|
//QPixmap pixmap = cirWidget->getImage();
|
||||||
//pictureFlowWidgetInternal->setSlide(index, pixmap);
|
//pictureFlowWidgetInternal->setSlide(index, pixmap);
|
||||||
}//if((item=_int_circles_widgets.find(gsItem.mGroupId)) == _int_circles_widgets.end())
|
}
|
||||||
} else {//if (!details.mIsExternal)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
|
std::map<RsGxsGroupId, CircleWidget*>::iterator itFound;
|
||||||
if((itFound=_ext_circles_widgets.find(gsItem.mGroupId)) == _ext_circles_widgets.end()) {
|
if((itFound=_ext_circles_widgets.find(gsItem.mGroupId)) == _ext_circles_widgets.end()) {
|
||||||
std::cerr << "PeopleDialog::insertExtCircles() add new GroupId: " << gsItem.mGroupId;
|
std::cerr << "PeopleDialog::insertExtCircles() add new GroupId: " << gsItem.mGroupId;
|
||||||
@ -339,7 +347,9 @@ void PeopleDialog::insertCircles(uint32_t token)
|
|||||||
QPixmap pixmap = gitem->getImage();
|
QPixmap pixmap = gitem->getImage();
|
||||||
pictureFlowWidgetExternal->addSlide( pixmap );
|
pictureFlowWidgetExternal->addSlide( pixmap );
|
||||||
_extListCir << gitem;
|
_extListCir << gitem;
|
||||||
} else {//if((itFound=_circles_widgets.find(gsItem.mGroupId)) == _circles_widgets.end())
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
|
std::cerr << "PeopleDialog::insertExtCircles() Update GroupId: " << gsItem.mGroupId;
|
||||||
std::cerr << " GroupName: " << gsItem.mGroupName;
|
std::cerr << " GroupName: " << gsItem.mGroupName;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
@ -350,9 +360,9 @@ void PeopleDialog::insertCircles(uint32_t token)
|
|||||||
//int index = _extListCir.indexOf(cirWidget);
|
//int index = _extListCir.indexOf(cirWidget);
|
||||||
//QPixmap pixmap = cirWidget->getImage();
|
//QPixmap pixmap = cirWidget->getImage();
|
||||||
//pictureFlowWidgetExternal->setSlide(index, pixmap);
|
//pictureFlowWidgetExternal->setSlide(index, pixmap);
|
||||||
}//if((item=_circles_items.find(gsItem.mGroupId)) == _circles_items.end())
|
}
|
||||||
}//else (!details.mIsExternal)
|
}
|
||||||
}//for(gsIt = gSummaryList.begin(); gsIt != gSummaryList.end(); ++gsIt)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeopleDialog::requestIdList()
|
void PeopleDialog::requestIdList()
|
||||||
|
@ -167,8 +167,9 @@ void BasePostedItem::loadMessage()
|
|||||||
|
|
||||||
std::vector<RsPostedPost> posts;
|
std::vector<RsPostedPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
if(! rsPosted->getBoardContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments))
|
if(! rsPosted->getBoardContent( groupId(), std::set<RsGxsMessageId>( { messageId() } ),posts,comments,votes))
|
||||||
{
|
{
|
||||||
RsErr() << "BasePostedItem::loadMessage() ERROR getting data" << std::endl;
|
RsErr() << "BasePostedItem::loadMessage() ERROR getting data" << std::endl;
|
||||||
mIsLoadingMessage = false;
|
mIsLoadingMessage = false;
|
||||||
@ -227,8 +228,9 @@ void BasePostedItem::loadComment()
|
|||||||
|
|
||||||
std::vector<RsPostedPost> posts;
|
std::vector<RsPostedPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
if(! rsPosted->getBoardContent( groupId(),msgIds,posts,comments))
|
if(! rsPosted->getBoardContent( groupId(),msgIds,posts,comments,votes))
|
||||||
{
|
{
|
||||||
RsErr() << "BasePostedItem::loadGroup() ERROR getting data" << std::endl;
|
RsErr() << "BasePostedItem::loadGroup() ERROR getting data" << std::endl;
|
||||||
mIsLoadingComment = false;
|
mIsLoadingComment = false;
|
||||||
|
@ -1033,8 +1033,9 @@ void PostedListWidget::getMsgData(const std::set<RsGxsMessageId>& msgIds,std::ve
|
|||||||
{
|
{
|
||||||
std::vector<RsPostedPost> posts;
|
std::vector<RsPostedPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
rsPosted->getBoardContent( groupId(),msgIds,posts,comments );
|
rsPosted->getBoardContent( groupId(),msgIds,posts,comments,votes );
|
||||||
|
|
||||||
psts.clear();
|
psts.clear();
|
||||||
|
|
||||||
@ -1046,8 +1047,9 @@ void PostedListWidget::getAllMsgData(std::vector<RsGxsGenericMsgData*>& psts)
|
|||||||
{
|
{
|
||||||
std::vector<RsPostedPost> posts;
|
std::vector<RsPostedPost> posts;
|
||||||
std::vector<RsGxsComment> comments;
|
std::vector<RsGxsComment> comments;
|
||||||
|
std::vector<RsGxsVote> votes;
|
||||||
|
|
||||||
rsPosted->getBoardAllContent( groupId(),posts,comments );
|
rsPosted->getBoardAllContent( groupId(),posts,comments,votes );
|
||||||
|
|
||||||
psts.clear();
|
psts.clear();
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "retroshare/rsposted.h"
|
#include "retroshare/rsposted.h"
|
||||||
#include "PostedUserNotify.h"
|
#include "PostedUserNotify.h"
|
||||||
#include "gui/MainWindow.h"
|
#include "gui/MainWindow.h"
|
||||||
|
#include "gui/common/FilesDefs.h"
|
||||||
|
|
||||||
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
|
PostedUserNotify::PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent) :
|
||||||
GxsUserNotify(ifaceImpl, g, parent)
|
GxsUserNotify(ifaceImpl, g, parent)
|
||||||
@ -37,12 +38,12 @@ bool PostedUserNotify::hasSetting(QString *name, QString *group)
|
|||||||
|
|
||||||
QIcon PostedUserNotify::getIcon()
|
QIcon PostedUserNotify::getIcon()
|
||||||
{
|
{
|
||||||
return QIcon(":/icons/png/posted.png");
|
return FilesDefs::getIconFromQtResourcePath(":/icons/png/posted.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon PostedUserNotify::getMainIcon(bool hasNew)
|
QIcon PostedUserNotify::getMainIcon(bool hasNew)
|
||||||
{
|
{
|
||||||
return hasNew ? QIcon(":/icons/png/posted-notify.png") : QIcon(":/icons/png/posted.png");
|
return hasNew ? FilesDefs::getIconFromQtResourcePath(":/icons/png/posted-notify.png") : FilesDefs::getIconFromQtResourcePath(":/icons/png/posted.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostedUserNotify::iconClicked()
|
void PostedUserNotify::iconClicked()
|
||||||
|
@ -31,6 +31,7 @@ public:
|
|||||||
PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
|
PostedUserNotify(RsGxsIfaceHelper *ifaceImpl, const GxsGroupFrameDialog *g, QObject *parent = 0);
|
||||||
|
|
||||||
virtual bool hasSetting(QString *name, QString *group);
|
virtual bool hasSetting(QString *name, QString *group);
|
||||||
|
virtual QString textInfo() const override { return tr("new board post(s)"); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual QIcon getIcon();
|
virtual QIcon getIcon();
|
||||||
|
@ -335,12 +335,13 @@ QString RetroshareDirModel::getAgeIndicatorString(const DirDetails &details) con
|
|||||||
const QIcon& RetroshareDirModel::getFlagsIcon(FileStorageFlags flags)
|
const QIcon& RetroshareDirModel::getFlagsIcon(FileStorageFlags flags)
|
||||||
{
|
{
|
||||||
static QIcon *static_icons[8] = {NULL};
|
static QIcon *static_icons[8] = {NULL};
|
||||||
|
if(static_icons[0] == NULL)
|
||||||
|
static_icons[0] = new QIcon();
|
||||||
|
|
||||||
int n=0;
|
int n=0;
|
||||||
if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) n += 1 ;
|
if(flags & DIR_FLAGS_ANONYMOUS_DOWNLOAD) n += 1 ;
|
||||||
if(flags & DIR_FLAGS_ANONYMOUS_SEARCH ) n += 2 ;
|
if(flags & DIR_FLAGS_ANONYMOUS_SEARCH ) n += 2 ;
|
||||||
if(flags & DIR_FLAGS_BROWSABLE ) n += 4 ;
|
if(flags & DIR_FLAGS_BROWSABLE ) n += 4 ;
|
||||||
n-= 1;
|
|
||||||
|
|
||||||
if(static_icons[n] == NULL)
|
if(static_icons[n] == NULL)
|
||||||
{
|
{
|
||||||
|
@ -250,19 +250,21 @@ void ShareManager::load()
|
|||||||
|
|
||||||
listWidget->item(row,COLUMN_GROUPS)->setText(getGroupString(mDirInfos[row].parent_groups));
|
listWidget->item(row,COLUMN_GROUPS)->setText(getGroupString(mDirInfos[row].parent_groups));
|
||||||
|
|
||||||
|
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||||
|
// As palette is not updated by stylesheet
|
||||||
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
|
QFont font = listWidget->item(row,COLUMN_GROUPS)->font();
|
||||||
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
|
font.setBold(mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ;
|
||||||
listWidget->item(row,COLUMN_GROUPS)->setTextColor( (mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE)? (Qt::black):(Qt::lightGray)) ;
|
listWidget->item(row,COLUMN_GROUPS)->setData(Qt::ForegroundRole, QColor((mDirInfos[row].shareflags & DIR_FLAGS_BROWSABLE) ? (Qt::black):(Qt::lightGray)) );
|
||||||
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
|
listWidget->item(row,COLUMN_GROUPS)->setFont(font);
|
||||||
|
|
||||||
if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists())
|
if(QDir(QString::fromUtf8(mDirInfos[row].filename.c_str())).exists())
|
||||||
{
|
{
|
||||||
listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::black);
|
listWidget->item(row,COLUMN_PATH)->setData(Qt::ForegroundRole, QColor(Qt::black));
|
||||||
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Double click to change shared directory path")) ;
|
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Double click to change shared directory path")) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
listWidget->item(row,COLUMN_PATH)->setTextColor(Qt::lightGray);
|
listWidget->item(row,COLUMN_PATH)->setData(Qt::ForegroundRole, QColor(Qt::lightGray));
|
||||||
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Directory does not exist! Double click to change shared directory path")) ;
|
listWidget->item(row,COLUMN_PATH)->setToolTip(tr("Directory does not exist! Double click to change shared directory path")) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,14 @@
|
|||||||
#define ROLE_SORT Qt::UserRole + 1
|
#define ROLE_SORT Qt::UserRole + 1
|
||||||
|
|
||||||
const static uint32_t timeToInactivity = 60 * 10; // in seconds
|
const static uint32_t timeToInactivity = 60 * 10; // in seconds
|
||||||
|
const static uint32_t timeToInactivity2 = 60 * 5; // in seconds
|
||||||
|
|
||||||
/** Default constructor */
|
/** Default constructor */
|
||||||
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
|
ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WindowFlags flags)
|
||||||
: ChatDialog(parent, flags), lobbyId(lid), mWindowedSetted(false), mPCWindow(nullptr),
|
: ChatDialog(parent, flags), lobbyId(lid), mWindowedSetted(false), mPCWindow(nullptr),
|
||||||
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
|
bullet_red_128(":/icons/bullet_red_128.png"), bullet_grey_128(":/icons/bullet_grey_128.png"),
|
||||||
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png")
|
bullet_green_128(":/icons/bullet_green_128.png"), bullet_yellow_128(":/icons/bullet_yellow_128.png"),
|
||||||
|
bullet_blue_128(":/icons/bullet_blue_128.png")
|
||||||
{
|
{
|
||||||
/* Invoke Qt Designer generated QObject setup routine */
|
/* Invoke Qt Designer generated QObject setup routine */
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
@ -614,10 +616,12 @@ void ChatLobbyDialog::updateParticipantsList()
|
|||||||
else
|
else
|
||||||
widgetitem = dynamic_cast<GxsIdRSTreeWidgetItem*>(qlFoundParticipants.at(0));
|
widgetitem = dynamic_cast<GxsIdRSTreeWidgetItem*>(qlFoundParticipants.at(0));
|
||||||
|
|
||||||
|
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||||
|
// As palette is not updated by stylesheet
|
||||||
if (isParticipantMuted(it2->first)) {
|
if (isParticipantMuted(it2->first)) {
|
||||||
widgetitem->setTextColor(COLUMN_NAME,QColor(255,0,0));
|
widgetitem->setData(COLUMN_NAME, Qt::ForegroundRole, QColor(255,0,0));
|
||||||
} else {
|
} else {
|
||||||
widgetitem->setTextColor(COLUMN_NAME,ui.participantsList->palette().color(QPalette::Active, QPalette::Text));
|
widgetitem->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
|
time_t tLastAct=widgetitem->text(COLUMN_ACTIVITY).toInt();
|
||||||
@ -630,13 +634,15 @@ void ChatLobbyDialog::updateParticipantsList()
|
|||||||
widgetitem->setIcon(COLUMN_ICON, bullet_red_128);
|
widgetitem->setIcon(COLUMN_ICON, bullet_red_128);
|
||||||
else if (tLastAct + timeToInactivity < now)
|
else if (tLastAct + timeToInactivity < now)
|
||||||
widgetitem->setIcon(COLUMN_ICON, bullet_grey_128);
|
widgetitem->setIcon(COLUMN_ICON, bullet_grey_128);
|
||||||
|
else if (tLastAct + timeToInactivity2 < now)
|
||||||
|
widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
|
||||||
else
|
else
|
||||||
widgetitem->setIcon(COLUMN_ICON, bullet_green_128);
|
widgetitem->setIcon(COLUMN_ICON, bullet_green_128);
|
||||||
|
|
||||||
RsGxsId gxs_id;
|
RsGxsId gxs_id;
|
||||||
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
|
rsMsgs->getIdentityForChatLobby(lobbyId, gxs_id);
|
||||||
|
|
||||||
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_yellow_128);
|
if (RsGxsId(participant.toStdString()) == gxs_id) widgetitem->setIcon(COLUMN_ICON, bullet_blue_128);
|
||||||
|
|
||||||
widgetitem->updateBannedState();
|
widgetitem->updateBannedState();
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ private:
|
|||||||
|
|
||||||
GxsIdChooser *ownIdChooser ;
|
GxsIdChooser *ownIdChooser ;
|
||||||
//icons cache
|
//icons cache
|
||||||
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128;
|
QIcon bullet_red_128, bullet_grey_128, bullet_green_128, bullet_yellow_128, bullet_blue_128;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,6 +63,7 @@ public:
|
|||||||
QString textToNotify() { return _textToNotify.join("\n");}
|
QString textToNotify() { return _textToNotify.join("\n");}
|
||||||
void setTextCaseSensitive(bool value);
|
void setTextCaseSensitive(bool value);
|
||||||
bool isTextCaseSensitive() {return _bTextCaseSensitive;}
|
bool isTextCaseSensitive() {return _bTextCaseSensitive;}
|
||||||
|
virtual QString textInfo() const override { return tr("mention(s)"); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void countChanged(ChatLobbyId id, unsigned int count);
|
void countChanged(ChatLobbyId id, unsigned int count);
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
~ChatUserNotify();
|
~ChatUserNotify();
|
||||||
|
|
||||||
virtual bool hasSetting(QString *name, QString *group);
|
virtual bool hasSetting(QString *name, QString *group);
|
||||||
|
virtual QString textInfo() const override { return tr("mention(s)"); }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void chatMessageReceived(ChatMessage msg);
|
void chatMessageReceived(ChatMessage msg);
|
||||||
|
@ -115,6 +115,7 @@ ChatWidget::ChatWidget(QWidget *parent)
|
|||||||
//ui->sendButton->setFixedHeight(iconHeight);
|
//ui->sendButton->setFixedHeight(iconHeight);
|
||||||
ui->sendButton->setIconSize(iconSize);
|
ui->sendButton->setIconSize(iconSize);
|
||||||
ui->typingLabel->setMaximumHeight(QFontMetricsF(font()).height()*1.2);
|
ui->typingLabel->setMaximumHeight(QFontMetricsF(font()).height()*1.2);
|
||||||
|
ui->fontcolorButton->setIconSize(iconSize);
|
||||||
|
|
||||||
//Initialize search
|
//Initialize search
|
||||||
iCharToStartSearch=Settings->getChatSearchCharToStartSearch();
|
iCharToStartSearch=Settings->getChatSearchCharToStartSearch();
|
||||||
@ -189,7 +190,7 @@ ChatWidget::ChatWidget(QWidget *parent)
|
|||||||
ui->hashBox->setDropWidget(this);
|
ui->hashBox->setDropWidget(this);
|
||||||
ui->hashBox->setAutoHide(true);
|
ui->hashBox->setAutoHide(true);
|
||||||
|
|
||||||
QMenu *fontmenu = new QMenu(tr("Set text font & color"));
|
QMenu *fontmenu = new QMenu();
|
||||||
fontmenu->addAction(ui->actionChooseFont);
|
fontmenu->addAction(ui->actionChooseFont);
|
||||||
fontmenu->addAction(ui->actionChooseColor);
|
fontmenu->addAction(ui->actionChooseColor);
|
||||||
fontmenu->addAction(ui->actionResetFont);
|
fontmenu->addAction(ui->actionResetFont);
|
||||||
@ -198,10 +199,10 @@ ChatWidget::ChatWidget(QWidget *parent)
|
|||||||
#ifdef USE_CMARK
|
#ifdef USE_CMARK
|
||||||
fontmenu->addAction(ui->actionSend_as_CommonMark);
|
fontmenu->addAction(ui->actionSend_as_CommonMark);
|
||||||
#endif
|
#endif
|
||||||
|
ui->fontcolorButton->setMenu(fontmenu);
|
||||||
|
|
||||||
QMenu *menu = new QMenu();
|
QMenu *menu = new QMenu();
|
||||||
menu->addAction(ui->actionMessageHistory);
|
menu->addAction(ui->actionMessageHistory);
|
||||||
menu->addMenu(fontmenu);
|
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addAction(ui->actionSaveChatHistory);
|
menu->addAction(ui->actionSaveChatHistory);
|
||||||
menu->addAction(ui->actionClearChatHistory);
|
menu->addAction(ui->actionClearChatHistory);
|
||||||
|
@ -455,13 +455,13 @@ border-image: url(:/images/closepressed.png)
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="notifyButton">
|
<widget class="QToolButton" name="fontcolorButton">
|
||||||
<property name="focusPolicy">
|
<property name="toolTip">
|
||||||
<enum>Qt::NoFocus</enum>
|
<string>Set font & color</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../icons.qrc">
|
<iconset resource="../icons.qrc">
|
||||||
<normaloff>:/icons/png/chat-bubble-notify.png</normaloff>:/icons/png/chat-bubble-notify.png</iconset>
|
<normaloff>:/icons/png/font.png</normaloff>:/icons/png/font.png</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSize">
|
<property name="iconSize">
|
||||||
<size>
|
<size>
|
||||||
@ -469,6 +469,9 @@ border-image: url(:/images/closepressed.png)
|
|||||||
<height>28</height>
|
<height>28</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="popupMode">
|
||||||
|
<enum>QToolButton::InstantPopup</enum>
|
||||||
|
</property>
|
||||||
<property name="autoRaise">
|
<property name="autoRaise">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
@ -769,6 +772,26 @@ border-image: url(:/images/closepressed.png)
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="notifyButton">
|
||||||
|
<property name="focusPolicy">
|
||||||
|
<enum>Qt::NoFocus</enum>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="../icons.qrc">
|
||||||
|
<normaloff>:/icons/png/chat-bubble-notify.png</normaloff>:/icons/png/chat-bubble-notify.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="iconSize">
|
||||||
|
<size>
|
||||||
|
<width>28</width>
|
||||||
|
<height>28</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="autoRaise">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="pushtoolsButton">
|
<widget class="QToolButton" name="pushtoolsButton">
|
||||||
<property name="focusPolicy">
|
<property name="focusPolicy">
|
||||||
|
@ -239,7 +239,10 @@ bool ElidedLabel::paintElidedLine( QPainter* painter, QString plainText
|
|||||||
*rectElision = mRectElision;
|
*rectElision = mRectElision;
|
||||||
|
|
||||||
if(drawRoundedRect)
|
if(drawRoundedRect)
|
||||||
if (painter) painter->drawRoundedRect(mRectElision, 2 , 2);
|
if (painter) {
|
||||||
|
painter->setBrush(QBrush(Qt::transparent));
|
||||||
|
painter->drawRoundedRect(mRectElision, 2 , 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (painter) painter->restore();
|
if (painter) painter->restore();
|
||||||
|
@ -717,7 +717,7 @@ void FriendList::insertPeers()
|
|||||||
groupItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
groupItem->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
|
||||||
groupItem->setTextAlignment(COLUMN_NAME, Qt::AlignLeft | Qt::AlignVCenter);
|
groupItem->setTextAlignment(COLUMN_NAME, Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
groupItem->setIcon(COLUMN_NAME, QIcon(IMAGE_GROUP24));
|
groupItem->setIcon(COLUMN_NAME, QIcon(IMAGE_GROUP24));
|
||||||
groupItem->setForeground(COLUMN_NAME, QBrush(textColorGroup()));
|
groupItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorGroup());
|
||||||
|
|
||||||
/* used to find back the item */
|
/* used to find back the item */
|
||||||
QString strID = QString::fromStdString(groupInfo->id.toStdString());
|
QString strID = QString::fromStdString(groupInfo->id.toStdString());
|
||||||
@ -1110,8 +1110,8 @@ void FriendList::insertPeers()
|
|||||||
for (int i = 0; i < columnCount; ++i) {
|
for (int i = 0; i < columnCount; ++i) {
|
||||||
sslItem->setData(i, ROLE_SORT_STATE, peerState);
|
sslItem->setData(i, ROLE_SORT_STATE, peerState);
|
||||||
|
|
||||||
sslItem->setTextColor(i, sslColor);
|
sslItem->setData(i, Qt::ForegroundRole, sslColor);
|
||||||
sslItem->setFont(i, sslFont);
|
sslItem->setData(i, Qt::FontRole, sslFont);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,8 +1222,8 @@ void FriendList::insertPeers()
|
|||||||
for (int i = 0; i < columnCount; ++i) {
|
for (int i = 0; i < columnCount; ++i) {
|
||||||
gpgItem->setData(i, ROLE_SORT_STATE, bestPeerState);
|
gpgItem->setData(i, ROLE_SORT_STATE, bestPeerState);
|
||||||
|
|
||||||
gpgItem->setTextColor(i, gpgColor);
|
gpgItem->setData(i, Qt::ForegroundRole, gpgColor);
|
||||||
gpgItem->setFont(i, gpgFont);
|
gpgItem->setData(i, Qt::FontRole, gpgFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (openPeers.find(gpgId) != openPeers.end()) {
|
if (openPeers.find(gpgId) != openPeers.end()) {
|
||||||
|
@ -100,7 +100,7 @@ FriendSelectionDialog::FriendSelectionDialog(QWidget *parent,const QString& head
|
|||||||
friends_widget->setModus(modus) ;
|
friends_widget->setModus(modus) ;
|
||||||
friends_widget->setShowType(show_type) ;
|
friends_widget->setShowType(show_type) ;
|
||||||
friends_widget->start() ;
|
friends_widget->start() ;
|
||||||
friends_widget->setSelectedIds(pre_selected_id_type, pre_selected_ids, false);
|
friends_widget->setSelectedIdsFromString(pre_selected_id_type, pre_selected_ids, false);
|
||||||
|
|
||||||
QLayout *l = new QVBoxLayout ;
|
QLayout *l = new QVBoxLayout ;
|
||||||
setLayout(l) ;
|
setLayout(l) ;
|
||||||
|
@ -215,7 +215,7 @@ static void initSslItem(QTreeWidgetItem *item, const RsPeerDetails &detail, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state != (int) RS_STATUS_OFFLINE) {
|
if (state != (int) RS_STATUS_OFFLINE) {
|
||||||
item->setTextColor(COLUMN_NAME, textColorOnline);
|
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline);
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(state)));
|
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(state)));
|
||||||
@ -278,18 +278,35 @@ void FriendSelectionWidget::secured_fillList()
|
|||||||
|
|
||||||
// get selected items
|
// get selected items
|
||||||
std::set<RsPeerId> sslIdsSelected;
|
std::set<RsPeerId> sslIdsSelected;
|
||||||
if (mShowTypes & SHOW_SSL) {
|
if (mShowTypes & SHOW_SSL)
|
||||||
|
{
|
||||||
|
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||||
|
for(auto& s:mPreSelectedIds)
|
||||||
|
sslIdsSelected.insert(RsPeerId(s));
|
||||||
|
|
||||||
selectedIds<RsPeerId,IDTYPE_SSL>(sslIdsSelected,true);
|
selectedIds<RsPeerId,IDTYPE_SSL>(sslIdsSelected,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<RsNodeGroupId> groupIdsSelected;
|
std::set<RsNodeGroupId> groupIdsSelected;
|
||||||
if (mShowTypes & SHOW_GROUP) {
|
|
||||||
|
if (mShowTypes & SHOW_GROUP)
|
||||||
|
{
|
||||||
selectedIds<RsNodeGroupId,IDTYPE_GROUP>(groupIdsSelected,true);
|
selectedIds<RsNodeGroupId,IDTYPE_GROUP>(groupIdsSelected,true);
|
||||||
|
|
||||||
|
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||||
|
for(auto& s:mPreSelectedIds)
|
||||||
|
groupIdsSelected.insert(RsNodeGroupId(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<RsPgpId> gpgIdsSelected;
|
std::set<RsPgpId> gpgIdsSelected;
|
||||||
if (mShowTypes & (SHOW_GPG | SHOW_NON_FRIEND_GPG)) {
|
|
||||||
|
if (mShowTypes & (SHOW_GPG | SHOW_NON_FRIEND_GPG))
|
||||||
|
{
|
||||||
selectedIds<RsPgpId,IDTYPE_GPG>(gpgIdsSelected,true);
|
selectedIds<RsPgpId,IDTYPE_GPG>(gpgIdsSelected,true);
|
||||||
|
|
||||||
|
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||||
|
for(auto& s:mPreSelectedIds)
|
||||||
|
gpgIdsSelected.insert(RsPgpId(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<RsGxsId> gxsIdsSelected;
|
std::set<RsGxsId> gxsIdsSelected;
|
||||||
@ -299,7 +316,8 @@ void FriendSelectionWidget::secured_fillList()
|
|||||||
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected,true);
|
selectedIds<RsGxsId,IDTYPE_GXS>(gxsIdsSelected,true);
|
||||||
|
|
||||||
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
if(!ui->friendList->topLevelItemCount()) // if not loaded yet, use the existing list.
|
||||||
gxsIdsSelected = mPreSelectedGxsIds;
|
for(auto& s:mPreSelectedIds)
|
||||||
|
gxsIdsSelected.insert(RsGxsId(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<RsGxsId> gxsIdsSelected2;
|
std::set<RsGxsId> gxsIdsSelected2;
|
||||||
@ -434,7 +452,7 @@ void FriendSelectionWidget::secured_fillList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (state != (int) RS_STATUS_OFFLINE) {
|
if (state != (int) RS_STATUS_OFFLINE) {
|
||||||
gpgItem->setTextColor(COLUMN_NAME, textColorOnline());
|
gpgItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||||
}
|
}
|
||||||
|
|
||||||
gpgItem->setFlags(Qt::ItemIsUserCheckable | gpgItem->flags());
|
gpgItem->setFlags(Qt::ItemIsUserCheckable | gpgItem->flags());
|
||||||
@ -571,7 +589,7 @@ void FriendSelectionWidget::secured_fillList()
|
|||||||
QString name = QString::fromUtf8(detail.mNickname.c_str());
|
QString name = QString::fromUtf8(detail.mNickname.c_str());
|
||||||
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
|
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
|
||||||
|
|
||||||
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
|
//gxsItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||||
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
|
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
|
||||||
gxsItem->setIcon(COLUMN_NAME, identicon);
|
gxsItem->setIcon(COLUMN_NAME, identicon);
|
||||||
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
|
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
|
||||||
@ -625,7 +643,7 @@ void FriendSelectionWidget::secured_fillList()
|
|||||||
QString name = QString::fromUtf8(detail.mNickname.c_str());
|
QString name = QString::fromUtf8(detail.mNickname.c_str());
|
||||||
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
|
gxsItem->setText(COLUMN_NAME, name + " ("+QString::fromStdString( (*gxsIt).toStdString() )+")");
|
||||||
|
|
||||||
//gxsItem->setTextColor(COLUMN_NAME, textColorOnline());
|
//gxsItem->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||||
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
|
gxsItem->setFlags(Qt::ItemIsUserCheckable | gxsItem->flags());
|
||||||
gxsItem->setIcon(COLUMN_NAME, identicon);
|
gxsItem->setIcon(COLUMN_NAME, identicon);
|
||||||
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
|
gxsItem->setData(COLUMN_DATA, ROLE_ID, QString::fromStdString(detail.mId.toStdString()));
|
||||||
@ -678,7 +696,12 @@ void FriendSelectionWidget::updateDisplay(bool)
|
|||||||
// This call is inlined so that there's no linking conflict with MinGW on Windows
|
// This call is inlined so that there's no linking conflict with MinGW on Windows
|
||||||
template<> inline void FriendSelectionWidget::setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(const std::set<RsGxsId>& ids, bool add)
|
template<> inline void FriendSelectionWidget::setSelectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(const std::set<RsGxsId>& ids, bool add)
|
||||||
{
|
{
|
||||||
mPreSelectedGxsIds = ids ;
|
if(!add)
|
||||||
|
mPreSelectedIds.clear();
|
||||||
|
|
||||||
|
for(auto& gxsId:ids)
|
||||||
|
mPreSelectedIds.insert(gxsId.toStdString());
|
||||||
|
|
||||||
loadIdentities();
|
loadIdentities();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -746,14 +769,12 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status)
|
|||||||
case IDTYPE_GPG:
|
case IDTYPE_GPG:
|
||||||
{
|
{
|
||||||
if (item->data(COLUMN_DATA, ROLE_ID).toString() == gpgId) {
|
if (item->data(COLUMN_DATA, ROLE_ID).toString() == gpgId) {
|
||||||
QColor color;
|
|
||||||
if (status != (int) RS_STATUS_OFFLINE) {
|
if (status != (int) RS_STATUS_OFFLINE) {
|
||||||
color = textColorOnline();
|
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||||
} else {
|
} else {
|
||||||
color = ui->friendList->palette().color(QPalette::Text);
|
item->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setTextColor(COLUMN_NAME, color);
|
|
||||||
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(gpgStatus)));
|
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(gpgStatus)));
|
||||||
|
|
||||||
item->setData(COLUMN_NAME, ROLE_SORT_STATE, gpgStatus);
|
item->setData(COLUMN_NAME, ROLE_SORT_STATE, gpgStatus);
|
||||||
@ -765,14 +786,12 @@ void FriendSelectionWidget::peerStatusChanged(const QString& peerId, int status)
|
|||||||
case IDTYPE_SSL:
|
case IDTYPE_SSL:
|
||||||
{
|
{
|
||||||
if (item->data(COLUMN_DATA, ROLE_ID).toString() == peerId) {
|
if (item->data(COLUMN_DATA, ROLE_ID).toString() == peerId) {
|
||||||
QColor color;
|
|
||||||
if (status != (int) RS_STATUS_OFFLINE) {
|
if (status != (int) RS_STATUS_OFFLINE) {
|
||||||
color = textColorOnline();
|
item->setData(COLUMN_NAME, Qt::ForegroundRole, textColorOnline());
|
||||||
} else {
|
} else {
|
||||||
color = ui->friendList->palette().color(QPalette::Text);
|
item->setData(COLUMN_NAME, Qt::ForegroundRole, QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setTextColor(COLUMN_NAME, color);
|
|
||||||
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(status)));
|
item->setIcon(COLUMN_NAME, QIcon(StatusDefs::imageUser(status)));
|
||||||
|
|
||||||
item->setData(COLUMN_NAME, ROLE_SORT_STATE, status);
|
item->setData(COLUMN_NAME, ROLE_SORT_STATE, status);
|
||||||
@ -981,7 +1000,7 @@ std::string FriendSelectionWidget::selectedId(IdType &idType)
|
|||||||
return idFromItem(item);
|
return idFromItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FriendSelectionWidget::selectedIds(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected)
|
void FriendSelectionWidget::selectedIds_internal(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected)
|
||||||
{
|
{
|
||||||
QTreeWidgetItemIterator itemIterator(ui->friendList);
|
QTreeWidgetItemIterator itemIterator(ui->friendList);
|
||||||
QTreeWidgetItem *item;
|
QTreeWidgetItem *item;
|
||||||
@ -1055,11 +1074,21 @@ void FriendSelectionWidget::selectAll()
|
|||||||
setSelected(mListModus, *itemIterator, true);
|
setSelected(mListModus, *itemIterator, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FriendSelectionWidget::setSelectedIds(IdType idType, const std::set<std::string> &ids, bool add)
|
void FriendSelectionWidget::setSelectedIdsFromString(IdType type, const std::set<std::string>& ids, bool add)
|
||||||
{
|
{
|
||||||
|
setSelectedIds_internal(type,ids,add);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FriendSelectionWidget::setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add)
|
||||||
|
{
|
||||||
|
mPreSelectedIds = ids;
|
||||||
|
|
||||||
|
// if items are already loaded, check them
|
||||||
|
|
||||||
QTreeWidgetItemIterator itemIterator(ui->friendList);
|
QTreeWidgetItemIterator itemIterator(ui->friendList);
|
||||||
QTreeWidgetItem *item;
|
QTreeWidgetItem *item;
|
||||||
while ((item = *itemIterator) != NULL) {
|
while ((item = *itemIterator) != NULL)
|
||||||
|
{
|
||||||
++itemIterator;
|
++itemIterator;
|
||||||
|
|
||||||
std::string id = idFromItem(item);
|
std::string id = idFromItem(item);
|
||||||
|
@ -85,10 +85,12 @@ public:
|
|||||||
int selectedItemCount();
|
int selectedItemCount();
|
||||||
std::string selectedId(IdType &idType);
|
std::string selectedId(IdType &idType);
|
||||||
|
|
||||||
|
void setSelectedIdsFromString(IdType type,const std::set<std::string>& ids,bool add);
|
||||||
|
|
||||||
template<class ID_CLASS,FriendSelectionWidget::IdType TYPE> void selectedIds(std::set<ID_CLASS>& ids, bool onlyDirectSelected)
|
template<class ID_CLASS,FriendSelectionWidget::IdType TYPE> void selectedIds(std::set<ID_CLASS>& ids, bool onlyDirectSelected)
|
||||||
{
|
{
|
||||||
std::set<std::string> tmpids ;
|
std::set<std::string> tmpids ;
|
||||||
selectedIds(TYPE, tmpids, onlyDirectSelected);
|
selectedIds_internal(TYPE, tmpids, onlyDirectSelected);
|
||||||
ids.clear() ;
|
ids.clear() ;
|
||||||
for(std::set<std::string>::const_iterator it(tmpids.begin());it!=tmpids.end();++it)
|
for(std::set<std::string>::const_iterator it(tmpids.begin());it!=tmpids.end();++it)
|
||||||
ids.insert(ID_CLASS(*it)) ;
|
ids.insert(ID_CLASS(*it)) ;
|
||||||
@ -98,7 +100,7 @@ public:
|
|||||||
std::set<std::string> tmpids ;
|
std::set<std::string> tmpids ;
|
||||||
for(typename std::set<ID_CLASS>::const_iterator it(ids.begin());it!=ids.end();++it)
|
for(typename std::set<ID_CLASS>::const_iterator it(ids.begin());it!=ids.end();++it)
|
||||||
tmpids.insert((*it).toStdString()) ;
|
tmpids.insert((*it).toStdString()) ;
|
||||||
setSelectedIds(TYPE, tmpids, add);
|
setSelectedIds_internal(TYPE, tmpids, add);
|
||||||
}
|
}
|
||||||
|
|
||||||
void itemsFromId(IdType idType, const std::string &id, QList<QTreeWidgetItem*> &items);
|
void itemsFromId(IdType idType, const std::string &id, QList<QTreeWidgetItem*> &items);
|
||||||
@ -145,8 +147,8 @@ private:
|
|||||||
void fillList();
|
void fillList();
|
||||||
void secured_fillList();
|
void secured_fillList();
|
||||||
|
|
||||||
void selectedIds(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected);
|
void selectedIds_internal(IdType idType, std::set<std::string> &ids, bool onlyDirectSelected);
|
||||||
void setSelectedIds(IdType idType, const std::set<std::string> &ids, bool add);
|
void setSelectedIds_internal(IdType idType, const std::set<std::string> &ids, bool add);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mStarted;
|
bool mStarted;
|
||||||
@ -170,7 +172,7 @@ private:
|
|||||||
std::vector<RsGxsGroupId> gxsIds ;
|
std::vector<RsGxsGroupId> gxsIds ;
|
||||||
QList<QAction*> mContextMenuActions;
|
QList<QAction*> mContextMenuActions;
|
||||||
|
|
||||||
std::set<RsGxsId> mPreSelectedGxsIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
|
std::set<std::string> mPreSelectedIds; // because loading of GxsIds is asynchroneous we keep selected Ids from the client in a list here and use it to initialize after loading them.
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(FriendSelectionWidget::ShowTypes)
|
||||||
|
@ -287,9 +287,6 @@ void GroupTreeWidget::initDisplayMenu(QToolButton *toolButton)
|
|||||||
|
|
||||||
void GroupTreeWidget::updateColors()
|
void GroupTreeWidget::updateColors()
|
||||||
{
|
{
|
||||||
QBrush brush;
|
|
||||||
QBrush standardBrush = ui->treeWidget->palette().color(QPalette::Text);
|
|
||||||
|
|
||||||
QTreeWidgetItemIterator itemIterator(ui->treeWidget);
|
QTreeWidgetItemIterator itemIterator(ui->treeWidget);
|
||||||
QTreeWidgetItem *item;
|
QTreeWidgetItem *item;
|
||||||
while ((item = *itemIterator) != NULL) {
|
while ((item = *itemIterator) != NULL) {
|
||||||
@ -297,12 +294,11 @@ void GroupTreeWidget::updateColors()
|
|||||||
|
|
||||||
int color = item->data(COLUMN_DATA, ROLE_COLOR).toInt();
|
int color = item->data(COLUMN_DATA, ROLE_COLOR).toInt();
|
||||||
if (color >= 0) {
|
if (color >= 0) {
|
||||||
brush = QBrush(mTextColor[color]);
|
item->setData(COLUMN_NAME, Qt::TextColorRole, mTextColor[color]);
|
||||||
} else {
|
} else {
|
||||||
brush = standardBrush;
|
item->setData(COLUMN_NAME, Qt::TextColorRole, QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
item->setForeground(COLUMN_NAME, brush);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,7 +352,7 @@ QTreeWidgetItem *GroupTreeWidget::addCategoryItem(const QString &name, const QIc
|
|||||||
int S = QFontMetricsF(font).height();
|
int S = QFontMetricsF(font).height();
|
||||||
|
|
||||||
item->setSizeHint(COLUMN_NAME, QSize(S*1.9, S*1.9));
|
item->setSizeHint(COLUMN_NAME, QSize(S*1.9, S*1.9));
|
||||||
item->setForeground(COLUMN_NAME, QBrush(textColorCategory()));
|
item->setData(COLUMN_NAME, Qt::TextColorRole, textColorCategory());
|
||||||
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_CATEGORY);
|
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_CATEGORY);
|
||||||
|
|
||||||
item->setExpanded(expand);
|
item->setExpanded(expand);
|
||||||
@ -513,15 +509,14 @@ void GroupTreeWidget::fillGroupItems(QTreeWidgetItem *categoryItem, const QList<
|
|||||||
item->setData(COLUMN_DATA, ROLE_SUBSCRIBE_FLAGS, itemInfo.subscribeFlags);
|
item->setData(COLUMN_DATA, ROLE_SUBSCRIBE_FLAGS, itemInfo.subscribeFlags);
|
||||||
|
|
||||||
/* Set color */
|
/* Set color */
|
||||||
QBrush brush;
|
|
||||||
if (itemInfo.publishKey) {
|
if (itemInfo.publishKey) {
|
||||||
brush = QBrush(textColorPrivateKey());
|
|
||||||
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_PRIVATEKEY);
|
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_PRIVATEKEY);
|
||||||
|
item->setData(COLUMN_NAME, Qt::ForegroundRole, QBrush(textColorPrivateKey()));
|
||||||
} else {
|
} else {
|
||||||
brush = ui->treeWidget->palette().color(QPalette::Text);
|
// Let StyleSheet color
|
||||||
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_STANDARD);
|
item->setData(COLUMN_DATA, ROLE_COLOR, GROUPTREEWIDGET_COLOR_STANDARD);
|
||||||
|
item->setData(COLUMN_NAME, Qt::BackgroundRole, QVariant());
|
||||||
}
|
}
|
||||||
item->setForeground(COLUMN_NAME, brush);
|
|
||||||
|
|
||||||
/* Calculate score */
|
/* Calculate score */
|
||||||
calculateScore(item, filterText);
|
calculateScore(item, filterText);
|
||||||
|
@ -36,6 +36,36 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
|
//#define DEBUG_EID_PAINT 1
|
||||||
|
|
||||||
|
/* To test it you can make an empty.qss file with:
|
||||||
|
QTreeView::item, QTreeWidget::item, QListWidget::item{
|
||||||
|
color: #AB0000;
|
||||||
|
background-color: #00DC00;
|
||||||
|
}
|
||||||
|
QTreeView::item:selected, QTreeWidget::item:selected, QListWidget::item:selected{
|
||||||
|
color: #00CD00;
|
||||||
|
background-color: #0000BA;
|
||||||
|
}
|
||||||
|
QTreeView::item:hover, QTreeWidget::item:hover, QListWidget::item:hover{
|
||||||
|
color: #0000EF;
|
||||||
|
background-color: #FEDCBA;
|
||||||
|
}
|
||||||
|
QQTreeView::item:selected:hover, TreeWidget::item:selected:hover, QListWidget::item:selected:hover{
|
||||||
|
color: #ABCDEF;
|
||||||
|
background-color: #FE0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ForumsDialog, GxsForumThreadWidget
|
||||||
|
{
|
||||||
|
qproperty-textColorRead: darkgray;
|
||||||
|
qproperty-textColorUnread: white;
|
||||||
|
qproperty-textColorUnreadChildren: red;
|
||||||
|
qproperty-textColorNotSubscribed: white;
|
||||||
|
qproperty-textColorMissing: darkred;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
RSElidedItemDelegate::RSElidedItemDelegate(QObject *parent)
|
RSElidedItemDelegate::RSElidedItemDelegate(QObject *parent)
|
||||||
: RSStyledItemDelegate(parent)
|
: RSStyledItemDelegate(parent)
|
||||||
, mOnlyPlainText(false), mPaintRoundedRect(true)
|
, mOnlyPlainText(false), mPaintRoundedRect(true)
|
||||||
@ -63,6 +93,18 @@ QSize RSElidedItemDelegate::sizeHint(const QStyleOptionViewItem &option, const Q
|
|||||||
return contSize;
|
return contSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline QColor getImagePixelColor(QImage img, int x, int y)
|
||||||
|
{
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
// RsDbg() << " RSEID: Found Color " << img.pixelColor(x,y).name(QColor::HexArgb).toStdString() << " at " << x << "," << y << std::endl;
|
||||||
|
#endif
|
||||||
|
return img.pixelColor(x,y);
|
||||||
|
#else
|
||||||
|
return img.pixel(x,y);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
if(!index.isValid())
|
if(!index.isValid())
|
||||||
@ -71,15 +113,16 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
painter->save();
|
painter->save();
|
||||||
// To draw with default for debug purpose
|
|
||||||
//QStyledItemDelegate::paint(painter, option, index);
|
|
||||||
|
|
||||||
QStyleOptionViewItem ownOption (option);
|
QStyleOptionViewItem ownOption (option);
|
||||||
initStyleOption(&ownOption, index);
|
initStyleOption(&ownOption, index);
|
||||||
//Prefer use icon from option
|
//Prefer use icon from option
|
||||||
if (!option.icon.isNull())
|
if (!option.icon.isNull())
|
||||||
ownOption.icon = option.icon;
|
ownOption.icon = option.icon;
|
||||||
|
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << __PRETTY_FUNCTION__ << std::endl << " RSEID: Enter for item with text:" << ownOption.text.toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
const QWidget* widget = option.widget;
|
const QWidget* widget = option.widget;
|
||||||
QStyle* ownStyle = widget ? widget->style() : QApplication::style();
|
QStyle* ownStyle = widget ? widget->style() : QApplication::style();
|
||||||
|
|
||||||
@ -89,28 +132,180 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||||||
td.setHtml(ownOption.text);
|
td.setHtml(ownOption.text);
|
||||||
ownOption.text = td.toPlainText();
|
ownOption.text = td.toPlainText();
|
||||||
}
|
}
|
||||||
//Get Font as option.font is not accurate
|
// Get Font as option.font is not accurate
|
||||||
if (index.data(Qt::FontRole).type() == QVariant::Font) {
|
if (index.data(Qt::FontRole).type() == QVariant::Font) {
|
||||||
QFont font = index.data(Qt::FontRole).value<QFont>();
|
QFont font = index.data(Qt::FontRole).value<QFont>();
|
||||||
ownOption.font = font;
|
ownOption.font = font;
|
||||||
ownOption.fontMetrics = QFontMetrics(font);
|
ownOption.fontMetrics = QFontMetrics(font);
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
QFontInfo info(font);
|
||||||
|
RsDbg() << " RSEID: Found font in model:" << info.family().toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
// Get Text color from model if one exists
|
||||||
QColor textColor;
|
QColor textColor;
|
||||||
if (index.data(Qt::TextColorRole).canConvert(QMetaType::QColor)) {
|
if (index.data(Qt::TextColorRole).isValid()) {
|
||||||
textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format.
|
//textColor = QColor(index.data(Qt::TextColorRole).toString());//Needs to pass from string else loose RBG format.
|
||||||
|
textColor = index.data(Qt::TextColorRole).value<QColor>();
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID: Found text color in model:" << textColor.name().toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (index.data(Qt::BackgroundRole).canConvert(QMetaType::QBrush)) {
|
// Get Brush from model if one exists
|
||||||
QBrush brush(index.data(Qt::BackgroundRole).convert(QMetaType::QBrush));
|
QBrush bgBrush;
|
||||||
ownOption.backgroundBrush = brush;
|
bgBrush.setColor(QColor());// To get color().spec()==QColor::Invalid)
|
||||||
|
if (index.data(Qt::BackgroundRole).isValid()) {
|
||||||
|
bgBrush = index.data(Qt::BackgroundRole).value<QBrush>();
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID: Found bg brush in model:" << bgBrush.color().name().toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//Code from: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2271
|
// If we get text and bg color from model, no need to retrieve it from base
|
||||||
|
if ( (bgBrush.color().spec()==QColor::Invalid) || (textColor.spec()!=QColor::Invalid) )
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID:"
|
||||||
|
<< ((bgBrush.color().spec()==QColor::Invalid) ? " Brush not defined" : "")
|
||||||
|
<< ((textColor.spec()==QColor::Invalid) ? " Text Color not defined" : "")
|
||||||
|
<< " so get it from base image." << std::endl;
|
||||||
|
#endif
|
||||||
|
// QPalette is not updated by StyleSheet all occurs in internal class. (QRenderRule)
|
||||||
|
// https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#4138
|
||||||
|
// void QStyleSheetStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter *p, const QWidget *w) const
|
||||||
|
// case CE_ItemViewItem:
|
||||||
|
// So we have to print it in Image to get colors by pixel
|
||||||
|
QSize moSize=sizeHint(option,index);
|
||||||
|
if (moSize.width() <= 20)
|
||||||
|
moSize.setWidth(20);
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID: for item size = " << moSize.width() << "x" << moSize.height() << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QImage moImg(moSize,QImage::Format_ARGB32);
|
||||||
|
QPainter moPnt;
|
||||||
|
moPnt.begin(&moImg);
|
||||||
|
moPnt.setCompositionMode (QPainter::CompositionMode_Source);
|
||||||
|
moPnt.fillRect(moImg.rect(), Qt::transparent);
|
||||||
|
moPnt.setCompositionMode (QPainter::CompositionMode_SourceOver);
|
||||||
|
|
||||||
|
QStyleOptionViewItem moOption (option);
|
||||||
|
// Define option to get only what we want
|
||||||
|
{
|
||||||
|
moOption.rect = QRect(QPoint(0,0),moSize);
|
||||||
|
moOption.state = ownOption.state;
|
||||||
|
moOption.text = " ████████████████";//Add a blank char to get BackGround Color at top left
|
||||||
|
// Remove unwanted info. Yes it can draw without that all public data ...
|
||||||
|
moOption.backgroundBrush = QBrush();
|
||||||
|
moOption.checkState = Qt::Unchecked;
|
||||||
|
moOption.decorationAlignment = Qt::AlignLeft;
|
||||||
|
moOption.decorationPosition = QStyleOptionViewItem::Left;
|
||||||
|
moOption.decorationSize = QSize();
|
||||||
|
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
|
||||||
|
moOption.features=0;
|
||||||
|
moOption.font = QFont();
|
||||||
|
moOption.icon = QIcon();
|
||||||
|
moOption.index = QModelIndex();
|
||||||
|
moOption.locale = QLocale();
|
||||||
|
moOption.showDecorationSelected = false;
|
||||||
|
moOption.textElideMode = Qt::ElideNone;
|
||||||
|
moOption.viewItemPosition = QStyleOptionViewItem::Middle;
|
||||||
|
//moOption.widget = nullptr; //Needed.
|
||||||
|
|
||||||
|
moOption.direction = Qt::LayoutDirectionAuto;
|
||||||
|
moOption.fontMetrics = QFontMetrics(QFont());
|
||||||
|
moOption.palette = QPalette();
|
||||||
|
moOption.styleObject = nullptr;
|
||||||
|
}
|
||||||
|
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex());
|
||||||
|
|
||||||
|
//// But these lines doesn't works.
|
||||||
|
{
|
||||||
|
//QStyleOptionViewItem moOptionsState;
|
||||||
|
//moOptionsState.initFrom(moOption.widget);
|
||||||
|
//moOptionsState.rect = QRect(QPoint(0,0),moSize);
|
||||||
|
//moOptionsState.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
|
||||||
|
//moOptionsState.text = "████████";
|
||||||
|
//moOptionsState.widget = option.widget;
|
||||||
|
//QStyledItemDelegate::paint(&moPnt, moOptionsState, QModelIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
moPnt.end();
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
// To save what it paint in application path
|
||||||
|
moImg.save("image.png");
|
||||||
|
#endif
|
||||||
|
// Get Color in this rect.
|
||||||
|
{
|
||||||
|
QColor moColor;
|
||||||
|
QColor moBGColor=getImagePixelColor(moImg,1,1); // BackGround may be paint.
|
||||||
|
QColor moColorBorder;// To avoid Border pixel
|
||||||
|
int moWidth = moImg.size().width(), moHeight = moImg.size().height();
|
||||||
|
for (int x = 0; (x<moWidth) && (moColor.spec() == QColor::Invalid); x++)
|
||||||
|
for (int y = 0; (y<moHeight) && (moColor.spec() == QColor::Invalid); y++)
|
||||||
|
if (getImagePixelColor(moImg,x,y) != moBGColor)
|
||||||
|
{
|
||||||
|
if (getImagePixelColor(moImg,x,y) == moColorBorder)
|
||||||
|
moColor = getImagePixelColor(moImg,x,y);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (moColorBorder.spec() == QColor::Invalid)
|
||||||
|
{
|
||||||
|
// First pixel border move inside
|
||||||
|
x+=5;
|
||||||
|
y+=5;
|
||||||
|
}
|
||||||
|
moColorBorder = getImagePixelColor(moImg,x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not found color is same as BackGround.
|
||||||
|
if (moColor.spec() == QColor::Invalid)
|
||||||
|
moColor = moBGColor;
|
||||||
|
|
||||||
|
if (bgBrush.color().spec()==QColor::Invalid)
|
||||||
|
{
|
||||||
|
bgBrush = QBrush(moBGColor);
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID: bg brush setted to " << moBGColor.name(QColor::HexArgb).toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (textColor.spec()==QColor::Invalid)
|
||||||
|
{
|
||||||
|
textColor = moColor;
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID: text color setted to " << moColor.name(QColor::HexArgb).toStdString() << std::endl;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
painter->setPen(textColor);
|
||||||
|
painter->setBrush(bgBrush);
|
||||||
|
ownOption.backgroundBrush = bgBrush;
|
||||||
|
|
||||||
|
// Code from: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2271
|
||||||
QRect checkRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &ownOption, widget);
|
QRect checkRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &ownOption, widget);
|
||||||
QRect iconRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemDecoration, &ownOption, widget);
|
QRect iconRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemDecoration, &ownOption, widget);
|
||||||
QRect textRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemText, &ownOption, widget);
|
QRect textRect = ownStyle->subElementRect(QStyle::SE_ItemViewItemText, &ownOption, widget);
|
||||||
|
|
||||||
// draw the background
|
// Draw the background
|
||||||
ownStyle->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);
|
if (bgBrush.color().alpha() == 0)
|
||||||
|
// No BackGround Color found, use default delegate to draw it.
|
||||||
|
ownStyle->proxy()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget);// This prefer draw StyleSheet bg than item one.
|
||||||
|
else
|
||||||
|
painter->fillRect(ownOption.rect,bgBrush);
|
||||||
|
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
{
|
||||||
|
QStyleOptionViewItem tstOption = option;
|
||||||
|
// Reduce rect to get this item bg color external and base internal
|
||||||
|
tstOption.rect.adjust(3,3,-6,-6);
|
||||||
|
// To draw with base for debug purpose
|
||||||
|
QStyledItemDelegate::paint(painter, tstOption, index);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// draw the check mark
|
// draw the check mark
|
||||||
if (ownOption.features & QStyleOptionViewItem::HasCheckIndicator) {
|
if (ownOption.features & QStyleOptionViewItem::HasCheckIndicator) {
|
||||||
QStyleOptionViewItem option(*&ownOption);
|
QStyleOptionViewItem option(*&ownOption);
|
||||||
@ -177,118 +372,19 @@ void RSElidedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &
|
|||||||
}
|
}
|
||||||
// draw the text
|
// draw the text
|
||||||
if (!ownOption.text.isEmpty()) {
|
if (!ownOption.text.isEmpty()) {
|
||||||
QPalette::ColorGroup cg = ownOption.state & QStyle::State_Enabled
|
#ifdef DEBUG_EID_PAINT
|
||||||
? QPalette::Normal : QPalette::Disabled;
|
// To draw text near base one.
|
||||||
if (cg == QPalette::Normal && !(ownOption.state & QStyle::State_Active))
|
ownOption.text = ownOption.text.prepend("__");
|
||||||
cg = QPalette::Inactive;
|
|
||||||
if (ownOption.state & QStyle::State_Selected) {
|
|
||||||
painter->setPen(ownOption.palette.color(cg, QPalette::HighlightedText));
|
|
||||||
} else {
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,6,0)
|
|
||||||
if (ownOption.state & QStyle::State_MouseOver) {
|
|
||||||
//TODO: Manage to get palette with HOVER css pseudoclass
|
|
||||||
// For now this is hidden by Qt: https://code.woboq.org/qt5/qtbase/src/widgets/styles/qstylesheetstyle.cpp.html#6103
|
|
||||||
// So we print default in image and get it's color...
|
|
||||||
QSize moSize=sizeHint(option,index);
|
|
||||||
QImage moImg(moSize,QImage::Format_ARGB32);
|
|
||||||
QPainter moPnt;
|
|
||||||
moPnt.begin(&moImg);
|
|
||||||
moPnt.setPen(Qt::black);//Fill Image with Black
|
|
||||||
moPnt.setBrush(Qt::black);
|
|
||||||
moPnt.drawRect(moImg.rect());
|
|
||||||
|
|
||||||
QStyleOptionViewItem moOption (option);
|
|
||||||
// Define option to get only what we want
|
|
||||||
{
|
|
||||||
moOption.rect = QRect(QPoint(0,0),moSize);
|
|
||||||
moOption.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
|
|
||||||
moOption.text = " ████████████████";//Add a blank char to get BackGround Color at top left
|
|
||||||
// Remove unwanted info. Yes it can draw without that all public data ...
|
|
||||||
moOption.backgroundBrush = QBrush();
|
|
||||||
moOption.checkState = Qt::Unchecked;
|
|
||||||
moOption.decorationAlignment = Qt::AlignLeft;
|
|
||||||
moOption.decorationPosition = QStyleOptionViewItem::Left;
|
|
||||||
moOption.decorationSize = QSize();
|
|
||||||
moOption.displayAlignment = Qt::AlignLeft | Qt::AlignTop;
|
|
||||||
moOption.features=0;
|
|
||||||
moOption.font = QFont();
|
|
||||||
moOption.icon = QIcon();
|
|
||||||
moOption.index = QModelIndex();
|
|
||||||
moOption.locale = QLocale();
|
|
||||||
moOption.showDecorationSelected = false;
|
|
||||||
moOption.textElideMode = Qt::ElideNone;
|
|
||||||
moOption.viewItemPosition = QStyleOptionViewItem::Middle;
|
|
||||||
//moOption.widget = nullptr; //Needed.
|
|
||||||
|
|
||||||
moOption.direction = Qt::LayoutDirectionAuto;
|
|
||||||
moOption.fontMetrics = QFontMetrics(QFont());
|
|
||||||
moOption.palette = QPalette();
|
|
||||||
moOption.styleObject = nullptr;
|
|
||||||
}
|
|
||||||
QStyledItemDelegate::paint(&moPnt, moOption, QModelIndex());
|
|
||||||
|
|
||||||
//// But these lines doesn't works.
|
|
||||||
{
|
|
||||||
//QStyleOptionViewItem moOptionsState;
|
|
||||||
//moOptionsState.initFrom(moOption.widget);
|
|
||||||
//moOptionsState.rect = QRect(QPoint(0,0),moSize);
|
|
||||||
//moOptionsState.state = QStyle::State_MouseOver | QStyle::State_Enabled | QStyle::State_Sibling;
|
|
||||||
//moOptionsState.text = "████████";
|
|
||||||
//moOptionsState.widget = option.widget;
|
|
||||||
//QStyledItemDelegate::paint(&moPnt, moOptionsState, QModelIndex());
|
|
||||||
}
|
|
||||||
|
|
||||||
moPnt.end();
|
|
||||||
// To save what it paint
|
|
||||||
//moImg.save("image.bmp");
|
|
||||||
|
|
||||||
// Get Color in this black rect.
|
|
||||||
QColor moColor;
|
|
||||||
QColor moBGColor=moImg.pixelColor(1,1); //BackGround may be paint.
|
|
||||||
QColor moColorBorder;// To avoid Border pixel
|
|
||||||
int moWidth = moImg.size().width(), moHeight = moImg.size().height();
|
|
||||||
for (int x = 0; (x<moWidth) && (moColor.spec() == QColor::Invalid); x++)
|
|
||||||
for (int y = 0; (y<moHeight) && (moColor.spec() == QColor::Invalid); y++)
|
|
||||||
if (moImg.pixelColor(x,y) != moBGColor)
|
|
||||||
{
|
|
||||||
if (moImg.pixelColor(x,y) == moColorBorder)
|
|
||||||
moColor = QColor(moImg.pixelColor(x,y).name());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (moColorBorder.spec() == QColor::Invalid)
|
|
||||||
{
|
|
||||||
// First pixel border move inside
|
|
||||||
x+=5;
|
|
||||||
y+=5;
|
|
||||||
}
|
|
||||||
moColorBorder = QColor(moImg.pixelColor(x,y).name());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not found color is same as BackGround.
|
|
||||||
if (moColor.spec() == QColor::Invalid)
|
|
||||||
moColor = moBGColor;
|
|
||||||
|
|
||||||
painter->setPen(moColor);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
if (textColor.spec()==QColor::Invalid) {
|
|
||||||
painter->setPen(ownOption.palette.color(cg, QPalette::Text));
|
|
||||||
} else { //Only get color from index for unselected(as Qt does)
|
|
||||||
painter->setPen(textColor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ownOption.state & QStyle::State_Editing) {
|
|
||||||
painter->setPen(ownOption.palette.color(cg, QPalette::Text));
|
|
||||||
painter->drawRect(textRect.adjusted(0, 0, -1, -1));
|
|
||||||
}
|
|
||||||
//d->viewItemDrawText(p, &ownOption, textRect);
|
|
||||||
QTextLayout textLayout(ownOption.text, painter->font());
|
QTextLayout textLayout(ownOption.text, painter->font());
|
||||||
QTextOption to = textLayout.textOption();
|
QTextOption to = textLayout.textOption();
|
||||||
StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect);
|
StyledElidedLabel::paintElidedLine(painter,ownOption.text,textRect,ownOption.font,ownOption.displayAlignment,to.wrapMode()&QTextOption::WordWrap,mPaintRoundedRect);
|
||||||
}
|
}
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
#ifdef DEBUG_EID_PAINT
|
||||||
|
RsDbg() << " RSEID: Finished" << std::endl;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
|
bool RSElidedItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
|
||||||
|
@ -537,8 +537,9 @@ bool RsCollectionDialog::addChild(QTreeWidgetItem* parent, const std::vector<Col
|
|||||||
|
|
||||||
if (colFileInfo.filename_has_wrong_characters)
|
if (colFileInfo.filename_has_wrong_characters)
|
||||||
{
|
{
|
||||||
|
//TODO (Phenom): Add qproperty for these text colors in stylesheets
|
||||||
wrong_chars = true ;
|
wrong_chars = true ;
|
||||||
item->setTextColor(COLUMN_FILE, QColor(255,80,120)) ;
|
item->setData(COLUMN_FILE, Qt::ForegroundRole, QColor(255,80,120)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentsFounds.empty()) {
|
if (parentsFounds.empty()) {
|
||||||
|
@ -88,11 +88,12 @@ void UserNotify::setNotifyEnabled(bool enabled, bool combined, bool blink)
|
|||||||
Settings->endGroup();
|
Settings->endGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem)
|
void UserNotify::initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem,const QString& subtext)
|
||||||
{
|
{
|
||||||
mMainAction = mainAction;
|
mMainAction = mainAction;
|
||||||
if (mMainAction) {
|
if (mMainAction) {
|
||||||
mButtonText = mMainAction->text();
|
mButtonText = mMainAction->text();
|
||||||
|
mButtonText2 = subtext;
|
||||||
if (mainToolBar) {
|
if (mainToolBar) {
|
||||||
mMainToolButton = dynamic_cast<QToolButton*>(mainToolBar->widgetForAction(mMainAction));
|
mMainToolButton = dynamic_cast<QToolButton*>(mainToolBar->widgetForAction(mMainAction));
|
||||||
}
|
}
|
||||||
@ -165,7 +166,18 @@ void UserNotify::update()
|
|||||||
|
|
||||||
if (mMainAction) {
|
if (mMainAction) {
|
||||||
mMainAction->setIcon(getMainIcon(count > 0));
|
mMainAction->setIcon(getMainIcon(count > 0));
|
||||||
mMainAction->setText((count > 0) ? QString("%1 (%2)").arg(mButtonText).arg(count) : mButtonText);
|
|
||||||
|
if(count > 0)
|
||||||
|
{
|
||||||
|
if(!mButtonText2.isNull())
|
||||||
|
mMainAction->setToolTip(QString("%1 (%2 %3)").arg(mButtonText).arg(count).arg(mButtonText2));
|
||||||
|
else
|
||||||
|
mMainAction->setToolTip(QString("%1 (%2)").arg(mButtonText).arg(count));
|
||||||
|
|
||||||
|
mMainAction->setText(QString("%1 (%2)").arg(mButtonText).arg(count));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mMainAction->setText(mButtonText);
|
||||||
|
|
||||||
QFont font = mMainAction->font();
|
QFont font = mMainAction->font();
|
||||||
font.setBold(count > 0);
|
font.setBold(count > 0);
|
||||||
|
@ -37,12 +37,17 @@ public:
|
|||||||
UserNotify(QObject *parent = 0);
|
UserNotify(QObject *parent = 0);
|
||||||
virtual ~UserNotify();
|
virtual ~UserNotify();
|
||||||
|
|
||||||
void initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem);
|
void initialize(QToolBar *mainToolBar, QAction *mainAction, QListWidgetItem *listItem,const QString& subtext);
|
||||||
void createIcons(QMenu *notifyMenu);
|
void createIcons(QMenu *notifyMenu);
|
||||||
QSystemTrayIcon* getTrayIcon(){ return mTrayIcon;}
|
QSystemTrayIcon* getTrayIcon(){ return mTrayIcon;}
|
||||||
QAction* getNotifyIcon(){ return mNotifyIcon;}
|
QAction* getNotifyIcon(){ return mNotifyIcon;}
|
||||||
|
|
||||||
virtual bool hasSetting(QString */*name*/, QString */*group*/) { return false; }
|
virtual bool hasSetting(QString */*name*/, QString */*group*/) { return false; }
|
||||||
|
|
||||||
|
// UserNotify is used to display tooltips when some services have no messages and so on, in the format of "Name (43242 new messages)"
|
||||||
|
// This method is used to pass the string that comes after the number.
|
||||||
|
virtual QString textInfo() const { return QString() ; }
|
||||||
|
|
||||||
bool notifyEnabled();
|
bool notifyEnabled();
|
||||||
bool notifyCombined();
|
bool notifyCombined();
|
||||||
bool notifyBlink();
|
bool notifyBlink();
|
||||||
@ -82,6 +87,7 @@ private:
|
|||||||
QAction *mNotifyIcon;
|
QAction *mNotifyIcon;
|
||||||
unsigned int mNewCount;
|
unsigned int mNewCount;
|
||||||
QString mButtonText;
|
QString mButtonText;
|
||||||
|
QString mButtonText2;
|
||||||
bool mLastBlinking;
|
bool mLastBlinking;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -937,5 +937,7 @@
|
|||||||
<file>emojione/1F1FF-1F1FC.png</file>
|
<file>emojione/1F1FF-1F1FC.png</file>
|
||||||
<file>emojione/flags.png</file>
|
<file>emojione/flags.png</file>
|
||||||
<file>emojione/flags2.png</file>
|
<file>emojione/flags2.png</file>
|
||||||
|
<file>emojione/man-facepalming.png</file>
|
||||||
|
<file>emojione/woman-facepalming.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@ -113,6 +113,8 @@
|
|||||||
"emojione/people2.png"|":man_with_gua_pi_mao:":"emojione/1F472.png";
|
"emojione/people2.png"|":man_with_gua_pi_mao:":"emojione/1F472.png";
|
||||||
"emojione/people2.png"|":levitate:|:man_in_business_suit_levitating:":"emojione/1F574.png";
|
"emojione/people2.png"|":levitate:|:man_in_business_suit_levitating:":"emojione/1F574.png";
|
||||||
"emojione/people2.png"|":dancer:":"emojione/1F483.png";
|
"emojione/people2.png"|":dancer:":"emojione/1F483.png";
|
||||||
|
"emojione/people2.png"|":man_facepalming:":"emojione/man-facepalming.png";
|
||||||
|
"emojione/people2.png"|":woman_facepalming:":"emojione/woman-facepalming.png";
|
||||||
"emojione/people2.png"|":bust_in_silhouette:":"emojione/1F464.png";
|
"emojione/people2.png"|":bust_in_silhouette:":"emojione/1F464.png";
|
||||||
"emojione/people2.png"|":busts_in_silhouette:":"emojione/1F465.png";
|
"emojione/people2.png"|":busts_in_silhouette:":"emojione/1F465.png";
|
||||||
"emojione/people2.png"|":family:":"emojione/1F46A.png";
|
"emojione/people2.png"|":family:":"emojione/1F46A.png";
|
||||||
|
BIN
retroshare-gui/src/gui/emojione/man-facepalming.png
Normal file
BIN
retroshare-gui/src/gui/emojione/man-facepalming.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
BIN
retroshare-gui/src/gui/emojione/woman-facepalming.png
Normal file
BIN
retroshare-gui/src/gui/emojione/woman-facepalming.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user