Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
f978c96265
|
|||
|
000bd789b1
|
|||
|
cd2545934e
|
|||
|
efa23f6b50
|
|||
|
5083bedf57
|
|||
|
a621e58db8
|
|||
|
fa41eb1b02
|
|||
|
5f3b4b7ddb
|
|||
|
0d09c9701d
|
|||
|
17e46ed0b2
|
|||
|
5931143564
|
|||
|
36f9cac0af
|
|||
|
eea479b3df
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
#Ignore all repo directories
|
#Ignore all repo directories
|
||||||
.flatpak-builder/
|
.flatpak-builder/
|
||||||
|
com.angoosh.RDPConnect/testing.py
|
||||||
|
|||||||
@@ -43,18 +43,6 @@
|
|||||||
<url type="vcs-browser">https://gitea.farmdash.org/angoosh/Flatpaks/src/branch/main/com.angoosh.RDPConnect</url>
|
<url type="vcs-browser">https://gitea.farmdash.org/angoosh/Flatpaks/src/branch/main/com.angoosh.RDPConnect</url>
|
||||||
|
|
||||||
<releases>
|
<releases>
|
||||||
<release version="1.0.2" date="2024-11-20">
|
|
||||||
<url type="details">https://gitea.farmdash.org/angoosh/Flatpaks/commit/85ea660c7e11d0c65c8aef23fcf76853882975cf</url>
|
|
||||||
<description>
|
|
||||||
<p>Password is now encrypted</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="1.0.3" date="2024-11-20">
|
|
||||||
<url type="details">https://gitea.farmdash.org/angoosh/Flatpaks/commit/2093a21ecfa86c20f15b9b44897d1c7bebfafd79</url>
|
|
||||||
<description>
|
|
||||||
<p>Cropped screenshot and made background invisible</p>
|
|
||||||
</description>
|
|
||||||
</release>
|
|
||||||
<release version="1.1.0" date="2024-11-22">
|
<release version="1.1.0" date="2024-11-22">
|
||||||
<url type="details">https://gitea.farmdash.org/angoosh/Flatpaks/src/tag/1.1.0</url>
|
<url type="details">https://gitea.farmdash.org/angoosh/Flatpaks/src/tag/1.1.0</url>
|
||||||
<description>
|
<description>
|
||||||
@@ -67,6 +55,18 @@
|
|||||||
<p>Updated to newest FreeRDP which seems to fix issues with hanging / freezing</p>
|
<p>Updated to newest FreeRDP which seems to fix issues with hanging / freezing</p>
|
||||||
</description>
|
</description>
|
||||||
</release>
|
</release>
|
||||||
|
<release version="1.3.0" date="2025-09-16">
|
||||||
|
<url type="details">https://gitea.farmdash.org/angoosh/Flatpaks/src/tag/1.3.0</url>
|
||||||
|
<description>
|
||||||
|
<p>Changed pasword storage from file to system keyring. Still using file for compatibility. Added connection history menu.</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
|
<release version="1.3.1" date="2025-09-16">
|
||||||
|
<url type="details">https://gitea.farmdash.org/angoosh/Flatpaks/src/tag/1.3.1</url>
|
||||||
|
<description>
|
||||||
|
<p>History menu now shows only unique entries, no duplicates</p>
|
||||||
|
</description>
|
||||||
|
</release>
|
||||||
</releases>
|
</releases>
|
||||||
|
|
||||||
<screenshots>
|
<screenshots>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ finish-args:
|
|||||||
- --filesystem=xdg-download
|
- --filesystem=xdg-download
|
||||||
- --socket=pcsc
|
- --socket=pcsc
|
||||||
# - --socket=system-bus
|
# - --socket=system-bus
|
||||||
|
- --socket=session-bus
|
||||||
# - --talk-name=org.freedesktop.Flatpak
|
# - --talk-name=org.freedesktop.Flatpak
|
||||||
|
|
||||||
add-build-extensions:
|
add-build-extensions:
|
||||||
@@ -68,7 +69,7 @@ modules:
|
|||||||
build-args:
|
build-args:
|
||||||
- --share=network
|
- --share=network
|
||||||
build-commands:
|
build-commands:
|
||||||
- pip3 install PyGObject cryptography
|
- pip3 install PyGObject cryptography keyring
|
||||||
|
|
||||||
- name: rdpconnect
|
- name: rdpconnect
|
||||||
buildsystem: simple
|
buildsystem: simple
|
||||||
|
|||||||
@@ -18,13 +18,15 @@ from cryptography.fernet import Fernet
|
|||||||
gi.require_version('Gtk', '4.0')
|
gi.require_version('Gtk', '4.0')
|
||||||
gi.require_version('Adw', '1')
|
gi.require_version('Adw', '1')
|
||||||
from gi.repository import Gtk, Adw, Gdk, Gio
|
from gi.repository import Gtk, Adw, Gdk, Gio
|
||||||
|
import keyring
|
||||||
|
|
||||||
APPID = "com.angoosh.RDPConnect"
|
APPID = "com.angoosh.RDPConnect"
|
||||||
HOMEDIR = os.path.expanduser('~')
|
HOMEDIR = os.path.expanduser('~')
|
||||||
|
|
||||||
VERSION = "1.2.0"
|
VERSION = "1.3.1"
|
||||||
|
|
||||||
conn_info = {}
|
conn_info = {}
|
||||||
|
hist_info = {}
|
||||||
settings = {}
|
settings = {}
|
||||||
settings["extra_params"] = {}
|
settings["extra_params"] = {}
|
||||||
fernet = ""
|
fernet = ""
|
||||||
@@ -32,7 +34,7 @@ fernet = ""
|
|||||||
def load_keys():
|
def load_keys():
|
||||||
global fernet
|
global fernet
|
||||||
cryptoKey = ""
|
cryptoKey = ""
|
||||||
try:
|
try:
|
||||||
with open(HOMEDIR+"/.config/rdpconnect/.key", "r") as keyfile:
|
with open(HOMEDIR+"/.config/rdpconnect/.key", "r") as keyfile:
|
||||||
cryptoKey = str.encode(keyfile.readline())
|
cryptoKey = str.encode(keyfile.readline())
|
||||||
print("Encription key loaded")
|
print("Encription key loaded")
|
||||||
@@ -45,18 +47,30 @@ def load_keys():
|
|||||||
fernet = Fernet(cryptoKey)
|
fernet = Fernet(cryptoKey)
|
||||||
|
|
||||||
def load_config():
|
def load_config():
|
||||||
global conn_info, settings
|
global conn_info, settings, hist_info
|
||||||
loaded_json = ""
|
loaded_json = ""
|
||||||
try:
|
try:
|
||||||
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "r") as connection_file:
|
with open(HOMEDIR+"/.config/rdpconnect/history.json", "r") as history_file:
|
||||||
for line in connection_file:
|
for line in history_file:
|
||||||
loaded_json += line
|
loaded_json += line
|
||||||
|
|
||||||
conn_info = json.loads(loaded_json)
|
hist_info = json.loads(loaded_json)
|
||||||
|
last_conn = hist_info[max(hist_info)]
|
||||||
|
conn_info["user"] = last_conn.split('@')[0]
|
||||||
|
conn_info["ip"] = last_conn.split('@')[1]
|
||||||
|
conn_info["passwd"] = keyring.get_password("com.angoosh.RDPConnect", last_conn)
|
||||||
|
|
||||||
conn_info["passwd"] = fernet.decrypt(str.encode(conn_info["passwd"])).decode()
|
|
||||||
except:
|
except:
|
||||||
print("[WARN] FILE: "+HOMEDIR+"/.config/rdpconnect/connection.json doesn't exist")
|
try:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "r") as connection_file:
|
||||||
|
for line in connection_file:
|
||||||
|
loaded_json += line
|
||||||
|
|
||||||
|
conn_info = json.loads(loaded_json)
|
||||||
|
|
||||||
|
conn_info["passwd"] = fernet.decrypt(str.encode(conn_info["passwd"])).decode()
|
||||||
|
except:
|
||||||
|
print("[WARN] FILE: "+HOMEDIR+"/.config/rdpconnect/connection.json doesn't exist")
|
||||||
|
|
||||||
loaded_json = ""
|
loaded_json = ""
|
||||||
try:
|
try:
|
||||||
@@ -68,14 +82,58 @@ def load_config():
|
|||||||
except:
|
except:
|
||||||
print("[WARN] FILE: "+HOMEDIR+"/.config/rdpconnect/settings.json doesn't exist")
|
print("[WARN] FILE: "+HOMEDIR+"/.config/rdpconnect/settings.json doesn't exist")
|
||||||
|
|
||||||
|
class HistoryWindow(Gtk.Window):
|
||||||
|
global hist_info, conn_info, app
|
||||||
|
def __init__(self, **kargs):
|
||||||
|
super().__init__(**kargs, title='History')
|
||||||
|
|
||||||
|
self.set_default_size(100, 300)
|
||||||
|
|
||||||
|
self.scroll = Gtk.ScrolledWindow()
|
||||||
|
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
|
||||||
|
self.grid = Gtk.Grid()
|
||||||
|
|
||||||
|
self.scroll.set_child(self.grid)
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
for i in hist_info:
|
||||||
|
self.addRow(hist_info[i], index)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
self.set_child(self.scroll)
|
||||||
|
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
def addRow(self, entry, index):
|
||||||
|
b = Gtk.Button(label=entry)
|
||||||
|
b.connect("clicked", self.apply_contents)
|
||||||
|
|
||||||
|
self.grid.attach(b, 0, index, 1, 1)
|
||||||
|
|
||||||
|
def apply_contents(self, button):
|
||||||
|
conn_info["user"] = button.get_label().split('@')[0]
|
||||||
|
conn_info["ip"] = button.get_label().split('@')[1]
|
||||||
|
|
||||||
|
app.ip.get_buffer().set_text(str(conn_info["ip"]), len(conn_info["ip"]))
|
||||||
|
app.user.get_buffer().set_text(str(conn_info["user"]), len(conn_info["user"]))
|
||||||
|
|
||||||
|
try:
|
||||||
|
conn_info["passwd"] = keyring.get_password("com.angoosh.RDPConnect", button.get_label())
|
||||||
|
app.passwd.get_buffer().set_text(str(conn_info["passwd"]), len(conn_info["passwd"]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.destroy()
|
||||||
|
|
||||||
class PreferencesWindow(Gtk.Window):
|
class PreferencesWindow(Gtk.Window):
|
||||||
global settings
|
global settings
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
self.builder = Gtk.Builder(self)
|
self.builder = Gtk.Builder(self)
|
||||||
self.builder.add_from_file("/app/preferences.ui")
|
self.builder.add_from_file("/app/preferences.ui")
|
||||||
|
|
||||||
self.resx = self.builder.get_object("resx")
|
self.resx = self.builder.get_object("resx")
|
||||||
self.resy = self.builder.get_object("resy")
|
self.resy = self.builder.get_object("resy")
|
||||||
self.monitors = self.builder.get_object("monitors")
|
self.monitors = self.builder.get_object("monitors")
|
||||||
@@ -85,7 +143,7 @@ class PreferencesWindow(Gtk.Window):
|
|||||||
self.mic = self.builder.get_object("mic")
|
self.mic = self.builder.get_object("mic")
|
||||||
self.dynres = self.builder.get_object("dynres")
|
self.dynres = self.builder.get_object("dynres")
|
||||||
self.clipboard = self.builder.get_object("clipboard")
|
self.clipboard = self.builder.get_object("clipboard")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.clipboard.set_state(settings["extra_params"]["clipboard"])
|
self.clipboard.set_state(settings["extra_params"]["clipboard"])
|
||||||
self.clipboard.set_active(settings["extra_params"]["clipboard"])
|
self.clipboard.set_active(settings["extra_params"]["clipboard"])
|
||||||
@@ -129,63 +187,64 @@ class PreferencesWindow(Gtk.Window):
|
|||||||
self.resy.get_buffer().set_text(str(settings["extra_params"]["h"]), len(settings["extra_params"]["h"]))
|
self.resy.get_buffer().set_text(str(settings["extra_params"]["h"]), len(settings["extra_params"]["h"]))
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
pref_window = self.builder.get_object("pref_window")
|
pref_window = self.builder.get_object("pref_window")
|
||||||
pref_window.show()
|
pref_window.show()
|
||||||
|
|
||||||
def f_resx(self, app):
|
def f_resx(self, app):
|
||||||
settings["extra_params"]["w"] = self.resx.get_buffer().get_text()
|
settings["extra_params"]["w"] = self.resx.get_buffer().get_text()
|
||||||
|
|
||||||
def f_resy(self, app):
|
def f_resy(self, app):
|
||||||
settings["extra_params"]["h"] = self.resy.get_buffer().get_text()
|
settings["extra_params"]["h"] = self.resy.get_buffer().get_text()
|
||||||
|
|
||||||
def monconf(self, app):
|
def monconf(self, app):
|
||||||
settings["extra_params"]["monitors"] = self.monitors.get_buffer().get_text()
|
settings["extra_params"]["monitors"] = self.monitors.get_buffer().get_text()
|
||||||
|
|
||||||
def clipboard(self, app, state):
|
def clipboard(self, app, state):
|
||||||
if state:
|
if state:
|
||||||
settings["extra_params"]["clipboard"] = True
|
settings["extra_params"]["clipboard"] = True
|
||||||
else:
|
else:
|
||||||
settings["extra_params"]["clipboard"] = False
|
settings["extra_params"]["clipboard"] = False
|
||||||
|
|
||||||
def dynres(self, app, state):
|
def dynres(self, app, state):
|
||||||
if state:
|
if state:
|
||||||
settings["extra_params"]["dynamic-resolution"] = True
|
settings["extra_params"]["dynamic-resolution"] = True
|
||||||
else:
|
else:
|
||||||
settings["extra_params"]["dynamic-resolution"] = False
|
settings["extra_params"]["dynamic-resolution"] = False
|
||||||
|
|
||||||
def microphone(self, app, state):
|
def microphone(self, app, state):
|
||||||
if state:
|
if state:
|
||||||
settings["extra_params"]["microphone"] = True
|
settings["extra_params"]["microphone"] = True
|
||||||
else:
|
else:
|
||||||
settings["extra_params"]["microphone"] = False
|
settings["extra_params"]["microphone"] = False
|
||||||
|
|
||||||
def sound(self, app, state):
|
def sound(self, app, state):
|
||||||
if state:
|
if state:
|
||||||
settings["extra_params"]["sound"] = True
|
settings["extra_params"]["sound"] = True
|
||||||
else:
|
else:
|
||||||
settings["extra_params"]["sound"] = False
|
settings["extra_params"]["sound"] = False
|
||||||
|
|
||||||
def xfree(self, app, state):
|
def xfree(self, app, state):
|
||||||
if state:
|
if state:
|
||||||
settings["rdp_bin"] = "xfreerdp"
|
settings["rdp_bin"] = "xfreerdp"
|
||||||
else:
|
else:
|
||||||
settings["rdp_bin"] = "sdl-freerdp"
|
settings["rdp_bin"] = "sdl-freerdp"
|
||||||
|
|
||||||
def fscr(self, app, state):
|
def fscr(self, app, state):
|
||||||
if state:
|
if state:
|
||||||
settings["extra_params"]["f"] = True
|
settings["extra_params"]["f"] = True
|
||||||
else:
|
else:
|
||||||
settings["extra_params"]["f"] = False
|
settings["extra_params"]["f"] = False
|
||||||
|
|
||||||
def on_destroy(self, app):
|
def on_destroy(self, app):
|
||||||
print("Saving settings config to "+HOMEDIR+"/.config/rdpconnect/settings.json")
|
print("Saving settings config to "+HOMEDIR+"/.config/rdpconnect/settings.json")
|
||||||
with open(HOMEDIR+"/.config/rdpconnect/settings.json", "w") as settings_file:
|
with open(HOMEDIR+"/.config/rdpconnect/settings.json", "w") as settings_file:
|
||||||
js = json.dumps(settings, sort_keys=True, indent=4, separators=(',', ': '))
|
js = json.dumps(settings, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
settings_file.write(js)
|
settings_file.write(js)
|
||||||
|
|
||||||
|
|
||||||
class MyApp(Adw.Application):
|
class MyApp(Adw.Application):
|
||||||
|
global hist_info
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
self.connect('activate', self.on_activate)
|
self.connect('activate', self.on_activate)
|
||||||
@@ -245,6 +304,10 @@ class MyApp(Adw.Application):
|
|||||||
action.connect('activate', self.on_about)
|
action.connect('activate', self.on_about)
|
||||||
self.add_action(action)
|
self.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction(name='history')
|
||||||
|
action.connect('activate', self.on_history)
|
||||||
|
self.add_action(action)
|
||||||
|
|
||||||
def on_about(self, action, param):
|
def on_about(self, action, param):
|
||||||
about_dialog = Gtk.AboutDialog(transient_for=self.win, modal=True)
|
about_dialog = Gtk.AboutDialog(transient_for=self.win, modal=True)
|
||||||
about_dialog.set_copyright("Antonin Kaplan")
|
about_dialog.set_copyright("Antonin Kaplan")
|
||||||
@@ -258,17 +321,36 @@ class MyApp(Adw.Application):
|
|||||||
def on_preferences(self, action, param):
|
def on_preferences(self, action, param):
|
||||||
PreferencesWindow()
|
PreferencesWindow()
|
||||||
|
|
||||||
|
def on_history(self, action, param):
|
||||||
|
HistoryWindow()
|
||||||
|
|
||||||
def saveConnConf(self):
|
def saveConnConf(self):
|
||||||
if settings["save_conn"]:
|
if settings["save_conn"]:
|
||||||
password = conn_info["passwd"]
|
password = conn_info["passwd"]
|
||||||
conn_info["passwd"] = fernet.encrypt(password.encode()).decode("utf-8")
|
useratip = conn_info["user"] + "@" + conn_info["ip"]
|
||||||
|
|
||||||
print("Saving connection config to "+HOMEDIR+"/.config/rdpconnect/connection.json")
|
new_conn = 1
|
||||||
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "w") as connection_file:
|
for i in hist_info:
|
||||||
js = json.dumps(conn_info, sort_keys=True, indent=4, separators=(',', ': '))
|
if hist_info[i] == useratip:
|
||||||
connection_file.write(js)
|
new_conn = 0
|
||||||
|
if new_conn == 1:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/history.json", "w") as hist_file:
|
||||||
|
hist_id = str(int(max(hist_info, default=0)) + 1)
|
||||||
|
hist_info[hist_id] = useratip
|
||||||
|
js = json.dumps(hist_info, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
hist_file.write(js)
|
||||||
|
|
||||||
conn_info["passwd"] = password
|
try:
|
||||||
|
keyring.set_password("com.angoosh.RDPConnect", useratip, password)
|
||||||
|
except:
|
||||||
|
conn_info["passwd"] = fernet.encrypt(password.encode()).decode("utf-8")
|
||||||
|
|
||||||
|
print("Saving connection config to "+HOMEDIR+"/.config/rdpconnect/connection.json")
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "w") as connection_file:
|
||||||
|
js = json.dumps(conn_info, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
connection_file.write(js)
|
||||||
|
|
||||||
|
conn_info["passwd"] = password
|
||||||
else:
|
else:
|
||||||
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "w") as connection_file:
|
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "w") as connection_file:
|
||||||
connection_file.write("")
|
connection_file.write("")
|
||||||
@@ -291,7 +373,7 @@ class MyApp(Adw.Application):
|
|||||||
settings["rdp_bin"] = "sdl-freerdp"
|
settings["rdp_bin"] = "sdl-freerdp"
|
||||||
|
|
||||||
self.saveConnConf()
|
self.saveConnConf()
|
||||||
|
|
||||||
extra_params = []
|
extra_params = []
|
||||||
for item in settings["extra_params"]:
|
for item in settings["extra_params"]:
|
||||||
#check if is boolean
|
#check if is boolean
|
||||||
@@ -302,7 +384,7 @@ class MyApp(Adw.Application):
|
|||||||
if str(settings["extra_params"][item]) != "":
|
if str(settings["extra_params"][item]) != "":
|
||||||
print(str(settings["extra_params"][item]))
|
print(str(settings["extra_params"][item]))
|
||||||
extra_params.append("/"+str(item)+":"+str(settings["extra_params"][item]))
|
extra_params.append("/"+str(item)+":"+str(settings["extra_params"][item]))
|
||||||
|
|
||||||
print(extra_params)
|
print(extra_params)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -2,9 +2,13 @@
|
|||||||
<interface>
|
<interface>
|
||||||
<menu id='app-menu'>
|
<menu id='app-menu'>
|
||||||
<section>
|
<section>
|
||||||
|
<item>
|
||||||
|
<attribute name='label'>History</attribute>
|
||||||
|
<attribute name='action'>app.history</attribute>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<attribute name='label'>Preferences</attribute>
|
<attribute name='label'>Preferences</attribute>
|
||||||
<attribute name='action'>app.preferences</attribute>
|
<attribute name='action'>app.preferences</attribute>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<attribute name='label'>About</attribute>
|
<attribute name='label'>About</attribute>
|
||||||
|
|||||||
385
testing.py
Normal file
385
testing.py
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created on Mon Nov 18 12:04:53 2024
|
||||||
|
|
||||||
|
@author: angoosh
|
||||||
|
|
||||||
|
references:
|
||||||
|
https://pygobject.gnome.org/tutorials/gtk4/introduction.html
|
||||||
|
https://docs.gtk.org/gtk3/index.html#classes
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import gi
|
||||||
|
import subprocess
|
||||||
|
import json
|
||||||
|
from cryptography.fernet import Fernet
|
||||||
|
gi.require_version('Gtk', '4.0')
|
||||||
|
gi.require_version('Adw', '1')
|
||||||
|
from gi.repository import Gtk, Adw, Gdk, Gio
|
||||||
|
import keyring
|
||||||
|
|
||||||
|
APPID = "com.angoosh.RDPConnect"
|
||||||
|
HOMEDIR = os.path.expanduser('~')
|
||||||
|
|
||||||
|
VERSION = "1.3.0"
|
||||||
|
|
||||||
|
conn_info = {}
|
||||||
|
hist_info = {}
|
||||||
|
settings = {}
|
||||||
|
settings["extra_params"] = {}
|
||||||
|
fernet = ""
|
||||||
|
|
||||||
|
def load_keys():
|
||||||
|
global fernet
|
||||||
|
cryptoKey = ""
|
||||||
|
try:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/.key", "r") as keyfile:
|
||||||
|
cryptoKey = str.encode(keyfile.readline())
|
||||||
|
print("Encription key loaded")
|
||||||
|
except:
|
||||||
|
cryptoKey = Fernet.generate_key()
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/.key", "w") as keyfile:
|
||||||
|
keyfile.write(cryptoKey.decode("utf-8"))
|
||||||
|
print("Encription key generated")
|
||||||
|
|
||||||
|
fernet = Fernet(cryptoKey)
|
||||||
|
|
||||||
|
def load_config():
|
||||||
|
global conn_info, settings
|
||||||
|
loaded_json = ""
|
||||||
|
try:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/history.json", "r") as history_file:
|
||||||
|
for line in history_file:
|
||||||
|
loaded_json += line
|
||||||
|
|
||||||
|
hist_info = json.loads(loaded_json)
|
||||||
|
last_conn = hist_info[max(hist_info)]
|
||||||
|
conn_info["user"] = last_conn.split('@')[0]
|
||||||
|
conn_info["ip"] = last_conn.split('@')[1]
|
||||||
|
conn_info["passwd"] = keyring.get_password("com.angoosh.RDPConnect", last_conn)
|
||||||
|
|
||||||
|
except:
|
||||||
|
try:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "r") as connection_file:
|
||||||
|
for line in connection_file:
|
||||||
|
loaded_json += line
|
||||||
|
|
||||||
|
conn_info = json.loads(loaded_json)
|
||||||
|
|
||||||
|
conn_info["passwd"] = fernet.decrypt(str.encode(conn_info["passwd"])).decode()
|
||||||
|
except:
|
||||||
|
print("[WARN] FILE: "+HOMEDIR+"/.config/rdpconnect/connection.json doesn't exist")
|
||||||
|
|
||||||
|
loaded_json = ""
|
||||||
|
try:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/settings.json", "r") as settings_file:
|
||||||
|
for line in settings_file:
|
||||||
|
loaded_json += line
|
||||||
|
|
||||||
|
settings = json.loads(loaded_json)
|
||||||
|
except:
|
||||||
|
print("[WARN] FILE: "+HOMEDIR+"/.config/rdpconnect/settings.json doesn't exist")
|
||||||
|
|
||||||
|
class HistoryWindow(Gtk.Window):
|
||||||
|
def __init__(self, **kargs):
|
||||||
|
super().__init__(**kargs, title='History')
|
||||||
|
|
||||||
|
self.set_default_size(100, 300)
|
||||||
|
|
||||||
|
self.scroll = Gtk.ScrolledWindow()
|
||||||
|
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
|
||||||
|
self.grid = Gtk.Grid()
|
||||||
|
|
||||||
|
self.scroll.set_child(self.grid)
|
||||||
|
|
||||||
|
index = 0
|
||||||
|
for i in hist_info:
|
||||||
|
self.addRow(hist_info[i], index)
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
self.set_child(self.scroll)
|
||||||
|
|
||||||
|
def addRow(self, entry, index):
|
||||||
|
runb = Gtk.Button(label=entry)
|
||||||
|
runb.connect("clicked", self.apply_contents)
|
||||||
|
|
||||||
|
self.grid.attach(runb, 0, index, 1, 1)
|
||||||
|
|
||||||
|
def apply_contents(self, button):
|
||||||
|
conn_info["user"] = button.get_label().split('@')[0]
|
||||||
|
conn_info["ip"] = button.get_label().split('@')[1]
|
||||||
|
try:
|
||||||
|
conn_info["passwd"] = keyring.get_password("com.angoosh.RDPConnect", button.get_label())
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class PreferencesWindow(Gtk.Window):
|
||||||
|
global settings
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
self.builder = Gtk.Builder(self)
|
||||||
|
self.builder.add_from_file("/app/preferences.ui")
|
||||||
|
|
||||||
|
self.resx = self.builder.get_object("resx")
|
||||||
|
self.resy = self.builder.get_object("resy")
|
||||||
|
self.monitors = self.builder.get_object("monitors")
|
||||||
|
self.fullscreen = self.builder.get_object("fullscreen")
|
||||||
|
self.xfree = self.builder.get_object("xfree")
|
||||||
|
self.sound = self.builder.get_object("sound")
|
||||||
|
self.mic = self.builder.get_object("mic")
|
||||||
|
self.dynres = self.builder.get_object("dynres")
|
||||||
|
self.clipboard = self.builder.get_object("clipboard")
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.clipboard.set_state(settings["extra_params"]["clipboard"])
|
||||||
|
self.clipboard.set_active(settings["extra_params"]["clipboard"])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.dynres.set_state(settings["extra_params"]["dynamic-resolution"])
|
||||||
|
self.dynres.set_active(settings["extra_params"]["dynamic-resolution"])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.mic.set_state(settings["extra_params"]["microphone"])
|
||||||
|
self.mic.set_active(settings["extra_params"]["microphone"])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.sound.set_state(settings["extra_params"]["sound"])
|
||||||
|
self.sound.set_active(settings["extra_params"]["sound"])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
if settings["rdp_bin"] == "xfreerdp":
|
||||||
|
self.xfree.set_state(True)
|
||||||
|
self.xfree.set_active(True)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.fullscreen.set_state(settings["extra_params"]["f"])
|
||||||
|
self.fullscreen.set_active(settings["extra_params"]["f"])
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.monitors.get_buffer().set_text(str(settings["extra_params"]["monitors"]), len(settings["extra_params"]["monitors"]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.resx.get_buffer().set_text(str(settings["extra_params"]["w"]), len(settings["extra_params"]["w"]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
self.resy.get_buffer().set_text(str(settings["extra_params"]["h"]), len(settings["extra_params"]["h"]))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
pref_window = self.builder.get_object("pref_window")
|
||||||
|
pref_window.show()
|
||||||
|
|
||||||
|
def f_resx(self, app):
|
||||||
|
settings["extra_params"]["w"] = self.resx.get_buffer().get_text()
|
||||||
|
|
||||||
|
def f_resy(self, app):
|
||||||
|
settings["extra_params"]["h"] = self.resy.get_buffer().get_text()
|
||||||
|
|
||||||
|
def monconf(self, app):
|
||||||
|
settings["extra_params"]["monitors"] = self.monitors.get_buffer().get_text()
|
||||||
|
|
||||||
|
def clipboard(self, app, state):
|
||||||
|
if state:
|
||||||
|
settings["extra_params"]["clipboard"] = True
|
||||||
|
else:
|
||||||
|
settings["extra_params"]["clipboard"] = False
|
||||||
|
|
||||||
|
def dynres(self, app, state):
|
||||||
|
if state:
|
||||||
|
settings["extra_params"]["dynamic-resolution"] = True
|
||||||
|
else:
|
||||||
|
settings["extra_params"]["dynamic-resolution"] = False
|
||||||
|
|
||||||
|
def microphone(self, app, state):
|
||||||
|
if state:
|
||||||
|
settings["extra_params"]["microphone"] = True
|
||||||
|
else:
|
||||||
|
settings["extra_params"]["microphone"] = False
|
||||||
|
|
||||||
|
def sound(self, app, state):
|
||||||
|
if state:
|
||||||
|
settings["extra_params"]["sound"] = True
|
||||||
|
else:
|
||||||
|
settings["extra_params"]["sound"] = False
|
||||||
|
|
||||||
|
def xfree(self, app, state):
|
||||||
|
if state:
|
||||||
|
settings["rdp_bin"] = "xfreerdp"
|
||||||
|
else:
|
||||||
|
settings["rdp_bin"] = "sdl-freerdp"
|
||||||
|
|
||||||
|
def fscr(self, app, state):
|
||||||
|
if state:
|
||||||
|
settings["extra_params"]["f"] = True
|
||||||
|
else:
|
||||||
|
settings["extra_params"]["f"] = False
|
||||||
|
|
||||||
|
def on_destroy(self, app):
|
||||||
|
print("Saving settings config to "+HOMEDIR+"/.config/rdpconnect/settings.json")
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/settings.json", "w") as settings_file:
|
||||||
|
js = json.dumps(settings, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
settings_file.write(js)
|
||||||
|
|
||||||
|
|
||||||
|
class MyApp(Adw.Application):
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super().__init__(**kwargs)
|
||||||
|
self.connect('activate', self.on_activate)
|
||||||
|
|
||||||
|
def on_activate(self, app):
|
||||||
|
builder = Gtk.Builder()
|
||||||
|
builder.add_from_file("/app/"+APPID+".ui")
|
||||||
|
buildermenu = Gtk.Builder()
|
||||||
|
buildermenu.add_from_file("/app/menu.ui")
|
||||||
|
menu_model = buildermenu.get_object('app-menu')
|
||||||
|
|
||||||
|
css_provider = Gtk.CssProvider()
|
||||||
|
if Adw.StyleManager().get_default().get_dark():
|
||||||
|
css_provider.load_from_file(Gio.File.new_for_path("/app/style-dark.css"))
|
||||||
|
else:
|
||||||
|
css_provider.load_from_file(Gio.File.new_for_path("/app/style-light.css"))
|
||||||
|
Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
|
||||||
|
|
||||||
|
connect = builder.get_object("connect")
|
||||||
|
connect.connect("clicked", self.connectRDP)
|
||||||
|
|
||||||
|
self.ip = builder.get_object("ip")
|
||||||
|
self.user = builder.get_object("user")
|
||||||
|
self.passwd = builder.get_object("pass")
|
||||||
|
|
||||||
|
self.save_conf = builder.get_object("save_conf")
|
||||||
|
|
||||||
|
try:
|
||||||
|
if settings["save_conn"]:
|
||||||
|
self.ip.get_buffer().set_text(str(conn_info["ip"]), len(conn_info["ip"]))
|
||||||
|
self.user.get_buffer().set_text(str(conn_info["user"]), len(conn_info["user"]))
|
||||||
|
self.passwd.get_buffer().set_text(str(conn_info["passwd"]), len(conn_info["passwd"]))
|
||||||
|
|
||||||
|
self.save_conf.set_active(True)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
#menu config
|
||||||
|
self.win = builder.get_object("main_window")
|
||||||
|
header_bar = Gtk.HeaderBar()
|
||||||
|
self.win.set_titlebar(header_bar)
|
||||||
|
|
||||||
|
menubutton = Gtk.MenuButton(menu_model=menu_model, icon_name='open-menu-symbolic')
|
||||||
|
header_bar.pack_end(menubutton)
|
||||||
|
|
||||||
|
self.win.set_application(self)
|
||||||
|
self.win.present()
|
||||||
|
|
||||||
|
def do_startup(self):
|
||||||
|
Gtk.Application.do_startup(self)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction(name='preferences')
|
||||||
|
action.connect('activate', self.on_preferences)
|
||||||
|
self.add_action(action)
|
||||||
|
|
||||||
|
action = Gio.SimpleAction(name='about')
|
||||||
|
action.connect('activate', self.on_about)
|
||||||
|
self.add_action(action)
|
||||||
|
|
||||||
|
#action = Gio.SimpleAction(name='history')
|
||||||
|
#action.connect('activate', self.on_history)
|
||||||
|
#self.add_action(action)
|
||||||
|
|
||||||
|
def on_about(self, action, param):
|
||||||
|
about_dialog = Gtk.AboutDialog(transient_for=self.win, modal=True)
|
||||||
|
about_dialog.set_copyright("Antonin Kaplan")
|
||||||
|
about_dialog.set_program_name("RDP Connect")
|
||||||
|
about_dialog.set_license_type(Gtk.License(16))
|
||||||
|
about_dialog.set_logo_icon_name("com.angoosh.RDPConnect")
|
||||||
|
about_dialog.set_version(VERSION)
|
||||||
|
about_dialog.set_website("https://gitea.farmdash.org/angoosh/Flatpaks")
|
||||||
|
about_dialog.present()
|
||||||
|
|
||||||
|
def on_preferences(self, action, param):
|
||||||
|
PreferencesWindow()
|
||||||
|
|
||||||
|
def on_history(self, action, param):
|
||||||
|
HistoryWindow()
|
||||||
|
|
||||||
|
def saveConnConf(self):
|
||||||
|
if settings["save_conn"]:
|
||||||
|
password = conn_info["passwd"]
|
||||||
|
useratip = conn_info["user"] + "@" + conn_info["ip"]
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/history.json", "w") as hist_file:
|
||||||
|
hist_id = str(int(max(hist_info, default=0)) + 1)
|
||||||
|
hist_info[hist_id] = useratip
|
||||||
|
js = json.dumps(hist_info, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
hist_file.write(js)
|
||||||
|
try:
|
||||||
|
keyring.set_password("com.angoosh.RDPConnect", useratip, password)
|
||||||
|
except:
|
||||||
|
conn_info["passwd"] = fernet.encrypt(password.encode()).decode("utf-8")
|
||||||
|
|
||||||
|
print("Saving connection config to "+HOMEDIR+"/.config/rdpconnect/connection.json")
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "w") as connection_file:
|
||||||
|
js = json.dumps(conn_info, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
connection_file.write(js)
|
||||||
|
|
||||||
|
conn_info["passwd"] = password
|
||||||
|
else:
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/connection.json", "w") as connection_file:
|
||||||
|
connection_file.write("")
|
||||||
|
|
||||||
|
print("Saving settings config to "+HOMEDIR+"/.config/rdpconnect/settings.json")
|
||||||
|
with open(HOMEDIR+"/.config/rdpconnect/settings.json", "w") as settings_file:
|
||||||
|
js = json.dumps(settings, sort_keys=True, indent=4, separators=(',', ': '))
|
||||||
|
settings_file.write(js)
|
||||||
|
|
||||||
|
def connectRDP(self, button):
|
||||||
|
conn_info["ip"] = self.ip.get_buffer().get_text()
|
||||||
|
conn_info["user"] = self.user.get_buffer().get_text()
|
||||||
|
conn_info["passwd"] = self.passwd.get_buffer().get_text()
|
||||||
|
|
||||||
|
if self.save_conf.get_active():
|
||||||
|
settings["save_conn"] = True
|
||||||
|
else:
|
||||||
|
settings["save_conn"] = False
|
||||||
|
if not "rdp_bin" in settings:
|
||||||
|
settings["rdp_bin"] = "sdl-freerdp"
|
||||||
|
|
||||||
|
self.saveConnConf()
|
||||||
|
|
||||||
|
extra_params = []
|
||||||
|
for item in settings["extra_params"]:
|
||||||
|
#check if is boolean
|
||||||
|
if type(settings["extra_params"][item]) == type(True):
|
||||||
|
if settings["extra_params"][item]:
|
||||||
|
extra_params.append("/"+str(item))
|
||||||
|
else:
|
||||||
|
if str(settings["extra_params"][item]) != "":
|
||||||
|
print(str(settings["extra_params"][item]))
|
||||||
|
extra_params.append("/"+str(item)+":"+str(settings["extra_params"][item]))
|
||||||
|
|
||||||
|
print(extra_params)
|
||||||
|
|
||||||
|
try:
|
||||||
|
print("Running", settings["rdp_bin"])
|
||||||
|
subprocess.run([settings["rdp_bin"], "/cert:ignore", "/v:"+str(conn_info["ip"]), "/u:"+str(conn_info["user"]), "/p:"+str(conn_info["passwd"])]+extra_params)
|
||||||
|
except:
|
||||||
|
print("Running sdl-freerdp")
|
||||||
|
subprocess.run(["sdl-freerdp", "/cert:ignore", "/v:"+str(conn_info["ip"]), "/u:"+str(conn_info["user"]), "/p:"+str(conn_info["passwd"])]+extra_params)
|
||||||
|
|
||||||
|
if not os.path.isdir(HOMEDIR+"/.config/rdpconnect"):
|
||||||
|
os.makedirs(HOMEDIR+"/.config/rdpconnect")
|
||||||
|
|
||||||
|
load_keys()
|
||||||
|
load_config()
|
||||||
|
app = MyApp(application_id=APPID)
|
||||||
|
app.run(sys.argv)
|
||||||
Reference in New Issue
Block a user